Agent Harness Updates
Release rolling / release (push) Successful in 10m1s

This commit is contained in:
2026-08-19 14:04:03 -04:00
parent 05852180d1
commit d047d26f0a
10 changed files with 606 additions and 42 deletions
+170 -14
View File
@@ -1465,6 +1465,89 @@ function bareAgentNormalizeGuestScript(code) {
return src.trim() + '\n'
}
/**
* Trim glued prose off a curl/wget URL (`orgBut` → `org`).
* @param {string} cmd
*/
function bareAgentTrimGluedShellCommand(cmd) {
let s = String(cmd || '').trim()
s = s.replace(/(\.(?:org|com|net|io|dev|fyi|info|edu|co))([A-Z].*)$/i, '$1')
s = s.replace(/(https?:\/\/[^\s]+?)(?=[A-Z][a-z])/, '$1')
return s.trim()
}
/**
* If a run_js_script body is actually a guest CLI (curl/wget/ip), return
* the command so dispatch can divert to run_command.
* @param {string} code
* @returns {string}
*/
function bareAgentShellCommandFromJsScript(code) {
const s = String(code || '')
if (!s.trim()) return ''
const trimmed = s.trim()
const looksShell =
typeof bareAgentLooksLikeShellCommand === 'function'
? bareAgentLooksLikeShellCommand(trimmed)
: /^(curl|wget|ip|ping|ifconfig)\b/i.test(trimmed)
if (
looksShell &&
!/\bfunction\b|\bclass\b|\bawait\b|\bconst\b|\blet\b|\bvar\b|\bimport\b/.test(trimmed)
) {
return bareAgentTrimGluedShellCommand(trimmed)
}
const execRe =
/\b(?:execLine|execSync|exec|spawnSync|system)\s*\(\s*(['"`])([\s\S]*?)\1/g
let m
while ((m = execRe.exec(s))) {
const cmd = String(m[2] || '').trim()
if (/^(curl|wget|ip|ping|ifconfig)\b/i.test(cmd)) {
return bareAgentTrimGluedShellCommand(cmd)
}
}
const fetchRe = /\bfetch\s*\(\s*(['"`])(https?:\/\/[^'"`]+)\1/
m = fetchRe.exec(s)
if (m) return 'curl -s ' + String(m[2] || '').trim()
const curlRe = /(?:^|[\n;])\s*((?:curl|wget)\s+https?:\/\/[^\s;'"`]+)/im
m = curlRe.exec(s)
if (m) return bareAgentTrimGluedShellCommand(m[1])
return ''
}
/**
* task_complete used as a surrender after a failed tool, not a real finish.
* @param {string} summary
*/
function bareAgentLooksLikeFailedTaskComplete(summary) {
const s = String(summary || '').toLowerCase()
if (!s.trim()) return false
return (
/error occurred/.test(s) ||
/alternative method required/.test(s) ||
(/attempted to /.test(s) && /error|fail/.test(s)) ||
/failed due to/.test(s) ||
/could not (run|execute|retrieve|complete|get)/.test(s) ||
/not (able|allowed) to (run|execute|complete)/.test(s) ||
/top-level (scope|await|module)/.test(s)
)
}
/**
* User asked to run a guest CLI (curl / IP lookup), not write JS.
* @param {string} text
*/
function bareAgentLooksLikeGuestCliRequest(text) {
const s = String(text || '').toLowerCase()
if (!s.trim()) return false
return (
/\b(run|execute|use)\b.{0,48}\b(curl|wget|ping|ifconfig|ip addr)\b/.test(s) ||
/\b(curl|wget)\b.{0,48}\b(ip address|public ip|our ip|my ip)\b/.test(s) ||
/\b(find|get|check|show|lookup)\b.{0,48}\b(ip address|public ip|our ip|my ip)\b/.test(
s
)
)
}
/** ~/.agent paths, config, history trim, man digest (preamble for /bin/agent). */
/**
@@ -6955,7 +7038,7 @@ function bareAgentToolDefinitions() {
function: {
name: 'run_command',
description:
'Run a shell command line via ctx.execLine (same as interactive shell). Output is captured to a temp file. Set capture_exit true to append a final EXIT:<code> line.',
'Run a guest CLI line (curl, wget, ip, ping, ls, cat, …) via ctx.execLine. Prefer this over run_js_script for any shell command. Output is captured to a temp file. Set capture_exit true to append a final EXIT:<code> line.',
parameters: {
type: 'object',
properties: {
@@ -6982,7 +7065,7 @@ function bareAgentToolDefinitions() {
function: {
name: 'run_js_script',
description:
'Run custom guest JavaScript only. Do not use this to replace read_file, write_file, list_directory, or run_command. Node is not installed. Writes ~/.agent/_tmp_agent_run.mjs and runs it on the Bare kernel. ctx and argv are already injected — never declare them, never export. Body must be: async function run(ctx, argv) { const vfs = ctx.vfs; ... }',
'Run custom guest JavaScript only. Do not use this for curl, wget, ip, ping, or any shell — call run_command. Do not use this to replace read_file, write_file, list_directory, or run_command. Node is not installed. Writes ~/.agent/_tmp_agent_run.mjs and runs it on the Bare kernel. ctx and argv are already injected — never declare them, never export. Body must be: async function run(ctx, argv) { const vfs = ctx.vfs; ... }',
parameters: {
type: 'object',
properties: {
@@ -8440,7 +8523,7 @@ function bareAgentToolCatalogPrompt(tools) {
'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.',
'These names are the only functions you can call. Skills such as ctx-api-change, docs-contract-update, hdms, and holesail are playbooks: load them with read_skill. Guest /bin names such as ctx-baredoctor, hdms, curl, and holepunch are commands for run_command, not tools. curl/wget/ip are run_command — never run_js_script.',
'When the user asks what tools you have or what you can do, list every name below. Do not invent names. Do not list skills as tools.',
'To call a tool, emit exactly:',
'<tool_call>{"name":"TOOL_NAME","arguments":{}}</tool_call>',
@@ -9082,6 +9165,19 @@ async function bareAgentDispatchTool(o) {
if (toolName === 'task_complete') {
const summary = typeof args.summary === 'string' ? args.summary : ''
if (
typeof bareAgentLooksLikeFailedTaskComplete === 'function' &&
bareAgentLooksLikeFailedTaskComplete(summary)
) {
appendProgress('task_complete_rejected_failure')
return bareAgentJsonResult({
ok: false,
error: 'task_not_complete',
hint:
'Do not call task_complete after a failed tool. Keep going. Guest CLI (curl, wget, ip, ping, ls) is run_command({command:"..."}). Never wrap curl in run_js_script. Call run_command now and report stdout.',
summary
})
}
appendProgress('task_complete: ' + summary.slice(0, 200))
onTaskComplete(summary || '(done)')
return bareAgentJsonResult({
@@ -9457,6 +9553,18 @@ async function bareAgentDispatchTool(o) {
if (toolName === 'run_js_script') {
const rawCode = typeof args.code === 'string' ? args.code : ''
const diverted =
typeof bareAgentShellCommandFromJsScript === 'function'
? bareAgentShellCommandFromJsScript(rawCode)
: ''
if (diverted) {
appendProgress('run_js_script_diverted_to_run_command ' + diverted.slice(0, 120))
return bareAgentDispatchTool({
...o,
toolName: 'run_command',
argsJson: JSON.stringify({ command: diverted, capture_exit: true })
})
}
const code =
typeof bareAgentNormalizeGuestScript === 'function'
? bareAgentNormalizeGuestScript(rawCode)
@@ -9485,6 +9593,20 @@ async function bareAgentDispatchTool(o) {
stdout_stderr: text
})
}
if (
/await is only valid|top.level|cannot find module|require is not defined|node\.js|ReferenceError|SyntaxError/i.test(
text
) ||
/await is only valid|top.level/i.test(String(out.error || ''))
) {
return bareAgentJsonResult({
ok: false,
error: 'guest_script_wrong_tool',
hint:
'Do not use run_js_script for curl/wget/ip/shell. Node is not installed. Call run_command({command:"curl -s https://api.ipify.org"}) and report stdout.',
stdout_stderr: text
})
}
return bareAgentJsonResult(
r.ok === false ? r : { ok: true, stdout_stderr: r.stdout_stderr }
)
@@ -13463,7 +13585,7 @@ const BARE_AGENT_STATIC_SYSTEM = `You are the Bare OS coding agent — a senior
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.
YOU CAN EXECUTE. Never say "I cannot execute commands", "I cannot run CLI", "I can help you use available tools", or "try:". That is a failure. Guest shell is run_command({command, cwd?}). There is no bash, shell, cli, or terminal tool — those names map to run_command. Emitting a ```bash fence instead of calling run_command is a failure. If the operator says "run it yourself", call the tool immediately and return the result.
YOU CAN EXECUTE. Never say "I cannot execute commands", "I cannot run CLI", "I can help you use available tools", or "try:". That is a failure. Guest shell is run_command({command, cwd?}). There is no bash, shell, cli, or terminal tool — those names map to run_command. Emitting a ```bash fence instead of calling run_command is a failure. If the operator says "run it yourself", call the tool immediately and return the result. curl, wget, ip, ping, ls, cat, and every other guest CLI are run_command — never wrap them in run_js_script. Do not call task_complete after a failed tool; retry with run_command until you have stdout.
Bare OS by Raven Scott (https://raven-scott.fyi). Repo: https://git.ssh.surf/snxraven/bare-operating-system. Booter: pear://qupw8zspk34pcxc7fqchzyeh33jtmxq1k7qze44fkosctwiid8zy
@@ -13480,7 +13602,7 @@ ACCESS (denylist, not allowlist). You already have full guest admin. You can cre
- 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). Never dump curl/ip/ls for the user — call run_command and report stdout.
- 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. Do not use run_js_script to read files, write files, or run shell — call read_file, write_file, run_command instead. Only use run_js_script for custom guest JS. The kernel already injects ctx and argv: never write const/let/var ctx, never export. Body must be only async function run(ctx, argv) { const vfs = ctx.vfs; ... }. Do not import Node builtins. Never paste a "final correct script" into the user reply — call the tool.
- Node is not installed in the guest. Never plan or run node, npm, or npx here. Do not use run_js_script to read files, write files, or run shell — call read_file, write_file, run_command instead. curl/wget/ip/ping are run_command({command:"curl -s https://api.ipify.org"}), never run_js_script. Only use run_js_script for custom guest JS. The kernel already injects ctx and argv: never write const/let/var ctx, never export. Body must be only async function run(ctx, argv) { const vfs = ctx.vfs; ... }. Do not import Node builtins. Never paste a "final correct script" into the user reply — call the tool.
- 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.
@@ -13492,7 +13614,7 @@ CODING LOOP. Multi-step work: todo_write (merge=true). Large unknown surface: en
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.
4. Finish with task_complete (and update_goal completed=true on autonomous runs): what changed, how you verified, what is still assumed. Never task_complete with "error occurred" / "attempted" / "alternative method required" — that is a failure, not a finish. 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.
@@ -13800,7 +13922,9 @@ function bareAgentLooksLikeInstructionDump(text) {
/please (run|execute|try) (this|the|it)/.test(low) ||
/try this command/.test(low) ||
/for .{0,60} try:/.test(low) ||
/let me know if you need help with other commands/.test(low)
/let me know if you need help with other commands/.test(low) ||
/the assistant (is supposed to|should|needs to|would) (use|call|generate)/.test(low) ||
/the correct approach is to call/.test(low)
) {
return true
}
@@ -13983,6 +14107,19 @@ function bareAgentExtractToolCallsFromText(text) {
}
}
const glued = /\b((?:curl|wget)\s+https?:\/\/[^\s]+)/gi
while ((m = glued.exec(src))) {
let cmd = String(m[1] || '').trim()
if (typeof bareAgentTrimGluedShellCommand === 'function') {
cmd = bareAgentTrimGluedShellCommand(cmd)
} else {
cmd = cmd.replace(/(\.(?:org|com|net|io|dev|fyi))([A-Z].*)$/i, '$1')
}
if (/^(curl|wget)\s+https?:\/\//i.test(cmd)) {
push('run_command', JSON.stringify({ command: cmd }))
}
}
return out
}
@@ -15146,6 +15283,13 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
userTask +=
'\n\n[harness] The operator told you to execute. Call run_command / write_file / the rest of AVAILABLE TOOLS yourself. Do not print commands for them. There is no bash tool — use run_command.'
}
if (
typeof bareAgentLooksLikeGuestCliRequest === 'function' &&
bareAgentLooksLikeGuestCliRequest(userTask)
) {
userTask +=
'\n\n[harness] This is a guest CLI request. Call run_command({command:"curl -s https://api.ipify.org"}) or the equivalent now. Do not use run_js_script. Do not dump the command. Do not task_complete until stdout has the result.'
}
if (discordReply) {
userTask +=
'\n\n[harness] This is Discord. Execute with tools. The operator will not run your commands. Call run_command yourself. Never dump curl/ip/bash for them to copy. Never say you cannot execute.'
@@ -15536,6 +15680,7 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
}
let assistantContent = ''
let thinkDump = ''
/** @type {Map<number, { id: string, name: string, args: string }>} */
const toolAcc = new Map()
/** @type {unknown} */
@@ -15547,14 +15692,22 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
if (recoveredFromText) return
recoveredFromText = true
if (typeof bareAgentExtractToolCallsFromText !== 'function') return
const extracted = bareAgentExtractToolCallsFromText(assistantContent)
const blob = assistantContent + '\n' + thinkDump
const extracted = bareAgentExtractToolCallsFromText(blob)
if (extracted.length) {
if (!toolAcc.size) {
for (const tc of extracted) bareAgentMergeToolCallDelta(toolAcc, tc)
appendProgress(
'recovered_tool_calls_from_text n=' + String(extracted.length)
)
const before = toolAcc.size
for (const tc of extracted) {
const shifted = {
index: before + 1000 + (typeof tc.index === 'number' ? tc.index : 0),
id: tc.id,
function: tc.function
}
bareAgentMergeToolCallDelta(toolAcc, shifted)
}
appendProgress(
(before ? 'recovered_additional_tool_calls_from_text n=' : 'recovered_tool_calls_from_text n=') +
String(extracted.length)
)
assistantContent = bareAgentStripToolCallsFromText(assistantContent)
}
if (
@@ -15619,6 +15772,7 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
*/
function feedThink(chunk) {
if (!chunk || !String(chunk).trim()) return
thinkDump += chunk
if (hideThink) return
clearStatusLine()
if (thinkPanel) thinkPanel.append(chunk)
@@ -15997,7 +16151,9 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
let toolCallsArr = bareAgentFinalizeToolCalls(toolAcc)
if (!toolCallsArr.length && typeof bareAgentExtractToolCallsFromText === 'function') {
const extracted = bareAgentExtractToolCallsFromText(assistantContent)
const extracted = bareAgentExtractToolCallsFromText(
assistantContent + '\n' + thinkDump
)
if (extracted.length) {
for (const tc of extracted) bareAgentMergeToolCallDelta(toolAcc, tc)
toolCallsArr = bareAgentFinalizeToolCalls(toolAcc)