> ## Documentation Index
> Fetch the complete documentation index at: https://docs.golf.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Golf utilities

> Built-in utilities for elicitation, sampling, and context management in Golf v0.2.0.

Golf v0.2.0 introduces powerful built-in utilities that enhance your tool development experience.

## Overview

Golf utilities provide four core capabilities:

1. **Context Access** - Direct access to FastMCP context without manual parameter passing
2. **Elicitation** - Interactive user prompting and input collection
3. **Sampling** - LLM interactions and text generation with multiple modes
4. **Authentication Integration** - Seamless token extraction

All utilities automatically handle context management using Python's `contextvars` for thread-safe, async-aware access to FastMCP features.

## Context access

### Get current context

The `get_current_context()` function provides direct access to the FastMCP context without requiring explicit context parameter passing.

```python theme={null}
from golf.utilities import get_current_context

async def context_aware_tool():
    # Get the current FastMCP context
    context = get_current_context()
    
    # Access request information
    request_id = getattr(context, 'request_id', None)
    
    return {
        "request_id": request_id,
        "context_available": True
    }
```

### Context with logging

```python theme={null}
from golf.utilities import get_current_context

async def logging_tool(message: str):
    context = get_current_context()
    
    # Use context for structured logging
    context.logger.info(f"Processing message: {message}")
    
    return {"status": "logged", "message": message}
```

### Error handling

```python theme={null}
from golf.utilities import get_current_context

async def safe_context_tool():
    try:
        context = get_current_context()
        return {"context_available": True}
    except RuntimeError as e:
        # Context not available (e.g., called outside MCP tool)
        return {
            "context_available": False, 
            "error": str(e)
        }
    except ImportError as e:
        # FastMCP not available or incompatible version
        return {
            "context_available": False,
            "error": "FastMCP >=2.11.0 required"
        }
```

## Elicitation utilities

Elicitation utilities enable your tools to interact with users, collect additional information, and create dynamic conversational experiences.

### Basic elicitation

```python theme={null}
from golf.utilities import elicit

async def interactive_tool():
    # Simple text prompt
    color = await elicit("What's your favorite color?")
    
    # Use the response in your tool logic
    return {"message": f"Great choice! {color} is a beautiful color."}
```

### Type-safe elicitation

```python theme={null}
from golf.utilities import elicit
from pydantic import BaseModel

class UserInfo(BaseModel):
    name: str
    email: str
    age: int

async def user_registration_tool():
    # Collect structured data with validation
    user_info = await elicit("Please provide your information:", UserInfo)
    
    return {
        "name": user_info.name,
        "email": user_info.email,
        "age": user_info.age
    }
```

### Confirmation dialogs

```python theme={null}
from golf.utilities import elicit_confirmation

async def deletion_tool(file_path: str):
    # Ask for confirmation before destructive action
    confirmed = await elicit_confirmation(
        f"Are you sure you want to delete {file_path}?"
    )
    
    if confirmed:
        # Perform deletion
        return {"status": "deleted", "file": file_path}
    else:
        return {"status": "cancelled", "file": file_path}
```

### Advanced elicitation with error handling

```python theme={null}
from golf.utilities import elicit, elicit_confirmation

async def configuration_tool():
    try:
        # Collect multiple pieces of information
        name = await elicit("What's your name?")
        email = await elicit("What's your email address?")
        
        # Confirm before saving
        confirmed = await elicit_confirmation(
            f"Save configuration for {name} ({email})?"
        )
        
        if confirmed:
            config = {"name": name, "email": email}
            return {"configuration": config, "saved": True}
        else:
            return {"configuration": None, "saved": False}
            
    except RuntimeError as e:
        # User declined or cancelled
        return {"error": f"Configuration failed: {str(e)}"}
```

## Sampling utilities

Sampling utilities provide direct access to LLM capabilities within your tools, enabling text generation, analysis, and AI-powered processing with multiple modes.

### Basic sampling

```python theme={null}
from golf.utilities import sample

async def explanation_tool(topic: str):
    # Generate an explanation using the default model
    explanation = await sample(f"Explain {topic} in simple terms")
    
    return {"topic": topic, "explanation": explanation}
```

### Structured sampling

The `sample_structured()` function uses a lower temperature (0.1) for more consistent, formatted outputs.

