Orginize
This commit is contained in:
@@ -0,0 +1,234 @@
|
||||
/** Shared agent tool helpers (preamble for /bin/agent; schemas/dispatch are sibling files). */
|
||||
|
||||
/**
|
||||
* Host-checkout verification hints (keep loosely aligned with scripts/lib/agent-check-hints-data.mjs).
|
||||
* @param {string} combined paths + topic
|
||||
* @returns {string[]}
|
||||
*/
|
||||
function bareAgentVerificationHintsList(combined) {
|
||||
const c = String(combined || '').toLowerCase()
|
||||
/** @type {string[]} */
|
||||
const hints = []
|
||||
if (/(^|\/)kernel\/|kernel\\|\/boot\/init|lib\/init|lib\\init/.test(c)) {
|
||||
hints.push('npm run bundle:kernel', 'node scripts/verify-kernel-seeder-parity.mjs')
|
||||
}
|
||||
if (/bare-os-coreutils|kernel\/bin|kernel\\bin/.test(c)) {
|
||||
hints.push('npm run build -w bare-os-coreutils', 'node scripts/verify-man-coverage.mjs')
|
||||
}
|
||||
if (/bare-os-booter|bare-os-ctx-api/.test(c)) {
|
||||
hints.push(
|
||||
'npm run test -w bare-os-booter',
|
||||
'node scripts/verify-ctx-api-feature-bits.mjs'
|
||||
)
|
||||
}
|
||||
if (/bare-os-protocol|seed-rpc|channel\.js/.test(c)) {
|
||||
hints.push('npm run test -w bare-os-protocol')
|
||||
}
|
||||
if (/bare-os-seeder/.test(c)) {
|
||||
hints.push('node scripts/verify-kernel-seeder-parity.mjs')
|
||||
}
|
||||
if (/bare-os-bare-libs|kernel\/lib\/bare|kernel\\lib\\bare/.test(c)) {
|
||||
hints.push('npm run build -w bare-os-bare-libs', 'node scripts/verify-bundle-health.mjs')
|
||||
}
|
||||
if (/shell|sh\.js|test\.js/.test(c) && /booter/.test(c)) {
|
||||
hints.push('npm run test:shell-fast')
|
||||
}
|
||||
if (/docs\/|handbook\/|developer-guide\//.test(c)) {
|
||||
hints.push('npm run pretest', 'node scripts/verify-doc-links.mjs')
|
||||
}
|
||||
if (!hints.length) hints.push('npm run pretest', 'npm test')
|
||||
return [...new Set(hints)]
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} s
|
||||
*/
|
||||
function bareAgentShellQuote(s) {
|
||||
return "'" + String(s).replace(/'/g, "'\\''") + "'"
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {unknown} v
|
||||
* @returns {string}
|
||||
*/
|
||||
function bareAgentJsonResult(v) {
|
||||
try {
|
||||
return JSON.stringify(v)
|
||||
} catch {
|
||||
return '{"error":"json_stringify_failed"}'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {Record<string, unknown>} ctx
|
||||
* @param {string} absPath
|
||||
*/
|
||||
function bareAgentPathAllowed(absPath) {
|
||||
if (typeof bareAgentPathAllowedRead === 'function') {
|
||||
return bareAgentPathAllowedRead(absPath)
|
||||
}
|
||||
const p = String(absPath || '').replace(/\\/g, '/')
|
||||
return Boolean(p.startsWith('/') && !p.includes('..'))
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} command
|
||||
* @param {unknown} denyList
|
||||
*/
|
||||
function bareAgentCommandDeniedByList(command, denyList) {
|
||||
const cmd = String(command || '').toLowerCase()
|
||||
const list = Array.isArray(denyList) ? denyList : []
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
const needle = String(list[i] || '').trim().toLowerCase()
|
||||
if (needle && cmd.includes(needle)) return needle
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, unknown>} base
|
||||
* @param {Record<string, unknown>} patch
|
||||
*/
|
||||
function bareAgentMergeConfigPatch(base, patch) {
|
||||
const out = { ...base }
|
||||
const keys = [
|
||||
'backend',
|
||||
'rest_base_url',
|
||||
'rest_api_key',
|
||||
'model',
|
||||
'qvac_model',
|
||||
'qvac_profile',
|
||||
'qvac_ctx_size',
|
||||
'qvac_device',
|
||||
'qvac_main_gpu',
|
||||
'qvac_gpu_layers',
|
||||
'max_tokens',
|
||||
'temperature',
|
||||
'provider',
|
||||
'max_iterations',
|
||||
'stream',
|
||||
'tool_parallelism',
|
||||
'request_timeout_ms',
|
||||
'access_policy',
|
||||
'allow_delete',
|
||||
'require_confirm_token',
|
||||
'command_deny',
|
||||
'mutate_deny_prefixes',
|
||||
'owner_name',
|
||||
'agent_label',
|
||||
'show_reasoning',
|
||||
'reasoning_mode',
|
||||
'reasoning_max_chars',
|
||||
'reasoning_include_tools',
|
||||
'allow_bridge_mutations',
|
||||
'allow_host_notifications',
|
||||
'allow_host_actions',
|
||||
'emergency_stop_mutations',
|
||||
'autonomous_mode_enabled',
|
||||
'autonomous_max_runtime_ms',
|
||||
'autonomous_completion_required_checks',
|
||||
'autonomous_allow_paths',
|
||||
'autonomous_deny_ops',
|
||||
'autonomous_active',
|
||||
'autonomous_started_at_ms',
|
||||
'autonomous_stop_requested',
|
||||
'autonomous_goal',
|
||||
'autonomous_status',
|
||||
'autonomous_last_error',
|
||||
'context_compaction',
|
||||
'compaction_keep_recent',
|
||||
'compaction_tool_chars',
|
||||
'plan_mode_active',
|
||||
'todo_nudge_enabled'
|
||||
]
|
||||
const numKeys = new Set([
|
||||
'max_tokens',
|
||||
'temperature',
|
||||
'max_iterations',
|
||||
'tool_parallelism',
|
||||
'request_timeout_ms',
|
||||
'reasoning_max_chars',
|
||||
'compaction_keep_recent',
|
||||
'compaction_tool_chars',
|
||||
'qvac_ctx_size',
|
||||
'qvac_gpu_layers',
|
||||
'autonomous_max_runtime_ms',
|
||||
'autonomous_started_at_ms'
|
||||
])
|
||||
for (const k of keys) {
|
||||
if (Object.prototype.hasOwnProperty.call(patch, k)) {
|
||||
/** @type {unknown} */
|
||||
const v = patch[k]
|
||||
if (numKeys.has(k)) {
|
||||
const n = Number(v)
|
||||
if (Number.isFinite(n)) out[k] = n
|
||||
} else if (
|
||||
k === 'autonomous_completion_required_checks' ||
|
||||
k === 'autonomous_allow_paths' ||
|
||||
k === 'autonomous_deny_ops' ||
|
||||
k === 'command_deny' ||
|
||||
k === 'mutate_deny_prefixes'
|
||||
) {
|
||||
out[k] = Array.isArray(v) ? v.map((x) => String(x ?? '')).filter(Boolean) : out[k]
|
||||
} else if (
|
||||
k === 'stream' ||
|
||||
k === 'allow_delete' ||
|
||||
k === 'show_reasoning' ||
|
||||
k === 'reasoning_include_tools' ||
|
||||
k === 'allow_bridge_mutations' ||
|
||||
k === 'allow_host_notifications' ||
|
||||
k === 'allow_host_actions' ||
|
||||
k === 'emergency_stop_mutations' ||
|
||||
k === 'autonomous_mode_enabled' ||
|
||||
k === 'autonomous_active' ||
|
||||
k === 'autonomous_stop_requested' ||
|
||||
k === 'plan_mode_active' ||
|
||||
k === 'todo_nudge_enabled'
|
||||
) {
|
||||
out[k] = Boolean(v)
|
||||
} else if (k === 'reasoning_mode') {
|
||||
const mode = String(v ?? '').trim().toLowerCase()
|
||||
out[k] = mode === 'summary' || mode === 'trace' ? mode : 'off'
|
||||
} else if (k === 'context_compaction') {
|
||||
const mode = String(v ?? '').trim().toLowerCase()
|
||||
out[k] = mode === 'off' || mode === 'aggressive' ? mode : 'auto'
|
||||
} else if (k === 'require_confirm_token') {
|
||||
out[k] = String(v ?? '')
|
||||
} else if (k === 'access_policy') {
|
||||
const pol = String(v ?? '').trim().toLowerCase()
|
||||
out[k] = pol === 'restricted' ? 'restricted' : 'full'
|
||||
} else {
|
||||
out[k] = String(v ?? '')
|
||||
}
|
||||
}
|
||||
}
|
||||
if (
|
||||
patch.extra_headers &&
|
||||
typeof patch.extra_headers === 'object' &&
|
||||
!Array.isArray(patch.extra_headers)
|
||||
) {
|
||||
out.extra_headers = { .../** @type {Record<string, string>} */ (patch.extra_headers) }
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, unknown>} ctx
|
||||
* @param {{ config: string }} paths
|
||||
* @param {Record<string, unknown>} config
|
||||
*/
|
||||
async function bareAgentSaveConfigFromTools(ctx, paths, config) {
|
||||
if (typeof bareAgentSaveConfig === 'function') {
|
||||
await bareAgentSaveConfig(ctx, paths, config)
|
||||
return
|
||||
}
|
||||
const vfs = ctx.vfs
|
||||
if (!vfs?.writeFile) return
|
||||
const json = JSON.stringify(config, null, 2) + '\n'
|
||||
const body =
|
||||
typeof ctx.b4a !== 'undefined' && ctx.b4a && typeof ctx.b4a.from === 'function'
|
||||
? ctx.b4a.from(json)
|
||||
: new TextEncoder().encode(json)
|
||||
await vfs.writeFile(paths.config, body)
|
||||
}
|
||||
Reference in New Issue
Block a user