openvisio-agent 0.18.14 → 0.18.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/scripts/certify.mjs +1 -1
- package/src/watch.mjs +11 -5
package/package.json
CHANGED
package/scripts/certify.mjs
CHANGED
|
@@ -93,7 +93,7 @@ const assertions = [
|
|
|
93
93
|
['quick replies preserve distinct top-level conversations', quickReply.includes('m.parentId ?? m.messageId') && quickReply.includes('...(parentId ? { parentId } : {})')],
|
|
94
94
|
['completion has an evidence failure gate', watcher.includes('WORK_CYCLE_FAILED')],
|
|
95
95
|
['failed evidence revisions persist and suppress self-triggered retries', watcher.includes('failedTaskVersions: [...failedTaskVersions]') && watcher.includes("failedTaskVersions.set(key, 'pending')") && watcher.includes('failedTaskRevisionIsCurrent(failedRevision, ticket)') && watcher.includes('ticket paused until its revision changes')],
|
|
96
|
-
['assigned coding tickets prefer their prepared local worktree', watcher.includes('findTicketWorktree(workdir, ticketId)') && watcher.includes('A prepared local git worktree for this ticket exists') && watcher.includes('Do not call list_codebases, codebase_tree, or get_codebase')],
|
|
96
|
+
['assigned coding tickets prefer their prepared local worktree', watcher.includes('findTicketWorktree(workdir, ticketId)') && watcher.includes('A prepared local git worktree for this ticket exists') && watcher.includes('Do not call list_codebases, codebase_tree, or get_codebase') && watcher.includes('cwd: cycleCwd') && watcher.includes('workdir: ticketWorktree')],
|
|
97
97
|
['OpenCode emits structured events for runtime evidence', watcher.includes("'--format', 'json'") && watcher.includes('opencodeEventEvidence(event)')],
|
|
98
98
|
['OpenCode API-key MCP disables OAuth probing', opencodeConfig.includes("oauth: false") && opencodeConfig.includes('timeout: 15_000')],
|
|
99
99
|
['OpenCode identities use isolated configs outside the code workspace', watcher.includes('opencodeRuntimeLayout({ cfgKey, workdir })') && watcher.includes("'--dir', workspace") && watcher.includes('OPENCODE_CONFIG: opencodeConfigPath') && watcher.includes('OPENCODE_CONFIG_CONTENT: JSON.stringify(opencodeConfig)')],
|
package/src/watch.mjs
CHANGED
|
@@ -453,13 +453,14 @@ function createOpencodeRunner({ mcpUrl, mcpHeaders, cfgKey, workdir, canCode, ma
|
|
|
453
453
|
// approval/sandbox bypass flag.
|
|
454
454
|
function createCodexRunner({ mcpUrl, mcpHeaders, workdir, canCode, maxCycleMs, log, debug, model, onTool, systemPrompt }) {
|
|
455
455
|
const bin = onPath('codex') || 'codex'
|
|
456
|
-
const
|
|
456
|
+
const defaultCwd = workdir || OV_DIR
|
|
457
457
|
const proxyPath = fileURLToPath(new URL('./codex-mcp-proxy.mjs', import.meta.url))
|
|
458
458
|
let cancelActive = null
|
|
459
459
|
|
|
460
460
|
function runCycle(prompt, cycleModel, cycleOptions = {}) {
|
|
461
461
|
return new Promise((resolve) => {
|
|
462
462
|
const m = cycleModel || model
|
|
463
|
+
const cycleCwd = cycleOptions.workdir || defaultCwd
|
|
463
464
|
const full = systemPrompt ? systemPrompt + '\n\n' + prompt : prompt
|
|
464
465
|
const disabledMcpTools = Array.isArray(cycleOptions.disabledMcpTools) ? cycleOptions.disabledMcpTools.filter(Boolean) : []
|
|
465
466
|
const mcpOverride = buildCodexMcpOverride({ mcpUrl, proxyCommand: process.execPath, proxyPath, disabledMcpTools })
|
|
@@ -542,7 +543,7 @@ function createCodexRunner({ mcpUrl, mcpHeaders, workdir, canCode, maxCycleMs, l
|
|
|
542
543
|
// mistaken for completed work. Keep it out of normal logs unless debug.
|
|
543
544
|
child = spawn(bin, args, {
|
|
544
545
|
...modelProcessOptions,
|
|
545
|
-
cwd,
|
|
546
|
+
cwd: cycleCwd,
|
|
546
547
|
env: {
|
|
547
548
|
...process.env,
|
|
548
549
|
...(mcpUrl ? {
|
|
@@ -577,7 +578,7 @@ function createCodexRunner({ mcpUrl, mcpHeaders, workdir, canCode, maxCycleMs, l
|
|
|
577
578
|
}
|
|
578
579
|
|
|
579
580
|
if (!mcpUrl) log('WARNING: no --mcp-url — Codex has no openvisio-team tools to act with. Re-connect with --mcp-url.')
|
|
580
|
-
log('codex runner ready' + (model ? ' [model ' + model + ']' : '') + (canCode ? ' [CODE workspace ' +
|
|
581
|
+
log('codex runner ready' + (model ? ' [model ' + model + ']' : '') + (canCode ? ' [CODE workspace ' + defaultCwd + ']' : ' [CHAT-ONLY]'))
|
|
581
582
|
return { runCycle, canCode, cancelCurrent: () => cancelActive?.() }
|
|
582
583
|
}
|
|
583
584
|
|
|
@@ -1419,6 +1420,11 @@ function loopBackendWs({ backend, wsUrl, apiKey, identifier, slug, claude, agent
|
|
|
1419
1420
|
lane.activeDelivery = delivery
|
|
1420
1421
|
const ctx = context ? [context] : []
|
|
1421
1422
|
const activeTaskRef = taskRef
|
|
1423
|
+
const ticketWorktree = kind === 'full' && activeTaskRef ? findTicketWorktree(workdir, activeTaskRef.ticketId) : ''
|
|
1424
|
+
const runnerOptions = {
|
|
1425
|
+
...(delivery?.watcherOwned ? { disabledMcpTools: ['post_message'] } : {}),
|
|
1426
|
+
...(ticketWorktree ? { workdir: ticketWorktree } : {}),
|
|
1427
|
+
}
|
|
1422
1428
|
const targets = [...new Set(targetChannels.filter((id) => id != null && Number.isFinite(Number(id))).map(Number))]
|
|
1423
1429
|
laneStatusTargets[laneName] = new Set(targets)
|
|
1424
1430
|
// credNote + charter live in the cached system prompt now — the per-cycle
|
|
@@ -1455,7 +1461,7 @@ function loopBackendWs({ backend, wsUrl, apiKey, identifier, slug, claude, agent
|
|
|
1455
1461
|
}
|
|
1456
1462
|
}
|
|
1457
1463
|
if (lane.cancelled) return
|
|
1458
|
-
const result = await runners[laneName].runCycle(prompt, useModel,
|
|
1464
|
+
const result = await runners[laneName].runCycle(prompt, useModel, runnerOptions)
|
|
1459
1465
|
let completionResult = result
|
|
1460
1466
|
if (lane.cancelled || result?.subtype === 'canceled') {
|
|
1461
1467
|
log(laneName + ' cycle cancelled; no blocker or reply will be published')
|
|
@@ -1492,7 +1498,7 @@ function loopBackendWs({ backend, wsUrl, apiKey, identifier, slug, claude, agent
|
|
|
1492
1498
|
if (kind === 'full' && cycleSucceeded(result) && missing.length) {
|
|
1493
1499
|
log(agent + ' coding cycle incomplete; recovery requires: ' + missing.join(', '))
|
|
1494
1500
|
const recoveryPrompt = `CONTINUE THE SAME OPENVISIO REQUEST. Your earlier output did not complete it. Missing runtime evidence: ${missing.join('; ')}. An intent or progress message is not completion. Continue the actual work now, verify it, and then provide one distinct final result or real blocker using the original delivery rule; a final result after an earlier progress message is explicitly allowed and required. Do not repeat the progress message. ${codexPushGuide}\n\nORIGINAL REQUEST AND ROUTING CONTEXT:\n${prompt}`
|
|
1495
|
-
const recovery = await runners.work.runCycle(recoveryPrompt, codeModel,
|
|
1501
|
+
const recovery = await runners.work.runCycle(recoveryPrompt, codeModel, runnerOptions)
|
|
1496
1502
|
if (lane.cancelled || recovery?.subtype === 'canceled') return
|
|
1497
1503
|
const recoveredResult = combineRuntimeWorkEvidence(result, recovery)
|
|
1498
1504
|
const recoveryMissing = missingRuntimeWorkEvidence(recoveredResult, { ticketCycle, resultMessageRequired })
|