Metadata-Version: 2.4
Name: klynx
Version: 0.0.13
Summary: A sophisticated, universal agentic AI coding framework built on LangGraph and LiteLLM.
Author-email: QZX <qzx480@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/qzx/klynx
Project-URL: Bug Tracker, https://github.com/qzx/klynx/issues
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Operating System :: OS Independent
Classifier: Intended Audience :: Developers
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: litellm>=1.40.0
Requires-Dist: langchain-core>=0.2.0
Requires-Dist: langgraph>=0.2.0
Requires-Dist: httpx>=0.25.0
Requires-Dist: openai>=1.30.0
Requires-Dist: pydantic>=2.7.0
Requires-Dist: rich>=13.0.0
Requires-Dist: playwright>=1.40.0
Requires-Dist: textual>=0.70.0
Requires-Dist: pyte>=0.8.2
Dynamic: license-file

# klynx

`klynx` 是一个面向代码任务的 Agent 库，默认运行在 `think -> act -> feedback` 主循环中，强调执行优先和最小工具路径。

这份 README 只说明 `klynx` 作为 Python 库的调用方式。

## 安装

要求：

- Python `>=3.9`
- 推荐 Python `3.11`

安装：

```bash
pip install klynx
```

开发模式：

```bash
pip install -e libs/klynx
```

如果你要启用浏览器工具，首次使用前需要额外安装 Playwright 浏览器：

```bash
playwright install chromium
```

## 顶层导出

`klynx` 当前对外导出的常用 API 有：

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

## 模型初始化

`klynx` 通过 LiteLLM 统一适配不同模型提供方。

查看内置模型别名：

```python
from klynx import list_models

print(list_models()[:10])
```

创建模型：

```python
import os
from klynx import setup_model

model = setup_model(
    "deepseek",
    "deepseek-chat",
    os.getenv("DEEPSEEK_API_KEY", ""),
)
```

也可以直接用内置别名：

```python
model = setup_model("kimi-k2.5")
```

## 创建 Agent

最小示例：

```python
import os
from klynx import create_agent, setup_model

model = setup_model(
    "deepseek",
    "deepseek-chat",
    os.getenv("DEEPSEEK_API_KEY", ""),
)

agent = create_agent(
    working_dir=".",
    model=model,
    max_iterations=30,
    memory_dir=".klynx-memory",
    load_project_docs=False,
)
```

当前默认行为：

- 默认工具组为 `system + core`
- 默认主路径是 `execute_command -> read_file -> apply_patch -> execute_command`
- `max_iterations=None` 或 `<= 0` 表示不设硬上限
- `tool_virtual_root` 默认为 `working_dir`

## 执行任务：`invoke(...)`

`invoke(...)` 是主入口，返回事件流生成器。

```python
for event in agent.invoke(
    "读取当前仓库结构并指出潜在的打包问题",
    thread_id="demo",
):
    etype = event.get("type")
    if etype in {"reasoning_token", "token"}:
        print(event["content"], end="")
    elif etype in {"answer", "summary", "warning", "error"}:
        print(f"\n[{etype}] {event['content']}")
    elif etype == "done":
        print("\n完成:", event)
```

常见事件类型：

- `reasoning_token`
- `token`
- `answer`
- `summary`
- `warning`
- `error`
- `done`

`done` 事件通常包含：

- `iteration_count`
- `task_completed`
- `total_tokens`
- `prompt_tokens`
- `completion_tokens`

如果你想把事件流包装成适合终端直接观察的输出，也可以使用库里自带的辅助函数：

```python
from klynx import run_terminal_agent_stream

result = run_terminal_agent_stream(
    agent,
    task="修复当前仓库中的 failing tests",
    thread_id="stream-demo",
)
```

或实例方法：

```python
result = agent.run_terminal_agent_stream(
    task="修复当前仓库中的 failing tests",
    thread_id="stream-demo",
)
```

## 直接问答：`ask(...)`

`ask(...)` 不走完整 agent 节点编排，而是直接调用底层模型，适合解释、问答、轻量咨询。

```python
for event in agent.ask(
    "解释一下 create_agent 的关键参数",
    thread_id="ask-demo",
):
    if event["type"] in {"reasoning_token", "token"}:
        print(event["content"], end="")
    elif event["type"] == "done":
        print("\n答案:", event["answer"])
```

对应的辅助函数：

```python
from klynx import run_terminal_ask_stream

answer = run_terminal_ask_stream(
    agent,
    message="解释一下 create_agent 的关键参数",
    thread_id="ask-demo",
)
```

## 读取上下文与历史

### `get_context(...)`

读取指定 `thread_id` 的当前完整状态：

```python
ctx = agent.get_context(thread_id="demo")
print(ctx.get("iteration_count"))
print(ctx.get("overall_goal"))
print(ctx.get("task_completed"))
```

### `get_history(...)`

读取检查点历史，便于查看 agent 做过哪些步骤：

