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

# SDK Reference

> Full Python SDK reference for embedding GitAgent in your application.

The GitAgent SDK lets you run agents programmatically from Python — in web servers, scripts, batch jobs, or any other Python context.

## Installation

```bash theme={null}
pip install gitagent
```

## Basic usage

```python theme={null}
from gitagent import Agent

agent = Agent(agent_dir="./my-agent")
response = agent.run("What's the weather in London?")
print(response.output)
```

## `Agent` class

```python theme={null}
from gitagent import Agent

agent = Agent(
    agent_dir="./my-agent",          # path to agent directory
    model_override="gpt-4o-mini",    # override agent.yaml model
    environment="production",         # tag for telemetry
    memory_user_id="user123",        # scope memory to a user
    session_id="session-abc",        # continue an existing session
    metadata={"customer": "acme"},   # arbitrary run metadata
)
```

### `agent.run()`

Run the agent synchronously.

```python theme={null}
response = agent.run(
    input="Your prompt here",
    session_id="optional-session",    # override session from constructor
    metadata={"key": "value"},        # merge with constructor metadata
    timeout=120,                       # seconds (default: from agent.yaml)
)
```

Returns a `RunResponse` object.

### `agent.run_async()`

Run the agent asynchronously.

```python theme={null}
import asyncio

async def main():
    agent = Agent(agent_dir="./my-agent")
    response = await agent.run_async("What's the capital of France?")
    print(response.output)

asyncio.run(main())
```

### `agent.stream()`

Stream the agent's output token by token:

```python theme={null}
for chunk in agent.stream("Write a poem about the ocean"):
    print(chunk, end="", flush=True)
print()  # newline after streaming
```

### `agent.run_flow()`

Run a specific SkillsFlow:

```python theme={null}
response = agent.run_flow(
    flow_name="research-report",
    input={"topic": "quantum computing"}
)
print(response.output)
```

## `RunResponse` object

```python theme={null}
response.output          # str: the agent's final response
response.run_id          # str: unique run identifier
response.session_id      # str: session identifier
response.skill_calls     # list[SkillCall]: skills that were called
response.duration_ms     # int: total run duration
response.usage           # TokenUsage: token counts and estimated cost
response.metadata        # dict: metadata attached to this run
response.error           # str | None: error message if run failed
response.success         # bool: True if no error
```

### `SkillCall`

```python theme={null}
call = response.skill_calls[0]
call.skill_name      # str
call.input           # dict
call.output          # any
call.duration_ms     # int
call.error           # str | None
```

### `TokenUsage`

```python theme={null}
usage = response.usage
usage.input_tokens        # int
usage.output_tokens       # int
usage.total_tokens        # int
usage.estimated_cost_usd  # float
```

## Embedding in a web server

### FastAPI

```python theme={null}
from fastapi import FastAPI
from pydantic import BaseModel
from gitagent import Agent

app = FastAPI()
agent = Agent(agent_dir="./my-agent")

class ChatRequest(BaseModel):
    message: str
    session_id: str | None = None
    user_id: str | None = None

@app.post("/chat")
async def chat(request: ChatRequest):
    response = await agent.run_async(
        input=request.message,
        session_id=request.session_id,
        memory_user_id=request.user_id
    )
    return {
        "output": response.output,
        "session_id": response.session_id,
        "run_id": response.run_id
    }
```

### Streaming with FastAPI

```python theme={null}
from fastapi.responses import StreamingResponse

@app.post("/chat/stream")
async def chat_stream(request: ChatRequest):
    async def generate():
        async for chunk in agent.stream_async(request.message):
            yield f"data: {chunk}\n\n"
        yield "data: [DONE]\n\n"

    return StreamingResponse(generate(), media_type="text/event-stream")
```

## Custom skill registration

Register skills programmatically without placing them in the `skills/` directory:

```python theme={null}
from gitagent import Agent, skill

@skill(name="my_tool", description="A custom tool")
def my_tool(input: str) -> str:
    return f"Processed: {input}"

agent = Agent(agent_dir="./my-agent")
agent.register_skill(my_tool)

response = agent.run("Use my_tool to process 'hello'")
```

## Hooks in code

Register hooks programmatically:

```python theme={null}
from gitagent import Agent
from gitagent.hooks import before_skill

@before_skill
def my_hook(context):
    print(f"Calling skill: {context.skill_name}")

agent = Agent(agent_dir="./my-agent")
agent.register_hook(my_hook)
```

## Error handling

```python theme={null}
from gitagent import Agent
from gitagent.exceptions import AgentError, SkillError, TimeoutError

try:
    response = agent.run("...", timeout=30)
except TimeoutError:
    print("Agent timed out")
except AgentError as e:
    print(f"Agent error: {e}")

# Or check the response object
if not response.success:
    print(f"Run failed: {response.error}")
```

## Batch processing

```python theme={null}
import asyncio
from gitagent import Agent

agent = Agent(agent_dir="./my-agent")

prompts = ["Summarize topic A", "Summarize topic B", "Summarize topic C"]

async def run_all():
    tasks = [agent.run_async(p) for p in prompts]
    return await asyncio.gather(*tasks)

responses = asyncio.run(run_all())
for r in responses:
    print(r.output)
```
