tool

package
v1.0.0-alpha.20 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 15, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BuildIntrospectionTools

func BuildIntrospectionTools(agentRoot string) []fantasy.AgentTool

BuildIntrospectionTools returns the four runtime-registered tools that let the model inspect its own declared context / envs / mounts out of agent.yaml: `context_list`, `context_show`, `env_list`, `mount_list`. Each reads /etc/agent.yaml (or wherever agentRoot points) at invocation time — agent.yaml is materialised once per run, so the data doesn't change between startup and tool call.

agentRoot is the agent's filesystem root (`/` for the docker executor, `<agent-uuid-dir>` for system). The tools join against it to find etc/agent.yaml and etc/context/*.md.

Env values are never returned — `env_list` surfaces keys + descriptions only. Mount host paths are never returned — `mount_list` surfaces targets + descriptions + the read-only flag. Both rules are by design: the agent.yaml on disk doesn't carry those fields in the first place, so the tools couldn't leak them even if asked.

func BuildJobTools

func BuildJobTools() []fantasy.AgentTool

BuildJobTools returns the three async-job tools when a daemon callback path is wired (OTTERSD_URL + OTTERS_AGENT_TOKEN both set in the spawn env). Returns an empty slice when env vars are missing — caller appends to LoadTools' result so absence just means the agent doesn't see those tools, not a hard failure.

One *jobsclient.Client is shared across all three tools — the underlying gRPC connection multiplexes RPCs and lazy-dials on first use, so an agent that never invokes a job tool pays nothing.

func BuildNotesTools

func BuildNotesTools(store *notes.Store, maxBytes, maxCount int) []fantasy.AgentTool

BuildNotesTools returns the six LLM-facing tools that operate on the per-agent notes store: note_save, note_list, note_show, note_delete, note_pin, note_unpin. The store is shared across all six; maxBytes / maxCount are the quota gates the store enforces inside Save.

Notes are durable facts the model writes about its operator — "the user's k8s cluster is named homelab" — that survive across sessions for the lifetime of the agent. They are distinct from chat memory (which the compactor may drop or summarise) and from context files (which are immutable, baked into the image).

note_pin / note_unpin toggle the in_context flag: pinned notes flow into the system prompt on every step via the PrepareStep callback, regardless of the notes-prompt-section config. Use it for facts the model needs to lean on continuously (project name, preferred conventions) rather than facts it only needs to recall occasionally (one-off URLs, historical context).

func LoadTools

func LoadTools(
	defs []Def, workDir string,
	notesStore *notes.Store, notesMaxBytes, notesMaxCount int,
	logger *zap.Logger,
) ([]fantasy.AgentTool, error)

LoadTools assembles the runtime's full tool set: the BIN-backed tools declared in agent.yaml, the daemon-callback job tools (when the agent has a daemon URL + token), the introspection tools (context_*, env_list, mount_list), and — when notesStore is non-nil — the note_* tools.

notesStore is intentionally optional: dev invocations of the runtime binary without a memory.db (e.g. a one-shot CLI prompt) still work, just without the notes capability registered.

Types

type Def

type Def struct {
	Name        string
	Description string
	Binary      string
	Args        []string
	Docs        Docs
}

Def declares a tool the runtime should register with the LLM. The shape is intentionally split between "what the tool does" (Name, Description, Binary, Args) and "what extra reading material the model gets" (Docs). The agentfile executor populates Docs from the BIN image's `vnd.openotters.bin.*` annotations.

type Docs

type Docs struct {
	// Usage is a USAGE.md-style long-form description. Appended to
	// the model-facing tool description under a "## Usage" section
	// at registration time.
	Usage string
}

Docs are documentation artefacts the executor materialised next to the binary. Each field is a path on the runtime's local filesystem; empty / missing files are tolerated silently so a BIN without docs degrades to "tool with short description only."

New annotation-driven artefacts (examples, schema, FAQ, …) plug in here as additional fields without breaking the runtime's agent.yaml schema.

type Input

type Input struct {
	Args  []string `` /* 138-byte string literal not displayed */
	Stdin string   `` /* 174-byte string literal not displayed */
}

Input is the BIN tool call shape exposed to the LLM. Fantasy reflects this struct into a JSON schema, so the model sees `args` and `stdin` as named fields and picks whichever the tool needs.

Both fields are optional. Tools that take only argv use `args` and ignore `stdin`; tools whose meaningful input flows over stdin (`yaegi run -`, `pandoc`, `markitdown`, …) use `stdin` (often alongside a small `args` like `["run", "-"]`). At least one of them is required — empty calls are rejected so the model gets immediate feedback rather than the binary's own help text.

type JobIDInput

type JobIDInput struct {
	JobID string `json:"job_id" jsonschema:"description=Job id returned by job_submit"`
}

JobIDInput is the shared schema for status / wait / cancel — they all take just a job id.

type ListJobsInput

type ListJobsInput struct {
	AllSessions bool   `` /* 132-byte string literal not displayed */
	Status      string `` /* 131-byte string literal not displayed */
	Limit       int    `json:"limit,omitempty" jsonschema:"description=Maximum number of jobs to return (most recent first). Default 20, max 100."`
}

ListJobsInput controls the agent-side job_list scope. By default only jobs from the current chat session are returned (matching the io.openotters.session-id label that job_submit auto-stamps); flip AllSessions to see everything this agent has submitted across sessions. Status / Limit are additional narrowers. AgentID is never accepted — the daemon scopes by the agent's bound JWT, so the agent can never list another agent's jobs.

type SubmitJobInput

type SubmitJobInput struct {
	Bin    string            `json:"bin" jsonschema:"description=BIN name as declared in this agent's Agentfile (sh, jq, kubectl, …)"`
	Args   []string          `json:"args,omitempty" jsonschema:"description=Positional arguments forwarded to the BIN"`
	Stdin  string            `json:"stdin,omitempty" jsonschema:"description=Optional stdin payload piped to the BIN"`
	Labels map[string]string `` /* 141-byte string literal not displayed */
}

SubmitJobInput is the model-facing schema for `job_submit`. The jsonschema tags drive what the model sees in its tool-list prompt — keep them tight so the model isn't tempted to pass irrelevant fields.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL