omnius 1.0.369 → 1.0.370
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 +524 -45
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -295152,7 +295152,13 @@ var init_todo_write = __esm({
|
|
|
295152
295152
|
- completed: fully done (tests pass, code works, goal met)
|
|
295153
295153
|
- blocked: stuck on a dependency (include blocker text)
|
|
295154
295154
|
|
|
295155
|
-
|
|
295155
|
+
## Nested decomposition
|
|
295156
|
+
- Use stable ids plus parentId to create subtasks under a parent objective.
|
|
295157
|
+
- Work on leaf subtasks; a parent is completed only after every child is completed with evidence.
|
|
295158
|
+
- When evidence changes the plan, rewrite the tree: add new child todos, block invalidated children with root cause, and keep the parent in_progress/blocked until the child set is truthful.
|
|
295159
|
+
- If a tool fails for a child, do not mark that child completed. Reconfigure it: re-read/observe current state, choose a different target/tool, or leave it blocked.
|
|
295160
|
+
|
|
295161
|
+
Mark tasks complete IMMEDIATELY after finishing — don't batch. Never mark completed if tests are failing or implementation is partial. The user watches this list in the chat UI in real time. Canonical call shape: todo_write({"todos":[{"id":"p1","content":"Implement feature","status":"in_progress"},{"id":"c1","parentId":"p1","content":"Inspect files","status":"in_progress"},{"id":"c2","parentId":"p1","content":"Make changes","status":"pending"},{"id":"c3","parentId":"p1","content":"Verify results","status":"pending"}]})`;
|
|
295156
295162
|
parameters = {
|
|
295157
295163
|
type: "object",
|
|
295158
295164
|
required: ["todos"],
|
|
@@ -295170,7 +295176,7 @@ Mark tasks complete IMMEDIATELY after finishing — don't batch. Never mark comp
|
|
|
295170
295176
|
type: "string",
|
|
295171
295177
|
enum: ["pending", "in_progress", "completed", "blocked"]
|
|
295172
295178
|
},
|
|
295173
|
-
parentId: { type: "string", description: "Parent todo id for sub-tasks" },
|
|
295179
|
+
parentId: { type: "string", description: "Parent todo id for nested sub-tasks. Parents summarize objectives; children carry concrete implementation/verification work. Never complete a parent until every child is completed with evidence." },
|
|
295174
295180
|
blocker: { type: "string", description: "Reason this is blocked (status=blocked only)" },
|
|
295175
295181
|
verifyCommand: {
|
|
295176
295182
|
type: "string",
|
|
@@ -295287,6 +295293,7 @@ Mark tasks complete IMMEDIATELY after finishing — don't batch. Never mark comp
|
|
|
295287
295293
|
const reminder = "Todos have been modified successfully. Ensure that you continue to use the todo list to track your progress. Mark the current task in_progress and the next task pending. Proceed with the current task.";
|
|
295288
295294
|
const payload = {
|
|
295289
295295
|
reminder,
|
|
295296
|
+
decompositionContract: "Use parentId for sub-todos. Keep parents in_progress/blocked until all children are completed with objective evidence. When tool evidence invalidates a child, rewrite that child as blocked or split it into new children instead of overclaiming completion.",
|
|
295290
295297
|
oldTodos: result.oldTodos,
|
|
295291
295298
|
newTodos: result.newTodos,
|
|
295292
295299
|
verificationNudgeNeeded
|
|
@@ -295295,9 +295302,10 @@ Mark tasks complete IMMEDIATELY after finishing — don't batch. Never mark comp
|
|
|
295295
295302
|
payload["inputRepair"] = Array.from(new Set(repairNotes));
|
|
295296
295303
|
payload["canonicalShape"] = {
|
|
295297
295304
|
todos: [
|
|
295298
|
-
{ content: "
|
|
295299
|
-
{ content: "
|
|
295300
|
-
{ content: "
|
|
295305
|
+
{ id: "p1", content: "Implement the requested change", status: "in_progress" },
|
|
295306
|
+
{ id: "c1", parentId: "p1", content: "Inspect files", status: "in_progress" },
|
|
295307
|
+
{ id: "c2", parentId: "p1", content: "Make changes", status: "pending" },
|
|
295308
|
+
{ id: "c3", parentId: "p1", content: "Verify results", status: "pending" }
|
|
295301
295309
|
]
|
|
295302
295310
|
};
|
|
295303
295311
|
}
|
|
@@ -546587,6 +546595,32 @@ ${content.slice(0, 500)}`,
|
|
|
546587
546595
|
}
|
|
546588
546596
|
});
|
|
546589
546597
|
|
|
546598
|
+
// packages/execution/dist/tools/clip-feature-python.js
|
|
546599
|
+
var CLIP_FEATURE_HELPERS_PY;
|
|
546600
|
+
var init_clip_feature_python = __esm({
|
|
546601
|
+
"packages/execution/dist/tools/clip-feature-python.js"() {
|
|
546602
|
+
"use strict";
|
|
546603
|
+
CLIP_FEATURE_HELPERS_PY = `
|
|
546604
|
+
def _omnius_feature_tensor(features):
|
|
546605
|
+
if hasattr(features, "image_embeds"):
|
|
546606
|
+
return features.image_embeds
|
|
546607
|
+
if hasattr(features, "text_embeds"):
|
|
546608
|
+
return features.text_embeds
|
|
546609
|
+
if hasattr(features, "pooler_output"):
|
|
546610
|
+
return features.pooler_output
|
|
546611
|
+
if hasattr(features, "last_hidden_state"):
|
|
546612
|
+
return features.last_hidden_state[:, 0]
|
|
546613
|
+
if isinstance(features, (tuple, list)):
|
|
546614
|
+
return features[0]
|
|
546615
|
+
return features
|
|
546616
|
+
|
|
546617
|
+
def _omnius_normalized_features(features):
|
|
546618
|
+
tensor = _omnius_feature_tensor(features)
|
|
546619
|
+
return tensor / tensor.norm(dim=-1, keepdim=True)
|
|
546620
|
+
`;
|
|
546621
|
+
}
|
|
546622
|
+
});
|
|
546623
|
+
|
|
546590
546624
|
// packages/execution/dist/tools/visual-memory.js
|
|
546591
546625
|
import { execSync as execSync39 } from "node:child_process";
|
|
546592
546626
|
import { existsSync as existsSync66, mkdirSync as mkdirSync39, writeFileSync as writeFileSync31, readFileSync as readFileSync48 } from "node:fs";
|
|
@@ -546639,19 +546673,38 @@ function normalizeVisualMemoryAction(args) {
|
|
|
546639
546673
|
}
|
|
546640
546674
|
function summarizeProcessFailure(stdout, stderr) {
|
|
546641
546675
|
const normalize2 = (text2) => text2.replace(/\r/g, "\n").split("\n").map((line) => line.trim()).filter(Boolean);
|
|
546642
|
-
const
|
|
546643
|
-
|
|
546644
|
-
|
|
546676
|
+
const stderrLines = normalize2(stderr);
|
|
546677
|
+
const stdoutLines = normalize2(stdout);
|
|
546678
|
+
const tagged = [
|
|
546679
|
+
...stderrLines.map((line) => `stderr: ${line}`),
|
|
546680
|
+
...stdoutLines.map((line) => `stdout: ${line}`)
|
|
546645
546681
|
];
|
|
546646
|
-
if (
|
|
546682
|
+
if (tagged.length === 0)
|
|
546647
546683
|
return "Vision ML script failed";
|
|
546648
|
-
|
|
546684
|
+
const exceptionRe = /(?:^|\s)(?:[A-Za-z_][\w.]*Error|[A-Za-z_][\w.]*Exception|AssertionError|KeyboardInterrupt|SystemExit):\s+.+$/;
|
|
546685
|
+
const tracebackIdx = tagged.findIndex((line) => /Traceback \(most recent call last\):/.test(line));
|
|
546686
|
+
const exceptionLine = [...stderrLines, ...stdoutLines].slice().reverse().find((line) => exceptionRe.test(line) && !/\bwarning:/i.test(line));
|
|
546687
|
+
const parts = [];
|
|
546688
|
+
if (exceptionLine) {
|
|
546689
|
+
parts.push(`Root cause: ${exceptionLine}`);
|
|
546690
|
+
}
|
|
546691
|
+
if (tracebackIdx >= 0) {
|
|
546692
|
+
parts.push("Traceback:");
|
|
546693
|
+
parts.push(...tagged.slice(tracebackIdx).slice(0, 18));
|
|
546694
|
+
}
|
|
546695
|
+
const tail = tagged.slice(-24);
|
|
546696
|
+
for (const line of tail) {
|
|
546697
|
+
if (!parts.includes(line))
|
|
546698
|
+
parts.push(line);
|
|
546699
|
+
}
|
|
546700
|
+
return parts.join("\n").slice(0, 2200);
|
|
546649
546701
|
}
|
|
546650
546702
|
var VMEM_DIR, VENV_DIR2, VENV_PY, VENV_PIP2, VISUAL_MEMORY_ACTIONS, VisualMemoryTool;
|
|
546651
546703
|
var init_visual_memory = __esm({
|
|
546652
546704
|
"packages/execution/dist/tools/visual-memory.js"() {
|
|
546653
546705
|
"use strict";
|
|
546654
546706
|
init_cuda_device_filter();
|
|
546707
|
+
init_clip_feature_python();
|
|
546655
546708
|
VMEM_DIR = join80(homedir20(), ".omnius", "visual-memory");
|
|
546656
546709
|
VENV_DIR2 = join80(homedir20(), ".omnius", "vision-ml-venv");
|
|
546657
546710
|
VENV_PY = join80(VENV_DIR2, "bin", "python3");
|
|
@@ -546994,6 +547047,8 @@ import torch
|
|
|
546994
547047
|
from PIL import Image
|
|
546995
547048
|
from transformers import CLIPProcessor, CLIPModel
|
|
546996
547049
|
|
|
547050
|
+
${CLIP_FEATURE_HELPERS_PY}
|
|
547051
|
+
|
|
546997
547052
|
image_path = ${pyLiteral(image)}
|
|
546998
547053
|
label = ${pyLiteral(label)}
|
|
546999
547054
|
aliases = ${JSON.stringify(aliases)}
|
|
@@ -547007,16 +547062,14 @@ processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
|
|
|
547007
547062
|
img = Image.open(image_path).convert("RGB")
|
|
547008
547063
|
inputs = processor(images=img, return_tensors="pt")
|
|
547009
547064
|
with torch.no_grad():
|
|
547010
|
-
image_features = model.get_image_features(**inputs)
|
|
547011
|
-
image_features = image_features / image_features.norm(dim=-1, keepdim=True)
|
|
547065
|
+
image_features = _omnius_normalized_features(model.get_image_features(**inputs))
|
|
547012
547066
|
|
|
547013
547067
|
embedding = image_features[0].cpu().numpy().tolist()
|
|
547014
547068
|
|
|
547015
547069
|
# Also embed the text label and aliases for cross-modal retrieval
|
|
547016
547070
|
text_inputs = processor(text=aliases, return_tensors="pt", padding=True)
|
|
547017
547071
|
with torch.no_grad():
|
|
547018
|
-
text_features = model.get_text_features(**text_inputs)
|
|
547019
|
-
text_features = text_features / text_features.norm(dim=-1, keepdim=True)
|
|
547072
|
+
text_features = _omnius_normalized_features(model.get_text_features(**text_inputs))
|
|
547020
547073
|
|
|
547021
547074
|
text_embeddings = {}
|
|
547022
547075
|
for i, alias in enumerate(aliases):
|
|
@@ -547089,6 +547142,8 @@ import torch
|
|
|
547089
547142
|
from PIL import Image
|
|
547090
547143
|
from transformers import CLIPProcessor, CLIPModel
|
|
547091
547144
|
|
|
547145
|
+
${CLIP_FEATURE_HELPERS_PY}
|
|
547146
|
+
|
|
547092
547147
|
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
|
|
547093
547148
|
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
|
|
547094
547149
|
|
|
@@ -547097,8 +547152,7 @@ img = Image.open(${pyLiteral(image)}).convert("RGB")
|
|
|
547097
547152
|
# Get image embedding
|
|
547098
547153
|
inputs = processor(images=img, return_tensors="pt")
|
|
547099
547154
|
with torch.no_grad():
|
|
547100
|
-
image_features = model.get_image_features(**inputs)
|
|
547101
|
-
image_features = image_features / image_features.norm(dim=-1, keepdim=True)
|
|
547155
|
+
image_features = _omnius_normalized_features(model.get_image_features(**inputs))
|
|
547102
547156
|
|
|
547103
547157
|
query = image_features[0].cpu().numpy()
|
|
547104
547158
|
|
|
@@ -547160,8 +547214,7 @@ extra_labels = ${JSON.stringify(extraLabels)}
|
|
|
547160
547214
|
if extra_labels:
|
|
547161
547215
|
text_inputs = processor(text=extra_labels, return_tensors="pt", padding=True)
|
|
547162
547216
|
with torch.no_grad():
|
|
547163
|
-
text_features = model.get_text_features(**text_inputs)
|
|
547164
|
-
text_features = text_features / text_features.norm(dim=-1, keepdim=True)
|
|
547217
|
+
text_features = _omnius_normalized_features(model.get_text_features(**text_inputs))
|
|
547165
547218
|
|
|
547166
547219
|
for i, label in enumerate(extra_labels):
|
|
547167
547220
|
sim = float(np.dot(query, text_features[i].cpu().numpy()))
|
|
@@ -547320,6 +547373,7 @@ var MM_DIR, MM_INDEX, MultimodalMemoryTool;
|
|
|
547320
547373
|
var init_multimodal_memory = __esm({
|
|
547321
547374
|
"packages/execution/dist/tools/multimodal-memory.js"() {
|
|
547322
547375
|
"use strict";
|
|
547376
|
+
init_clip_feature_python();
|
|
547323
547377
|
MM_DIR = join81(homedir21(), ".omnius", "multimodal-episodes");
|
|
547324
547378
|
MM_INDEX = join81(MM_DIR, "index.json");
|
|
547325
547379
|
MultimodalMemoryTool = class {
|
|
@@ -547413,13 +547467,13 @@ var init_multimodal_memory = __esm({
|
|
|
547413
547467
|
import json, torch
|
|
547414
547468
|
from PIL import Image
|
|
547415
547469
|
from transformers import CLIPProcessor, CLIPModel
|
|
547470
|
+
${CLIP_FEATURE_HELPERS_PY}
|
|
547416
547471
|
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
|
|
547417
547472
|
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
|
|
547418
547473
|
img = Image.open("${imagePath}").convert("RGB")
|
|
547419
547474
|
inputs = processor(images=img, return_tensors="pt")
|
|
547420
547475
|
with torch.no_grad():
|
|
547421
|
-
features = model.get_image_features(**inputs)
|
|
547422
|
-
features = features / features.norm(dim=-1, keepdim=True)
|
|
547476
|
+
features = _omnius_normalized_features(model.get_image_features(**inputs))
|
|
547423
547477
|
print(json.dumps(features[0].cpu().numpy().tolist()))
|
|
547424
547478
|
`;
|
|
547425
547479
|
const scriptFile = join81(tmpdir17(), `mm-clip-${Date.now()}.py`);
|
|
@@ -547639,12 +547693,12 @@ Recall later: multimodal_memory action=recall query="${personName}"`,
|
|
|
547639
547693
|
const clipTextScript = `
|
|
547640
547694
|
import json, torch
|
|
547641
547695
|
from transformers import CLIPProcessor, CLIPModel
|
|
547696
|
+
${CLIP_FEATURE_HELPERS_PY}
|
|
547642
547697
|
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
|
|
547643
547698
|
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
|
|
547644
547699
|
inputs = processor(text=["${query.replace(/"/g, '\\"').replace(/\n/g, " ")}"], return_tensors="pt", padding=True)
|
|
547645
547700
|
with torch.no_grad():
|
|
547646
|
-
features = model.get_text_features(**inputs)
|
|
547647
|
-
features = features / features.norm(dim=-1, keepdim=True)
|
|
547701
|
+
features = _omnius_normalized_features(model.get_text_features(**inputs))
|
|
547648
547702
|
print(json.dumps(features[0].cpu().numpy().tolist()))
|
|
547649
547703
|
`;
|
|
547650
547704
|
const scriptFile = join81(tmpdir17(), `mm-clipq-${Date.now()}.py`);
|
|
@@ -567219,7 +567273,6 @@ function normalizeFailurePatterns(patterns) {
|
|
|
567219
567273
|
});
|
|
567220
567274
|
}
|
|
567221
567275
|
function buildFailureModeHandoff(input) {
|
|
567222
|
-
const patterns = normalizeFailurePatterns(input.errorPatterns).slice(0, input.maxPatterns ?? 10);
|
|
567223
567276
|
const toolCalls = input.toolCallLog ?? [];
|
|
567224
567277
|
const maxRecentCalls = input.maxRecentCalls ?? 8;
|
|
567225
567278
|
const recentCalls = maxRecentCalls > 0 ? toolCalls.slice(-maxRecentCalls) : [];
|
|
@@ -567231,6 +567284,7 @@ function buildFailureModeHandoff(input) {
|
|
|
567231
567284
|
const currentStep = cleanInline(input.taskState?.currentStep, 180);
|
|
567232
567285
|
const nextAction = cleanInline(input.taskState?.nextAction, 180);
|
|
567233
567286
|
const goal = cleanInline(input.taskGoal || input.taskState?.goal || input.taskState?.originalGoal || "", 260);
|
|
567287
|
+
const patterns = normalizeFailurePatterns(input.errorPatterns).slice(0, input.maxPatterns ?? 10);
|
|
567234
567288
|
if (patterns.length === 0 && recentCalls.length === 0 && modified.length === 0 && failedApproaches.length === 0 && !goal) {
|
|
567235
567289
|
return null;
|
|
567236
567290
|
}
|
|
@@ -568200,6 +568254,10 @@ function resolutionSystemPrompt() {
|
|
|
568200
568254
|
" - exit code 0 on an unrelated command does not resolve the request.",
|
|
568201
568255
|
" - Doing PART of the request, or adjacent work, is NOT resolution.",
|
|
568202
568256
|
" - If the request had multiple parts, EVERY part must be addressed.",
|
|
568257
|
+
" - If the original request explicitly allows a degraded fallback such as",
|
|
568258
|
+
" documenting/reporting a tool failure, that fallback can resolve the task",
|
|
568259
|
+
" only when the failure is clearly disclosed and the requested fallback",
|
|
568260
|
+
" artifact/report/verifier is evidenced.",
|
|
568203
568261
|
"",
|
|
568204
568262
|
"Respond with ONLY a JSON object, no prose, no code fences:",
|
|
568205
568263
|
'{"resolved": true|false,',
|
|
@@ -568211,6 +568269,25 @@ function resolutionSystemPrompt() {
|
|
|
568211
568269
|
"original request. When in doubt, resolved=false and name what is missing."
|
|
568212
568270
|
].join("\n");
|
|
568213
568271
|
}
|
|
568272
|
+
function detectExplicitDegradedCompletion(i2) {
|
|
568273
|
+
const original = i2.originalGoal.toLowerCase();
|
|
568274
|
+
const summary = i2.proposedSummary.toLowerCase();
|
|
568275
|
+
const evidence = `${i2.actionsDigest}
|
|
568276
|
+
${i2.evidenceDigest}`.toLowerCase();
|
|
568277
|
+
const permitsFallback = /\bif\b[\s\S]{0,160}\b(?:fails?|failed|failure|blocked|unavailable|cannot|can't|unable)\b[\s\S]{0,180}\b(?:document|report|note|record|summari[sz]e|explain)\b/.test(original) || /\b(?:document|report|note|record|summari[sz]e|explain)\b[\s\S]{0,180}\b(?:fails?|failed|failure|blocked|unavailable|cannot|can't|unable)\b/.test(original) || /\b(?:fallback|degraded|best effort|best-effort|honestly document|document honestly)\b/.test(original);
|
|
568278
|
+
if (!permitsFallback)
|
|
568279
|
+
return null;
|
|
568280
|
+
const disclosesFailure = /\b(?:fail(?:ed|ure)?|blocked|unable|could not|couldn't|cannot|can't|degraded|partial|not available|unavailable)\b/.test(summary);
|
|
568281
|
+
if (!disclosesFailure)
|
|
568282
|
+
return null;
|
|
568283
|
+
const hasFallbackEvidence = /\b(?:passed|success|succeeded|verified|wrote|created|saved|report|artifact|file changed|files changed|last test outcome: passed|exit code 0)\b/.test(evidence) || /\b(?:verifier|verification|report)\b/.test(summary);
|
|
568284
|
+
if (!hasFallbackEvidence)
|
|
568285
|
+
return null;
|
|
568286
|
+
return {
|
|
568287
|
+
accepted: true,
|
|
568288
|
+
reason: "original request explicitly allowed a degraded/failure-report fallback and the completion disclosed the failure with fallback evidence"
|
|
568289
|
+
};
|
|
568290
|
+
}
|
|
568214
568291
|
function buildResolutionPrompt(i2) {
|
|
568215
568292
|
return [
|
|
568216
568293
|
"ORIGINAL REQUEST (what the user actually asked for):",
|
|
@@ -568261,6 +568338,134 @@ var init_completion_resolution_verifier = __esm({
|
|
|
568261
568338
|
}
|
|
568262
568339
|
});
|
|
568263
568340
|
|
|
568341
|
+
// packages/orchestrator/dist/todoTruth.js
|
|
568342
|
+
function normalizeText2(value2) {
|
|
568343
|
+
return value2.toLowerCase().replace(/[_-]+/g, " ").replace(/[^a-z0-9./ ]+/g, " ").replace(/\s+/g, " ").trim();
|
|
568344
|
+
}
|
|
568345
|
+
function extractArg(argsKey, key) {
|
|
568346
|
+
if (!argsKey)
|
|
568347
|
+
return "";
|
|
568348
|
+
const re = new RegExp(`(?:^|,)${key}=([^,]+)`);
|
|
568349
|
+
return argsKey.match(re)?.[1]?.trim() ?? "";
|
|
568350
|
+
}
|
|
568351
|
+
function toolAliases(toolName) {
|
|
568352
|
+
const normalized = normalizeText2(toolName);
|
|
568353
|
+
const spaceAlias = normalizeText2(toolName.replace(/_/g, " "));
|
|
568354
|
+
const compactAlias = toolName.toLowerCase().replace(/[^a-z0-9]+/g, "");
|
|
568355
|
+
return [...new Set([normalized, spaceAlias, compactAlias].filter(Boolean))];
|
|
568356
|
+
}
|
|
568357
|
+
function todoMentionsFailedCall(todo, call) {
|
|
568358
|
+
if (NON_WORK_TOOLS.has(call.name))
|
|
568359
|
+
return false;
|
|
568360
|
+
const content = normalizeText2(todo.content);
|
|
568361
|
+
const compactContent2 = todo.content.toLowerCase().replace(/[^a-z0-9]+/g, "");
|
|
568362
|
+
const mentionsTool = toolAliases(call.name).some((alias) => {
|
|
568363
|
+
if (alias.length <= 2)
|
|
568364
|
+
return false;
|
|
568365
|
+
if (/^[a-z0-9]+$/.test(alias) && alias === call.name.toLowerCase().replace(/[^a-z0-9]+/g, "")) {
|
|
568366
|
+
return compactContent2.includes(alias);
|
|
568367
|
+
}
|
|
568368
|
+
return content.includes(alias);
|
|
568369
|
+
});
|
|
568370
|
+
if (!mentionsTool)
|
|
568371
|
+
return false;
|
|
568372
|
+
const action = normalizeText2(extractArg(call.argsKey, "action"));
|
|
568373
|
+
if (!action)
|
|
568374
|
+
return true;
|
|
568375
|
+
return content.includes(action) || action.length <= 2;
|
|
568376
|
+
}
|
|
568377
|
+
function evidenceLine(call) {
|
|
568378
|
+
const preview = String(call.outputPreview ?? "").split("\n").map((line) => line.trim()).find(Boolean);
|
|
568379
|
+
const action = extractArg(call.argsKey, "action");
|
|
568380
|
+
const detail = preview || "tool returned failure";
|
|
568381
|
+
return `${call.name}${action ? ` ${action}` : ""}: ${detail}`.slice(0, 260);
|
|
568382
|
+
}
|
|
568383
|
+
function hasLaterSuccessForSameFamily(calls, failedIndex) {
|
|
568384
|
+
const failed = calls[failedIndex];
|
|
568385
|
+
if (!failed)
|
|
568386
|
+
return false;
|
|
568387
|
+
const failedAction = normalizeText2(extractArg(failed.argsKey, "action"));
|
|
568388
|
+
for (let i2 = failedIndex + 1; i2 < calls.length; i2++) {
|
|
568389
|
+
const next = calls[i2];
|
|
568390
|
+
if (!next || next.success !== true || next.name !== failed.name)
|
|
568391
|
+
continue;
|
|
568392
|
+
const nextAction = normalizeText2(extractArg(next.argsKey, "action"));
|
|
568393
|
+
if (!failedAction || !nextAction || failedAction === nextAction)
|
|
568394
|
+
return true;
|
|
568395
|
+
}
|
|
568396
|
+
return false;
|
|
568397
|
+
}
|
|
568398
|
+
function firstUnresolvedChild(todo, childrenByParent) {
|
|
568399
|
+
const id = todo.id;
|
|
568400
|
+
if (!id)
|
|
568401
|
+
return null;
|
|
568402
|
+
const children2 = childrenByParent.get(id) ?? [];
|
|
568403
|
+
return children2.find((child) => child.status === "blocked") ?? children2.find((child) => child.status === "in_progress") ?? children2.find((child) => child.status === "pending") ?? null;
|
|
568404
|
+
}
|
|
568405
|
+
function reconcileCompletedTodosWithEvidence(input) {
|
|
568406
|
+
const nextTodos = input.todos.map((todo) => ({ ...todo }));
|
|
568407
|
+
const downgrades = [];
|
|
568408
|
+
const childrenByParent = /* @__PURE__ */ new Map();
|
|
568409
|
+
for (const todo of nextTodos) {
|
|
568410
|
+
if (!todo.parentId)
|
|
568411
|
+
continue;
|
|
568412
|
+
const arr = childrenByParent.get(todo.parentId) ?? [];
|
|
568413
|
+
arr.push(todo);
|
|
568414
|
+
childrenByParent.set(todo.parentId, arr);
|
|
568415
|
+
}
|
|
568416
|
+
for (const todo of nextTodos) {
|
|
568417
|
+
if (todo.status !== "completed")
|
|
568418
|
+
continue;
|
|
568419
|
+
const unresolvedChild = firstUnresolvedChild(todo, childrenByParent);
|
|
568420
|
+
if (unresolvedChild) {
|
|
568421
|
+
const childStatus = unresolvedChild.status;
|
|
568422
|
+
const targetStatus = childStatus === "blocked" ? "blocked" : "in_progress";
|
|
568423
|
+
const blocker2 = childStatus === "blocked" ? `Child todo blocked: ${unresolvedChild.content}${unresolvedChild.blocker ? ` (${unresolvedChild.blocker})` : ""}` : `Child todo not complete: [${childStatus}] ${unresolvedChild.content}`;
|
|
568424
|
+
downgrades.push({
|
|
568425
|
+
id: todo.id,
|
|
568426
|
+
content: todo.content,
|
|
568427
|
+
from: "completed",
|
|
568428
|
+
to: targetStatus,
|
|
568429
|
+
blocker: blocker2,
|
|
568430
|
+
evidence: blocker2
|
|
568431
|
+
});
|
|
568432
|
+
todo.status = targetStatus;
|
|
568433
|
+
todo.blocker = blocker2;
|
|
568434
|
+
continue;
|
|
568435
|
+
}
|
|
568436
|
+
const startTurn = todo.id && input.todoStartTurnById?.has(todo.id) ? input.todoStartTurnById.get(todo.id) : 0;
|
|
568437
|
+
const relevantCalls = input.toolCallLog.filter((call) => (call.turn ?? 0) >= startTurn);
|
|
568438
|
+
const failedIndex = relevantCalls.findIndex((call) => call.success === false && todoMentionsFailedCall(todo, call) && !hasLaterSuccessForSameFamily(relevantCalls, relevantCalls.indexOf(call)));
|
|
568439
|
+
if (failedIndex < 0)
|
|
568440
|
+
continue;
|
|
568441
|
+
const failed = relevantCalls[failedIndex];
|
|
568442
|
+
const evidence = evidenceLine(failed);
|
|
568443
|
+
const blocker = `Completion claim contradicted by failed ${failed.name} evidence. Reconfigure this subtask: verify whether the goal is already satisfied, choose a different target/tool, or leave the todo blocked with the root cause.`;
|
|
568444
|
+
downgrades.push({
|
|
568445
|
+
id: todo.id,
|
|
568446
|
+
content: todo.content,
|
|
568447
|
+
from: "completed",
|
|
568448
|
+
to: "blocked",
|
|
568449
|
+
blocker,
|
|
568450
|
+
evidence
|
|
568451
|
+
});
|
|
568452
|
+
todo.status = "blocked";
|
|
568453
|
+
todo.blocker = `${blocker} Evidence: ${evidence}`;
|
|
568454
|
+
}
|
|
568455
|
+
return {
|
|
568456
|
+
todos: nextTodos,
|
|
568457
|
+
changed: downgrades.length > 0,
|
|
568458
|
+
downgrades
|
|
568459
|
+
};
|
|
568460
|
+
}
|
|
568461
|
+
var NON_WORK_TOOLS;
|
|
568462
|
+
var init_todoTruth = __esm({
|
|
568463
|
+
"packages/orchestrator/dist/todoTruth.js"() {
|
|
568464
|
+
"use strict";
|
|
568465
|
+
NON_WORK_TOOLS = /* @__PURE__ */ new Set(["todo_write", "todo_read", "task_complete"]);
|
|
568466
|
+
}
|
|
568467
|
+
});
|
|
568468
|
+
|
|
568264
568469
|
// packages/orchestrator/dist/evidenceBranch.js
|
|
568265
568470
|
function buildStructuralPreview2(lines, path12, query) {
|
|
568266
568471
|
const n2 = lines.length;
|
|
@@ -570467,6 +570672,7 @@ var init_agenticRunner = __esm({
|
|
|
570467
570672
|
init_evidenceLedger();
|
|
570468
570673
|
init_adversaryStream();
|
|
570469
570674
|
init_completion_resolution_verifier();
|
|
570675
|
+
init_todoTruth();
|
|
570470
570676
|
init_evidenceBranch();
|
|
570471
570677
|
init_resolution_memory();
|
|
570472
570678
|
init_contextEngine();
|
|
@@ -570642,6 +570848,7 @@ var init_agenticRunner = __esm({
|
|
|
570642
570848
|
// Research: Kumaran et al. (2016) — complementary learning systems
|
|
570643
570849
|
// Fast learning from errors → immediate behavioral change
|
|
570644
570850
|
_errorPatterns = /* @__PURE__ */ new Map();
|
|
570851
|
+
_taskRelevantErrorPatterns = /* @__PURE__ */ new Map();
|
|
570645
570852
|
_errorGuidanceInjected = /* @__PURE__ */ new Set();
|
|
570646
570853
|
// prevent duplicate injection per turn
|
|
570647
570854
|
// REG-26 (Patch C): Reflexion-style structured failure memory. Indexed by
|
|
@@ -571219,6 +571426,145 @@ ${parts.join("\n")}
|
|
|
571219
571426
|
writesUserTaskArtifacts() {
|
|
571220
571427
|
return this.options.artifactMode === "user-task" && !this.options.subAgent;
|
|
571221
571428
|
}
|
|
571429
|
+
_backendModelLabel(backend = this.backend) {
|
|
571430
|
+
const b = backend;
|
|
571431
|
+
const direct = b["model"] ?? b["resolvedModel"] ?? b["modelName"];
|
|
571432
|
+
if (typeof direct === "string" && direct.trim())
|
|
571433
|
+
return direct.trim();
|
|
571434
|
+
const nested = b["config"];
|
|
571435
|
+
if (nested && typeof nested === "object") {
|
|
571436
|
+
const model = nested["model"];
|
|
571437
|
+
if (typeof model === "string" && model.trim())
|
|
571438
|
+
return model.trim();
|
|
571439
|
+
}
|
|
571440
|
+
return "unknown";
|
|
571441
|
+
}
|
|
571442
|
+
_emitModelResolutionTelemetry(purpose, turn) {
|
|
571443
|
+
try {
|
|
571444
|
+
const backendName = this.backend.constructor?.name ?? "unknown";
|
|
571445
|
+
const resolved = this._backendModelLabel(this.backend);
|
|
571446
|
+
this.emit({
|
|
571447
|
+
type: "status",
|
|
571448
|
+
content: `Model resolution: purpose=${purpose} resolved=${resolved} backend=${backendName}`,
|
|
571449
|
+
turn,
|
|
571450
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
571451
|
+
});
|
|
571452
|
+
} catch {
|
|
571453
|
+
}
|
|
571454
|
+
}
|
|
571455
|
+
_cosineSimilarity(a2, b) {
|
|
571456
|
+
if (!a2 || !b || a2.length !== b.length || a2.length === 0)
|
|
571457
|
+
return 0;
|
|
571458
|
+
let dot = 0;
|
|
571459
|
+
let na = 0;
|
|
571460
|
+
let nb = 0;
|
|
571461
|
+
for (let i2 = 0; i2 < a2.length; i2++) {
|
|
571462
|
+
const av = a2[i2] ?? 0;
|
|
571463
|
+
const bv = b[i2] ?? 0;
|
|
571464
|
+
dot += av * bv;
|
|
571465
|
+
na += av * av;
|
|
571466
|
+
nb += bv * bv;
|
|
571467
|
+
}
|
|
571468
|
+
const denom = Math.sqrt(na) * Math.sqrt(nb);
|
|
571469
|
+
return denom > 0 ? dot / denom : 0;
|
|
571470
|
+
}
|
|
571471
|
+
_embeddingBaseUrl() {
|
|
571472
|
+
const raw = this.backend["baseUrl"] || "http://localhost:11434";
|
|
571473
|
+
return raw.replace(/\/v1\/?$/, "");
|
|
571474
|
+
}
|
|
571475
|
+
_failurePatternText(pattern) {
|
|
571476
|
+
return [
|
|
571477
|
+
`signature: ${pattern.signature}`,
|
|
571478
|
+
pattern.tool ? `tool: ${pattern.tool}` : "",
|
|
571479
|
+
pattern.errorType ? `errorType: ${pattern.errorType}` : "",
|
|
571480
|
+
pattern.guidance ? `guidance: ${pattern.guidance}` : ""
|
|
571481
|
+
].filter(Boolean).join("\n");
|
|
571482
|
+
}
|
|
571483
|
+
async _inferRelevantFailurePatternSignatures(taskGoal, candidates, maxPatterns) {
|
|
571484
|
+
if (candidates.length === 0)
|
|
571485
|
+
return /* @__PURE__ */ new Set();
|
|
571486
|
+
try {
|
|
571487
|
+
this._emitModelResolutionTelemetry("failure_pattern_relevance");
|
|
571488
|
+
const backend = this._auxInferenceBackend();
|
|
571489
|
+
const resp = await backend.chatCompletion({
|
|
571490
|
+
messages: [
|
|
571491
|
+
{
|
|
571492
|
+
role: "system",
|
|
571493
|
+
content: "You select prior failure patterns that are semantically relevant to the active task. Return only JSON."
|
|
571494
|
+
},
|
|
571495
|
+
{
|
|
571496
|
+
role: "user",
|
|
571497
|
+
content: JSON.stringify({
|
|
571498
|
+
taskGoal,
|
|
571499
|
+
max: maxPatterns,
|
|
571500
|
+
candidates: candidates.slice(0, 30).map((pattern) => ({
|
|
571501
|
+
signature: pattern.signature,
|
|
571502
|
+
tool: pattern.tool,
|
|
571503
|
+
errorType: pattern.errorType,
|
|
571504
|
+
guidance: pattern.guidance
|
|
571505
|
+
})),
|
|
571506
|
+
outputSchema: { relevant: ["signature"] }
|
|
571507
|
+
})
|
|
571508
|
+
}
|
|
571509
|
+
],
|
|
571510
|
+
tools: [],
|
|
571511
|
+
temperature: 0,
|
|
571512
|
+
maxTokens: 500,
|
|
571513
|
+
timeoutMs: 2e4
|
|
571514
|
+
});
|
|
571515
|
+
const raw = resp.choices?.[0]?.message?.content ?? "";
|
|
571516
|
+
const start2 = raw.indexOf("{");
|
|
571517
|
+
const end = raw.lastIndexOf("}");
|
|
571518
|
+
if (start2 < 0 || end <= start2)
|
|
571519
|
+
return /* @__PURE__ */ new Set();
|
|
571520
|
+
const parsed = JSON.parse(raw.slice(start2, end + 1));
|
|
571521
|
+
return new Set((parsed.relevant ?? []).map((item) => String(item)).filter((signature) => candidates.some((pattern) => pattern.signature === signature)).slice(0, maxPatterns));
|
|
571522
|
+
} catch {
|
|
571523
|
+
return /* @__PURE__ */ new Set();
|
|
571524
|
+
}
|
|
571525
|
+
}
|
|
571526
|
+
async _selectTaskRelevantErrorPatterns(taskGoal, maxPatterns) {
|
|
571527
|
+
const candidates = normalizeFailurePatterns(this._errorPatterns).slice(0, 40);
|
|
571528
|
+
if (!taskGoal.trim() || candidates.length === 0)
|
|
571529
|
+
return /* @__PURE__ */ new Map();
|
|
571530
|
+
const selected = /* @__PURE__ */ new Map();
|
|
571531
|
+
let selectedBy = "none";
|
|
571532
|
+
try {
|
|
571533
|
+
const embeddings = await generateEmbeddingBatch([taskGoal, ...candidates.map((pattern) => this._failurePatternText(pattern))], { baseUrl: this._embeddingBaseUrl(), timeoutMs: 12e3 });
|
|
571534
|
+
const query = embeddings[0]?.vector;
|
|
571535
|
+
const minScore = Number.parseFloat(process.env["OMNIUS_FAILURE_PATTERN_SIM_MIN"] ?? "0.58");
|
|
571536
|
+
if (query) {
|
|
571537
|
+
const scored = candidates.map((pattern, index) => ({
|
|
571538
|
+
pattern,
|
|
571539
|
+
score: embeddings[index + 1]?.vector ? this._cosineSimilarity(query, embeddings[index + 1].vector) : 0
|
|
571540
|
+
})).filter((item) => item.score >= minScore).sort((a2, b) => b.score - a2.score).slice(0, maxPatterns);
|
|
571541
|
+
for (const item of scored) {
|
|
571542
|
+
const raw = this._errorPatterns.get(item.pattern.signature);
|
|
571543
|
+
if (raw)
|
|
571544
|
+
selected.set(item.pattern.signature, raw);
|
|
571545
|
+
}
|
|
571546
|
+
if (selected.size > 0)
|
|
571547
|
+
selectedBy = "vector";
|
|
571548
|
+
}
|
|
571549
|
+
} catch {
|
|
571550
|
+
}
|
|
571551
|
+
if (selected.size === 0) {
|
|
571552
|
+
const relevant = await this._inferRelevantFailurePatternSignatures(taskGoal, candidates, maxPatterns);
|
|
571553
|
+
for (const signature of relevant) {
|
|
571554
|
+
const raw = this._errorPatterns.get(signature);
|
|
571555
|
+
if (raw)
|
|
571556
|
+
selected.set(signature, raw);
|
|
571557
|
+
}
|
|
571558
|
+
if (selected.size > 0)
|
|
571559
|
+
selectedBy = "inference";
|
|
571560
|
+
}
|
|
571561
|
+
this.emit({
|
|
571562
|
+
type: "status",
|
|
571563
|
+
content: `Failure handoff semantic selection: ${selected.size}/${candidates.length} persisted pattern(s) selected by ${selectedBy}`,
|
|
571564
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
571565
|
+
});
|
|
571566
|
+
return selected;
|
|
571567
|
+
}
|
|
571222
571568
|
_persistCompletionContract(contract) {
|
|
571223
571569
|
if (!this.writesUserTaskArtifacts())
|
|
571224
571570
|
return;
|
|
@@ -572584,7 +572930,7 @@ ${context2 ?? ""}`;
|
|
|
572584
572930
|
`Task affect: uncertainty=${affect.uncertainty.toFixed(2)} frustration=${affect.frustration.toFixed(2)} confidence=${affect.confidence.toFixed(2)} momentum=${affect.momentum.toFixed(2)}`
|
|
572585
572931
|
].join("\n");
|
|
572586
572932
|
}
|
|
572587
|
-
_buildPreflightTaskMemoryRecall(taskGoal) {
|
|
572933
|
+
async _buildPreflightTaskMemoryRecall(taskGoal) {
|
|
572588
572934
|
if (process.env["OMNIUS_DISABLE_PREFLIGHT_MEMORY_RECALL"] === "1")
|
|
572589
572935
|
return "";
|
|
572590
572936
|
if (this.options.stateDir || this.options.subAgent)
|
|
@@ -572593,17 +572939,31 @@ ${context2 ?? ""}`;
|
|
|
572593
572939
|
return "";
|
|
572594
572940
|
try {
|
|
572595
572941
|
const query = taskGoal.slice(0, 1e3);
|
|
572596
|
-
const
|
|
572597
|
-
|
|
572942
|
+
const embedding = await generateEmbedding(query, {
|
|
572943
|
+
baseUrl: this._embeddingBaseUrl(),
|
|
572944
|
+
timeoutMs: 1e4
|
|
572945
|
+
});
|
|
572946
|
+
if (!embedding?.vector)
|
|
572947
|
+
return "";
|
|
572948
|
+
const results = this._episodeStore.search({ query, limit: 12 }, {
|
|
572949
|
+
queryEmbedding: embedding.vector,
|
|
572950
|
+
lexicalWeight: 0,
|
|
572951
|
+
embeddingWeight: 1
|
|
572952
|
+
});
|
|
572953
|
+
const minScore = Number.parseFloat(process.env["OMNIUS_PREFLIGHT_MEMORY_SIM_MIN"] ?? "0.58");
|
|
572954
|
+
const useful = results.map((entry) => ({
|
|
572955
|
+
entry,
|
|
572956
|
+
score: entry.embedding ? this._cosineSimilarity(embedding.vector, entry.embedding) : 0
|
|
572957
|
+
})).filter(({ entry, score }) => typeof entry.content === "string" && entry.content.trim().length >= 30 && score >= minScore).sort((a2, b) => b.score - a2.score).slice(0, 3);
|
|
572598
572958
|
if (useful.length === 0)
|
|
572599
572959
|
return "";
|
|
572600
|
-
const lines = useful.map((entry, index) => {
|
|
572601
|
-
const tool = typeof entry.
|
|
572602
|
-
return `${index + 1}. ${entry.content.replace(/\s+/g, " ").slice(0, 260)}${tool}`;
|
|
572960
|
+
const lines = useful.map(({ entry, score }, index) => {
|
|
572961
|
+
const tool = typeof entry.toolName === "string" && entry.toolName ? ` tool=${entry.toolName}` : "";
|
|
572962
|
+
return `${index + 1}. sim=${score.toFixed(3)} ${entry.content.replace(/\s+/g, " ").slice(0, 260)}${tool}`;
|
|
572603
572963
|
});
|
|
572604
572964
|
return [
|
|
572605
572965
|
`[PREFLIGHT MEMORY RECALL]`,
|
|
572606
|
-
`Retrieved
|
|
572966
|
+
`Retrieved vector-similar prior episodes before the first action. Use these as hypotheses, not truth; verify against current files/UI.`,
|
|
572607
572967
|
...lines,
|
|
572608
572968
|
`If the current task resembles one of these, prefer the remembered working verification path and avoid the remembered failure pattern.`
|
|
572609
572969
|
].join("\n");
|
|
@@ -572716,9 +573076,26 @@ ${shellLines.join("\n")}` : "Commands run: none"
|
|
|
572716
573076
|
const failCount = toolCallLog.filter((e2) => e2.success === false).length;
|
|
572717
573077
|
evidenceParts.push(`Failed tool calls this run: ${failCount}`);
|
|
572718
573078
|
const evidenceDigest = evidenceParts.join("\n");
|
|
573079
|
+
const degraded = detectExplicitDegradedCompletion({
|
|
573080
|
+
originalGoal,
|
|
573081
|
+
actionsDigest,
|
|
573082
|
+
evidenceDigest,
|
|
573083
|
+
proposedSummary
|
|
573084
|
+
});
|
|
573085
|
+
if (degraded) {
|
|
573086
|
+
this._resolutionGateRejections = 0;
|
|
573087
|
+
this.emit({
|
|
573088
|
+
type: "status",
|
|
573089
|
+
content: `Resolution gate accepted explicit degraded completion: ${degraded.reason}`,
|
|
573090
|
+
turn,
|
|
573091
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
573092
|
+
});
|
|
573093
|
+
return { proceed: true };
|
|
573094
|
+
}
|
|
572719
573095
|
let verdict = null;
|
|
572720
573096
|
try {
|
|
572721
573097
|
const backend = this._auxInferenceBackend();
|
|
573098
|
+
this._emitModelResolutionTelemetry("completion_resolution", turn);
|
|
572722
573099
|
for (let attempt = 0; attempt < 2 && !verdict; attempt++) {
|
|
572723
573100
|
const resp = await backend.chatCompletion({
|
|
572724
573101
|
messages: [
|
|
@@ -576151,6 +576528,7 @@ Respond with your assessment, then take action.`;
|
|
|
576151
576528
|
this.pendingUserMessages.length = 0;
|
|
576152
576529
|
const persistentTaskGoal = cleanForStorage(actualUserGoal || "") || cleanedTask;
|
|
576153
576530
|
const userGoal = persistentTaskGoal.slice(0, 500);
|
|
576531
|
+
this._taskRelevantErrorPatterns = process.env["OMNIUS_DISABLE_FAILURE_HANDOFF"] === "1" ? /* @__PURE__ */ new Map() : await this._selectTaskRelevantErrorPatterns(persistentTaskGoal, 10);
|
|
576154
576532
|
this._taskState = {
|
|
576155
576533
|
goal: userGoal,
|
|
576156
576534
|
originalGoal: userGoal,
|
|
@@ -576195,6 +576573,7 @@ Respond with your assessment, then take action.`;
|
|
|
576195
576573
|
contextWindowSize: this.options.contextWindowSize ?? 0,
|
|
576196
576574
|
verbose: false
|
|
576197
576575
|
});
|
|
576576
|
+
this._emitModelResolutionTelemetry("main");
|
|
576198
576577
|
this._hookManager.runSessionHook("session_start", this._sessionId);
|
|
576199
576578
|
if (this.writesUserTaskArtifacts()) {
|
|
576200
576579
|
this._initializeCompletionContract(task, context2, actualUserGoal);
|
|
@@ -576425,7 +576804,7 @@ TASK: ${scrubbedTask}` : scrubbedTask;
|
|
|
576425
576804
|
...missionCompletionContract ? [{ role: "system", content: missionCompletionContract }] : [],
|
|
576426
576805
|
{ role: "user", content: userContent }
|
|
576427
576806
|
];
|
|
576428
|
-
const preflightMemoryRecall = this._buildPreflightTaskMemoryRecall(persistentTaskGoal);
|
|
576807
|
+
const preflightMemoryRecall = await this._buildPreflightTaskMemoryRecall(persistentTaskGoal);
|
|
576429
576808
|
if (preflightMemoryRecall) {
|
|
576430
576809
|
messages2.splice(messages2.length - 1, 0, {
|
|
576431
576810
|
role: "system",
|
|
@@ -576545,7 +576924,7 @@ TASK: ${scrubbedTask}` : scrubbedTask;
|
|
|
576545
576924
|
try {
|
|
576546
576925
|
const failureHandoff = buildFailureModeHandoff({
|
|
576547
576926
|
taskGoal: persistentTaskGoal,
|
|
576548
|
-
errorPatterns: this.
|
|
576927
|
+
errorPatterns: this._taskRelevantErrorPatterns,
|
|
576549
576928
|
toolCallLog,
|
|
576550
576929
|
taskState: this._taskState,
|
|
576551
576930
|
maxPatterns: 10,
|
|
@@ -580022,13 +580401,15 @@ Respond with EXACTLY this structure before your next tool call:
|
|
|
580022
580401
|
default:
|
|
580023
580402
|
guidance = `This tool failed previously with a similar error. Review the error message carefully and adjust your approach before retrying.`;
|
|
580024
580403
|
}
|
|
580025
|
-
|
|
580404
|
+
const learnedPattern = {
|
|
580026
580405
|
count,
|
|
580027
580406
|
guidance,
|
|
580028
580407
|
lastSeen: Date.now(),
|
|
580029
580408
|
tool: tc.name,
|
|
580030
580409
|
errorType
|
|
580031
|
-
}
|
|
580410
|
+
};
|
|
580411
|
+
this._errorPatterns.set(sig, learnedPattern);
|
|
580412
|
+
this._taskRelevantErrorPatterns.set(sig, learnedPattern);
|
|
580032
580413
|
if (this._failureStore) {
|
|
580033
580414
|
try {
|
|
580034
580415
|
this._failureStore.insert({
|
|
@@ -580078,13 +580459,48 @@ Respond with EXACTLY this structure before your next tool call:
|
|
|
580078
580459
|
}
|
|
580079
580460
|
if (tc.name === "todo_write") {
|
|
580080
580461
|
try {
|
|
580081
|
-
|
|
580462
|
+
let _todosNow = this.readSessionTodos() || [];
|
|
580082
580463
|
for (const _tp of _todosNow) {
|
|
580083
580464
|
const _tpId = _tp.id;
|
|
580084
580465
|
if (_tp.status === "in_progress" && _tpId && !this._todoInProgressTurn.has(_tpId)) {
|
|
580085
580466
|
this._todoInProgressTurn.set(_tpId, turn);
|
|
580086
580467
|
}
|
|
580087
580468
|
}
|
|
580469
|
+
const truth = reconcileCompletedTodosWithEvidence({
|
|
580470
|
+
todos: _todosNow,
|
|
580471
|
+
toolCallLog,
|
|
580472
|
+
todoStartTurnById: this._todoInProgressTurn
|
|
580473
|
+
});
|
|
580474
|
+
if (truth.changed) {
|
|
580475
|
+
const sid = this._sessionId || process.env["OMNIUS_SESSION_ID"] || "default";
|
|
580476
|
+
writeTodos(sid, truth.todos.map((t2) => ({
|
|
580477
|
+
id: t2.id,
|
|
580478
|
+
content: t2.content,
|
|
580479
|
+
status: t2.status,
|
|
580480
|
+
parentId: t2.parentId,
|
|
580481
|
+
blocker: t2.blocker,
|
|
580482
|
+
verifyCommand: t2.verifyCommand,
|
|
580483
|
+
declaredArtifacts: t2.declaredArtifacts
|
|
580484
|
+
})));
|
|
580485
|
+
_todosNow = this.readSessionTodos() || truth.todos;
|
|
580486
|
+
const downgradeLines = truth.downgrades.slice(0, 6).map((d2) => `- ${d2.content}: ${d2.from} -> ${d2.to}; ${d2.evidence}`).join("\n");
|
|
580487
|
+
messages2.push({
|
|
580488
|
+
role: "system",
|
|
580489
|
+
content: [
|
|
580490
|
+
`[TODO TRUTH RECONCILIATION]`,
|
|
580491
|
+
`One or more completed todo claims contradicted the evidence or nested child status and were rewritten in the active todo list.`,
|
|
580492
|
+
downgradeLines,
|
|
580493
|
+
``,
|
|
580494
|
+
`Reconfigure the affected subtask tree now: read/verify the current state, choose a different tool or target if the prior route failed, or leave the child todo blocked with the root cause. Do not mark a parent completed until every child is completed with evidence.`
|
|
580495
|
+
].join("\n")
|
|
580496
|
+
});
|
|
580497
|
+
this.emit({
|
|
580498
|
+
type: "status",
|
|
580499
|
+
content: `Todo truth reconciled ${truth.downgrades.length} completed claim(s) from evidence/nested child state`,
|
|
580500
|
+
turn,
|
|
580501
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
580502
|
+
});
|
|
580503
|
+
}
|
|
580088
580504
|
if (!this._newFieldNudgeFired) {
|
|
580089
580505
|
this._todoWritesObservedForNudge++;
|
|
580090
580506
|
const _anyFieldUsed = _todosNow.some((t2) => typeof t2.verifyCommand === "string" || Array.isArray(t2.declaredArtifacts));
|
|
@@ -580824,7 +581240,7 @@ Then use file_read on individual FILES inside it.`);
|
|
|
580824
581240
|
if (process.env["OMNIUS_DISABLE_FAILURE_HANDOFF"] !== "1" && !result.success && turn - lastFailureHandoffTurn >= 4) {
|
|
580825
581241
|
const runtimeHandoff = buildFailureModeHandoff({
|
|
580826
581242
|
taskGoal: persistentTaskGoal,
|
|
580827
|
-
errorPatterns: this.
|
|
581243
|
+
errorPatterns: this._taskRelevantErrorPatterns,
|
|
580828
581244
|
toolCallLog,
|
|
580829
581245
|
taskState: this._taskState,
|
|
580830
581246
|
maxPatterns: 5,
|
|
@@ -584348,7 +584764,7 @@ ${content.slice(0, 8e3)}
|
|
|
584348
584764
|
try {
|
|
584349
584765
|
const compactFailureHandoff = buildFailureModeHandoff({
|
|
584350
584766
|
taskGoal: this._taskState.goal,
|
|
584351
|
-
errorPatterns: this.
|
|
584767
|
+
errorPatterns: this._taskRelevantErrorPatterns,
|
|
584352
584768
|
taskState: this._taskState,
|
|
584353
584769
|
maxPatterns: 6,
|
|
584354
584770
|
maxRecentCalls: 0
|
|
@@ -613124,6 +613540,33 @@ function buildTodoProgressBar(todos, maxWidth) {
|
|
|
613124
613540
|
if (truncated && maxWidth > 0) out += `${DIM_LABEL}…${RESET3}`;
|
|
613125
613541
|
return out;
|
|
613126
613542
|
}
|
|
613543
|
+
function orderTodosForDisplay(todos) {
|
|
613544
|
+
const byParent = /* @__PURE__ */ new Map();
|
|
613545
|
+
const byId = new Set(todos.map((t2) => t2.id));
|
|
613546
|
+
const roots = [];
|
|
613547
|
+
for (const todo of todos) {
|
|
613548
|
+
if (todo.parentId && byId.has(todo.parentId)) {
|
|
613549
|
+
const arr = byParent.get(todo.parentId) ?? [];
|
|
613550
|
+
arr.push(todo);
|
|
613551
|
+
byParent.set(todo.parentId, arr);
|
|
613552
|
+
} else {
|
|
613553
|
+
roots.push(todo);
|
|
613554
|
+
}
|
|
613555
|
+
}
|
|
613556
|
+
const out = [];
|
|
613557
|
+
const seen = /* @__PURE__ */ new Set();
|
|
613558
|
+
const visit = (todo, depth) => {
|
|
613559
|
+
if (seen.has(todo.id)) return;
|
|
613560
|
+
seen.add(todo.id);
|
|
613561
|
+
out.push({ ...todo, depth: Math.min(depth, 4) });
|
|
613562
|
+
for (const child of byParent.get(todo.id) ?? []) {
|
|
613563
|
+
visit(child, depth + 1);
|
|
613564
|
+
}
|
|
613565
|
+
};
|
|
613566
|
+
for (const root of roots) visit(root, 0);
|
|
613567
|
+
for (const todo of todos) visit(todo, 0);
|
|
613568
|
+
return out;
|
|
613569
|
+
}
|
|
613127
613570
|
function render() {
|
|
613128
613571
|
if (!_enabled) return;
|
|
613129
613572
|
if (!panelEffectivelyVisible()) {
|
|
@@ -613149,16 +613592,18 @@ function render() {
|
|
|
613149
613592
|
const progressBar = buildTodoProgressBar(_lastTodos, maxBarWidth);
|
|
613150
613593
|
const headerText = `${headerPrefix}${progressBar}`;
|
|
613151
613594
|
lines.push(headerText);
|
|
613152
|
-
const
|
|
613595
|
+
const displayTodos = orderTodosForDisplay(_lastTodos);
|
|
613596
|
+
const visible = displayTodos.slice(0, MAX_VISIBLE_ROWS - 1);
|
|
613153
613597
|
for (const t2 of visible) {
|
|
613154
613598
|
const { mark, color } = statusToAnsi(t2.status);
|
|
613155
613599
|
const contentWidth = Math.max(4, cols - 8);
|
|
613156
|
-
const
|
|
613600
|
+
const indent2 = t2.depth > 0 ? `${" ".repeat(t2.depth - 1)}- ` : "";
|
|
613601
|
+
const contentText = indent2 + t2.content + (t2.blocker ? ` (blocked: ${t2.blocker})` : "");
|
|
613157
613602
|
const truncated = truncate2(contentText, contentWidth);
|
|
613158
613603
|
lines.push(`${color}${mark}${RESET3} ${color}${truncated}${RESET3}`);
|
|
613159
613604
|
}
|
|
613160
|
-
if (
|
|
613161
|
-
const more =
|
|
613605
|
+
if (displayTodos.length > visible.length) {
|
|
613606
|
+
const more = displayTodos.length - visible.length;
|
|
613162
613607
|
lines[lines.length - 1] = `${DIM_LABEL}… +${more} more${RESET3}`;
|
|
613163
613608
|
}
|
|
613164
613609
|
let out = HIDE + SAVE;
|
|
@@ -717470,6 +717915,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
717470
717915
|
},
|
|
717471
717916
|
async () => {
|
|
717472
717917
|
const result = await runner.run(effectiveTask, systemContext);
|
|
717918
|
+
_apiCallbacks?.onRunResult?.(result);
|
|
717473
717919
|
const tokens = {
|
|
717474
717920
|
total: result.totalTokens,
|
|
717475
717921
|
estimated: result.estimatedTokens
|
|
@@ -723752,6 +724198,7 @@ async function runWithTUI(task, config, repoPath2, callbacks) {
|
|
|
723752
724198
|
}
|
|
723753
724199
|
}
|
|
723754
724200
|
_apiCallbacks = callbacks ?? null;
|
|
724201
|
+
const headlessMode = Boolean(callbacks);
|
|
723755
724202
|
await bootstrapMcpAndPlugins(repoRoot);
|
|
723756
724203
|
renderCompactHeader(config.model);
|
|
723757
724204
|
renderUserMessage(task);
|
|
@@ -723762,6 +724209,10 @@ async function runWithTUI(task, config, repoPath2, callbacks) {
|
|
|
723762
724209
|
try {
|
|
723763
724210
|
const handle2 = startTask(task, config, repoRoot);
|
|
723764
724211
|
await handle2.promise;
|
|
724212
|
+
if (headlessMode) {
|
|
724213
|
+
_apiCallbacks = null;
|
|
724214
|
+
return;
|
|
724215
|
+
}
|
|
723765
724216
|
try {
|
|
723766
724217
|
const ikDir = join174(repoRoot, ".omnius", "identity");
|
|
723767
724218
|
const ikFile = join174(ikDir, "self-state.json");
|
|
@@ -724045,6 +724496,10 @@ Rules:
|
|
|
724045
724496
|
} catch {
|
|
724046
724497
|
}
|
|
724047
724498
|
} catch (err) {
|
|
724499
|
+
if (headlessMode) {
|
|
724500
|
+
_apiCallbacks = null;
|
|
724501
|
+
throw err;
|
|
724502
|
+
}
|
|
724048
724503
|
try {
|
|
724049
724504
|
const ikFile = join174(repoRoot, ".omnius", "identity", "self-state.json");
|
|
724050
724505
|
if (existsSync161(ikFile)) {
|
|
@@ -724271,6 +724726,7 @@ async function runJson(task, config, repoPath2) {
|
|
|
724271
724726
|
let result;
|
|
724272
724727
|
const assistantTexts = [];
|
|
724273
724728
|
const toolCallLog = [];
|
|
724729
|
+
let runnerResult = null;
|
|
724274
724730
|
try {
|
|
724275
724731
|
await runWithTUI(task, config, repoPath2, {
|
|
724276
724732
|
onAssistantText: (text2) => {
|
|
@@ -724294,13 +724750,29 @@ async function runJson(task, config, repoPath2) {
|
|
|
724294
724750
|
},
|
|
724295
724751
|
onStatus: (content) => {
|
|
724296
724752
|
origWrite(JSON.stringify({ type: "status", content }) + "\n");
|
|
724753
|
+
},
|
|
724754
|
+
onRunResult: (runResult) => {
|
|
724755
|
+
runnerResult = {
|
|
724756
|
+
status: runResult.status,
|
|
724757
|
+
completed: runResult.completed,
|
|
724758
|
+
summary: runResult.summary,
|
|
724759
|
+
turns: runResult.turns,
|
|
724760
|
+
toolCalls: runResult.toolCalls,
|
|
724761
|
+
filesEdited: runResult.filesEdited,
|
|
724762
|
+
testsRun: runResult.testsRun
|
|
724763
|
+
};
|
|
724297
724764
|
}
|
|
724298
724765
|
});
|
|
724766
|
+
const rr = runnerResult;
|
|
724299
724767
|
result = {
|
|
724300
|
-
status: "completed",
|
|
724301
|
-
summary: extractSummary(captured),
|
|
724768
|
+
status: rr?.completed ? "completed" : rr?.status ?? "completed",
|
|
724769
|
+
summary: rr?.summary || extractSummary(captured),
|
|
724770
|
+
turns: rr?.turns,
|
|
724771
|
+
toolCalls: rr?.toolCalls,
|
|
724772
|
+
filesModified: rr?.filesEdited,
|
|
724773
|
+
testsRun: rr?.testsRun,
|
|
724302
724774
|
durationMs: Date.now() - startTime,
|
|
724303
|
-
exitCode: 0
|
|
724775
|
+
exitCode: rr && !rr.completed ? 2 : 0
|
|
724304
724776
|
};
|
|
724305
724777
|
} catch (err) {
|
|
724306
724778
|
result = {
|
|
@@ -724324,7 +724796,14 @@ async function runJson(task, config, repoPath2) {
|
|
|
724324
724796
|
result.tool_calls = toolCallLog;
|
|
724325
724797
|
}
|
|
724326
724798
|
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
724327
|
-
if (result.exitCode !== 0) process.exit(
|
|
724799
|
+
if (result.exitCode !== 0) process.exit(result.exitCode);
|
|
724800
|
+
if (shouldForceJsonExit()) process.exit(0);
|
|
724801
|
+
}
|
|
724802
|
+
function shouldForceJsonExit() {
|
|
724803
|
+
if (process.env["OMNIUS_JSON_NO_FORCE_EXIT"] === "1") return false;
|
|
724804
|
+
if (process.env["VITEST"] === "true" || process.env["NODE_ENV"] === "test")
|
|
724805
|
+
return false;
|
|
724806
|
+
return true;
|
|
724328
724807
|
}
|
|
724329
724808
|
function extractSummary(captured) {
|
|
724330
724809
|
const all2 = captured.join("");
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.370",
|
|
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.370",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
package/package.json
CHANGED