omnius 1.0.688 → 1.0.690
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 +480 -378
- package/docs/DISCOVERY.json +78 -0
- package/docs/DISCOVERY.md +2 -0
- package/docs/work-orders/runtime-health-remediation/TRACKER.md +14 -0
- package/docs/work-orders/runtime-health-remediation/WO-20-exact-session-continuation.md +88 -0
- package/docs/work-orders/runtime-health-remediation/WO-21-task-convergence-and-todo-scope.md +115 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -360167,6 +360167,7 @@ var init_todo_write = __esm({
|
|
|
360167
360167
|
init_todo_store();
|
|
360168
360168
|
_currentSessionId = "";
|
|
360169
360169
|
TodoWriteTool = class {
|
|
360170
|
+
executionScope = null;
|
|
360170
360171
|
name = "todo_write";
|
|
360171
360172
|
description = `Update the session task checklist. To be used proactively and often to track progress and pending tasks. Make sure that at least one task is in_progress at all times.
|
|
360172
360173
|
|
|
@@ -360306,6 +360307,24 @@ Mark tasks complete IMMEDIATELY after finishing — don't batch. Never mark comp
|
|
|
360306
360307
|
}
|
|
360307
360308
|
}
|
|
360308
360309
|
};
|
|
360310
|
+
constructor(scope) {
|
|
360311
|
+
if (scope)
|
|
360312
|
+
this.bindExecutionScope(scope);
|
|
360313
|
+
}
|
|
360314
|
+
bindExecutionScope(scope) {
|
|
360315
|
+
const sessionId = String(scope.sessionId ?? "").trim();
|
|
360316
|
+
if (!sessionId)
|
|
360317
|
+
throw new TypeError("todo_write requires a non-empty host session scope");
|
|
360318
|
+
if (this.executionScope && this.executionScope.sessionId !== sessionId) {
|
|
360319
|
+
throw new Error(`todo_write is already bound to session '${this.executionScope.sessionId}'`);
|
|
360320
|
+
}
|
|
360321
|
+
this.executionScope = Object.freeze({ ...scope, sessionId });
|
|
360322
|
+
}
|
|
360323
|
+
resolveSessionId(args) {
|
|
360324
|
+
if (this.executionScope)
|
|
360325
|
+
return this.executionScope.sessionId;
|
|
360326
|
+
return typeof args["session_id"] === "string" && args["session_id"].trim() ? args["session_id"].trim() : typeof args["sessionId"] === "string" && args["sessionId"].trim() ? args["sessionId"].trim() : getTodoSessionId();
|
|
360327
|
+
}
|
|
360309
360328
|
async execute(args) {
|
|
360310
360329
|
const start2 = performance.now();
|
|
360311
360330
|
try {
|
|
@@ -360406,7 +360425,7 @@ Mark tasks complete IMMEDIATELY after finishing — don't batch. Never mark comp
|
|
|
360406
360425
|
};
|
|
360407
360426
|
}
|
|
360408
360427
|
enforceActiveLeafTodo(incoming, repairNotes);
|
|
360409
|
-
const sessionId =
|
|
360428
|
+
const sessionId = this.resolveSessionId(args);
|
|
360410
360429
|
const oldTodos = readTodos(sessionId);
|
|
360411
360430
|
const canonicalize4 = (todos) => JSON.stringify(todos.map((t2) => ({
|
|
360412
360431
|
content: t2.content,
|
|
@@ -360517,6 +360536,7 @@ Mark tasks complete IMMEDIATELY after finishing — don't batch. Never mark comp
|
|
|
360517
360536
|
"acceptance"
|
|
360518
360537
|
]);
|
|
360519
360538
|
TodoReadTool = class {
|
|
360539
|
+
executionScope = null;
|
|
360520
360540
|
name = "todo_read";
|
|
360521
360541
|
description = "Read the current task checklist for this session.";
|
|
360522
360542
|
parameters = {
|
|
@@ -360528,10 +360548,28 @@ Mark tasks complete IMMEDIATELY after finishing — don't batch. Never mark comp
|
|
|
360528
360548
|
}
|
|
360529
360549
|
}
|
|
360530
360550
|
};
|
|
360551
|
+
constructor(scope) {
|
|
360552
|
+
if (scope)
|
|
360553
|
+
this.bindExecutionScope(scope);
|
|
360554
|
+
}
|
|
360555
|
+
bindExecutionScope(scope) {
|
|
360556
|
+
const sessionId = String(scope.sessionId ?? "").trim();
|
|
360557
|
+
if (!sessionId)
|
|
360558
|
+
throw new TypeError("todo_read requires a non-empty host session scope");
|
|
360559
|
+
if (this.executionScope && this.executionScope.sessionId !== sessionId) {
|
|
360560
|
+
throw new Error(`todo_read is already bound to session '${this.executionScope.sessionId}'`);
|
|
360561
|
+
}
|
|
360562
|
+
this.executionScope = Object.freeze({ ...scope, sessionId });
|
|
360563
|
+
}
|
|
360564
|
+
resolveSessionId(args) {
|
|
360565
|
+
if (this.executionScope)
|
|
360566
|
+
return this.executionScope.sessionId;
|
|
360567
|
+
return typeof args["session_id"] === "string" && args["session_id"].trim() ? args["session_id"].trim() : typeof args["sessionId"] === "string" && args["sessionId"].trim() ? args["sessionId"].trim() : getTodoSessionId();
|
|
360568
|
+
}
|
|
360531
360569
|
async execute(args) {
|
|
360532
360570
|
const start2 = performance.now();
|
|
360533
360571
|
try {
|
|
360534
|
-
const sessionId =
|
|
360572
|
+
const sessionId = this.resolveSessionId(args);
|
|
360535
360573
|
const todos = readTodos(sessionId);
|
|
360536
360574
|
return {
|
|
360537
360575
|
success: true,
|
|
@@ -630245,6 +630283,58 @@ var init_contextBudget = __esm({
|
|
|
630245
630283
|
}
|
|
630246
630284
|
});
|
|
630247
630285
|
|
|
630286
|
+
// packages/orchestrator/dist/convergence-progress.js
|
|
630287
|
+
function classifyAuthoritativeProgress(input) {
|
|
630288
|
+
if (!input.success || input.noop || input.runtimeAuthored)
|
|
630289
|
+
return null;
|
|
630290
|
+
const kind = input.confirmedMutation ? "mutation" : input.todoTransition ? "todo_transition" : input.workboardTransition ? "workboard_transition" : input.assertiveVerifier ? "verifier_receipt" : input.deliveryReceipt ? "delivery_receipt" : null;
|
|
630291
|
+
return kind ? { kind, fingerprint: `${kind}:${input.fingerprint}` } : null;
|
|
630292
|
+
}
|
|
630293
|
+
var ConvergenceProgressTracker;
|
|
630294
|
+
var init_convergence_progress = __esm({
|
|
630295
|
+
"packages/orchestrator/dist/convergence-progress.js"() {
|
|
630296
|
+
"use strict";
|
|
630297
|
+
ConvergenceProgressTracker = class {
|
|
630298
|
+
fingerprints = /* @__PURE__ */ new Set();
|
|
630299
|
+
progressCount = 0;
|
|
630300
|
+
lastProgressTurn = 0;
|
|
630301
|
+
lastKind;
|
|
630302
|
+
reviewLatched = false;
|
|
630303
|
+
record(turn, signal) {
|
|
630304
|
+
if (!signal || this.fingerprints.has(signal.fingerprint))
|
|
630305
|
+
return false;
|
|
630306
|
+
this.fingerprints.add(signal.fingerprint);
|
|
630307
|
+
this.progressCount += 1;
|
|
630308
|
+
this.lastProgressTurn = Math.max(0, turn);
|
|
630309
|
+
this.lastKind = signal.kind;
|
|
630310
|
+
this.reviewLatched = false;
|
|
630311
|
+
return true;
|
|
630312
|
+
}
|
|
630313
|
+
shouldLatchReview(input) {
|
|
630314
|
+
if (this.reviewLatched || input.openLeafCount <= 0)
|
|
630315
|
+
return false;
|
|
630316
|
+
const threshold = Math.max(1, Math.floor(input.thresholdTurns));
|
|
630317
|
+
if (input.turn - this.lastProgressTurn < threshold)
|
|
630318
|
+
return false;
|
|
630319
|
+
this.reviewLatched = true;
|
|
630320
|
+
return true;
|
|
630321
|
+
}
|
|
630322
|
+
hasRecentProgress(turn, windowTurns) {
|
|
630323
|
+
return this.progressCount > 0 && turn - this.lastProgressTurn <= Math.max(1, Math.floor(windowTurns));
|
|
630324
|
+
}
|
|
630325
|
+
snapshot(turn) {
|
|
630326
|
+
return {
|
|
630327
|
+
count: this.progressCount,
|
|
630328
|
+
lastProgressTurn: this.lastProgressTurn,
|
|
630329
|
+
turnsSinceProgress: Math.max(0, turn - this.lastProgressTurn),
|
|
630330
|
+
reviewLatched: this.reviewLatched,
|
|
630331
|
+
...this.lastKind ? { lastKind: this.lastKind } : {}
|
|
630332
|
+
};
|
|
630333
|
+
}
|
|
630334
|
+
};
|
|
630335
|
+
}
|
|
630336
|
+
});
|
|
630337
|
+
|
|
630248
630338
|
// packages/orchestrator/dist/inference-pressure.js
|
|
630249
630339
|
function getInferencePressureCoordinator() {
|
|
630250
630340
|
processCoordinator ??= new InferencePressureCoordinator({
|
|
@@ -662510,6 +662600,7 @@ var init_agenticRunner = __esm({
|
|
|
662510
662600
|
"packages/orchestrator/dist/agenticRunner.js"() {
|
|
662511
662601
|
"use strict";
|
|
662512
662602
|
init_contextBudget();
|
|
662603
|
+
init_convergence_progress();
|
|
662513
662604
|
init_inference_pressure();
|
|
662514
662605
|
init_interruption_lifecycle();
|
|
662515
662606
|
init_tool_exposure_policy();
|
|
@@ -663967,7 +664058,7 @@ ${loadPrompt("agentic/system-small.md")}`;
|
|
|
663967
664058
|
if (this.options.subAgent || this.options.recursionDepth > 0)
|
|
663968
664059
|
return [];
|
|
663969
664060
|
const normalizedGoal = goal.replace(/\s+/g, " ").trim();
|
|
663970
|
-
if (normalizedGoal.length < 120 && !this.
|
|
664061
|
+
if (normalizedGoal.length < 120 && !this._resumeInterrupted)
|
|
663971
664062
|
return [];
|
|
663972
664063
|
return [
|
|
663973
664064
|
{
|
|
@@ -664035,44 +664126,6 @@ ${loadPrompt("agentic/system-small.md")}`;
|
|
|
664035
664126
|
}
|
|
664036
664127
|
];
|
|
664037
664128
|
}
|
|
664038
|
-
_isContinuationResumeGoal(goal) {
|
|
664039
|
-
const tokens3 = goal.toLowerCase().replace(/[^a-z0-9]+/g, " ").split(/\s+/).filter(Boolean);
|
|
664040
|
-
if (tokens3.length === 0 || tokens3.length > 14)
|
|
664041
|
-
return false;
|
|
664042
|
-
const continuationTerms = /* @__PURE__ */ new Set([
|
|
664043
|
-
"again",
|
|
664044
|
-
"and",
|
|
664045
|
-
"back",
|
|
664046
|
-
"carry",
|
|
664047
|
-
"complete",
|
|
664048
|
-
"continue",
|
|
664049
|
-
"finish",
|
|
664050
|
-
"from",
|
|
664051
|
-
"last",
|
|
664052
|
-
"latest",
|
|
664053
|
-
"left",
|
|
664054
|
-
"my",
|
|
664055
|
-
"off",
|
|
664056
|
-
"please",
|
|
664057
|
-
"previous",
|
|
664058
|
-
"prior",
|
|
664059
|
-
"proceed",
|
|
664060
|
-
"request",
|
|
664061
|
-
"resume",
|
|
664062
|
-
"task",
|
|
664063
|
-
"that",
|
|
664064
|
-
"the",
|
|
664065
|
-
"this",
|
|
664066
|
-
"to",
|
|
664067
|
-
"try",
|
|
664068
|
-
"work"
|
|
664069
|
-
]);
|
|
664070
|
-
const hasResumeVerb = tokens3.some((token) => token === "continue" || token === "resume" || token === "proceed" || token === "complete" || token === "finish");
|
|
664071
|
-
if (!hasResumeVerb)
|
|
664072
|
-
return false;
|
|
664073
|
-
const continuationTokenCount = tokens3.filter((token) => continuationTerms.has(token)).length;
|
|
664074
|
-
return continuationTokenCount / tokens3.length >= 0.7;
|
|
664075
|
-
}
|
|
664076
664129
|
/**
|
|
664077
664130
|
* Build a compact workboard context string for injection into the
|
|
664078
664131
|
* system prompt. Returns null when no active board exists or when
|
|
@@ -664597,18 +664650,20 @@ ${parts.join("\n")}
|
|
|
664597
664650
|
recordWorkboardToolCall(toolName, args, success, output2, result, meta = {}) {
|
|
664598
664651
|
const board = this._currentWorkboardSnapshotForFrame() ?? this.getOrCreateWorkboard();
|
|
664599
664652
|
if (!board)
|
|
664600
|
-
return;
|
|
664653
|
+
return false;
|
|
664601
664654
|
if (toolName === "task_complete" || toolName === "workboard_create")
|
|
664602
|
-
return;
|
|
664655
|
+
return false;
|
|
664603
664656
|
if (meta.repeatShortCircuit || result?.runtimeAuthored)
|
|
664604
|
-
return;
|
|
664657
|
+
return false;
|
|
664605
664658
|
if (meta.focusDecisionKind === "block_tool_call")
|
|
664606
|
-
return;
|
|
664659
|
+
return false;
|
|
664607
664660
|
if (result?.success === true && this._isProjectEditTool(toolName) && !this._isRealProjectMutation(toolName, result) && result.alreadyApplied !== true) {
|
|
664608
|
-
return;
|
|
664661
|
+
return false;
|
|
664609
664662
|
}
|
|
664610
664663
|
const dir = this._workboardDir();
|
|
664611
664664
|
try {
|
|
664665
|
+
const statusFingerprint = (snapshot) => snapshot.cards.filter((card) => !card.supersededBy).map((card) => `${card.id}:${card.status}:${card.lane ?? ""}`).sort().join("|");
|
|
664666
|
+
const beforeStatus = statusFingerprint(board);
|
|
664612
664667
|
const evidenceSummary = toolName === "shell" && meta.shellFilesystemMutation ? `shell filesystem mutation ${success ? "ok" : "fail"}` : `${toolName} ${success ? "ok" : "fail"}`;
|
|
664613
664668
|
const rawEvidenceOutput = typeof output2 === "string" && output2.length > 0 ? output2 : result?.output || result?.error || "";
|
|
664614
664669
|
const evidenceContent = rawEvidenceOutput.slice(0, 1e3);
|
|
@@ -664629,14 +664684,15 @@ ${parts.join("\n")}
|
|
|
664629
664684
|
};
|
|
664630
664685
|
const actor = this.options.subAgent ? "sub-agent" : "agent";
|
|
664631
664686
|
const advanced = this._advanceWorkboardForTool(board, toolName, result, actor, meta);
|
|
664687
|
+
const workboardTransition = statusFingerprint(advanced) !== beforeStatus;
|
|
664632
664688
|
const targetCardId = this._workboardTargetCardId(advanced, toolName, args, result, meta);
|
|
664633
664689
|
if (!targetCardId)
|
|
664634
|
-
return;
|
|
664690
|
+
return workboardTransition;
|
|
664635
664691
|
const targetCard = advanced.cards.find((card) => card.id === targetCardId);
|
|
664636
664692
|
if (!targetCard)
|
|
664637
|
-
return;
|
|
664693
|
+
return workboardTransition;
|
|
664638
664694
|
if (targetCard.assignee && targetCard.assignee !== actor && targetCard.assignee !== "any") {
|
|
664639
|
-
return;
|
|
664695
|
+
return workboardTransition;
|
|
664640
664696
|
}
|
|
664641
664697
|
const evidenced = result?.executionReceipt ? attachTrustedWorkboardCommandEvidence(dir, {
|
|
664642
664698
|
runId: this.currentArtifactRunId(),
|
|
@@ -664654,7 +664710,7 @@ ${parts.join("\n")}
|
|
|
664654
664710
|
evidence
|
|
664655
664711
|
});
|
|
664656
664712
|
const persistedEvidence = evidenced.cards.find((card) => card.id === targetCard.id)?.evidence.find((item) => item.summary === evidence.summary && item.content === evidence.content);
|
|
664657
|
-
const substantive = success === true && result?.runtimeAuthored !== true;
|
|
664713
|
+
const substantive = success === true && result?.runtimeAuthored !== true && (workboardTransition || this._isRealProjectMutation(toolName, result) || meta.shellFilesystemMutation === true || toolName === "shell" && result !== void 0 && this._shellResultLooksLikeVerification(args, result) || Boolean(result?.completionDeliveryReceipt));
|
|
664658
664714
|
this._workboard = updateWorkboardMetadata(dir, {
|
|
664659
664715
|
runId: this.currentArtifactRunId(),
|
|
664660
664716
|
actor,
|
|
@@ -664667,7 +664723,9 @@ ${parts.join("\n")}
|
|
|
664667
664723
|
occurredAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
664668
664724
|
} : void 0
|
|
664669
664725
|
});
|
|
664726
|
+
return workboardTransition;
|
|
664670
664727
|
} catch {
|
|
664728
|
+
return false;
|
|
664671
664729
|
}
|
|
664672
664730
|
}
|
|
664673
664731
|
/** Persist the workboard snapshot before run teardown. */
|
|
@@ -665135,6 +665193,9 @@ runtime_module_sha256=${record.runtimeProvenance.module.sha256 ?? "unknown"}`
|
|
|
665135
665193
|
workboardDir: options2?.workboardDir ?? "",
|
|
665136
665194
|
skipCrossTaskHandoff: options2?.skipCrossTaskHandoff ?? false
|
|
665137
665195
|
};
|
|
665196
|
+
const explicitSessionId = String(options2?.sessionId ?? "").trim();
|
|
665197
|
+
const inheritedSessionId = String(process.env["OMNIUS_SESSION_ID"] ?? "").trim();
|
|
665198
|
+
this._sessionId = explicitSessionId || !options2?.subAgent && inheritedSessionId || `session-${Date.now()}-${crypto.randomUUID()}`;
|
|
665138
665199
|
this.setCanonicalToolExposureContracts(this.options.canonicalToolExposureContracts);
|
|
665139
665200
|
this._adversaryMode = this.options.adversaryMode;
|
|
665140
665201
|
this._streamingExecutor.setConcurrencyResolver((name10, args) => this.resolveToolConcurrencySafe(name10, args));
|
|
@@ -674080,6 +674141,11 @@ ${blob}
|
|
|
674080
674141
|
}
|
|
674081
674142
|
if (!this.isToolAllowedByProfile(tool.name, tool.aliases))
|
|
674082
674143
|
return;
|
|
674144
|
+
tool.bindExecutionScope?.({
|
|
674145
|
+
sessionId: this._sessionId,
|
|
674146
|
+
taskEpoch: this._taskEpoch,
|
|
674147
|
+
ownerId: this._interruptionOwnerId
|
|
674148
|
+
});
|
|
674083
674149
|
const registeredTool = withTaskCompleteCloseoutContract(tool);
|
|
674084
674150
|
this.tools.set(registeredTool.name, registeredTool);
|
|
674085
674151
|
if (registeredTool.name === "generate_image") {
|
|
@@ -675003,8 +675069,8 @@ ${notice}`;
|
|
|
675003
675069
|
_fsWriteFileSync(_pathJoin(dir, `${this._activeRunId || this._sessionId}-epoch-${taskEpoch}.json`), JSON.stringify(archive, null, 2), "utf8");
|
|
675004
675070
|
} catch {
|
|
675005
675071
|
}
|
|
675006
|
-
|
|
675007
|
-
|
|
675072
|
+
writeTodos(this._sessionId, []);
|
|
675073
|
+
this._supersededTodoIds.clear();
|
|
675008
675074
|
this._workboard = null;
|
|
675009
675075
|
}
|
|
675010
675076
|
/**
|
|
@@ -675035,8 +675101,8 @@ ${notice}`;
|
|
|
675035
675101
|
}, null, 2), "utf8");
|
|
675036
675102
|
} catch {
|
|
675037
675103
|
}
|
|
675038
|
-
|
|
675039
|
-
|
|
675104
|
+
writeTodos(this._sessionId, []);
|
|
675105
|
+
this._supersededTodoIds.clear();
|
|
675040
675106
|
this._workboard = null;
|
|
675041
675107
|
this.emit({
|
|
675042
675108
|
type: "status",
|
|
@@ -676867,7 +676933,6 @@ Respond with the assessment and take the selected evidence-backed action.`;
|
|
|
676867
676933
|
this.aborted = false;
|
|
676868
676934
|
this._abortController = new AbortController();
|
|
676869
676935
|
this._turnAbortController = new AbortController();
|
|
676870
|
-
this._sessionId = this.options.sessionId && String(this.options.sessionId) || process.env["OMNIUS_SESSION_ID"] && String(process.env["OMNIUS_SESSION_ID"]) || `session-${Date.now()}`;
|
|
676871
676936
|
this._taskEpoch += 1;
|
|
676872
676937
|
this._contextMemoryTaskRecordId = null;
|
|
676873
676938
|
this._contextMemoryArtifactByPath.clear();
|
|
@@ -676899,10 +676964,8 @@ Respond with the assessment and take the selected evidence-backed action.`;
|
|
|
676899
676964
|
}
|
|
676900
676965
|
this._interruptionLifecycle = null;
|
|
676901
676966
|
} else {
|
|
676902
|
-
|
|
676903
|
-
|
|
676904
|
-
throw new Error(`Run ${recovered.runId} is paused after recovery. Resume that exact generation instead of starting new work.`);
|
|
676905
|
-
}
|
|
676967
|
+
const recoveredPause = recovered.phase === "paused" && recovered.recovered;
|
|
676968
|
+
if (recoveredPause && this._resumeInterrupted) {
|
|
676906
676969
|
this._taskEpoch = recovered.taskEpoch;
|
|
676907
676970
|
this._activeRunId = recovered.runId;
|
|
676908
676971
|
const resumed = lifecycle.requestResume(recovered.owner, "explicit restart recovery requested");
|
|
@@ -676912,6 +676975,11 @@ Respond with the assessment and take the selected evidence-backed action.`;
|
|
|
676912
676975
|
if (!acknowledged.accepted)
|
|
676913
676976
|
throw new Error(acknowledged.reason);
|
|
676914
676977
|
} else {
|
|
676978
|
+
if (recoveredPause) {
|
|
676979
|
+
const superseded = lifecycle.requestStop(recovered.owner, `superseded by a new task submitted after recovery of run ${recovered.runId}`);
|
|
676980
|
+
if (!superseded.accepted)
|
|
676981
|
+
throw new Error(superseded.reason);
|
|
676982
|
+
}
|
|
676915
676983
|
lifecycle.beginRun({
|
|
676916
676984
|
sessionId: this._sessionId,
|
|
676917
676985
|
runId: this._activeRunId,
|
|
@@ -677189,8 +677257,8 @@ Respond with the assessment and take the selected evidence-backed action.`;
|
|
|
677189
677257
|
this._fileRegistry.clear();
|
|
677190
677258
|
this._memexArchive.clear();
|
|
677191
677259
|
this._todoOutputLedger.clear();
|
|
677192
|
-
|
|
677193
|
-
const continuesPriorTask = this._allowImplicitContinuation || this.
|
|
677260
|
+
this._supersededTodoIds.clear();
|
|
677261
|
+
const continuesPriorTask = this._allowImplicitContinuation || this._resumeInterrupted;
|
|
677194
677262
|
if (!continuesPriorTask) {
|
|
677195
677263
|
this._hidePriorSessionTodosForFreshTask(persistentTaskGoal);
|
|
677196
677264
|
}
|
|
@@ -677696,7 +677764,7 @@ ${dynamicProjectContext}`
|
|
|
677696
677764
|
let estimatedTokens = 0;
|
|
677697
677765
|
let toolCallCount = 0;
|
|
677698
677766
|
let substantiveProgressCount = 0;
|
|
677699
|
-
const
|
|
677767
|
+
const convergenceProgress = new ConvergenceProgressTracker();
|
|
677700
677768
|
let completed = false;
|
|
677701
677769
|
let summary = "";
|
|
677702
677770
|
let acceptedTaskCompleteStatus;
|
|
@@ -677765,6 +677833,7 @@ ${dynamicProjectContext}`
|
|
|
677765
677833
|
let consecutiveTextOnly = 0;
|
|
677766
677834
|
let consecutiveThinkOnly = 0;
|
|
677767
677835
|
let loopInterventionCount = 0;
|
|
677836
|
+
let loopCircuitBreakerLatched = false;
|
|
677768
677837
|
const MAX_CONSECUTIVE_TEXT_ONLY = 3;
|
|
677769
677838
|
const MAX_CONSECUTIVE_THINK_ONLY = 6;
|
|
677770
677839
|
let narratedToolCallCount = 0;
|
|
@@ -679485,34 +679554,32 @@ Respond with EXACTLY this structure before your next tool call:
|
|
|
679485
679554
|
nextSelfEval = now2 + selfEvalInterval;
|
|
679486
679555
|
}
|
|
679487
679556
|
const turnsRemaining = this.options.maxTurns - turn;
|
|
679488
|
-
if (this.options.allowTurnExtension && turnsRemaining <= 3 && turnsRemaining > 0 &&
|
|
679557
|
+
if (this.options.allowTurnExtension && turnsRemaining <= 3 && turnsRemaining > 0 && convergenceProgress.hasRecentProgress(turn, 6)) {
|
|
679558
|
+
const extension3 = 30;
|
|
679559
|
+
const progress = convergenceProgress.snapshot(turn);
|
|
679560
|
+
this.options.maxTurns += extension3;
|
|
679561
|
+
this.emit({
|
|
679562
|
+
type: "status",
|
|
679563
|
+
content: `Convergence triage: recent ${progress.lastKind ?? "task"} advancement (${progress.turnsSinceProgress} turn(s) ago) extended the limit by ${extension3} (now ${this.options.maxTurns})`,
|
|
679564
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
679565
|
+
});
|
|
679489
679566
|
const recentOutcomes = this._adversaryToolOutcomes.slice(-6);
|
|
679490
679567
|
const recentSuccesses = recentOutcomes.filter((o2) => o2.succeeded).length;
|
|
679491
679568
|
const uniqueResults = new Set(recentOutcomes.map((o2) => o2.preview.slice(0, 40))).size;
|
|
679492
|
-
const
|
|
679493
|
-
|
|
679494
|
-
|
|
679495
|
-
|
|
679496
|
-
|
|
679497
|
-
|
|
679498
|
-
|
|
679499
|
-
|
|
679500
|
-
|
|
679501
|
-
|
|
679502
|
-
|
|
679503
|
-
|
|
679504
|
-
|
|
679505
|
-
|
|
679506
|
-
content: `Timeout triage: EXTENDED by ${extension3} turns (active session detected)`,
|
|
679507
|
-
adversaryAction: {
|
|
679508
|
-
detection: "none",
|
|
679509
|
-
recentSuccesses,
|
|
679510
|
-
recentFailures: recentOutcomes.length - recentSuccesses,
|
|
679511
|
-
intervention: `Extended maxTurns to ${this.options.maxTurns}`,
|
|
679512
|
-
details: [`Recent outcomes:`, ...detailsLines].join("\n")
|
|
679513
|
-
}
|
|
679514
|
-
});
|
|
679515
|
-
}
|
|
679569
|
+
const detailsLines = recentOutcomes.map((o2) => `- ${o2.tool}: ${o2.succeeded ? "OK" : "ERR"} — ${o2.preview}`);
|
|
679570
|
+
this.emit({
|
|
679571
|
+
type: "debug_adversary",
|
|
679572
|
+
turn,
|
|
679573
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
679574
|
+
content: `Timeout triage: EXTENDED by ${extension3} turns after typed task advancement`,
|
|
679575
|
+
adversaryAction: {
|
|
679576
|
+
detection: "none",
|
|
679577
|
+
recentSuccesses,
|
|
679578
|
+
recentFailures: recentOutcomes.length - recentSuccesses,
|
|
679579
|
+
intervention: `Extended maxTurns to ${this.options.maxTurns}`,
|
|
679580
|
+
details: [`Recent outcomes:`, ...detailsLines].join("\n")
|
|
679581
|
+
}
|
|
679582
|
+
});
|
|
679516
679583
|
}
|
|
679517
679584
|
const steeringBoundary = await this._applySteeringAtSafeBoundary(messages2, turn);
|
|
679518
679585
|
if (steeringBoundary !== "continue") {
|
|
@@ -680824,7 +680891,7 @@ Corrective action: try a different approach first: read relevant files, adjust a
|
|
|
680824
680891
|
turn,
|
|
680825
680892
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
680826
680893
|
});
|
|
680827
|
-
const budgetMsg = `[BUDGET EXHAUSTED] You have used all ${toolBudgets[tc.name]} allowed ${tc.name} calls for the current phase. You ALREADY have enough information from previous calls. DO NOT try to call ${tc.name} again — it will be blocked. ` + (this._todoWriteAvailable() ? `If
|
|
680894
|
+
const budgetMsg = `[BUDGET EXHAUSTED] You have used all ${toolBudgets[tc.name]} allowed ${tc.name} calls for the current phase. You ALREADY have enough information from previous calls. DO NOT try to call ${tc.name} again — it will be blocked. ` + (this._todoWriteAvailable() ? `If the current phase is complete, update the todo truth and take an action from the next phase; the detected context-tree phase transition resets the allowance. ` : `If more phases remain, continue with a different available tool instead of repeating the exhausted one. `) + `If all phases are done: call task_complete with your final summary.`;
|
|
680828
680895
|
this.emit({
|
|
680829
680896
|
type: "tool_result",
|
|
680830
680897
|
toolName: tc.name,
|
|
@@ -683035,22 +683102,6 @@ Evidence: ${evidencePreview}`.slice(0, 500);
|
|
|
683035
683102
|
turn,
|
|
683036
683103
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
683037
683104
|
});
|
|
683038
|
-
const branchCacheHit = result.completionEvidenceMetrics?.["branchCacheHit"] === true;
|
|
683039
|
-
const nonSubstantiveResult = result.noop === true || branchCacheHit || repeatShortCircuit !== null && result.runtimeAuthored === true;
|
|
683040
|
-
if (!nonSubstantiveResult) {
|
|
683041
|
-
const observationFingerprint = [
|
|
683042
|
-
this._buildToolFingerprint(tc.name, tc.arguments ?? {}),
|
|
683043
|
-
result.success ? "ok" : "error",
|
|
683044
|
-
result.beforeHash ?? "",
|
|
683045
|
-
result.afterHash ?? "",
|
|
683046
|
-
realMutationPaths.join(","),
|
|
683047
|
-
this.quickHash(String(result.output ?? result.error ?? result.llmContent ?? ""))
|
|
683048
|
-
].join("|");
|
|
683049
|
-
if (!substantiveProgressFingerprints.has(observationFingerprint)) {
|
|
683050
|
-
substantiveProgressFingerprints.add(observationFingerprint);
|
|
683051
|
-
substantiveProgressCount++;
|
|
683052
|
-
}
|
|
683053
|
-
}
|
|
683054
683105
|
this._taskState.toolCallCount++;
|
|
683055
683106
|
if (realFileMutation) {
|
|
683056
683107
|
this._lastFileWriteTurn = turn;
|
|
@@ -683405,13 +683456,36 @@ ${delegateDir}` : delegateDir;
|
|
|
683405
683456
|
});
|
|
683406
683457
|
} catch {
|
|
683407
683458
|
}
|
|
683408
|
-
this.recordWorkboardToolCall(tc.name, tc.arguments, result.success, result.output || result.error || output2, result, {
|
|
683459
|
+
const workboardTransition = this.recordWorkboardToolCall(tc.name, tc.arguments, result.success, result.output || result.error || output2, result, {
|
|
683409
683460
|
repeatShortCircuit: Boolean(repeatShortCircuit),
|
|
683410
683461
|
focusDecisionKind: focusDecision?.kind,
|
|
683411
683462
|
shellFilesystemMutation,
|
|
683412
683463
|
turn
|
|
683413
683464
|
});
|
|
683414
|
-
|
|
683465
|
+
const progressSignal = classifyAuthoritativeProgress({
|
|
683466
|
+
toolName: tc.name,
|
|
683467
|
+
fingerprint: [
|
|
683468
|
+
toolFingerprint,
|
|
683469
|
+
result.afterHash ?? "",
|
|
683470
|
+
realMutationPaths.join(","),
|
|
683471
|
+
result.completionDeliveryReceipt?.receiptId ?? "",
|
|
683472
|
+
workboardTransition ? "workboard-transition" : ""
|
|
683473
|
+
].join("|"),
|
|
683474
|
+
success: result.success,
|
|
683475
|
+
noop: result.noop === true,
|
|
683476
|
+
runtimeAuthored: result.runtimeAuthored === true,
|
|
683477
|
+
confirmedMutation: realFileMutation || shellFilesystemMutation || result.success === true && result.mutated === true,
|
|
683478
|
+
todoTransition: tc.name === "todo_write" && result.success === true && !this._isTodoWriteNoopResult(result),
|
|
683479
|
+
workboardTransition,
|
|
683480
|
+
assertiveVerifier: tc.name === "shell" && result.success === true && this._shellResultLooksLikeVerification(tc.arguments, result),
|
|
683481
|
+
deliveryReceipt: Boolean(result.completionDeliveryReceipt)
|
|
683482
|
+
});
|
|
683483
|
+
if (convergenceProgress.record(turn, progressSignal)) {
|
|
683484
|
+
substantiveProgressCount = convergenceProgress.snapshot(turn).count;
|
|
683485
|
+
loopInterventionCount = 0;
|
|
683486
|
+
loopCircuitBreakerLatched = false;
|
|
683487
|
+
}
|
|
683488
|
+
if (tc.name === "todo_write" && result.success === true && !this._isTodoWriteNoopResult(result)) {
|
|
683415
683489
|
this._lastTodoWriteTurn = turn;
|
|
683416
683490
|
}
|
|
683417
683491
|
if (tc.name === "file_read" || tc.name === "list_directory" || tc.name === "find_files" || tc.name === "grep_search") {
|
|
@@ -683957,21 +684031,19 @@ ${sr.result.output}`;
|
|
|
683957
684031
|
freqMap.set(key2, (freqMap.get(key2) ?? 0) + 1);
|
|
683958
684032
|
}
|
|
683959
684033
|
const topRepeated = [...freqMap.entries()].sort((a2, b) => b[1] - a2[1]).slice(0, 2).map(([k, v]) => `${k} (${v}x)`).join(", ");
|
|
683960
|
-
loopInterventionCount++;
|
|
683961
684034
|
const loopTier2 = this.options.modelTier ?? "large";
|
|
683962
684035
|
const maxInterventions = loopTier2 === "small" ? 3 : loopTier2 === "medium" ? 5 : 8;
|
|
684036
|
+
loopInterventionCount = Math.min(maxInterventions, loopInterventionCount + 1);
|
|
683963
684037
|
let loopCircuitBreakerFired = false;
|
|
683964
684038
|
const loopInterventionOrdinal = loopInterventionCount;
|
|
683965
|
-
if (loopInterventionCount >= maxInterventions) {
|
|
684039
|
+
if (loopInterventionCount >= maxInterventions && !loopCircuitBreakerLatched) {
|
|
683966
684040
|
loopCircuitBreakerFired = true;
|
|
684041
|
+
loopCircuitBreakerLatched = true;
|
|
683967
684042
|
this.emit({
|
|
683968
684043
|
type: "status",
|
|
683969
|
-
content: `Loop circuit breaker
|
|
684044
|
+
content: `Loop circuit breaker latched after ${loopInterventionCount} interventions; awaiting authoritative task advancement or an agent-selected blocker/clarification decision`,
|
|
683970
684045
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
683971
684046
|
});
|
|
683972
|
-
const partialResults = this._taskState.completedSteps.length > 0 ? this._taskState.completedSteps.join(". ") : `Progress made before loop: ${topRepeated}`;
|
|
683973
|
-
void partialResults;
|
|
683974
|
-
loopInterventionCount = 0;
|
|
683975
684047
|
}
|
|
683976
684048
|
const findings = [];
|
|
683977
684049
|
for (const [key2, entry] of recentToolResults) {
|
|
@@ -684315,7 +684387,9 @@ Your most recent tool calls SUCCEEDED. If the task is complete, call task_comple
|
|
|
684315
684387
|
}
|
|
684316
684388
|
}
|
|
684317
684389
|
const todosNow = this.readSessionTodos() || [];
|
|
684318
|
-
const
|
|
684390
|
+
const parentIds = new Set(todosNow.map((todo) => todo.parentId).filter((id2) => Boolean(id2)));
|
|
684391
|
+
const leavesNow = todosNow.filter((todo) => !parentIds.has(todo.id));
|
|
684392
|
+
const completedNow = leavesNow.filter((t2) => t2.status === "completed").length;
|
|
684319
684393
|
stagnationWindow.push({
|
|
684320
684394
|
turn,
|
|
684321
684395
|
ts: Date.now(),
|
|
@@ -684326,6 +684400,40 @@ Your most recent tool calls SUCCEEDED. If the task is complete, call task_comple
|
|
|
684326
684400
|
});
|
|
684327
684401
|
} catch {
|
|
684328
684402
|
}
|
|
684403
|
+
try {
|
|
684404
|
+
const todosNow = this.readSessionTodos() || [];
|
|
684405
|
+
const parentIds = new Set(todosNow.map((todo) => todo.parentId).filter((id2) => Boolean(id2)));
|
|
684406
|
+
const leaves = todosNow.filter((todo) => !parentIds.has(todo.id));
|
|
684407
|
+
const openLeaves = leaves.filter((todo) => todo.status !== "completed");
|
|
684408
|
+
const configuredThreshold = Number.parseInt(process.env["OMNIUS_CONVERGENCE_REVIEW_TURNS"] ?? "", 10);
|
|
684409
|
+
const defaultThreshold = this.options.modelTier === "small" ? 6 : this.options.modelTier === "medium" ? 8 : 10;
|
|
684410
|
+
const thresholdTurns = Number.isFinite(configuredThreshold) && configuredThreshold > 0 ? configuredThreshold : defaultThreshold;
|
|
684411
|
+
if (convergenceProgress.shouldLatchReview({
|
|
684412
|
+
turn,
|
|
684413
|
+
openLeafCount: openLeaves.length,
|
|
684414
|
+
thresholdTurns
|
|
684415
|
+
})) {
|
|
684416
|
+
const progress = convergenceProgress.snapshot(turn);
|
|
684417
|
+
const activeLeaf = openLeaves.find((todo) => todo.status === "in_progress") ?? openLeaves[0];
|
|
684418
|
+
const review = [
|
|
684419
|
+
"[CONVERGENCE REVIEW REQUIRED]",
|
|
684420
|
+
`The task leaf frontier has not advanced for ${progress.turnsSinceProgress} turns.`,
|
|
684421
|
+
`Leaf progress: ${leaves.length - openLeaves.length}/${leaves.length}.`,
|
|
684422
|
+
activeLeaf ? `Current leaf: ${activeLeaf.id} (${activeLeaf.status}) ${activeLeaf.content}` : "Current leaf: none.",
|
|
684423
|
+
"Reads, searches, and changed error text are evidence, not task advancement.",
|
|
684424
|
+
"Choose the next action from current evidence. You may continue with one specific action and its expected evidence, update or block the leaf truthfully, ask for missing input, or call task_complete only if completion is already proven.",
|
|
684425
|
+
"This review is advisory. The host does not infer the decision for you."
|
|
684426
|
+
].join("\n");
|
|
684427
|
+
messages2.push({ role: "system", content: review });
|
|
684428
|
+
this.emit({
|
|
684429
|
+
type: "status",
|
|
684430
|
+
content: `Convergence review latched at leaf progress ${leaves.length - openLeaves.length}/${leaves.length} after ${progress.turnsSinceProgress} turns without authoritative advancement`,
|
|
684431
|
+
turn,
|
|
684432
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
684433
|
+
});
|
|
684434
|
+
}
|
|
684435
|
+
} catch {
|
|
684436
|
+
}
|
|
684329
684437
|
}
|
|
684330
684438
|
let prevCycleSubstantiveProgress = substantiveProgressCount;
|
|
684331
684439
|
while (!completed && !this.aborted && !this._completionIncompleteVerification && this.options.bruteForce && bruteForceCycle < this.options.bruteForceMaxCycles) {
|
|
@@ -684334,7 +684442,7 @@ Your most recent tool calls SUCCEEDED. If the task is complete, call task_comple
|
|
|
684334
684442
|
if (bruteForceCycle > 1 && substantiveProgressCount === prevCycleSubstantiveProgress) {
|
|
684335
684443
|
this.emit({
|
|
684336
684444
|
type: "status",
|
|
684337
|
-
content: `Stopping re-engagement — cycle ${bruteForceCycle - 1} produced no
|
|
684445
|
+
content: `Stopping re-engagement — cycle ${bruteForceCycle - 1} produced no authoritative mutation, todo/workboard transition, verifier receipt, or delivery receipt (${toolCallCount} attempted tool calls; ${substantiveProgressCount} authoritative advancements).`,
|
|
684338
684446
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
684339
684447
|
});
|
|
684340
684448
|
break;
|
|
@@ -684344,7 +684452,7 @@ Your most recent tool calls SUCCEEDED. If the task is complete, call task_comple
|
|
|
684344
684452
|
consecutiveThinkOnly = 0;
|
|
684345
684453
|
this.emit({
|
|
684346
684454
|
type: "status",
|
|
684347
|
-
content: `Re-engaging — cycle ${bruteForceCycle} (${totalTurns} turns, ${toolCallCount} attempted calls / ${substantiveProgressCount}
|
|
684455
|
+
content: `Re-engaging — cycle ${bruteForceCycle} (${totalTurns} turns, ${toolCallCount} attempted calls / ${substantiveProgressCount} authoritative advancements)`,
|
|
684348
684456
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
684349
684457
|
});
|
|
684350
684458
|
this._reg61CooldownUntilTurn = -1;
|
|
@@ -702517,6 +702625,7 @@ __export(dist_exports3, {
|
|
|
702517
702625
|
CoherenceGate: () => CoherenceGate,
|
|
702518
702626
|
ContentAddressedArtifactStore: () => ContentAddressedArtifactStore,
|
|
702519
702627
|
ConvergenceBreaker: () => ConvergenceBreaker,
|
|
702628
|
+
ConvergenceProgressTracker: () => ConvergenceProgressTracker,
|
|
702520
702629
|
CoordinatorManager: () => CoordinatorManager,
|
|
702521
702630
|
CostTracker: () => CostTracker,
|
|
702522
702631
|
DEFAULT_ADAPTIVE_POLICY_CONFIG: () => DEFAULT_ADAPTIVE_POLICY_CONFIG,
|
|
@@ -702641,6 +702750,7 @@ __export(dist_exports3, {
|
|
|
702641
702750
|
checkMilestoneComplete: () => checkMilestoneComplete,
|
|
702642
702751
|
chooseCheapModelRoute: () => chooseCheapModelRoute,
|
|
702643
702752
|
claimAssertion: () => claimAssertion,
|
|
702753
|
+
classifyAuthoritativeProgress: () => classifyAuthoritativeProgress,
|
|
702644
702754
|
classifyBreadth: () => classifyBreadth,
|
|
702645
702755
|
classifyClaimKind: () => classifyClaimKind,
|
|
702646
702756
|
classifyCompletionClaim: () => classifyCompletionClaim,
|
|
@@ -702999,6 +703109,7 @@ var init_dist8 = __esm({
|
|
|
702999
703109
|
init_mergeRunner();
|
|
703000
703110
|
init_retryController();
|
|
703001
703111
|
init_agenticRunner();
|
|
703112
|
+
init_convergence_progress();
|
|
703002
703113
|
init_inference_pressure();
|
|
703003
703114
|
init_canonical_context_projection();
|
|
703004
703115
|
init_runtime_rollout();
|
|
@@ -715497,6 +715608,9 @@ function adaptExecutionTool(tool, options2 = {}) {
|
|
|
715497
715608
|
return mapExecutionToolResult(result);
|
|
715498
715609
|
}
|
|
715499
715610
|
};
|
|
715611
|
+
if (typeof tool.bindExecutionScope === "function") {
|
|
715612
|
+
adapted.bindExecutionScope = (scope) => tool.bindExecutionScope(scope);
|
|
715613
|
+
}
|
|
715500
715614
|
if (typeof tool.cancel === "function") {
|
|
715501
715615
|
adapted.cancel = () => tool.cancel();
|
|
715502
715616
|
}
|
|
@@ -731239,6 +731353,7 @@ __export(omnius_directory_exports, {
|
|
|
731239
731353
|
appendCompactionAudit: () => appendCompactionAudit,
|
|
731240
731354
|
buildContextRestorePrompt: () => buildContextRestorePrompt,
|
|
731241
731355
|
buildContextRestoreSnapshot: () => buildContextRestoreSnapshot,
|
|
731356
|
+
buildExactContinuationSnapshot: () => buildExactContinuationSnapshot,
|
|
731242
731357
|
buildHandoffPrompt: () => buildHandoffPrompt,
|
|
731243
731358
|
cleanPromptForDiary: () => cleanPromptForDiary,
|
|
731244
731359
|
clearTaskHandoff: () => clearTaskHandoff,
|
|
@@ -731260,6 +731375,8 @@ __export(omnius_directory_exports, {
|
|
|
731260
731375
|
loadSessionHistory: () => loadSessionHistory,
|
|
731261
731376
|
loadTuiSessionState: () => loadTuiSessionState,
|
|
731262
731377
|
loadUsageHistory: () => loadUsageHistory,
|
|
731378
|
+
pendingTaskMatchesInterruptionIdentity: () => pendingTaskMatchesInterruptionIdentity,
|
|
731379
|
+
pendingTaskMatchesRunningInterruption: () => pendingTaskMatchesRunningInterruption,
|
|
731263
731380
|
readIndexData: () => readIndexData,
|
|
731264
731381
|
readIndexMeta: () => readIndexMeta,
|
|
731265
731382
|
readTaskHandoff: () => readTaskHandoff2,
|
|
@@ -731659,21 +731776,64 @@ function loadRecentSessions(repoRoot, limit2 = 5) {
|
|
|
731659
731776
|
return [];
|
|
731660
731777
|
}
|
|
731661
731778
|
}
|
|
731779
|
+
function isValidPendingTask(value2, repoRoot) {
|
|
731780
|
+
if (!value2 || typeof value2 !== "object") return false;
|
|
731781
|
+
const task = value2;
|
|
731782
|
+
if (typeof task.prompt !== "string" || !task.prompt.trim() || typeof task.progressSummary !== "string" || !Array.isArray(task.filesModified) || !task.filesModified.every((item) => typeof item === "string") || typeof task.bruteForce !== "boolean" || typeof task.savedAt !== "string" || !Number.isFinite(Date.parse(task.savedAt)) || typeof task.toolCallCount !== "number" || !Number.isFinite(task.toolCallCount) || task.toolCallCount < 0) {
|
|
731783
|
+
return false;
|
|
731784
|
+
}
|
|
731785
|
+
if (task.schema !== void 0 && task.schema !== "omnius.pending-task.v2") {
|
|
731786
|
+
return false;
|
|
731787
|
+
}
|
|
731788
|
+
if (task.projectRoot !== void 0 && resolve77(task.projectRoot) !== resolve77(repoRoot)) {
|
|
731789
|
+
return false;
|
|
731790
|
+
}
|
|
731791
|
+
if (task.interruption !== void 0) {
|
|
731792
|
+
const interruption = task.interruption;
|
|
731793
|
+
if (typeof interruption.sessionId !== "string" || !interruption.sessionId.trim() || typeof interruption.runId !== "string" || !interruption.runId.trim() || !Number.isInteger(interruption.taskEpoch) || interruption.taskEpoch < 1 || !Number.isInteger(interruption.ownerGeneration) || interruption.ownerGeneration < 1 || interruption.phase !== "pausing" && interruption.phase !== "paused") {
|
|
731794
|
+
return false;
|
|
731795
|
+
}
|
|
731796
|
+
}
|
|
731797
|
+
if (task.resumeOnStartup === true && !task.interruption) return false;
|
|
731798
|
+
return true;
|
|
731799
|
+
}
|
|
731800
|
+
function pendingTaskMatchesRunningInterruption(pendingTask, candidate) {
|
|
731801
|
+
return candidate?.phase === "running" && pendingTaskMatchesInterruptionIdentity(pendingTask, candidate);
|
|
731802
|
+
}
|
|
731803
|
+
function pendingTaskMatchesInterruptionIdentity(pendingTask, candidate) {
|
|
731804
|
+
const expected = pendingTask.interruption;
|
|
731805
|
+
return Boolean(
|
|
731806
|
+
expected && candidate && candidate.sessionId === expected.sessionId && candidate.runId === expected.runId && candidate.taskEpoch === expected.taskEpoch && candidate.ownerGeneration === expected.ownerGeneration
|
|
731807
|
+
);
|
|
731808
|
+
}
|
|
731662
731809
|
function savePendingTask(repoRoot, task) {
|
|
731663
731810
|
const historyDir = join162(repoRoot, OMNIUS_DIR2, "history");
|
|
731664
731811
|
mkdirSync95(historyDir, { recursive: true });
|
|
731665
|
-
|
|
731666
|
-
|
|
731667
|
-
|
|
731668
|
-
|
|
731669
|
-
|
|
731812
|
+
const filePath = join162(historyDir, PENDING_TASK_FILE);
|
|
731813
|
+
const tempPath = `${filePath}.tmp-${process.pid}`;
|
|
731814
|
+
const checkpoint = {
|
|
731815
|
+
...task,
|
|
731816
|
+
schema: "omnius.pending-task.v2",
|
|
731817
|
+
projectRoot: resolve77(repoRoot)
|
|
731818
|
+
};
|
|
731819
|
+
const payload = JSON.stringify(checkpoint, null, 2) + "\n";
|
|
731820
|
+
writeFileSync85(tempPath, payload, "utf-8");
|
|
731821
|
+
try {
|
|
731822
|
+
renameSync30(tempPath, filePath);
|
|
731823
|
+
} catch {
|
|
731824
|
+
writeFileSync85(filePath, payload, "utf-8");
|
|
731825
|
+
try {
|
|
731826
|
+
unlinkSync37(tempPath);
|
|
731827
|
+
} catch {
|
|
731828
|
+
}
|
|
731829
|
+
}
|
|
731670
731830
|
}
|
|
731671
731831
|
function loadPendingTask(repoRoot) {
|
|
731672
731832
|
const filePath = join162(repoRoot, OMNIUS_DIR2, "history", PENDING_TASK_FILE);
|
|
731673
731833
|
try {
|
|
731674
731834
|
if (!existsSync148(filePath)) return null;
|
|
731675
731835
|
const data = JSON.parse(readFileSync124(filePath, "utf-8"));
|
|
731676
|
-
return data;
|
|
731836
|
+
return isValidPendingTask(data, repoRoot) ? data : null;
|
|
731677
731837
|
} catch {
|
|
731678
731838
|
return null;
|
|
731679
731839
|
}
|
|
@@ -732047,6 +732207,13 @@ function saveSessionContext(repoRoot, entry) {
|
|
|
732047
732207
|
ctx3.entries.push(normalizedEntry);
|
|
732048
732208
|
}
|
|
732049
732209
|
}
|
|
732210
|
+
ctx3.entries = ctx3.entries.map((item, index) => ({ item, index })).sort((a2, b) => {
|
|
732211
|
+
const left = Date.parse(a2.item.savedAt || "");
|
|
732212
|
+
const right = Date.parse(b.item.savedAt || "");
|
|
732213
|
+
const leftTime = Number.isFinite(left) ? left : 0;
|
|
732214
|
+
const rightTime = Number.isFinite(right) ? right : 0;
|
|
732215
|
+
return leftTime - rightTime || a2.index - b.index;
|
|
732216
|
+
}).map(({ item }) => item);
|
|
732050
732217
|
if (ctx3.entries.length > ctx3.maxEntries) {
|
|
732051
732218
|
ctx3.entries = ctx3.entries.slice(-ctx3.maxEntries);
|
|
732052
732219
|
}
|
|
@@ -732180,80 +732347,12 @@ function isManualSessionEntry(entry) {
|
|
|
732180
732347
|
const summary = normalizeSessionText(entry.summary || entry.assistantResponse, 160).toLowerCase();
|
|
732181
732348
|
return entry.source === "manual" || task === "(manual save)" || entry.toolCalls === 0 && summary.startsWith("manual context save");
|
|
732182
732349
|
}
|
|
732183
|
-
function isDeicticContinuationGoal(goal) {
|
|
732184
|
-
const tokens3 = normalizeSessionText(cleanPromptForDiary(goal), 180).toLowerCase().replace(/[^a-z0-9]+/g, " ").split(/\s+/).filter(Boolean);
|
|
732185
|
-
if (tokens3.length === 0 || tokens3.length > 14) return false;
|
|
732186
|
-
const hasResumeVerb = tokens3.some(
|
|
732187
|
-
(token) => token === "continue" || token === "resume" || token === "proceed" || token === "complete" || token === "finish"
|
|
732188
|
-
);
|
|
732189
|
-
if (!hasResumeVerb) return false;
|
|
732190
|
-
const deicticCount = tokens3.filter((token) => DEICTIC_CONTINUATION_TERMS.has(token)).length;
|
|
732191
|
-
return deicticCount / tokens3.length >= 0.7;
|
|
732192
|
-
}
|
|
732193
732350
|
function readRestoreWorkboard(repoRoot, runId) {
|
|
732194
732351
|
if (!runId) return null;
|
|
732195
732352
|
return readJsonOrNull(
|
|
732196
732353
|
join162(repoRoot, OMNIUS_DIR2, "workboards", runId, "active.json")
|
|
732197
732354
|
);
|
|
732198
732355
|
}
|
|
732199
|
-
function scoreRestoreLedger(ledger, workboard) {
|
|
732200
|
-
const status = ledger.status || "open";
|
|
732201
|
-
if (status === "approved") return -1e3;
|
|
732202
|
-
const evidence = ledger.evidence ?? [];
|
|
732203
|
-
const unresolvedCount = ledger.unresolved?.length ?? 0;
|
|
732204
|
-
const activeCards = (workboard?.cards ?? []).filter(
|
|
732205
|
-
(card) => card.status === "open" || card.status === "in_progress" || card.status === "needs_changes" || card.status === "blocked"
|
|
732206
|
-
).length;
|
|
732207
|
-
const mutationTools = /* @__PURE__ */ new Set(["file_edit", "file_patch", "batch_edit", "file_write"]);
|
|
732208
|
-
const mutationEvidence = evidence.filter((item) => mutationTools.has(item.toolName || "")).length;
|
|
732209
|
-
const failedMutationEvidence = evidence.filter(
|
|
732210
|
-
(item) => mutationTools.has(item.toolName || "") && item.success === false
|
|
732211
|
-
).length;
|
|
732212
|
-
const targetPathEvidence = evidence.filter((item) => (item.targetPaths?.length ?? 0) > 0).length;
|
|
732213
|
-
const blockedEvidence = evidence.filter((item) => {
|
|
732214
|
-
const summary = String(item.summary ?? "").toLowerCase();
|
|
732215
|
-
return summary.includes("[focus supervisor block]") || summary.includes("stale") || summary.includes("blocked");
|
|
732216
|
-
}).length;
|
|
732217
|
-
let score = 0;
|
|
732218
|
-
if (status === "open") score += 10;
|
|
732219
|
-
else if (status === "incomplete_verification") score += 18;
|
|
732220
|
-
else if (status === "request_changes" || status === "blocked") score += 16;
|
|
732221
|
-
else score += 4;
|
|
732222
|
-
score += Math.min(evidence.length, 20);
|
|
732223
|
-
score += Math.min(unresolvedCount, 10) * 4;
|
|
732224
|
-
score += Math.min(activeCards, 8) * 3;
|
|
732225
|
-
score += Math.min(mutationEvidence, 8) * 5;
|
|
732226
|
-
score += Math.min(failedMutationEvidence, 8) * 3;
|
|
732227
|
-
score += Math.min(targetPathEvidence, 6) * 2;
|
|
732228
|
-
score += Math.min(blockedEvidence, 6) * 2;
|
|
732229
|
-
const goal = normalizeSessionText(ledger.goal, 260);
|
|
732230
|
-
if (goal.length >= 80) score += 5;
|
|
732231
|
-
if (isDeicticContinuationGoal(goal) && mutationEvidence === 0 && unresolvedCount === 0 && activeCards === 0) {
|
|
732232
|
-
score -= 25;
|
|
732233
|
-
}
|
|
732234
|
-
return score;
|
|
732235
|
-
}
|
|
732236
|
-
function selectActiveTaskAnchor(repoRoot) {
|
|
732237
|
-
const ledgerDir = join162(repoRoot, OMNIUS_DIR2, "completion-ledgers");
|
|
732238
|
-
try {
|
|
732239
|
-
if (!existsSync148(ledgerDir)) return null;
|
|
732240
|
-
const candidates = readdirSync48(ledgerDir).filter((name10) => name10.endsWith(".json")).map((name10) => {
|
|
732241
|
-
const filePath = join162(ledgerDir, name10);
|
|
732242
|
-
const ledger = readJsonOrNull(filePath);
|
|
732243
|
-
if (!ledger || !ledger.goal) return null;
|
|
732244
|
-
const runId = ledger.runId || name10.replace(/\.json$/, "");
|
|
732245
|
-
const workboard = readRestoreWorkboard(repoRoot, runId);
|
|
732246
|
-
const score = scoreRestoreLedger(ledger, workboard);
|
|
732247
|
-
const mtimeMs = statSync58(filePath).mtimeMs;
|
|
732248
|
-
return { ledger: { ...ledger, runId }, workboard, score, mtimeMs };
|
|
732249
|
-
}).filter((item) => Boolean(item));
|
|
732250
|
-
candidates.sort((a2, b) => b.score - a2.score || b.mtimeMs - a2.mtimeMs);
|
|
732251
|
-
const selected = candidates.find((candidate) => candidate.score >= 18);
|
|
732252
|
-
return selected ?? null;
|
|
732253
|
-
} catch {
|
|
732254
|
-
return null;
|
|
732255
|
-
}
|
|
732256
|
-
}
|
|
732257
732356
|
function formatActiveTaskAnchor(selected) {
|
|
732258
732357
|
const ledger = selected.ledger;
|
|
732259
732358
|
const evidence = ledger.evidence ?? [];
|
|
@@ -732285,31 +732384,9 @@ ${evidenceLines.join("\n")}
|
|
|
732285
732384
|
${unresolvedLines.join("\n")}
|
|
732286
732385
|
` : "") + (boardCards.length > 0 ? `Active workboard cards:
|
|
732287
732386
|
${boardCards.join("\n")}
|
|
732288
|
-
` : "") + `Continuation rule:
|
|
732387
|
+
` : "") + `Continuation rule: this frontier is active only because its exact durable interruption identity was selected.
|
|
732289
732388
|
</active-task-anchor>`;
|
|
732290
732389
|
}
|
|
732291
|
-
function uniqueSessionIds(ids) {
|
|
732292
|
-
const seen = /* @__PURE__ */ new Set();
|
|
732293
|
-
const out = [];
|
|
732294
|
-
for (const raw of ids) {
|
|
732295
|
-
const id2 = String(raw || "").trim();
|
|
732296
|
-
if (!id2 || seen.has(id2)) continue;
|
|
732297
|
-
seen.add(id2);
|
|
732298
|
-
out.push(id2);
|
|
732299
|
-
}
|
|
732300
|
-
return out;
|
|
732301
|
-
}
|
|
732302
|
-
function collectRestoreSessionIds(ctx3, activeTask, historySessionId) {
|
|
732303
|
-
const entries2 = ctx3?.entries ?? [];
|
|
732304
|
-
const usefulEntries = entries2.filter((entry) => !isManualSessionEntry(entry));
|
|
732305
|
-
const chronological = usefulEntries.length > 0 ? usefulEntries : entries2;
|
|
732306
|
-
return uniqueSessionIds([
|
|
732307
|
-
activeTask?.ledger.runId,
|
|
732308
|
-
...[...chronological].reverse().map((entry) => entry.sessionId),
|
|
732309
|
-
...[...entries2].reverse().map((entry) => entry.sessionId),
|
|
732310
|
-
historySessionId
|
|
732311
|
-
]);
|
|
732312
|
-
}
|
|
732313
732390
|
function childMapForTodos(todos) {
|
|
732314
732391
|
const byId = new Set(todos.map((todo) => todo.id));
|
|
732315
732392
|
const byParent = /* @__PURE__ */ new Map();
|
|
@@ -732382,20 +732459,8 @@ ${treeLines.join("\n")}${omitted > 0 ? `
|
|
|
732382
732459
|
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.
|
|
732383
732460
|
</restored-todo-state>`;
|
|
732384
732461
|
}
|
|
732385
|
-
function
|
|
732386
|
-
|
|
732387
|
-
const todos = readTodos(sessionId).filter((todo) => todo && todo.id && todo.content);
|
|
732388
|
-
if (todos.length === 0) continue;
|
|
732389
|
-
return {
|
|
732390
|
-
sessionId,
|
|
732391
|
-
todos,
|
|
732392
|
-
block: buildRestoredTodoBlock(sessionId, todos)
|
|
732393
|
-
};
|
|
732394
|
-
}
|
|
732395
|
-
return null;
|
|
732396
|
-
}
|
|
732397
|
-
function buildRestoreHistoryAnchor(repoRoot) {
|
|
732398
|
-
const [latest] = listSessions(repoRoot);
|
|
732462
|
+
function buildRestoreHistoryAnchor(repoRoot, exactSessionId) {
|
|
732463
|
+
const latest = exactSessionId ? listSessions(repoRoot).find((entry) => entry.id === exactSessionId) : listSessions(repoRoot)[0];
|
|
732399
732464
|
if (!latest?.id) return null;
|
|
732400
732465
|
const lines = loadSessionHistory(repoRoot, latest.id) ?? [];
|
|
732401
732466
|
const recordedLineCount = lines.filter((line) => String(line ?? "").trim()).length;
|
|
@@ -732411,6 +732476,76 @@ Recall contract: do not replay or ingest the transcript wholesale. Use the struc
|
|
|
732411
732476
|
</restored-interface-history>`;
|
|
732412
732477
|
return { sessionId: latest.id, path: path16, lineCount: recordedLineCount, block };
|
|
732413
732478
|
}
|
|
732479
|
+
function buildExactContinuationSnapshot(repoRoot, pendingTask) {
|
|
732480
|
+
const identity3 = pendingTask.interruption;
|
|
732481
|
+
if (!identity3) return null;
|
|
732482
|
+
if (pendingTask.projectRoot && resolve77(pendingTask.projectRoot) !== resolve77(repoRoot)) {
|
|
732483
|
+
return null;
|
|
732484
|
+
}
|
|
732485
|
+
const ledgerPath2 = join162(
|
|
732486
|
+
repoRoot,
|
|
732487
|
+
OMNIUS_DIR2,
|
|
732488
|
+
"completion-ledgers",
|
|
732489
|
+
`${identity3.runId}.json`
|
|
732490
|
+
);
|
|
732491
|
+
const rawLedger = readJsonOrNull(ledgerPath2);
|
|
732492
|
+
const ledger = rawLedger && (!rawLedger.runId || rawLedger.runId === identity3.runId) && (!rawLedger.taskEpoch || rawLedger.taskEpoch === identity3.taskEpoch) ? { ...rawLedger, runId: identity3.runId } : null;
|
|
732493
|
+
const rawWorkboard = readRestoreWorkboard(repoRoot, identity3.runId);
|
|
732494
|
+
const workboard = rawWorkboard && (!rawWorkboard.runId || rawWorkboard.runId === identity3.runId) && (!rawWorkboard.taskEpoch || rawWorkboard.taskEpoch === identity3.taskEpoch) ? rawWorkboard : null;
|
|
732495
|
+
const activeTaskAnchor = ledger ? formatActiveTaskAnchor({ ledger, workboard }) : null;
|
|
732496
|
+
const exactTodos = readTodos(identity3.sessionId).filter(
|
|
732497
|
+
(todo) => todo && todo.id && todo.content
|
|
732498
|
+
);
|
|
732499
|
+
const restoredTodos = exactTodos.length > 0 ? {
|
|
732500
|
+
sessionId: identity3.sessionId,
|
|
732501
|
+
todos: exactTodos,
|
|
732502
|
+
block: buildRestoredTodoBlock(identity3.sessionId, exactTodos)
|
|
732503
|
+
} : null;
|
|
732504
|
+
const historyAnchor = buildRestoreHistoryAnchor(repoRoot, identity3.sessionId);
|
|
732505
|
+
const contextEntries = (loadSessionContext(repoRoot)?.entries ?? []).filter((entry) => entry.sessionId === identity3.sessionId).sort((a2, b) => a2.savedAt.localeCompare(b.savedAt)).slice(-4);
|
|
732506
|
+
const contextLines = contextEntries.map((entry) => {
|
|
732507
|
+
const status = entry.completed ? "done" : "partial";
|
|
732508
|
+
const outcome = normalizeSessionText(
|
|
732509
|
+
entry.assistantResponse || entry.summary || entry.task,
|
|
732510
|
+
220
|
|
732511
|
+
);
|
|
732512
|
+
return `- [${status}] ${outcome}`;
|
|
732513
|
+
});
|
|
732514
|
+
const progressLines = [
|
|
732515
|
+
`<exact-continuation schema="omnius.exact-continuation.v1">`,
|
|
732516
|
+
`project_root=${resolve77(repoRoot)}`,
|
|
732517
|
+
`session_id=${identity3.sessionId}`,
|
|
732518
|
+
`run_id=${identity3.runId}`,
|
|
732519
|
+
`task_epoch=${identity3.taskEpoch}`,
|
|
732520
|
+
`owner_generation=${identity3.ownerGeneration}`,
|
|
732521
|
+
`original_user_goal_json=${JSON.stringify(pendingTask.prompt)}`,
|
|
732522
|
+
pendingTask.progressSummary ? `checkpoint_progress=${normalizeSessionText(pendingTask.progressSummary, 500)}` : null,
|
|
732523
|
+
pendingTask.filesModified.length > 0 ? `checkpoint_files=${pendingTask.filesModified.slice(0, 20).map((item) => normalizeSessionText(item, 160)).join(", ")}` : null,
|
|
732524
|
+
"Authority contract: continue only this interrupted run. Treat all other project history as historical orientation, not an active frontier.",
|
|
732525
|
+
activeTaskAnchor,
|
|
732526
|
+
contextLines.length > 0 ? `Same-session chronology:
|
|
732527
|
+
${contextLines.join("\n")}` : null,
|
|
732528
|
+
restoredTodos?.block,
|
|
732529
|
+
historyAnchor?.block,
|
|
732530
|
+
`</exact-continuation>`
|
|
732531
|
+
].filter((line) => Boolean(line));
|
|
732532
|
+
return {
|
|
732533
|
+
prompt: progressLines.join("\n"),
|
|
732534
|
+
sourceSessionId: identity3.sessionId,
|
|
732535
|
+
todoSessionId: restoredTodos?.sessionId,
|
|
732536
|
+
todoCount: restoredTodos?.todos.length ?? 0,
|
|
732537
|
+
historySessionId: historyAnchor?.sessionId,
|
|
732538
|
+
historyPath: historyAnchor?.path,
|
|
732539
|
+
historyLineCount: historyAnchor?.lineCount,
|
|
732540
|
+
selection: {
|
|
732541
|
+
kind: "exact_interruption",
|
|
732542
|
+
sessionId: identity3.sessionId,
|
|
732543
|
+
runId: identity3.runId,
|
|
732544
|
+
taskEpoch: identity3.taskEpoch,
|
|
732545
|
+
ownerGeneration: identity3.ownerGeneration
|
|
732546
|
+
}
|
|
732547
|
+
};
|
|
732548
|
+
}
|
|
732414
732549
|
function appendRestoreBlocks(base3, blocks) {
|
|
732415
732550
|
return [base3, ...blocks].filter((part) => part && part.trim()).join("\n\n");
|
|
732416
732551
|
}
|
|
@@ -732441,53 +732576,24 @@ function sessionContextToHistoryBoxData(ctx3, title = "Session History") {
|
|
|
732441
732576
|
}
|
|
732442
732577
|
function buildContextRestoreSnapshot(repoRoot) {
|
|
732443
732578
|
const ctx3 = loadSessionContext(repoRoot);
|
|
732444
|
-
const handoffPrompt = buildHandoffPrompt(repoRoot);
|
|
732445
|
-
const activeTask = selectActiveTaskAnchor(repoRoot);
|
|
732446
|
-
const activeTaskAnchor = activeTask ? formatActiveTaskAnchor(activeTask) : null;
|
|
732447
732579
|
const historyAnchor = buildRestoreHistoryAnchor(repoRoot);
|
|
732448
|
-
const
|
|
732449
|
-
|
|
732450
|
-
|
|
732451
|
-
|
|
732452
|
-
|
|
732453
|
-
const usefulEntries2 = (ctx3?.entries ?? []).filter((entry) => !isManualSessionEntry(entry));
|
|
732454
|
-
const baseCtx = ctx3 && ctx3.entries.length > 0 ? `
|
|
732455
|
-
|
|
732456
|
-
<session-recap>
|
|
732457
|
-
Recent tasks: ${(usefulEntries2.length > 0 ? usefulEntries2 : ctx3.entries).slice(-3).map(
|
|
732458
|
-
(e2) => `[${e2.completed ? "done" : "partial"}] ${normalizeSessionText(e2.summary || e2.task, 80)}`
|
|
732459
|
-
).join(", ")}
|
|
732460
|
-
</session-recap>` : "";
|
|
732461
|
-
const prompt2 = appendRestoreBlocks(
|
|
732462
|
-
safeHandoffPrompt + (activeTaskAnchor ? `
|
|
732463
|
-
|
|
732464
|
-
${activeTaskAnchor}` : "") + baseCtx,
|
|
732465
|
-
[restoredTodos?.block, historyAnchor?.block]
|
|
732466
|
-
);
|
|
732467
|
-
return {
|
|
732468
|
-
prompt: prompt2,
|
|
732469
|
-
sourceSessionId,
|
|
732470
|
-
todoSessionId: restoredTodos?.sessionId,
|
|
732471
|
-
todoCount: restoredTodos?.todos.length ?? 0,
|
|
732472
|
-
historySessionId: historyAnchor?.sessionId,
|
|
732473
|
-
historyPath: historyAnchor?.path,
|
|
732474
|
-
historyLineCount: historyAnchor?.lineCount
|
|
732475
|
-
};
|
|
732476
|
-
}
|
|
732580
|
+
const usefulEntries = (ctx3?.entries ?? []).filter(
|
|
732581
|
+
(entry) => !isManualSessionEntry(entry)
|
|
732582
|
+
);
|
|
732583
|
+
const chronological = usefulEntries.length > 0 ? usefulEntries : ctx3?.entries ?? [];
|
|
732584
|
+
const sourceSessionId = chronological.at(-1)?.sessionId ?? historyAnchor?.sessionId;
|
|
732477
732585
|
if (!ctx3 || ctx3.entries.length === 0) {
|
|
732478
|
-
const prompt2 = appendRestoreBlocks(
|
|
732586
|
+
const prompt2 = appendRestoreBlocks("", [historyAnchor?.block]);
|
|
732479
732587
|
if (!prompt2.trim()) return null;
|
|
732480
732588
|
return {
|
|
732481
732589
|
prompt: prompt2,
|
|
732482
732590
|
sourceSessionId,
|
|
732483
|
-
|
|
732484
|
-
todoCount: restoredTodos?.todos.length ?? 0,
|
|
732591
|
+
todoCount: 0,
|
|
732485
732592
|
historySessionId: historyAnchor?.sessionId,
|
|
732486
732593
|
historyPath: historyAnchor?.path,
|
|
732487
732594
|
historyLineCount: historyAnchor?.lineCount
|
|
732488
732595
|
};
|
|
732489
732596
|
}
|
|
732490
|
-
const usefulEntries = ctx3.entries.filter((entry) => !isManualSessionEntry(entry));
|
|
732491
732597
|
const recent = (usefulEntries.length > 0 ? usefulEntries : ctx3.entries).slice(-20);
|
|
732492
732598
|
const chronology = recent.map((e2) => {
|
|
732493
732599
|
const status = e2.completed ? "done" : "partial";
|
|
@@ -732511,9 +732617,7 @@ Provenance: ${last2.provenance} (file_read to expand)` : "";
|
|
|
732511
732617
|
KG summary: .omnius/context/kg-summary/latest.md (file_read to expand; legacy pointer: .omnius/context/kg-summary-latest.md)`;
|
|
732512
732618
|
const prompt = appendRestoreBlocks(
|
|
732513
732619
|
`<session-recap>
|
|
732514
|
-
|
|
732515
|
-
|
|
732516
|
-
` : "") + `Project chronology (older to newer):
|
|
732620
|
+
Project chronology (older to newer):
|
|
732517
732621
|
Scope: full retained rolling window (${recent.length} entr${recent.length === 1 ? "y" : "ies"}).
|
|
732518
732622
|
${chronology.join("\n")}
|
|
732519
732623
|
` + (latestCompleted ? `
|
|
@@ -732521,16 +732625,14 @@ ${latestCompleted}
|
|
|
732521
732625
|
` : "\n") + `
|
|
732522
732626
|
Recent structured task state (older to newer; transcript omitted from model context):
|
|
732523
732627
|
${recentTaskState}
|
|
732524
|
-
|
|
732525
|
-
|
|
732526
|
-
|
|
732527
|
-
[restoredTodos?.block, historyAnchor?.block]
|
|
732628
|
+
This chronology is historical orientation only. It does not select an active task, todo tree, or run. Use an exact interruption checkpoint or an explicit lifecycle command for continuation authority.${prov}${kg}
|
|
732629
|
+
</session-recap>`,
|
|
732630
|
+
[historyAnchor?.block]
|
|
732528
732631
|
);
|
|
732529
732632
|
return {
|
|
732530
732633
|
prompt,
|
|
732531
732634
|
sourceSessionId,
|
|
732532
|
-
|
|
732533
|
-
todoCount: restoredTodos?.todos.length ?? 0,
|
|
732635
|
+
todoCount: 0,
|
|
732534
732636
|
historySessionId: historyAnchor?.sessionId,
|
|
732535
732637
|
historyPath: historyAnchor?.path,
|
|
732536
732638
|
historyLineCount: historyAnchor?.lineCount
|
|
@@ -732982,7 +733084,7 @@ function deleteUsageRecord(kind, value2, repoRoot) {
|
|
|
732982
733084
|
remove(join162(repoRoot, OMNIUS_DIR2, USAGE_HISTORY_FILE));
|
|
732983
733085
|
}
|
|
732984
733086
|
}
|
|
732985
|
-
var OMNIUS_DIR2, LEGACY_DIRS, SUBDIRS, gitignoreWatchers, gitignoreRetryTimers, CONTEXT_FILES, PENDING_TASK_FILE, HANDOFF_FILE, CONTEXT_SAVE_FILE, CONTEXT_LEDGER_FILE, COMPACTION_AUDIT_FILE, MAX_CONTEXT_ENTRIES, MAX_SESSION_DIARY_ENTRIES, MAX_SESSION_DIARY_DETAILED_ENTRIES, MAX_CONTEXT_LEDGER_LINES, MAX_CONTEXT_LEDGER_BYTES, SAME_TASK_REPLACE_WINDOW_MS, LOCK_TIMEOUT_MS, LOCK_RETRY_MS, LOCK_RETRY_MAX, MODEL_CONTEXT_NOISE_LINE_RE, DEFAULT_RESTORED_SESSION_HISTORY_MAX_LINES,
|
|
733087
|
+
var OMNIUS_DIR2, LEGACY_DIRS, SUBDIRS, gitignoreWatchers, gitignoreRetryTimers, CONTEXT_FILES, PENDING_TASK_FILE, HANDOFF_FILE, CONTEXT_SAVE_FILE, CONTEXT_LEDGER_FILE, COMPACTION_AUDIT_FILE, MAX_CONTEXT_ENTRIES, MAX_SESSION_DIARY_ENTRIES, MAX_SESSION_DIARY_DETAILED_ENTRIES, MAX_CONTEXT_LEDGER_LINES, MAX_CONTEXT_LEDGER_BYTES, SAME_TASK_REPLACE_WINDOW_MS, LOCK_TIMEOUT_MS, LOCK_RETRY_MS, LOCK_RETRY_MAX, MODEL_CONTEXT_NOISE_LINE_RE, DEFAULT_RESTORED_SESSION_HISTORY_MAX_LINES, SESSIONS_DIR, SESSIONS_INDEX, TUI_STATE_SUFFIX, AUTHORED_SESSION_LINE, VISUAL_CHROME_LINE, SESSION_TITLE_STATUS_LINE, SKIP_DIRS2, HOME_SKIP_DIRS, USAGE_HISTORY_FILE, MAX_HISTORY_RECORDS;
|
|
732986
733088
|
var init_omnius_directory = __esm({
|
|
732987
733089
|
"packages/cli/src/tui/omnius-directory.ts"() {
|
|
732988
733090
|
init_dist5();
|
|
@@ -733019,34 +733121,6 @@ var init_omnius_directory = __esm({
|
|
|
733019
733121
|
LOCK_RETRY_MAX = 100;
|
|
733020
733122
|
MODEL_CONTEXT_NOISE_LINE_RE = /^\s*(?:🔊|E Task timeout reached|E Incomplete:|⚠ Task incomplete|Tokens:\s*[\d,]+|▹\s*continue\b|·\s*(?:Starting fresh|Context (?:auto-)?restored|Nexus P2P network connected|REST API:|Voice feedback enabled|Memory maintenance:|Memory:|reclaimed\s+(?:\d|space\b)|physical footprint:)|.*\bSHELL TRANSCRIPT\b.*).*$/i;
|
|
733021
733123
|
DEFAULT_RESTORED_SESSION_HISTORY_MAX_LINES = 600;
|
|
733022
|
-
DEICTIC_CONTINUATION_TERMS = /* @__PURE__ */ new Set([
|
|
733023
|
-
"again",
|
|
733024
|
-
"and",
|
|
733025
|
-
"back",
|
|
733026
|
-
"carry",
|
|
733027
|
-
"complete",
|
|
733028
|
-
"continue",
|
|
733029
|
-
"finish",
|
|
733030
|
-
"from",
|
|
733031
|
-
"last",
|
|
733032
|
-
"latest",
|
|
733033
|
-
"left",
|
|
733034
|
-
"my",
|
|
733035
|
-
"off",
|
|
733036
|
-
"please",
|
|
733037
|
-
"previous",
|
|
733038
|
-
"prior",
|
|
733039
|
-
"proceed",
|
|
733040
|
-
"request",
|
|
733041
|
-
"resume",
|
|
733042
|
-
"task",
|
|
733043
|
-
"that",
|
|
733044
|
-
"the",
|
|
733045
|
-
"this",
|
|
733046
|
-
"to",
|
|
733047
|
-
"try",
|
|
733048
|
-
"work"
|
|
733049
|
-
]);
|
|
733050
733124
|
SESSIONS_DIR = "sessions";
|
|
733051
733125
|
SESSIONS_INDEX = "sessions-index.json";
|
|
733052
733126
|
TUI_STATE_SUFFIX = ".tui-state.json";
|
|
@@ -767195,7 +767269,7 @@ sleep 1
|
|
|
767195
767269
|
}
|
|
767196
767270
|
const paused = ctx3.pauseTask?.() ?? false;
|
|
767197
767271
|
if (interruptionAccepted(paused)) {
|
|
767198
|
-
ctx3.savePendingTaskState?.();
|
|
767272
|
+
ctx3.savePendingTaskState?.({ reason: "pause", resumeOnStartup: false });
|
|
767199
767273
|
renderInfo(interruptionMessage(paused, "Task paused."));
|
|
767200
767274
|
} else {
|
|
767201
767275
|
renderWarning(interruptionMessage(paused, "Could not pause the task."));
|
|
@@ -777335,7 +777409,7 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
777335
777409
|
`Updated Omnius v${currentVersion} → v${terminal.installed_version ?? info.latestVersion}; daemon v${terminal.daemon_version ?? info.latestVersion}${terminal.tray_was_running ? ", indicator restarted" : ""}.`
|
|
777336
777410
|
);
|
|
777337
777411
|
ctx3.contextSave?.();
|
|
777338
|
-
ctx3.savePendingTaskState?.();
|
|
777412
|
+
ctx3.savePendingTaskState?.({ reason: "update", resumeOnStartup: true });
|
|
777339
777413
|
if (ctx3.hasActiveTask?.()) ctx3.abortActiveTask?.({ preserveResume: true });
|
|
777340
777414
|
ctx3.killEphemeral?.({ preserveInfrastructure: true });
|
|
777341
777415
|
process.exit(120);
|
|
@@ -777924,7 +777998,7 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
777924
777998
|
!daemonUpgrade.ok ? `Daemon still at ${daemonUpgrade.observedVersion ?? "unknown"} — restarting client anyway` : daemonUpgrade.action === "restarted" ? `Daemon upgraded to ${expectedDaemonVersion}` : `Daemon verified at ${expectedDaemonVersion}`
|
|
777925
777999
|
);
|
|
777926
778000
|
ctx3.contextSave?.();
|
|
777927
|
-
const hadActiveTask = ctx3.savePendingTaskState?.() ?? false;
|
|
778001
|
+
const hadActiveTask = ctx3.savePendingTaskState?.({ reason: "update", resumeOnStartup: true }) ?? false;
|
|
777928
778002
|
const resumeFlag = hadActiveTask ? "1" : "update-only";
|
|
777929
778003
|
installOverlay.stop("Restarting with new version...");
|
|
777930
778004
|
await new Promise((r2) => setTimeout(r2, 1500));
|
|
@@ -803546,13 +803620,12 @@ function normalizeTelegramCallbackQuery(update2) {
|
|
|
803546
803620
|
};
|
|
803547
803621
|
}
|
|
803548
803622
|
function adaptTool5(tool, todoSessionId, progress) {
|
|
803623
|
+
if (todoSessionId && (tool.name === "todo_write" || tool.name === "todo_read")) {
|
|
803624
|
+
tool.bindExecutionScope?.({ sessionId: todoSessionId });
|
|
803625
|
+
}
|
|
803549
803626
|
return adaptExecutionTool(tool, {
|
|
803550
803627
|
onProgress: (toolName, event) => progress?.onProgress(toolName, event),
|
|
803551
|
-
execute: async (_tool,
|
|
803552
|
-
const previousTodoSession = todoSessionId ? getTodoSessionId() : "";
|
|
803553
|
-
if (todoSessionId && (tool.name === "todo_write" || tool.name === "todo_read")) {
|
|
803554
|
-
setTodoSessionId(todoSessionId);
|
|
803555
|
-
}
|
|
803628
|
+
execute: async (_tool, _args, invoke) => {
|
|
803556
803629
|
try {
|
|
803557
803630
|
const result = await invoke();
|
|
803558
803631
|
progress?.complete(tool.name, result);
|
|
@@ -803564,10 +803637,6 @@ function adaptTool5(tool, todoSessionId, progress) {
|
|
|
803564
803637
|
error: err instanceof Error ? err.message : String(err)
|
|
803565
803638
|
});
|
|
803566
803639
|
throw err;
|
|
803567
|
-
} finally {
|
|
803568
|
-
if (todoSessionId && (tool.name === "todo_write" || tool.name === "todo_read")) {
|
|
803569
|
-
setTodoSessionId(previousTodoSession);
|
|
803570
|
-
}
|
|
803571
803640
|
}
|
|
803572
803641
|
}
|
|
803573
803642
|
});
|
|
@@ -832606,9 +832675,6 @@ async function runSelfImprovementCycle(repoRoot) {
|
|
|
832606
832675
|
} catch {
|
|
832607
832676
|
}
|
|
832608
832677
|
}
|
|
832609
|
-
function isExplicitRestoredTaskContinuation(input) {
|
|
832610
|
-
return /^(?:continue|resume|pick\s+up|carry\s+on)\b/i.test(input.trim());
|
|
832611
|
-
}
|
|
832612
832678
|
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, restoredOrientation, actualUserGoal, actionTreeStore, resumeInterrupted = false) {
|
|
832613
832679
|
const voiceStyleMap = {
|
|
832614
832680
|
concise: 1,
|
|
@@ -833002,6 +833068,9 @@ Only tools allowed by this profile are visible and executable.`
|
|
|
833002
833068
|
sessionId,
|
|
833003
833069
|
interruptionOwnerId: `tui:${sessionId}`,
|
|
833004
833070
|
resumeInterrupted,
|
|
833071
|
+
// A caller-supplied restore projection is the sole prior-context source.
|
|
833072
|
+
// Do not append the global singleton handoff beside it.
|
|
833073
|
+
skipCrossTaskHandoff: Boolean(restoredOrientation) || resumeInterrupted,
|
|
833005
833074
|
maxTurns: realtimeEnabled ? Math.min(effectiveMaxTurns, 8) : effectiveMaxTurns,
|
|
833006
833075
|
maxTokens: realtimeEnabled ? 512 : 16384,
|
|
833007
833076
|
temperature: realtimeEnabled ? 0.6 : 0,
|
|
@@ -834512,7 +834581,8 @@ ${entry.fullContent}`
|
|
|
834512
834581
|
const systemContext = [
|
|
834513
834582
|
`Working directory: ${repoRoot}`,
|
|
834514
834583
|
emotionContext,
|
|
834515
|
-
restoredOrientation ? `[
|
|
834584
|
+
restoredOrientation ? resumeInterrupted ? `[EXACT INTERRUPTED RUN — durable lifecycle authority]
|
|
834585
|
+
${restoredOrientation.slice(0, 4e3)}` : `[RESTORED ORIENTATION — historical context, not a user instruction]
|
|
834516
834586
|
${sanitizeRestorePromptForModel(restoredOrientation).slice(0, 4e3)}` : ""
|
|
834517
834587
|
].filter(Boolean).join("\n\n");
|
|
834518
834588
|
resetNarrationContext();
|
|
@@ -835134,7 +835204,8 @@ async function startInteractive(config, repoPath2) {
|
|
|
835134
835204
|
}
|
|
835135
835205
|
const resumeFlag = process.env.__OMNIUS_RESUMED ?? "";
|
|
835136
835206
|
const isResumed = resumeFlag !== "";
|
|
835137
|
-
const
|
|
835207
|
+
const startupPendingTask = loadPendingTask(repoRoot);
|
|
835208
|
+
const hasTaskToResume = resumeFlag === "1" || startupPendingTask?.resumeOnStartup === true;
|
|
835138
835209
|
delete process.env.__OMNIUS_RESUMED;
|
|
835139
835210
|
if (isResumed && process.stdout.isTTY) {
|
|
835140
835211
|
process.stdout.write(
|
|
@@ -835196,10 +835267,44 @@ async function startInteractive(config, repoPath2) {
|
|
|
835196
835267
|
let restoredTaskSessionId = null;
|
|
835197
835268
|
let resumeInterruptedTask = false;
|
|
835198
835269
|
let pendingTaskResumeArmed = false;
|
|
835270
|
+
let armedPendingTask = null;
|
|
835199
835271
|
let saveVisualSessionSnapshotRef = null;
|
|
835200
835272
|
let terminalRestoredForExit = false;
|
|
835201
835273
|
let interactiveExiting = false;
|
|
835202
835274
|
let idleMemoryMaintenance = null;
|
|
835275
|
+
const persistActiveTaskForRestart = (exitReason) => {
|
|
835276
|
+
if (!activeTask || !lastSubmittedPrompt) return false;
|
|
835277
|
+
if (!activeTask.runner.isPaused) {
|
|
835278
|
+
const receipt2 = activeTask.runner.pause();
|
|
835279
|
+
if (receipt2?.accepted === false) return false;
|
|
835280
|
+
}
|
|
835281
|
+
const interruption = pendingInterruptionIdentity(activeTask);
|
|
835282
|
+
if (!interruption) return false;
|
|
835283
|
+
savePendingTask(repoRoot, {
|
|
835284
|
+
prompt: lastSubmittedPrompt,
|
|
835285
|
+
progressSummary: `Task paused for ${exitReason}. ${activeTask.toolCallCount} tool calls completed.`,
|
|
835286
|
+
filesModified: Array.from(activeTask.filesTouched),
|
|
835287
|
+
bruteForce: bruteForceEnabled,
|
|
835288
|
+
savedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
835289
|
+
toolCallCount: activeTask.toolCallCount,
|
|
835290
|
+
exitReason,
|
|
835291
|
+
resumeOnStartup: true,
|
|
835292
|
+
interruption
|
|
835293
|
+
});
|
|
835294
|
+
return true;
|
|
835295
|
+
};
|
|
835296
|
+
const armPendingTaskResume = (pendingTask) => {
|
|
835297
|
+
restoredTaskSessionId = pendingTask.interruption?.sessionId ?? null;
|
|
835298
|
+
resumeInterruptedTask = Boolean(pendingTask.interruption);
|
|
835299
|
+
pendingTaskResumeArmed = true;
|
|
835300
|
+
armedPendingTask = pendingTask;
|
|
835301
|
+
const exactSnapshot = buildExactContinuationSnapshot(repoRoot, pendingTask);
|
|
835302
|
+
restoredSessionContext = exactSnapshot?.prompt ?? [
|
|
835303
|
+
`Original user goal: ${pendingTask.prompt}`,
|
|
835304
|
+
pendingTask.progressSummary,
|
|
835305
|
+
pendingTask.filesModified.length > 0 ? `Modified: ${pendingTask.filesModified.slice(0, 20).join(", ")}` : ""
|
|
835306
|
+
].filter(Boolean).join("\n");
|
|
835307
|
+
};
|
|
835203
835308
|
const restoreTerminalForExit = () => {
|
|
835204
835309
|
if (!process.stdout.isTTY || terminalRestoredForExit) return;
|
|
835205
835310
|
terminalRestoredForExit = true;
|
|
@@ -835231,18 +835336,7 @@ async function startInteractive(config, repoPath2) {
|
|
|
835231
835336
|
}
|
|
835232
835337
|
if (activeTask) {
|
|
835233
835338
|
if (interruption === "pause") {
|
|
835234
|
-
|
|
835235
|
-
if (receipt2?.accepted !== false && lastSubmittedPrompt) {
|
|
835236
|
-
savePendingTask(repoRoot, {
|
|
835237
|
-
prompt: lastSubmittedPrompt,
|
|
835238
|
-
progressSummary: `Task paused during process shutdown. ${activeTask.toolCallCount} tool calls completed.`,
|
|
835239
|
-
filesModified: Array.from(activeTask.filesTouched),
|
|
835240
|
-
bruteForce: bruteForceEnabled,
|
|
835241
|
-
savedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
835242
|
-
toolCallCount: activeTask.toolCallCount,
|
|
835243
|
-
interruption: pendingInterruptionIdentity(activeTask)
|
|
835244
|
-
});
|
|
835245
|
-
}
|
|
835339
|
+
persistActiveTaskForRestart("shutdown");
|
|
835246
835340
|
} else {
|
|
835247
835341
|
activeTask.runner.abort();
|
|
835248
835342
|
discardPendingTask(repoRoot);
|
|
@@ -837089,9 +837183,9 @@ This is an independent background session started from /background.`
|
|
|
837089
837183
|
if (options2.injectNextTask !== false) {
|
|
837090
837184
|
restoredSessionContext = snapshot.prompt;
|
|
837091
837185
|
}
|
|
837092
|
-
const restoredId = snapshot.
|
|
837093
|
-
|
|
837094
|
-
|
|
837186
|
+
const restoredId = options2.bindTaskIdentity && snapshot.selection ? snapshot.selection.sessionId : null;
|
|
837187
|
+
if (restoredId && snapshot.selection?.kind === "exact_interruption") {
|
|
837188
|
+
restoredTaskSessionId = restoredId;
|
|
837095
837189
|
try {
|
|
837096
837190
|
process.env["OMNIUS_SESSION_ID"] = restoredId;
|
|
837097
837191
|
} catch {
|
|
@@ -838195,8 +838289,14 @@ The user pasted a clipboard image saved at ${relPath}. Use the OCR, vision analy
|
|
|
838195
838289
|
} catch {
|
|
838196
838290
|
}
|
|
838197
838291
|
},
|
|
838198
|
-
savePendingTaskState() {
|
|
838292
|
+
savePendingTaskState(options2) {
|
|
838199
838293
|
if (lastSubmittedPrompt && activeTask) {
|
|
838294
|
+
if (!activeTask.runner.isPaused) {
|
|
838295
|
+
const receipt2 = activeTask.runner.pause();
|
|
838296
|
+
if (receipt2?.accepted === false) return false;
|
|
838297
|
+
}
|
|
838298
|
+
const interruption = pendingInterruptionIdentity(activeTask);
|
|
838299
|
+
if (!interruption) return false;
|
|
838200
838300
|
const activeToolCallCount = activeTask.toolCallCount;
|
|
838201
838301
|
const activeFilesTouched = Array.from(activeTask.filesTouched);
|
|
838202
838302
|
savePendingTask(repoRoot, {
|
|
@@ -838206,7 +838306,9 @@ The user pasted a clipboard image saved at ${relPath}. Use the OCR, vision analy
|
|
|
838206
838306
|
bruteForce: bruteForceEnabled,
|
|
838207
838307
|
savedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
838208
838308
|
toolCallCount: activeToolCallCount,
|
|
838209
|
-
|
|
838309
|
+
exitReason: options2?.reason ?? "pause",
|
|
838310
|
+
resumeOnStartup: options2?.resumeOnStartup === true,
|
|
838311
|
+
interruption
|
|
838210
838312
|
});
|
|
838211
838313
|
return true;
|
|
838212
838314
|
}
|
|
@@ -839881,19 +839983,11 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
839881
839983
|
resumeTask() {
|
|
839882
839984
|
const pendingTask = loadPendingTask(repoRoot);
|
|
839883
839985
|
if (!pendingTask) return false;
|
|
839884
|
-
|
|
839885
|
-
resumeInterruptedTask = Boolean(pendingTask.interruption);
|
|
839886
|
-
pendingTaskResumeArmed = true;
|
|
839986
|
+
armPendingTaskResume(pendingTask);
|
|
839887
839987
|
setTimeout(() => {
|
|
839888
|
-
const resumeContext = [
|
|
839889
|
-
`Continuing previous task: ${pendingTask.prompt}`,
|
|
839890
|
-
pendingTask.progressSummary ? `Progress: ${pendingTask.progressSummary}` : "",
|
|
839891
|
-
pendingTask.filesModified.length > 0 ? `Modified: ${pendingTask.filesModified.slice(0, 5).join(", ")}` : "",
|
|
839892
|
-
"Continue where you left off."
|
|
839893
|
-
].filter(Boolean).join("\n");
|
|
839894
839988
|
const shortPrompt = pendingTask.prompt.slice(0, 40) + (pendingTask.prompt.length > 40 ? "..." : "");
|
|
839895
839989
|
writeContent(() => renderInfo(`Picking up: ${shortPrompt}`));
|
|
839896
|
-
rl.emit("line",
|
|
839990
|
+
rl.emit("line", pendingTask.prompt);
|
|
839897
839991
|
}, 100);
|
|
839898
839992
|
return true;
|
|
839899
839993
|
},
|
|
@@ -840151,7 +840245,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
840151
840245
|
}
|
|
840152
840246
|
statusBar.ensureMonitorTimer();
|
|
840153
840247
|
showPrompt();
|
|
840154
|
-
if (!isResumed) {
|
|
840248
|
+
if (!isResumed && !hasTaskToResume) {
|
|
840155
840249
|
const savedCtx = loadSessionContext(repoRoot);
|
|
840156
840250
|
if (savedCtx && savedCtx.entries.length > 0) {
|
|
840157
840251
|
const lastEntry = savedCtx.entries[savedCtx.entries.length - 1];
|
|
@@ -840277,30 +840371,13 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
840277
840371
|
}
|
|
840278
840372
|
startReminderDispatcher();
|
|
840279
840373
|
if (hasTaskToResume) {
|
|
840280
|
-
const pendingTask = loadPendingTask(repoRoot);
|
|
840374
|
+
const pendingTask = startupPendingTask ?? loadPendingTask(repoRoot);
|
|
840281
840375
|
if (pendingTask) {
|
|
840282
|
-
|
|
840283
|
-
resumeInterruptedTask = Boolean(pendingTask.interruption);
|
|
840284
|
-
pendingTaskResumeArmed = true;
|
|
840376
|
+
armPendingTaskResume(pendingTask);
|
|
840285
840377
|
setTimeout(() => {
|
|
840286
|
-
const restoreSnapshot = buildContextRestoreSnapshot(repoRoot);
|
|
840287
|
-
if (restoreSnapshot) {
|
|
840288
|
-
applyRestoreSnapshot(restoreSnapshot, {
|
|
840289
|
-
replayVisual: false,
|
|
840290
|
-
injectNextTask: false
|
|
840291
|
-
});
|
|
840292
|
-
}
|
|
840293
|
-
const sessionCtx = restoreSnapshot?.prompt ?? buildContextRestorePrompt(repoRoot);
|
|
840294
|
-
const resumeContext = [
|
|
840295
|
-
sessionCtx || "",
|
|
840296
|
-
`Continuing task after update: ${pendingTask.prompt}`,
|
|
840297
|
-
pendingTask.progressSummary ? `Progress: ${pendingTask.progressSummary}` : "",
|
|
840298
|
-
pendingTask.filesModified.length > 0 ? `Modified: ${pendingTask.filesModified.slice(0, 5).join(", ")}` : "",
|
|
840299
|
-
"Continue where you left off."
|
|
840300
|
-
].filter(Boolean).join("\n");
|
|
840301
840378
|
const shortPrompt = pendingTask.prompt.slice(0, 40) + (pendingTask.prompt.length > 40 ? "..." : "");
|
|
840302
840379
|
writeContent(() => renderInfo(`Picking up: ${shortPrompt}`));
|
|
840303
|
-
rl.emit("line",
|
|
840380
|
+
rl.emit("line", pendingTask.prompt);
|
|
840304
840381
|
}, 100);
|
|
840305
840382
|
}
|
|
840306
840383
|
}
|
|
@@ -840492,10 +840569,7 @@ ${result.content.slice(0, 2e3)}${result.content.length > 2e3 ? "\n[truncated]" :
|
|
|
840492
840569
|
if (quitMatch === "quit" || quitMatch === "exit" || quitMatch === "q") {
|
|
840493
840570
|
interactiveExiting = true;
|
|
840494
840571
|
saveVisualSessionSnapshot();
|
|
840495
|
-
if (activeTask)
|
|
840496
|
-
activeTask.runner.abort();
|
|
840497
|
-
discardPendingTask(repoRoot);
|
|
840498
|
-
}
|
|
840572
|
+
if (activeTask) persistActiveTaskForRestart("quit");
|
|
840499
840573
|
idleMemoryMaintenance?.stop();
|
|
840500
840574
|
taskManager.stopAll();
|
|
840501
840575
|
if (blessEngine?.isActive) blessEngine.stop();
|
|
@@ -840513,10 +840587,7 @@ ${result.content.slice(0, 2e3)}${result.content.length > 2e3 ? "\n[truncated]" :
|
|
|
840513
840587
|
if (cmdResult === "exit") {
|
|
840514
840588
|
interactiveExiting = true;
|
|
840515
840589
|
saveVisualSessionSnapshot();
|
|
840516
|
-
if (activeTask)
|
|
840517
|
-
activeTask.runner.abort();
|
|
840518
|
-
discardPendingTask(repoRoot);
|
|
840519
|
-
}
|
|
840590
|
+
if (activeTask) persistActiveTaskForRestart("quit");
|
|
840520
840591
|
idleMemoryMaintenance?.stop();
|
|
840521
840592
|
taskManager.stopAll();
|
|
840522
840593
|
if (telegramBridge) await telegramBridge.stopAndWait();
|
|
@@ -841078,6 +841149,10 @@ ${formatTaskCompletionMeta(previousMetaForIntake)}`
|
|
|
841078
841149
|
);
|
|
841079
841150
|
}
|
|
841080
841151
|
if (promptRecallCancelled) return;
|
|
841152
|
+
const pendingTaskForAdmission = pendingTaskResumeArmed ? armedPendingTask : null;
|
|
841153
|
+
if (pendingTaskForAdmission) {
|
|
841154
|
+
fullInput = pendingTaskForAdmission.prompt;
|
|
841155
|
+
}
|
|
841081
841156
|
lastSubmittedPrompt = fullInput;
|
|
841082
841157
|
const taskPreview = fullInput.length > 100 ? fullInput.slice(0, 100) + "..." : fullInput;
|
|
841083
841158
|
emotionEngine.setCurrentTask(taskPreview);
|
|
@@ -841094,18 +841169,19 @@ ${formatTaskCompletionMeta(previousMetaForIntake)}`
|
|
|
841094
841169
|
} catch {
|
|
841095
841170
|
}
|
|
841096
841171
|
let taskInput = fullInput;
|
|
841097
|
-
const reuseRestoredTaskSession = Boolean(restoredTaskSessionId) &&
|
|
841172
|
+
const reuseRestoredTaskSession = Boolean(restoredTaskSessionId) && resumeInterruptedTask && Boolean(pendingTaskForAdmission?.interruption);
|
|
841098
841173
|
let taskSessionId = reuseRestoredTaskSession ? restoredTaskSessionId : null;
|
|
841099
841174
|
const adoptInterruptedGeneration = reuseRestoredTaskSession && resumeInterruptedTask;
|
|
841100
841175
|
const consumePendingTaskAfterAdmission = pendingTaskResumeArmed;
|
|
841101
841176
|
let restoredOrientation = null;
|
|
841102
841177
|
if (restoredSessionContext) {
|
|
841103
|
-
restoredOrientation = sanitizeRestorePromptForModel(restoredSessionContext);
|
|
841178
|
+
restoredOrientation = pendingTaskForAdmission ? restoredSessionContext : sanitizeRestorePromptForModel(restoredSessionContext);
|
|
841104
841179
|
restoredSessionContext = null;
|
|
841105
841180
|
}
|
|
841106
841181
|
restoredTaskSessionId = null;
|
|
841107
841182
|
resumeInterruptedTask = false;
|
|
841108
841183
|
pendingTaskResumeArmed = false;
|
|
841184
|
+
armedPendingTask = null;
|
|
841109
841185
|
if (taskIntakePacket) {
|
|
841110
841186
|
taskInput = `${taskIntakePacket}
|
|
841111
841187
|
|
|
@@ -841162,14 +841238,23 @@ ${taskInput}`;
|
|
|
841162
841238
|
realtimeEnabled,
|
|
841163
841239
|
taskSessionId,
|
|
841164
841240
|
restoredOrientation,
|
|
841165
|
-
fullInput,
|
|
841241
|
+
pendingTaskForAdmission?.prompt ?? fullInput,
|
|
841166
841242
|
idleActionTree,
|
|
841167
841243
|
adoptInterruptedGeneration
|
|
841168
841244
|
);
|
|
841169
841245
|
activeTask = task;
|
|
841170
841246
|
if (consumePendingTaskAfterAdmission) {
|
|
841171
841247
|
const adopted = task.runner.interruptionState;
|
|
841172
|
-
if (!
|
|
841248
|
+
if (pendingTaskForAdmission && !pendingTaskForAdmission.interruption || pendingTaskForAdmission && pendingTaskMatchesRunningInterruption(
|
|
841249
|
+
pendingTaskForAdmission,
|
|
841250
|
+
adopted ? {
|
|
841251
|
+
sessionId: adopted.sessionId,
|
|
841252
|
+
runId: adopted.runId,
|
|
841253
|
+
taskEpoch: adopted.taskEpoch,
|
|
841254
|
+
ownerGeneration: adopted.owner.generation,
|
|
841255
|
+
phase: adopted.phase
|
|
841256
|
+
} : null
|
|
841257
|
+
)) {
|
|
841173
841258
|
discardPendingTask(repoRoot);
|
|
841174
841259
|
}
|
|
841175
841260
|
}
|
|
@@ -841227,6 +841312,21 @@ ${taskInput}`;
|
|
|
841227
841312
|
scheduleAgentSNREval(lastSubmittedPrompt);
|
|
841228
841313
|
}
|
|
841229
841314
|
if (activeTask) {
|
|
841315
|
+
if (pendingTaskForAdmission?.interruption) {
|
|
841316
|
+
const state5 = activeTask.runner.interruptionState;
|
|
841317
|
+
if (state5 && state5.phase !== "running" && state5.phase !== "pausing" && state5.phase !== "paused" && state5.phase !== "resuming" && pendingTaskMatchesInterruptionIdentity(
|
|
841318
|
+
pendingTaskForAdmission,
|
|
841319
|
+
{
|
|
841320
|
+
sessionId: state5.sessionId,
|
|
841321
|
+
runId: state5.runId,
|
|
841322
|
+
taskEpoch: state5.taskEpoch,
|
|
841323
|
+
ownerGeneration: state5.owner.generation,
|
|
841324
|
+
phase: state5.phase
|
|
841325
|
+
}
|
|
841326
|
+
)) {
|
|
841327
|
+
discardPendingTask(repoRoot);
|
|
841328
|
+
}
|
|
841329
|
+
}
|
|
841230
841330
|
sessionFilesTouched = Array.from(activeTask.filesTouched);
|
|
841231
841331
|
sessionToolCallCount = activeTask.toolCallCount;
|
|
841232
841332
|
sessionAvailableTools = Array.from(activeTask.availableTools);
|
|
@@ -841506,7 +841606,7 @@ Rationale: ${proposal.rationale}${provenanceNote}${dmnDevDiscipline(proposal.cat
|
|
|
841506
841606
|
peerMesh = null;
|
|
841507
841607
|
inferenceRouter = null;
|
|
841508
841608
|
}
|
|
841509
|
-
if (activeTask)
|
|
841609
|
+
if (activeTask) persistActiveTaskForRestart("shutdown");
|
|
841510
841610
|
taskManager.stopAll();
|
|
841511
841611
|
killAllFullSubAgents();
|
|
841512
841612
|
idleMemoryMaintenance?.stop();
|
|
@@ -841600,6 +841700,8 @@ ${c3.dim("(Use /quit to exit)")}
|
|
|
841600
841700
|
bruteForce: bruteForceEnabled,
|
|
841601
841701
|
savedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
841602
841702
|
toolCallCount: activeTask.toolCallCount,
|
|
841703
|
+
exitReason: "pause",
|
|
841704
|
+
resumeOnStartup: false,
|
|
841603
841705
|
interruption: pendingInterruptionIdentity(activeTask)
|
|
841604
841706
|
});
|
|
841605
841707
|
}
|