omnius 1.0.462 → 1.0.464
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/dist/index.js +592 -119
- package/npm-shrinkwrap.json +14 -14
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -567631,7 +567631,15 @@ function ago(ms) {
|
|
|
567631
567631
|
const h = Math.floor(m2 / 60);
|
|
567632
567632
|
return `${h}h ago`;
|
|
567633
567633
|
}
|
|
567634
|
-
function computeNextActionHint(reconciled) {
|
|
567634
|
+
function computeNextActionHint(reconciled, recentFailures, focusDirective) {
|
|
567635
|
+
if (focusDirective?.requiredNextAction) {
|
|
567636
|
+
const reason = focusDirective.reason ? ` Reason: ${focusDirective.reason.slice(0, 180)}.` : "";
|
|
567637
|
+
return `Active recovery directive requires ${focusDirective.requiredNextAction}.${reason} Follow that before completion or unrelated work.`;
|
|
567638
|
+
}
|
|
567639
|
+
if (recentFailures.length > 0) {
|
|
567640
|
+
const first2 = recentFailures[0];
|
|
567641
|
+
return `Resolve or explicitly account for unresolved failure "${first2.stem}" (${first2.attempts} attempt${first2.attempts === 1 ? "" : "s"}). Do not infer completion from plan state while failures remain.`;
|
|
567642
|
+
}
|
|
567635
567643
|
const inProgress = reconciled.find((t2) => t2.reconciled === "in_progress");
|
|
567636
567644
|
if (inProgress)
|
|
567637
567645
|
return `Continue your in-progress item: "${inProgress.content.slice(0, 100)}".`;
|
|
@@ -567661,7 +567669,10 @@ function computeNextActionHint(reconciled) {
|
|
|
567661
567669
|
const first2 = completedUnverified[0];
|
|
567662
567670
|
return `A completed todo has a verifyCommand that hasn't run during this snapshot: ${first2.rationale}`;
|
|
567663
567671
|
}
|
|
567664
|
-
|
|
567672
|
+
if (reconciled.length === 0) {
|
|
567673
|
+
return `No declared plan items are available. Continue from the active goal and evidence; report completion only with direct verification.`;
|
|
567674
|
+
}
|
|
567675
|
+
return `Declared plan items have no visible gaps. Continue from the active goal and evidence; report completion only with direct verification.`;
|
|
567665
567676
|
}
|
|
567666
567677
|
function regenerate(opts) {
|
|
567667
567678
|
const startMs = Date.now();
|
|
@@ -567756,7 +567767,18 @@ function regenerate(opts) {
|
|
|
567756
567767
|
}
|
|
567757
567768
|
}
|
|
567758
567769
|
lines.push(``);
|
|
567759
|
-
|
|
567770
|
+
if (opts.focusDirective?.requiredNextAction) {
|
|
567771
|
+
lines.push(`ACTIVE RECOVERY DIRECTIVE:`);
|
|
567772
|
+
lines.push(` required_next_action=${opts.focusDirective.requiredNextAction}`);
|
|
567773
|
+
if (opts.focusDirective.state) {
|
|
567774
|
+
lines.push(` state=${opts.focusDirective.state}`);
|
|
567775
|
+
}
|
|
567776
|
+
if (opts.focusDirective.reason) {
|
|
567777
|
+
lines.push(` reason=${opts.focusDirective.reason.slice(0, 240)}`);
|
|
567778
|
+
}
|
|
567779
|
+
lines.push(``);
|
|
567780
|
+
}
|
|
567781
|
+
const nextActionHint = computeNextActionHint(reconciled, opts.recentFailures, opts.focusDirective);
|
|
567760
567782
|
lines.push(`SUGGESTED NEXT STEP (derived from gap analysis, not authoritative):`);
|
|
567761
567783
|
lines.push(` ${nextActionHint}`);
|
|
567762
567784
|
lines.push(``);
|
|
@@ -575157,21 +575179,13 @@ function violatesDirective(directive, input) {
|
|
|
575157
575179
|
}
|
|
575158
575180
|
if (input.toolName === "ask_user")
|
|
575159
575181
|
return false;
|
|
575182
|
+
const family = actionFamily(input.toolName, input.args);
|
|
575183
|
+
if (directive.requiredNextAction !== "update_todos" && directiveExplicitlyForbidsCall(directive, input, family)) {
|
|
575184
|
+
return true;
|
|
575185
|
+
}
|
|
575160
575186
|
if (directive.requiredNextAction === "read_authoritative_target" && input.usesAuthoritativeTargetEvidence && isEditTool(input.toolName)) {
|
|
575161
575187
|
return false;
|
|
575162
575188
|
}
|
|
575163
|
-
const family = actionFamily(input.toolName, input.args);
|
|
575164
|
-
if (directive.requiredNextAction !== "update_todos") {
|
|
575165
|
-
if (directive.forbiddenActionFamilies.includes(family))
|
|
575166
|
-
return true;
|
|
575167
|
-
if (directive.forbiddenActionFamilies.includes(input.toolName)) {
|
|
575168
|
-
if (input.toolName === "shell" && input.isReadLike)
|
|
575169
|
-
return false;
|
|
575170
|
-
if (input.toolName === "shell" && input.shellLikelyMutatesFilesystem)
|
|
575171
|
-
return false;
|
|
575172
|
-
return true;
|
|
575173
|
-
}
|
|
575174
|
-
}
|
|
575175
575189
|
switch (directive.requiredNextAction) {
|
|
575176
575190
|
case "update_todos":
|
|
575177
575191
|
if (input.toolName === "shell")
|
|
@@ -575204,6 +575218,17 @@ function violatesDirective(directive, input) {
|
|
|
575204
575218
|
return false;
|
|
575205
575219
|
}
|
|
575206
575220
|
}
|
|
575221
|
+
function directiveExplicitlyForbidsCall(directive, input, family) {
|
|
575222
|
+
if (directive.forbiddenActionFamilies.includes(family))
|
|
575223
|
+
return true;
|
|
575224
|
+
if (!directive.forbiddenActionFamilies.includes(input.toolName))
|
|
575225
|
+
return false;
|
|
575226
|
+
if (input.toolName === "shell" && input.isReadLike)
|
|
575227
|
+
return false;
|
|
575228
|
+
if (input.toolName === "shell" && input.shellLikelyMutatesFilesystem)
|
|
575229
|
+
return false;
|
|
575230
|
+
return true;
|
|
575231
|
+
}
|
|
575207
575232
|
function forbiddenCachedEvidenceFamilies(input, family) {
|
|
575208
575233
|
return [family];
|
|
575209
575234
|
}
|
|
@@ -578503,7 +578528,7 @@ function classifyThinkOutcome(raw) {
|
|
|
578503
578528
|
}
|
|
578504
578529
|
return null;
|
|
578505
578530
|
}
|
|
578506
|
-
var TOOL_SUBSETS, TOOL_AUTO_DEMOTE_TURNS, TOOL_ACTION_REASON_KEYS, TOOL_ACTION_REASON_SCOPES, TOOL_ACTION_REASON_SCHEMA, SYSTEM_PROMPT, SYSTEM_PROMPT_MEDIUM, SYSTEM_PROMPT_SMALL, VISUAL_TOOLS, AUDIO_TOOLS, SOCIAL_TOOLS, SPATIAL_TOOLS, CODE_TOOLS, AgenticRunner, OllamaAgenticBackend;
|
|
578531
|
+
var TOOL_SUBSETS, TOOL_AUTO_DEMOTE_TURNS, TOOL_ACTION_REASON_KEYS, TOOL_ACTION_REASON_SCOPES, READ_ONLY_ACTION_REASON_OPTIONAL_TOOLS, TOOL_ACTION_REASON_SCHEMA, SYSTEM_PROMPT, SYSTEM_PROMPT_MEDIUM, SYSTEM_PROMPT_SMALL, VISUAL_TOOLS, AUDIO_TOOLS, SOCIAL_TOOLS, SPATIAL_TOOLS, CODE_TOOLS, AgenticRunner, OllamaAgenticBackend;
|
|
578507
578532
|
var init_agenticRunner = __esm({
|
|
578508
578533
|
"packages/orchestrator/dist/agenticRunner.js"() {
|
|
578509
578534
|
"use strict";
|
|
@@ -578608,6 +578633,25 @@ var init_agenticRunner = __esm({
|
|
|
578608
578633
|
"completion",
|
|
578609
578634
|
"other"
|
|
578610
578635
|
]);
|
|
578636
|
+
READ_ONLY_ACTION_REASON_OPTIONAL_TOOLS = /* @__PURE__ */ new Set([
|
|
578637
|
+
"file_read",
|
|
578638
|
+
"file_explore",
|
|
578639
|
+
"list_directory",
|
|
578640
|
+
"grep_search",
|
|
578641
|
+
"grep",
|
|
578642
|
+
"glob_find",
|
|
578643
|
+
"find_files",
|
|
578644
|
+
"todo_read",
|
|
578645
|
+
"memory_read",
|
|
578646
|
+
"memory_search",
|
|
578647
|
+
"semantic_map",
|
|
578648
|
+
"code_graph",
|
|
578649
|
+
"graph_query",
|
|
578650
|
+
"graph_traverse",
|
|
578651
|
+
"web_search",
|
|
578652
|
+
"web_fetch",
|
|
578653
|
+
"tool_search"
|
|
578654
|
+
]);
|
|
578611
578655
|
TOOL_ACTION_REASON_SCHEMA = {
|
|
578612
578656
|
type: "object",
|
|
578613
578657
|
description: "Compact public action contract for this exact tool call. Do not include hidden chain-of-thought; use concise task-state facts.",
|
|
@@ -579548,7 +579592,7 @@ ${parts.join("\n")}
|
|
|
579548
579592
|
if (ts.failedApproaches.length > 0) {
|
|
579549
579593
|
lines.push(`recent_failed_approaches=${ts.failedApproaches.slice(-3).join(" | ").replace(/\s+/g, " ").slice(0, 420)}`);
|
|
579550
579594
|
}
|
|
579551
|
-
lines.push("tool_call_contract=
|
|
579595
|
+
lines.push("tool_call_contract=Mutating/side-effectful tool calls require action_reason {task_anchor,intent,evidence,expected_result,scope}; read-only evidence tools may include it but must never be blocked only for missing metadata. Compact public facts only, no hidden chain-of-thought.");
|
|
579552
579596
|
lines.push(`scope_contract=${Array.from(TOOL_ACTION_REASON_SCOPES).join("|")}; use targeted_patch for constrained code edits and full_file_rewrite only for deliberate whole-file replacement.`);
|
|
579553
579597
|
const focus = this._focusSupervisor?.snapshot().directive ?? null;
|
|
579554
579598
|
if (focus) {
|
|
@@ -584760,7 +584804,7 @@ ${blob}
|
|
|
584760
584804
|
* size. The hash is computed over the full canonical value.
|
|
584761
584805
|
*/
|
|
584762
584806
|
_buildExactArgsKey(args) {
|
|
584763
|
-
return Object.entries(args ?? {}).sort(([a2], [b]) => a2.localeCompare(b)).map(([k, v]) => `${k}=${this._formatExactArgValue(v)}`).join(",");
|
|
584807
|
+
return Object.entries(args ?? {}).filter(([key]) => !TOOL_ACTION_REASON_KEYS.has(key)).sort(([a2], [b]) => a2.localeCompare(b)).map(([k, v]) => `${k}=${this._formatExactArgValue(v)}`).join(",");
|
|
584764
584808
|
}
|
|
584765
584809
|
_buildToolFingerprint(name10, args) {
|
|
584766
584810
|
const canonical = this.lookupRegisteredTool(name10)?.name ?? name10;
|
|
@@ -585235,7 +585279,8 @@ Rewrite it now for ${ctx3.model}.`;
|
|
|
585235
585279
|
const unknownKeys = providedKeys.filter((key) => !props.has(key));
|
|
585236
585280
|
const aliases = this.suggestArgumentAliases(missingRequired, providedKeys, args, props);
|
|
585237
585281
|
const corrected = this.buildCorrectedArgsPreview(args, props, aliases);
|
|
585238
|
-
const
|
|
585282
|
+
const actionReasonOnlyFailure = validationError.includes("[TOOL ACTION REASON CONTRACT]");
|
|
585283
|
+
const siblingMatches = actionReasonOnlyFailure ? [] : this.findSiblingToolSchemaMatches(toolName, providedKeys);
|
|
585239
585284
|
const lines = [
|
|
585240
585285
|
`[RUNTIME TOOL ARGUMENT REPAIR]`,
|
|
585241
585286
|
`Tool call failed before execution: ${toolName}`,
|
|
@@ -585300,7 +585345,10 @@ Rewrite it now for ${ctx3.model}.`;
|
|
|
585300
585345
|
path: ["file", "image", "media", "filepath", "file_path", "filename"],
|
|
585301
585346
|
image: ["path", "file", "media", "filepath", "file_path", "filename"],
|
|
585302
585347
|
command: ["cmd", "shell_command"],
|
|
585303
|
-
query: ["prompt", "task", "message", "input", "text"]
|
|
585348
|
+
query: ["prompt", "task", "message", "input", "text"],
|
|
585349
|
+
start_line: ["line", "lineNumber", "line_number", "startLine"],
|
|
585350
|
+
end_line: ["endLine", "end_line", "lineEnd", "line_end", "end"],
|
|
585351
|
+
new_content: ["content", "newContent", "new_content"]
|
|
585304
585352
|
};
|
|
585305
585353
|
for (const required of missingRequired) {
|
|
585306
585354
|
for (const alias of aliasMap[required] ?? []) {
|
|
@@ -586794,6 +586842,7 @@ TASK: ${scrubbedTask}` : scrubbedTask;
|
|
|
586794
586842
|
preview: (entry.wentWrong || "").slice(0, 200),
|
|
586795
586843
|
distinctErrors: entry.errorSignatures?.size
|
|
586796
586844
|
})).sort((a2, b) => b.attempts - a2.attempts).slice(0, 5);
|
|
586845
|
+
const _wsFocusDirective = this._focusSupervisor?.snapshot().directive ?? null;
|
|
586797
586846
|
const _ws = regenerate({
|
|
586798
586847
|
workingDir: _wsWorkingDir,
|
|
586799
586848
|
goal: this._taskState.originalGoal || this._taskState.goal || "",
|
|
@@ -586801,6 +586850,11 @@ TASK: ${scrubbedTask}` : scrubbedTask;
|
|
|
586801
586850
|
triggerReason: _wsTrigger,
|
|
586802
586851
|
todos: _wsTodos,
|
|
586803
586852
|
recentFailures: _wsFailures,
|
|
586853
|
+
focusDirective: _wsFocusDirective ? {
|
|
586854
|
+
requiredNextAction: _wsFocusDirective.requiredNextAction,
|
|
586855
|
+
reason: _wsFocusDirective.reason,
|
|
586856
|
+
state: _wsFocusDirective.state
|
|
586857
|
+
} : null,
|
|
586804
586858
|
maxFiles: WORLD_STATE_MAX_FILES,
|
|
586805
586859
|
lastBuildSuccess: this._lastBuildSuccessTurn >= 0 ? {
|
|
586806
586860
|
command: this._lastBuildSuccessCommand,
|
|
@@ -587181,6 +587235,25 @@ If this matches your current shape, try it before continuing.`
|
|
|
587181
587235
|
if (_m)
|
|
587182
587236
|
_staleSamples.push(` - ${c9.name}: ${_m[0]}`);
|
|
587183
587237
|
}
|
|
587238
|
+
const _reg44FocusDirective = this._focusDirectiveSuppressesEditPressure();
|
|
587239
|
+
const _reg44ChoiceLines = _reg44FocusDirective ? [
|
|
587240
|
+
`A focus recovery directive is active and overrides the generic stuck escape options.`,
|
|
587241
|
+
`Required next action: ${_reg44FocusDirective.requiredNextAction}.`,
|
|
587242
|
+
`Reason: ${_reg44FocusDirective.reason}.`,
|
|
587243
|
+
`Do not choose a generic produce/complete/debate escape until this recovery directive is satisfied or reported impossible with evidence.`
|
|
587244
|
+
] : [
|
|
587245
|
+
`Pick ONE of these for your next response:`,
|
|
587246
|
+
``,
|
|
587247
|
+
` (a) PRODUCE: emit a file_write / file_edit / file_patch that creates or changes project content. Even a partial draft of the next planned file is progress. Use shell only for commands/tests/system operations, not as a workaround for failed edit-tool encoding.`,
|
|
587248
|
+
``,
|
|
587249
|
+
` (b) ERROR-INFORMED LOCAL TRIAGE: anchor on the freshest local failure, identify the implicated file/path/symbol/command, then make one targeted local move instead of broad exploration.`,
|
|
587250
|
+
``,
|
|
587251
|
+
this._renderLocalFailureNudge(turn),
|
|
587252
|
+
``,
|
|
587253
|
+
` (c) DEBATE: if you've tried 3+ approaches and they all hit the same wall, invoke \`debate\` with the failed task as the prompt — get a second opinion.`,
|
|
587254
|
+
``,
|
|
587255
|
+
` (d) DECLARE BLOCKED: if you genuinely cannot make progress (missing dependency, ambiguous spec, external service down), call \`task_complete\` with a summary that NAMES THE BLOCKER explicitly. Don't keep looping.`
|
|
587256
|
+
];
|
|
587184
587257
|
messages2.push({
|
|
587185
587258
|
role: "system",
|
|
587186
587259
|
content: [
|
|
@@ -587194,17 +587267,7 @@ If this matches your current shape, try it before continuing.`
|
|
|
587194
587267
|
``,
|
|
587195
587268
|
`You are consuming turns without producing new state. Every shape of "agent stuck" — read-heavy without writes, repeated cache hits, blocked-shell loops, no-op todo updates — looks like this signal. The exact tool names don't matter; the ratio does.`,
|
|
587196
587269
|
``,
|
|
587197
|
-
|
|
587198
|
-
``,
|
|
587199
|
-
` (a) PRODUCE: emit a file_write / file_edit / file_patch that creates or changes project content. Even a partial draft of the next planned file is progress. Use shell only for commands/tests/system operations, not as a workaround for failed edit-tool encoding.`,
|
|
587200
|
-
``,
|
|
587201
|
-
` (b) ERROR-INFORMED LOCAL TRIAGE: anchor on the freshest local failure, identify the implicated file/path/symbol/command, then make one targeted local move instead of broad exploration.`,
|
|
587202
|
-
``,
|
|
587203
|
-
this._renderLocalFailureNudge(turn),
|
|
587204
|
-
``,
|
|
587205
|
-
` (c) DEBATE: if you've tried 3+ approaches and they all hit the same wall, invoke \`debate\` with the failed task as the prompt — get a second opinion.`,
|
|
587206
|
-
``,
|
|
587207
|
-
` (d) DECLARE BLOCKED: if you genuinely cannot make progress (missing dependency, ambiguous spec, external service down), call \`task_complete\` with a summary that NAMES THE BLOCKER explicitly. Don't keep looping.`,
|
|
587270
|
+
..._reg44ChoiceLines,
|
|
587208
587271
|
``,
|
|
587209
587272
|
`Recent failures (real or synthetic):`,
|
|
587210
587273
|
_failureBlocks,
|
|
@@ -587359,6 +587422,27 @@ ${_staleSamples.join("\n")}` : ``,
|
|
|
587359
587422
|
});
|
|
587360
587423
|
if (_wtWorstCount >= _wtThreshold && !_wtHadSuccessfulVerify) {
|
|
587361
587424
|
this._writeThrashCooldownUntilTurn = turn + 8;
|
|
587425
|
+
const _reg50FocusDirective = this._focusDirectiveSuppressesEditPressure();
|
|
587426
|
+
const _reg50ChoiceLines = _reg50FocusDirective ? [
|
|
587427
|
+
`A focus recovery directive is active and overrides the generic write-thrash choices.`,
|
|
587428
|
+
`Required next action: ${_reg50FocusDirective.requiredNextAction}.`,
|
|
587429
|
+
`Reason: ${_reg50FocusDirective.reason}.`,
|
|
587430
|
+
`Do not write ${_wtWorstPath} again until the focus directive is satisfied or reported impossible with evidence.`
|
|
587431
|
+
] : [
|
|
587432
|
+
`Pick ONE of these for your next response:`,
|
|
587433
|
+
``,
|
|
587434
|
+
` (a) RUN-AND-READ: Run the EXACT command that fails (test/typecheck/build) and READ THE FULL ERROR MESSAGE LITERALLY. Do not summarize it from memory; paste it back into context. The current write hasn't been validated against any error.`,
|
|
587435
|
+
``,
|
|
587436
|
+
` (b) DELETE-AND-RESTART: If the file has been rewritten ${_wtWorstCount} times, the current approach is wrong. Either delete the file and try a fundamentally different design, OR revert to a known-good earlier version (use git, working_notes, or memory_search to find one).`,
|
|
587437
|
+
``,
|
|
587438
|
+
` (c) ERROR-INFORMED LOCAL TRIAGE: use the exact failing local command and error line to identify one implicated path/symbol/config key, then inspect or change only that target. Do not search online for a codebase-local failure.`,
|
|
587439
|
+
``,
|
|
587440
|
+
this._renderLocalFailureNudge(turn),
|
|
587441
|
+
``,
|
|
587442
|
+
` (d) DECLARE BLOCKED: If the file's correct shape genuinely isn't knowable from the spec + this codebase, call task_complete with a summary that names this specific file as the blocker. Don't burn more turns on it.`,
|
|
587443
|
+
``,
|
|
587444
|
+
`Do NOT in your next response: write to ${_wtWorstPath} again without first running and reading the failing command's output.`
|
|
587445
|
+
];
|
|
587362
587446
|
messages2.push({
|
|
587363
587447
|
role: "system",
|
|
587364
587448
|
content: [
|
|
@@ -587369,19 +587453,7 @@ ${_staleSamples.join("\n")}` : ``,
|
|
|
587369
587453
|
``,
|
|
587370
587454
|
`No successful test/build/typecheck command ran between writes — you are iterating the file blind, hoping the next variation works. This is a write-thrash anti-pattern. Repeated edits without verification confirm nothing.`,
|
|
587371
587455
|
``,
|
|
587372
|
-
|
|
587373
|
-
``,
|
|
587374
|
-
` (a) RUN-AND-READ: Run the EXACT command that fails (test/typecheck/build) and READ THE FULL ERROR MESSAGE LITERALLY. Do not summarize it from memory; paste it back into context. The current write hasn't been validated against any error.`,
|
|
587375
|
-
``,
|
|
587376
|
-
` (b) DELETE-AND-RESTART: If the file has been rewritten ${_wtWorstCount} times, the current approach is wrong. Either delete the file and try a fundamentally different design, OR revert to a known-good earlier version (use git, working_notes, or memory_search to find one).`,
|
|
587377
|
-
``,
|
|
587378
|
-
` (c) ERROR-INFORMED LOCAL TRIAGE: use the exact failing local command and error line to identify one implicated path/symbol/config key, then inspect or change only that target. Do not search online for a codebase-local failure.`,
|
|
587379
|
-
``,
|
|
587380
|
-
this._renderLocalFailureNudge(turn),
|
|
587381
|
-
``,
|
|
587382
|
-
` (d) DECLARE BLOCKED: If the file's correct shape genuinely isn't knowable from the spec + this codebase, call task_complete with a summary that names this specific file as the blocker. Don't burn more turns on it.`,
|
|
587383
|
-
``,
|
|
587384
|
-
`Do NOT in your next response: write to ${_wtWorstPath} again without first running and reading the failing command's output.`
|
|
587456
|
+
..._reg50ChoiceLines
|
|
587385
587457
|
].join("\n")
|
|
587386
587458
|
});
|
|
587387
587459
|
this.emit({
|
|
@@ -587497,6 +587569,25 @@ ${_staleSamples.join("\n")}` : ``,
|
|
|
587497
587569
|
}
|
|
587498
587570
|
if (_efWorstCount >= _efThreshold) {
|
|
587499
587571
|
this._editFailThrashCooldownUntilTurn = turn + 8;
|
|
587572
|
+
const _reg53FocusDirective = this._focusDirectiveSuppressesEditPressure();
|
|
587573
|
+
const _reg53ChoiceLines = _reg53FocusDirective ? [
|
|
587574
|
+
`A focus recovery directive is active and overrides generic stale-edit recovery choices.`,
|
|
587575
|
+
`Required next action: ${_reg53FocusDirective.requiredNextAction}.`,
|
|
587576
|
+
`Reason: ${_reg53FocusDirective.reason}.`,
|
|
587577
|
+
`Do not call file_edit or batch_edit on ${_efWorstPath} again until that directive is satisfied or reported impossible with evidence.`
|
|
587578
|
+
] : [
|
|
587579
|
+
`STOP guessing variants of old_string. Pick ONE of these for your next response:`,
|
|
587580
|
+
``,
|
|
587581
|
+
` (a) FILE_READ + COPY-EXACT: Call file_read on ${_efWorstPath}, then copy the EXACT bytes (whitespace, indentation, punctuation) for old_string from that read. Do not paraphrase or reformat.`,
|
|
587582
|
+
``,
|
|
587583
|
+
` (b) USE THE INLINE SNIPPET: Recent edit failures already include a "closest match" snippet showing the actual current content near where you tried to edit. Read that snippet in your last error message and use its content verbatim as old_string.`,
|
|
587584
|
+
``,
|
|
587585
|
+
` (c) REPLACE_ALL: If you want a global rename, set replace_all=true and the uniqueness check is bypassed.`,
|
|
587586
|
+
``,
|
|
587587
|
+
` (d) CONSTRAINED PATCH: If the exact replacement is too brittle, use file_patch with expected_old_content or batch_edit/file_edit against fresh current text. Use file_write only for new files, dry-run proposals, or deliberate hash-guarded full_file_rewrite actions.`,
|
|
587588
|
+
``,
|
|
587589
|
+
`Do NOT in your next response: call file_edit or batch_edit on ${_efWorstPath} again with another guess at old_string.`
|
|
587590
|
+
];
|
|
587500
587591
|
messages2.push({
|
|
587501
587592
|
role: "system",
|
|
587502
587593
|
content: [
|
|
@@ -587507,17 +587598,7 @@ ${_staleSamples.join("\n")}` : ``,
|
|
|
587507
587598
|
``,
|
|
587508
587599
|
`Each failure means your old_string did not match the file content. Your remembered version of this file has diverged from what's on disk — likely because an earlier edit succeeded and shifted things, or because you guessed at the file's content.`,
|
|
587509
587600
|
``,
|
|
587510
|
-
|
|
587511
|
-
``,
|
|
587512
|
-
` (a) FILE_READ + COPY-EXACT: Call file_read on ${_efWorstPath}, then copy the EXACT bytes (whitespace, indentation, punctuation) for old_string from that read. Do not paraphrase or reformat.`,
|
|
587513
|
-
``,
|
|
587514
|
-
` (b) USE THE INLINE SNIPPET: Recent edit failures already include a "closest match" snippet showing the actual current content near where you tried to edit. Read that snippet in your last error message and use its content verbatim as old_string.`,
|
|
587515
|
-
``,
|
|
587516
|
-
` (c) REPLACE_ALL: If you want a global rename, set replace_all=true and the uniqueness check is bypassed.`,
|
|
587517
|
-
``,
|
|
587518
|
-
` (d) CONSTRAINED PATCH: If the exact replacement is too brittle, use file_patch with expected_old_content or batch_edit/file_edit against fresh current text. Use file_write only for new files, dry-run proposals, or deliberate hash-guarded full_file_rewrite actions.`,
|
|
587519
|
-
``,
|
|
587520
|
-
`Do NOT in your next response: call file_edit or batch_edit on ${_efWorstPath} again with another guess at old_string.`
|
|
587601
|
+
..._reg53ChoiceLines
|
|
587521
587602
|
].join("\n")
|
|
587522
587603
|
});
|
|
587523
587604
|
this.emit({
|
|
@@ -588619,7 +588700,7 @@ ${memoryLines.join("\n")}`
|
|
|
588619
588700
|
const executeSingle = async (tc) => {
|
|
588620
588701
|
if (this.aborted)
|
|
588621
588702
|
return null;
|
|
588622
|
-
const actionReasonForAdvisory = this.
|
|
588703
|
+
const actionReasonForAdvisory = this._toolActionReasonForCall(tc.name, tc.arguments ?? {});
|
|
588623
588704
|
const cohortKey = this.buildArgCohortKey(tc.name, tc.arguments);
|
|
588624
588705
|
const cohort = this._argCohorts.get(cohortKey);
|
|
588625
588706
|
if (cohort && cohort.failure >= 3 && cohort.success === 0) {
|
|
@@ -589483,6 +589564,7 @@ ${cachedResult}`,
|
|
|
589483
589564
|
let validationError = this._validateToolActionReason(resolvedTool?.name ?? tc.name, tc.arguments ?? {});
|
|
589484
589565
|
if (!validationError) {
|
|
589485
589566
|
tc.arguments = this._stripToolActionReasonArgs(tc.arguments ?? {});
|
|
589567
|
+
tc.arguments = this._normalizeToolArgsForExecution(resolvedTool?.name ?? tc.name, tc.arguments ?? {});
|
|
589486
589568
|
validationError = this._validateFileWriteOverwriteContract(resolvedTool?.name ?? tc.name, tc.arguments ?? {}, toolActionReason);
|
|
589487
589569
|
}
|
|
589488
589570
|
if (!validationError) {
|
|
@@ -593769,21 +593851,40 @@ ${marker}` : marker);
|
|
|
593769
593851
|
}
|
|
593770
593852
|
return matchesFresh(args);
|
|
593771
593853
|
}
|
|
593772
|
-
|
|
593854
|
+
_toolActionReasonPolicy(toolName, args) {
|
|
593773
593855
|
if (process.env["OMNIUS_DISABLE_TOOL_ACTION_REASON"] === "1") {
|
|
593774
|
-
return
|
|
593856
|
+
return "disabled";
|
|
593775
593857
|
}
|
|
593776
593858
|
if ((process.env["VITEST"] || process.env["NODE_ENV"] === "test") && process.env["OMNIUS_REQUIRE_TOOL_ACTION_REASON"] !== "1") {
|
|
593777
|
-
return
|
|
593859
|
+
return "disabled";
|
|
593778
593860
|
}
|
|
593779
593861
|
if (this.options.artifactMode === "internal")
|
|
593780
|
-
return
|
|
593862
|
+
return "disabled";
|
|
593781
593863
|
if (toolName.startsWith("__"))
|
|
593782
|
-
return
|
|
593783
|
-
return
|
|
593864
|
+
return "disabled";
|
|
593865
|
+
return this._toolActionReasonIsOptional(toolName, args) ? "optional" : "required";
|
|
593866
|
+
}
|
|
593867
|
+
_requiresToolActionReason(toolName, args) {
|
|
593868
|
+
return this._toolActionReasonPolicy(toolName, args) === "required";
|
|
593869
|
+
}
|
|
593870
|
+
_toolActionReasonIsOptional(toolName, args) {
|
|
593871
|
+
const resolved = this.lookupRegisteredTool(toolName);
|
|
593872
|
+
const canonical = resolved?.name ?? toolName;
|
|
593873
|
+
if (READ_ONLY_ACTION_REASON_OPTIONAL_TOOLS.has(canonical))
|
|
593874
|
+
return true;
|
|
593875
|
+
const tool = resolved?.tool;
|
|
593876
|
+
if (typeof tool?.isReadOnly === "function") {
|
|
593877
|
+
try {
|
|
593878
|
+
if (tool.isReadOnly(args ?? {}))
|
|
593879
|
+
return true;
|
|
593880
|
+
} catch {
|
|
593881
|
+
}
|
|
593882
|
+
}
|
|
593883
|
+
return false;
|
|
593784
593884
|
}
|
|
593785
593885
|
_withToolActionReasonSchema(toolName, parameters) {
|
|
593786
|
-
|
|
593886
|
+
const policy = this._toolActionReasonPolicy(toolName);
|
|
593887
|
+
if (policy === "disabled") {
|
|
593787
593888
|
return parameters ?? { type: "object", properties: {} };
|
|
593788
593889
|
}
|
|
593789
593890
|
const base3 = parameters && typeof parameters === "object" && !Array.isArray(parameters) ? { ...parameters } : { type: "object" };
|
|
@@ -593794,11 +593895,21 @@ ${marker}` : marker);
|
|
|
593794
593895
|
...base3,
|
|
593795
593896
|
type: "object",
|
|
593796
593897
|
properties,
|
|
593797
|
-
required: [.../* @__PURE__ */ new Set([...required, "action_reason"])]
|
|
593898
|
+
required: policy === "required" ? [.../* @__PURE__ */ new Set([...required, "action_reason"])] : required
|
|
593798
593899
|
};
|
|
593799
593900
|
}
|
|
593800
593901
|
_extractToolActionReason(args) {
|
|
593801
|
-
|
|
593902
|
+
let raw = args["action_reason"] ?? args["actionReason"] ?? args["justification"];
|
|
593903
|
+
if (typeof raw === "string") {
|
|
593904
|
+
const trimmed = raw.trim();
|
|
593905
|
+
if (!trimmed)
|
|
593906
|
+
return null;
|
|
593907
|
+
try {
|
|
593908
|
+
raw = JSON.parse(trimmed);
|
|
593909
|
+
} catch {
|
|
593910
|
+
return null;
|
|
593911
|
+
}
|
|
593912
|
+
}
|
|
593802
593913
|
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
593803
593914
|
return null;
|
|
593804
593915
|
const rec = raw;
|
|
@@ -593811,20 +593922,46 @@ ${marker}` : marker);
|
|
|
593811
593922
|
};
|
|
593812
593923
|
return reason;
|
|
593813
593924
|
}
|
|
593925
|
+
_toolActionReasonForCall(toolName, args) {
|
|
593926
|
+
const explicit = this._extractToolActionReason(args);
|
|
593927
|
+
if (explicit)
|
|
593928
|
+
return explicit;
|
|
593929
|
+
if (this._toolActionReasonPolicy(toolName, args) !== "optional")
|
|
593930
|
+
return null;
|
|
593931
|
+
return this._synthesizeReadOnlyToolActionReason(toolName, args);
|
|
593932
|
+
}
|
|
593933
|
+
_synthesizeReadOnlyToolActionReason(toolName, args) {
|
|
593934
|
+
const canonical = this.lookupRegisteredTool(toolName)?.name ?? toolName;
|
|
593935
|
+
const goal = this._taskState.currentStep || this._taskState.nextAction || this._taskState.goal || this._taskState.originalGoal || "current task";
|
|
593936
|
+
const targets = this._extractToolTargetPaths(canonical, args).slice(0, 3);
|
|
593937
|
+
const targetText = targets.length > 0 ? ` for ${targets.join(", ")}` : "";
|
|
593938
|
+
return {
|
|
593939
|
+
task_anchor: String(goal).replace(/\s+/g, " ").trim().slice(0, 160),
|
|
593940
|
+
intent: `Run read-only ${canonical}${targetText} to gather current evidence.`,
|
|
593941
|
+
evidence: "Read-only metadata fallback; no project mutation is authorized by this action.",
|
|
593942
|
+
expected_result: `Current ${canonical} evidence for the next decision.`,
|
|
593943
|
+
scope: "discovery"
|
|
593944
|
+
};
|
|
593945
|
+
}
|
|
593814
593946
|
_validateToolActionReason(toolName, args) {
|
|
593815
|
-
|
|
593947
|
+
const policy = this._toolActionReasonPolicy(toolName, args);
|
|
593948
|
+
if (policy === "disabled")
|
|
593816
593949
|
return null;
|
|
593817
593950
|
const raw = args["action_reason"] ?? args["actionReason"] ?? args["justification"];
|
|
593818
|
-
if (!raw || typeof raw
|
|
593951
|
+
if (!raw || typeof raw === "string" && !raw.trim()) {
|
|
593952
|
+
if (policy === "optional")
|
|
593953
|
+
return null;
|
|
593819
593954
|
return [
|
|
593820
593955
|
"[TOOL ACTION REASON CONTRACT]",
|
|
593821
|
-
`
|
|
593956
|
+
`This side-effectful tool call must include action_reason: { task_anchor, intent, evidence, expected_result, scope }.`,
|
|
593822
593957
|
`Use compact public facts only; do not include hidden chain-of-thought.`,
|
|
593823
593958
|
`scope must be one of: ${Array.from(TOOL_ACTION_REASON_SCOPES).join(", ")}.`
|
|
593824
593959
|
].join("\n");
|
|
593825
593960
|
}
|
|
593826
593961
|
const reason = this._extractToolActionReason(args);
|
|
593827
593962
|
if (!reason) {
|
|
593963
|
+
if (policy === "optional")
|
|
593964
|
+
return null;
|
|
593828
593965
|
return "[TOOL ACTION REASON CONTRACT] action_reason must be an object with compact public task-state fields.";
|
|
593829
593966
|
}
|
|
593830
593967
|
const missing = [
|
|
@@ -593835,9 +593972,13 @@ ${marker}` : marker);
|
|
|
593835
593972
|
"scope"
|
|
593836
593973
|
].filter((key) => reason[key].length < 3);
|
|
593837
593974
|
if (missing.length > 0) {
|
|
593975
|
+
if (policy === "optional")
|
|
593976
|
+
return null;
|
|
593838
593977
|
return `[TOOL ACTION REASON CONTRACT] action_reason missing non-empty field(s): ${missing.join(", ")}.`;
|
|
593839
593978
|
}
|
|
593840
593979
|
if (!TOOL_ACTION_REASON_SCOPES.has(reason.scope)) {
|
|
593980
|
+
if (policy === "optional")
|
|
593981
|
+
return null;
|
|
593841
593982
|
return `[TOOL ACTION REASON CONTRACT] action_reason.scope="${reason.scope}" is invalid. Use one of: ${Array.from(TOOL_ACTION_REASON_SCOPES).join(", ")}.`;
|
|
593842
593983
|
}
|
|
593843
593984
|
return null;
|
|
@@ -593854,6 +593995,39 @@ ${marker}` : marker);
|
|
|
593854
593995
|
}
|
|
593855
593996
|
return changed ? next : args;
|
|
593856
593997
|
}
|
|
593998
|
+
_normalizeToolArgsForExecution(toolName, args) {
|
|
593999
|
+
if (toolName !== "file_patch")
|
|
594000
|
+
return args;
|
|
594001
|
+
let next = args;
|
|
594002
|
+
const copy = () => {
|
|
594003
|
+
if (next === args)
|
|
594004
|
+
next = { ...args };
|
|
594005
|
+
return next;
|
|
594006
|
+
};
|
|
594007
|
+
const coerceLineNumber = (value2) => {
|
|
594008
|
+
if (typeof value2 === "number")
|
|
594009
|
+
return value2;
|
|
594010
|
+
if (typeof value2 === "string" && /^\d+$/.test(value2.trim())) {
|
|
594011
|
+
return Number(value2.trim());
|
|
594012
|
+
}
|
|
594013
|
+
return value2;
|
|
594014
|
+
};
|
|
594015
|
+
if (next["start_line"] === void 0 && args["line"] !== void 0) {
|
|
594016
|
+
copy()["start_line"] = coerceLineNumber(args["line"]);
|
|
594017
|
+
}
|
|
594018
|
+
if (next["end_line"] === void 0 && args["line_end"] !== void 0) {
|
|
594019
|
+
copy()["end_line"] = coerceLineNumber(args["line_end"]);
|
|
594020
|
+
}
|
|
594021
|
+
if (next["end_line"] === void 0 && args["endLine"] !== void 0) {
|
|
594022
|
+
copy()["end_line"] = coerceLineNumber(args["endLine"]);
|
|
594023
|
+
}
|
|
594024
|
+
for (const key of ["start_line", "end_line"]) {
|
|
594025
|
+
if (typeof next[key] === "string") {
|
|
594026
|
+
copy()[key] = coerceLineNumber(next[key]);
|
|
594027
|
+
}
|
|
594028
|
+
}
|
|
594029
|
+
return next;
|
|
594030
|
+
}
|
|
593857
594031
|
_validateFileWriteOverwriteContract(toolName, args, actionReason) {
|
|
593858
594032
|
if (toolName !== "file_write")
|
|
593859
594033
|
return null;
|
|
@@ -595862,7 +596036,7 @@ ${trimmedNew}`;
|
|
|
595862
596036
|
args = JSON.parse(tc.function.arguments);
|
|
595863
596037
|
} catch {
|
|
595864
596038
|
}
|
|
595865
|
-
const actionReason = this.
|
|
596039
|
+
const actionReason = this._toolActionReasonForCall(name10, args);
|
|
595866
596040
|
const argsKey = this._buildExactArgsKey(args);
|
|
595867
596041
|
const fingerprint = this._buildToolFingerprint(name10, args);
|
|
595868
596042
|
const prior = this._adversaryToolOutcomes.find((o2) => o2.succeeded && o2.tool === name10 && o2.fingerprint === fingerprint && o2.stateVersion === this._adversaryStateVersion && o2.turn < turn);
|
|
@@ -627821,6 +627995,7 @@ var omnius_directory_exports = {};
|
|
|
627821
627995
|
__export(omnius_directory_exports, {
|
|
627822
627996
|
OMNIUS_DIR: () => OMNIUS_DIR,
|
|
627823
627997
|
buildContextRestorePrompt: () => buildContextRestorePrompt,
|
|
627998
|
+
buildContextRestoreSnapshot: () => buildContextRestoreSnapshot,
|
|
627824
627999
|
buildHandoffPrompt: () => buildHandoffPrompt,
|
|
627825
628000
|
cleanPromptForDiary: () => cleanPromptForDiary,
|
|
627826
628001
|
clearTaskHandoff: () => clearTaskHandoff,
|
|
@@ -628764,9 +628939,7 @@ function selectActiveTaskAnchor(repoRoot) {
|
|
|
628764
628939
|
return null;
|
|
628765
628940
|
}
|
|
628766
628941
|
}
|
|
628767
|
-
function
|
|
628768
|
-
const selected = selectActiveTaskAnchor(repoRoot);
|
|
628769
|
-
if (!selected) return null;
|
|
628942
|
+
function formatActiveTaskAnchor(selected) {
|
|
628770
628943
|
const ledger = selected.ledger;
|
|
628771
628944
|
const evidence = ledger.evidence ?? [];
|
|
628772
628945
|
const selectedEvidence = [...evidence.slice(0, 2), ...evidence.slice(-4)];
|
|
@@ -628800,6 +628973,131 @@ ${boardCards.join("\n")}
|
|
|
628800
628973
|
` : "") + `Continuation rule: when the user asks to continue, resume this active task unless the new prompt names a different target.
|
|
628801
628974
|
</active-task-anchor>`;
|
|
628802
628975
|
}
|
|
628976
|
+
function uniqueSessionIds(ids) {
|
|
628977
|
+
const seen = /* @__PURE__ */ new Set();
|
|
628978
|
+
const out = [];
|
|
628979
|
+
for (const raw of ids) {
|
|
628980
|
+
const id2 = String(raw || "").trim();
|
|
628981
|
+
if (!id2 || seen.has(id2)) continue;
|
|
628982
|
+
seen.add(id2);
|
|
628983
|
+
out.push(id2);
|
|
628984
|
+
}
|
|
628985
|
+
return out;
|
|
628986
|
+
}
|
|
628987
|
+
function collectRestoreSessionIds(ctx3, activeTask, historySessionId) {
|
|
628988
|
+
const entries = ctx3?.entries ?? [];
|
|
628989
|
+
const usefulEntries = entries.filter((entry) => !isManualSessionEntry(entry));
|
|
628990
|
+
const chronological = usefulEntries.length > 0 ? usefulEntries : entries;
|
|
628991
|
+
return uniqueSessionIds([
|
|
628992
|
+
activeTask?.ledger.runId,
|
|
628993
|
+
...[...chronological].reverse().map((entry) => entry.sessionId),
|
|
628994
|
+
...[...entries].reverse().map((entry) => entry.sessionId),
|
|
628995
|
+
historySessionId
|
|
628996
|
+
]);
|
|
628997
|
+
}
|
|
628998
|
+
function childMapForTodos(todos) {
|
|
628999
|
+
const byId = new Set(todos.map((todo) => todo.id));
|
|
629000
|
+
const byParent = /* @__PURE__ */ new Map();
|
|
629001
|
+
for (const todo of todos) {
|
|
629002
|
+
if (!todo.parentId || !byId.has(todo.parentId)) continue;
|
|
629003
|
+
const bucket = byParent.get(todo.parentId) ?? [];
|
|
629004
|
+
bucket.push(todo);
|
|
629005
|
+
byParent.set(todo.parentId, bucket);
|
|
629006
|
+
}
|
|
629007
|
+
for (const bucket of byParent.values()) {
|
|
629008
|
+
bucket.sort((a2, b) => a2.createdAt - b.createdAt || a2.id.localeCompare(b.id));
|
|
629009
|
+
}
|
|
629010
|
+
return byParent;
|
|
629011
|
+
}
|
|
629012
|
+
function statusRank2(status) {
|
|
629013
|
+
switch (status) {
|
|
629014
|
+
case "in_progress":
|
|
629015
|
+
return 0;
|
|
629016
|
+
case "blocked":
|
|
629017
|
+
return 1;
|
|
629018
|
+
case "pending":
|
|
629019
|
+
return 2;
|
|
629020
|
+
case "completed":
|
|
629021
|
+
return 3;
|
|
629022
|
+
default:
|
|
629023
|
+
return 4;
|
|
629024
|
+
}
|
|
629025
|
+
}
|
|
629026
|
+
function orderedTodoTree(todos) {
|
|
629027
|
+
const byId = new Set(todos.map((todo) => todo.id));
|
|
629028
|
+
const byParent = childMapForTodos(todos);
|
|
629029
|
+
const roots = todos.filter((todo) => !todo.parentId || !byId.has(todo.parentId)).sort((a2, b) => statusRank2(a2.status) - statusRank2(b.status) || a2.createdAt - b.createdAt || a2.id.localeCompare(b.id));
|
|
629030
|
+
const out = [];
|
|
629031
|
+
const seen = /* @__PURE__ */ new Set();
|
|
629032
|
+
const visit = (todo, depth) => {
|
|
629033
|
+
if (seen.has(todo.id)) return;
|
|
629034
|
+
seen.add(todo.id);
|
|
629035
|
+
out.push({ todo, depth });
|
|
629036
|
+
for (const child of byParent.get(todo.id) ?? []) visit(child, depth + 1);
|
|
629037
|
+
};
|
|
629038
|
+
for (const root of roots) visit(root, 0);
|
|
629039
|
+
for (const todo of todos) visit(todo, 0);
|
|
629040
|
+
return out;
|
|
629041
|
+
}
|
|
629042
|
+
function formatTodoLine(todo, depth) {
|
|
629043
|
+
const indent2 = " ".repeat(Math.min(depth, 6));
|
|
629044
|
+
const blocker = todo.blocker ? ` blocker="${normalizeSessionText(todo.blocker, 120)}"` : "";
|
|
629045
|
+
const verify2 = todo.verifyCommand ? ` verify="${normalizeSessionText(todo.verifyCommand, 120)}"` : "";
|
|
629046
|
+
const artifacts = todo.declaredArtifacts && todo.declaredArtifacts.length > 0 ? ` artifacts=${todo.declaredArtifacts.slice(0, 4).map((item) => normalizeSessionText(item, 80)).join(",")}` : "";
|
|
629047
|
+
return `${indent2}- [${todo.status}] ${normalizeSessionText(todo.content, 180)} (id=${todo.id}${todo.parentId ? ` parent=${todo.parentId}` : ""}${blocker}${verify2}${artifacts})`;
|
|
629048
|
+
}
|
|
629049
|
+
function buildRestoredTodoBlock(sessionId, todos) {
|
|
629050
|
+
const byParent = childMapForTodos(todos);
|
|
629051
|
+
const leafTodos = todos.filter((todo) => (byParent.get(todo.id)?.length ?? 0) === 0);
|
|
629052
|
+
const completedLeaves = leafTodos.filter((todo) => todo.status === "completed").length;
|
|
629053
|
+
const activeTodos = todos.filter((todo) => todo.status === "in_progress" || todo.status === "blocked").sort((a2, b) => statusRank2(a2.status) - statusRank2(b.status) || b.updatedAt - a2.updatedAt).slice(0, 8);
|
|
629054
|
+
const ordered = orderedTodoTree(todos);
|
|
629055
|
+
const visible = ordered.slice(0, 48);
|
|
629056
|
+
const omitted = Math.max(0, ordered.length - visible.length);
|
|
629057
|
+
const activeLines = activeTodos.map((todo) => `- [${todo.status}] ${normalizeSessionText(todo.content, 180)} (id=${todo.id})`);
|
|
629058
|
+
const treeLines = visible.map(({ todo, depth }) => formatTodoLine(todo, depth));
|
|
629059
|
+
return `<restored-todo-state>
|
|
629060
|
+
todo_session_id=${sessionId}
|
|
629061
|
+
total=${todos.length}; leaf_progress=${completedLeaves}/${leafTodos.length || todos.length}
|
|
629062
|
+
` + (activeLines.length > 0 ? `Active/blocked items:
|
|
629063
|
+
${activeLines.join("\n")}
|
|
629064
|
+
` : "") + `Todo tree:
|
|
629065
|
+
${treeLines.join("\n")}${omitted > 0 ? `
|
|
629066
|
+
- ... ${omitted} more todo(s) in restored session` : ""}
|
|
629067
|
+
Continuation contract: this is the live checklist from the restored run. Continue it and update it with todo_write; do not recreate a parallel plan unless the new user request explicitly changes direction.
|
|
629068
|
+
</restored-todo-state>`;
|
|
629069
|
+
}
|
|
629070
|
+
function findRestoredTodoState(sessionIds) {
|
|
629071
|
+
for (const sessionId of sessionIds) {
|
|
629072
|
+
const todos = readTodos(sessionId).filter((todo) => todo && todo.id && todo.content);
|
|
629073
|
+
if (todos.length === 0) continue;
|
|
629074
|
+
return {
|
|
629075
|
+
sessionId,
|
|
629076
|
+
todos,
|
|
629077
|
+
block: buildRestoredTodoBlock(sessionId, todos)
|
|
629078
|
+
};
|
|
629079
|
+
}
|
|
629080
|
+
return null;
|
|
629081
|
+
}
|
|
629082
|
+
function buildRestoreHistoryAnchor(repoRoot) {
|
|
629083
|
+
const [latest] = listSessions(repoRoot);
|
|
629084
|
+
if (!latest?.id) return null;
|
|
629085
|
+
const lines = loadSessionHistory(repoRoot, latest.id) ?? [];
|
|
629086
|
+
const meaningfulTail = lines.map((line) => cleanSessionHistoryDisplayLine(line)).filter((line) => line && !isNoisySessionHistoryLine(line)).slice(-18).map((line) => `- ${normalizeSessionText(line, 220)}`);
|
|
629087
|
+
const path12 = join136(OMNIUS_DIR, SESSIONS_DIR, `${latest.id}.jsonl`);
|
|
629088
|
+
const block = `<restored-interface-history>
|
|
629089
|
+
latest_visual_session_id=${latest.id}
|
|
629090
|
+
full_transcript_path=${path12}
|
|
629091
|
+
recorded_lines=${lines.length}
|
|
629092
|
+
` + (meaningfulTail.length > 0 ? `Recent visible transcript tail:
|
|
629093
|
+
${meaningfulTail.join("\n")}
|
|
629094
|
+
` : "") + `Recall contract: the full transcript artifact above is restored into the TUI scrollback and is the authoritative previous interface state. Read it only when exact prior UI/tool output is needed; otherwise use this restored state to avoid rediscovery.
|
|
629095
|
+
</restored-interface-history>`;
|
|
629096
|
+
return { sessionId: latest.id, path: path12, lineCount: lines.length, block };
|
|
629097
|
+
}
|
|
629098
|
+
function appendRestoreBlocks(base3, blocks) {
|
|
629099
|
+
return [base3, ...blocks].filter((part) => part && part.trim()).join("\n\n");
|
|
629100
|
+
}
|
|
628803
629101
|
function formatSessionHistoryDisplay(ctx3) {
|
|
628804
629102
|
return buildSessionHistoryBoxLines(
|
|
628805
629103
|
sessionContextToHistoryBoxData(ctx3),
|
|
@@ -628825,10 +629123,15 @@ function sessionContextToHistoryBoxData(ctx3, title = "Session History") {
|
|
|
628825
629123
|
updatedAt: ctx3?.updatedAt ?? null
|
|
628826
629124
|
};
|
|
628827
629125
|
}
|
|
628828
|
-
function
|
|
629126
|
+
function buildContextRestoreSnapshot(repoRoot) {
|
|
628829
629127
|
const ctx3 = loadSessionContext(repoRoot);
|
|
628830
629128
|
const handoffPrompt = buildHandoffPrompt(repoRoot);
|
|
628831
|
-
const
|
|
629129
|
+
const activeTask = selectActiveTaskAnchor(repoRoot);
|
|
629130
|
+
const activeTaskAnchor = activeTask ? formatActiveTaskAnchor(activeTask) : null;
|
|
629131
|
+
const historyAnchor = buildRestoreHistoryAnchor(repoRoot);
|
|
629132
|
+
const restoreSessionIds = collectRestoreSessionIds(ctx3, activeTask, historyAnchor?.sessionId);
|
|
629133
|
+
const restoredTodos = findRestoredTodoState(restoreSessionIds);
|
|
629134
|
+
const sourceSessionId = restoredTodos?.sessionId ?? restoreSessionIds[0];
|
|
628832
629135
|
if (handoffPrompt) {
|
|
628833
629136
|
const usefulEntries2 = (ctx3?.entries ?? []).filter((entry) => !isManualSessionEntry(entry));
|
|
628834
629137
|
const baseCtx = ctx3 && ctx3.entries.length > 0 ? `
|
|
@@ -628838,13 +629141,37 @@ Recent tasks: ${(usefulEntries2.length > 0 ? usefulEntries2 : ctx3.entries).slic
|
|
|
628838
629141
|
(e2) => `[${e2.completed ? "done" : "partial"}] ${normalizeSessionText(e2.summary || e2.task, 80)}`
|
|
628839
629142
|
).join(", ")}
|
|
628840
629143
|
</session-recap>` : "";
|
|
628841
|
-
|
|
629144
|
+
const prompt2 = appendRestoreBlocks(
|
|
629145
|
+
handoffPrompt + (activeTaskAnchor ? `
|
|
628842
629146
|
|
|
628843
|
-
${activeTaskAnchor}` : "") + baseCtx
|
|
629147
|
+
${activeTaskAnchor}` : "") + baseCtx,
|
|
629148
|
+
[restoredTodos?.block, historyAnchor?.block]
|
|
629149
|
+
);
|
|
629150
|
+
return {
|
|
629151
|
+
prompt: prompt2,
|
|
629152
|
+
sourceSessionId,
|
|
629153
|
+
todoSessionId: restoredTodos?.sessionId,
|
|
629154
|
+
todoCount: restoredTodos?.todos.length ?? 0,
|
|
629155
|
+
historySessionId: historyAnchor?.sessionId,
|
|
629156
|
+
historyPath: historyAnchor?.path,
|
|
629157
|
+
historyLineCount: historyAnchor?.lineCount
|
|
629158
|
+
};
|
|
629159
|
+
}
|
|
629160
|
+
if (!ctx3 || ctx3.entries.length === 0) {
|
|
629161
|
+
const prompt2 = appendRestoreBlocks(activeTaskAnchor ?? "", [restoredTodos?.block, historyAnchor?.block]);
|
|
629162
|
+
if (!prompt2.trim()) return null;
|
|
629163
|
+
return {
|
|
629164
|
+
prompt: prompt2,
|
|
629165
|
+
sourceSessionId,
|
|
629166
|
+
todoSessionId: restoredTodos?.sessionId,
|
|
629167
|
+
todoCount: restoredTodos?.todos.length ?? 0,
|
|
629168
|
+
historySessionId: historyAnchor?.sessionId,
|
|
629169
|
+
historyPath: historyAnchor?.path,
|
|
629170
|
+
historyLineCount: historyAnchor?.lineCount
|
|
629171
|
+
};
|
|
628844
629172
|
}
|
|
628845
|
-
if (!ctx3 || ctx3.entries.length === 0) return activeTaskAnchor;
|
|
628846
629173
|
const usefulEntries = ctx3.entries.filter((entry) => !isManualSessionEntry(entry));
|
|
628847
|
-
const recent = (usefulEntries.length > 0 ? usefulEntries : ctx3.entries).slice(-
|
|
629174
|
+
const recent = (usefulEntries.length > 0 ? usefulEntries : ctx3.entries).slice(-20);
|
|
628848
629175
|
const chronology = recent.map((e2) => {
|
|
628849
629176
|
const status = e2.completed ? "done" : "partial";
|
|
628850
629177
|
const summary = normalizeSessionText(e2.assistantResponse || e2.summary || e2.task, 140);
|
|
@@ -628855,7 +629182,7 @@ ${activeTaskAnchor}` : "") + baseCtx;
|
|
|
628855
629182
|
const last2 = recent[recent.length - 1] ?? ctx3.entries[ctx3.entries.length - 1];
|
|
628856
629183
|
const lastCompleted = [...usefulEntries].reverse().find((entry) => entry.completed);
|
|
628857
629184
|
const latestCompleted = lastCompleted ? `Latest completed task: ${normalizeSessionText(lastCompleted.assistantResponse || lastCompleted.summary || lastCompleted.task, 180)}` : "";
|
|
628858
|
-
const recentDialogue = recent.slice(-
|
|
629185
|
+
const recentDialogue = recent.slice(-8).map((entry) => {
|
|
628859
629186
|
const assistant = normalizeSessionText(entry.assistantResponse || entry.summary, 320) || "(no assistant reply captured)";
|
|
628860
629187
|
const user = cleanPromptForDiary(entry.task).slice(0, 220);
|
|
628861
629188
|
return `User: ${user}
|
|
@@ -628865,10 +629192,12 @@ Assistant: ${assistant}`;
|
|
|
628865
629192
|
Provenance: ${last2.provenance} (file_read to expand)` : "";
|
|
628866
629193
|
const kg = `
|
|
628867
629194
|
KG summary: .omnius/context/kg-summary/latest.md (file_read to expand; legacy pointer: .omnius/context/kg-summary-latest.md)`;
|
|
628868
|
-
|
|
629195
|
+
const prompt = appendRestoreBlocks(
|
|
629196
|
+
`<session-recap>
|
|
628869
629197
|
` + (activeTaskAnchor ? `${activeTaskAnchor}
|
|
628870
629198
|
|
|
628871
629199
|
` : "") + `Project chronology (older to newer):
|
|
629200
|
+
Scope: full retained rolling window (${recent.length} entr${recent.length === 1 ? "y" : "ies"}).
|
|
628872
629201
|
${chronology.join("\n")}
|
|
628873
629202
|
` + (latestCompleted ? `
|
|
628874
629203
|
${latestCompleted}
|
|
@@ -628877,7 +629206,21 @@ Most recent exchanges (older to newer):
|
|
|
628877
629206
|
${recentDialogue}
|
|
628878
629207
|
` + (activeTaskAnchor ? `For continuation prompts, resume the active task anchor above; use chronology only to avoid repeating completed work.${prov}${kg}
|
|
628879
629208
|
` : `Continue from the latest exchange and do not repeat completed work.${prov}${kg}
|
|
628880
|
-
`) + `</session-recap
|
|
629209
|
+
`) + `</session-recap>`,
|
|
629210
|
+
[restoredTodos?.block, historyAnchor?.block]
|
|
629211
|
+
);
|
|
629212
|
+
return {
|
|
629213
|
+
prompt,
|
|
629214
|
+
sourceSessionId,
|
|
629215
|
+
todoSessionId: restoredTodos?.sessionId,
|
|
629216
|
+
todoCount: restoredTodos?.todos.length ?? 0,
|
|
629217
|
+
historySessionId: historyAnchor?.sessionId,
|
|
629218
|
+
historyPath: historyAnchor?.path,
|
|
629219
|
+
historyLineCount: historyAnchor?.lineCount
|
|
629220
|
+
};
|
|
629221
|
+
}
|
|
629222
|
+
function buildContextRestorePrompt(repoRoot) {
|
|
629223
|
+
return buildContextRestoreSnapshot(repoRoot)?.prompt ?? null;
|
|
628881
629224
|
}
|
|
628882
629225
|
function getLastTaskSummary(repoRoot) {
|
|
628883
629226
|
const ctx3 = loadSessionContext(repoRoot);
|
|
@@ -629204,6 +629547,7 @@ var OMNIUS_DIR, LEGACY_DIRS, SUBDIRS, gitignoreWatchers, gitignoreRetryTimers, C
|
|
|
629204
629547
|
var init_omnius_directory = __esm({
|
|
629205
629548
|
"packages/cli/src/tui/omnius-directory.ts"() {
|
|
629206
629549
|
"use strict";
|
|
629550
|
+
init_dist5();
|
|
629207
629551
|
init_task_complete_box();
|
|
629208
629552
|
OMNIUS_DIR = ".omnius";
|
|
629209
629553
|
LEGACY_DIRS = [".oa", ".open-agents"];
|
|
@@ -632134,6 +632478,12 @@ var init_status_bar = __esm({
|
|
|
632134
632478
|
}
|
|
632135
632479
|
return out;
|
|
632136
632480
|
}
|
|
632481
|
+
/** Capture the main session scrollback for persistence, independent of active tab. */
|
|
632482
|
+
capturePersistedSessionLines(width = 100) {
|
|
632483
|
+
const mainView = this._agentViews.get("main");
|
|
632484
|
+
const lines = mainView?.contentLines ?? this._contentLines;
|
|
632485
|
+
return this.expandDynamicBlockSentinels(lines, width);
|
|
632486
|
+
}
|
|
632137
632487
|
/**
|
|
632138
632488
|
* Append a previously-registered dynamic block's sentinel to scrollback
|
|
632139
632489
|
* and trigger a repaint. The block's renderer fires immediately at the
|
|
@@ -633500,6 +633850,40 @@ var init_status_bar = __esm({
|
|
|
633500
633850
|
this.fillContentArea();
|
|
633501
633851
|
this.renderFooterAndPositionInput();
|
|
633502
633852
|
}
|
|
633853
|
+
/**
|
|
633854
|
+
* Restore persisted scrollback into the main TUI view after process restart.
|
|
633855
|
+
*
|
|
633856
|
+
* Session transcripts are persisted with dynamic blocks already expanded, so
|
|
633857
|
+
* this intentionally restores plain rendered lines rather than stale sentinel
|
|
633858
|
+
* callbacks from a prior process.
|
|
633859
|
+
*/
|
|
633860
|
+
restoreMainContentLines(lines) {
|
|
633861
|
+
const mainView = this._agentViews.get("main");
|
|
633862
|
+
const restored = lines.filter((line) => typeof line === "string").slice(-this._contentMaxLines);
|
|
633863
|
+
if (mainView) {
|
|
633864
|
+
mainView.contentLines.splice(0, mainView.contentLines.length, ...restored);
|
|
633865
|
+
mainView.scrollOffset = 0;
|
|
633866
|
+
this._activeViewId = "main";
|
|
633867
|
+
this._contentLines = mainView.contentLines;
|
|
633868
|
+
} else {
|
|
633869
|
+
this._contentLines.splice(0, this._contentLines.length, ...restored);
|
|
633870
|
+
}
|
|
633871
|
+
this._contentScrollOffset = 0;
|
|
633872
|
+
this._pendingTrailingBlanks = 0;
|
|
633873
|
+
this._inProgressLine = "";
|
|
633874
|
+
this.clearStreamingRepaintTimer();
|
|
633875
|
+
this._lastBufferedFingerprint = "";
|
|
633876
|
+
this._lastBufferedAt = 0;
|
|
633877
|
+
this._autoScroll = true;
|
|
633878
|
+
this.markContentMutated();
|
|
633879
|
+
this.clampContentScrollOffset();
|
|
633880
|
+
if (this.active) {
|
|
633881
|
+
this.fillContentArea();
|
|
633882
|
+
this.repaintContent();
|
|
633883
|
+
this.renderFooterAndPositionInput();
|
|
633884
|
+
this.refreshHeaderContent();
|
|
633885
|
+
}
|
|
633886
|
+
}
|
|
633503
633887
|
/** Set callback for header focus changes (wired by interactive.ts to banner) */
|
|
633504
633888
|
setHeaderFocusHandler(handler) {
|
|
633505
633889
|
this._headerFocusHandler = handler;
|
|
@@ -659283,11 +659667,12 @@ sleep 1
|
|
|
659283
659667
|
const prompt = ctx3.contextRestore?.();
|
|
659284
659668
|
if (prompt) {
|
|
659285
659669
|
const info = ctx3.contextShow?.();
|
|
659670
|
+
const snapshot = typeof prompt === "string" ? null : prompt;
|
|
659671
|
+
ctx3.setRestoredContext?.(prompt);
|
|
659286
659672
|
renderInfo(
|
|
659287
|
-
`Context restored from ${info?.entries ?? 0} saved session(s). Will be injected into your next task.`
|
|
659673
|
+
`Context restored from ${info?.entries ?? 0} saved session(s)${snapshot?.historyLineCount ? `; replayed ${snapshot.historyLineCount} transcript line(s)` : ""}${snapshot?.todoCount ? `; restored ${snapshot.todoCount} todo(s)` : ""}. Will be injected into your next task.`
|
|
659288
659674
|
);
|
|
659289
|
-
renderContextHistory(ctx3, "Session History");
|
|
659290
|
-
ctx3.setRestoredContext?.(prompt);
|
|
659675
|
+
if (!snapshot?.historyLineCount) renderContextHistory(ctx3, "Session History");
|
|
659291
659676
|
} else {
|
|
659292
659677
|
renderWarning(
|
|
659293
659678
|
"No saved session context found. Complete a task first, or use /context save."
|
|
@@ -738589,7 +738974,7 @@ async function runSelfImprovementCycle(repoRoot) {
|
|
|
738589
738974
|
} catch {
|
|
738590
738975
|
}
|
|
738591
738976
|
}
|
|
738592
|
-
function startTask(task, config, repoRoot, voice, stream, taskStores, bruteForce, statusBar, sudoCallback, costTracker, onComplete, taskType, contextWindowSize, modelCaps, personality, deepContext, onCompaction, emotionEngine, flowEnabled, slashCommandHandler, thinkingEnabled, askUserCallback, selfModifyEnabled, sessionMetrics, realtimeEnabled) {
|
|
738977
|
+
function startTask(task, config, repoRoot, voice, stream, taskStores, bruteForce, statusBar, sudoCallback, costTracker, onComplete, taskType, contextWindowSize, modelCaps, personality, deepContext, onCompaction, emotionEngine, flowEnabled, slashCommandHandler, thinkingEnabled, askUserCallback, selfModifyEnabled, sessionMetrics, realtimeEnabled, restoredRunSessionId) {
|
|
738593
738978
|
const voiceStyleMap = {
|
|
738594
738979
|
concise: 1,
|
|
738595
738980
|
balanced: 3,
|
|
@@ -738610,7 +738995,7 @@ function startTask(task, config, repoRoot, voice, stream, taskStores, bruteForce
|
|
|
738610
738995
|
if (emotionEngine) emotionEngine.autistMode = true;
|
|
738611
738996
|
}
|
|
738612
738997
|
const modelTier2 = getModelTier(config.model);
|
|
738613
|
-
const sessionId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
738998
|
+
const sessionId = typeof restoredRunSessionId === "string" && restoredRunSessionId.trim() ? restoredRunSessionId.trim() : `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
738614
738999
|
const taskMetricDescription = cleanForStorage(task).replace(/\s+/g, " ").slice(0, 160) || "task";
|
|
738615
739000
|
costTracker?.startTask(taskMetricDescription);
|
|
738616
739001
|
sessionMetrics?.startTask(taskMetricDescription);
|
|
@@ -740614,7 +740999,8 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
740614
740999
|
toolCalls: result.toolCalls,
|
|
740615
741000
|
completed: result.completed,
|
|
740616
741001
|
model: config.model,
|
|
740617
|
-
source: "task_complete"
|
|
741002
|
+
source: "task_complete",
|
|
741003
|
+
sessionId
|
|
740618
741004
|
});
|
|
740619
741005
|
} catch {
|
|
740620
741006
|
}
|
|
@@ -740651,7 +741037,8 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
740651
741037
|
toolCalls: result.toolCalls,
|
|
740652
741038
|
completed: result.completed,
|
|
740653
741039
|
model: config.model,
|
|
740654
|
-
source: "task_complete"
|
|
741040
|
+
source: "task_complete",
|
|
741041
|
+
sessionId
|
|
740655
741042
|
},
|
|
740656
741043
|
accomplishments: extractedAccomplishments.length > 0 ? extractedAccomplishments : [
|
|
740657
741044
|
`Completed task in ${result.turns} turns with ${result.toolCalls} tool calls`
|
|
@@ -740675,11 +741062,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
740675
741062
|
}
|
|
740676
741063
|
try {
|
|
740677
741064
|
const historySessionId = process.env["OMNIUS_SESSION_ID"] || `session-${Date.now().toString(36)}`;
|
|
740678
|
-
const
|
|
740679
|
-
const contentLines = typeof statusBar?.expandDynamicBlockSentinels === "function" ? statusBar.expandDynamicBlockSentinels(
|
|
740680
|
-
rawContentLines,
|
|
740681
|
-
100
|
|
740682
|
-
) : rawContentLines;
|
|
741065
|
+
const contentLines = typeof statusBar?.capturePersistedSessionLines === "function" ? statusBar.capturePersistedSessionLines(100) : statusBar?._contentLines ?? [];
|
|
740683
741066
|
if (contentLines.length > 0) {
|
|
740684
741067
|
const description = cleanPromptForDiary(task).slice(0, 240);
|
|
740685
741068
|
const historyTitle = description.slice(0, 80) || void 0;
|
|
@@ -740920,6 +741303,8 @@ async function startInteractive(config, repoPath2) {
|
|
|
740920
741303
|
}
|
|
740921
741304
|
await bootstrapMcpAndPlugins(repoRoot);
|
|
740922
741305
|
let restoredSessionContext = null;
|
|
741306
|
+
let restoredTaskSessionId = null;
|
|
741307
|
+
let saveVisualSessionSnapshotRef = null;
|
|
740923
741308
|
let terminalRestoredForExit = false;
|
|
740924
741309
|
let interactiveExiting = false;
|
|
740925
741310
|
let idleMemoryMaintenance = null;
|
|
@@ -740948,6 +741333,10 @@ async function startInteractive(config, repoPath2) {
|
|
|
740948
741333
|
);
|
|
740949
741334
|
const cleanupAndExit = (code8) => {
|
|
740950
741335
|
interactiveExiting = true;
|
|
741336
|
+
try {
|
|
741337
|
+
saveVisualSessionSnapshotRef?.("process exit");
|
|
741338
|
+
} catch {
|
|
741339
|
+
}
|
|
740951
741340
|
if (_shellToolRef) _shellToolRef.killAll();
|
|
740952
741341
|
idleMemoryMaintenance?.stop();
|
|
740953
741342
|
killAllFullSubAgents();
|
|
@@ -741464,14 +741853,14 @@ ${result.summary}`
|
|
|
741464
741853
|
const { getLastTaskSummary: getLastTaskSummary2 } = (init_omnius_directory(), __toCommonJS(omnius_directory_exports));
|
|
741465
741854
|
const taskSummary = hasTaskToResume ? getLastTaskSummary2(repoRoot) : null;
|
|
741466
741855
|
const resumeMsg = taskSummary ? `v${version5} — picking up: ${taskSummary}` : `Updated to v${version5}.`;
|
|
741856
|
+
const restoreSnapshot = buildContextRestoreSnapshot(repoRoot);
|
|
741857
|
+
const replayedVisual = restoreSnapshot ? applyRestoreSnapshot(restoreSnapshot, { replayVisual: true }) : false;
|
|
741467
741858
|
writeContent(() => {
|
|
741468
741859
|
renderInfo(resumeMsg);
|
|
741469
|
-
|
|
741470
|
-
if (resumePrompt) {
|
|
741471
|
-
restoredSessionContext = resumePrompt;
|
|
741860
|
+
if (restoreSnapshot) {
|
|
741472
741861
|
const info = loadSessionContext(repoRoot);
|
|
741473
741862
|
renderInfo(
|
|
741474
|
-
`Context restored from ${info?.entries.length ?? 0} session(s).`
|
|
741863
|
+
`Context restored from ${info?.entries.length ?? 0} session(s)${replayedVisual ? `; replayed ${restoreSnapshot.historyLineCount ?? 0} transcript line(s).` : "."}`
|
|
741475
741864
|
);
|
|
741476
741865
|
}
|
|
741477
741866
|
});
|
|
@@ -742455,6 +742844,69 @@ This is an independent background session started from /background.`
|
|
|
742455
742844
|
}
|
|
742456
742845
|
}
|
|
742457
742846
|
setDreamWriteContent(writeContent);
|
|
742847
|
+
function saveVisualSessionSnapshot(reason) {
|
|
742848
|
+
try {
|
|
742849
|
+
const historySessionId = process.env["OMNIUS_SESSION_ID"] || process.env["OMNIUS_TUI_SESSION_ID"] || `session-${Date.now().toString(36)}`;
|
|
742850
|
+
const contentLines = statusBar.capturePersistedSessionLines(100);
|
|
742851
|
+
if (contentLines.length === 0) return;
|
|
742852
|
+
const description = cleanPromptForDiary(lastSubmittedPrompt || lastCompletedSummary || reason).slice(0, 240) || reason;
|
|
742853
|
+
const historyTitle = description.slice(0, 80) || void 0;
|
|
742854
|
+
saveSessionHistory(repoRoot, historySessionId, contentLines, {
|
|
742855
|
+
name: historyTitle,
|
|
742856
|
+
description,
|
|
742857
|
+
taskCount: 1,
|
|
742858
|
+
model: currentConfig.model
|
|
742859
|
+
});
|
|
742860
|
+
importTranscriptSession({
|
|
742861
|
+
id: `tui:${historySessionId}`,
|
|
742862
|
+
projectRoot: repoRoot,
|
|
742863
|
+
model: currentConfig.model,
|
|
742864
|
+
title: historyTitle,
|
|
742865
|
+
description,
|
|
742866
|
+
transcriptLines: contentLines,
|
|
742867
|
+
updatedAt: Date.now()
|
|
742868
|
+
});
|
|
742869
|
+
} catch {
|
|
742870
|
+
}
|
|
742871
|
+
}
|
|
742872
|
+
saveVisualSessionSnapshotRef = saveVisualSessionSnapshot;
|
|
742873
|
+
function replayRestoredVisualSession(snapshot) {
|
|
742874
|
+
if (!snapshot.historySessionId) return false;
|
|
742875
|
+
const lines = loadSessionHistory(repoRoot, snapshot.historySessionId);
|
|
742876
|
+
if (!lines || lines.length === 0) return false;
|
|
742877
|
+
try {
|
|
742878
|
+
statusBar.restoreMainContentLines(lines);
|
|
742879
|
+
return true;
|
|
742880
|
+
} catch {
|
|
742881
|
+
return false;
|
|
742882
|
+
}
|
|
742883
|
+
}
|
|
742884
|
+
function applyRestoreSnapshot(snapshot, options2 = {}) {
|
|
742885
|
+
if (options2.injectNextTask !== false) {
|
|
742886
|
+
restoredSessionContext = snapshot.prompt;
|
|
742887
|
+
}
|
|
742888
|
+
const restoredId = snapshot.todoSessionId || snapshot.sourceSessionId || null;
|
|
742889
|
+
restoredTaskSessionId = restoredId;
|
|
742890
|
+
if (restoredId) {
|
|
742891
|
+
try {
|
|
742892
|
+
process.env["OMNIUS_SESSION_ID"] = restoredId;
|
|
742893
|
+
} catch {
|
|
742894
|
+
}
|
|
742895
|
+
try {
|
|
742896
|
+
setTodoSessionId(restoredId);
|
|
742897
|
+
} catch {
|
|
742898
|
+
}
|
|
742899
|
+
try {
|
|
742900
|
+
setTuiTasksSession(restoredId);
|
|
742901
|
+
} catch {
|
|
742902
|
+
}
|
|
742903
|
+
try {
|
|
742904
|
+
refreshTuiTasks();
|
|
742905
|
+
} catch {
|
|
742906
|
+
}
|
|
742907
|
+
}
|
|
742908
|
+
return options2.replayVisual ? replayRestoredVisualSession(snapshot) : false;
|
|
742909
|
+
}
|
|
742458
742910
|
async function writeContentAsync(fn) {
|
|
742459
742911
|
if (!statusBar.isActive) return fn();
|
|
742460
742912
|
if (isNeovimActive()) {
|
|
@@ -743230,6 +743682,7 @@ Log: ${nexusLogPath}`
|
|
|
743230
743682
|
clearInterval(reminderDispatchTimer);
|
|
743231
743683
|
reminderDispatchTimer = null;
|
|
743232
743684
|
}
|
|
743685
|
+
saveVisualSessionSnapshot("command exit");
|
|
743233
743686
|
statusBar.deactivate();
|
|
743234
743687
|
if (carousel.isRunning) carousel.stop();
|
|
743235
743688
|
banner.stop();
|
|
@@ -745446,7 +745899,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
745446
745899
|
toolCalls: sessionToolCallCount,
|
|
745447
745900
|
source: "manual",
|
|
745448
745901
|
completed: false,
|
|
745449
|
-
model: currentConfig.model
|
|
745902
|
+
model: currentConfig.model,
|
|
745903
|
+
sessionId: getTodoSessionId() || process.env["OMNIUS_SESSION_ID"]
|
|
745450
745904
|
};
|
|
745451
745905
|
saveSessionContext(repoRoot, entry);
|
|
745452
745906
|
return true;
|
|
@@ -745455,10 +745909,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
745455
745909
|
}
|
|
745456
745910
|
},
|
|
745457
745911
|
contextRestore() {
|
|
745458
|
-
return
|
|
745912
|
+
return buildContextRestoreSnapshot(repoRoot);
|
|
745459
745913
|
},
|
|
745460
745914
|
setRestoredContext(ctx3) {
|
|
745461
|
-
|
|
745915
|
+
if (typeof ctx3 === "string") {
|
|
745916
|
+
restoredSessionContext = ctx3;
|
|
745917
|
+
} else {
|
|
745918
|
+
applyRestoreSnapshot(ctx3, { replayVisual: true });
|
|
745919
|
+
}
|
|
745462
745920
|
},
|
|
745463
745921
|
contextShow() {
|
|
745464
745922
|
const ctx3 = loadSessionContext(repoRoot);
|
|
@@ -745601,28 +746059,30 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
745601
746059
|
const auto = countdown <= 0;
|
|
745602
746060
|
const doRestore = selectResult.confirmed && selectResult.key === "restore";
|
|
745603
746061
|
if (doRestore) {
|
|
745604
|
-
const
|
|
745605
|
-
if (
|
|
745606
|
-
|
|
746062
|
+
const snapshot = buildContextRestoreSnapshot(repoRoot);
|
|
746063
|
+
if (snapshot) {
|
|
746064
|
+
const replayedVisual = applyRestoreSnapshot(snapshot, { replayVisual: true });
|
|
745607
746065
|
const info = loadSessionContext(repoRoot);
|
|
745608
746066
|
writeContent(() => {
|
|
745609
746067
|
renderInfo(
|
|
745610
|
-
auto ? `Context auto-restored from ${info?.entries.length ?? 0} session(s).` : `Context restored from ${info?.entries.length ?? 0} session(s).`
|
|
746068
|
+
auto ? `Context auto-restored from ${info?.entries.length ?? 0} session(s)${replayedVisual ? `; replayed ${snapshot.historyLineCount ?? 0} transcript line(s)` : ""}${snapshot.todoCount ? `; restored ${snapshot.todoCount} todo(s)` : ""}.` : `Context restored from ${info?.entries.length ?? 0} session(s)${replayedVisual ? `; replayed ${snapshot.historyLineCount ?? 0} transcript line(s)` : ""}${snapshot.todoCount ? `; restored ${snapshot.todoCount} todo(s)` : ""}.`
|
|
745611
746069
|
);
|
|
745612
|
-
if (
|
|
745613
|
-
|
|
745614
|
-
|
|
745615
|
-
|
|
745616
|
-
|
|
745617
|
-
|
|
745618
|
-
|
|
745619
|
-
|
|
745620
|
-
|
|
745621
|
-
|
|
745622
|
-
|
|
745623
|
-
|
|
746070
|
+
if (!replayedVisual) {
|
|
746071
|
+
if (statusBar.isActive && !isNeovimActive() && !isOverlayActive()) {
|
|
746072
|
+
renderSessionHistoryBox(
|
|
746073
|
+
{
|
|
746074
|
+
registerDynamicBlock: (id2, render2) => statusBar.registerDynamicBlock(id2, render2),
|
|
746075
|
+
appendDynamicBlock: (id2) => statusBar.appendDynamicBlock(id2)
|
|
746076
|
+
},
|
|
746077
|
+
sessionContextToHistoryBoxData(info, "Session History")
|
|
746078
|
+
);
|
|
746079
|
+
} else {
|
|
746080
|
+
const historyDisplay = formatSessionHistoryDisplay(info);
|
|
746081
|
+
process.stdout.write(
|
|
746082
|
+
historyDisplay.endsWith("\n") ? historyDisplay : `${historyDisplay}
|
|
745624
746083
|
`
|
|
745625
|
-
|
|
746084
|
+
);
|
|
746085
|
+
}
|
|
745626
746086
|
}
|
|
745627
746087
|
});
|
|
745628
746088
|
} else {
|
|
@@ -745682,7 +746142,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
745682
746142
|
const pendingTask = loadPendingTask(repoRoot);
|
|
745683
746143
|
if (pendingTask) {
|
|
745684
746144
|
setTimeout(() => {
|
|
745685
|
-
const
|
|
746145
|
+
const restoreSnapshot = buildContextRestoreSnapshot(repoRoot);
|
|
746146
|
+
if (restoreSnapshot) {
|
|
746147
|
+
applyRestoreSnapshot(restoreSnapshot, {
|
|
746148
|
+
replayVisual: true,
|
|
746149
|
+
injectNextTask: false
|
|
746150
|
+
});
|
|
746151
|
+
}
|
|
746152
|
+
const sessionCtx = restoreSnapshot?.prompt ?? buildContextRestorePrompt(repoRoot);
|
|
745686
746153
|
const resumeContext = [
|
|
745687
746154
|
sessionCtx || "",
|
|
745688
746155
|
`Continuing task after update: ${pendingTask.prompt}`,
|
|
@@ -745853,6 +746320,7 @@ ${result.content.slice(0, 2e3)}${result.content.length > 2e3 ? "\n[truncated]" :
|
|
|
745853
746320
|
const quitMatch = input.trim().replace(/^\//, "").toLowerCase();
|
|
745854
746321
|
if (quitMatch === "quit" || quitMatch === "exit" || quitMatch === "q") {
|
|
745855
746322
|
interactiveExiting = true;
|
|
746323
|
+
saveVisualSessionSnapshot("quit");
|
|
745856
746324
|
if (activeTask) activeTask.runner.abort();
|
|
745857
746325
|
idleMemoryMaintenance?.stop();
|
|
745858
746326
|
taskManager.stopAll();
|
|
@@ -745870,6 +746338,7 @@ ${result.content.slice(0, 2e3)}${result.content.length > 2e3 ? "\n[truncated]" :
|
|
|
745870
746338
|
);
|
|
745871
746339
|
if (cmdResult === "exit") {
|
|
745872
746340
|
interactiveExiting = true;
|
|
746341
|
+
saveVisualSessionSnapshot("command exit");
|
|
745873
746342
|
if (activeTask) activeTask.runner.abort();
|
|
745874
746343
|
idleMemoryMaintenance?.stop();
|
|
745875
746344
|
taskManager.stopAll();
|
|
@@ -746434,6 +746903,7 @@ ${formatTaskCompletionMeta(previousMetaForIntake)}`
|
|
|
746434
746903
|
} catch {
|
|
746435
746904
|
}
|
|
746436
746905
|
let taskInput = fullInput;
|
|
746906
|
+
let taskSessionId = restoredTaskSessionId;
|
|
746437
746907
|
if (restoredSessionContext) {
|
|
746438
746908
|
taskInput = `${restoredSessionContext}
|
|
746439
746909
|
|
|
@@ -746442,6 +746912,7 @@ ${formatTaskCompletionMeta(previousMetaForIntake)}`
|
|
|
746442
746912
|
NEW TASK: ${fullInput}`;
|
|
746443
746913
|
restoredSessionContext = null;
|
|
746444
746914
|
}
|
|
746915
|
+
restoredTaskSessionId = null;
|
|
746445
746916
|
if (taskIntakePacket) {
|
|
746446
746917
|
taskInput = `${taskIntakePacket}
|
|
746447
746918
|
|
|
@@ -746490,7 +746961,8 @@ ${taskInput}`;
|
|
|
746490
746961
|
handleAskUser,
|
|
746491
746962
|
selfModifyEnabled,
|
|
746492
746963
|
sessionMetrics,
|
|
746493
|
-
realtimeEnabled
|
|
746964
|
+
realtimeEnabled,
|
|
746965
|
+
taskSessionId
|
|
746494
746966
|
);
|
|
746495
746967
|
activeTask = task;
|
|
746496
746968
|
_recallText = null;
|
|
@@ -746729,6 +747201,7 @@ Rationale: ${proposal.rationale}${provenanceNote}${dmnDevDiscipline(proposal.cat
|
|
|
746729
747201
|
rl.on("close", () => {
|
|
746730
747202
|
if (interactiveExiting) return;
|
|
746731
747203
|
interactiveExiting = true;
|
|
747204
|
+
saveVisualSessionSnapshot("readline close");
|
|
746732
747205
|
if (peerMesh) {
|
|
746733
747206
|
peerMesh.stop().catch(() => {
|
|
746734
747207
|
});
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.464",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "omnius",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.464",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
|
@@ -430,9 +430,9 @@
|
|
|
430
430
|
}
|
|
431
431
|
},
|
|
432
432
|
"node_modules/@helia/utils/node_modules/cborg": {
|
|
433
|
-
"version": "5.1.
|
|
434
|
-
"resolved": "https://registry.npmjs.org/cborg/-/cborg-5.1.
|
|
435
|
-
"integrity": "sha512-
|
|
433
|
+
"version": "5.1.7",
|
|
434
|
+
"resolved": "https://registry.npmjs.org/cborg/-/cborg-5.1.7.tgz",
|
|
435
|
+
"integrity": "sha512-rGg2MG9zZEUKtKqjkBppIWUecTXf9N1vs1Qru43vJWoDaODhCrtmzdehCaA/aq/c1cPI5A0kPrJ5Tf+jIfhV4w==",
|
|
436
436
|
"license": "Apache-2.0",
|
|
437
437
|
"bin": {
|
|
438
438
|
"cborg": "lib/bin.js"
|
|
@@ -461,9 +461,9 @@
|
|
|
461
461
|
}
|
|
462
462
|
},
|
|
463
463
|
"node_modules/@ipld/dag-cbor/node_modules/cborg": {
|
|
464
|
-
"version": "5.1.
|
|
465
|
-
"resolved": "https://registry.npmjs.org/cborg/-/cborg-5.1.
|
|
466
|
-
"integrity": "sha512-
|
|
464
|
+
"version": "5.1.7",
|
|
465
|
+
"resolved": "https://registry.npmjs.org/cborg/-/cborg-5.1.7.tgz",
|
|
466
|
+
"integrity": "sha512-rGg2MG9zZEUKtKqjkBppIWUecTXf9N1vs1Qru43vJWoDaODhCrtmzdehCaA/aq/c1cPI5A0kPrJ5Tf+jIfhV4w==",
|
|
467
467
|
"license": "Apache-2.0",
|
|
468
468
|
"bin": {
|
|
469
469
|
"cborg": "lib/bin.js"
|
|
@@ -480,9 +480,9 @@
|
|
|
480
480
|
}
|
|
481
481
|
},
|
|
482
482
|
"node_modules/@ipld/dag-json/node_modules/cborg": {
|
|
483
|
-
"version": "5.1.
|
|
484
|
-
"resolved": "https://registry.npmjs.org/cborg/-/cborg-5.1.
|
|
485
|
-
"integrity": "sha512-
|
|
483
|
+
"version": "5.1.7",
|
|
484
|
+
"resolved": "https://registry.npmjs.org/cborg/-/cborg-5.1.7.tgz",
|
|
485
|
+
"integrity": "sha512-rGg2MG9zZEUKtKqjkBppIWUecTXf9N1vs1Qru43vJWoDaODhCrtmzdehCaA/aq/c1cPI5A0kPrJ5Tf+jIfhV4w==",
|
|
486
486
|
"license": "Apache-2.0",
|
|
487
487
|
"bin": {
|
|
488
488
|
"cborg": "lib/bin.js"
|
|
@@ -4342,9 +4342,9 @@
|
|
|
4342
4342
|
}
|
|
4343
4343
|
},
|
|
4344
4344
|
"node_modules/ipns/node_modules/cborg": {
|
|
4345
|
-
"version": "5.1.
|
|
4346
|
-
"resolved": "https://registry.npmjs.org/cborg/-/cborg-5.1.
|
|
4347
|
-
"integrity": "sha512-
|
|
4345
|
+
"version": "5.1.7",
|
|
4346
|
+
"resolved": "https://registry.npmjs.org/cborg/-/cborg-5.1.7.tgz",
|
|
4347
|
+
"integrity": "sha512-rGg2MG9zZEUKtKqjkBppIWUecTXf9N1vs1Qru43vJWoDaODhCrtmzdehCaA/aq/c1cPI5A0kPrJ5Tf+jIfhV4w==",
|
|
4348
4348
|
"license": "Apache-2.0",
|
|
4349
4349
|
"bin": {
|
|
4350
4350
|
"cborg": "lib/bin.js"
|
package/package.json
CHANGED