# Klynx Python SDK

`klynx` is a Python framework for building coding agents with a default `think -> act -> feedback` loop.
It supports both:

- A ready-to-use default agent runtime
- A composable graph builder API for custom orchestration

## Install (PyPI)

```bash
pip install -U klynx
```

Optional browser tooling (needed only if your tools use browser automation):

```bash
playwright install chromium
```

## Quick Start

### 1) Set your model API key

Example (OpenAI):

```bash
export OPENAI_API_KEY="sk-..."
```

### 2) Create a model and a default agent

```python
from klynx import create_agent, setup_model

model = setup_model("gpt-4o")
agent = create_agent(
    working_dir=".",
    model=model,
    max_iterations=20,
    load_project_docs=False,
)
```

### 3) Stream a task and read the final answer

```python
for event in agent.invoke(task="Summarize this repository architecture", thread_id="demo"):
    if event.get("type") == "done":
        print(event.get("answer", ""))
```

## API Exports

```python
from klynx import (
    create_agent,
    create_builder,
    KlynxAgent,
    KlynxGraphBuilder,
    ComposableAgentRuntime,
    setup_model,
    list_models,
    set_tavily_api,
    run_terminal_agent_stream,
    run_terminal_ask_stream,
)
```

## Usage Tutorial

### Tutorial 1: Direct Q&A mode

```python
from klynx import create_agent, setup_model

model = setup_model("gpt-4o")
agent = create_agent(working_dir=".", model=model)

for event in agent.ask("Explain the key modules in this codebase", thread_id="ask-demo"):
    if event.get("type") == "done":
        print(event.get("answer", ""))
```

### Tutorial 2: Build a composable runtime with `create_builder`

```python
from klynx import create_builder, setup_model

model = setup_model("gpt-4o")

builder = create_builder(name="demo_builder")
builder.add_node("klynx_loop")
builder.set_entry_point("klynx_loop")

runtime = builder.build(
    working_dir=".",
    model=model,
    max_iterations=12,
)

for event in runtime.invoke(task="Find TODOs and propose fixes", thread_id="builder-demo"):
    if event.get("type") == "done":
        print(event.get("answer", ""))
```

### Tutorial 3: Add custom nodes after the default loop

```python
from klynx import create_builder, setup_model

model = setup_model("gpt-4o")


def post_process(runtime, payload):
    return [{"type": "summary", "content": "Post-processing completed."}]

builder = create_builder(name="pipeline")
builder.add_node("klynx_loop")
builder.add_node("post_process", post_process)
builder.add_edge("klynx_loop", "post_process")
builder.set_entry_point("klynx_loop")

runtime = builder.build(working_dir=".", model=model)
for event in runtime.invoke(task="Refactor this module", thread_id="pipeline-demo"):
    print(event)
```

### Tutorial 4: Manage toolsets dynamically

Both the default agent and builder runtime support tool mutation:

```python
runtime.add_tools("group:core")
runtime.add_tools("group:interactive")
runtime.add_tools("group:network_and_extra")
runtime.add_tools("none")
```

### Tutorial 5: Enable web search tools

```python
from klynx import set_tavily_api

set_tavily_api("tvly-...")
```

## Event Model

`invoke(...)` and `ask(...)` produce event dictionaries. Common types include:

- `token`
- `reasoning_token`
- `tool_exec`
- `tool_result`
- `warning`
- `error`
- `done`

A `done` event usually contains the final answer and token metrics.

## Model Setup Notes

`setup_model(...)` supports both alias and provider/model usage:

```python
setup_model("gpt-4o")
setup_model("openai", "gpt-4o")
setup_model("deepseek", "deepseek-chat")
```

Use `list_models()` to inspect available aliases.

## Terminal Helpers

For terminal-only usage, you can use helper stream runners:

- `run_terminal_agent_stream(...)`
- `run_terminal_ask_stream(...)`

## Related Package

If you want a full command-line and TUI experience, install:

```bash
pip install -U klynx-cli
```
