1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
//! Native tool extension API.
//!
//! A `Tool` is the boundary between the agent loop and any extension runtime
//! — native Zig code, a Lua bridge, a future Python or Go bridge. libpanto
//! itself does not parse tool inputs or outputs; it just dispatches.
const std = @import("std");
const Allocator = std.mem.Allocator;
const tool_source = @import("tool_source.zig");
pub const ToolDecl = tool_source.ToolDecl;
pub const Tool = struct {
/// Metadata: `name`, `description`, `schema_json`. Borrowed — the
/// lifetime of every string in `decl` is owned by whoever
/// constructs the `Tool`. Typically the same owner that backs
/// `ctx` (e.g. an adapter for an out-of-process runtime, or a
/// `comptime` static in a native tool).
decl: ToolDecl,
/// Opaque context pointer passed back to every vtable call.
ctx: *anyopaque,
vtable: *const VTable,
pub const VTable = struct {
/// Invoke the tool. MUST be thread-safe — the agent may call
/// `invoke` concurrently from multiple threads when the LLM emits
/// multiple ToolUse blocks in a single response.
///
/// `input` is the raw JSON bytes the provider sent. The tool is
/// responsible for parsing them if it cares about their structure.
///
/// Returns owned bytes allocated with `allocator`. These bytes
/// become the `content` of the ToolResult block sent back to the
/// LLM. The agent takes ownership and frees them.
///
/// Returning an error aborts the current turn. The agent surfaces
/// the error to the user. Native tool implementations are
/// responsible for catching their own panics — a panic in `invoke`
/// will crash the process. Adapters that bridge to safer languages
/// (Lua, Python, Go) should convert panics/exceptions into errors.
invoke: *const fn (
ctx: *anyopaque,
input: []const u8,
allocator: Allocator,
) anyerror![]u8,
/// Called when the tool is unregistered or the registry is torn
/// down. Frees any resources owned by `ctx`, including `ctx`
/// itself if it was heap-allocated.
///
/// The strings inside `decl` are also typically owned by the
/// same allocation as `ctx` — the tool's deinit hook is
/// responsible for freeing them.
deinit: *const fn (ctx: *anyopaque, allocator: Allocator) void,
};
};
|