open-agents-ai 0.187.480 → 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 CHANGED
@@ -512230,6 +512230,40 @@ var init_critic = __esm({
512230
512230
  });
512231
512231
 
512232
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
+ }
512233
512267
  function categorizeError(errorText) {
512234
512268
  if (!errorText)
512235
512269
  return "unknown";
@@ -512265,22 +512299,40 @@ function synthesizeReflection(input) {
512265
512299
  const category = categorizeError(input.errorText);
512266
512300
  const stem = buildStem(input.toolName, input.args);
512267
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);
512268
512307
  return {
512269
512308
  stem,
512270
512309
  attempted: `${input.toolName}(${argPreview})`,
512271
512310
  wentWrong: firstSignalLine(input.errorText),
512272
512311
  hypothesis: HYPOTHESES[category],
512273
512312
  turn: input.turn,
512274
- attempts: (input.priorAttempts ?? 0) + 1
512313
+ attempts: (input.priorAttempts ?? 0) + 1,
512314
+ subject,
512315
+ errorSignatures: sigs
512275
512316
  };
512276
512317
  }
512277
512318
  function renderReflectionMessage(r2) {
512278
- return [
512279
- `[REFLECTION your last attempt of \`${r2.attempted}\` failed (turn ${r2.turn}, ${r2.attempts} attempt${r2.attempts === 1 ? "" : "s"} so far).`,
512280
- `Last error: "${r2.wentWrong}"`,
512281
- `Hypothesis: ${r2.hypothesis}`,
512282
- `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.]`
512283
- ].join("\n");
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");
512284
512336
  }
512285
512337
  var CATEGORY_PATTERNS, HYPOTHESES;
512286
512338
  var init_reflection = __esm({
@@ -518676,6 +518728,14 @@ var init_agenticRunner = __esm({
518676
518728
  _failureReflections = /* @__PURE__ */ new Map();
518677
518729
  _reflectionsInjectedThisTurn = /* @__PURE__ */ new Set();
518678
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;
518679
518739
  // ── WO-AM-01/04/10: Associative memory stores ──
518680
518740
  // Episode store: every tool call → persistent episode with importance + decay
518681
518741
  // Temporal KG: entities + relations with temporal validity (valid_from/valid_until)
@@ -520820,6 +520880,36 @@ TASK: ${task}` : task;
520820
520880
  }
520821
520881
  injectionsThisTurn = 0;
520822
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
+ }
520823
520913
  while (deferredSoftInjections.length > 0 && injectionsThisTurn < INJECTION_BUDGET_SOFT) {
520824
520914
  const next = deferredSoftInjections.shift();
520825
520915
  messages2.push({ role: next.role, content: next.content });
@@ -521695,7 +521785,12 @@ ${memoryLines.join("\n")}`
521695
521785
  const _reflEntry = this._failureReflections.get(_reflStem);
521696
521786
  if (_reflEntry) {
521697
521787
  this._reflectionsInjectedThisTurn.add(_reflStem);
521698
- pushSoftInjection("system", renderReflectionMessage(_reflEntry));
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
+ }
521699
521794
  }
521700
521795
  }
521701
521796
  }
@@ -522137,6 +522232,21 @@ ${criticDecision.cachedResult.slice(0, 500)}` : `[BLOCKED — the observer confi
522137
522232
  const lastLog = toolCallLog[toolCallLog.length - 1];
522138
522233
  if (lastLog)
522139
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
+ }
522140
522250
  if (["file_write", "file_edit", "file_patch", "batch_edit"].includes(tc.name) && this._patchHistoryStore) {
522141
522251
  try {
522142
522252
  const filePath2 = tc.arguments?.path || tc.arguments?.file_path;
@@ -522196,7 +522306,10 @@ ${criticDecision.cachedResult.slice(0, 500)}` : `[BLOCKED — the observer confi
522196
522306
  args: tc.arguments ?? {},
522197
522307
  errorText: _refErr,
522198
522308
  turn,
522199
- priorAttempts: _prior?.attempts ?? 0
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
522200
522313
  });
522201
522314
  this._failureReflections.set(_refStem, _entry);
522202
522315
  if (this._failureReflections.size > 32) {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.480",
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.480",
9
+ "version": "0.187.481",
10
10
  "hasInstallScript": true,
11
11
  "license": "CC-BY-NC-4.0",
12
12
  "dependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.480",
3
+ "version": "0.187.481",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",