AI coding assistant with pluggable tools and token tracking, built on OpenHands SDK
Project description
token-wise-agent
Кастомный агент для написания кода, построенный на OpenHands SDK.
Цель дипломной работы — исследовать, как кастомные инструменты сокращают количество API-вызовов и расход токенов при работе на бенчмарке SWE-bench.
Архитектура
agent/cli.py ← CLI entry point (twa)
└── LocalConversation (OpenHands SDK)
├── Agent + system_prompt.j2 ← кастомный системный промпт
│ └── LLM (litellm → Anthropic / OpenAI / любой провайдер)
├── BashTool ← кастомный: stateless subprocess
├── GlobTool ← кастомный: поиск файлов по glob-паттерну
├── GrepTool ← кастомный: regex-поиск с контекстом
├── SmartReaderTool ← кастомный: чтение файла с диапазоном строк и контекстом
├── SmartEditorTool ← кастомный: редактирование файлов (replace/insert/create/delete/undo)
├── SubmitTool ← кастомный: сигнал завершения задачи (SWE-bench режим)
└── ThinkTool ← SDK built-in: внутренние размышления
token-wise-agent/
├── agent/
│ ├── cli.py # CLI entry point
│ ├── config.py # Загрузка конфига (.env + YAML + CLI)
│ ├── agent_tracker.py # Трекинг метрик агента (токены, стоимость, вызовы)
│ ├── trajectory.py # Сохранение траектории в .traj.json
│ ├── configs/
│ │ ├── agent_config.yaml # SWE-bench режим: промпты, tools, step_limit
│ │ ├── agent_config_user.yaml# Интерактивный режим
│ │ └── pricing.yaml # Стоимость токенов по моделям
│ ├── prompts/
│ │ ├── system_prompt.j2 # Промпт для SWE-bench режима
│ │ └── system_prompt_user.j2 # Промпт для интерактивного режима
│ └── tools/
│ ├── bash.py
│ ├── bash_session.py
│ ├── glob.py
│ ├── grep.py
│ ├── smart_reader.py
│ ├── smart_editor.py
│ ├── submit.py
│ └── tree.py # Авто-инъекция структуры репозитория
├── benchmarks/
│ ├── run_benchmark.py # SWE-Bench-style раннер
│ └── tasks/ # 10 задач с багами и тестами
├── tests/
│ └── test_tools.py
├── Dockerfile # Образ для запуска агента в изоляции
└── .env.example
Установка
Через pip (рекомендуется)
pip install token-wise-agent
twa edit # настройка API ключа
twa # запуск
Для разработки
Требуется uv.
git clone <repo-url>
cd token-wise-agent
uv sync
cp .env.example .env
# Вставьте API ключ в .env
Использование
Интерактивный режим
twa # запустить интерактивный чат
twa -i --working-dir /path/to/project # другая рабочая директория
В интерактивном режиме доступны команды:
| Команда | Действие |
|---|---|
/confirm |
Переключиться в режим подтверждений (агент спрашивает перед каждым tool call) |
/auto |
Вернуться в автоматический режим |
exit / Ctrl+C |
Выйти |
В режиме подтверждений: Enter — одобрить действие, любой текст — отклонить и передать агенту как причину.
Одноразовый режим (SWE-bench)
twa "Fix the failing tests in tests/" # запустить агента на задаче
twa --quiet "задача" # без вывода агента
twa --model anthropic/claude-opus-4.7 "задача"
twa --working-dir /path/to/project "задача"
twa --list-tools # список инструментов из конфига
Редактирование конфигурации
twa edit # редактировать .env (API ключ, модель)
twa edit config # редактировать agent_config_user.yaml
Конфигурация
Три источника конфигурации с чётким разделением:
~/.config/token-wise-agent/.env — секреты и подключение
| Переменная | Описание |
|---|---|
AGENT_API_KEY |
API ключ |
AGENT_BASE_URL |
Кастомный API endpoint (для OpenAI-совместимых сервисов) |
AGENT_MODEL |
litellm model ID (например anthropic/claude-sonnet-4-6) |
~/.config/token-wise-agent/agent_config_user.yaml — поведение агента
agent:
system_template: "system_prompt_user.j2"
llm_params:
temperature: 0.5
step_limit: 50
tools:
- think
- bash
- glob
- grep
- smart_reader
- smart_editor
Редактируется через twa edit config. Два готовых конфига в пакете:
agent_config.yaml— SWE-bench режим (step_limit: 30,temperature: 0.0, включёнsubmit)agent_config_user.yaml— интерактивный режим (step_limit: 50,temperature: 0.5)
agent/configs/pricing.yaml — стоимость токенов
# Цена за миллион токенов (USD)
anthropic/claude-sonnet-4-6:
input: 1.90
output: 9.54
anthropic/claude-opus-4.7:
input: 6.10
output: 30.49
Используется для подсчёта стоимости и передаётся в LiteLLM. Добавьте новую модель — стоимость подхватится автоматически.
CLI аргументы
| Аргумент | Описание |
|---|---|
-i / --interactive |
Запустить интерактивный режим |
--model |
Переопределить модель из .env |
--max-steps |
Переопределить step_limit из YAML |
--working-dir |
Рабочая директория (по умолчанию .) |
--quiet |
Подавить вывод агента |
--agent-config |
Путь к альтернативному YAML конфигу |
Инструменты
| Имя | Источник | Описание |
|---|---|---|
bash |
Кастомный | Stateless subprocess — каждый вызов независим |
bash_session |
Обёртка над TerminalTool | Персистентная bash-сессия (состояние между вызовами) |
glob |
Кастомный | Поиск файлов по glob-паттерну (сортировка по mtime) |
grep |
Кастомный | Regex-поиск по файлам с N строками контекста |
smart_reader |
Кастомный | Чтение файла: диапазон строк, контекст вокруг строки, авто-truncation |
smart_editor |
Кастомный | Редактирование файлов: replace, insert, create, delete, undo |
submit |
Кастомный | Сигнал завершения — останавливает агента (SWE-bench режим) |
think |
SDK built-in | Внутренние размышления перед действием |
Алиасы инструментов. Если модель вызывает
read_file,read_files,view_fileилиview— они прозрачно перенаправляются наsmart_readerбез лишних ошибок и потери шагов.
Бенчмарк
10 SWE-Bench-style задач. Структура каждой задачи:
task_XXX/
├── issue.md — описание бага
├── src/ — код с багом
├── tests/ — тесты (видны агенту)
└── gold_tests/ — золотые тесты (скрыты, запускаются после submit)
Локальный запуск
uv run python benchmarks/run_benchmark.py # все задачи
uv run python benchmarks/run_benchmark.py task_001 # одна задача
uv run python benchmarks/run_benchmark.py --quiet task_001
uv run python benchmarks/run_benchmark.py --model anthropic/claude-opus-4.7 task_001
uv run python benchmarks/run_benchmark.py --save results.json
Docker-режим (изолированное окружение)
uv run python benchmarks/run_benchmark.py --docker --docker-build task_001
uv run python benchmarks/run_benchmark.py --docker task_001 task_003
uv run python benchmarks/run_benchmark.py --docker --docker-image myrepo/agent:v1
В Docker-режиме код задачи монтируется в /testbed, агентский код живёт в /app образа.
API-ключи пробрасываются через --env-file ~/.config/token-wise-agent/.env.
Качество кода
Проект использует ruff для линтинга и форматирования.
uv run ruff check . # линтинг
uv run ruff format . # форматирование
uv run pytest tests/ -v # тесты
Pre-commit хуки (опционально):
uv run pre-commit install
CI запускается автоматически на каждый push в master и на Pull Request.
Трекинг метрик
После каждого запуска (одноразовый режим) выводится таблица и сохраняется METRICS.json в рабочей директории:
Agent Summary
┏━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┓
┃ Metric ┃ Value ┃
┡━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━┩
│ Model │ anthropic/… │
│ Latency │ 90.0s │
│ LLM calls │ 7 │
│ Total tool calls │ 14 │
│ Tool errors │ 0 │
│ │ │
│ Input tokens │ 120,000 │
│ Output tokens │ 3,200 │
│ │ │
│ Total cost │ $0.0414 │
└────────────────────┴─────────────┘
Полная траектория каждого запуска сохраняется в ~/.config/token-wise-agent/:
~/.config/token-wise-agent/
├── last_twa_run.traj.json # последний одноразовый запуск
└── run_YYYY-MM-DD_HH-MM-SS/
├── task_001.traj.json
└── task_002.traj.json
Добавление нового инструмента
- Создай файл в
agent/tools/(шаблон —smart_reader.py) - Добавь импорт в
agent/tools/__init__.py - Добавь имя тула в
tools:в нужномagent_config.yaml
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file token_wise_agent-1.0.5.tar.gz.
File metadata
- Download URL: token_wise_agent-1.0.5.tar.gz
- Upload date:
- Size: 462.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7f5b1506a05ed806ea78dac6b3c28c9fdcffebd0682f1d65129ed76a4efc88ca
|
|
| MD5 |
6ed4469219e3d85bf1841ab5b6328a2a
|
|
| BLAKE2b-256 |
cdb2e29ac1c4911826c815e775b59be54be44a202fd31b2130c779adc170640b
|
Provenance
The following attestation bundles were made for token_wise_agent-1.0.5.tar.gz:
Publisher:
publish.yml on AimorYou/token-wise-agent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
token_wise_agent-1.0.5.tar.gz -
Subject digest:
7f5b1506a05ed806ea78dac6b3c28c9fdcffebd0682f1d65129ed76a4efc88ca - Sigstore transparency entry: 1470846779
- Sigstore integration time:
-
Permalink:
AimorYou/token-wise-agent@2f43ceb9bf43f1f198aa7296bfd6ec643ae86c20 -
Branch / Tag:
refs/tags/v1.0.5 - Owner: https://github.com/AimorYou
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2f43ceb9bf43f1f198aa7296bfd6ec643ae86c20 -
Trigger Event:
push
-
Statement type:
File details
Details for the file token_wise_agent-1.0.5-py3-none-any.whl.
File metadata
- Download URL: token_wise_agent-1.0.5-py3-none-any.whl
- Upload date:
- Size: 36.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
792a96a25c90470ec6bb91700c914dde72482ce6588ba0f4b775b69365b46c6e
|
|
| MD5 |
d6db361f1b11b3274475a04c05bc689a
|
|
| BLAKE2b-256 |
9465bf9ba66af7b55a64d0dacca7b902300888208eb073e2f8e67cf4620dc750
|
Provenance
The following attestation bundles were made for token_wise_agent-1.0.5-py3-none-any.whl:
Publisher:
publish.yml on AimorYou/token-wise-agent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
token_wise_agent-1.0.5-py3-none-any.whl -
Subject digest:
792a96a25c90470ec6bb91700c914dde72482ce6588ba0f4b775b69365b46c6e - Sigstore transparency entry: 1470846915
- Sigstore integration time:
-
Permalink:
AimorYou/token-wise-agent@2f43ceb9bf43f1f198aa7296bfd6ec643ae86c20 -
Branch / Tag:
refs/tags/v1.0.5 - Owner: https://github.com/AimorYou
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2f43ceb9bf43f1f198aa7296bfd6ec643ae86c20 -
Trigger Event:
push
-
Statement type: