1631 lines
52 KiB
JavaScript
1631 lines
52 KiB
JavaScript
/** OpenAI-style tool schemas for /bin/agent (preamble; no import). */
|
||
|
||
/**
|
||
* @returns {unknown[]}
|
||
*/
|
||
function bareAgentToolDefinitions() {
|
||
return [
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'read_file',
|
||
description:
|
||
'Read a UTF-8 text file from the VFS. Path may be absolute or ~/... (tilde is expanded). Optional offset/limit return numbered line slices (Grok-style).',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
path: { type: 'string', description: 'Absolute file path' },
|
||
file_path: { type: 'string', description: 'Alias for path' },
|
||
max_bytes: {
|
||
type: 'integer',
|
||
description: 'Max bytes to read (default 256000)'
|
||
},
|
||
offset: {
|
||
type: 'integer',
|
||
description: '1-based start line for a numbered slice'
|
||
},
|
||
limit: {
|
||
type: 'integer',
|
||
description: 'Max lines to return from offset'
|
||
},
|
||
numbered: {
|
||
type: 'boolean',
|
||
description: 'Prefix N→ on each line when slicing (default true if offset/limit set)'
|
||
}
|
||
},
|
||
required: ['path']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'write_file',
|
||
description:
|
||
'Create a new file or overwrite an existing one at any writable guest path. Path may be absolute or ~/... (tilde is expanded to the session home). Parent directories are created as needed. Returns the expanded path — verify with list_directory or file_stat before claiming the file exists. Do not ask permission.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
path: { type: 'string', description: 'Absolute path or ~/file' },
|
||
file_path: { type: 'string', description: 'Alias for path' },
|
||
content: { type: 'string', description: 'Full file contents' }
|
||
},
|
||
required: ['path', 'content']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'edit_file',
|
||
description:
|
||
'Edit a text file: full replacement via content, or search/replace. old_string must be unique unless replace_all is true.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
path: { type: 'string' },
|
||
file_path: { type: 'string', description: 'Alias for path' },
|
||
content: {
|
||
type: 'string',
|
||
description: 'If set (non-empty), full file replacement'
|
||
},
|
||
old_string: {
|
||
type: 'string',
|
||
description: 'Search string (used with new_string)'
|
||
},
|
||
new_string: { type: 'string', description: 'Replacement text' },
|
||
replace_all: {
|
||
type: 'boolean',
|
||
description: 'Replace every occurrence of old_string (default false)'
|
||
}
|
||
},
|
||
required: ['path']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'create_directory',
|
||
description:
|
||
'Create a directory (recursive). Path may be absolute or ~/... (tilde is expanded). Returns the expanded path — list_directory it before claiming it exists.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
path: { type: 'string', description: 'Absolute path or ~/dir' },
|
||
dir: { type: 'string', description: 'Alias for path' }
|
||
},
|
||
required: ['path']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'search_files',
|
||
description:
|
||
'Run grep -R to list paths matching a pattern (bounded). Uses the shell.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
pattern: { type: 'string' },
|
||
root: {
|
||
type: 'string',
|
||
description: 'Directory to search (default /home)'
|
||
},
|
||
max_lines: { type: 'integer', description: 'Default 200' }
|
||
},
|
||
required: ['pattern']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'run_command',
|
||
description:
|
||
'Run a guest CLI line (curl, wget, ip, ping, ls, cat, …) via ctx.execLine. Prefer this over run_js_script for any shell command. Output is captured to a temp file. Set capture_exit true to append a final EXIT:<code> line.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
command: {
|
||
type: 'string',
|
||
description: 'Full command string (e.g. ls -la /bin)'
|
||
},
|
||
cwd: {
|
||
type: 'string',
|
||
description: 'Working directory (cd there first). Persists as ~/.agent/last_cwd.'
|
||
},
|
||
timeout_ms: { type: 'integer' },
|
||
capture_exit: {
|
||
type: 'boolean',
|
||
description: 'If true, append last line EXIT:<code> to capture (default false)'
|
||
}
|
||
},
|
||
required: ['command']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'run_js_script',
|
||
description:
|
||
'Run custom guest JavaScript only. Do not use this for curl, wget, ip, ping, or any shell — call run_command. Do not use this to replace read_file, write_file, list_directory, or run_command. Node is not installed. Writes ~/.agent/_tmp_agent_run.mjs and runs it on the Bare kernel. ctx and argv are already injected — never declare them, never export. Body must be: async function run(ctx, argv) { const vfs = ctx.vfs; ... }',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
code: { type: 'string', description: 'Full ESM/CommonJS script body' }
|
||
},
|
||
required: ['code']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'get_system_info',
|
||
description:
|
||
'Lightweight context: API version, uname, optional resource hook. Questions about **which kernel features are on/off in this session** → read_proc_file on /proc/bare_os/features (or features.json) and /proc/bare_os/capabilities.json; not apropos_man. For other /proc JSON use read_proc_file; swarm → get_swarm_peers; resource table → get_resource_limits. want=capabilities|swarm still returns those blobs when needed.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
want: {
|
||
type: 'string',
|
||
enum: ['summary', 'capabilities', 'swarm'],
|
||
description: 'Optional focus (default summary)'
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'edit_agent_config',
|
||
description:
|
||
'Merge keys into ~/.agent/config.json (shallow merge for known keys only).',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
patch: {
|
||
type: 'object',
|
||
description:
|
||
'Partial config object (rest_base_url, model, temperature, owner_name, agent_label, …)'
|
||
}
|
||
},
|
||
required: ['patch']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'list_bin',
|
||
description: 'List Tier-1 utilities in /bin via VFS.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
limit: { type: 'integer', description: 'Max names (default 400)' }
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'list_directory',
|
||
description:
|
||
'List directory entries via ctx.vfs.readdir. Optional one-line stat per entry (bounded).',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
path: { type: 'string', description: 'Absolute directory path' },
|
||
max_entries: { type: 'integer', description: 'Max names (default 500, cap 2000)' },
|
||
include_stat: {
|
||
type: 'boolean',
|
||
description: 'If true, call stat on each entry (slower; default false)'
|
||
},
|
||
tree: {
|
||
type: 'boolean',
|
||
description: 'Grok-style bounded BFS tree instead of a flat listing'
|
||
},
|
||
max_depth: { type: 'integer', description: 'Tree depth (default 6)' }
|
||
},
|
||
required: ['path']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'file_stat',
|
||
description:
|
||
'Stat a path: size, mtime, type, mode. Uses lstat when follow_symlinks is false (default).',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
path: { type: 'string' },
|
||
follow_symlinks: {
|
||
type: 'boolean',
|
||
description: 'If true, use stat (follow); if false, lstat (default false)'
|
||
}
|
||
},
|
||
required: ['path']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'move_path',
|
||
description:
|
||
'Rename or move a file or directory via shell mv. Any writable VFS path is allowed; the read-only base system (/bin, /etc, /boot, /lib, /usr, /share, /proc, /dev) is denied.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
from_path: { type: 'string' },
|
||
to_path: { type: 'string' }
|
||
},
|
||
required: ['from_path', 'to_path']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'delete_path',
|
||
description:
|
||
'Delete a file or directory (recursive optional). Allowed by default. Optional confirm_token only if require_confirm_token is set. Cannot delete the read-only base system.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
path: { type: 'string' },
|
||
recursive: {
|
||
type: 'boolean',
|
||
description: 'Remove directories recursively (default false)'
|
||
},
|
||
confirm_token: {
|
||
type: 'string',
|
||
description: 'Must match config require_confirm_token when that key is non-empty'
|
||
}
|
||
},
|
||
required: ['path']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'read_man_page',
|
||
description:
|
||
'Read one manual page from /share/man/man.json (bounded text). Prefer over parsing man output.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
topic: { type: 'string', description: 'Page name (e.g. grep, agent)' },
|
||
section: {
|
||
type: 'integer',
|
||
description: 'Manual section 1–8 if disambiguating (optional)'
|
||
},
|
||
max_chars: { type: 'integer', description: 'Cap rendered slice (default 12000)' }
|
||
},
|
||
required: ['topic']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'apropos_man',
|
||
description:
|
||
'Keyword search over the merged man DB (same idea as man -k). Returns matching name(section) lines. This is documentation search only—never use it to answer what kernel features are currently enabled or disabled (use read_proc_file on /proc/bare_os/features).',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
keyword: { type: 'string' },
|
||
max_results: { type: 'integer', description: 'Default 40, max 200' }
|
||
},
|
||
required: ['keyword']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'read_proc_file',
|
||
description:
|
||
'Read any /proc path (bounded), including the full /proc/bare_os kernel surface. Canonical live feature state: /proc/bare_os/features or features.json. Prefer this over shelling cat.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
path: {
|
||
type: 'string',
|
||
description:
|
||
'Absolute /proc path (any kernel node). Examples: /proc/bare_os/features.json, /proc/bare_os/capabilities.json, /proc/bare_os/swarm.json.'
|
||
},
|
||
max_bytes: { type: 'integer', description: 'Default 256000' }
|
||
},
|
||
required: ['path']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'get_swarm_peers',
|
||
description: 'Return parsed /proc/bare_os/swarm.json when readable (P2P / Hyperswarm snapshot).',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'get_resource_limits',
|
||
description:
|
||
'Return ctx.bareOsGetResourceStatus() when available (pipeline / resource snapshot).',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'run_js_script_at_path',
|
||
description:
|
||
'Execute an existing .mjs script by absolute path (Bare kernel runner). Same as running that path with run_command but dedicated for clarity.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
path: { type: 'string', description: 'Absolute path to .mjs file' }
|
||
},
|
||
required: ['path']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'web_fetch',
|
||
description:
|
||
'Fetch live HTTP(S) URLs and return structured content for the assistant. Uses ctx.httpFetch (same policy as wget/curl: BARE_OS_HTTP_ALLOWLIST / DENYLIST). For official docs index use read_man_page / apropos_man — they are not web pages. Supports GET/HEAD/POST and extract modes: auto (JSON vs HTML vs text), markdownish plain text from HTML, links (anchor hrefs), meta (title/og:), raw UTF-8 slice, or json parse.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
url: { type: 'string', description: 'Absolute http(s) URL' },
|
||
method: {
|
||
type: 'string',
|
||
description: 'HTTP method (default GET)',
|
||
enum: ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS']
|
||
},
|
||
headers: {
|
||
type: 'object',
|
||
description: 'Optional header map (string values only)'
|
||
},
|
||
body: {
|
||
type: 'string',
|
||
description: 'Request body for non-GET (e.g. JSON string for APIs)'
|
||
},
|
||
content_type: {
|
||
type: 'string',
|
||
description: 'Content-Type when body is set (default application/octet-stream)'
|
||
},
|
||
format: {
|
||
type: 'string',
|
||
enum: ['auto', 'json', 'markdownish', 'text', 'links', 'meta', 'raw'],
|
||
description:
|
||
'auto: sniff Content-Type; json: parse JSON; markdownish/text: strip HTML to readable text; links: absolute http(s) links; meta: title/description/og tags; raw: bounded UTF-8 text'
|
||
},
|
||
max_response_bytes: {
|
||
type: 'integer',
|
||
description: 'Cap downloaded bytes (default 524288, max 2MiB)'
|
||
},
|
||
max_redirects: {
|
||
type: 'integer',
|
||
description: 'Max redirects to follow (default 5)'
|
||
},
|
||
timeout_ms: {
|
||
type: 'integer',
|
||
description: 'Per-request timeout ms (default 30000, max 120000)'
|
||
},
|
||
max_links: {
|
||
type: 'integer',
|
||
description: 'Max links when format=links (default 200)'
|
||
}
|
||
},
|
||
required: ['url']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'read_skill',
|
||
description:
|
||
'Load the full SKILL.md for a modular agent skill (folder id or frontmatter name, case-insensitive). Workspace ~/.agent/workspace/skills/ overrides ~/.agent/skills/. Use after checking the compact skills index in the system prompt.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
skill: {
|
||
type: 'string',
|
||
description: 'Skill folder name (e.g. p2p-os-status) or YAML frontmatter name'
|
||
},
|
||
max_bytes: {
|
||
type: 'integer',
|
||
description: 'Max bytes of SKILL.md (default 256000)'
|
||
}
|
||
},
|
||
required: ['skill']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'list_services',
|
||
description:
|
||
'List initd service definitions and current runtime phases from /proc/bare_os/initd_readiness.json when available.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'service_status',
|
||
description:
|
||
'Read one initd unit status by name from /proc/bare_os/initd_readiness.json and include journal hint paths when present.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
name: { type: 'string', description: 'Unit name, e.g. bare-cron' }
|
||
},
|
||
required: ['name']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'list_timers',
|
||
description:
|
||
'List user timer drop-ins from ~/.config/bare-os/timers and optionally include short file previews.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
include_preview: {
|
||
type: 'boolean',
|
||
description: 'Include bounded timer file text previews (default false)'
|
||
},
|
||
max_entries: {
|
||
type: 'integer',
|
||
description: 'Maximum timer files to return (default 128, max 512)'
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'read_cron_log',
|
||
description:
|
||
'Read /var/log/bare-os/cron.log with bounded output and optional tail mode.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
max_chars: {
|
||
type: 'integer',
|
||
description: 'Maximum returned characters (default 12000)'
|
||
},
|
||
tail_only: {
|
||
type: 'boolean',
|
||
description: 'When true, return only the trailing max_chars slice'
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'read_audit_log',
|
||
description:
|
||
'Read /var/log/bare-os/audit.log with bounded output and best-effort secret redaction.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
max_chars: {
|
||
type: 'integer',
|
||
description: 'Maximum returned characters (default 12000)'
|
||
},
|
||
tail_only: {
|
||
type: 'boolean',
|
||
description: 'When true, return only the trailing max_chars slice'
|
||
},
|
||
redact: {
|
||
type: 'boolean',
|
||
description: 'Apply lightweight token redaction (default true)'
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'read_boot_policy',
|
||
description:
|
||
'Read /etc/bare-os/boot.policy.json and return text plus parsed JSON when available.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
max_chars: {
|
||
type: 'integer',
|
||
description: 'Maximum returned characters (default 20000)'
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'read_kernel_extension_resolution',
|
||
description:
|
||
'Read /run/bare-os/kernel-ext-resolution.json for extension ordering, conflicts, and pin outcomes.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
max_chars: {
|
||
type: 'integer',
|
||
description: 'Maximum returned characters (default 20000)'
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'get_initd_graph',
|
||
description:
|
||
'Read initd dependency DAG/readiness graph from /proc/bare_os/initd_dag.json and /proc/bare_os/initd_readiness.json.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'read_unit_journal',
|
||
description:
|
||
'Read a bounded/redacted tail of /run/bare-os/unit-journal/<unit>.ndjson.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
unit: { type: 'string', description: 'Initd unit name, e.g. bare-cron' },
|
||
max_chars: { type: 'integer', description: 'Maximum output chars (default 12000)' },
|
||
tail_only: { type: 'boolean', description: 'Return trailing max_chars only' }
|
||
},
|
||
required: ['unit']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'inspect_ipc_backpressure',
|
||
description:
|
||
'Inspect IPC/backpressure operator snapshots from /proc/bare_os JSON surfaces.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'get_network_summary',
|
||
description:
|
||
'Read a typed network/swarm summary from /proc/bare_os surfaces with best-effort fallback paths.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'tail_telemetry_streams',
|
||
description:
|
||
'Read bounded/redacted tails from telemetry logs such as /var/log/bare-os/audit.log, logger.jsonl, and initd logs.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
max_chars: { type: 'integer', description: 'Maximum chars per stream (default 8000)' }
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'pkg_index_lookup',
|
||
description:
|
||
'Run pkg-swarm-index lookup and return parsed output for one package key.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
key: { type: 'string', description: 'Package key to lookup' }
|
||
},
|
||
required: ['key']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'list_verification_scripts',
|
||
description:
|
||
'List known verification scripts from /scripts and summarize likely check families.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'run_maintenance_gate',
|
||
description:
|
||
'Run one named maintenance check with bounded capture (id maps to a known verifier). Use run_command for arbitrary guest commands.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
command: { type: 'string', description: 'Allowlisted command id' },
|
||
cwd: { type: 'string', description: 'Optional working directory' },
|
||
timeout_ms: { type: 'integer', description: 'Timeout in milliseconds' }
|
||
},
|
||
required: ['command']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'run_contract_checks',
|
||
description:
|
||
'Run a grouped set of contract checks by profile id (allowlisted) with bounded output.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
profile: { type: 'string', description: 'Check profile id, e.g. core, docs, parity' }
|
||
},
|
||
required: ['profile']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'summarize_build_drift',
|
||
description:
|
||
'Summarize build/generated drift by comparing git status and key generated artifacts.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'get_hrpc_bridge_health',
|
||
description:
|
||
'Read HRPC bridge/operator health from /proc/bare_os surfaces and include host capability hints when available.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'get_hrpc_allowlist_status',
|
||
description:
|
||
'Inspect effective HRPC allowlist/probe status using hrpc probe and operator snapshots.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'discord_send_message',
|
||
description:
|
||
'Send a Discord Direct Message on the open operator channel. Reach out anytime — do not wait for the user to message first. Defaults to the last whitelisted DM partner (or the sole whitelist id). Never sends to anyone off DISCORD_ID_WHITELIST. If the bot is offline the message is queued in ~/.discord/outbox.json.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
text: {
|
||
type: 'string',
|
||
description: 'Message body (Discord markdown). Max 4000 characters.'
|
||
},
|
||
user_id: {
|
||
type: 'string',
|
||
description: 'Optional Discord user snowflake. Omit to use the open channel partner.'
|
||
}
|
||
},
|
||
required: ['text']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'discord_channel_status',
|
||
description:
|
||
'Show the Discord DM channel: partner user id, last inbound/outbound, pending outbox, inbox count, whether the bot client is live.',
|
||
parameters: { type: 'object', properties: {} }
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'discord_read_inbox',
|
||
description:
|
||
'Read recent inbound Discord DMs stored on the channel (from the operator). Use when you need what they said while you were not in a turn.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
max: { type: 'integer', description: 'How many recent messages (default 12, max 50)' }
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'emit_host_notification',
|
||
description:
|
||
'Request an audited host notification via HRPC route. Also fans out to the open Discord DM channel when one exists. Enabled by default; emergency_stop_mutations or a denylist can still block.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
title: { type: 'string' },
|
||
message: { type: 'string' },
|
||
level: { type: 'string', enum: ['info', 'warn', 'error'] }
|
||
},
|
||
required: ['title', 'message']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'request_host_action',
|
||
description:
|
||
'Request a schema-validated host action through HRPC. Enabled by default; emergency_stop_mutations or a denylist can still block.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
action: { type: 'string', description: 'Host action id' },
|
||
payload: { type: 'object', description: 'Action payload object' }
|
||
},
|
||
required: ['action']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'autonomous_run',
|
||
description:
|
||
'Start an autonomous coding run with a goal. Enables autonomous mode, keeps the ReAct loop going until task_complete, stop, or timebox. Optional scope path, runtime cap, and quality-gate ids.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
goal: { type: 'string', description: 'Task goal the agent should complete autonomously' },
|
||
scope_path: { type: 'string', description: 'Preferred working scope path (optional)' },
|
||
max_runtime_ms: { type: 'integer', description: 'Optional runtime cap override' },
|
||
required_checks: {
|
||
type: 'array',
|
||
items: { type: 'string' },
|
||
description: 'Optional quality gates (allowlisted check ids)'
|
||
}
|
||
},
|
||
required: ['goal']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'autonomous_run_status',
|
||
description:
|
||
'Return current autonomous run state, elapsed/runtime budget, configured checks, and latest status.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'autonomous_run_stop',
|
||
description:
|
||
'Request manual stop for an autonomous run; loop will stop safely on next control checkpoint.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
reason: { type: 'string' }
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'verification_hints',
|
||
description:
|
||
'Suggest npm/node verification commands for a developer working at the Bare OS git checkout on the host (paths or topic keywords). Does not run commands.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
topic: {
|
||
type: 'string',
|
||
description: 'Free-text task or area (e.g. kernel init, seed RPC, shell)'
|
||
},
|
||
paths_touched: {
|
||
type: 'string',
|
||
description:
|
||
'Optional comma-separated path-like strings from the repo (forward slashes ok)'
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'runtime_diagnostic_bundle',
|
||
description:
|
||
'Non-secret snapshot: ctx API version, optional resource status, and every readable /proc/bare_os file. Prefer over many separate read_proc_file calls.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'search_replace',
|
||
description:
|
||
'Replace old_string with new_string in a file. Match must be unique unless replace_all is true. Same uniqueness rules as Grok Build edit_file.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
path: { type: 'string' },
|
||
file_path: { type: 'string', description: 'Alias for path' },
|
||
old_string: { type: 'string' },
|
||
new_string: { type: 'string' },
|
||
replace_all: { type: 'boolean' }
|
||
},
|
||
required: ['old_string', 'new_string']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'glob_files',
|
||
description:
|
||
'Walk the VFS from root and return paths matching a glob (supports ** and *). Prefer this over run_command find/ls.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
pattern: {
|
||
type: 'string',
|
||
description: 'Glob such as **/*.js or src/**/foo.md'
|
||
},
|
||
root: {
|
||
type: 'string',
|
||
description: 'Directory to walk (default session home)'
|
||
},
|
||
max_results: { type: 'integer', description: 'Default 100, cap 400' }
|
||
},
|
||
required: ['pattern']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'todo_write',
|
||
description:
|
||
'Create or update the session todo list (Grok-style). merge=true updates by id; merge=false replaces the list.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
todos: {
|
||
type: 'array',
|
||
description: 'Items with id, optional content, status pending|in_progress|completed|cancelled',
|
||
items: {
|
||
type: 'object',
|
||
properties: {
|
||
id: { type: 'string' },
|
||
content: { type: 'string' },
|
||
status: { type: 'string' }
|
||
},
|
||
required: ['id']
|
||
}
|
||
},
|
||
merge: {
|
||
type: 'boolean',
|
||
description: 'Default true: update matching ids, keep others'
|
||
}
|
||
},
|
||
required: ['todos']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'memory_search',
|
||
description:
|
||
'Search ~/.agent/workspace/memory, MEMORY.md, and compact.md by keyword (guest-safe, no embeddings).',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
query: { type: 'string' },
|
||
max_hits: { type: 'integer', description: 'Default 8' }
|
||
},
|
||
required: ['query']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'memory_get',
|
||
description:
|
||
'Read one memory file. Path must be under ~/.agent/workspace/memory or a named file there.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
path: { type: 'string', description: 'Absolute path or basename under workspace/memory' },
|
||
max_bytes: { type: 'integer' }
|
||
},
|
||
required: ['path']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'enter_plan_mode',
|
||
description:
|
||
'Switch to read-only plan mode. Writes are denied except ~/.agent/plan.md until exit_plan_mode.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
note: { type: 'string', description: 'Optional starter text appended to plan.md' }
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'exit_plan_mode',
|
||
description: 'Leave plan mode and allow mutating tools again.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
summary: { type: 'string' }
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'ask_user_question',
|
||
description:
|
||
'Pose one or more multiple-choice questions to the user (Grok-style). Persists to ~/.agent/ask.json.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
questions: {
|
||
type: 'array',
|
||
items: {
|
||
type: 'object',
|
||
properties: {
|
||
question: { type: 'string' },
|
||
options: {
|
||
type: 'array',
|
||
items: {
|
||
type: 'object',
|
||
properties: {
|
||
label: { type: 'string' },
|
||
description: { type: 'string' }
|
||
}
|
||
}
|
||
},
|
||
multi_select: { type: 'boolean' }
|
||
},
|
||
required: ['question']
|
||
}
|
||
}
|
||
},
|
||
required: ['questions']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'grep',
|
||
description:
|
||
'Search file contents with a JS regular expression (Grok-style, VFS-native). Prefer this over run_command grep. Supports glob, ignore_case, context lines, and files_with_matches.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
pattern: {
|
||
type: 'string',
|
||
description: 'JavaScript regular expression (no surrounding slashes)'
|
||
},
|
||
path: {
|
||
type: 'string',
|
||
description: 'Directory or file to search (default session home)'
|
||
},
|
||
root: { type: 'string', description: 'Alias for path' },
|
||
glob: {
|
||
type: 'string',
|
||
description: 'Optional file glob such as **/*.js'
|
||
},
|
||
ignore_case: { type: 'boolean' },
|
||
before: { type: 'integer', description: 'Context lines before each match' },
|
||
after: { type: 'integer', description: 'Context lines after each match' },
|
||
context: { type: 'integer', description: 'Context lines before and after' },
|
||
max_matches: { type: 'integer', description: 'Default 50, cap 200' },
|
||
files_with_matches: {
|
||
type: 'boolean',
|
||
description: 'Return matching paths only'
|
||
},
|
||
output_mode: {
|
||
type: 'string',
|
||
description: 'content (default) | files_with_matches | count'
|
||
}
|
||
},
|
||
required: ['pattern']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'apply_patch',
|
||
description:
|
||
'Apply a Codex/Grok multi-file patch (*** Begin Patch … *** End Patch). Supports *** Add File, *** Delete File, *** Update File, optional *** Move to, and @@ hunks with + / - / context lines. Prefer this for multi-hunk or multi-file edits.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
patch: { type: 'string', description: 'Full apply_patch document' },
|
||
input: { type: 'string', description: 'Alias for patch' }
|
||
},
|
||
required: ['patch']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'update_goal',
|
||
description:
|
||
'Report progress on the current autonomous/session goal. completed=true ends the goal. blocked_reason is a failure signal after 3+ failed attempts — never use it for success.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
completed: { type: 'boolean' },
|
||
message: { type: 'string', description: 'Short progress or completion note' },
|
||
blocked_reason: { type: 'string' }
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'web_search',
|
||
description:
|
||
'Search the public web (DuckDuckGo instant answers via the same HTTP policy as web_fetch / wget). Use for current facts, docs, and error lookup. Then web_fetch promising URLs.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
query: { type: 'string' },
|
||
max_results: { type: 'integer', description: 'Default 8, cap 16' }
|
||
},
|
||
required: ['query']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'git_status',
|
||
description:
|
||
'Guest git status --short plus diff --stat (isomorphic-git /bin/git). Prefer this over parsing git via run_command when you only need a snapshot.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
cwd: {
|
||
type: 'string',
|
||
description: 'Repo directory (default PWD or home)'
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'memory_append',
|
||
description:
|
||
'Append a durable FACT / CHECK / RISK / HANDOFF line to MEMORY.md or today\'s daily log. Prefer this over write_file for memory.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
text: { type: 'string', description: 'What to remember' },
|
||
kind: {
|
||
type: 'string',
|
||
enum: ['FACT', 'CHECK', 'RISK', 'HANDOFF', 'NOTE'],
|
||
description: 'Ledger tag (default NOTE)'
|
||
},
|
||
daily: {
|
||
type: 'boolean',
|
||
description: 'Append to memory/YYYY-MM-DD.md instead of MEMORY.md'
|
||
}
|
||
},
|
||
required: ['text']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'list_skills',
|
||
description:
|
||
'List discovered SKILL.md ids from workspace/skills and ~/.agent/skills. Use read_skill to load one.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
max: { type: 'integer', description: 'Max entries (default 40)' }
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'list_agent_tools',
|
||
description:
|
||
'Return the live callable tool registry (name, description, parameter keys). Use this when the user asks what tools you have. Skills and /bin names are not in this list.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
name: {
|
||
type: 'string',
|
||
description: 'Optional tool name or substring to describe one entry'
|
||
}
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'schedule_task',
|
||
description:
|
||
'Create or replace a guest timer that re-runs the agent (Grok scheduler, mapped to ~/.config/bare-os/timers). Interval like 5m, 2h, 1d, or five cron fields. Max 8 timers on the guest.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
id: { type: 'string', description: 'Timer id (stored as agent-<id>.timer)' },
|
||
interval: { type: 'string', description: '5m, 2h, 1d, or cron (min hour day month dow)' },
|
||
prompt: { type: 'string', description: 'Task the agent should run on each fire' },
|
||
auto: {
|
||
type: 'boolean',
|
||
description: 'Pass --auto (default true)'
|
||
}
|
||
},
|
||
required: ['interval', 'prompt']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'unschedule_task',
|
||
description: 'Delete a guest agent timer by id (agent-<id>.timer).',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
id: { type: 'string' }
|
||
},
|
||
required: ['id']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'list_scheduled',
|
||
description:
|
||
'List guest agent timers (agent-*.timer) under ~/.config/bare-os/timers, with previews.',
|
||
parameters: { type: 'object', properties: {} }
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'fuzzy_find',
|
||
description:
|
||
'Fuzzy-search file names under a root (Grok-style). Prefer this when you remember part of a filename.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
query: { type: 'string' },
|
||
root: { type: 'string', description: 'Directory to walk (default home)' },
|
||
max: { type: 'integer', description: 'Default 20, cap 80' }
|
||
},
|
||
required: ['query']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'read_many',
|
||
description:
|
||
'Read several UTF-8 files in one call (bounded). Prefer over many read_file calls for a small set.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
paths: { type: 'array', items: { type: 'string' } },
|
||
max_bytes_each: { type: 'integer', description: 'Default 32000' }
|
||
},
|
||
required: ['paths']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'wait_for',
|
||
description:
|
||
'Poll a file or guest command until a regex matches, or timeout (Grok monitor lite; sync).',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
pattern: { type: 'string', description: 'JS regex' },
|
||
path: { type: 'string', description: 'File to poll' },
|
||
command: { type: 'string', description: 'Guest command whose output is polled' },
|
||
timeout_ms: { type: 'integer', description: 'Default 15000, cap 120000' },
|
||
interval_ms: { type: 'integer', description: 'Default 400, min 100' },
|
||
ignore_case: { type: 'boolean' }
|
||
},
|
||
required: ['pattern']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'undo_last_edit',
|
||
description:
|
||
'Restore the last file snapshot from ~/.agent/edits.json (write_file / edit / apply_patch / delete).',
|
||
parameters: { type: 'object', properties: {} }
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'git_diff',
|
||
description: 'git diff (optional path / --stat) via /bin/git. Prefer over raw run_command.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
cwd: { type: 'string' },
|
||
path: { type: 'string' },
|
||
stat: { type: 'boolean', description: 'Only --stat (default false)' }
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'history_search',
|
||
description: 'Search this session\'s ~/.agent/history.json by keyword.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
query: { type: 'string' },
|
||
max: { type: 'integer' }
|
||
},
|
||
required: ['query']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'git_log',
|
||
description:
|
||
'git log --oneline (optional -N / path) via /bin/git. Prefer over raw run_command.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
cwd: { type: 'string' },
|
||
max: { type: 'integer', description: 'Default 20, cap 80' },
|
||
path: { type: 'string' }
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'git_show',
|
||
description: 'git show <rev> (optional path / --stat) via /bin/git.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
cwd: { type: 'string' },
|
||
rev: { type: 'string', description: 'Commit-ish (default HEAD)' },
|
||
path: { type: 'string' },
|
||
stat: { type: 'boolean' }
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'git_blame',
|
||
description: 'git blame a file via /bin/git.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
cwd: { type: 'string' },
|
||
path: { type: 'string' }
|
||
},
|
||
required: ['path']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'copy_path',
|
||
description:
|
||
'Copy a file or directory on the VFS (parents created). Prefer this over run_command cp.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
from_path: { type: 'string' },
|
||
to_path: { type: 'string' }
|
||
},
|
||
required: ['from_path', 'to_path']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'diff_files',
|
||
description:
|
||
'Unified diff of two UTF-8 files (no git). Prefer this when comparing two paths that are not a git hunk.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
from_path: { type: 'string' },
|
||
to_path: { type: 'string' },
|
||
context: { type: 'integer', description: 'Context lines (default 3)' }
|
||
},
|
||
required: ['from_path', 'to_path']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'find_symbol',
|
||
description:
|
||
'Find likely definitions of a symbol (function/class/const/def/fn) under a root. Prefer over ad-hoc grep for go-to-definition.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
name: { type: 'string' },
|
||
root: { type: 'string' },
|
||
glob: { type: 'string' },
|
||
max: { type: 'integer' }
|
||
},
|
||
required: ['name']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'create_skill',
|
||
description:
|
||
'Write a Grok-style SKILL.md (YAML frontmatter + body) under ~/.agent/workspace/skills/<id>/.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
id: { type: 'string', description: 'Folder name (kebab-case)' },
|
||
name: { type: 'string' },
|
||
description: { type: 'string' },
|
||
body: { type: 'string', description: 'Markdown instructions after frontmatter' }
|
||
},
|
||
required: ['id', 'description']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'remember',
|
||
description:
|
||
'Save a durable FACT to MEMORY.md now (Grok /remember). Same store as memory_append.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
text: { type: 'string' },
|
||
daily: { type: 'boolean' }
|
||
},
|
||
required: ['text']
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'rewind_session',
|
||
description:
|
||
'Grok /rewind: drop the last N user turns from ~/.agent/history.json (and everything after). Default 1 turn.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
steps: { type: 'integer', description: 'How many user turns to drop (default 1)' },
|
||
user_index: { type: 'integer', description: 'Rewind to this 0-based user turn instead' },
|
||
keep_user: { type: 'boolean', description: 'Keep the target user prompt' }
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'export_session',
|
||
description:
|
||
'Grok /export: write the current chat history as Markdown. Default ~/.agent/export.md.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
path: { type: 'string' }
|
||
}
|
||
}
|
||
}
|
||
},
|
||
{
|
||
type: 'function',
|
||
function: {
|
||
name: 'task_complete',
|
||
description:
|
||
'Call when the user task is fully done. Provide a concise summary.',
|
||
parameters: {
|
||
type: 'object',
|
||
properties: {
|
||
summary: { type: 'string' }
|
||
},
|
||
required: ['summary']
|
||
}
|
||
}
|
||
}
|
||
]
|
||
}
|
||
|
||
/**
|
||
* Live tool registry derived from bareAgentToolDefinitions (never hand-maintained).
|
||
* @param {unknown[]} [tools]
|
||
* @returns {{ name: string, description: string, params: string[] }[]}
|
||
*/
|
||
function bareAgentToolCatalog(tools) {
|
||
const src =
|
||
Array.isArray(tools) && tools.length ? tools : bareAgentToolDefinitions()
|
||
/** @type {{ name: string, description: string, params: string[] }[]} */
|
||
const out = []
|
||
/** @type {Record<string, number>} */
|
||
const seen = {}
|
||
for (const t of src) {
|
||
if (!t || typeof t !== 'object') continue
|
||
const o = /** @type {Record<string, unknown>} */ (t)
|
||
const fn =
|
||
o.function && typeof o.function === 'object'
|
||
? /** @type {Record<string, unknown>} */ (o.function)
|
||
: o
|
||
const name = typeof fn.name === 'string' ? fn.name.trim() : ''
|
||
if (!name || seen[name]) continue
|
||
seen[name] = 1
|
||
const description =
|
||
typeof fn.description === 'string'
|
||
? fn.description.replace(/\s+/g, ' ').trim()
|
||
: ''
|
||
const paramsRoot =
|
||
fn.parameters && typeof fn.parameters === 'object'
|
||
? /** @type {Record<string, unknown>} */ (fn.parameters)
|
||
: {}
|
||
const props =
|
||
paramsRoot.properties &&
|
||
typeof paramsRoot.properties === 'object' &&
|
||
!Array.isArray(paramsRoot.properties)
|
||
? /** @type {Record<string, unknown>} */ (paramsRoot.properties)
|
||
: {}
|
||
out.push({ name, description, params: Object.keys(props) })
|
||
}
|
||
return out
|
||
}
|
||
|
||
/**
|
||
* System-prompt block. Placed last so small local models see the real tool
|
||
* names instead of the skills index.
|
||
* @param {unknown[]} [tools]
|
||
*/
|
||
function bareAgentToolCatalogPrompt(tools) {
|
||
const cat = bareAgentToolCatalog(tools)
|
||
const lines = [
|
||
'AVAILABLE TOOLS (' +
|
||
cat.length +
|
||
' callable functions — live registry)',
|
||
'These names are the only functions you can call. Skills such as ctx-api-change, docs-contract-update, hdms, and holesail are playbooks: load them with read_skill. Guest /bin names such as ctx-baredoctor, hdms, curl, and holepunch are commands for run_command, not tools. curl/wget/ip are run_command — never run_js_script.',
|
||
'When the user asks what tools you have or what you can do, list every name below. Do not invent names. Do not list skills as tools.',
|
||
'To call a tool, emit exactly:',
|
||
'<tool_call>{"name":"TOOL_NAME","arguments":{}}</tool_call>',
|
||
'You may call list_agent_tools to reprint this catalog.',
|
||
''
|
||
]
|
||
for (const t of cat) {
|
||
const desc =
|
||
t.description.length > 110
|
||
? t.description.slice(0, 107) + '...'
|
||
: t.description
|
||
const params = t.params.length ? ' (' + t.params.join(', ') + ')' : ''
|
||
lines.push(
|
||
'- ' + t.name + params + (desc ? ' — ' + desc : '')
|
||
)
|
||
}
|
||
return lines.join('\n')
|
||
}
|