```python theme={null}
from golf.utilities import sample_structured

async def entity_extraction_tool(text: str):
    # Use structured sampling for formatted outputs
    entities = await sample_structured(
        f"Extract entities from this text: {text}",
        format_instructions="Return as JSON with keys: persons, organizations, locations"
    )
    
    return {"text": text, "entities": entities}
```

### Context-enhanced sampling

The `sample_with_context()` function automatically appends context data to prompts.

```python theme={null}
from golf.utilities import sample_with_context

async def personalized_report_tool(data: str):
    # Sample with automatic context enhancement
    report = await sample_with_context(
        f"Generate a personalized report based on this data: {data}",
        context_data={
            "user_preferences": "detailed analysis",
            "report_format": "executive summary"
        }
    )
    
    return {"data": data, "report": report}
```

### Advanced sampling with parameters

```python theme={null}
from golf.utilities import sample

async def creative_writing_tool(prompt: str, style: str):
    # Advanced sampling with custom parameters
    story = await sample(
        f"Write a short story in {style} style based on: {prompt}",
        model="gpt-4",
        max_tokens=500,
        temperature=0.8
    )
    
    return {
        "prompt": prompt,
        "style": style,
        "story": story
    }
```

### Sampling error handling

```python theme={null}
from golf.utilities import sample, sample_structured

async def robust_analysis_tool(text: str):
    try:
        # Attempt structured analysis
        analysis = await sample_structured(
            f"Analyze the sentiment and themes in: {text}",
            format_instructions="Return JSON with sentiment and themes"
        )
        return {"analysis": analysis, "method": "structured"}
        
    except RuntimeError as e:
        # Fall back to basic sampling
        try:
            analysis = await sample(f"Analyze: {text}")
            return {"analysis": analysis, "method": "basic"}
        except RuntimeError:
            return {
                "error": "Analysis failed", 
                "text": text
            }
```

## Authentication integration

Golf utilities seamlessly integrate with the authentication system for secure API forwarding.

### Basic token forwarding

```python theme={null}
from golf.utilities import sample
from golf.auth import get_auth_token

async def api_analysis_tool(data: str):
    # Get authentication token
    auth_token = get_auth_token()
    
    if not auth_token:
        return {"error": "Authentication required"}
    
    # Use token for upstream API call
    import httpx
    async with httpx.AsyncClient() as client:
        response = await client.post(
            "https://api.example.com/analyze",
            headers={"Authorization": f"Bearer {auth_token}"},
            json={"data": data}
        )
        
        # Enhance results with LLM sampling
        summary = await sample(
            f"Summarize this API response: {response.text}"
        )
        
        return {
            "api_response": response.json(),
            "summary": summary
        }
```

### Combined context and auth

```python theme={null}
from golf.utilities import get_current_context, sample
from golf.auth import get_auth_token

async def secure_personalized_tool(request: str):
    # Get both context and auth
    context = get_current_context()
    auth_token = get_auth_token()
    
    if not auth_token:
        return {"error": "Authentication required"}
    
    # Log request with context
    context.logger.info(f"Processing request: {request}")
    
    # Generate personalized response
    response = await sample(
        f"Respond to this request personally: {request}",
        context_data={
            "user_authenticated": True,
            "request_id": getattr(context, 'request_id', None)
        }
    )
    
    return {
        "request": request,
        "response": response,
        "authenticated": True
    }
```

## Error handling best practices

### Comprehensive error handling

```python theme={null}
from golf.utilities import get_current_context, sample, elicit
from golf.auth import get_auth_token

async def production_ready_tool(task: str):
    try:
        # Verify context availability
        context = get_current_context()
        
        # Check authentication
        auth_token = get_auth_token()
        if not auth_token:
            confirmation = await elicit_confirmation(
                "No authentication found. Continue with limited functionality?"
            )
            if not confirmation:
                return {"error": "Authentication required"}
        
        # Perform main task
        result = await sample(f"Complete this task: {task}")
        
        # Log success
        context.logger.info(f"Task completed: {task}")
        
        return {
            "task": task,
            "result": result,
            "authenticated": bool(auth_token)
        }
        
    except ImportError:
        return {
            "error": "FastMCP >=2.11.0 required",
            "task": task
        }
    except RuntimeError as e:
        if "Context" in str(e):
            return {
                "error": "Must be called from MCP tool context",
                "task": task
            }
        elif "declined" in str(e):
            return {
                "error": "User declined operation",
                "task": task
            }
        else:
            return {
                "error": f"Operation failed: {str(e)}",
                "task": task
            }
```
