agentao 0.2.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agentao-0.2.5/.env.example +22 -0
- agentao-0.2.5/.github/workflows/ci.yml +115 -0
- agentao-0.2.5/.gitignore +57 -0
- agentao-0.2.5/.python-version +1 -0
- agentao-0.2.5/CHANGELOG.md +126 -0
- agentao-0.2.5/CLAUDE.md +370 -0
- agentao-0.2.5/LICENSE +21 -0
- agentao-0.2.5/PKG-INFO +1041 -0
- agentao-0.2.5/README.md +981 -0
- agentao-0.2.5/README.zh.md +970 -0
- agentao-0.2.5/agentao/__init__.py +11 -0
- agentao-0.2.5/agentao/agent.py +955 -0
- agentao-0.2.5/agentao/agents/__init__.py +4 -0
- agentao-0.2.5/agentao/agents/definitions/codebase-investigator.md +14 -0
- agentao-0.2.5/agentao/agents/definitions/generalist.md +8 -0
- agentao-0.2.5/agentao/agents/manager.py +118 -0
- agentao-0.2.5/agentao/agents/tools.py +615 -0
- agentao-0.2.5/agentao/cancellation.py +51 -0
- agentao-0.2.5/agentao/cli.py +2219 -0
- agentao-0.2.5/agentao/context_manager.py +583 -0
- agentao-0.2.5/agentao/display.py +698 -0
- agentao-0.2.5/agentao/llm/__init__.py +5 -0
- agentao-0.2.5/agentao/llm/client.py +648 -0
- agentao-0.2.5/agentao/mcp/__init__.py +11 -0
- agentao-0.2.5/agentao/mcp/client.py +289 -0
- agentao-0.2.5/agentao/mcp/config.py +117 -0
- agentao-0.2.5/agentao/mcp/tool.py +88 -0
- agentao-0.2.5/agentao/permissions.py +232 -0
- agentao-0.2.5/agentao/plan/__init__.py +12 -0
- agentao-0.2.5/agentao/plan/controller.py +236 -0
- agentao-0.2.5/agentao/plan/prompt.py +104 -0
- agentao-0.2.5/agentao/plan/session.py +72 -0
- agentao-0.2.5/agentao/session.py +239 -0
- agentao-0.2.5/agentao/skills/__init__.py +5 -0
- agentao-0.2.5/agentao/skills/manager.py +331 -0
- agentao-0.2.5/agentao/tool_runner.py +373 -0
- agentao-0.2.5/agentao/tools/__init__.py +44 -0
- agentao-0.2.5/agentao/tools/agents.py +175 -0
- agentao-0.2.5/agentao/tools/ask_user.py +50 -0
- agentao-0.2.5/agentao/tools/base.py +113 -0
- agentao-0.2.5/agentao/tools/file_ops.py +382 -0
- agentao-0.2.5/agentao/tools/memory.py +472 -0
- agentao-0.2.5/agentao/tools/plan.py +96 -0
- agentao-0.2.5/agentao/tools/search.py +286 -0
- agentao-0.2.5/agentao/tools/shell.py +362 -0
- agentao-0.2.5/agentao/tools/skill.py +59 -0
- agentao-0.2.5/agentao/tools/todo.py +81 -0
- agentao-0.2.5/agentao/tools/web.py +267 -0
- agentao-0.2.5/agentao/transport/__init__.py +15 -0
- agentao-0.2.5/agentao/transport/base.py +55 -0
- agentao-0.2.5/agentao/transport/events.py +46 -0
- agentao-0.2.5/agentao/transport/null.py +23 -0
- agentao-0.2.5/agentao/transport/sdk.py +165 -0
- agentao-0.2.5/pyproject.toml +79 -0
- agentao-0.2.5/skills/skill-creator/LICENSE.txt +202 -0
- agentao-0.2.5/skills/skill-creator/SKILL.md +479 -0
- agentao-0.2.5/skills/skill-creator/agents/analyzer.md +274 -0
- agentao-0.2.5/skills/skill-creator/agents/comparator.md +202 -0
- agentao-0.2.5/skills/skill-creator/agents/grader.md +223 -0
- agentao-0.2.5/skills/skill-creator/assets/eval_review.html +146 -0
- agentao-0.2.5/skills/skill-creator/eval-viewer/generate_review.py +471 -0
- agentao-0.2.5/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- agentao-0.2.5/skills/skill-creator/references/schemas.md +430 -0
- agentao-0.2.5/skills/skill-creator/scripts/__init__.py +0 -0
- agentao-0.2.5/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- agentao-0.2.5/skills/skill-creator/scripts/generate_report.py +326 -0
- agentao-0.2.5/skills/skill-creator/scripts/improve_description.py +248 -0
- agentao-0.2.5/skills/skill-creator/scripts/package_skill.py +136 -0
- agentao-0.2.5/skills/skill-creator/scripts/quick_validate.py +103 -0
- agentao-0.2.5/skills/skill-creator/scripts/run_eval.py +310 -0
- agentao-0.2.5/skills/skill-creator/scripts/run_loop.py +332 -0
- agentao-0.2.5/skills/skill-creator/scripts/utils.py +47 -0
- agentao-0.2.5/tests/README.md +59 -0
- agentao-0.2.5/tests/__init__.py +0 -0
- agentao-0.2.5/tests/test_agentao_md.py +83 -0
- agentao-0.2.5/tests/test_agents_manager.py +206 -0
- agentao-0.2.5/tests/test_clear_resets_confirm.py +159 -0
- agentao-0.2.5/tests/test_context_manager.py +435 -0
- agentao-0.2.5/tests/test_date_in_prompt.py +97 -0
- agentao-0.2.5/tests/test_imports.py +52 -0
- agentao-0.2.5/tests/test_logging.py +103 -0
- agentao-0.2.5/tests/test_mcp_config.py +221 -0
- agentao-0.2.5/tests/test_mcp_tool.py +164 -0
- agentao-0.2.5/tests/test_memory_injection.py +74 -0
- agentao-0.2.5/tests/test_memory_management.py +100 -0
- agentao-0.2.5/tests/test_menu_confirmation.py +186 -0
- agentao-0.2.5/tests/test_microcompaction.py +109 -0
- agentao-0.2.5/tests/test_model_command.py +59 -0
- agentao-0.2.5/tests/test_multi_turn.py +38 -0
- agentao-0.2.5/tests/test_permissions.py +318 -0
- agentao-0.2.5/tests/test_plan_controller.py +268 -0
- agentao-0.2.5/tests/test_plan_mode_prompt.py +183 -0
- agentao-0.2.5/tests/test_plan_session.py +55 -0
- agentao-0.2.5/tests/test_plan_tools.py +99 -0
- agentao-0.2.5/tests/test_readchar_confirmation.py +187 -0
- agentao-0.2.5/tests/test_reliability_prompt.py +110 -0
- agentao-0.2.5/tests/test_session.py +219 -0
- agentao-0.2.5/tests/test_skill_integration.py +46 -0
- agentao-0.2.5/tests/test_skill_resources.py +59 -0
- agentao-0.2.5/tests/test_skills.py +67 -0
- agentao-0.2.5/tests/test_skills_manager.py +443 -0
- agentao-0.2.5/tests/test_skills_prompt.py +64 -0
- agentao-0.2.5/tests/test_status_pause.py +198 -0
- agentao-0.2.5/tests/test_subagent_routing.py +112 -0
- agentao-0.2.5/tests/test_tool_confirmation.py +122 -0
- agentao-0.2.5/tests/test_transport.py +140 -0
- agentao-0.2.5/uv.lock +4168 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# LLM Provider Configuration
|
|
2
|
+
|
|
3
|
+
# Default LLM Provider (optional, defaults to OPENAI)
|
|
4
|
+
# Determines which {PROVIDER}_API_KEY, {PROVIDER}_BASE_URL, {PROVIDER}_MODEL to use
|
|
5
|
+
# Examples: OPENAI, DEEPSEEK, GEMINI, ANTHROPIC
|
|
6
|
+
# LLM_PROVIDER=OPENAI
|
|
7
|
+
|
|
8
|
+
# API Key (required)
|
|
9
|
+
OPENAI_API_KEY=your-api-key-here
|
|
10
|
+
|
|
11
|
+
# Base URL (optional, for OpenAI-compatible endpoints)
|
|
12
|
+
# For OpenAI: leave empty or use https://api.openai.com/v1
|
|
13
|
+
# For other providers: use their base URL
|
|
14
|
+
# OPENAI_BASE_URL=https://api.openai.com/v1
|
|
15
|
+
|
|
16
|
+
# Model (optional, defaults to gpt-4-turbo-preview)
|
|
17
|
+
# For OpenAI: gpt-4-turbo-preview, gpt-4, gpt-3.5-turbo, etc.
|
|
18
|
+
# For Claude via OpenAI-compatible endpoints: claude-3-opus-20240229, claude-3-sonnet-20240229, etc.
|
|
19
|
+
# OPENAI_MODEL=gpt-4-turbo-preview
|
|
20
|
+
|
|
21
|
+
# LLM Temperature (0.0-2.0, default: 0.2, lower = more deterministic)
|
|
22
|
+
# LLM_TEMPERATURE=0.2
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
# ─────────────────────────────────────────────────────────────
|
|
11
|
+
# Job 1 · Unit tests across Python 3.10 / 3.11 / 3.12
|
|
12
|
+
# ─────────────────────────────────────────────────────────────
|
|
13
|
+
test:
|
|
14
|
+
name: Test · Python ${{ matrix.python-version }}
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
strategy:
|
|
17
|
+
fail-fast: false
|
|
18
|
+
matrix:
|
|
19
|
+
python-version: ["3.10", "3.11", "3.12"]
|
|
20
|
+
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
|
|
24
|
+
- name: Install uv
|
|
25
|
+
uses: astral-sh/setup-uv@v5
|
|
26
|
+
|
|
27
|
+
- name: Install Python ${{ matrix.python-version }}
|
|
28
|
+
run: uv python install ${{ matrix.python-version }}
|
|
29
|
+
|
|
30
|
+
- name: Install dependencies
|
|
31
|
+
run: uv sync --python ${{ matrix.python-version }}
|
|
32
|
+
|
|
33
|
+
- name: Run tests
|
|
34
|
+
run: uv run --python ${{ matrix.python-version }} python -m pytest tests/ -v --tb=short
|
|
35
|
+
|
|
36
|
+
# ─────────────────────────────────────────────────────────────
|
|
37
|
+
# Job 2 · Build wheel + sdist, verify metadata with twine
|
|
38
|
+
# ─────────────────────────────────────────────────────────────
|
|
39
|
+
build:
|
|
40
|
+
name: Build distribution
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
needs: test
|
|
43
|
+
|
|
44
|
+
steps:
|
|
45
|
+
- uses: actions/checkout@v4
|
|
46
|
+
|
|
47
|
+
- name: Install uv
|
|
48
|
+
uses: astral-sh/setup-uv@v5
|
|
49
|
+
|
|
50
|
+
- name: Build wheel and sdist
|
|
51
|
+
run: uv build
|
|
52
|
+
|
|
53
|
+
- name: Check dist metadata with twine
|
|
54
|
+
run: uvx twine check dist/*
|
|
55
|
+
|
|
56
|
+
- name: Upload dist artifacts
|
|
57
|
+
uses: actions/upload-artifact@v4
|
|
58
|
+
with:
|
|
59
|
+
name: dist
|
|
60
|
+
path: dist/
|
|
61
|
+
retention-days: 7
|
|
62
|
+
|
|
63
|
+
# ─────────────────────────────────────────────────────────────
|
|
64
|
+
# Job 3 · Install from wheel, verify imports + CLI entry point
|
|
65
|
+
# ─────────────────────────────────────────────────────────────
|
|
66
|
+
smoke:
|
|
67
|
+
name: Smoke · Python ${{ matrix.python-version }}
|
|
68
|
+
runs-on: ubuntu-latest
|
|
69
|
+
needs: build
|
|
70
|
+
strategy:
|
|
71
|
+
fail-fast: false
|
|
72
|
+
matrix:
|
|
73
|
+
python-version: ["3.10", "3.11", "3.12"]
|
|
74
|
+
|
|
75
|
+
steps:
|
|
76
|
+
- name: Download dist artifacts
|
|
77
|
+
uses: actions/download-artifact@v4
|
|
78
|
+
with:
|
|
79
|
+
name: dist
|
|
80
|
+
path: dist/
|
|
81
|
+
|
|
82
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
83
|
+
uses: actions/setup-python@v5
|
|
84
|
+
with:
|
|
85
|
+
python-version: ${{ matrix.python-version }}
|
|
86
|
+
|
|
87
|
+
- name: Install wheel into a clean environment
|
|
88
|
+
run: pip install dist/*.whl
|
|
89
|
+
|
|
90
|
+
- name: Import check — package and public API
|
|
91
|
+
run: |
|
|
92
|
+
python -c "
|
|
93
|
+
import agentao
|
|
94
|
+
print('version:', agentao.__version__)
|
|
95
|
+
from agentao import Agentao, SkillManager
|
|
96
|
+
print('Public API OK')
|
|
97
|
+
"
|
|
98
|
+
|
|
99
|
+
- name: Import check — CLI entry point importable
|
|
100
|
+
run: python -c "from agentao.cli import entrypoint; print('CLI entrypoint OK')"
|
|
101
|
+
|
|
102
|
+
- name: Verify agentao command is on PATH
|
|
103
|
+
run: python -c "import shutil; assert shutil.which('agentao'), 'agentao not found on PATH'; print('agentao on PATH OK')"
|
|
104
|
+
|
|
105
|
+
- name: Verify bundled skills are discoverable after install
|
|
106
|
+
run: |
|
|
107
|
+
python -c "
|
|
108
|
+
from pathlib import Path
|
|
109
|
+
import agentao.skills.manager as m
|
|
110
|
+
bundled = m._BUNDLED_SKILLS_DIR
|
|
111
|
+
assert bundled.exists(), f'Bundled skills dir missing: {bundled}'
|
|
112
|
+
skills = [d.name for d in bundled.iterdir() if d.is_dir()]
|
|
113
|
+
assert 'skill-creator' in skills, f'skill-creator not found in {bundled}: {skills}'
|
|
114
|
+
print('Bundled skills OK:', skills)
|
|
115
|
+
"
|
agentao-0.2.5/.gitignore
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Python-generated files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
*.egg-info/
|
|
20
|
+
.installed.cfg
|
|
21
|
+
*.egg
|
|
22
|
+
|
|
23
|
+
# Virtual environments
|
|
24
|
+
venv/
|
|
25
|
+
ENV/
|
|
26
|
+
env/
|
|
27
|
+
.venv
|
|
28
|
+
|
|
29
|
+
# IDEs
|
|
30
|
+
.vscode/
|
|
31
|
+
.idea/
|
|
32
|
+
*.swp
|
|
33
|
+
*.swo
|
|
34
|
+
*~
|
|
35
|
+
|
|
36
|
+
# Environment variables
|
|
37
|
+
.env
|
|
38
|
+
|
|
39
|
+
# ChatAgent specific
|
|
40
|
+
.chatagent_memory.json
|
|
41
|
+
.agentao_memory.json
|
|
42
|
+
chatagent.log
|
|
43
|
+
*.log
|
|
44
|
+
.chatagent/
|
|
45
|
+
.agentao/
|
|
46
|
+
examples/
|
|
47
|
+
workspace/
|
|
48
|
+
|
|
49
|
+
# OS
|
|
50
|
+
.DS_Store
|
|
51
|
+
Thumbs.db
|
|
52
|
+
|
|
53
|
+
# Temporary development files
|
|
54
|
+
scratch_*.py
|
|
55
|
+
HIDDEN_*.md
|
|
56
|
+
*_DRAFT.md
|
|
57
|
+
*.tmp
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Agentao are documented here.
|
|
4
|
+
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## [0.2.3] — 2026-04-06
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Plan mode v2** — tool-driven save/finalize workflow
|
|
12
|
+
- `plan_save(content)` tool: persists a draft and returns a `draft_id`
|
|
13
|
+
- `plan_finalize(draft_id)` tool: triggers the approval prompt; stale IDs are rejected
|
|
14
|
+
- Approval prompt shows the full plan before asking "Execute this plan? [y/N]"
|
|
15
|
+
- One-shot `consume_approval_request()` flag prevents repeated approval prompts
|
|
16
|
+
- Auto-save fallback skipped when a draft is already finalized
|
|
17
|
+
- `agentao/plan/` sub-package: `session.py` (3-state FSM), `controller.py` (single exit path), `prompt.py` (mandatory turn protocol)
|
|
18
|
+
- 44 new tests covering FSM transitions, lifecycle, tools, and prompt structure
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- Plan approval prompt now only appears after the model explicitly calls `plan_finalize`
|
|
22
|
+
- `/plan save` removed as a CLI command; saving is now model-driven via the `plan_save` tool
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
- Finalized drafts can no longer be overwritten by the auto-save fallback path
|
|
26
|
+
|
|
27
|
+
### Packaging
|
|
28
|
+
- Added MIT `LICENSE` file (Bo Jin)
|
|
29
|
+
- Heavy optional dependencies (`pymupdf`, `pdfplumber`, `pandas`, `openpyxl`, `Pillow`, `pycryptodome`, `google-genai`) moved to optional extras: `pdf`, `excel`, `image`, `crypto`, `google`; `full` installs everything
|
|
30
|
+
- `skills/` and `workspace/` excluded from both wheel and sdist
|
|
31
|
+
- `requires-python` lowered from `>=3.12` to `>=3.10`
|
|
32
|
+
- Added `authors`, `license`, `keywords`, `classifiers`, `[project.urls]`
|
|
33
|
+
- Version is now defined once in `agentao/__init__.py` and read dynamically by hatchling
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## [0.2.1] — 2026-03-xx
|
|
38
|
+
|
|
39
|
+
### Added
|
|
40
|
+
- **Permission mode system** — three named presets: `read-only`, `workspace-write` (default), `full-access`
|
|
41
|
+
- `/mode` command to switch and persist permission mode to `.agentao/settings.json`
|
|
42
|
+
- Plan mode enforced via `PLAN` permission preset (no writes, no dangerous shell)
|
|
43
|
+
- Mode restored exactly on `/plan implement` or `/plan clear`
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
- Tool confirmation now driven by the active permission mode rather than per-tool flags
|
|
47
|
+
- `/clear` resets permission escalation (`allow_all_tools`) back to False
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## [0.2.0] — 2026-03-xx
|
|
52
|
+
|
|
53
|
+
### Added
|
|
54
|
+
- **Plan mode** — `/plan` enters a read-only research-and-draft workflow; agent proposes a structured Markdown plan before any mutations
|
|
55
|
+
- **Display engine v2** — semantic tool headers (`→ read`, `← edit`, `$ shell`, `✱ search`), buffered output, tail-biased truncation, diff rendering, warning consolidation, live elapsed timer
|
|
56
|
+
- **Background agent dashboard** — `/agents`, `/agent dashboard`, `/agent status`
|
|
57
|
+
- **Transport protocol** — decoupled runtime from UI via `EventType` stream
|
|
58
|
+
|
|
59
|
+
### Fixed
|
|
60
|
+
- Streaming fallback, thinking handler scope, on_max_iterations guard
|
|
61
|
+
- Buffer all shell output; robust `\r`/ANSI/CRLF handling
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## [0.1.11] — 2026-02-xx
|
|
66
|
+
|
|
67
|
+
### Added
|
|
68
|
+
- **Three-tier context compression** — microcompaction (55% usage) + LLM summarization (65%) + circuit breaker after 3 failures
|
|
69
|
+
- Structured 9-section LLM summary; partial compaction keeps last 20 messages verbatim
|
|
70
|
+
- Three-tier overflow recovery on context-too-long API error
|
|
71
|
+
- **Three-tier token counting** — real `prompt_tokens` from API → `count_tokens` API → local estimator (tiktoken / CJK heuristic)
|
|
72
|
+
- `/context` command with token breakdown by component
|
|
73
|
+
- Background agent push via `CancellationToken`
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## [0.1.8] — 2026-01-xx
|
|
78
|
+
|
|
79
|
+
### Added
|
|
80
|
+
- **Sub-agent system** — foreground and background sub-agents with parent context injection and stats footer
|
|
81
|
+
- `/agent bg <name> <task>` for background execution
|
|
82
|
+
- Tool output file saving, head+tail truncation, per-line length limit
|
|
83
|
+
- `/new` command; auto `max_completion_tokens`; session lifecycle hooks
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## [0.1.5] — 2025-12-xx
|
|
88
|
+
|
|
89
|
+
### Added
|
|
90
|
+
- **Task checklist** (`todo_write`) — LLM-managed task list injected into system prompt; visible via `/todos`
|
|
91
|
+
- **MCP (Model Context Protocol)** support — stdio and SSE transports; `mcp_*` tool registration
|
|
92
|
+
- **Memory management** — persistent `.agentao_memory.json`; `save_memory`, `search_memory`, `delete_memory` tools; `/memory` commands
|
|
93
|
+
- **Permission system** — per-tool confirmation with single-key menu; session escalation with **2** (Yes to all)
|
|
94
|
+
- Cognitive Resonance — automatic memory recall with injection confirmation before each response
|
|
95
|
+
- Session save/resume (`/sessions`)
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## [0.1.1] — 2025-11-xx
|
|
100
|
+
|
|
101
|
+
### Added
|
|
102
|
+
- Renamed to **Agentao** (Agent + Tao)
|
|
103
|
+
- Gemini provider support (`google-genai`)
|
|
104
|
+
- `web_fetch` with automatic crawl4ai fallback for JS-heavy pages
|
|
105
|
+
- `/confirm`, `/stream`, `/tools`, `/provider` commands
|
|
106
|
+
- Sub-agent system (early version)
|
|
107
|
+
- `ask_user` tool for LLM-initiated clarification
|
|
108
|
+
- `-p` / `--print` flag for non-interactive print mode
|
|
109
|
+
- Multi-line paste via `prompt_toolkit`; single-key confirmation via `readchar`
|
|
110
|
+
|
|
111
|
+
### Changed
|
|
112
|
+
- System prompt: reliability principles, structured reasoning (Action / Expectation / If wrong), operational guidelines
|
|
113
|
+
- Context management: `ContextManager`, pinned messages, tool result truncation
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## [0.1.0] — 2025-10-xx
|
|
118
|
+
|
|
119
|
+
### Added
|
|
120
|
+
- Initial release as **ChatAgent**
|
|
121
|
+
- CLI chat loop with OpenAI-compatible API
|
|
122
|
+
- Tool system: `read_file`, `write_file`, `replace`, `glob`, `grep`, `run_shell_command`, `web_fetch`, `google_web_search`, `save_memory`
|
|
123
|
+
- Skills system — auto-discovery from `skills/` with YAML frontmatter
|
|
124
|
+
- `AGENTAO.md` auto-loading for project-specific instructions
|
|
125
|
+
- Current date injected as `<system-reminder>`
|
|
126
|
+
- Complete LLM interaction logging to `agentao.log`
|
agentao-0.2.5/CLAUDE.md
ADDED
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Package Management
|
|
6
|
+
|
|
7
|
+
**Always use `uv` for package management**, not pip:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Install dependencies
|
|
11
|
+
uv sync
|
|
12
|
+
|
|
13
|
+
# Add a new dependency
|
|
14
|
+
uv add package-name
|
|
15
|
+
|
|
16
|
+
# Run Python scripts
|
|
17
|
+
uv run python script.py
|
|
18
|
+
|
|
19
|
+
# Run the CLI
|
|
20
|
+
uv run agentao
|
|
21
|
+
# or
|
|
22
|
+
uv run python main.py
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Running and Testing
|
|
26
|
+
|
|
27
|
+
### Start the Agent
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Quick start
|
|
31
|
+
./run.sh
|
|
32
|
+
|
|
33
|
+
# Or directly
|
|
34
|
+
uv run agentao
|
|
35
|
+
|
|
36
|
+
# Or via Python
|
|
37
|
+
uv run python main.py
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Run Tests
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Run all tests with pytest
|
|
44
|
+
uv run python -m pytest tests/
|
|
45
|
+
|
|
46
|
+
# Run a specific test file
|
|
47
|
+
uv run python tests/test_imports.py
|
|
48
|
+
uv run python tests/test_tool_confirmation.py
|
|
49
|
+
uv run python tests/test_readchar_confirmation.py
|
|
50
|
+
uv run python tests/test_date_in_prompt.py
|
|
51
|
+
|
|
52
|
+
# All test files are in tests/ directory
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Configuration
|
|
56
|
+
|
|
57
|
+
Copy and edit `.env` from `.env.example`:
|
|
58
|
+
```bash
|
|
59
|
+
cp .env.example .env
|
|
60
|
+
# Edit .env with your API key and settings
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Required: `OPENAI_API_KEY`
|
|
64
|
+
Optional: `OPENAI_BASE_URL`, `OPENAI_MODEL`
|
|
65
|
+
|
|
66
|
+
## Architecture
|
|
67
|
+
|
|
68
|
+
### Three-Layer Design
|
|
69
|
+
|
|
70
|
+
Agentao uses a **Tool-Agent-CLI** architecture:
|
|
71
|
+
|
|
72
|
+
1. **CLI Layer** (`cli.py`): User interface with Rich, handles commands, manages session state (like `allow_all_tools`)
|
|
73
|
+
2. **Agent Layer** (`agent.py`): Orchestrates LLM, tools, skills, and conversation history
|
|
74
|
+
3. **Tool Layer** (`tools/`): Individual tool implementations following the Tool base class
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
User → CLI → Agent → LLM + Tools
|
|
78
|
+
↓
|
|
79
|
+
SkillManager (loads from skills/)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Tool System
|
|
83
|
+
|
|
84
|
+
All tools inherit from `Tool` base class (`tools/base.py`):
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
class MyTool(Tool):
|
|
88
|
+
@property
|
|
89
|
+
def name(self) -> str:
|
|
90
|
+
return "my_tool"
|
|
91
|
+
|
|
92
|
+
@property
|
|
93
|
+
def description(self) -> str:
|
|
94
|
+
return "Description for LLM"
|
|
95
|
+
|
|
96
|
+
@property
|
|
97
|
+
def parameters(self) -> Dict[str, Any]:
|
|
98
|
+
return {...} # JSON Schema
|
|
99
|
+
|
|
100
|
+
@property
|
|
101
|
+
def requires_confirmation(self) -> bool:
|
|
102
|
+
return False # True for dangerous operations
|
|
103
|
+
|
|
104
|
+
def execute(self, **kwargs) -> str:
|
|
105
|
+
return "Result"
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Tool Registration**: Tools are registered in `agent.py::_register_tools()`. The `ToolRegistry` converts them to OpenAI function calling format.
|
|
109
|
+
|
|
110
|
+
**Tool Confirmation**: Tools with `requires_confirmation=True` (Shell, Web, File Writing) pause execution and prompt user via `confirmation_callback` passed from CLI.
|
|
111
|
+
|
|
112
|
+
**Tools requiring confirmation:**
|
|
113
|
+
- `run_shell_command` - Shell command execution
|
|
114
|
+
- `web_fetch` - Fetch web content
|
|
115
|
+
- `google_web_search` - Web search
|
|
116
|
+
- `write_file` - File writing/overwriting (prevents data loss)
|
|
117
|
+
|
|
118
|
+
### Skills System
|
|
119
|
+
|
|
120
|
+
**Dynamic Loading**: Skills are auto-discovered from `skills/` directory. Each subdirectory contains:
|
|
121
|
+
- `SKILL.md` - Main file with YAML frontmatter (`name:`, `description:`)
|
|
122
|
+
- `reference/*.md` (optional) - Additional documentation loaded on-demand
|
|
123
|
+
|
|
124
|
+
**Skill Manager** (`skills/manager.py`):
|
|
125
|
+
- Parses YAML frontmatter from SKILL.md files
|
|
126
|
+
- Maintains `available_skills` dict (all skills)
|
|
127
|
+
- Maintains `active_skills` dict (currently activated)
|
|
128
|
+
- Injects active skill context into system prompt
|
|
129
|
+
|
|
130
|
+
**Activation**: Use `activate_skill` tool or `/skills` command. Active skills add their documentation to the system prompt.
|
|
131
|
+
|
|
132
|
+
### System Prompt Composition
|
|
133
|
+
|
|
134
|
+
The system prompt is dynamically built in `agent.py::_build_system_prompt()`:
|
|
135
|
+
|
|
136
|
+
1. **AGENTAO.md** (if exists in cwd) - Project-specific instructions
|
|
137
|
+
2. **Agent Instructions** - Base Agentao capabilities
|
|
138
|
+
3. **Current Date/Time** - Auto-injected: `YYYY-MM-DD HH:MM:SS (Day)`
|
|
139
|
+
4. **Available Skills** - List with descriptions
|
|
140
|
+
5. **Active Skills Context** - Full documentation of activated skills
|
|
141
|
+
|
|
142
|
+
This composition happens on every `chat()` call to keep skills context fresh.
|
|
143
|
+
|
|
144
|
+
### Conversation Flow
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
# agent.py::chat()
|
|
148
|
+
1. User message added to self.messages
|
|
149
|
+
2. System prompt built (includes AGENTAO.md, date, skills)
|
|
150
|
+
3. LLM called with messages + tools
|
|
151
|
+
4. Loop (max 100 iterations):
|
|
152
|
+
a. If tool_calls: execute each tool
|
|
153
|
+
- Check requires_confirmation
|
|
154
|
+
- Call confirmation_callback if needed
|
|
155
|
+
- Execute tool or cancel based on response
|
|
156
|
+
b. Add tool results to messages
|
|
157
|
+
c. Call LLM again with updated messages
|
|
158
|
+
d. If no tool_calls: return final response
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Logging System
|
|
162
|
+
|
|
163
|
+
**Complete LLM interaction logging** to `agentao.log`:
|
|
164
|
+
- Every request/response (full content, no truncation)
|
|
165
|
+
- All tool calls with formatted JSON arguments
|
|
166
|
+
- Tool results
|
|
167
|
+
- Token usage
|
|
168
|
+
- Timestamps
|
|
169
|
+
|
|
170
|
+
Logger is in `llm/client.py`. To debug tool execution or LLM behavior, check this log file.
|
|
171
|
+
|
|
172
|
+
### CLI Commands
|
|
173
|
+
|
|
174
|
+
User commands (start with `/`):
|
|
175
|
+
- `/clear` - Clears history AND resets `allow_all_tools` to False
|
|
176
|
+
- `/reset-confirm` - Resets `allow_all_tools` only (keeps history)
|
|
177
|
+
- `/status` - Shows message count, model, active skills, confirmation mode
|
|
178
|
+
- `/model [name]` - List models or switch to specified model
|
|
179
|
+
- `/skills` - List available/active skills
|
|
180
|
+
- `/memory` - Show saved memories
|
|
181
|
+
- `/mcp` - List MCP servers and tools
|
|
182
|
+
- `/help` - Show help
|
|
183
|
+
|
|
184
|
+
Session state `allow_all_tools` persists across tool confirmations within one session.
|
|
185
|
+
|
|
186
|
+
### MCP (Model Context Protocol) System
|
|
187
|
+
|
|
188
|
+
Agentao supports connecting to external MCP servers that provide additional tools.
|
|
189
|
+
|
|
190
|
+
**Configuration**: `.agentao/mcp.json` (project) and `~/.agentao/mcp.json` (global):
|
|
191
|
+
```json
|
|
192
|
+
{
|
|
193
|
+
"mcpServers": {
|
|
194
|
+
"server-name": {
|
|
195
|
+
"command": "npx",
|
|
196
|
+
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path"],
|
|
197
|
+
"env": { "TOKEN": "$MY_TOKEN" },
|
|
198
|
+
"trust": false
|
|
199
|
+
},
|
|
200
|
+
"remote-server": {
|
|
201
|
+
"url": "https://api.example.com/sse",
|
|
202
|
+
"headers": { "Authorization": "Bearer $API_KEY" },
|
|
203
|
+
"timeout": 30
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**Transport types**: `command` (stdio subprocess) or `url` (SSE).
|
|
210
|
+
|
|
211
|
+
**Tool naming**: MCP tools are registered as `mcp_{server}_{tool}` (e.g. `mcp_github_create_issue`).
|
|
212
|
+
|
|
213
|
+
**Architecture**:
|
|
214
|
+
```
|
|
215
|
+
.agentao/mcp.json → McpConfig → McpClientManager → McpClient (per server)
|
|
216
|
+
↓
|
|
217
|
+
list_tools() / call_tool()
|
|
218
|
+
↓
|
|
219
|
+
McpTool(Tool) → ToolRegistry
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
**Key files**:
|
|
223
|
+
- `agentao/mcp/config.py` - Config loading, env var expansion
|
|
224
|
+
- `agentao/mcp/client.py` - McpClient (single server), McpClientManager (multi-server)
|
|
225
|
+
- `agentao/mcp/tool.py` - McpTool wrapper adapting MCP tools to Tool base class
|
|
226
|
+
|
|
227
|
+
**Async bridge**: MCP SDK is async-only; McpClientManager uses a dedicated event loop with `run_until_complete()` to bridge into sync Agentao code.
|
|
228
|
+
|
|
229
|
+
**CLI**: `/mcp list`, `/mcp add <name> <command|url>`, `/mcp remove <name>`
|
|
230
|
+
|
|
231
|
+
## Adding New Components
|
|
232
|
+
|
|
233
|
+
### Adding a Tool
|
|
234
|
+
|
|
235
|
+
1. Create tool class in `agentao/tools/<module>.py`
|
|
236
|
+
2. Implement `Tool` interface (name, description, parameters, execute)
|
|
237
|
+
3. Set `requires_confirmation=True` if dangerous:
|
|
238
|
+
- Shell commands (arbitrary execution)
|
|
239
|
+
- Web access (network requests, privacy)
|
|
240
|
+
- File writing/overwriting (data loss risk)
|
|
241
|
+
- File deletion (irreversible)
|
|
242
|
+
4. Register in `agent.py::_register_tools()`:
|
|
243
|
+
```python
|
|
244
|
+
from .tools.mymodule import MyTool
|
|
245
|
+
# In _register_tools():
|
|
246
|
+
tools_to_register.append(MyTool())
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Adding a Skill
|
|
250
|
+
|
|
251
|
+
1. Create directory: `skills/my-skill/`
|
|
252
|
+
2. Create `SKILL.md` with YAML frontmatter:
|
|
253
|
+
```yaml
|
|
254
|
+
---
|
|
255
|
+
name: my-skill
|
|
256
|
+
description: Use when... (trigger conditions)
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
# Skill Documentation
|
|
260
|
+
...
|
|
261
|
+
```
|
|
262
|
+
3. (Optional) Add `reference/*.md` files for on-demand loading
|
|
263
|
+
4. Restart agent - skill auto-discovered
|
|
264
|
+
|
|
265
|
+
Reference files are loaded only when skill is activated (saves memory).
|
|
266
|
+
|
|
267
|
+
## Important Patterns
|
|
268
|
+
|
|
269
|
+
### Confirmation Callback Pattern
|
|
270
|
+
|
|
271
|
+
CLI creates callback and passes to Agent:
|
|
272
|
+
```python
|
|
273
|
+
# cli.py
|
|
274
|
+
def confirm_tool_execution(self, name, desc, args) -> bool:
|
|
275
|
+
# Show menu, get user choice
|
|
276
|
+
# Return True/False
|
|
277
|
+
|
|
278
|
+
self.agent = Agentao(
|
|
279
|
+
confirmation_callback=self.confirm_tool_execution
|
|
280
|
+
)
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
Agent checks before tool execution:
|
|
284
|
+
```python
|
|
285
|
+
# agent.py
|
|
286
|
+
if tool.requires_confirmation and self.confirmation_callback:
|
|
287
|
+
confirmed = self.confirmation_callback(name, desc, args)
|
|
288
|
+
if not confirmed:
|
|
289
|
+
result = "Tool execution cancelled by user"
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Single-Key Input
|
|
293
|
+
|
|
294
|
+
Uses `readchar` library for instant response:
|
|
295
|
+
```python
|
|
296
|
+
import readchar
|
|
297
|
+
key = readchar.readkey() # No Enter needed
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
Supports: `1`, `2`, `3`, `Esc`, `Ctrl+C`. Invalid keys are silently ignored.
|
|
301
|
+
|
|
302
|
+
### Memory System
|
|
303
|
+
|
|
304
|
+
Persistent JSON storage in `.agentao_memory.json` (gitignored):
|
|
305
|
+
```python
|
|
306
|
+
# tools/memory.py
|
|
307
|
+
{"memories": [{"key": "...", "value": "...", "tags": [...], "timestamp": "..."}]}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
**Available Tools:**
|
|
311
|
+
- `save_memory` - Save/update memories
|
|
312
|
+
- `search_memory` - Search by keyword
|
|
313
|
+
- `delete_memory` - Delete specific memory
|
|
314
|
+
- `clear_all_memories` - Clear all memories
|
|
315
|
+
- `filter_memory_by_tag` - Filter by tag
|
|
316
|
+
|
|
317
|
+
**CLI Commands:**
|
|
318
|
+
- `/memory` or `/memory list` - List all memories
|
|
319
|
+
- `/memory search <query>` - Search memories
|
|
320
|
+
- `/memory tag <tag>` - Filter by tag
|
|
321
|
+
- `/memory delete <key>` - Delete specific memory
|
|
322
|
+
- `/memory clear` - Clear all (with confirmation)
|
|
323
|
+
|
|
324
|
+
See `docs/features/memory-management.md` for detailed documentation.
|
|
325
|
+
|
|
326
|
+
## File Organization
|
|
327
|
+
|
|
328
|
+
```
|
|
329
|
+
agentao/
|
|
330
|
+
├── agentao/ # Main package
|
|
331
|
+
│ ├── agent.py # Core orchestration
|
|
332
|
+
│ ├── cli.py # CLI interface with Rich
|
|
333
|
+
│ ├── llm/
|
|
334
|
+
│ │ └── client.py # OpenAI client wrapper
|
|
335
|
+
│ ├── tools/ # Tool implementations
|
|
336
|
+
│ │ ├── base.py # Tool base class + registry
|
|
337
|
+
│ │ ├── file_ops.py # Read, write, edit, list
|
|
338
|
+
│ │ ├── search.py # Glob, grep
|
|
339
|
+
│ │ ├── shell.py # Shell execution
|
|
340
|
+
│ │ ├── web.py # Fetch, search
|
|
341
|
+
│ │ ├── memory.py # Persistent memory
|
|
342
|
+
│ │ ├── agents.py # Helper agents
|
|
343
|
+
│ │ └── skill.py # Skill activation
|
|
344
|
+
│ ├── mcp/ # MCP (Model Context Protocol) support
|
|
345
|
+
│ │ ├── config.py # Config loading + env var expansion
|
|
346
|
+
│ │ ├── client.py # McpClient + McpClientManager
|
|
347
|
+
│ │ └── tool.py # McpTool wrapper for Tool interface
|
|
348
|
+
│ └── skills/
|
|
349
|
+
│ └── manager.py # Skill loading + management
|
|
350
|
+
├── skills/ # Skill definitions (SKILL.md files)
|
|
351
|
+
├── tests/ # Test files (test_*.py)
|
|
352
|
+
├── docs/ # Documentation
|
|
353
|
+
│ ├── features/ # Feature documentation
|
|
354
|
+
│ ├── updates/ # Update logs
|
|
355
|
+
│ ├── implementation/ # Technical implementation details
|
|
356
|
+
│ └── dev-notes/ # Development notes (archived)
|
|
357
|
+
├── CLAUDE.md # Claude Code guidance
|
|
358
|
+
├── AGENTAO.md # Project-specific instructions
|
|
359
|
+
└── main.py # Entry point
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
## Key Dependencies
|
|
363
|
+
|
|
364
|
+
- `openai` - LLM client (OpenAI-compatible APIs)
|
|
365
|
+
- `rich` - CLI interface (markdown, panels, prompts)
|
|
366
|
+
- `readchar` - Single-key input (no Enter needed)
|
|
367
|
+
- `httpx` - HTTP client for web tools
|
|
368
|
+
- `beautifulsoup4` - HTML parsing
|
|
369
|
+
- `python-dotenv` - Environment configuration
|
|
370
|
+
- `mcp` - Model Context Protocol client SDK
|