Agent Updates
This commit is contained in:
+110
-7
@@ -1159,6 +1159,47 @@ async function bareAgentLoadHistory(ctx, path) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear persisted chat session (history + progress log; keeps config and instructions).
|
||||
* @param {Record<string, unknown>} ctx
|
||||
* @param {ReturnType<typeof bareAgentPaths>} paths
|
||||
* @param {string} argv0
|
||||
*/
|
||||
async function bareAgentResetChatSession(ctx, paths, argv0) {
|
||||
const vfs = ctx.vfs
|
||||
if (!vfs || typeof vfs.mkdir !== 'function' || typeof vfs.writeFile !== 'function') {
|
||||
throw new Error('agent reset: vfs unavailable')
|
||||
}
|
||||
await vfs.mkdir(paths.dir, { recursive: true })
|
||||
const emptyHist =
|
||||
typeof ctx.b4a !== 'undefined' && ctx.b4a && typeof ctx.b4a.from === 'function'
|
||||
? ctx.b4a.from('[]\n')
|
||||
: new TextEncoder().encode('[]\n')
|
||||
await vfs.writeFile(paths.history, emptyHist)
|
||||
const stamp = new Date().toISOString() + ' chat session reset\n'
|
||||
const progBody =
|
||||
typeof ctx.b4a !== 'undefined' && ctx.b4a && typeof ctx.b4a.from === 'function'
|
||||
? ctx.b4a.from(stamp)
|
||||
: new TextEncoder().encode(stamp)
|
||||
await vfs.writeFile(paths.progress, progBody)
|
||||
try {
|
||||
const z =
|
||||
typeof ctx.b4a !== 'undefined' && ctx.b4a && typeof ctx.b4a.from === 'function'
|
||||
? ctx.b4a.from('')
|
||||
: new TextEncoder().encode('')
|
||||
await vfs.writeFile(paths.cmdOut, z)
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
try {
|
||||
ctx.console.log(
|
||||
argv0 + ': chat session cleared (' + paths.history + ', ' + paths.progress + ')'
|
||||
)
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
|
||||
/** SSE line split + data payload parse (shared by agent-openai + tests). */
|
||||
|
||||
/**
|
||||
@@ -1513,7 +1554,7 @@ function bareAgentToolDefinitions() {
|
||||
function: {
|
||||
name: 'run_js_script',
|
||||
description:
|
||||
'Save JS to ~/.agent/_tmp_agent_run.mjs and execute it via the shell like any drive script (absolute path; same Bare kernel runner as /bin — no separate node binary). Prefer define async function run(ctx, argv). stdout/stderr captured.',
|
||||
'REQUIRED to run agent-authored JavaScript: Node is not installed. Writes code to ~/.agent/_tmp_agent_run.mjs and runs it by absolute path (Bare kernel — same as /bin scripts). Do not use run_command with node/npm/npx. Prefer async function run(ctx, argv). stdout/stderr captured.',
|
||||
parameters: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
@@ -2100,15 +2141,46 @@ function bareAgentWriteOut(out, s) {
|
||||
|
||||
const BARE_AGENT_STATIC_SYSTEM = `You are the Bare OS autonomous agent inside a JavaScript POSIX-like environment on Hyperdrive + Hyperswarm (Pear/Bare runtime).
|
||||
|
||||
There is no host \`node\` binary. Userland \`.js\` / \`.mjs\` is run by the kernel (path on a drive, e.g. /home/.../x.mjs, or \`./x.mjs\` in the shell) like /bin scripts. run_js_script writes a file and runs it that way; for ad-hoc lines use run_command with real /bin tools or sh -c.
|
||||
JavaScript execution on this OS: **Node.js is not installed.** The \`node\`, \`npm\`, and \`npx\` commands **do not exist** and must never appear in plans or in run_command. To run JS as part of your agent work, **you must call the run_js_script tool** (writes under ~/.agent and executes via the Bare kernel). Optional: once a script exists on disk, run_command may invoke it by **absolute path** (e.g. \`/home/.../script.mjs\`)—same mechanism as \`/bin\` scripts—not via \`node\`.
|
||||
|
||||
Capabilities: use ctx.execLine for shell commands (same language as the interactive shell). Use ctx.vfs readFile/writeFile/mkdir/readdir/chmod where available. Paths under /home, /mnt, /tmp map to Hypercore-backed storage; system paths like /bin, /etc are on the system drive.
|
||||
Capabilities: ctx.execLine for shell lines; ctx.vfs readFile/writeFile/mkdir/readdir/chmod. Paths under /home (personal Hyperdrive), /mnt, /tmp are writable where policy allows; /bin, /etc are system drive.
|
||||
|
||||
Safety: never exfiltrate ~/.agent/config.json or API keys in chat. Prefer least-privilege commands. Call task_complete(summary) only when fully done.
|
||||
Safety: never exfiltrate ~/.agent/config.json or API keys. Prefer least-privilege commands. Call task_complete(summary) when fully done.
|
||||
|
||||
Discovery: run man <topic> from the shell, or read /share/man/man.json. Tier-1 utilities live under /bin.
|
||||
Discovery: man <topic>, /share/man/man.json; Tier-1 utilities in /bin.
|
||||
|
||||
Always prefer tools over guessing when facts about the filesystem or commands are needed.`
|
||||
Prefer tools over guessing for filesystem and shell facts.`
|
||||
|
||||
/**
|
||||
* Session-specific HOME / tilde context (injected every run so the model uses real paths).
|
||||
* @param {Record<string, unknown>} ctx
|
||||
* @param {string} home from bareAgentResolveHome
|
||||
* @param {{ dir: string, config: string }} paths
|
||||
*/
|
||||
function bareAgentSessionHomeBlock(ctx, home, paths) {
|
||||
const env =
|
||||
ctx.env && typeof ctx.env === 'object'
|
||||
? /** @type {Record<string, string>} */ (ctx.env)
|
||||
: {}
|
||||
const homeEnv = String(env.HOME || '').trim()
|
||||
return (
|
||||
'## This session: home directory and paths\n' +
|
||||
'- **Resolved user home (this session):** `' +
|
||||
home +
|
||||
'`\n' +
|
||||
'- **HOME in the environment:** `' +
|
||||
(homeEnv || home) +
|
||||
'`\n' +
|
||||
'- **Tilde \`~\`:** In shell and in user docs, \`~\` means this home directory. Examples: \`~/.agent\` == `' +
|
||||
paths.dir +
|
||||
'`, agent config `' +
|
||||
paths.config +
|
||||
'`. 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'
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {unknown} tc
|
||||
@@ -2298,6 +2370,8 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
|
||||
let systemContent =
|
||||
BARE_AGENT_STATIC_SYSTEM +
|
||||
'\n\n' +
|
||||
bareAgentSessionHomeBlock(ctx, home, paths) +
|
||||
'\n\n' +
|
||||
manDigest.slice(0, 12000)
|
||||
if (instructions)
|
||||
systemContent += '\n\n## Session notes\n' + instructions.slice(0, 8000)
|
||||
@@ -2575,14 +2649,21 @@ async function run(ctx, argv) {
|
||||
ctx.console.log(
|
||||
'usage: ' +
|
||||
argv0 +
|
||||
' [--setup] YOUR_REQUEST_HERE\n' +
|
||||
' [--setup | --reset] YOUR_REQUEST_HERE\n' +
|
||||
' ' +
|
||||
argv0 +
|
||||
' --setup\n' +
|
||||
' ' +
|
||||
argv0 +
|
||||
' --reset\n' +
|
||||
' ' +
|
||||
argv0 +
|
||||
' reset\n' +
|
||||
'\n' +
|
||||
'Runs an autonomous coding/OS agent against any OpenAI-compatible HTTPS API.\n' +
|
||||
'Configuration: ~/.agent/config.json on your personal drive (created on first run).\n' +
|
||||
'Use --setup to interactively set API URL, key, model, and provider label.\n' +
|
||||
'Use --reset or `reset` to clear ~/.agent/history.json and start a fresh chat session.\n' +
|
||||
'\n' +
|
||||
'Examples:\n' +
|
||||
' ' +
|
||||
@@ -2591,6 +2672,9 @@ async function run(ctx, argv) {
|
||||
' ' +
|
||||
argv0 +
|
||||
' --setup\n' +
|
||||
' ' +
|
||||
argv0 +
|
||||
' --reset\n' +
|
||||
'\n' +
|
||||
'See man agent.'
|
||||
)
|
||||
@@ -2599,14 +2683,33 @@ async function run(ctx, argv) {
|
||||
}
|
||||
|
||||
let setupFlag = false
|
||||
let resetFlag = false
|
||||
/** @type {string[]} */
|
||||
const rest = []
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const a = args[i]
|
||||
if (a === '--setup') setupFlag = true
|
||||
else if (a === '--reset') resetFlag = true
|
||||
else rest.push(a)
|
||||
}
|
||||
|
||||
const wantReset =
|
||||
resetFlag || (rest.length === 1 && rest[0] === 'reset')
|
||||
if (wantReset) {
|
||||
const home = bareAgentResolveHome(ctx)
|
||||
const paths = bareAgentPaths(home)
|
||||
try {
|
||||
await bareAgentResetChatSession(ctx, paths, argv0)
|
||||
ctx.exitCode = 0
|
||||
} catch (e) {
|
||||
const msg =
|
||||
e && typeof e === 'object' && 'message' in e ? String(e.message) : String(e)
|
||||
ctx.console.error(argv0 + ': ' + msg)
|
||||
ctx.exitCode = 1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
const task = rest.join(' ').trim()
|
||||
if (!task && !setupFlag) {
|
||||
ctx.console.error(argv0 + ': missing task (or use --setup)')
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"schema": 2,
|
||||
"profileId": "bare-os-posix-like",
|
||||
"generatedAt": "2026-04-22T02:08:07.698Z",
|
||||
"generatedAt": "2026-04-22T02:18:32.387Z",
|
||||
"note": "Sparse POSIX Issue 7 coverage hints for /bin utilities. Omitted command names are not yet profiled here.",
|
||||
"commandIndex": [
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"atMs": 1776823687697,
|
||||
"atMs": 1776824312386,
|
||||
"commands": [
|
||||
"agent",
|
||||
"arch",
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -364,3 +364,44 @@ async function bareAgentLoadHistory(ctx, path) {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear persisted chat session (history + progress log; keeps config and instructions).
|
||||
* @param {Record<string, unknown>} ctx
|
||||
* @param {ReturnType<typeof bareAgentPaths>} paths
|
||||
* @param {string} argv0
|
||||
*/
|
||||
async function bareAgentResetChatSession(ctx, paths, argv0) {
|
||||
const vfs = ctx.vfs
|
||||
if (!vfs || typeof vfs.mkdir !== 'function' || typeof vfs.writeFile !== 'function') {
|
||||
throw new Error('agent reset: vfs unavailable')
|
||||
}
|
||||
await vfs.mkdir(paths.dir, { recursive: true })
|
||||
const emptyHist =
|
||||
typeof ctx.b4a !== 'undefined' && ctx.b4a && typeof ctx.b4a.from === 'function'
|
||||
? ctx.b4a.from('[]\n')
|
||||
: new TextEncoder().encode('[]\n')
|
||||
await vfs.writeFile(paths.history, emptyHist)
|
||||
const stamp = new Date().toISOString() + ' chat session reset\n'
|
||||
const progBody =
|
||||
typeof ctx.b4a !== 'undefined' && ctx.b4a && typeof ctx.b4a.from === 'function'
|
||||
? ctx.b4a.from(stamp)
|
||||
: new TextEncoder().encode(stamp)
|
||||
await vfs.writeFile(paths.progress, progBody)
|
||||
try {
|
||||
const z =
|
||||
typeof ctx.b4a !== 'undefined' && ctx.b4a && typeof ctx.b4a.from === 'function'
|
||||
? ctx.b4a.from('')
|
||||
: new TextEncoder().encode('')
|
||||
await vfs.writeFile(paths.cmdOut, z)
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
try {
|
||||
ctx.console.log(
|
||||
argv0 + ': chat session cleared (' + paths.history + ', ' + paths.progress + ')'
|
||||
)
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ function bareAgentToolDefinitions() {
|
||||
function: {
|
||||
name: 'run_js_script',
|
||||
description:
|
||||
'Save JS to ~/.agent/_tmp_agent_run.mjs and execute it via the shell like any drive script (absolute path; same Bare kernel runner as /bin — no separate node binary). Prefer define async function run(ctx, argv). stdout/stderr captured.',
|
||||
'REQUIRED to run agent-authored JavaScript: Node is not installed. Writes code to ~/.agent/_tmp_agent_run.mjs and runs it by absolute path (Bare kernel — same as /bin scripts). Do not use run_command with node/npm/npx. Prefer async function run(ctx, argv). stdout/stderr captured.',
|
||||
parameters: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
|
||||
@@ -46,15 +46,46 @@ function bareAgentWriteOut(out, s) {
|
||||
|
||||
const BARE_AGENT_STATIC_SYSTEM = `You are the Bare OS autonomous agent inside a JavaScript POSIX-like environment on Hyperdrive + Hyperswarm (Pear/Bare runtime).
|
||||
|
||||
There is no host \`node\` binary. Userland \`.js\` / \`.mjs\` is run by the kernel (path on a drive, e.g. /home/.../x.mjs, or \`./x.mjs\` in the shell) like /bin scripts. run_js_script writes a file and runs it that way; for ad-hoc lines use run_command with real /bin tools or sh -c.
|
||||
JavaScript execution on this OS: **Node.js is not installed.** The \`node\`, \`npm\`, and \`npx\` commands **do not exist** and must never appear in plans or in run_command. To run JS as part of your agent work, **you must call the run_js_script tool** (writes under ~/.agent and executes via the Bare kernel). Optional: once a script exists on disk, run_command may invoke it by **absolute path** (e.g. \`/home/.../script.mjs\`)—same mechanism as \`/bin\` scripts—not via \`node\`.
|
||||
|
||||
Capabilities: use ctx.execLine for shell commands (same language as the interactive shell). Use ctx.vfs readFile/writeFile/mkdir/readdir/chmod where available. Paths under /home, /mnt, /tmp map to Hypercore-backed storage; system paths like /bin, /etc are on the system drive.
|
||||
Capabilities: ctx.execLine for shell lines; ctx.vfs readFile/writeFile/mkdir/readdir/chmod. Paths under /home (personal Hyperdrive), /mnt, /tmp are writable where policy allows; /bin, /etc are system drive.
|
||||
|
||||
Safety: never exfiltrate ~/.agent/config.json or API keys in chat. Prefer least-privilege commands. Call task_complete(summary) only when fully done.
|
||||
Safety: never exfiltrate ~/.agent/config.json or API keys. Prefer least-privilege commands. Call task_complete(summary) when fully done.
|
||||
|
||||
Discovery: run man <topic> from the shell, or read /share/man/man.json. Tier-1 utilities live under /bin.
|
||||
Discovery: man <topic>, /share/man/man.json; Tier-1 utilities in /bin.
|
||||
|
||||
Always prefer tools over guessing when facts about the filesystem or commands are needed.`
|
||||
Prefer tools over guessing for filesystem and shell facts.`
|
||||
|
||||
/**
|
||||
* Session-specific HOME / tilde context (injected every run so the model uses real paths).
|
||||
* @param {Record<string, unknown>} ctx
|
||||
* @param {string} home from bareAgentResolveHome
|
||||
* @param {{ dir: string, config: string }} paths
|
||||
*/
|
||||
function bareAgentSessionHomeBlock(ctx, home, paths) {
|
||||
const env =
|
||||
ctx.env && typeof ctx.env === 'object'
|
||||
? /** @type {Record<string, string>} */ (ctx.env)
|
||||
: {}
|
||||
const homeEnv = String(env.HOME || '').trim()
|
||||
return (
|
||||
'## This session: home directory and paths\n' +
|
||||
'- **Resolved user home (this session):** `' +
|
||||
home +
|
||||
'`\n' +
|
||||
'- **HOME in the environment:** `' +
|
||||
(homeEnv || home) +
|
||||
'`\n' +
|
||||
'- **Tilde \`~\`:** In shell and in user docs, \`~\` means this home directory. Examples: \`~/.agent\` == `' +
|
||||
paths.dir +
|
||||
'`, agent config `' +
|
||||
paths.config +
|
||||
'`. 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'
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {unknown} tc
|
||||
@@ -244,6 +275,8 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
|
||||
let systemContent =
|
||||
BARE_AGENT_STATIC_SYSTEM +
|
||||
'\n\n' +
|
||||
bareAgentSessionHomeBlock(ctx, home, paths) +
|
||||
'\n\n' +
|
||||
manDigest.slice(0, 12000)
|
||||
if (instructions)
|
||||
systemContent += '\n\n## Session notes\n' + instructions.slice(0, 8000)
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
"section": 1,
|
||||
"title": "OpenAI-compatible autonomous coding agent",
|
||||
"synopsis": [
|
||||
"agent [--setup]",
|
||||
"agent [--setup | --reset]",
|
||||
"agent reset",
|
||||
"agent [--setup] REQUEST"
|
||||
],
|
||||
"description": "Runs a persistent ReAct-style loop against any OpenAI-compatible HTTPS API (Groq, OpenAI, xAI, etc.). **No environment variables** are used for credentials: everything lives in **`~/.agent/config.json`** on your **personal Hyperdrive**, created on first run with Groq-oriented defaults.\n\nOn a **TTY**, the interactive shell line editor is suspended during the session (**`suspendReplForSubprocess`**). Assistant output streams with ANSI highlighting; tool invocations are labeled.\n\n**Interrupt:** **Ctrl+C** aborts in-flight HTTPS requests (**`SIGINT`** / **`AbortSignal`**) and restores the REPL.\n\n**HTTPS policy:** Delegated **`fetch`** follows the booter (**`ctx.httpFetch`**). Where **`BARE_OS_HTTP_ALLOWLIST`** is set, operators must include your provider hostname (for example **`api.groq.com`**, **`api.openai.com`**, **`api.x.ai`**).\n\n**Tools:** **`read_file`**, **`write_file`**, **`edit_file`**, **`create_directory`**, **`search_files`** (**`grep`**), **`run_command`** (**`execLine`**), **`run_js_script`** (writes **`~/.agent/_tmp_agent_run.mjs`** then runs it by **path**, same as **`./script.mjs`**), **`get_system_info`**, **`edit_agent_config`**, **`list_bin`**, **`task_complete`**.",
|
||||
"description": "Runs a persistent ReAct-style loop against any OpenAI-compatible HTTPS API (Groq, OpenAI, xAI, etc.). **No environment variables** are used for credentials: everything lives in **`~/.agent/config.json`** on your **personal Hyperdrive**, created on first run with Groq-oriented defaults.\n\nOn a **TTY**, the interactive shell line editor is suspended during the session (**`suspendReplForSubprocess`**). Assistant output streams with ANSI highlighting; tool invocations are labeled.\n\n**Interrupt:** **Ctrl+C** aborts in-flight HTTPS requests (**`SIGINT`** / **`AbortSignal`**) and restores the REPL.\n\n**HTTPS policy:** Delegated **`fetch`** follows the booter (**`ctx.httpFetch`**). Where **`BARE_OS_HTTP_ALLOWLIST`** is set, operators must include your provider hostname (for example **`api.groq.com`**, **`api.openai.com`**, **`api.x.ai`**).\n\n**Tools:** **`read_file`**, **`write_file`**, **`edit_file`**, **`create_directory`**, **`search_files`** (**`grep`**), **`run_command`** (**`execLine`**), **`run_js_script`** (**Node is not installed** — use this tool for JS; writes **`~/.agent/_tmp_agent_run.mjs`** then executes by absolute path like **`./script.mjs`**), **`get_system_info`**, **`edit_agent_config`**, **`list_bin`**, **`task_complete`**.",
|
||||
"options": [
|
||||
{
|
||||
"flag": "--setup",
|
||||
@@ -15,6 +16,10 @@
|
||||
{
|
||||
"flag": "--help",
|
||||
"meaning": "usage summary (also **`-h`**)"
|
||||
},
|
||||
{
|
||||
"flag": "--reset",
|
||||
"meaning": "clear **`~/.agent/history.json`** and truncate **`~/.agent/progress.txt`** (fresh chat session; **`config.json`** unchanged)"
|
||||
}
|
||||
],
|
||||
"files": [
|
||||
@@ -31,6 +36,10 @@
|
||||
"caption": "configure credentials",
|
||||
"code": "agent --setup"
|
||||
},
|
||||
{
|
||||
"caption": "clear chat session history",
|
||||
"code": "agent --reset"
|
||||
},
|
||||
{
|
||||
"caption": "natural-language task",
|
||||
"code": "agent \"list ten random names from /bin\""
|
||||
|
||||
@@ -9,14 +9,21 @@ async function run(ctx, argv) {
|
||||
ctx.console.log(
|
||||
'usage: ' +
|
||||
argv0 +
|
||||
' [--setup] YOUR_REQUEST_HERE\n' +
|
||||
' [--setup | --reset] YOUR_REQUEST_HERE\n' +
|
||||
' ' +
|
||||
argv0 +
|
||||
' --setup\n' +
|
||||
' ' +
|
||||
argv0 +
|
||||
' --reset\n' +
|
||||
' ' +
|
||||
argv0 +
|
||||
' reset\n' +
|
||||
'\n' +
|
||||
'Runs an autonomous coding/OS agent against any OpenAI-compatible HTTPS API.\n' +
|
||||
'Configuration: ~/.agent/config.json on your personal drive (created on first run).\n' +
|
||||
'Use --setup to interactively set API URL, key, model, and provider label.\n' +
|
||||
'Use --reset or `reset` to clear ~/.agent/history.json and start a fresh chat session.\n' +
|
||||
'\n' +
|
||||
'Examples:\n' +
|
||||
' ' +
|
||||
@@ -25,6 +32,9 @@ async function run(ctx, argv) {
|
||||
' ' +
|
||||
argv0 +
|
||||
' --setup\n' +
|
||||
' ' +
|
||||
argv0 +
|
||||
' --reset\n' +
|
||||
'\n' +
|
||||
'See man agent.'
|
||||
)
|
||||
@@ -33,14 +43,33 @@ async function run(ctx, argv) {
|
||||
}
|
||||
|
||||
let setupFlag = false
|
||||
let resetFlag = false
|
||||
/** @type {string[]} */
|
||||
const rest = []
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const a = args[i]
|
||||
if (a === '--setup') setupFlag = true
|
||||
else if (a === '--reset') resetFlag = true
|
||||
else rest.push(a)
|
||||
}
|
||||
|
||||
const wantReset =
|
||||
resetFlag || (rest.length === 1 && rest[0] === 'reset')
|
||||
if (wantReset) {
|
||||
const home = bareAgentResolveHome(ctx)
|
||||
const paths = bareAgentPaths(home)
|
||||
try {
|
||||
await bareAgentResetChatSession(ctx, paths, argv0)
|
||||
ctx.exitCode = 0
|
||||
} catch (e) {
|
||||
const msg =
|
||||
e && typeof e === 'object' && 'message' in e ? String(e.message) : String(e)
|
||||
ctx.console.error(argv0 + ': ' + msg)
|
||||
ctx.exitCode = 1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
const task = rest.join(' ').trim()
|
||||
if (!task && !setupFlag) {
|
||||
ctx.console.error(argv0 + ': missing task (or use --setup)')
|
||||
|
||||
@@ -1159,6 +1159,47 @@ async function bareAgentLoadHistory(ctx, path) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear persisted chat session (history + progress log; keeps config and instructions).
|
||||
* @param {Record<string, unknown>} ctx
|
||||
* @param {ReturnType<typeof bareAgentPaths>} paths
|
||||
* @param {string} argv0
|
||||
*/
|
||||
async function bareAgentResetChatSession(ctx, paths, argv0) {
|
||||
const vfs = ctx.vfs
|
||||
if (!vfs || typeof vfs.mkdir !== 'function' || typeof vfs.writeFile !== 'function') {
|
||||
throw new Error('agent reset: vfs unavailable')
|
||||
}
|
||||
await vfs.mkdir(paths.dir, { recursive: true })
|
||||
const emptyHist =
|
||||
typeof ctx.b4a !== 'undefined' && ctx.b4a && typeof ctx.b4a.from === 'function'
|
||||
? ctx.b4a.from('[]\n')
|
||||
: new TextEncoder().encode('[]\n')
|
||||
await vfs.writeFile(paths.history, emptyHist)
|
||||
const stamp = new Date().toISOString() + ' chat session reset\n'
|
||||
const progBody =
|
||||
typeof ctx.b4a !== 'undefined' && ctx.b4a && typeof ctx.b4a.from === 'function'
|
||||
? ctx.b4a.from(stamp)
|
||||
: new TextEncoder().encode(stamp)
|
||||
await vfs.writeFile(paths.progress, progBody)
|
||||
try {
|
||||
const z =
|
||||
typeof ctx.b4a !== 'undefined' && ctx.b4a && typeof ctx.b4a.from === 'function'
|
||||
? ctx.b4a.from('')
|
||||
: new TextEncoder().encode('')
|
||||
await vfs.writeFile(paths.cmdOut, z)
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
try {
|
||||
ctx.console.log(
|
||||
argv0 + ': chat session cleared (' + paths.history + ', ' + paths.progress + ')'
|
||||
)
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
|
||||
/** SSE line split + data payload parse (shared by agent-openai + tests). */
|
||||
|
||||
/**
|
||||
@@ -1513,7 +1554,7 @@ function bareAgentToolDefinitions() {
|
||||
function: {
|
||||
name: 'run_js_script',
|
||||
description:
|
||||
'Save JS to ~/.agent/_tmp_agent_run.mjs and execute it via the shell like any drive script (absolute path; same Bare kernel runner as /bin — no separate node binary). Prefer define async function run(ctx, argv). stdout/stderr captured.',
|
||||
'REQUIRED to run agent-authored JavaScript: Node is not installed. Writes code to ~/.agent/_tmp_agent_run.mjs and runs it by absolute path (Bare kernel — same as /bin scripts). Do not use run_command with node/npm/npx. Prefer async function run(ctx, argv). stdout/stderr captured.',
|
||||
parameters: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
@@ -2100,15 +2141,46 @@ function bareAgentWriteOut(out, s) {
|
||||
|
||||
const BARE_AGENT_STATIC_SYSTEM = `You are the Bare OS autonomous agent inside a JavaScript POSIX-like environment on Hyperdrive + Hyperswarm (Pear/Bare runtime).
|
||||
|
||||
There is no host \`node\` binary. Userland \`.js\` / \`.mjs\` is run by the kernel (path on a drive, e.g. /home/.../x.mjs, or \`./x.mjs\` in the shell) like /bin scripts. run_js_script writes a file and runs it that way; for ad-hoc lines use run_command with real /bin tools or sh -c.
|
||||
JavaScript execution on this OS: **Node.js is not installed.** The \`node\`, \`npm\`, and \`npx\` commands **do not exist** and must never appear in plans or in run_command. To run JS as part of your agent work, **you must call the run_js_script tool** (writes under ~/.agent and executes via the Bare kernel). Optional: once a script exists on disk, run_command may invoke it by **absolute path** (e.g. \`/home/.../script.mjs\`)—same mechanism as \`/bin\` scripts—not via \`node\`.
|
||||
|
||||
Capabilities: use ctx.execLine for shell commands (same language as the interactive shell). Use ctx.vfs readFile/writeFile/mkdir/readdir/chmod where available. Paths under /home, /mnt, /tmp map to Hypercore-backed storage; system paths like /bin, /etc are on the system drive.
|
||||
Capabilities: ctx.execLine for shell lines; ctx.vfs readFile/writeFile/mkdir/readdir/chmod. Paths under /home (personal Hyperdrive), /mnt, /tmp are writable where policy allows; /bin, /etc are system drive.
|
||||
|
||||
Safety: never exfiltrate ~/.agent/config.json or API keys in chat. Prefer least-privilege commands. Call task_complete(summary) only when fully done.
|
||||
Safety: never exfiltrate ~/.agent/config.json or API keys. Prefer least-privilege commands. Call task_complete(summary) when fully done.
|
||||
|
||||
Discovery: run man <topic> from the shell, or read /share/man/man.json. Tier-1 utilities live under /bin.
|
||||
Discovery: man <topic>, /share/man/man.json; Tier-1 utilities in /bin.
|
||||
|
||||
Always prefer tools over guessing when facts about the filesystem or commands are needed.`
|
||||
Prefer tools over guessing for filesystem and shell facts.`
|
||||
|
||||
/**
|
||||
* Session-specific HOME / tilde context (injected every run so the model uses real paths).
|
||||
* @param {Record<string, unknown>} ctx
|
||||
* @param {string} home from bareAgentResolveHome
|
||||
* @param {{ dir: string, config: string }} paths
|
||||
*/
|
||||
function bareAgentSessionHomeBlock(ctx, home, paths) {
|
||||
const env =
|
||||
ctx.env && typeof ctx.env === 'object'
|
||||
? /** @type {Record<string, string>} */ (ctx.env)
|
||||
: {}
|
||||
const homeEnv = String(env.HOME || '').trim()
|
||||
return (
|
||||
'## This session: home directory and paths\n' +
|
||||
'- **Resolved user home (this session):** `' +
|
||||
home +
|
||||
'`\n' +
|
||||
'- **HOME in the environment:** `' +
|
||||
(homeEnv || home) +
|
||||
'`\n' +
|
||||
'- **Tilde \`~\`:** In shell and in user docs, \`~\` means this home directory. Examples: \`~/.agent\` == `' +
|
||||
paths.dir +
|
||||
'`, agent config `' +
|
||||
paths.config +
|
||||
'`. 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'
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {unknown} tc
|
||||
@@ -2298,6 +2370,8 @@ async function bareOsRunAgentSession(ctx, argv0, task, runOpts) {
|
||||
let systemContent =
|
||||
BARE_AGENT_STATIC_SYSTEM +
|
||||
'\n\n' +
|
||||
bareAgentSessionHomeBlock(ctx, home, paths) +
|
||||
'\n\n' +
|
||||
manDigest.slice(0, 12000)
|
||||
if (instructions)
|
||||
systemContent += '\n\n## Session notes\n' + instructions.slice(0, 8000)
|
||||
@@ -2575,14 +2649,21 @@ async function run(ctx, argv) {
|
||||
ctx.console.log(
|
||||
'usage: ' +
|
||||
argv0 +
|
||||
' [--setup] YOUR_REQUEST_HERE\n' +
|
||||
' [--setup | --reset] YOUR_REQUEST_HERE\n' +
|
||||
' ' +
|
||||
argv0 +
|
||||
' --setup\n' +
|
||||
' ' +
|
||||
argv0 +
|
||||
' --reset\n' +
|
||||
' ' +
|
||||
argv0 +
|
||||
' reset\n' +
|
||||
'\n' +
|
||||
'Runs an autonomous coding/OS agent against any OpenAI-compatible HTTPS API.\n' +
|
||||
'Configuration: ~/.agent/config.json on your personal drive (created on first run).\n' +
|
||||
'Use --setup to interactively set API URL, key, model, and provider label.\n' +
|
||||
'Use --reset or `reset` to clear ~/.agent/history.json and start a fresh chat session.\n' +
|
||||
'\n' +
|
||||
'Examples:\n' +
|
||||
' ' +
|
||||
@@ -2591,6 +2672,9 @@ async function run(ctx, argv) {
|
||||
' ' +
|
||||
argv0 +
|
||||
' --setup\n' +
|
||||
' ' +
|
||||
argv0 +
|
||||
' --reset\n' +
|
||||
'\n' +
|
||||
'See man agent.'
|
||||
)
|
||||
@@ -2599,14 +2683,33 @@ async function run(ctx, argv) {
|
||||
}
|
||||
|
||||
let setupFlag = false
|
||||
let resetFlag = false
|
||||
/** @type {string[]} */
|
||||
const rest = []
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const a = args[i]
|
||||
if (a === '--setup') setupFlag = true
|
||||
else if (a === '--reset') resetFlag = true
|
||||
else rest.push(a)
|
||||
}
|
||||
|
||||
const wantReset =
|
||||
resetFlag || (rest.length === 1 && rest[0] === 'reset')
|
||||
if (wantReset) {
|
||||
const home = bareAgentResolveHome(ctx)
|
||||
const paths = bareAgentPaths(home)
|
||||
try {
|
||||
await bareAgentResetChatSession(ctx, paths, argv0)
|
||||
ctx.exitCode = 0
|
||||
} catch (e) {
|
||||
const msg =
|
||||
e && typeof e === 'object' && 'message' in e ? String(e.message) : String(e)
|
||||
ctx.console.error(argv0 + ': ' + msg)
|
||||
ctx.exitCode = 1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
const task = rest.join(' ').trim()
|
||||
if (!task && !setupFlag) {
|
||||
ctx.console.error(argv0 + ': missing task (or use --setup)')
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"schema": 2,
|
||||
"profileId": "bare-os-posix-like",
|
||||
"generatedAt": "2026-04-22T02:08:07.698Z",
|
||||
"generatedAt": "2026-04-22T02:18:32.387Z",
|
||||
"note": "Sparse POSIX Issue 7 coverage hints for /bin utilities. Omitted command names are not yet profiled here.",
|
||||
"commandIndex": [
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"atMs": 1776823687697,
|
||||
"atMs": 1776824312386,
|
||||
"commands": [
|
||||
"agent",
|
||||
"arch",
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user