open-agents-ai 0.187.480 → 0.187.482

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,21 @@ 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;
518739
+ // REG-32: one-shot per-stem nudge toward web_search on opaque errors.
518740
+ // Closes the gap where qwen3.6 pivots away from a single failure (different
518741
+ // stem on next turn) and never triggers REG-26/28's retry-based web_search
518742
+ // escalations. Fires on the FIRST failure of a stem when the local
518743
+ // diagnostic can't help (unknown category or long multi-line error with
518744
+ // no extractable subject).
518745
+ _opaqueErrorHintInjected = /* @__PURE__ */ new Set();
518679
518746
  // ── WO-AM-01/04/10: Associative memory stores ──
518680
518747
  // Episode store: every tool call → persistent episode with importance + decay
518681
518748
  // Temporal KG: entities + relations with temporal validity (valid_from/valid_until)
@@ -520820,6 +520887,36 @@ TASK: ${task}` : task;
520820
520887
  }
520821
520888
  injectionsThisTurn = 0;
520822
520889
  this._reflectionsInjectedThisTurn.clear();
520890
+ this._typecheckHintInjectedThisTurn = false;
520891
+ this._completionPromptInjectedThisTurn = false;
520892
+ try {
520893
+ const _todos = this.readSessionTodos() || [];
520894
+ if (_todos.length > 0 && _todos.every((t2) => t2.status === "completed") && this._lastBuildSuccessTurn >= 0 && turn - this._lastBuildSuccessTurn <= 8 && !this._completionPromptInjectedThisTurn) {
520895
+ this._completionPromptInjectedThisTurn = true;
520896
+ messages2.push({
520897
+ role: "system",
520898
+ content: [
520899
+ `[ALL TODOS COMPLETED + LAST VALIDATION PASSED — TIME TO DECLARE DONE]`,
520900
+ ``,
520901
+ `Status:`,
520902
+ ` • Todos: ${_todos.length}/${_todos.length} completed`,
520903
+ ` • Last successful validation: \`${this._lastBuildSuccessCommand.slice(0, 120)}\` (turn ${this._lastBuildSuccessTurn}, ${turn - this._lastBuildSuccessTurn} turn(s) ago)`,
520904
+ ``,
520905
+ `Your work is done. Call task_complete now with a concise summary of what was implemented:`,
520906
+ ``,
520907
+ ` task_complete({ summary: "<one-paragraph description of what was built and verified>" })`,
520908
+ ``,
520909
+ `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.`
520910
+ ].join("\n")
520911
+ });
520912
+ this.emit({
520913
+ type: "status",
520914
+ content: `REG-31: positive completion signal injected (todos all done, last build success ${turn - this._lastBuildSuccessTurn}t ago)`,
520915
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
520916
+ });
520917
+ }
520918
+ } catch {
520919
+ }
520823
520920
  while (deferredSoftInjections.length > 0 && injectionsThisTurn < INJECTION_BUDGET_SOFT) {
520824
520921
  const next = deferredSoftInjections.shift();
520825
520922
  messages2.push({ role: next.role, content: next.content });
@@ -521695,7 +521792,12 @@ ${memoryLines.join("\n")}`
521695
521792
  const _reflEntry = this._failureReflections.get(_reflStem);
521696
521793
  if (_reflEntry) {
521697
521794
  this._reflectionsInjectedThisTurn.add(_reflStem);
521698
- pushSoftInjection("system", renderReflectionMessage(_reflEntry));
521795
+ const _isEscalation = _reflEntry.attempts >= 3 || (_reflEntry.errorSignatures?.size ?? 0) >= 3;
521796
+ if (_isEscalation) {
521797
+ messages2.push({ role: "system", content: renderReflectionMessage(_reflEntry) });
521798
+ } else {
521799
+ pushSoftInjection("system", renderReflectionMessage(_reflEntry));
521800
+ }
521699
521801
  }
521700
521802
  }
521701
521803
  }
@@ -522137,6 +522239,21 @@ ${criticDecision.cachedResult.slice(0, 500)}` : `[BLOCKED — the observer confi
522137
522239
  const lastLog = toolCallLog[toolCallLog.length - 1];
522138
522240
  if (lastLog)
522139
522241
  lastLog.success = true;
522242
+ if (tc.name === "shell") {
522243
+ const _shellCmd = String(tc.arguments?.["command"] ?? tc.arguments?.["cmd"] ?? "");
522244
+ 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);
522245
+ if (_typecheckOnly && !this._typecheckHintInjectedThisTurn) {
522246
+ this._typecheckHintInjectedThisTurn = true;
522247
+ 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).]`);
522248
+ }
522249
+ }
522250
+ if (tc.name === "shell") {
522251
+ const _shellCmd2 = String(tc.arguments?.["command"] ?? tc.arguments?.["cmd"] ?? "");
522252
+ if (/\b(build|test|run\b|start\b|serve\b|verify|check)\b/i.test(_shellCmd2)) {
522253
+ this._lastBuildSuccessTurn = turn;
522254
+ this._lastBuildSuccessCommand = _shellCmd2.slice(0, 200);
522255
+ }
522256
+ }
522140
522257
  if (["file_write", "file_edit", "file_patch", "batch_edit"].includes(tc.name) && this._patchHistoryStore) {
522141
522258
  try {
522142
522259
  const filePath2 = tc.arguments?.path || tc.arguments?.file_path;
@@ -522196,7 +522313,10 @@ ${criticDecision.cachedResult.slice(0, 500)}` : `[BLOCKED — the observer confi
522196
522313
  args: tc.arguments ?? {},
522197
522314
  errorText: _refErr,
522198
522315
  turn,
522199
- priorAttempts: _prior?.attempts ?? 0
522316
+ priorAttempts: _prior?.attempts ?? 0,
522317
+ // REG-27: carry forward distinct error-signature set so the
522318
+ // agent's renderer can detect error-shift (3+ different errors)
522319
+ priorErrorSignatures: _prior?.errorSignatures
522200
522320
  });
522201
522321
  this._failureReflections.set(_refStem, _entry);
522202
522322
  if (this._failureReflections.size > 32) {
@@ -522204,6 +522324,22 @@ ${criticDecision.cachedResult.slice(0, 500)}` : `[BLOCKED — the observer confi
522204
522324
  if (oldestKey !== void 0)
522205
522325
  this._failureReflections.delete(oldestKey);
522206
522326
  }
522327
+ if (!_prior && !this._opaqueErrorHintInjected.has(_refStem) && _entry.subject == null && (categorizeError(_refErr) === "unknown" || _refErr.length > 100)) {
522328
+ this._opaqueErrorHintInjected.add(_refStem);
522329
+ const _searchQuery = _entry.wentWrong.replace(/"/g, '\\"').slice(0, 200);
522330
+ pushSoftInjection("system", [
522331
+ `[OPAQUE ERROR — local diagnostic patterns cannot pinpoint a specific target to verify. Error class is unrecognized or output is substantial enough that external context is likely needed.]`,
522332
+ ``,
522333
+ `Tool: ${tc.name}`,
522334
+ `Error: "${_entry.wentWrong}"`,
522335
+ ``,
522336
+ `Before attempting a fix or pivoting to a different command, run a web search of the exact error string:`,
522337
+ ``,
522338
+ ` web_search({"query": "${_searchQuery}"})`,
522339
+ ``,
522340
+ `A 30-second external lookup is more reliable than local guesses for framework/version-specific errors your training data may not cover.`
522341
+ ].join("\n"));
522342
+ }
522207
522343
  }
522208
522344
  if (!result.success && tc.name === "shell" && /\[PERMISSION_ERROR\]/.test(result.error ?? "")) {
522209
522345
  this.emit({
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.480",
3
+ "version": "0.187.482",
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.482",
10
10
  "hasInstallScript": true,
11
11
  "license": "CC-BY-NC-4.0",
12
12
  "dependencies": {
@@ -3229,9 +3229,9 @@
3229
3229
  }
3230
3230
  },
3231
3231
  "node_modules/caniuse-lite": {
3232
- "version": "1.0.30001790",
3233
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001790.tgz",
3234
- "integrity": "sha512-bOoxfJPyYo+ds6W0YfptaCWbFnJYjh2Y1Eow5lRv+vI2u8ganPZqNm1JwNh0t2ELQCqIWg4B3dWEusgAmsoyOw==",
3232
+ "version": "1.0.30001791",
3233
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001791.tgz",
3234
+ "integrity": "sha512-yk0l/YSrOnFZk3UROpDLQD9+kC1l4meK/wed583AXrzoarMGJcbRi2Q4RaUYbKxYAsZ8sWmaSa/DsLmdBeI1vQ==",
3235
3235
  "funding": [
3236
3236
  {
3237
3237
  "type": "opencollective",
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.482",
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",