open-agents-ai 0.187.479 → 0.187.481
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 +269 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -512229,6 +512229,139 @@ var init_critic = __esm({
|
|
|
512229
512229
|
}
|
|
512230
512230
|
});
|
|
512231
512231
|
|
|
512232
|
+
// packages/orchestrator/dist/reflection.js
|
|
512233
|
+
function extractSubject(errorText) {
|
|
512234
|
+
if (!errorText)
|
|
512235
|
+
return null;
|
|
512236
|
+
const PATTERNS = [
|
|
512237
|
+
// Quoted module / type / symbol after recognizable phrases
|
|
512238
|
+
/cannot find (?:module|name|type|symbol|reference|file|namespace)\s+['"`]([^'"`\n]{1,80})['"`]/i,
|
|
512239
|
+
/(?:undefined|unresolved)\s+(?:reference|import|symbol)\s+(?:to\s+)?['"`]([^'"`\n]{1,80})['"`]/i,
|
|
512240
|
+
/['"`]([^'"`\n]{1,80})['"`]\s+is not (?:a function|defined|assignable)/i,
|
|
512241
|
+
/is not assignable to (?:type|parameter)\s+['"`]([^'"`\n]{1,80})['"`]/i,
|
|
512242
|
+
/\btype\s+['"`]([^'"`\n]{1,80})['"`]\s+is not assignable/i,
|
|
512243
|
+
/\benoent\b[^'"`\n]*['"`]([^'"`\n]{1,200})['"`]/i,
|
|
512244
|
+
/\b(?:permission denied|eacces)\b[^'"`\n]*['"`]([^'"`\n]{1,200})['"`]/i,
|
|
512245
|
+
/no such file or directory[^'"`\n]*['"`]([^'"`\n]{1,200})['"`]/i,
|
|
512246
|
+
/\b([a-z_][a-z0-9_]*)\s+is not defined\b/i,
|
|
512247
|
+
/\b(?:property|method|attribute)\s+['"`]([^'"`\n]{1,80})['"`]\s+(?:does not exist|not found)/i,
|
|
512248
|
+
/\bcannot resolve\s+['"`]?([^'"`\n\s]{1,120})['"`]?/i,
|
|
512249
|
+
/\bmodule not found:?\s+['"`]?([^'"`\n\s]{1,120})['"`]?/i
|
|
512250
|
+
];
|
|
512251
|
+
for (const re of PATTERNS) {
|
|
512252
|
+
const m2 = errorText.match(re);
|
|
512253
|
+
if (m2 && m2[1]) {
|
|
512254
|
+
const subj = m2[1].trim();
|
|
512255
|
+
if (subj.length > 0 && subj.length <= 200)
|
|
512256
|
+
return subj;
|
|
512257
|
+
}
|
|
512258
|
+
}
|
|
512259
|
+
return null;
|
|
512260
|
+
}
|
|
512261
|
+
function errorSignature(errorText) {
|
|
512262
|
+
if (!errorText)
|
|
512263
|
+
return "";
|
|
512264
|
+
const norm = errorText.replace(/\r?\n/g, " ").replace(/\s+/g, " ").replace(/^\s*error:\s*/i, "").trim().toLowerCase();
|
|
512265
|
+
return norm.slice(0, 50);
|
|
512266
|
+
}
|
|
512267
|
+
function categorizeError(errorText) {
|
|
512268
|
+
if (!errorText)
|
|
512269
|
+
return "unknown";
|
|
512270
|
+
for (const { category, re } of CATEGORY_PATTERNS) {
|
|
512271
|
+
if (re.test(errorText))
|
|
512272
|
+
return category;
|
|
512273
|
+
}
|
|
512274
|
+
return "unknown";
|
|
512275
|
+
}
|
|
512276
|
+
function buildStem(toolName, args) {
|
|
512277
|
+
if (!args || Object.keys(args).length === 0)
|
|
512278
|
+
return toolName;
|
|
512279
|
+
const entries = Object.entries(args).sort(([a2], [b]) => a2.localeCompare(b));
|
|
512280
|
+
const first2 = entries[0];
|
|
512281
|
+
const v = typeof first2[1] === "string" ? first2[1] : JSON.stringify(first2[1]);
|
|
512282
|
+
return `${toolName}:${first2[0]}=${v.slice(0, 60)}`;
|
|
512283
|
+
}
|
|
512284
|
+
function firstSignalLine(errorText) {
|
|
512285
|
+
if (!errorText)
|
|
512286
|
+
return "";
|
|
512287
|
+
const lines = errorText.split(/\r?\n/);
|
|
512288
|
+
for (const raw of lines) {
|
|
512289
|
+
const line = raw.trim();
|
|
512290
|
+
if (!line)
|
|
512291
|
+
continue;
|
|
512292
|
+
if (line === "Error:" || line === "error:")
|
|
512293
|
+
continue;
|
|
512294
|
+
return line.slice(0, 200);
|
|
512295
|
+
}
|
|
512296
|
+
return errorText.slice(0, 200);
|
|
512297
|
+
}
|
|
512298
|
+
function synthesizeReflection(input) {
|
|
512299
|
+
const category = categorizeError(input.errorText);
|
|
512300
|
+
const stem = buildStem(input.toolName, input.args);
|
|
512301
|
+
const argPreview = JSON.stringify(input.args ?? {}).slice(0, 120);
|
|
512302
|
+
const subject = extractSubject(input.errorText);
|
|
512303
|
+
const sigs = new Set(input.priorErrorSignatures ?? []);
|
|
512304
|
+
const sig = errorSignature(input.errorText);
|
|
512305
|
+
if (sig)
|
|
512306
|
+
sigs.add(sig);
|
|
512307
|
+
return {
|
|
512308
|
+
stem,
|
|
512309
|
+
attempted: `${input.toolName}(${argPreview})`,
|
|
512310
|
+
wentWrong: firstSignalLine(input.errorText),
|
|
512311
|
+
hypothesis: HYPOTHESES[category],
|
|
512312
|
+
turn: input.turn,
|
|
512313
|
+
attempts: (input.priorAttempts ?? 0) + 1,
|
|
512314
|
+
subject,
|
|
512315
|
+
errorSignatures: sigs
|
|
512316
|
+
};
|
|
512317
|
+
}
|
|
512318
|
+
function renderReflectionMessage(r2) {
|
|
512319
|
+
const lines = [];
|
|
512320
|
+
const distinctErrors = r2.errorSignatures?.size ?? 0;
|
|
512321
|
+
if (distinctErrors >= 3) {
|
|
512322
|
+
lines.push(`[ERROR-SHIFT DETECTED — ${distinctErrors} DIFFERENT errors have emerged for \`${r2.attempted}\` across ${r2.attempts} attempts.`, `Each "fix" you've made is moving the bug somewhere new instead of resolving it. Your understanding of the failure is wrong.`, `STOP fixing. Re-read the FIRST error you saw on this call and trace exactly what each subsequent fix changed. Do NOT make another change until you can explain why the next change addresses the root.]`, ``);
|
|
512323
|
+
}
|
|
512324
|
+
lines.push(`[REFLECTION — your last attempt of \`${r2.attempted}\` failed (turn ${r2.turn}, ${r2.attempts} attempt${r2.attempts === 1 ? "" : "s"} so far).`);
|
|
512325
|
+
lines.push(`Last error: "${r2.wentWrong}"`);
|
|
512326
|
+
lines.push(`Hypothesis: ${r2.hypothesis}`);
|
|
512327
|
+
if (r2.subject) {
|
|
512328
|
+
lines.push(`Specifically: verify \`${r2.subject}\` exists at the expected location with the smallest possible read command before retrying.`);
|
|
512329
|
+
}
|
|
512330
|
+
if (r2.attempts >= 3) {
|
|
512331
|
+
lines.push(``);
|
|
512332
|
+
lines.push(`[FORCED — your intrinsic knowledge has not resolved this in ${r2.attempts} attempts. Your NEXT call MUST be \`web_search("${r2.wentWrong.replace(/"/g, '\\"').slice(0, 120)}")\` (or close-equivalent). Read the top result before making another fix attempt.]`);
|
|
512333
|
+
}
|
|
512334
|
+
lines.push(`VERIFY this hypothesis with a single small command BEFORE retrying the same tool. If you retry without verifying, you will likely fail the same way.]`);
|
|
512335
|
+
return lines.join("\n");
|
|
512336
|
+
}
|
|
512337
|
+
var CATEGORY_PATTERNS, HYPOTHESES;
|
|
512338
|
+
var init_reflection = __esm({
|
|
512339
|
+
"packages/orchestrator/dist/reflection.js"() {
|
|
512340
|
+
"use strict";
|
|
512341
|
+
CATEGORY_PATTERNS = [
|
|
512342
|
+
{ category: "permission_denied", re: /\b(permission denied|eacces|access denied|operation not permitted|forbidden)\b/i },
|
|
512343
|
+
{ category: "type_or_reference_error", re: /\b(type error|cannot find module|cannot find name|is not (a function|defined|assignable)|undefined reference|unresolved (import|reference)|missing required)\b/i },
|
|
512344
|
+
{ category: "connection_refused", re: /\b(connection refused|econnrefused|connection reset|econnreset|host unreachable|getaddrinfo|enotfound)\b/i },
|
|
512345
|
+
{ category: "timeout", re: /\b(timeout|timed out|etimedout|deadline exceeded)\b/i },
|
|
512346
|
+
{ category: "syntax_error", re: /\b(syntax error|parse error|unexpected token|unexpected end of (input|json)|malformed)\b/i },
|
|
512347
|
+
{ category: "not_found", re: /\b(not found|enoent|no such file|cannot find|does not exist|404)\b/i },
|
|
512348
|
+
// Use [1-9]\d* so multi-digit non-zero codes (e.g. "return code 127") match —
|
|
512349
|
+
// the prior [^0] only matched a single character and failed on multi-digit.
|
|
512350
|
+
{ category: "nonzero_exit", re: /\b(exit code [1-9]\d*|exit status [1-9]\d*|command failed|exit code: ?[1-9]\d*|return code [1-9]\d*)\b/i }
|
|
512351
|
+
];
|
|
512352
|
+
HYPOTHESES = {
|
|
512353
|
+
permission_denied: "permissions issue — check ownership and mode of the target; you may need to operate on a writeable location",
|
|
512354
|
+
not_found: "the named resource doesn't exist at the expected location — verify the path/name with a single-line list before retrying",
|
|
512355
|
+
connection_refused: "remote service is unreachable — verify it's running and reachable before retrying with the same address",
|
|
512356
|
+
timeout: "operation took too long — reduce scope (smaller batch, fewer items) or verify the service is healthy",
|
|
512357
|
+
syntax_error: "malformed input — re-read the surrounding context; the input you produced doesn't match what the consumer expects",
|
|
512358
|
+
type_or_reference_error: "a name, type, or import doesn't resolve — verify the reference matches what's defined; do not guess at the symbol",
|
|
512359
|
+
nonzero_exit: "the command exited with a failure code — read the FULL error output and verify args + prerequisites before retrying",
|
|
512360
|
+
unknown: "re-read the full error message and identify the most likely cause; verify your assumption with a single small command before retrying"
|
|
512361
|
+
};
|
|
512362
|
+
}
|
|
512363
|
+
});
|
|
512364
|
+
|
|
512232
512365
|
// packages/orchestrator/dist/pressure-gate.js
|
|
512233
512366
|
function detectPressure(message2) {
|
|
512234
512367
|
const hasProfanity = PRESSURE_SIGNALS.test(message2);
|
|
@@ -518460,6 +518593,7 @@ var init_agenticRunner = __esm({
|
|
|
518460
518593
|
init_personality();
|
|
518461
518594
|
init_promptLoader();
|
|
518462
518595
|
init_critic();
|
|
518596
|
+
init_reflection();
|
|
518463
518597
|
init_pressure_gate();
|
|
518464
518598
|
init_dist5();
|
|
518465
518599
|
init_dist7();
|
|
@@ -518586,6 +518720,22 @@ var init_agenticRunner = __esm({
|
|
|
518586
518720
|
_errorPatterns = /* @__PURE__ */ new Map();
|
|
518587
518721
|
_errorGuidanceInjected = /* @__PURE__ */ new Set();
|
|
518588
518722
|
// prevent duplicate injection per turn
|
|
518723
|
+
// REG-26 (Patch C): Reflexion-style structured failure memory. Indexed by
|
|
518724
|
+
// fingerprint stem (tool + first arg, truncated). When the agent retries a
|
|
518725
|
+
// tool with a stem matching a stored reflection, surface "what was tried,
|
|
518726
|
+
// what went wrong, hypothesis to verify" as a system message before the
|
|
518727
|
+
// dispatch — generic across all stacks. See packages/orchestrator/src/reflection.ts.
|
|
518728
|
+
_failureReflections = /* @__PURE__ */ new Map();
|
|
518729
|
+
_reflectionsInjectedThisTurn = /* @__PURE__ */ new Set();
|
|
518730
|
+
// prevent duplicate inject per turn
|
|
518731
|
+
// REG-30: one-shot per-turn typecheck-vs-build hint
|
|
518732
|
+
_typecheckHintInjectedThisTurn = false;
|
|
518733
|
+
// REG-31: track most recent successful build-shaped shell so the turn-start
|
|
518734
|
+
// positive-completion check knows when the agent has validated its work.
|
|
518735
|
+
_lastBuildSuccessTurn = -1;
|
|
518736
|
+
_lastBuildSuccessCommand = "";
|
|
518737
|
+
// REG-31: prevent duplicate completion suggestion per turn
|
|
518738
|
+
_completionPromptInjectedThisTurn = false;
|
|
518589
518739
|
// ── WO-AM-01/04/10: Associative memory stores ──
|
|
518590
518740
|
// Episode store: every tool call → persistent episode with importance + decay
|
|
518591
518741
|
// Temporal KG: entities + relations with temporal validity (valid_from/valid_until)
|
|
@@ -520729,6 +520879,37 @@ TASK: ${task}` : task;
|
|
|
520729
520879
|
break;
|
|
520730
520880
|
}
|
|
520731
520881
|
injectionsThisTurn = 0;
|
|
520882
|
+
this._reflectionsInjectedThisTurn.clear();
|
|
520883
|
+
this._typecheckHintInjectedThisTurn = false;
|
|
520884
|
+
this._completionPromptInjectedThisTurn = false;
|
|
520885
|
+
try {
|
|
520886
|
+
const _todos = this.readSessionTodos() || [];
|
|
520887
|
+
if (_todos.length > 0 && _todos.every((t2) => t2.status === "completed") && this._lastBuildSuccessTurn >= 0 && turn - this._lastBuildSuccessTurn <= 8 && !this._completionPromptInjectedThisTurn) {
|
|
520888
|
+
this._completionPromptInjectedThisTurn = true;
|
|
520889
|
+
messages2.push({
|
|
520890
|
+
role: "system",
|
|
520891
|
+
content: [
|
|
520892
|
+
`[ALL TODOS COMPLETED + LAST VALIDATION PASSED — TIME TO DECLARE DONE]`,
|
|
520893
|
+
``,
|
|
520894
|
+
`Status:`,
|
|
520895
|
+
` • Todos: ${_todos.length}/${_todos.length} completed`,
|
|
520896
|
+
` • Last successful validation: \`${this._lastBuildSuccessCommand.slice(0, 120)}\` (turn ${this._lastBuildSuccessTurn}, ${turn - this._lastBuildSuccessTurn} turn(s) ago)`,
|
|
520897
|
+
``,
|
|
520898
|
+
`Your work is done. Call task_complete now with a concise summary of what was implemented:`,
|
|
520899
|
+
``,
|
|
520900
|
+
` task_complete({ summary: "<one-paragraph description of what was built and verified>" })`,
|
|
520901
|
+
``,
|
|
520902
|
+
`Do NOT add more polish, more files, or more validation. The plan is complete; the validation passed; the spec is implemented. Calling task_complete is the correct next action.`
|
|
520903
|
+
].join("\n")
|
|
520904
|
+
});
|
|
520905
|
+
this.emit({
|
|
520906
|
+
type: "status",
|
|
520907
|
+
content: `REG-31: positive completion signal injected (todos all done, last build success ${turn - this._lastBuildSuccessTurn}t ago)`,
|
|
520908
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
520909
|
+
});
|
|
520910
|
+
}
|
|
520911
|
+
} catch {
|
|
520912
|
+
}
|
|
520732
520913
|
while (deferredSoftInjections.length > 0 && injectionsThisTurn < INJECTION_BUDGET_SOFT) {
|
|
520733
520914
|
const next = deferredSoftInjections.shift();
|
|
520734
520915
|
messages2.push({ role: next.role, content: next.content });
|
|
@@ -521598,6 +521779,21 @@ ${memoryLines.join("\n")}`
|
|
|
521598
521779
|
if (observerRedundantBlock) {
|
|
521599
521780
|
this._littlemanRedundantBlocks.delete(toolFingerprint);
|
|
521600
521781
|
}
|
|
521782
|
+
{
|
|
521783
|
+
const _reflStem = buildStem(tc.name, tc.arguments ?? {});
|
|
521784
|
+
if (!this._reflectionsInjectedThisTurn.has(_reflStem)) {
|
|
521785
|
+
const _reflEntry = this._failureReflections.get(_reflStem);
|
|
521786
|
+
if (_reflEntry) {
|
|
521787
|
+
this._reflectionsInjectedThisTurn.add(_reflStem);
|
|
521788
|
+
const _isEscalation = _reflEntry.attempts >= 3 || (_reflEntry.errorSignatures?.size ?? 0) >= 3;
|
|
521789
|
+
if (_isEscalation) {
|
|
521790
|
+
messages2.push({ role: "system", content: renderReflectionMessage(_reflEntry) });
|
|
521791
|
+
} else {
|
|
521792
|
+
pushSoftInjection("system", renderReflectionMessage(_reflEntry));
|
|
521793
|
+
}
|
|
521794
|
+
}
|
|
521795
|
+
}
|
|
521796
|
+
}
|
|
521601
521797
|
const criticDecision = evaluate({
|
|
521602
521798
|
proposedCall: { tool: tc.name, args: tc.arguments ?? {} },
|
|
521603
521799
|
fingerprint: toolFingerprint,
|
|
@@ -521624,6 +521820,11 @@ ${criticDecision.cachedResult.slice(0, 500)}` : `[BLOCKED — the observer confi
|
|
|
521624
521820
|
}
|
|
521625
521821
|
if (criticDecision.decision === "force_progress_block") {
|
|
521626
521822
|
dedupHitCount.set(toolFingerprint, criticDecision.hitNumber);
|
|
521823
|
+
const _existingFp = recentToolResults.get(toolFingerprint);
|
|
521824
|
+
if (_existingFp !== void 0) {
|
|
521825
|
+
recentToolResults.delete(toolFingerprint);
|
|
521826
|
+
recentToolResults.set(toolFingerprint, _existingFp);
|
|
521827
|
+
}
|
|
521627
521828
|
this.emit({ type: "tool_call", toolName: tc.name, toolArgs: tc.arguments, turn, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
|
|
521628
521829
|
this.emit({
|
|
521629
521830
|
type: "tool_result",
|
|
@@ -521637,6 +521838,11 @@ ${criticDecision.cachedResult.slice(0, 500)}` : `[BLOCKED — the observer confi
|
|
|
521637
521838
|
}
|
|
521638
521839
|
if (criticDecision.decision === "serve_cached") {
|
|
521639
521840
|
dedupHitCount.set(toolFingerprint, criticDecision.hitNumber);
|
|
521841
|
+
const _existingFp = recentToolResults.get(toolFingerprint);
|
|
521842
|
+
if (_existingFp !== void 0) {
|
|
521843
|
+
recentToolResults.delete(toolFingerprint);
|
|
521844
|
+
recentToolResults.set(toolFingerprint, _existingFp);
|
|
521845
|
+
}
|
|
521640
521846
|
this.emit({
|
|
521641
521847
|
type: "tool_call",
|
|
521642
521848
|
toolName: tc.name,
|
|
@@ -522026,6 +522232,21 @@ ${criticDecision.cachedResult.slice(0, 500)}` : `[BLOCKED — the observer confi
|
|
|
522026
522232
|
const lastLog = toolCallLog[toolCallLog.length - 1];
|
|
522027
522233
|
if (lastLog)
|
|
522028
522234
|
lastLog.success = true;
|
|
522235
|
+
if (tc.name === "shell") {
|
|
522236
|
+
const _shellCmd = String(tc.arguments?.["command"] ?? tc.arguments?.["cmd"] ?? "");
|
|
522237
|
+
const _typecheckOnly = /\b(--noEmit|--dry-run|--check\b|\bmypy\b|\bruff check\b|\bcargo check\b|\bstylelint --check\b|\bpylint\b(?!.*--exit-zero))\b/i.test(_shellCmd);
|
|
522238
|
+
if (_typecheckOnly && !this._typecheckHintInjectedThisTurn) {
|
|
522239
|
+
this._typecheckHintInjectedThisTurn = true;
|
|
522240
|
+
pushSoftInjection("system", `[Typecheck PASSED but does NOT mean the project builds or runs. Typecheck only validates declarations, not runtime behavior, plugin pipelines, or build-time transformations. Before declaring this work complete, run the actual build/run command for the project (the verb is typically "build", "run", "start", or "compile" — context-specific to your stack).]`);
|
|
522241
|
+
}
|
|
522242
|
+
}
|
|
522243
|
+
if (tc.name === "shell") {
|
|
522244
|
+
const _shellCmd2 = String(tc.arguments?.["command"] ?? tc.arguments?.["cmd"] ?? "");
|
|
522245
|
+
if (/\b(build|test|run\b|start\b|serve\b|verify|check)\b/i.test(_shellCmd2)) {
|
|
522246
|
+
this._lastBuildSuccessTurn = turn;
|
|
522247
|
+
this._lastBuildSuccessCommand = _shellCmd2.slice(0, 200);
|
|
522248
|
+
}
|
|
522249
|
+
}
|
|
522029
522250
|
if (["file_write", "file_edit", "file_patch", "batch_edit"].includes(tc.name) && this._patchHistoryStore) {
|
|
522030
522251
|
try {
|
|
522031
522252
|
const filePath2 = tc.arguments?.path || tc.arguments?.file_path;
|
|
@@ -522062,6 +522283,8 @@ ${criticDecision.cachedResult.slice(0, 500)}` : `[BLOCKED — the observer confi
|
|
|
522062
522283
|
}
|
|
522063
522284
|
if (result.success) {
|
|
522064
522285
|
this._recentFailures = this._recentFailures.filter((f2) => f2.fingerprint !== toolFingerprint);
|
|
522286
|
+
const _stem = buildStem(tc.name, tc.arguments ?? {});
|
|
522287
|
+
this._failureReflections.delete(_stem);
|
|
522065
522288
|
}
|
|
522066
522289
|
if (!result.success) {
|
|
522067
522290
|
this._recentFailures.push({
|
|
@@ -522075,6 +522298,25 @@ ${criticDecision.cachedResult.slice(0, 500)}` : `[BLOCKED — the observer confi
|
|
|
522075
522298
|
if (this._recentFailures.length > 8) {
|
|
522076
522299
|
this._recentFailures = this._recentFailures.slice(-8);
|
|
522077
522300
|
}
|
|
522301
|
+
const _refStem = buildStem(tc.name, tc.arguments ?? {});
|
|
522302
|
+
const _prior = this._failureReflections.get(_refStem);
|
|
522303
|
+
const _refErr = (result.error ?? result.output ?? "").toString();
|
|
522304
|
+
const _entry = synthesizeReflection({
|
|
522305
|
+
toolName: tc.name,
|
|
522306
|
+
args: tc.arguments ?? {},
|
|
522307
|
+
errorText: _refErr,
|
|
522308
|
+
turn,
|
|
522309
|
+
priorAttempts: _prior?.attempts ?? 0,
|
|
522310
|
+
// REG-27: carry forward distinct error-signature set so the
|
|
522311
|
+
// agent's renderer can detect error-shift (3+ different errors)
|
|
522312
|
+
priorErrorSignatures: _prior?.errorSignatures
|
|
522313
|
+
});
|
|
522314
|
+
this._failureReflections.set(_refStem, _entry);
|
|
522315
|
+
if (this._failureReflections.size > 32) {
|
|
522316
|
+
const oldestKey = this._failureReflections.keys().next().value;
|
|
522317
|
+
if (oldestKey !== void 0)
|
|
522318
|
+
this._failureReflections.delete(oldestKey);
|
|
522319
|
+
}
|
|
522078
522320
|
}
|
|
522079
522321
|
if (!result.success && tc.name === "shell" && /\[PERMISSION_ERROR\]/.test(result.error ?? "")) {
|
|
522080
522322
|
this.emit({
|
|
@@ -522340,9 +522582,35 @@ ${sr.result.output}`;
|
|
|
522340
522582
|
for (const batch2 of batches) {
|
|
522341
522583
|
if (this.aborted)
|
|
522342
522584
|
break;
|
|
522585
|
+
const batchFingerprintFirstId = /* @__PURE__ */ new Map();
|
|
522586
|
+
const batchInFlight = /* @__PURE__ */ new Map();
|
|
522587
|
+
const buildBatchFp = (call) => {
|
|
522588
|
+
const args = call.args ?? {};
|
|
522589
|
+
const argsKey = Object.entries(args).sort(([a2], [b]) => a2.localeCompare(b)).map(([k, v]) => `${k}=${typeof v === "string" ? v.slice(0, 160) : JSON.stringify(v).slice(0, 160)}`).join(",");
|
|
522590
|
+
return `${call.name}:${argsKey}`;
|
|
522591
|
+
};
|
|
522592
|
+
for (const call of batch2.calls) {
|
|
522593
|
+
const fp = buildBatchFp(call);
|
|
522594
|
+
if (!batchFingerprintFirstId.has(fp)) {
|
|
522595
|
+
batchFingerprintFirstId.set(fp, call.id);
|
|
522596
|
+
}
|
|
522597
|
+
}
|
|
522343
522598
|
const results = await executeBatch(batch2, async (call) => {
|
|
522344
522599
|
const originalTc = rawToolCalls.find((tc) => tc.id === call.id);
|
|
522345
|
-
|
|
522600
|
+
const fp = buildBatchFp(call);
|
|
522601
|
+
const firstId = batchFingerprintFirstId.get(fp);
|
|
522602
|
+
if (firstId !== void 0 && call.id !== void 0 && firstId !== call.id) {
|
|
522603
|
+
const inflight = batchInFlight.get(fp);
|
|
522604
|
+
if (inflight) {
|
|
522605
|
+
const cloned = await inflight;
|
|
522606
|
+
if (!cloned)
|
|
522607
|
+
return null;
|
|
522608
|
+
return { tc: { ...cloned.tc, id: call.id }, output: cloned.output };
|
|
522609
|
+
}
|
|
522610
|
+
}
|
|
522611
|
+
const promise = executeSingle(originalTc);
|
|
522612
|
+
batchInFlight.set(fp, promise);
|
|
522613
|
+
return promise;
|
|
522346
522614
|
}, 5);
|
|
522347
522615
|
for (const r2 of results) {
|
|
522348
522616
|
if (r2) {
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "open-agents-ai",
|
|
3
|
-
"version": "0.187.
|
|
3
|
+
"version": "0.187.481",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "open-agents-ai",
|
|
9
|
-
"version": "0.187.
|
|
9
|
+
"version": "0.187.481",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "CC-BY-NC-4.0",
|
|
12
12
|
"dependencies": {
|
package/package.json
CHANGED