refactor(agentik-cli): вложенные subcommands (conv ls/new/...)
- conv-ls/new/show/delete/rename -> вложенные под agentik-cli conv
- ConvCommand — Subcommand-родитель, регистрирует 5 дочерних
команд в init { subcommands(...) }
- ConvSubcommand(name, description) extends AgentikSubcommand —
базовый класс для всех conv-подкоманд (наследует --server/--id)
Два гоччаса kotlinx.cli 0.3.6 которые пришлось обойти:
1. parent.execute() вызывается ПОСЛЕ leaf.execute() всегда когда
leaf достигнут через parent. Если parent делает что-то в
execute() — вывод дублируется после каждой дочерней команды.
Фикс: ConvCommand.execute() = Unit (no-op). Дочерние команды
смотрятся через 'agentik-cli conv --help'.
2. По умолчанию 'conv new --server ...' парсится как
conv[--server ...] + позиционный arg 'new' на уровне
родителя, и дочерняя команда не запускается. Фикс:
ArgParser(strictSubcommandOptionsOrder = true) — все аргументы
после имени subcommand передаются в его парсер.
Smoke (linuxX64 kexe + JVM fatjar): conv ls/new/rename/show/delete
+ msgs/send/interrupt/info работают.
This commit is contained in:
+38
-21
@@ -7,7 +7,7 @@
|
||||
стрим ответа `send` идёт в stdout построчно, никакого embedded-REPL.
|
||||
|
||||
Решает: быстрый способ дёрнуть агента из shell-скрипта или руками,
|
||||
не поднимая отдельную TUI-сессию.
|
||||
не поднимая отдельную TUI-сессии.
|
||||
|
||||
## Платформы
|
||||
|
||||
@@ -24,28 +24,32 @@
|
||||
## Подкоманды
|
||||
|
||||
```
|
||||
agentik-cli <subcommand> [options]
|
||||
agentik-cli <command> [args...]
|
||||
|
||||
Subcommands:
|
||||
conv-ls Список диалогов агента
|
||||
conv-new Создать диалог; печатает id
|
||||
conv-show Метаданные диалога
|
||||
conv-delete Удалить диалог
|
||||
conv-rename Переименовать диалог
|
||||
msgs Показать сообщения диалога
|
||||
send Отправить user-ход и стримить ответ
|
||||
interrupt Прервать текущий ход диалога
|
||||
info Показать server URL и agent id
|
||||
Команды верхнего уровня:
|
||||
conv <subcommand> операции над диалогами (см. ниже)
|
||||
msgs <id> [--limit N] показать сообщения
|
||||
send <id> <text...> отправить ход, стримит response-события в stdout
|
||||
interrupt <id> прервать текущий ход
|
||||
info показать конфиг (server URL + agent id)
|
||||
|
||||
Подкоманды `conv`:
|
||||
conv ls список диалогов
|
||||
conv new [--temp] создать диалог, печатает id
|
||||
conv show <id> метаданные диалога
|
||||
conv delete <id> удалить диалог
|
||||
conv rename <id> <title> переименовать
|
||||
```
|
||||
|
||||
`--server URL` и `--id ID` (env: `AGENTIK_SERVER`, `AGENTIK_AGENT_ID`)
|
||||
задаются **после** имени subcommand'а — kotlinx.cli не шарит опции
|
||||
родителя в subcommand. Пример:
|
||||
родителя в subcommand. Примеры:
|
||||
|
||||
```bash
|
||||
agentik-cli conv-ls --server http://192.168.76.166:8080/agentik
|
||||
agentik-cli conv-new --server http://localhost:8080/agentik
|
||||
agentik-cli conv ls --server http://192.168.76.166:8080/agentik
|
||||
agentik-cli conv new --server http://localhost:8080/agentik
|
||||
agentik-cli send --server http://localhost:8080/agentik conv-abc "привет"
|
||||
agentik-cli info # через AGENTIK_SERVER env-переменную
|
||||
```
|
||||
|
||||
## Как запустить
|
||||
@@ -55,14 +59,14 @@ agentik-cli send --server http://localhost:8080/agentik conv-abc "привет"
|
||||
```bash
|
||||
./gradlew :agentik-cli:shadowJar
|
||||
java --enable-native-access=ALL-UNNAMED \
|
||||
-jar agentik-cli/build/libs/agentik-cli-0.1.0-SNAPSHOT-all.jar --help
|
||||
-jar agentik-cli/build/libs/agentik-cli-0.1.0-SNAPSHOT-all.jar conv --help
|
||||
```
|
||||
|
||||
### Native linuxX64
|
||||
|
||||
```bash
|
||||
./gradlew :agentik-cli:linkReleaseExecutableLinuxX64
|
||||
./agentik-cli/build/bin/linuxX64/releaseExecutable/agentik-cli.kexe --help
|
||||
./agentik-cli/build/bin/linuxX64/releaseExecutable/agentik-cli.kexe conv --help
|
||||
```
|
||||
|
||||
### Native macOS / Windows
|
||||
@@ -79,14 +83,14 @@ CI-ноут: запускать `./gradlew :agentik-cli:linkReleaseExecutableMac
|
||||
|
||||
```bash
|
||||
# Список диалогов (таблица)
|
||||
agentik-cli conv-ls --server http://localhost:8080/agentik
|
||||
agentik-cli conv ls --server http://localhost:8080/agentik
|
||||
|
||||
# Создать диалог
|
||||
ID=$(agentik-cli conv-new --server http://localhost:8080/agentik)
|
||||
ID=$(agentik-cli conv new --server http://localhost:8080/agentik)
|
||||
echo "new conv: $ID"
|
||||
|
||||
# Переименовать
|
||||
agentik-cli conv-rename --server http://localhost:8080/agentik "$ID" "мой чат"
|
||||
agentik-cli conv rename --server http://localhost:8080/agentik "$ID" "мой чат"
|
||||
|
||||
# Отправить ход и стримить ответ
|
||||
agentik-cli send --server http://localhost:8080/agentik "$ID" "2+2"
|
||||
@@ -98,7 +102,7 @@ agentik-cli msgs --server http://localhost:8080/agentik "$ID" --limit 10
|
||||
agentik-cli interrupt --server http://localhost:8080/agentik "$ID"
|
||||
|
||||
# Удалить
|
||||
agentik-cli conv-delete --server http://localhost:8080/agentik "$ID"
|
||||
agentik-cli conv delete --server http://localhost:8080/agentik "$ID"
|
||||
|
||||
# Через env-переменную
|
||||
AGENTIK_SERVER=http://localhost:8080/agentik agentik-cli info
|
||||
@@ -146,6 +150,19 @@ event End
|
||||
требует `@OptIn(ExperimentalForeignApi::class)`).
|
||||
- **Stdout / exit code** — работают на K/N через корутины.
|
||||
|
||||
## Готчасы kotlinx.cli
|
||||
|
||||
- **Вложенные subcommands + parent.execute().** В kotlinx.cli 0.3.6
|
||||
`parent.execute()` вызывается ПОСЛЕ `leaf.execute()` всегда,
|
||||
когда leaf был достигнут через parent. Поэтому `ConvCommand.execute()`
|
||||
сделан no-op (`override fun execute() = Unit`), иначе вывод
|
||||
дочерней команды дублируется выводом родителя. Дочерние команды
|
||||
смотрятся через `agentik-cli conv --help`.
|
||||
- **strictSubcommandOptionsOrder.** Без этого флага `conv new --server ...`
|
||||
парсится как `conv [--server ...]` + позиционный аргумент `new`
|
||||
на уровне родителя — и дочерняя команда не запускается.
|
||||
В `ArgParser` сразу включается `strictSubcommandOptionsOrder = true`.
|
||||
|
||||
## Тесты
|
||||
|
||||
Тесты для подкоманд пока не написаны (TODO). Базовый smoke
|
||||
|
||||
Reference in New Issue
Block a user