88 lines
3.1 KiB
Markdown
88 lines
3.1 KiB
Markdown
# `:agent-toolsets` — реестр инструментов агента (KMP, jvm + native)
|
|
|
|
## Что это
|
|
|
|
Ядро системы tools для LLM-агента:
|
|
|
|
- `Toolset` — интерфейс, объединяющий несколько связанных tools
|
|
(`MemoryTools`, `SkillsTools`, `FileSystemTools`).
|
|
- `ToolRegistry` — глобальный реестр + фильтр enabled/disabled.
|
|
- `ToolDispatcher` — берёт решение LLM (вызов инструмента с аргументами)
|
|
→ запускает → возвращает результат.
|
|
- **Cooperative cancel** — `interrupt()` корректно отменяет in-flight
|
|
вызов, помечая результат `[cancelled by user]`.
|
|
- **Concurrency budget** — `backgroundScope = Dispatchers.IO
|
|
.limitedParallelism(4)` (см. коммит `86eb063`) — защищает
|
|
threadpool от переполнения при fan-out 30+ диалогов.
|
|
|
|
Решает: надёжный механизм tool-calls с прерываниями, без
|
|
blocking-pool exhaustion, без утечки. Переиспользуется во всех
|
|
IM-фронтендах (CLI, TUI, IRC, web).
|
|
|
|
## Где используется
|
|
|
|
- `:standalone` подключает несколько `Toolset`-имплементаций
|
|
(memory / skills / files / web), фильтрует через
|
|
`AGENTIK_TOOLSETS_DEFAULT` env.
|
|
|
|
## Как подключить
|
|
|
|
```kotlin
|
|
commonMain.dependencies {
|
|
api("pw.binom.agentik:agent-toolsets:0.1.0")
|
|
}
|
|
|
|
class MyToolset : Toolset {
|
|
override val name = "my"
|
|
override val description = "Custom user-defined tools"
|
|
override val tools = listOf(myTool1, myTool2)
|
|
}
|
|
|
|
val dispatcher = ToolDispatcher(
|
|
toolsets = listOf(MemoryTools(memory), MyToolset()),
|
|
enabled = setOf("memory", "my"),
|
|
)
|
|
```
|
|
|
|
## Версии
|
|
|
|
`gradle/libs.versions.toml` → `[versions] agentik-agent-toolsets`.
|
|
|
|
## Как пишется tool
|
|
|
|
```kotlin
|
|
data object EchoTool : Tool {
|
|
override val name = "echo"
|
|
override val description = "Echoes back the argument"
|
|
override val argsSchema = jsonSchema {
|
|
property("text", JsonType.STRING) { required = true }
|
|
}
|
|
|
|
override suspend fun invoke(args: JsonObject): ToolResult {
|
|
val text = args["text"]?.jsonPrimitive?.content ?: return ToolResult.Error("missing text")
|
|
return ToolResult.Text(text)
|
|
}
|
|
}
|
|
```
|
|
|
|
## Тесты
|
|
|
|
```
|
|
./gradlew :agent-toolsets:allTests
|
|
```
|
|
|
|
Покрывают: invoke happy-path, invalid args, cooperative cancel,
|
|
budget exhaustion, registry filter, parallel dispatch.
|
|
|
|
## Чего здесь НЕТ
|
|
|
|
- Никакого конкретного LLM. Dispatcher вызывает tools, не LLM.
|
|
- Никакого persistent storage. Опирается на контракт `ContextStore`
|
|
(см. `:storage-core`).
|
|
|
|
## Текущий статус
|
|
|
|
Используется продакшеном. Реализует полную спецификацию из
|
|
[INTERRUPT-DESIGN.md](../../docs/INTERRUPT-DESIGN.md): tool exchange
|
|
log, rolling buffer, partial-state persistence.
|