```python
history = agent.get_history(thread_id="demo", limit=10)
for item in history:
    print(item["display_index"], item["node"], item["action"])
```

### `rollback(...)`

将后续执行回滚到某个历史检查点：

```python
ok = agent.rollback(thread_id="demo", target_index=1)
print(ok)
```

## 工具加载策略

默认不建议全量加载工具。

推荐按需启用：

```python
# create_agent() 后默认已有 system + core

agent.add_tools("group:extended_fs")
agent.add_tools("group:interactive")
agent.add_tools("group:network_and_extra")
```

仍然兼容显式全量加载：

```python
agent.add_tools("all")
```

如果你想从“零工具”开始：

```python
agent.add_tools("none")
# 或
agent.clear_tools()
```

这会禁用当前全部内置工具和已注册的外部工具。

可用工具组：

- `group:core`
- `group:extended_fs`
- `group:interactive`
- `group:network_and_extra`
- `group:skills`

建议理解为：

- `core`：本地代码任务默认路径
- `extended_fs`：辅助文件操作
- `interactive`：交互式终端与 TUI
- `network_and_extra`：联网搜索与浏览器
- `skills`：`load_skill`

## 自定义外部工具

`klynx` 支持把 Python callable 注册成运行时外部工具。

最简单的方式：

```python
def echo_text(input: str) -> str:
    return f"echo:{input}"

agent.add_tools(echo_text, "Echo the provided text.")
```

如果你想显式指定工具名，推荐用字典或元组形式：

```python
agent.add_tools(
    {
        "name": "echo_tool",
        "func": echo_text,
        "description": "Echo the provided text.",
    }
)

agent.add_tools(("echo_tool", echo_text, "Echo the provided text."))
```

如果你要完全禁用默认工具，只保留自定义外部工具：

```python
agent.add_tools(
    "none",
    {
        "name": "echo_tool",
        "func": echo_text,
        "description": "Echo the provided text.",
    },
)
```

外部工具会出现在当前 active tools 中，但不属于内置工具组。

## 交互式终端 / TUI / 浏览器

这些都属于库能力的一部分，但不是默认加载。

### 交互式终端

需要 REPL、前台程序或持续 stdin/stdout 会话时：

```python
agent.add_tools("group:interactive")
```

常见相关工具：

- `exec_command`
- `write_stdin`
- `wait_terminal_until`
- `read_terminal_since_last`
- `run_and_wait`

### TUI

需要屏幕化终端应用时，同样开启 `group:interactive`。

常见相关工具：

- `open_tui`
- `read_tui`
- `read_tui_diff`
- `read_tui_region`
- `find_text_in_tui`
- `send_keys_and_read`
- `wait_tui_until`

### 联网搜索与浏览器

```python
from klynx import set_tavily_api

set_tavily_api("tvly-...")
agent.add_tools("group:network_and_extra")
```

常见相关工具：

- `web_search`
- `browser_open`
- `browser_view`
- `browser_act`
- `browser_scroll`
- `browser_screenshot`

## Skills

Skill 是一个包含 `SKILL.md` 的目录。

内置 skills：

- `skill-creator`
- `skill-installer`

开关内置 skills：

```python
agent.basic_skills("off")
agent.basic_skills("on")
```

安装外部 skill：

```python
agent.add_skills("my-skill", r"E:\skills\my-skill", "可选描述")
agent.add_skills(r"E:\skills\my-skill")
agent.add_skills("my-skill")
```

如果设置了 `memory_dir`，会自动扫描：

```text
<memory_dir>/.klynx/skills/
```

运行时可通过 `load_skill(name)` 将对应 `SKILL.md` 注入当前上下文。

## `create_agent(...)` 常用参数

- `working_dir`：Agent 工作目录
- `model`：模型实例
- `max_iterations`：最大迭代次数
- `memory_dir`：记忆目录
- `load_project_docs`：是否自动加载项目文档
- `tool_virtual_root`：文件工具访问根目录
- `allow_shell_commands`：是否允许 `execute_command`
- `checkpointer`：自定义 LangGraph checkpointer
- `browser_headless`：浏览器是否无头运行
- `append_system_prompt`：追加系统提示词
- `hooks`：运行时 hooks

示例：

```python
from langgraph.checkpoint.memory import MemorySaver

agent = create_agent(
    working_dir=".",
    model=model,
    checkpointer=MemorySaver(),
    tool_virtual_root=".",
    allow_shell_commands=True,
    max_iterations=20,
)
```

## 示例与文档

示例位于：

- `tutorials/examples/basic_agent_example.py`
- `tutorials/examples/plan_act_agent.py`
- `tutorials/examples/direct_answer_agent_example.py`
- `tutorials/examples/no_summary_like_agent_example.py`

更多说明见：

- `tutorials/klynx_tutorial.md`
- `tutorials/tutorials_examples_guide.md`
- `tutorials/README.md`
