mirror of
https://github.com/patriceckhart/zot.git
synced 2026-06-27 05:46:34 +02:00
Extensions can now register tools the LLM calls directly. The model
sees them in its tool list alongside the built-ins (read, write,
edit, bash, skill); when it invokes one, zot routes the tool_call
to the owning extension subprocess and feeds the tool_result back.
Wire format additions (internal/extproto):
ext -> host:
register_tool {name, description, schema}
ready # all initial regs flushed
tool_result {id, content[], is_error} # reply to a tool_call
host -> ext:
tool_call {id, name, args} # raw json args from the model
Manager (internal/agent/extensions):
- tracks per-extension RegisterToolFromExt frames
- validates schemas parse as JSON before registering (bad schema
skipped + logged, doesn't crash zot)
- toolIndex map for O(1) lookup
- WaitForReady(grace): blocks per extension on its readyCh until
a ready frame arrives or the grace expires; called once after
Discover so the agent's tool registry is built against the
final set
- Tools() / HasTool() / InvokeTool() public surface
- readLoop closes readyCh on stdout EOF so a wedged extension
doesn't permanently block WaitForReady
extensionTool (internal/agent/extensions/tool.go):
implements core.Tool. Execute() round-trips through
Manager.InvokeTool with a 60s default timeout, decodes
base64 image blocks, surfaces extension+tool name in
ToolResult.Details for the renderer.
internal/agent/build.go:
- new ExtensionToolSource interface (declared here to avoid the
build->extensions->core import cycle) + ExtensionToolInfo
mirror of extensions.ToolInfo
- Resolved.MergeExtensionTools(): folds extension tools into
ToolRegistry, re-renders the system prompt's tool summary
with both built-in and extension tools listed
- Resolved gains private bookkeeping fields so the rebuild
works without re-running Resolve
internal/agent/cli.go:
extension manager built BEFORE the agent in interactive mode
so MergeExtensionTools can fire before NewAgent. Same in
buildAgent + buildAgentFor closures so login / model-switch
rebuilds also include extension tools. extToolAdapter bridges
*extensions.Manager to ExtensionToolSource.
internal/agent/rpc.go:
extension lifecycle now also runs in `zot rpc` mode. Notify and
Display from extensions surface as `ext_notify` / `ext_display`
events on the rpc stream so any consumer can react.
pkg/zotext (Go SDK):
- ToolHandler, ToolResult, ToolContent types
- Tool(name, desc, schema, fn) registration method
- TextResult / TextErrorResult / Image / ImageBytes constructors
- Run() now also flushes register_tool frames + a final ready
sentinel after the last registration
examples/extensions/weather: working Go example registering one
tool. Deterministic fake weather (sha1 of city -> temp + cond) so
the demo is repeatable. Plus README explaining how to install.
Tests:
internal/agent/extensions/tool_test.go: spawns a mock /bin/sh
extension that registers a tool, sends ready, and echoes tool
calls. Verifies registration timing, lookup via HasTool/Tools,
invoke roundtrip via InvokeTool.
End-to-end verified against live anthropic backend:
prompt: "What is the weather in Berlin?"
-> [tool_call] weather({"city":"Berlin"})
-> [tool_result] Berlin: 16°C, fog (deterministic fake)
-> reply: "Berlin is 16°C."
Docs/extensions.md updated with phase 2 wire format, the new SDK
tool API, and the weather example.
|
||
|---|---|---|
| .. | ||
| extensions | ||
| rpc | ||
| sdk | ||
| skills | ||