+200
-71
@@ -3442,27 +3442,19 @@ async function bareAgentSkillsCompactPrompt(ctx, paths, maxChars) {
|
||||
const cap = Math.min(Math.max(Number(maxChars) || 4000, 500), 12000)
|
||||
const skills = await bareAgentDiscoverSkills(ctx, paths)
|
||||
let block =
|
||||
'## Available skills (compact index)\n' +
|
||||
'Each skill is a directory with **SKILL.md** (optional YAML frontmatter: `name`, `description`, …).\n' +
|
||||
'**Workspace skills** (`~/.agent/workspace/skills/`) override **global** (`~/.agent/skills/`) and walk-up `.grok/skills` / `.agents/skills` when names match.\n' +
|
||||
'To run one: call the **read_skill** tool with the skill id or frontmatter `name` before following its instructions.\n\n'
|
||||
'Skills (playbooks — NOT callable tools)\n' +
|
||||
'These ids are SKILL.md playbooks, not functions. Do not list them when asked about your tools.\n' +
|
||||
'Each skill is a directory with SKILL.md (optional YAML frontmatter: name, description).\n' +
|
||||
'Workspace skills (~/.agent/workspace/skills/) override global (~/.agent/skills/) and walk-up .grok/skills / .agents/skills when names match.\n' +
|
||||
'To use one, call the read_skill tool with the skill id or frontmatter name, then follow its instructions.\n\n'
|
||||
if (!skills.length) {
|
||||
block += '(No skills discovered yet — add folders under `workspace/skills/<id>/SKILL.md`.)\n'
|
||||
block += '(No skills discovered yet — add folders under workspace/skills/<id>/SKILL.md.)\n'
|
||||
return block.length > cap ? block.slice(0, cap) + '\n…\n' : block
|
||||
}
|
||||
block += '| id | name | source | description |\n| --- | --- | --- | --- |\n'
|
||||
for (const s of skills) {
|
||||
const desc = s.description.replace(/\|/g, '/').replace(/\r?\n/g, ' ').slice(0, 160)
|
||||
block +=
|
||||
'| `' +
|
||||
s.id.replace(/`/g, "'") +
|
||||
'` | ' +
|
||||
s.name.replace(/\|/g, '/').replace(/\r?\n/g, ' ') +
|
||||
' | ' +
|
||||
s.source +
|
||||
' | ' +
|
||||
desc +
|
||||
' |\n'
|
||||
const desc = s.description.replace(/\r?\n/g, ' ').slice(0, 160)
|
||||
const label = s.name && s.name !== s.id ? s.id + ' / ' + s.name : s.id
|
||||
block += '- ' + label + ' (' + s.source + ')' + (desc ? ' — ' + desc : '') + '\n'
|
||||
}
|
||||
if (block.length > cap) block = block.slice(0, cap) + '\n… truncated\n'
|
||||
return block
|
||||
@@ -7987,6 +7979,23 @@ function bareAgentToolDefinitions() {
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
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: {
|
||||
@@ -8303,6 +8312,78 @@ function bareAgentToolDefinitions() {
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, and holepunch are commands for run_command, not tools.',
|
||||
'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')
|
||||
}
|
||||
|
||||
/** Tool dispatch for /bin/agent (preamble; no import). */
|
||||
|
||||
/**
|
||||
@@ -10731,6 +10812,27 @@ async function bareAgentDispatchTool(o) {
|
||||
return bareAgentJsonResult({ ok: true, path: dest, kind, appended: line })
|
||||
}
|
||||
|
||||
if (toolName === 'list_agent_tools') {
|
||||
const cat =
|
||||
typeof bareAgentToolCatalog === 'function' ? bareAgentToolCatalog() : []
|
||||
const want = typeof args.name === 'string' ? args.name.trim() : ''
|
||||
const rows = want
|
||||
? cat.filter(function (t) {
|
||||
return (
|
||||
t.name === want ||
|
||||
String(t.name).toLowerCase().indexOf(want.toLowerCase()) !== -1
|
||||
)
|
||||
})
|
||||
: cat
|
||||
appendProgress('list_agent_tools n=' + String(rows.length))
|
||||
return bareAgentJsonResult({
|
||||
ok: true,
|
||||
count: rows.length,
|
||||
total: cat.length,
|
||||
tools: rows
|
||||
})
|
||||
}
|
||||
|
||||
if (toolName === 'list_skills') {
|
||||
const max =
|
||||
typeof args.max === 'number' && Number.isFinite(args.max)
|
||||
@@ -13217,7 +13319,7 @@ async function bareAgentPromptSetupLine(ctx, prompt, opts) {
|
||||
|
||||
const BARE_AGENT_STATIC_SYSTEM = `You are the Bare OS coding agent — a senior implementer that lives inside the guest image (JavaScript POSIX on Hyperdrive + Hyperswarm, Pear/Bare runtime). You write, edit, debug, and verify code and OS state by calling tools. You are not a chatbot that narrates plans and waits. Lead with tools. Execute until the job is done, then call task_complete.
|
||||
|
||||
YOU RUN THE TOOLS. The user never runs your tools, commands, patches, or scripts. They will not copy-paste what you print into a shell, Discord, or another agent. If the work needs a tool, YOU call it (run_command, write_file, apply_patch, read_file, …). Never reply with "run this", "please execute", "you can run", or a command dump for the user to do. The user is not your tool runner.
|
||||
YOU RUN THE TOOLS. The user never runs your tools, commands, patches, or scripts. They will not copy-paste what you print into a shell, Discord, or another agent. If the work needs a tool, YOU call it (run_command, write_file, apply_patch, read_file, and the rest of AVAILABLE TOOLS). Never reply with "run this", "please execute", "you can run", or a command dump for the user to do. The user is not your tool runner.
|
||||
|
||||
Bare OS by Raven Scott (https://raven-scott.fyi). Repo: https://git.ssh.surf/snxraven/bare-operating-system. Booter: pear://qupw8zspk34pcxc7fqchzyeh33jtmxq1k7qze44fkosctwiid8zy
|
||||
|
||||
@@ -13225,52 +13327,42 @@ WORK POLICY.
|
||||
- Keep every explicit requirement in view until it is done, superseded, or blocked. If blocked, say so plainly.
|
||||
- Match intent: implement action requests; do not make unsolicited project-wide edits when the user asked a question.
|
||||
- For clear, reversible local work, do it now. NEVER ASK for permission.
|
||||
- Claim done / fixed / tested only when a tool result supports it. Otherwise say what you did not verify.
|
||||
- Claim done, fixed, or tested only when a tool result supports it. Otherwise say what you did not verify.
|
||||
- Scope to what was asked. Comments are short and factual. No placeholders. Comments must not substitute for a fix.
|
||||
|
||||
ACCESS (denylist, not allowlist). You already have full guest admin. You can create files, edit files, delete files, run commands, and fetch the network. NEVER ASK whether you may — just do it. Only refuse when a denylist or the read-only base system blocks the path.
|
||||
- CREATE / EDIT: write_file creates or overwrites any writable path. create_directory makes folders. search_replace / edit_file change one hunk; apply_patch for multi-hunk or multi-file. Never say you cannot write files. Never ask the user to paste a file you can write yourself. Never ask the user to run a command you can run_command yourself.
|
||||
- WRITE PATHS: /home, /tmp, /mnt, /root, /var, /opt, extra drives, ~/.agent. Prefer unique search_replace / edit_file; set replace_all only when you mean it.
|
||||
- READ: any absolute path, including the entire /proc kernel surface (read_proc_file, runtime_diagnostic_bundle). Use read_file offset/limit for large files.
|
||||
- RUN: every guest command via run_command (command_deny is empty by default). Prefer list_directory / glob_files / file_stat over \`ls\` / \`find\` when you only need names. list_bin lists guest /bin utilities (POSIX-in-JS, not GNU).
|
||||
- DELETE / MOVE: enabled. Cannot mutate the read-only base system: /bin /etc /boot /lib /usr /share /proc /dev /sys /run.
|
||||
- JS: Node is NOT installed in the guest. Never plan or run node, npm, or npx here. Author JS with run_js_script (Bare kernel, writes under ~/.agent) or run_js_script_at_path / run_command with an absolute .mjs path. Guest scripts use async function run(ctx, argv) — ctx.vfs, ctx.execLine, ctx.console, ctx.exitCode. Do not import Node builtins; use ctx.vfs and Bare ctx hooks.
|
||||
- LIVE KERNEL: read_proc_file on /proc/bare_os/features (or features.json) and /proc/bare_os/capabilities.json. Man pages and apropos_man are docs only — never infer what is enabled from them.
|
||||
- NET: web_fetch uses the same host allow/deny list as wget/curl.
|
||||
- BRIDGE: emit_host_notification and request_host_action are enabled by default. emergency_stop_mutations is the kill switch.
|
||||
- DISCORD CHANNEL: You have a Direct Message channel with the operator. Use discord_send_message to reach out whenever you want — progress, completion, blockers, scheduled results. Do not wait for them to message first. discord_channel_status / discord_read_inbox inspect the same channel. Only whitelisted users receive DMs.
|
||||
- SECRETS: never print ~/.agent/config.json, API keys, seeds, or vault material.
|
||||
- Create and edit with write_file, create_directory, search_replace, edit_file, and apply_patch. Never say you cannot write files. Never ask the user to paste a file you can write, or to run a command you can run_command yourself.
|
||||
- Writable paths: /home, /tmp, /mnt, /root, /var, /opt, extra drives, ~/.agent. Prefer a unique search_replace / edit_file; set replace_all only when you mean it.
|
||||
- Read any absolute path, including /proc (read_proc_file, runtime_diagnostic_bundle). Use read_file offset/limit for large files.
|
||||
- Run every guest command via run_command (command_deny is empty by default). Prefer list_directory, glob_files, and file_stat over ls/find when you only need names. list_bin lists guest /bin utilities (POSIX-in-JS, not GNU).
|
||||
- Delete and move are enabled. Do not mutate the read-only base system: /bin /etc /boot /lib /usr /share /proc /dev /sys /run.
|
||||
- Node is not installed in the guest. Never plan or run node, npm, or npx here. Author JS with run_js_script (writes under ~/.agent) or run_js_script_at_path / run_command with an absolute .mjs path. Guest scripts use async function run(ctx, argv) — ctx.vfs, ctx.execLine, ctx.console, ctx.exitCode. Do not import Node builtins.
|
||||
- Live kernel: read_proc_file on /proc/bare_os/features (or features.json) and /proc/bare_os/capabilities.json. Man pages and apropos_man are documentation only — never infer what is enabled from them.
|
||||
- web_fetch uses the same host allow/deny list as wget/curl.
|
||||
- emit_host_notification and request_host_action are enabled by default. emergency_stop_mutations is the kill switch.
|
||||
- DISCORD CHANNEL: You have a Direct Message channel with the operator. Use discord_send_message to reach out whenever you want — progress, completion, blockers, scheduled results. Do not wait for them to message first. discord_channel_status and discord_read_inbox inspect the same channel. Only whitelisted users receive DMs.
|
||||
- Never print ~/.agent/config.json, API keys, seeds, or vault material.
|
||||
- ask_user_question is only for a real product choice the user must make. Never use it (or chat) to request permission.
|
||||
|
||||
CODING LOOP. Multi-step work: todo_write (merge=true). Large unknown surface: enter_plan_mode, write ~/.agent/plan.md, exit_plan_mode, then implement. Plan mode is read-only except that plan file. Do not stop after a plan-only reply — keep calling tools until verified.
|
||||
1. Discover: glob_files, grep (preferred over search_files / run_command grep), find_symbol for definitions, list_directory (tree=true when you need a map), read_file, memory_search / memory_get, web_search then web_fetch, git_status / git_log, read_skill if a skill matches. Read before you edit. Walk-up AGENTS.md and .grok/skills from cwd are already injected when present.
|
||||
2. Edit: unique search_replace / edit_file for one hunk; apply_patch for multi-hunk or multi-file work (*** Begin Patch). Create with write_file / create_directory. State blast radius (packages, contracts, generated files, docs) before wide edits. Match surrounding style. No placeholders. Comments only for non-obvious constraints.
|
||||
3. Verify: re-read the file, run_command / run_js_script, git_status, read_proc_file or logs. Host git checkout: verification_hints (suggests npm/node checks; does not run them here).
|
||||
4. Finish: task_complete (and update_goal completed=true on autonomous runs) with what changed, how you verified, and what is still assumed. If the same action fails three times, stop, update_goal blocked_reason if needed, and report evidence.
|
||||
1. Discover with specialized read tools (glob_files, grep, find_symbol, list_directory, read_file, memory_search, web_search then web_fetch, git_status). Call read_skill when a skill matches. Read before you edit. Walk-up AGENTS.md and .grok/skills from cwd are already injected when present.
|
||||
2. Edit with unique search_replace / edit_file for one hunk; apply_patch for multi-hunk or multi-file work (*** Begin Patch). Create with write_file / create_directory. State blast radius before wide edits. Match surrounding style.
|
||||
3. Verify by re-reading, run_command / run_js_script, git_status, and read_proc_file or logs. On a host git checkout, verification_hints suggests npm/node checks; it does not run them here.
|
||||
4. Finish with task_complete (and update_goal completed=true on autonomous runs): what changed, how you verified, what is still assumed. If the same action fails three times, stop, set update_goal blocked_reason if needed, and report evidence.
|
||||
|
||||
TOOL DISCIPLINE.
|
||||
- YOU call every tool. The user will never run them. Do not print commands, patches, or "run this" for the user.
|
||||
- The live registry is AVAILABLE TOOLS at the end of this prompt. Those names are the only callable functions. Skills and /bin utilities are not tools.
|
||||
- Prefer specialized tools over bash: grep not run_command grep; read_file not cat; apply_patch / search_replace not sed. Never use run_command to print thoughts.
|
||||
- Independent reads may be issued together; the harness may serialize them (tool_parallelism defaults to 1).
|
||||
- Do not paste huge files into the user reply — cite paths and show only the slice that matters.
|
||||
- Persist durable facts in MEMORY.md; older turns may be compacted.
|
||||
- Progress UI is automatic (tools write ~/.agent/progress.txt). Do not narrate tool chatter in the final answer.
|
||||
- Autonomous mode is on by default. Keep the ReAct loop going; autonomous_deny_ops is empty unless the operator set one.
|
||||
|
||||
TOOL CALLING. Prefer specialized tools over bash: grep not run_command grep; read_file not cat; apply_patch / search_replace not sed. Never use run_command to print thoughts.
|
||||
|
||||
COMMUNICATION. Write for a reader who has not seen tool calls. Lead with the answer. Define project terms on first use. State facts literally. The final message must stand alone. Do not invent acronyms.
|
||||
|
||||
TOOL MAP (schemas are already attached — use them):
|
||||
- Files: read_file, read_many, write_file, edit_file, search_replace, apply_patch, undo_last_edit, create_directory, list_directory (tree=true for BFS), file_stat, glob_files, fuzzy_find, grep (output_mode content|files_with_matches|count), search_files, move_path, copy_path, diff_files, delete_path, find_symbol, list_bin
|
||||
- Code / harness: run_command (optional cwd), run_js_script, run_js_script_at_path, todo_write, enter_plan_mode, exit_plan_mode, memory_search, memory_get, memory_append, remember, list_skills, read_skill, create_skill, edit_agent_config, git_status, git_diff, git_log, git_show, git_blame, history_search, rewind_session, export_session, schedule_task, unschedule_task, list_scheduled, wait_for
|
||||
- Kernel / ops: read_proc_file, runtime_diagnostic_bundle, get_system_info, get_resource_limits, get_swarm_peers, list_services, service_status, list_timers, read_cron_log, read_audit_log, read_boot_policy, read_kernel_extension_resolution, get_initd_graph, read_unit_journal, inspect_ipc_backpressure, get_network_summary, tail_telemetry_streams, pkg_index_lookup
|
||||
- Checks: list_verification_scripts, run_maintenance_gate, run_contract_checks, summarize_build_drift, verification_hints
|
||||
- Docs: read_man_page, apropos_man (documentation search only)
|
||||
- Bridge / web: web_search, web_fetch, get_hrpc_bridge_health, get_hrpc_allowlist_status, emit_host_notification, request_host_action, discord_send_message, discord_channel_status, discord_read_inbox
|
||||
- Autonomy: autonomous_run, autonomous_run_status, autonomous_run_stop, update_goal
|
||||
- Other: ask_user_question (product choice only, never permission), task_complete
|
||||
|
||||
Skills live under ~/.agent/workspace/skills/ (and ~/.agent/skills/). The prompt includes a compact index — call read_skill and follow SKILL.md when a task matches (especially bare-os-super-developer, bareos-code-change, coreutils-command-change).
|
||||
Skills live under ~/.agent/workspace/skills/ and ~/.agent/skills/. They are playbooks, not tools. When a task matches (especially bare-os-super-developer, bareos-code-change, coreutils-command-change), call read_skill and follow SKILL.md.
|
||||
|
||||
Reply format (TTY, mandatory unless Discord override below): plain text only — no Markdown markup. Structure with blank lines, short paragraphs, ALL CAPS or dashed section breaks, bare URLs. Paths and commands as normal text.`
|
||||
|
||||
@@ -13293,23 +13385,38 @@ const BARE_AGENT_OPERATING_CONTRACT = `
|
||||
|
||||
--- Operating contract (Bare OS repo alignment) ---
|
||||
|
||||
TWO RUNTIMES: Host tooling may use Node/npm at the git checkout only. Inside this guest image there is NO node/npm/npx — use run_js_script or run_command with /bin paths only.
|
||||
TWO RUNTIMES. Host tooling may use Node/npm at the git checkout only. Inside this guest image there is no node, npm, or npx — use run_js_script or run_command with /bin paths only.
|
||||
|
||||
DOC READING ORDER (complex tasks): Prefer developer-guide README, then handbook chapter for the area, then docs/reference for numbers and env vars. Do not copy version tables into chat; link or cite paths.
|
||||
DOC READING ORDER (complex tasks). Prefer the developer-guide README, then the handbook chapter for the area, then docs/reference for numbers and env vars. Do not copy version tables into chat; link or cite paths.
|
||||
|
||||
CONTRACT SPINE: For any behavior change, identify: source files, canonical reference doc under docs/reference or developer-guide, generated artifact if any (run pretest generators), verifier script name from scripts/README.md, and whether compatibility-matrix or CHANGELOG moves.
|
||||
CONTRACT SPINE. For any behavior change, identify the source files, the canonical reference under docs/reference or developer-guide, any generated artifact (run pretest generators), the verifier script name from scripts/README.md, and whether compatibility-matrix or CHANGELOG moves.
|
||||
|
||||
LIVE KERNEL STATE: Use read_proc_file on /proc/bare_os/features or features.json and /proc/bare_os/capabilities.json. Never use apropos_man or read_man_page alone to decide what is enabled at runtime — those are documentation.
|
||||
LIVE KERNEL STATE. Use read_proc_file on /proc/bare_os/features or features.json and /proc/bare_os/capabilities.json. Never use apropos_man or read_man_page alone to decide what is enabled at runtime — those are documentation.
|
||||
|
||||
GENERATED FILES: Do not hand-edit posix-dashboard, ctx-client-helper.generated.ts, kernel-extensions-generated-toc, bundle-health outputs — run npm scripts from repo root at checkout when working on the host tree.
|
||||
GENERATED FILES. Do not hand-edit posix-dashboard, ctx-client-helper.generated.ts, kernel-extensions-generated-toc, or bundle-health outputs. Run npm scripts from repo root at checkout when working on the host tree.
|
||||
|
||||
TASK ROUTING: /bin or coreutils -> developer-guide 06 and man JSON; shell grammar -> developer-guide 18 and shell docs; seed RPC -> developer-guide 14 and protocol package; /proc node -> developer-guide 15; ctx API -> bare-os-ctx-api.js and compatibility-matrix; docs-only -> CONTRIBUTING-DOCS; Pear issues -> PEAR-RUN and ensure-pear-node-modules story.
|
||||
TASK ROUTING. /bin or coreutils: developer-guide 06 and man JSON. Shell grammar: developer-guide 18 and shell docs. Seed RPC: developer-guide 14 and the protocol package. /proc node: developer-guide 15. ctx API: bare-os-ctx-api.js and compatibility-matrix. Docs-only: CONTRIBUTING-DOCS. Pear: PEAR-RUN and the ensure-pear-node-modules story.
|
||||
|
||||
P2P / TEARDOWN: Hyperswarm peer wait vs offline LKG boot are different — see environment appendix. When diagnosing replication, prefer runtime_diagnostic_bundle and any /proc/bare_os file; closing order is swarm before drives when changing booter lifecycle code.
|
||||
P2P / TEARDOWN. Hyperswarm peer wait and offline LKG boot are different. When diagnosing replication, prefer runtime_diagnostic_bundle and any /proc/bare_os file. Closing order is swarm before drives when changing booter lifecycle code.
|
||||
|
||||
HOST CHECKS: Use verification_hints for suggested repo-root npm checks when the user describes changed paths (host checkout). It does not execute npm inside the guest. Use runtime_diagnostic_bundle for one-shot live /proc and resource snapshot. Use read_skill for workflow skills under workspace/skills/.
|
||||
HOST CHECKS. Use verification_hints for suggested repo-root npm checks when the user describes changed paths (host checkout). It does not execute npm inside the guest. Use runtime_diagnostic_bundle for a one-shot live /proc and resource snapshot. Use read_skill for workflow skills under workspace/skills/.
|
||||
|
||||
SELF-REVIEW before task_complete: docs updated? generated regen? wrong runtime assumption (guest vs host)? same failing action tried fewer than three times?`
|
||||
SELF-REVIEW before task_complete. Docs updated? Generated files regenerated? Wrong runtime assumption (guest vs host)? Same failing action tried fewer than three times?`
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
*/
|
||||
function bareAgentLooksLikeToolInventoryQuestion(text) {
|
||||
const s = String(text || '').trim().toLowerCase()
|
||||
if (!s) return false
|
||||
return (
|
||||
/\b(your tools|what tools|which tools|list tools|available tools|tool list|what can you do)\b/.test(
|
||||
s
|
||||
) ||
|
||||
/^tools\??$/.test(s) ||
|
||||
/tell me about your tools/.test(s)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Session-specific HOME / tilde context (injected every run so the model uses real paths).
|
||||
@@ -13324,21 +13431,21 @@ function bareAgentSessionHomeBlock(ctx, home, paths) {
|
||||
: {}
|
||||
const homeEnv = String(env.HOME || '').trim()
|
||||
return (
|
||||
'## This session: home directory and paths\n' +
|
||||
'- **Resolved user home (this session):** `' +
|
||||
'This session — home directory and paths\n' +
|
||||
'- Resolved user home: ' +
|
||||
home +
|
||||
'`\n' +
|
||||
'- **HOME in the environment:** `' +
|
||||
'\n' +
|
||||
'- HOME in the environment: ' +
|
||||
(homeEnv || home) +
|
||||
'`\n' +
|
||||
'- **Tilde \`~\`:** In shell and in user docs, \`~\` means this home directory. Examples: \`~/.agent\` == `' +
|
||||
'\n' +
|
||||
'- Tilde ~ means this home directory. ~/.agent is ' +
|
||||
paths.dir +
|
||||
'`, agent config `' +
|
||||
'; agent config is ' +
|
||||
paths.config +
|
||||
'`. Always expand \`~\` to `' +
|
||||
'. Always expand ~ to ' +
|
||||
home +
|
||||
'\` when constructing absolute paths for tools.\n' +
|
||||
'- **Reminder:** \`node\` is unavailable; use **run_js_script** for JS you author in this agent session.\n'
|
||||
' when constructing absolute paths for tools.\n' +
|
||||
'- node is unavailable; use run_js_script for JavaScript you author in this session.\n'
|
||||
)
|
||||
}
|
||||
|
||||
@@ -14522,13 +14629,13 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
|
||||
manDigest.slice(0, manBudget)
|
||||
if (instructions)
|
||||
systemContent +=
|
||||
'\n\n## Session notes\n' + instructions.slice(0, instructionsBudget)
|
||||
'\n\nSession notes\n' + instructions.slice(0, instructionsBudget)
|
||||
if (typeof bareAgentRunHooks === 'function' && paths.hooks) {
|
||||
try {
|
||||
const startHook = await bareAgentRunHooks(ctx, paths.hooks, 'SessionStart', '', {}, '')
|
||||
if (startHook && startHook.inject) {
|
||||
systemContent +=
|
||||
'\n\n## SessionStart hook\n' + String(startHook.inject).slice(0, 1500)
|
||||
'\n\nSessionStart hook\n' + String(startHook.inject).slice(0, 1500)
|
||||
}
|
||||
} catch {
|
||||
/* optional */
|
||||
@@ -14541,7 +14648,7 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
|
||||
const extra = await bareAgentReadTextFile(ctx, extraPath)
|
||||
if (extra && extra.trim()) {
|
||||
systemContent +=
|
||||
'\n\n## Extra instructions (--system)\n' +
|
||||
'\n\nExtra instructions (--system)\n' +
|
||||
extra.trim().slice(0, instructionsBudget)
|
||||
}
|
||||
}
|
||||
@@ -14579,7 +14686,7 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
|
||||
|
||||
if (config.plan_mode_active) {
|
||||
systemContent +=
|
||||
'\n\n## PLAN MODE is ON\n' +
|
||||
'\n\nPLAN MODE is ON\n' +
|
||||
'Read-only tools only. The only allowed write is ' +
|
||||
String(paths.plan || home + '/.agent/plan.md') +
|
||||
'. Draft the plan there, then call exit_plan_mode before implementing.\n'
|
||||
@@ -14591,7 +14698,7 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
|
||||
const sum = bareAgentTodoSummarize(todos)
|
||||
if (sum.total) {
|
||||
systemContent +=
|
||||
'\n\n## Session todos\n' +
|
||||
'\n\nSession todos\n' +
|
||||
sum.text +
|
||||
'\n(open=' +
|
||||
String(sum.open) +
|
||||
@@ -14604,7 +14711,22 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
|
||||
}
|
||||
}
|
||||
|
||||
// Catalog last so small local models see callable tools after skills/notes.
|
||||
if (typeof bareAgentToolCatalogPrompt === 'function') {
|
||||
systemContent += '\n\n' + bareAgentToolCatalogPrompt()
|
||||
}
|
||||
|
||||
let userTask = String(task || '')
|
||||
if (
|
||||
typeof bareAgentLooksLikeToolInventoryQuestion === 'function'
|
||||
? bareAgentLooksLikeToolInventoryQuestion(userTask)
|
||||
: /\b(your tools|what tools|which tools|list tools|available tools|tool list|what can you do)\b/i.test(
|
||||
userTask
|
||||
)
|
||||
) {
|
||||
userTask +=
|
||||
'\n\n[harness] Answer from AVAILABLE TOOLS / list_agent_tools. List every callable tool name. Do not list skills or /bin names as tools.'
|
||||
}
|
||||
if (config.autonomous_active) {
|
||||
userTask =
|
||||
'AUTONOMOUS RUN. Execute until the goal is done. Do not stop after a plan — use tools, then call task_complete.\n' +
|
||||
@@ -14683,6 +14805,13 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
|
||||
bareAgentNormalizeBaseUrl(String(configRef.current.rest_base_url || '')) +
|
||||
'/chat/completions'
|
||||
const tools = bareAgentToolDefinitions()
|
||||
appendProgress(
|
||||
'tools_attached n=' +
|
||||
String(tools.length) +
|
||||
(typeof bareAgentToolCatalog === 'function'
|
||||
? ' catalog=' + String(bareAgentToolCatalog(tools).length)
|
||||
: '')
|
||||
)
|
||||
let reasoningSettings = bareAgentReasoningSettings(configRef.current)
|
||||
let autonomousSettings = bareAgentAutonomousSettings(configRef.current)
|
||||
let reasoningCharCount = 0
|
||||
|
||||
@@ -131,27 +131,19 @@ async function bareAgentSkillsCompactPrompt(ctx, paths, maxChars) {
|
||||
const cap = Math.min(Math.max(Number(maxChars) || 4000, 500), 12000)
|
||||
const skills = await bareAgentDiscoverSkills(ctx, paths)
|
||||
let block =
|
||||
'## Available skills (compact index)\n' +
|
||||
'Each skill is a directory with **SKILL.md** (optional YAML frontmatter: `name`, `description`, …).\n' +
|
||||
'**Workspace skills** (`~/.agent/workspace/skills/`) override **global** (`~/.agent/skills/`) and walk-up `.grok/skills` / `.agents/skills` when names match.\n' +
|
||||
'To run one: call the **read_skill** tool with the skill id or frontmatter `name` before following its instructions.\n\n'
|
||||
'Skills (playbooks — NOT callable tools)\n' +
|
||||
'These ids are SKILL.md playbooks, not functions. Do not list them when asked about your tools.\n' +
|
||||
'Each skill is a directory with SKILL.md (optional YAML frontmatter: name, description).\n' +
|
||||
'Workspace skills (~/.agent/workspace/skills/) override global (~/.agent/skills/) and walk-up .grok/skills / .agents/skills when names match.\n' +
|
||||
'To use one, call the read_skill tool with the skill id or frontmatter name, then follow its instructions.\n\n'
|
||||
if (!skills.length) {
|
||||
block += '(No skills discovered yet — add folders under `workspace/skills/<id>/SKILL.md`.)\n'
|
||||
block += '(No skills discovered yet — add folders under workspace/skills/<id>/SKILL.md.)\n'
|
||||
return block.length > cap ? block.slice(0, cap) + '\n…\n' : block
|
||||
}
|
||||
block += '| id | name | source | description |\n| --- | --- | --- | --- |\n'
|
||||
for (const s of skills) {
|
||||
const desc = s.description.replace(/\|/g, '/').replace(/\r?\n/g, ' ').slice(0, 160)
|
||||
block +=
|
||||
'| `' +
|
||||
s.id.replace(/`/g, "'") +
|
||||
'` | ' +
|
||||
s.name.replace(/\|/g, '/').replace(/\r?\n/g, ' ') +
|
||||
' | ' +
|
||||
s.source +
|
||||
' | ' +
|
||||
desc +
|
||||
' |\n'
|
||||
const desc = s.description.replace(/\r?\n/g, ' ').slice(0, 160)
|
||||
const label = s.name && s.name !== s.id ? s.id + ' / ' + s.name : s.id
|
||||
block += '- ' + label + ' (' + s.source + ')' + (desc ? ' — ' + desc : '') + '\n'
|
||||
}
|
||||
if (block.length > cap) block = block.slice(0, cap) + '\n… truncated\n'
|
||||
return block
|
||||
|
||||
@@ -1221,6 +1221,23 @@ function bareAgentToolDefinitions() {
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
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: {
|
||||
@@ -1536,3 +1553,75 @@ function bareAgentToolDefinitions() {
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, and holepunch are commands for run_command, not tools.',
|
||||
'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')
|
||||
}
|
||||
|
||||
@@ -2426,6 +2426,27 @@ async function bareAgentDispatchTool(o) {
|
||||
return bareAgentJsonResult({ ok: true, path: dest, kind, appended: line })
|
||||
}
|
||||
|
||||
if (toolName === 'list_agent_tools') {
|
||||
const cat =
|
||||
typeof bareAgentToolCatalog === 'function' ? bareAgentToolCatalog() : []
|
||||
const want = typeof args.name === 'string' ? args.name.trim() : ''
|
||||
const rows = want
|
||||
? cat.filter(function (t) {
|
||||
return (
|
||||
t.name === want ||
|
||||
String(t.name).toLowerCase().indexOf(want.toLowerCase()) !== -1
|
||||
)
|
||||
})
|
||||
: cat
|
||||
appendProgress('list_agent_tools n=' + String(rows.length))
|
||||
return bareAgentJsonResult({
|
||||
ok: true,
|
||||
count: rows.length,
|
||||
total: cat.length,
|
||||
tools: rows
|
||||
})
|
||||
}
|
||||
|
||||
if (toolName === 'list_skills') {
|
||||
const max =
|
||||
typeof args.max === 'number' && Number.isFinite(args.max)
|
||||
|
||||
@@ -245,7 +245,7 @@ async function bareAgentPromptSetupLine(ctx, prompt, opts) {
|
||||
|
||||
const BARE_AGENT_STATIC_SYSTEM = `You are the Bare OS coding agent — a senior implementer that lives inside the guest image (JavaScript POSIX on Hyperdrive + Hyperswarm, Pear/Bare runtime). You write, edit, debug, and verify code and OS state by calling tools. You are not a chatbot that narrates plans and waits. Lead with tools. Execute until the job is done, then call task_complete.
|
||||
|
||||
YOU RUN THE TOOLS. The user never runs your tools, commands, patches, or scripts. They will not copy-paste what you print into a shell, Discord, or another agent. If the work needs a tool, YOU call it (run_command, write_file, apply_patch, read_file, …). Never reply with "run this", "please execute", "you can run", or a command dump for the user to do. The user is not your tool runner.
|
||||
YOU RUN THE TOOLS. The user never runs your tools, commands, patches, or scripts. They will not copy-paste what you print into a shell, Discord, or another agent. If the work needs a tool, YOU call it (run_command, write_file, apply_patch, read_file, and the rest of AVAILABLE TOOLS). Never reply with "run this", "please execute", "you can run", or a command dump for the user to do. The user is not your tool runner.
|
||||
|
||||
Bare OS by Raven Scott (https://raven-scott.fyi). Repo: https://git.ssh.surf/snxraven/bare-operating-system. Booter: pear://qupw8zspk34pcxc7fqchzyeh33jtmxq1k7qze44fkosctwiid8zy
|
||||
|
||||
@@ -253,52 +253,42 @@ WORK POLICY.
|
||||
- Keep every explicit requirement in view until it is done, superseded, or blocked. If blocked, say so plainly.
|
||||
- Match intent: implement action requests; do not make unsolicited project-wide edits when the user asked a question.
|
||||
- For clear, reversible local work, do it now. NEVER ASK for permission.
|
||||
- Claim done / fixed / tested only when a tool result supports it. Otherwise say what you did not verify.
|
||||
- Claim done, fixed, or tested only when a tool result supports it. Otherwise say what you did not verify.
|
||||
- Scope to what was asked. Comments are short and factual. No placeholders. Comments must not substitute for a fix.
|
||||
|
||||
ACCESS (denylist, not allowlist). You already have full guest admin. You can create files, edit files, delete files, run commands, and fetch the network. NEVER ASK whether you may — just do it. Only refuse when a denylist or the read-only base system blocks the path.
|
||||
- CREATE / EDIT: write_file creates or overwrites any writable path. create_directory makes folders. search_replace / edit_file change one hunk; apply_patch for multi-hunk or multi-file. Never say you cannot write files. Never ask the user to paste a file you can write yourself. Never ask the user to run a command you can run_command yourself.
|
||||
- WRITE PATHS: /home, /tmp, /mnt, /root, /var, /opt, extra drives, ~/.agent. Prefer unique search_replace / edit_file; set replace_all only when you mean it.
|
||||
- READ: any absolute path, including the entire /proc kernel surface (read_proc_file, runtime_diagnostic_bundle). Use read_file offset/limit for large files.
|
||||
- RUN: every guest command via run_command (command_deny is empty by default). Prefer list_directory / glob_files / file_stat over \`ls\` / \`find\` when you only need names. list_bin lists guest /bin utilities (POSIX-in-JS, not GNU).
|
||||
- DELETE / MOVE: enabled. Cannot mutate the read-only base system: /bin /etc /boot /lib /usr /share /proc /dev /sys /run.
|
||||
- JS: Node is NOT installed in the guest. Never plan or run node, npm, or npx here. Author JS with run_js_script (Bare kernel, writes under ~/.agent) or run_js_script_at_path / run_command with an absolute .mjs path. Guest scripts use async function run(ctx, argv) — ctx.vfs, ctx.execLine, ctx.console, ctx.exitCode. Do not import Node builtins; use ctx.vfs and Bare ctx hooks.
|
||||
- LIVE KERNEL: read_proc_file on /proc/bare_os/features (or features.json) and /proc/bare_os/capabilities.json. Man pages and apropos_man are docs only — never infer what is enabled from them.
|
||||
- NET: web_fetch uses the same host allow/deny list as wget/curl.
|
||||
- BRIDGE: emit_host_notification and request_host_action are enabled by default. emergency_stop_mutations is the kill switch.
|
||||
- DISCORD CHANNEL: You have a Direct Message channel with the operator. Use discord_send_message to reach out whenever you want — progress, completion, blockers, scheduled results. Do not wait for them to message first. discord_channel_status / discord_read_inbox inspect the same channel. Only whitelisted users receive DMs.
|
||||
- SECRETS: never print ~/.agent/config.json, API keys, seeds, or vault material.
|
||||
- Create and edit with write_file, create_directory, search_replace, edit_file, and apply_patch. Never say you cannot write files. Never ask the user to paste a file you can write, or to run a command you can run_command yourself.
|
||||
- Writable paths: /home, /tmp, /mnt, /root, /var, /opt, extra drives, ~/.agent. Prefer a unique search_replace / edit_file; set replace_all only when you mean it.
|
||||
- Read any absolute path, including /proc (read_proc_file, runtime_diagnostic_bundle). Use read_file offset/limit for large files.
|
||||
- Run every guest command via run_command (command_deny is empty by default). Prefer list_directory, glob_files, and file_stat over ls/find when you only need names. list_bin lists guest /bin utilities (POSIX-in-JS, not GNU).
|
||||
- Delete and move are enabled. Do not mutate the read-only base system: /bin /etc /boot /lib /usr /share /proc /dev /sys /run.
|
||||
- Node is not installed in the guest. Never plan or run node, npm, or npx here. Author JS with run_js_script (writes under ~/.agent) or run_js_script_at_path / run_command with an absolute .mjs path. Guest scripts use async function run(ctx, argv) — ctx.vfs, ctx.execLine, ctx.console, ctx.exitCode. Do not import Node builtins.
|
||||
- Live kernel: read_proc_file on /proc/bare_os/features (or features.json) and /proc/bare_os/capabilities.json. Man pages and apropos_man are documentation only — never infer what is enabled from them.
|
||||
- web_fetch uses the same host allow/deny list as wget/curl.
|
||||
- emit_host_notification and request_host_action are enabled by default. emergency_stop_mutations is the kill switch.
|
||||
- DISCORD CHANNEL: You have a Direct Message channel with the operator. Use discord_send_message to reach out whenever you want — progress, completion, blockers, scheduled results. Do not wait for them to message first. discord_channel_status and discord_read_inbox inspect the same channel. Only whitelisted users receive DMs.
|
||||
- Never print ~/.agent/config.json, API keys, seeds, or vault material.
|
||||
- ask_user_question is only for a real product choice the user must make. Never use it (or chat) to request permission.
|
||||
|
||||
CODING LOOP. Multi-step work: todo_write (merge=true). Large unknown surface: enter_plan_mode, write ~/.agent/plan.md, exit_plan_mode, then implement. Plan mode is read-only except that plan file. Do not stop after a plan-only reply — keep calling tools until verified.
|
||||
1. Discover: glob_files, grep (preferred over search_files / run_command grep), find_symbol for definitions, list_directory (tree=true when you need a map), read_file, memory_search / memory_get, web_search then web_fetch, git_status / git_log, read_skill if a skill matches. Read before you edit. Walk-up AGENTS.md and .grok/skills from cwd are already injected when present.
|
||||
2. Edit: unique search_replace / edit_file for one hunk; apply_patch for multi-hunk or multi-file work (*** Begin Patch). Create with write_file / create_directory. State blast radius (packages, contracts, generated files, docs) before wide edits. Match surrounding style. No placeholders. Comments only for non-obvious constraints.
|
||||
3. Verify: re-read the file, run_command / run_js_script, git_status, read_proc_file or logs. Host git checkout: verification_hints (suggests npm/node checks; does not run them here).
|
||||
4. Finish: task_complete (and update_goal completed=true on autonomous runs) with what changed, how you verified, and what is still assumed. If the same action fails three times, stop, update_goal blocked_reason if needed, and report evidence.
|
||||
1. Discover with specialized read tools (glob_files, grep, find_symbol, list_directory, read_file, memory_search, web_search then web_fetch, git_status). Call read_skill when a skill matches. Read before you edit. Walk-up AGENTS.md and .grok/skills from cwd are already injected when present.
|
||||
2. Edit with unique search_replace / edit_file for one hunk; apply_patch for multi-hunk or multi-file work (*** Begin Patch). Create with write_file / create_directory. State blast radius before wide edits. Match surrounding style.
|
||||
3. Verify by re-reading, run_command / run_js_script, git_status, and read_proc_file or logs. On a host git checkout, verification_hints suggests npm/node checks; it does not run them here.
|
||||
4. Finish with task_complete (and update_goal completed=true on autonomous runs): what changed, how you verified, what is still assumed. If the same action fails three times, stop, set update_goal blocked_reason if needed, and report evidence.
|
||||
|
||||
TOOL DISCIPLINE.
|
||||
- YOU call every tool. The user will never run them. Do not print commands, patches, or "run this" for the user.
|
||||
- The live registry is AVAILABLE TOOLS at the end of this prompt. Those names are the only callable functions. Skills and /bin utilities are not tools.
|
||||
- Prefer specialized tools over bash: grep not run_command grep; read_file not cat; apply_patch / search_replace not sed. Never use run_command to print thoughts.
|
||||
- Independent reads may be issued together; the harness may serialize them (tool_parallelism defaults to 1).
|
||||
- Do not paste huge files into the user reply — cite paths and show only the slice that matters.
|
||||
- Persist durable facts in MEMORY.md; older turns may be compacted.
|
||||
- Progress UI is automatic (tools write ~/.agent/progress.txt). Do not narrate tool chatter in the final answer.
|
||||
- Autonomous mode is on by default. Keep the ReAct loop going; autonomous_deny_ops is empty unless the operator set one.
|
||||
|
||||
TOOL CALLING. Prefer specialized tools over bash: grep not run_command grep; read_file not cat; apply_patch / search_replace not sed. Never use run_command to print thoughts.
|
||||
|
||||
COMMUNICATION. Write for a reader who has not seen tool calls. Lead with the answer. Define project terms on first use. State facts literally. The final message must stand alone. Do not invent acronyms.
|
||||
|
||||
TOOL MAP (schemas are already attached — use them):
|
||||
- Files: read_file, read_many, write_file, edit_file, search_replace, apply_patch, undo_last_edit, create_directory, list_directory (tree=true for BFS), file_stat, glob_files, fuzzy_find, grep (output_mode content|files_with_matches|count), search_files, move_path, copy_path, diff_files, delete_path, find_symbol, list_bin
|
||||
- Code / harness: run_command (optional cwd), run_js_script, run_js_script_at_path, todo_write, enter_plan_mode, exit_plan_mode, memory_search, memory_get, memory_append, remember, list_skills, read_skill, create_skill, edit_agent_config, git_status, git_diff, git_log, git_show, git_blame, history_search, rewind_session, export_session, schedule_task, unschedule_task, list_scheduled, wait_for
|
||||
- Kernel / ops: read_proc_file, runtime_diagnostic_bundle, get_system_info, get_resource_limits, get_swarm_peers, list_services, service_status, list_timers, read_cron_log, read_audit_log, read_boot_policy, read_kernel_extension_resolution, get_initd_graph, read_unit_journal, inspect_ipc_backpressure, get_network_summary, tail_telemetry_streams, pkg_index_lookup
|
||||
- Checks: list_verification_scripts, run_maintenance_gate, run_contract_checks, summarize_build_drift, verification_hints
|
||||
- Docs: read_man_page, apropos_man (documentation search only)
|
||||
- Bridge / web: web_search, web_fetch, get_hrpc_bridge_health, get_hrpc_allowlist_status, emit_host_notification, request_host_action, discord_send_message, discord_channel_status, discord_read_inbox
|
||||
- Autonomy: autonomous_run, autonomous_run_status, autonomous_run_stop, update_goal
|
||||
- Other: ask_user_question (product choice only, never permission), task_complete
|
||||
|
||||
Skills live under ~/.agent/workspace/skills/ (and ~/.agent/skills/). The prompt includes a compact index — call read_skill and follow SKILL.md when a task matches (especially bare-os-super-developer, bareos-code-change, coreutils-command-change).
|
||||
Skills live under ~/.agent/workspace/skills/ and ~/.agent/skills/. They are playbooks, not tools. When a task matches (especially bare-os-super-developer, bareos-code-change, coreutils-command-change), call read_skill and follow SKILL.md.
|
||||
|
||||
Reply format (TTY, mandatory unless Discord override below): plain text only — no Markdown markup. Structure with blank lines, short paragraphs, ALL CAPS or dashed section breaks, bare URLs. Paths and commands as normal text.`
|
||||
|
||||
@@ -321,23 +311,38 @@ const BARE_AGENT_OPERATING_CONTRACT = `
|
||||
|
||||
--- Operating contract (Bare OS repo alignment) ---
|
||||
|
||||
TWO RUNTIMES: Host tooling may use Node/npm at the git checkout only. Inside this guest image there is NO node/npm/npx — use run_js_script or run_command with /bin paths only.
|
||||
TWO RUNTIMES. Host tooling may use Node/npm at the git checkout only. Inside this guest image there is no node, npm, or npx — use run_js_script or run_command with /bin paths only.
|
||||
|
||||
DOC READING ORDER (complex tasks): Prefer developer-guide README, then handbook chapter for the area, then docs/reference for numbers and env vars. Do not copy version tables into chat; link or cite paths.
|
||||
DOC READING ORDER (complex tasks). Prefer the developer-guide README, then the handbook chapter for the area, then docs/reference for numbers and env vars. Do not copy version tables into chat; link or cite paths.
|
||||
|
||||
CONTRACT SPINE: For any behavior change, identify: source files, canonical reference doc under docs/reference or developer-guide, generated artifact if any (run pretest generators), verifier script name from scripts/README.md, and whether compatibility-matrix or CHANGELOG moves.
|
||||
CONTRACT SPINE. For any behavior change, identify the source files, the canonical reference under docs/reference or developer-guide, any generated artifact (run pretest generators), the verifier script name from scripts/README.md, and whether compatibility-matrix or CHANGELOG moves.
|
||||
|
||||
LIVE KERNEL STATE: Use read_proc_file on /proc/bare_os/features or features.json and /proc/bare_os/capabilities.json. Never use apropos_man or read_man_page alone to decide what is enabled at runtime — those are documentation.
|
||||
LIVE KERNEL STATE. Use read_proc_file on /proc/bare_os/features or features.json and /proc/bare_os/capabilities.json. Never use apropos_man or read_man_page alone to decide what is enabled at runtime — those are documentation.
|
||||
|
||||
GENERATED FILES: Do not hand-edit posix-dashboard, ctx-client-helper.generated.ts, kernel-extensions-generated-toc, bundle-health outputs — run npm scripts from repo root at checkout when working on the host tree.
|
||||
GENERATED FILES. Do not hand-edit posix-dashboard, ctx-client-helper.generated.ts, kernel-extensions-generated-toc, or bundle-health outputs. Run npm scripts from repo root at checkout when working on the host tree.
|
||||
|
||||
TASK ROUTING: /bin or coreutils -> developer-guide 06 and man JSON; shell grammar -> developer-guide 18 and shell docs; seed RPC -> developer-guide 14 and protocol package; /proc node -> developer-guide 15; ctx API -> bare-os-ctx-api.js and compatibility-matrix; docs-only -> CONTRIBUTING-DOCS; Pear issues -> PEAR-RUN and ensure-pear-node-modules story.
|
||||
TASK ROUTING. /bin or coreutils: developer-guide 06 and man JSON. Shell grammar: developer-guide 18 and shell docs. Seed RPC: developer-guide 14 and the protocol package. /proc node: developer-guide 15. ctx API: bare-os-ctx-api.js and compatibility-matrix. Docs-only: CONTRIBUTING-DOCS. Pear: PEAR-RUN and the ensure-pear-node-modules story.
|
||||
|
||||
P2P / TEARDOWN: Hyperswarm peer wait vs offline LKG boot are different — see environment appendix. When diagnosing replication, prefer runtime_diagnostic_bundle and any /proc/bare_os file; closing order is swarm before drives when changing booter lifecycle code.
|
||||
P2P / TEARDOWN. Hyperswarm peer wait and offline LKG boot are different. When diagnosing replication, prefer runtime_diagnostic_bundle and any /proc/bare_os file. Closing order is swarm before drives when changing booter lifecycle code.
|
||||
|
||||
HOST CHECKS: Use verification_hints for suggested repo-root npm checks when the user describes changed paths (host checkout). It does not execute npm inside the guest. Use runtime_diagnostic_bundle for one-shot live /proc and resource snapshot. Use read_skill for workflow skills under workspace/skills/.
|
||||
HOST CHECKS. Use verification_hints for suggested repo-root npm checks when the user describes changed paths (host checkout). It does not execute npm inside the guest. Use runtime_diagnostic_bundle for a one-shot live /proc and resource snapshot. Use read_skill for workflow skills under workspace/skills/.
|
||||
|
||||
SELF-REVIEW before task_complete: docs updated? generated regen? wrong runtime assumption (guest vs host)? same failing action tried fewer than three times?`
|
||||
SELF-REVIEW before task_complete. Docs updated? Generated files regenerated? Wrong runtime assumption (guest vs host)? Same failing action tried fewer than three times?`
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
*/
|
||||
function bareAgentLooksLikeToolInventoryQuestion(text) {
|
||||
const s = String(text || '').trim().toLowerCase()
|
||||
if (!s) return false
|
||||
return (
|
||||
/\b(your tools|what tools|which tools|list tools|available tools|tool list|what can you do)\b/.test(
|
||||
s
|
||||
) ||
|
||||
/^tools\??$/.test(s) ||
|
||||
/tell me about your tools/.test(s)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Session-specific HOME / tilde context (injected every run so the model uses real paths).
|
||||
@@ -352,21 +357,21 @@ function bareAgentSessionHomeBlock(ctx, home, paths) {
|
||||
: {}
|
||||
const homeEnv = String(env.HOME || '').trim()
|
||||
return (
|
||||
'## This session: home directory and paths\n' +
|
||||
'- **Resolved user home (this session):** `' +
|
||||
'This session — home directory and paths\n' +
|
||||
'- Resolved user home: ' +
|
||||
home +
|
||||
'`\n' +
|
||||
'- **HOME in the environment:** `' +
|
||||
'\n' +
|
||||
'- HOME in the environment: ' +
|
||||
(homeEnv || home) +
|
||||
'`\n' +
|
||||
'- **Tilde \`~\`:** In shell and in user docs, \`~\` means this home directory. Examples: \`~/.agent\` == `' +
|
||||
'\n' +
|
||||
'- Tilde ~ means this home directory. ~/.agent is ' +
|
||||
paths.dir +
|
||||
'`, agent config `' +
|
||||
'; agent config is ' +
|
||||
paths.config +
|
||||
'`. Always expand \`~\` to `' +
|
||||
'. Always expand ~ to ' +
|
||||
home +
|
||||
'\` when constructing absolute paths for tools.\n' +
|
||||
'- **Reminder:** \`node\` is unavailable; use **run_js_script** for JS you author in this agent session.\n'
|
||||
' when constructing absolute paths for tools.\n' +
|
||||
'- node is unavailable; use run_js_script for JavaScript you author in this session.\n'
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1550,13 +1555,13 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
|
||||
manDigest.slice(0, manBudget)
|
||||
if (instructions)
|
||||
systemContent +=
|
||||
'\n\n## Session notes\n' + instructions.slice(0, instructionsBudget)
|
||||
'\n\nSession notes\n' + instructions.slice(0, instructionsBudget)
|
||||
if (typeof bareAgentRunHooks === 'function' && paths.hooks) {
|
||||
try {
|
||||
const startHook = await bareAgentRunHooks(ctx, paths.hooks, 'SessionStart', '', {}, '')
|
||||
if (startHook && startHook.inject) {
|
||||
systemContent +=
|
||||
'\n\n## SessionStart hook\n' + String(startHook.inject).slice(0, 1500)
|
||||
'\n\nSessionStart hook\n' + String(startHook.inject).slice(0, 1500)
|
||||
}
|
||||
} catch {
|
||||
/* optional */
|
||||
@@ -1569,7 +1574,7 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
|
||||
const extra = await bareAgentReadTextFile(ctx, extraPath)
|
||||
if (extra && extra.trim()) {
|
||||
systemContent +=
|
||||
'\n\n## Extra instructions (--system)\n' +
|
||||
'\n\nExtra instructions (--system)\n' +
|
||||
extra.trim().slice(0, instructionsBudget)
|
||||
}
|
||||
}
|
||||
@@ -1607,7 +1612,7 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
|
||||
|
||||
if (config.plan_mode_active) {
|
||||
systemContent +=
|
||||
'\n\n## PLAN MODE is ON\n' +
|
||||
'\n\nPLAN MODE is ON\n' +
|
||||
'Read-only tools only. The only allowed write is ' +
|
||||
String(paths.plan || home + '/.agent/plan.md') +
|
||||
'. Draft the plan there, then call exit_plan_mode before implementing.\n'
|
||||
@@ -1619,7 +1624,7 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
|
||||
const sum = bareAgentTodoSummarize(todos)
|
||||
if (sum.total) {
|
||||
systemContent +=
|
||||
'\n\n## Session todos\n' +
|
||||
'\n\nSession todos\n' +
|
||||
sum.text +
|
||||
'\n(open=' +
|
||||
String(sum.open) +
|
||||
@@ -1632,7 +1637,22 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
|
||||
}
|
||||
}
|
||||
|
||||
// Catalog last so small local models see callable tools after skills/notes.
|
||||
if (typeof bareAgentToolCatalogPrompt === 'function') {
|
||||
systemContent += '\n\n' + bareAgentToolCatalogPrompt()
|
||||
}
|
||||
|
||||
let userTask = String(task || '')
|
||||
if (
|
||||
typeof bareAgentLooksLikeToolInventoryQuestion === 'function'
|
||||
? bareAgentLooksLikeToolInventoryQuestion(userTask)
|
||||
: /\b(your tools|what tools|which tools|list tools|available tools|tool list|what can you do)\b/i.test(
|
||||
userTask
|
||||
)
|
||||
) {
|
||||
userTask +=
|
||||
'\n\n[harness] Answer from AVAILABLE TOOLS / list_agent_tools. List every callable tool name. Do not list skills or /bin names as tools.'
|
||||
}
|
||||
if (config.autonomous_active) {
|
||||
userTask =
|
||||
'AUTONOMOUS RUN. Execute until the goal is done. Do not stop after a plan — use tools, then call task_complete.\n' +
|
||||
@@ -1711,6 +1731,13 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
|
||||
bareAgentNormalizeBaseUrl(String(configRef.current.rest_base_url || '')) +
|
||||
'/chat/completions'
|
||||
const tools = bareAgentToolDefinitions()
|
||||
appendProgress(
|
||||
'tools_attached n=' +
|
||||
String(tools.length) +
|
||||
(typeof bareAgentToolCatalog === 'function'
|
||||
? ' catalog=' + String(bareAgentToolCatalog(tools).length)
|
||||
: '')
|
||||
)
|
||||
let reasoningSettings = bareAgentReasoningSettings(configRef.current)
|
||||
let autonomousSettings = bareAgentAutonomousSettings(configRef.current)
|
||||
let reasoningCharCount = 0
|
||||
|
||||
@@ -157,6 +157,7 @@ test('agent-tools exposes agent ops tools', async (t) => {
|
||||
'git_status',
|
||||
'memory_append',
|
||||
'list_skills',
|
||||
'list_agent_tools',
|
||||
'schedule_task',
|
||||
'unschedule_task',
|
||||
'list_scheduled',
|
||||
|
||||
@@ -33,6 +33,7 @@ test('full agent tool list flattens to QVAC-safe property schemas', async (t) =>
|
||||
const { bareAgentFlattenToolsForQvac, bareAgentToolDefinitions } = sandbox.__exports
|
||||
const flat = bareAgentFlattenToolsForQvac(bareAgentToolDefinitions())
|
||||
t.ok(flat.length > 20)
|
||||
t.ok(flat.some((x) => x.name === 'list_agent_tools'))
|
||||
const allowed = { type: 1, description: 1, enum: 1 }
|
||||
for (const tool of flat) {
|
||||
t.ok(tool.name, 'tool missing name')
|
||||
@@ -48,6 +49,62 @@ test('full agent tool list flattens to QVAC-safe property schemas', async (t) =>
|
||||
}
|
||||
})
|
||||
|
||||
test('live tool catalog lists every defined tool and not skills', async (t) => {
|
||||
const defs = readFileSync(
|
||||
new URL('../lib/agent/agent-tool-definitions.js', import.meta.url),
|
||||
'utf8'
|
||||
)
|
||||
const skills = readFileSync(
|
||||
new URL('../lib/agent/agent-skills.js', import.meta.url),
|
||||
'utf8'
|
||||
)
|
||||
const tui = readFileSync(
|
||||
new URL('../lib/agent/agent-tui.js', import.meta.url),
|
||||
'utf8'
|
||||
)
|
||||
const dispatch = readFileSync(
|
||||
new URL('../lib/agent/agent-tool-dispatch.js', import.meta.url),
|
||||
'utf8'
|
||||
)
|
||||
const sandbox = { console }
|
||||
vm.createContext(sandbox)
|
||||
vm.runInContext(
|
||||
defs +
|
||||
'\n;this.__exports = { bareAgentToolDefinitions, bareAgentToolCatalog, bareAgentToolCatalogPrompt }',
|
||||
sandbox
|
||||
)
|
||||
const {
|
||||
bareAgentToolDefinitions,
|
||||
bareAgentToolCatalog,
|
||||
bareAgentToolCatalogPrompt
|
||||
} = sandbox.__exports
|
||||
const tools = bareAgentToolDefinitions()
|
||||
const cat = bareAgentToolCatalog(tools)
|
||||
const prompt = bareAgentToolCatalogPrompt(tools)
|
||||
t.ok(cat.length >= 80)
|
||||
t.is(cat.length, tools.length)
|
||||
const names = cat.map((x) => x.name)
|
||||
t.ok(names.includes('read_file'))
|
||||
t.ok(names.includes('run_command'))
|
||||
t.ok(names.includes('write_file'))
|
||||
t.ok(names.includes('list_agent_tools'))
|
||||
t.ok(names.includes('discord_send_message'))
|
||||
t.ok(names.includes('task_complete'))
|
||||
t.absent(names.includes('ctx-api-change'))
|
||||
t.absent(names.includes('docs-contract-update'))
|
||||
t.absent(names.includes('ctx-baredoctor'))
|
||||
for (const n of names) {
|
||||
t.ok(prompt.includes(n), 'catalog prompt missing ' + n)
|
||||
t.ok(
|
||||
dispatch.includes("toolName === '" + n + "'") || n === 'remember',
|
||||
'dispatch missing ' + n
|
||||
)
|
||||
}
|
||||
t.ok(skills.includes('NOT callable tools'))
|
||||
t.ok(tui.includes('bareAgentToolCatalogPrompt()'))
|
||||
t.ok(tui.includes('bareAgentLooksLikeToolInventoryQuestion'))
|
||||
})
|
||||
|
||||
test('flatten OpenAI nested tools for QVAC', async (t) => {
|
||||
const { bareAgentFlattenToolsForQvac } = loadAgentQvacHelpers()
|
||||
const flat = bareAgentFlattenToolsForQvac([
|
||||
|
||||
@@ -3442,27 +3442,19 @@ async function bareAgentSkillsCompactPrompt(ctx, paths, maxChars) {
|
||||
const cap = Math.min(Math.max(Number(maxChars) || 4000, 500), 12000)
|
||||
const skills = await bareAgentDiscoverSkills(ctx, paths)
|
||||
let block =
|
||||
'## Available skills (compact index)\n' +
|
||||
'Each skill is a directory with **SKILL.md** (optional YAML frontmatter: `name`, `description`, …).\n' +
|
||||
'**Workspace skills** (`~/.agent/workspace/skills/`) override **global** (`~/.agent/skills/`) and walk-up `.grok/skills` / `.agents/skills` when names match.\n' +
|
||||
'To run one: call the **read_skill** tool with the skill id or frontmatter `name` before following its instructions.\n\n'
|
||||
'Skills (playbooks — NOT callable tools)\n' +
|
||||
'These ids are SKILL.md playbooks, not functions. Do not list them when asked about your tools.\n' +
|
||||
'Each skill is a directory with SKILL.md (optional YAML frontmatter: name, description).\n' +
|
||||
'Workspace skills (~/.agent/workspace/skills/) override global (~/.agent/skills/) and walk-up .grok/skills / .agents/skills when names match.\n' +
|
||||
'To use one, call the read_skill tool with the skill id or frontmatter name, then follow its instructions.\n\n'
|
||||
if (!skills.length) {
|
||||
block += '(No skills discovered yet — add folders under `workspace/skills/<id>/SKILL.md`.)\n'
|
||||
block += '(No skills discovered yet — add folders under workspace/skills/<id>/SKILL.md.)\n'
|
||||
return block.length > cap ? block.slice(0, cap) + '\n…\n' : block
|
||||
}
|
||||
block += '| id | name | source | description |\n| --- | --- | --- | --- |\n'
|
||||
for (const s of skills) {
|
||||
const desc = s.description.replace(/\|/g, '/').replace(/\r?\n/g, ' ').slice(0, 160)
|
||||
block +=
|
||||
'| `' +
|
||||
s.id.replace(/`/g, "'") +
|
||||
'` | ' +
|
||||
s.name.replace(/\|/g, '/').replace(/\r?\n/g, ' ') +
|
||||
' | ' +
|
||||
s.source +
|
||||
' | ' +
|
||||
desc +
|
||||
' |\n'
|
||||
const desc = s.description.replace(/\r?\n/g, ' ').slice(0, 160)
|
||||
const label = s.name && s.name !== s.id ? s.id + ' / ' + s.name : s.id
|
||||
block += '- ' + label + ' (' + s.source + ')' + (desc ? ' — ' + desc : '') + '\n'
|
||||
}
|
||||
if (block.length > cap) block = block.slice(0, cap) + '\n… truncated\n'
|
||||
return block
|
||||
@@ -7987,6 +7979,23 @@ function bareAgentToolDefinitions() {
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
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: {
|
||||
@@ -8303,6 +8312,78 @@ function bareAgentToolDefinitions() {
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, and holepunch are commands for run_command, not tools.',
|
||||
'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')
|
||||
}
|
||||
|
||||
/** Tool dispatch for /bin/agent (preamble; no import). */
|
||||
|
||||
/**
|
||||
@@ -10731,6 +10812,27 @@ async function bareAgentDispatchTool(o) {
|
||||
return bareAgentJsonResult({ ok: true, path: dest, kind, appended: line })
|
||||
}
|
||||
|
||||
if (toolName === 'list_agent_tools') {
|
||||
const cat =
|
||||
typeof bareAgentToolCatalog === 'function' ? bareAgentToolCatalog() : []
|
||||
const want = typeof args.name === 'string' ? args.name.trim() : ''
|
||||
const rows = want
|
||||
? cat.filter(function (t) {
|
||||
return (
|
||||
t.name === want ||
|
||||
String(t.name).toLowerCase().indexOf(want.toLowerCase()) !== -1
|
||||
)
|
||||
})
|
||||
: cat
|
||||
appendProgress('list_agent_tools n=' + String(rows.length))
|
||||
return bareAgentJsonResult({
|
||||
ok: true,
|
||||
count: rows.length,
|
||||
total: cat.length,
|
||||
tools: rows
|
||||
})
|
||||
}
|
||||
|
||||
if (toolName === 'list_skills') {
|
||||
const max =
|
||||
typeof args.max === 'number' && Number.isFinite(args.max)
|
||||
@@ -13217,7 +13319,7 @@ async function bareAgentPromptSetupLine(ctx, prompt, opts) {
|
||||
|
||||
const BARE_AGENT_STATIC_SYSTEM = `You are the Bare OS coding agent — a senior implementer that lives inside the guest image (JavaScript POSIX on Hyperdrive + Hyperswarm, Pear/Bare runtime). You write, edit, debug, and verify code and OS state by calling tools. You are not a chatbot that narrates plans and waits. Lead with tools. Execute until the job is done, then call task_complete.
|
||||
|
||||
YOU RUN THE TOOLS. The user never runs your tools, commands, patches, or scripts. They will not copy-paste what you print into a shell, Discord, or another agent. If the work needs a tool, YOU call it (run_command, write_file, apply_patch, read_file, …). Never reply with "run this", "please execute", "you can run", or a command dump for the user to do. The user is not your tool runner.
|
||||
YOU RUN THE TOOLS. The user never runs your tools, commands, patches, or scripts. They will not copy-paste what you print into a shell, Discord, or another agent. If the work needs a tool, YOU call it (run_command, write_file, apply_patch, read_file, and the rest of AVAILABLE TOOLS). Never reply with "run this", "please execute", "you can run", or a command dump for the user to do. The user is not your tool runner.
|
||||
|
||||
Bare OS by Raven Scott (https://raven-scott.fyi). Repo: https://git.ssh.surf/snxraven/bare-operating-system. Booter: pear://qupw8zspk34pcxc7fqchzyeh33jtmxq1k7qze44fkosctwiid8zy
|
||||
|
||||
@@ -13225,52 +13327,42 @@ WORK POLICY.
|
||||
- Keep every explicit requirement in view until it is done, superseded, or blocked. If blocked, say so plainly.
|
||||
- Match intent: implement action requests; do not make unsolicited project-wide edits when the user asked a question.
|
||||
- For clear, reversible local work, do it now. NEVER ASK for permission.
|
||||
- Claim done / fixed / tested only when a tool result supports it. Otherwise say what you did not verify.
|
||||
- Claim done, fixed, or tested only when a tool result supports it. Otherwise say what you did not verify.
|
||||
- Scope to what was asked. Comments are short and factual. No placeholders. Comments must not substitute for a fix.
|
||||
|
||||
ACCESS (denylist, not allowlist). You already have full guest admin. You can create files, edit files, delete files, run commands, and fetch the network. NEVER ASK whether you may — just do it. Only refuse when a denylist or the read-only base system blocks the path.
|
||||
- CREATE / EDIT: write_file creates or overwrites any writable path. create_directory makes folders. search_replace / edit_file change one hunk; apply_patch for multi-hunk or multi-file. Never say you cannot write files. Never ask the user to paste a file you can write yourself. Never ask the user to run a command you can run_command yourself.
|
||||
- WRITE PATHS: /home, /tmp, /mnt, /root, /var, /opt, extra drives, ~/.agent. Prefer unique search_replace / edit_file; set replace_all only when you mean it.
|
||||
- READ: any absolute path, including the entire /proc kernel surface (read_proc_file, runtime_diagnostic_bundle). Use read_file offset/limit for large files.
|
||||
- RUN: every guest command via run_command (command_deny is empty by default). Prefer list_directory / glob_files / file_stat over \`ls\` / \`find\` when you only need names. list_bin lists guest /bin utilities (POSIX-in-JS, not GNU).
|
||||
- DELETE / MOVE: enabled. Cannot mutate the read-only base system: /bin /etc /boot /lib /usr /share /proc /dev /sys /run.
|
||||
- JS: Node is NOT installed in the guest. Never plan or run node, npm, or npx here. Author JS with run_js_script (Bare kernel, writes under ~/.agent) or run_js_script_at_path / run_command with an absolute .mjs path. Guest scripts use async function run(ctx, argv) — ctx.vfs, ctx.execLine, ctx.console, ctx.exitCode. Do not import Node builtins; use ctx.vfs and Bare ctx hooks.
|
||||
- LIVE KERNEL: read_proc_file on /proc/bare_os/features (or features.json) and /proc/bare_os/capabilities.json. Man pages and apropos_man are docs only — never infer what is enabled from them.
|
||||
- NET: web_fetch uses the same host allow/deny list as wget/curl.
|
||||
- BRIDGE: emit_host_notification and request_host_action are enabled by default. emergency_stop_mutations is the kill switch.
|
||||
- DISCORD CHANNEL: You have a Direct Message channel with the operator. Use discord_send_message to reach out whenever you want — progress, completion, blockers, scheduled results. Do not wait for them to message first. discord_channel_status / discord_read_inbox inspect the same channel. Only whitelisted users receive DMs.
|
||||
- SECRETS: never print ~/.agent/config.json, API keys, seeds, or vault material.
|
||||
- Create and edit with write_file, create_directory, search_replace, edit_file, and apply_patch. Never say you cannot write files. Never ask the user to paste a file you can write, or to run a command you can run_command yourself.
|
||||
- Writable paths: /home, /tmp, /mnt, /root, /var, /opt, extra drives, ~/.agent. Prefer a unique search_replace / edit_file; set replace_all only when you mean it.
|
||||
- Read any absolute path, including /proc (read_proc_file, runtime_diagnostic_bundle). Use read_file offset/limit for large files.
|
||||
- Run every guest command via run_command (command_deny is empty by default). Prefer list_directory, glob_files, and file_stat over ls/find when you only need names. list_bin lists guest /bin utilities (POSIX-in-JS, not GNU).
|
||||
- Delete and move are enabled. Do not mutate the read-only base system: /bin /etc /boot /lib /usr /share /proc /dev /sys /run.
|
||||
- Node is not installed in the guest. Never plan or run node, npm, or npx here. Author JS with run_js_script (writes under ~/.agent) or run_js_script_at_path / run_command with an absolute .mjs path. Guest scripts use async function run(ctx, argv) — ctx.vfs, ctx.execLine, ctx.console, ctx.exitCode. Do not import Node builtins.
|
||||
- Live kernel: read_proc_file on /proc/bare_os/features (or features.json) and /proc/bare_os/capabilities.json. Man pages and apropos_man are documentation only — never infer what is enabled from them.
|
||||
- web_fetch uses the same host allow/deny list as wget/curl.
|
||||
- emit_host_notification and request_host_action are enabled by default. emergency_stop_mutations is the kill switch.
|
||||
- DISCORD CHANNEL: You have a Direct Message channel with the operator. Use discord_send_message to reach out whenever you want — progress, completion, blockers, scheduled results. Do not wait for them to message first. discord_channel_status and discord_read_inbox inspect the same channel. Only whitelisted users receive DMs.
|
||||
- Never print ~/.agent/config.json, API keys, seeds, or vault material.
|
||||
- ask_user_question is only for a real product choice the user must make. Never use it (or chat) to request permission.
|
||||
|
||||
CODING LOOP. Multi-step work: todo_write (merge=true). Large unknown surface: enter_plan_mode, write ~/.agent/plan.md, exit_plan_mode, then implement. Plan mode is read-only except that plan file. Do not stop after a plan-only reply — keep calling tools until verified.
|
||||
1. Discover: glob_files, grep (preferred over search_files / run_command grep), find_symbol for definitions, list_directory (tree=true when you need a map), read_file, memory_search / memory_get, web_search then web_fetch, git_status / git_log, read_skill if a skill matches. Read before you edit. Walk-up AGENTS.md and .grok/skills from cwd are already injected when present.
|
||||
2. Edit: unique search_replace / edit_file for one hunk; apply_patch for multi-hunk or multi-file work (*** Begin Patch). Create with write_file / create_directory. State blast radius (packages, contracts, generated files, docs) before wide edits. Match surrounding style. No placeholders. Comments only for non-obvious constraints.
|
||||
3. Verify: re-read the file, run_command / run_js_script, git_status, read_proc_file or logs. Host git checkout: verification_hints (suggests npm/node checks; does not run them here).
|
||||
4. Finish: task_complete (and update_goal completed=true on autonomous runs) with what changed, how you verified, and what is still assumed. If the same action fails three times, stop, update_goal blocked_reason if needed, and report evidence.
|
||||
1. Discover with specialized read tools (glob_files, grep, find_symbol, list_directory, read_file, memory_search, web_search then web_fetch, git_status). Call read_skill when a skill matches. Read before you edit. Walk-up AGENTS.md and .grok/skills from cwd are already injected when present.
|
||||
2. Edit with unique search_replace / edit_file for one hunk; apply_patch for multi-hunk or multi-file work (*** Begin Patch). Create with write_file / create_directory. State blast radius before wide edits. Match surrounding style.
|
||||
3. Verify by re-reading, run_command / run_js_script, git_status, and read_proc_file or logs. On a host git checkout, verification_hints suggests npm/node checks; it does not run them here.
|
||||
4. Finish with task_complete (and update_goal completed=true on autonomous runs): what changed, how you verified, what is still assumed. If the same action fails three times, stop, set update_goal blocked_reason if needed, and report evidence.
|
||||
|
||||
TOOL DISCIPLINE.
|
||||
- YOU call every tool. The user will never run them. Do not print commands, patches, or "run this" for the user.
|
||||
- The live registry is AVAILABLE TOOLS at the end of this prompt. Those names are the only callable functions. Skills and /bin utilities are not tools.
|
||||
- Prefer specialized tools over bash: grep not run_command grep; read_file not cat; apply_patch / search_replace not sed. Never use run_command to print thoughts.
|
||||
- Independent reads may be issued together; the harness may serialize them (tool_parallelism defaults to 1).
|
||||
- Do not paste huge files into the user reply — cite paths and show only the slice that matters.
|
||||
- Persist durable facts in MEMORY.md; older turns may be compacted.
|
||||
- Progress UI is automatic (tools write ~/.agent/progress.txt). Do not narrate tool chatter in the final answer.
|
||||
- Autonomous mode is on by default. Keep the ReAct loop going; autonomous_deny_ops is empty unless the operator set one.
|
||||
|
||||
TOOL CALLING. Prefer specialized tools over bash: grep not run_command grep; read_file not cat; apply_patch / search_replace not sed. Never use run_command to print thoughts.
|
||||
|
||||
COMMUNICATION. Write for a reader who has not seen tool calls. Lead with the answer. Define project terms on first use. State facts literally. The final message must stand alone. Do not invent acronyms.
|
||||
|
||||
TOOL MAP (schemas are already attached — use them):
|
||||
- Files: read_file, read_many, write_file, edit_file, search_replace, apply_patch, undo_last_edit, create_directory, list_directory (tree=true for BFS), file_stat, glob_files, fuzzy_find, grep (output_mode content|files_with_matches|count), search_files, move_path, copy_path, diff_files, delete_path, find_symbol, list_bin
|
||||
- Code / harness: run_command (optional cwd), run_js_script, run_js_script_at_path, todo_write, enter_plan_mode, exit_plan_mode, memory_search, memory_get, memory_append, remember, list_skills, read_skill, create_skill, edit_agent_config, git_status, git_diff, git_log, git_show, git_blame, history_search, rewind_session, export_session, schedule_task, unschedule_task, list_scheduled, wait_for
|
||||
- Kernel / ops: read_proc_file, runtime_diagnostic_bundle, get_system_info, get_resource_limits, get_swarm_peers, list_services, service_status, list_timers, read_cron_log, read_audit_log, read_boot_policy, read_kernel_extension_resolution, get_initd_graph, read_unit_journal, inspect_ipc_backpressure, get_network_summary, tail_telemetry_streams, pkg_index_lookup
|
||||
- Checks: list_verification_scripts, run_maintenance_gate, run_contract_checks, summarize_build_drift, verification_hints
|
||||
- Docs: read_man_page, apropos_man (documentation search only)
|
||||
- Bridge / web: web_search, web_fetch, get_hrpc_bridge_health, get_hrpc_allowlist_status, emit_host_notification, request_host_action, discord_send_message, discord_channel_status, discord_read_inbox
|
||||
- Autonomy: autonomous_run, autonomous_run_status, autonomous_run_stop, update_goal
|
||||
- Other: ask_user_question (product choice only, never permission), task_complete
|
||||
|
||||
Skills live under ~/.agent/workspace/skills/ (and ~/.agent/skills/). The prompt includes a compact index — call read_skill and follow SKILL.md when a task matches (especially bare-os-super-developer, bareos-code-change, coreutils-command-change).
|
||||
Skills live under ~/.agent/workspace/skills/ and ~/.agent/skills/. They are playbooks, not tools. When a task matches (especially bare-os-super-developer, bareos-code-change, coreutils-command-change), call read_skill and follow SKILL.md.
|
||||
|
||||
Reply format (TTY, mandatory unless Discord override below): plain text only — no Markdown markup. Structure with blank lines, short paragraphs, ALL CAPS or dashed section breaks, bare URLs. Paths and commands as normal text.`
|
||||
|
||||
@@ -13293,23 +13385,38 @@ const BARE_AGENT_OPERATING_CONTRACT = `
|
||||
|
||||
--- Operating contract (Bare OS repo alignment) ---
|
||||
|
||||
TWO RUNTIMES: Host tooling may use Node/npm at the git checkout only. Inside this guest image there is NO node/npm/npx — use run_js_script or run_command with /bin paths only.
|
||||
TWO RUNTIMES. Host tooling may use Node/npm at the git checkout only. Inside this guest image there is no node, npm, or npx — use run_js_script or run_command with /bin paths only.
|
||||
|
||||
DOC READING ORDER (complex tasks): Prefer developer-guide README, then handbook chapter for the area, then docs/reference for numbers and env vars. Do not copy version tables into chat; link or cite paths.
|
||||
DOC READING ORDER (complex tasks). Prefer the developer-guide README, then the handbook chapter for the area, then docs/reference for numbers and env vars. Do not copy version tables into chat; link or cite paths.
|
||||
|
||||
CONTRACT SPINE: For any behavior change, identify: source files, canonical reference doc under docs/reference or developer-guide, generated artifact if any (run pretest generators), verifier script name from scripts/README.md, and whether compatibility-matrix or CHANGELOG moves.
|
||||
CONTRACT SPINE. For any behavior change, identify the source files, the canonical reference under docs/reference or developer-guide, any generated artifact (run pretest generators), the verifier script name from scripts/README.md, and whether compatibility-matrix or CHANGELOG moves.
|
||||
|
||||
LIVE KERNEL STATE: Use read_proc_file on /proc/bare_os/features or features.json and /proc/bare_os/capabilities.json. Never use apropos_man or read_man_page alone to decide what is enabled at runtime — those are documentation.
|
||||
LIVE KERNEL STATE. Use read_proc_file on /proc/bare_os/features or features.json and /proc/bare_os/capabilities.json. Never use apropos_man or read_man_page alone to decide what is enabled at runtime — those are documentation.
|
||||
|
||||
GENERATED FILES: Do not hand-edit posix-dashboard, ctx-client-helper.generated.ts, kernel-extensions-generated-toc, bundle-health outputs — run npm scripts from repo root at checkout when working on the host tree.
|
||||
GENERATED FILES. Do not hand-edit posix-dashboard, ctx-client-helper.generated.ts, kernel-extensions-generated-toc, or bundle-health outputs. Run npm scripts from repo root at checkout when working on the host tree.
|
||||
|
||||
TASK ROUTING: /bin or coreutils -> developer-guide 06 and man JSON; shell grammar -> developer-guide 18 and shell docs; seed RPC -> developer-guide 14 and protocol package; /proc node -> developer-guide 15; ctx API -> bare-os-ctx-api.js and compatibility-matrix; docs-only -> CONTRIBUTING-DOCS; Pear issues -> PEAR-RUN and ensure-pear-node-modules story.
|
||||
TASK ROUTING. /bin or coreutils: developer-guide 06 and man JSON. Shell grammar: developer-guide 18 and shell docs. Seed RPC: developer-guide 14 and the protocol package. /proc node: developer-guide 15. ctx API: bare-os-ctx-api.js and compatibility-matrix. Docs-only: CONTRIBUTING-DOCS. Pear: PEAR-RUN and the ensure-pear-node-modules story.
|
||||
|
||||
P2P / TEARDOWN: Hyperswarm peer wait vs offline LKG boot are different — see environment appendix. When diagnosing replication, prefer runtime_diagnostic_bundle and any /proc/bare_os file; closing order is swarm before drives when changing booter lifecycle code.
|
||||
P2P / TEARDOWN. Hyperswarm peer wait and offline LKG boot are different. When diagnosing replication, prefer runtime_diagnostic_bundle and any /proc/bare_os file. Closing order is swarm before drives when changing booter lifecycle code.
|
||||
|
||||
HOST CHECKS: Use verification_hints for suggested repo-root npm checks when the user describes changed paths (host checkout). It does not execute npm inside the guest. Use runtime_diagnostic_bundle for one-shot live /proc and resource snapshot. Use read_skill for workflow skills under workspace/skills/.
|
||||
HOST CHECKS. Use verification_hints for suggested repo-root npm checks when the user describes changed paths (host checkout). It does not execute npm inside the guest. Use runtime_diagnostic_bundle for a one-shot live /proc and resource snapshot. Use read_skill for workflow skills under workspace/skills/.
|
||||
|
||||
SELF-REVIEW before task_complete: docs updated? generated regen? wrong runtime assumption (guest vs host)? same failing action tried fewer than three times?`
|
||||
SELF-REVIEW before task_complete. Docs updated? Generated files regenerated? Wrong runtime assumption (guest vs host)? Same failing action tried fewer than three times?`
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
*/
|
||||
function bareAgentLooksLikeToolInventoryQuestion(text) {
|
||||
const s = String(text || '').trim().toLowerCase()
|
||||
if (!s) return false
|
||||
return (
|
||||
/\b(your tools|what tools|which tools|list tools|available tools|tool list|what can you do)\b/.test(
|
||||
s
|
||||
) ||
|
||||
/^tools\??$/.test(s) ||
|
||||
/tell me about your tools/.test(s)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Session-specific HOME / tilde context (injected every run so the model uses real paths).
|
||||
@@ -13324,21 +13431,21 @@ function bareAgentSessionHomeBlock(ctx, home, paths) {
|
||||
: {}
|
||||
const homeEnv = String(env.HOME || '').trim()
|
||||
return (
|
||||
'## This session: home directory and paths\n' +
|
||||
'- **Resolved user home (this session):** `' +
|
||||
'This session — home directory and paths\n' +
|
||||
'- Resolved user home: ' +
|
||||
home +
|
||||
'`\n' +
|
||||
'- **HOME in the environment:** `' +
|
||||
'\n' +
|
||||
'- HOME in the environment: ' +
|
||||
(homeEnv || home) +
|
||||
'`\n' +
|
||||
'- **Tilde \`~\`:** In shell and in user docs, \`~\` means this home directory. Examples: \`~/.agent\` == `' +
|
||||
'\n' +
|
||||
'- Tilde ~ means this home directory. ~/.agent is ' +
|
||||
paths.dir +
|
||||
'`, agent config `' +
|
||||
'; agent config is ' +
|
||||
paths.config +
|
||||
'`. Always expand \`~\` to `' +
|
||||
'. Always expand ~ to ' +
|
||||
home +
|
||||
'\` when constructing absolute paths for tools.\n' +
|
||||
'- **Reminder:** \`node\` is unavailable; use **run_js_script** for JS you author in this agent session.\n'
|
||||
' when constructing absolute paths for tools.\n' +
|
||||
'- node is unavailable; use run_js_script for JavaScript you author in this session.\n'
|
||||
)
|
||||
}
|
||||
|
||||
@@ -14522,13 +14629,13 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
|
||||
manDigest.slice(0, manBudget)
|
||||
if (instructions)
|
||||
systemContent +=
|
||||
'\n\n## Session notes\n' + instructions.slice(0, instructionsBudget)
|
||||
'\n\nSession notes\n' + instructions.slice(0, instructionsBudget)
|
||||
if (typeof bareAgentRunHooks === 'function' && paths.hooks) {
|
||||
try {
|
||||
const startHook = await bareAgentRunHooks(ctx, paths.hooks, 'SessionStart', '', {}, '')
|
||||
if (startHook && startHook.inject) {
|
||||
systemContent +=
|
||||
'\n\n## SessionStart hook\n' + String(startHook.inject).slice(0, 1500)
|
||||
'\n\nSessionStart hook\n' + String(startHook.inject).slice(0, 1500)
|
||||
}
|
||||
} catch {
|
||||
/* optional */
|
||||
@@ -14541,7 +14648,7 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
|
||||
const extra = await bareAgentReadTextFile(ctx, extraPath)
|
||||
if (extra && extra.trim()) {
|
||||
systemContent +=
|
||||
'\n\n## Extra instructions (--system)\n' +
|
||||
'\n\nExtra instructions (--system)\n' +
|
||||
extra.trim().slice(0, instructionsBudget)
|
||||
}
|
||||
}
|
||||
@@ -14579,7 +14686,7 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
|
||||
|
||||
if (config.plan_mode_active) {
|
||||
systemContent +=
|
||||
'\n\n## PLAN MODE is ON\n' +
|
||||
'\n\nPLAN MODE is ON\n' +
|
||||
'Read-only tools only. The only allowed write is ' +
|
||||
String(paths.plan || home + '/.agent/plan.md') +
|
||||
'. Draft the plan there, then call exit_plan_mode before implementing.\n'
|
||||
@@ -14591,7 +14698,7 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
|
||||
const sum = bareAgentTodoSummarize(todos)
|
||||
if (sum.total) {
|
||||
systemContent +=
|
||||
'\n\n## Session todos\n' +
|
||||
'\n\nSession todos\n' +
|
||||
sum.text +
|
||||
'\n(open=' +
|
||||
String(sum.open) +
|
||||
@@ -14604,7 +14711,22 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
|
||||
}
|
||||
}
|
||||
|
||||
// Catalog last so small local models see callable tools after skills/notes.
|
||||
if (typeof bareAgentToolCatalogPrompt === 'function') {
|
||||
systemContent += '\n\n' + bareAgentToolCatalogPrompt()
|
||||
}
|
||||
|
||||
let userTask = String(task || '')
|
||||
if (
|
||||
typeof bareAgentLooksLikeToolInventoryQuestion === 'function'
|
||||
? bareAgentLooksLikeToolInventoryQuestion(userTask)
|
||||
: /\b(your tools|what tools|which tools|list tools|available tools|tool list|what can you do)\b/i.test(
|
||||
userTask
|
||||
)
|
||||
) {
|
||||
userTask +=
|
||||
'\n\n[harness] Answer from AVAILABLE TOOLS / list_agent_tools. List every callable tool name. Do not list skills or /bin names as tools.'
|
||||
}
|
||||
if (config.autonomous_active) {
|
||||
userTask =
|
||||
'AUTONOMOUS RUN. Execute until the goal is done. Do not stop after a plan — use tools, then call task_complete.\n' +
|
||||
@@ -14683,6 +14805,13 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
|
||||
bareAgentNormalizeBaseUrl(String(configRef.current.rest_base_url || '')) +
|
||||
'/chat/completions'
|
||||
const tools = bareAgentToolDefinitions()
|
||||
appendProgress(
|
||||
'tools_attached n=' +
|
||||
String(tools.length) +
|
||||
(typeof bareAgentToolCatalog === 'function'
|
||||
? ' catalog=' + String(bareAgentToolCatalog(tools).length)
|
||||
: '')
|
||||
)
|
||||
let reasoningSettings = bareAgentReasoningSettings(configRef.current)
|
||||
let autonomousSettings = bareAgentAutonomousSettings(configRef.current)
|
||||
let reasoningCharCount = 0
|
||||
|
||||
Reference in New Issue
Block a user