open-agents-ai 0.187.498 → 0.187.499

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
@@ -255394,14 +255394,26 @@ function buildScaffoldedPrompt(args) {
255394
255394
  lines.push(bulletList(args.features));
255395
255395
  lines.push("");
255396
255396
  }
255397
- lines.push(`## Tech stack POSITIVE constraints (use these)`);
255398
- lines.push(bulletList(args.stack));
255399
- lines.push("");
255400
- lines.push(`## Tech stack — NEGATIVE constraints (do NOT use these)`);
255401
- lines.push(`These prohibitions are load-bearing. Default training data favors popular alternatives; you must respect the explicit "no" here even when a forbidden choice would be conventional.`);
255402
- lines.push("");
255403
- lines.push(bulletList(args.anti_stack));
255404
- lines.push("");
255397
+ if (args.stack && args.stack.length > 0) {
255398
+ lines.push(`## Tech stack — POSITIVE constraints (use these)`);
255399
+ lines.push(bulletList(args.stack));
255400
+ lines.push("");
255401
+ } else {
255402
+ lines.push(`## Tech stack — POSITIVE constraints`);
255403
+ lines.push(`The caller did not specify positive tech-stack constraints. The spec MUST declare its own tech stack explicitly in section 1 (Overview) — language, runtime, frameworks, persistence, build/test tools — so the downstream implementer has unambiguous targets. Do NOT leave the stack as an open choice.`);
255404
+ lines.push("");
255405
+ }
255406
+ if (args.anti_stack && args.anti_stack.length > 0) {
255407
+ lines.push(`## Tech stack — NEGATIVE constraints (do NOT use these)`);
255408
+ lines.push(`These prohibitions are load-bearing. Default training data favors popular alternatives; you must respect the explicit "no" here even when a forbidden choice would be conventional.`);
255409
+ lines.push("");
255410
+ lines.push(bulletList(args.anti_stack));
255411
+ lines.push("");
255412
+ } else {
255413
+ lines.push(`## Tech stack — NEGATIVE constraints`);
255414
+ lines.push(`No explicit prohibitions supplied. The spec is free to choose any tooling consistent with the positive constraints, but the spec itself SHOULD include a brief "anti-requirements" section (see section 11) listing the patterns/libraries explicitly excluded — even if the caller did not pre-specify them.`);
255415
+ lines.push("");
255416
+ }
255405
255417
  if (args.notes && args.notes.trim().length > 0) {
255406
255418
  lines.push(`## Additional constraints / notes`);
255407
255419
  lines.push(args.notes.trim());
@@ -514617,6 +514629,23 @@ function renderCriticPrompt(inputs) {
514617
514629
  lines.push(`9. **Unresolved failures**: stems with attempts ≥ 3 that never cleared.`);
514618
514630
  lines.push(`10. **Generic-vs-specific drift**: code claims to be generic but contains`);
514619
514631
  lines.push(` framework- or vendor-specific keywords.`);
514632
+ lines.push(`11. **Backtest evidence for new code (CRITICAL — recurring failure mode)**: For any`);
514633
+ lines.push(` NEWLY ADDED tool, module, public function, or prompt-generation feature,`);
514634
+ lines.push(` the implementer MUST have invoked the new code with realistic input and`);
514635
+ lines.push(` inspected the actual rendered/returned output. Unit-test pass is necessary`);
514636
+ lines.push(` but NOT sufficient — unit tests verify the implementer's own assertions,`);
514637
+ lines.push(` not whether the output is human-usable. Look for evidence in the recent`);
514638
+ lines.push(` tool calls of: a node/python/shell invocation that exercises the new code`);
514639
+ lines.push(` with realistic args, OR a manual-inspection step (cat / file_read of the`);
514640
+ lines.push(` output, head/tail of generated content). If you find ONLY unit-test`);
514641
+ lines.push(` evidence and no realistic-invocation evidence for new code, this is a`);
514642
+ lines.push(` \`request_changes\` regardless of test count. Tests passing while output is`);
514643
+ lines.push(` nonsense is a recurring class of negligence this gate exists to catch.`);
514644
+ lines.push(`12. **Empty-section / contradiction sweep**: For any output the implementer`);
514645
+ lines.push(` generates programmatically (prompts, configs, docs), check for sections`);
514646
+ lines.push(` that say "(none specified)" / "(no items)" / "(empty)" alongside framing`);
514647
+ lines.push(` text that asserts the section IS load-bearing. These contradictions`);
514648
+ lines.push(` indicate the generator wasn't tested with the empty / minimal-input case.`);
514620
514649
  lines.push(``);
514621
514650
  lines.push(`Do NOT flag:`);
514622
514651
  lines.push(`- Stylistic choices (formatting, naming) unless they hide a real bug.`);
@@ -514910,6 +514939,221 @@ var init_backward_pass_runner = __esm({
514910
514939
  }
514911
514940
  });
514912
514941
 
514942
+ // packages/orchestrator/dist/stuck-meta-analyzer.js
514943
+ function renderAnalyzerPrompt(inputs) {
514944
+ const lines = [];
514945
+ lines.push(`# STUCK-STATE META-ANALYSIS`);
514946
+ lines.push(``);
514947
+ lines.push(`You are a META-ANALYSIS sub-agent. Another agent (the implementer) is`);
514948
+ lines.push(`stuck in an unproductive tool-call loop and the runtime's structural`);
514949
+ lines.push(`stuck-detector has fired. Your job: examine the loop + state below and`);
514950
+ lines.push(`return ONE specific next tool call that will unblock the implementer.`);
514951
+ lines.push(``);
514952
+ lines.push(`## Context`);
514953
+ lines.push(`Goal: ${inputs.goal.slice(0, 600)}`);
514954
+ lines.push(`Working directory: ${inputs.workingDir}`);
514955
+ lines.push(`Trigger: ${inputs.triggerReason} (turn ${inputs.turn})`);
514956
+ if (inputs.workspaceSummary) {
514957
+ lines.push(``);
514958
+ lines.push(`## Workspace summary`);
514959
+ lines.push(inputs.workspaceSummary.slice(0, 1500));
514960
+ }
514961
+ lines.push(``);
514962
+ lines.push(`## Plan status (reconciled against disk)`);
514963
+ if (inputs.planStatus.length === 0) {
514964
+ lines.push(`(no plan items declared)`);
514965
+ } else {
514966
+ for (const t2 of inputs.planStatus.slice(0, 12)) {
514967
+ lines.push(` [${t2.reconciled}] ${t2.content.slice(0, 100)} — ${t2.rationale.slice(0, 120)}`);
514968
+ }
514969
+ }
514970
+ lines.push(``);
514971
+ lines.push(`## Recent unresolved failures`);
514972
+ if (inputs.recentFailures.length === 0) {
514973
+ lines.push(`(none)`);
514974
+ } else {
514975
+ for (const f2 of inputs.recentFailures.slice(0, 5)) {
514976
+ lines.push(` - ${f2.stem} (attempts=${f2.attempts}): ${f2.preview.slice(0, 200)}`);
514977
+ }
514978
+ }
514979
+ lines.push(``);
514980
+ lines.push(`## The loop pattern (recent tool calls, oldest first)`);
514981
+ if (inputs.recentToolCalls.length === 0) {
514982
+ lines.push(`(no recent calls)`);
514983
+ } else {
514984
+ const recent = inputs.recentToolCalls.slice(-30);
514985
+ for (const c9 of recent) {
514986
+ const status = c9.success === false ? "FAIL" : "OK";
514987
+ const args = c9.argsKey ? ` ${c9.argsKey}` : "";
514988
+ const preview = c9.outputPreview ? ` → "${c9.outputPreview.slice(0, 100)}"` : "";
514989
+ lines.push(` ${c9.name}${args} [${status}]${preview}`);
514990
+ }
514991
+ }
514992
+ lines.push(``);
514993
+ if (inputs.availableTools && inputs.availableTools.length > 0) {
514994
+ lines.push(`## Tools available to the implementer`);
514995
+ lines.push(inputs.availableTools.slice(0, 60).join(", "));
514996
+ lines.push(``);
514997
+ }
514998
+ lines.push(`## Your task`);
514999
+ lines.push(``);
515000
+ lines.push(`Diagnose the loop in 1 sentence (what specific category of un-`);
515001
+ lines.push(`productive activity is happening?). Then emit ONE concrete next`);
515002
+ lines.push(`tool call the implementer should make. Do NOT emit a list of`);
515003
+ lines.push(`alternatives. Do NOT emit categories like "PRODUCE" or "EDIT" —`);
515004
+ lines.push(`emit the actual tool name and the actual args (with concrete`);
515005
+ lines.push(`paths and a content seed when applicable).`);
515006
+ lines.push(``);
515007
+ lines.push(`Universal rules for the directive:`);
515008
+ lines.push(`- Use only tools the implementer has access to.`);
515009
+ lines.push(`- The next_action MUST produce new state on disk (file_write,`);
515010
+ lines.push(` file_edit, batch_edit, file_patch, shell mutation, or similar).`);
515011
+ lines.push(` If the loop is read-heavy, the unblocker is virtually always a`);
515012
+ lines.push(` write of some kind.`);
515013
+ lines.push(`- The args_seed must contain enough content that the implementer`);
515014
+ lines.push(` can apply or refine it directly. For file writes, the args_seed`);
515015
+ lines.push(` MUST include a 'content' field with at least skeleton text`);
515016
+ lines.push(` (function signatures, imports, key structures). For shell calls,`);
515017
+ lines.push(` include the exact command.`);
515018
+ lines.push(`- The anti_pattern must name the SPECIFIC repeated activity to stop`);
515019
+ lines.push(` (e.g. "list_directory of /tests/* repeatedly with no writes"),`);
515020
+ lines.push(` not just "stop being stuck".`);
515021
+ lines.push(`- The verification must be a concrete check (a tool call OR an`);
515022
+ lines.push(` expected state change) the implementer runs after the action.`);
515023
+ lines.push(``);
515024
+ lines.push(`## Output format`);
515025
+ lines.push(``);
515026
+ lines.push(`Reason briefly (1-3 sentences) about the loop, then emit a SINGLE`);
515027
+ lines.push(`JSON code block with this exact shape:`);
515028
+ lines.push(``);
515029
+ lines.push("```json");
515030
+ lines.push(`{`);
515031
+ lines.push(` "diagnosis": "<1-sentence root cause>",`);
515032
+ lines.push(` "next_action": {`);
515033
+ lines.push(` "tool": "<exact tool name from the available list>",`);
515034
+ lines.push(` "args_seed": { /* concrete args; for writes, include 'path' + 'content' seed */ },`);
515035
+ lines.push(` "rationale": "<why this unblocks>"`);
515036
+ lines.push(` },`);
515037
+ lines.push(` "anti_pattern": "<the specific loop activity to stop>",`);
515038
+ lines.push(` "verification": "<concrete check after the action>"`);
515039
+ lines.push(`}`);
515040
+ lines.push("```");
515041
+ lines.push(``);
515042
+ lines.push(`Be SPECIFIC. Vague directives are useless to a stuck implementer.`);
515043
+ return lines.join("\n");
515044
+ }
515045
+ function parseDirective(rawResponse) {
515046
+ const fallback = (msg) => ({
515047
+ diagnosis: `(meta-analyzer parse failed: ${msg})`,
515048
+ next_action: {
515049
+ tool: "(unknown)",
515050
+ args_seed: {},
515051
+ rationale: "Parser fell back; directive should not be injected."
515052
+ },
515053
+ anti_pattern: "(unknown)",
515054
+ verification: "(unknown)",
515055
+ raw: rawResponse,
515056
+ parseFallback: true
515057
+ });
515058
+ if (!rawResponse || typeof rawResponse !== "string" || rawResponse.trim().length === 0) {
515059
+ return fallback("empty response");
515060
+ }
515061
+ const fenceMatch = rawResponse.match(/```(?:json)?\s*\n([\s\S]*?)\n```/);
515062
+ let jsonText = null;
515063
+ if (fenceMatch) {
515064
+ jsonText = fenceMatch[1].trim();
515065
+ } else {
515066
+ const first2 = rawResponse.indexOf("{");
515067
+ const last2 = rawResponse.lastIndexOf("}");
515068
+ if (first2 !== -1 && last2 > first2)
515069
+ jsonText = rawResponse.slice(first2, last2 + 1);
515070
+ }
515071
+ if (!jsonText)
515072
+ return fallback("no JSON block found");
515073
+ let parsed;
515074
+ try {
515075
+ parsed = JSON.parse(jsonText);
515076
+ } catch (e2) {
515077
+ return fallback(`JSON parse: ${e2 instanceof Error ? e2.message : String(e2)}`);
515078
+ }
515079
+ if (!parsed || typeof parsed !== "object")
515080
+ return fallback("not an object");
515081
+ const diagnosis = typeof parsed.diagnosis === "string" && parsed.diagnosis.trim().length > 0 ? parsed.diagnosis.slice(0, 400) : "";
515082
+ const next = parsed.next_action;
515083
+ const tool = next && typeof next.tool === "string" ? next.tool.trim() : "";
515084
+ const args_seed = next && typeof next.args_seed === "object" && next.args_seed !== null ? next.args_seed : {};
515085
+ const rationale = next && typeof next.rationale === "string" ? next.rationale.slice(0, 400) : "";
515086
+ const anti_pattern = typeof parsed.anti_pattern === "string" ? parsed.anti_pattern.slice(0, 400) : "";
515087
+ const verification = typeof parsed.verification === "string" ? parsed.verification.slice(0, 400) : "";
515088
+ if (!diagnosis || !tool || !anti_pattern || !verification) {
515089
+ return fallback("missing required fields");
515090
+ }
515091
+ return {
515092
+ diagnosis,
515093
+ next_action: { tool, args_seed, rationale },
515094
+ anti_pattern,
515095
+ verification,
515096
+ raw: rawResponse
515097
+ };
515098
+ }
515099
+ function renderDirectiveAsMessage(d2) {
515100
+ if (d2.parseFallback) {
515101
+ return "";
515102
+ }
515103
+ const lines = [];
515104
+ lines.push(`[STUCK-STATE META-ANALYZER — REG-49]`);
515105
+ lines.push(``);
515106
+ lines.push(`A meta-analyzer sub-agent reviewed the recent tool-call pattern, the`);
515107
+ lines.push(`current world state, and the plan; it produced a single concrete`);
515108
+ lines.push(`unblocking action for you to take.`);
515109
+ lines.push(``);
515110
+ lines.push(`DIAGNOSIS: ${d2.diagnosis}`);
515111
+ lines.push(``);
515112
+ lines.push(`STOP DOING (anti-pattern): ${d2.anti_pattern}`);
515113
+ lines.push(``);
515114
+ lines.push(`DO NEXT:`);
515115
+ lines.push(` Tool: ${d2.next_action.tool}`);
515116
+ const argsJson = JSON.stringify(d2.next_action.args_seed, null, 2);
515117
+ lines.push(` Args:`);
515118
+ for (const ln of argsJson.split("\n"))
515119
+ lines.push(` ${ln}`);
515120
+ lines.push(` Rationale: ${d2.next_action.rationale}`);
515121
+ lines.push(``);
515122
+ lines.push(`AFTER THE ACTION, verify with: ${d2.verification}`);
515123
+ lines.push(``);
515124
+ lines.push(`This directive comes from a meta-analysis of YOUR recent activity. The`);
515125
+ lines.push(`args above are a SEED — refine them as needed (filenames, content) but`);
515126
+ lines.push(`emit a tool call of this kind on your next response. Do NOT emit`);
515127
+ lines.push(`another instance of the anti-pattern; that loop has been blocked.`);
515128
+ return lines.join("\n");
515129
+ }
515130
+ async function runStuckAnalyzer(opts) {
515131
+ const startMs = Date.now();
515132
+ const prompt = renderAnalyzerPrompt(opts.inputs);
515133
+ const promptBytes = Buffer.byteLength(prompt, "utf-8");
515134
+ let raw = "";
515135
+ try {
515136
+ raw = await opts.callable(prompt);
515137
+ } catch (e2) {
515138
+ raw = "";
515139
+ }
515140
+ const responseBytes = Buffer.byteLength(raw, "utf-8");
515141
+ const directive = parseDirective(raw);
515142
+ const injection = renderDirectiveAsMessage(directive);
515143
+ return {
515144
+ directive,
515145
+ injection,
515146
+ promptBytes,
515147
+ responseBytes,
515148
+ durationMs: Date.now() - startMs
515149
+ };
515150
+ }
515151
+ var init_stuck_meta_analyzer = __esm({
515152
+ "packages/orchestrator/dist/stuck-meta-analyzer.js"() {
515153
+ "use strict";
515154
+ }
515155
+ });
515156
+
514913
515157
  // packages/orchestrator/dist/pressure-gate.js
514914
515158
  function detectPressure(message2) {
514915
515159
  const hasProfanity = PRESSURE_SIGNALS.test(message2);
@@ -520475,7 +520719,7 @@ function executeHook(hook, env2 = {}) {
520475
520719
  maxBuffer: 1024 * 1024
520476
520720
  // 1MB
520477
520721
  });
520478
- const directive = parseDirective(output);
520722
+ const directive = parseDirective2(output);
520479
520723
  return {
520480
520724
  success: true,
520481
520725
  output: output.trim(),
@@ -520493,7 +520737,7 @@ function executeHook(hook, env2 = {}) {
520493
520737
  };
520494
520738
  }
520495
520739
  }
520496
- function parseDirective(output) {
520740
+ function parseDirective2(output) {
520497
520741
  const lines = output.split("\n");
520498
520742
  for (const line of lines) {
520499
520743
  const trimmed = line.trim();
@@ -521149,6 +521393,7 @@ var init_agenticRunner = __esm({
521149
521393
  init_world_state_regenerator();
521150
521394
  init_backward_pass_runner();
521151
521395
  init_world_state_plan_reconciler();
521396
+ init_stuck_meta_analyzer();
521152
521397
  init_pressure_gate();
521153
521398
  init_dist5();
521154
521399
  init_dist7();
@@ -524025,6 +524270,91 @@ ${_staleSamples.join("\n")}` : ``,
524025
524270
  content: `REG-44 STUCK detector fired at turn ${turn} — triggers=[${_trigLabels.join(",")}], reads=${_readCount}, mutations=${_mutationCount}, stale=${_staleCount}, window=${_windowCalls.length}`,
524026
524271
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
524027
524272
  });
524273
+ try {
524274
+ const _smaRaw = (process.env["OA_STUCK_META_ANALYZER"] || "off").toLowerCase();
524275
+ const _smaOn = _smaRaw === "on" || _smaRaw === "1" || _smaRaw === "true";
524276
+ if (_smaOn) {
524277
+ const _smaCallable = async (prompt) => {
524278
+ try {
524279
+ const _r = await this.backend.chatCompletion({
524280
+ messages: [
524281
+ { role: "system", content: "You are a META-ANALYSIS sub-agent. Audit the implementer's stuck state and emit a structured JSON directive." },
524282
+ { role: "user", content: prompt }
524283
+ ],
524284
+ tools: [],
524285
+ temperature: 0,
524286
+ maxTokens: parseInt(process.env["OA_STUCK_META_MAX_TOKENS"] || "2048", 10) || 2048,
524287
+ timeoutMs: parseInt(process.env["OA_STUCK_META_TIMEOUT_MS"] || "120000", 10) || 12e4
524288
+ });
524289
+ const _c = _r?.choices?.[0]?.message?.content;
524290
+ return typeof _c === "string" ? _c : "";
524291
+ } catch {
524292
+ return "";
524293
+ }
524294
+ };
524295
+ const _smaCalls = _windowCalls.slice(-25).map((c9) => ({
524296
+ name: c9.name,
524297
+ argsKey: c9.argsKey,
524298
+ success: c9.success,
524299
+ outputPreview: (c9.outputPreview || "").split(/\r?\n/)[0]?.slice(0, 120) ?? ""
524300
+ }));
524301
+ const _smaPlan = (() => {
524302
+ try {
524303
+ const _todos = this.readSessionTodos() || [];
524304
+ return _todos.slice(0, 12).map((t2) => ({
524305
+ content: t2.content || "",
524306
+ reconciled: t2.status || "pending",
524307
+ rationale: "(reconcile context unavailable here; structural status only)"
524308
+ }));
524309
+ } catch {
524310
+ return [];
524311
+ }
524312
+ })();
524313
+ const _smaFailures = Array.from(this._failureReflections.entries()).map(([stem, entry]) => ({
524314
+ stem,
524315
+ attempts: entry.attempts,
524316
+ preview: (entry.wentWrong || "").slice(0, 200)
524317
+ })).sort((a2, b) => b.attempts - a2.attempts).slice(0, 5);
524318
+ const _smaTools = Array.from(this.tools.keys());
524319
+ runStuckAnalyzer({
524320
+ inputs: {
524321
+ goal: this._taskState.originalGoal || this._taskState.goal || "",
524322
+ workingDir: this._workingDirectory || process.cwd(),
524323
+ triggerReason: `reg44-${_trigLabels[0] || "unknown"}`,
524324
+ recentToolCalls: _smaCalls,
524325
+ planStatus: _smaPlan,
524326
+ recentFailures: _smaFailures,
524327
+ workspaceSummary: void 0,
524328
+ // world-state regen owns this; analyzer infers from calls
524329
+ availableTools: _smaTools,
524330
+ turn
524331
+ },
524332
+ callable: _smaCallable
524333
+ }).then((_smaResult) => {
524334
+ if (_smaResult.injection && !_smaResult.directive.parseFallback) {
524335
+ messages2.push({ role: "system", content: _smaResult.injection });
524336
+ this.emit({
524337
+ type: "status",
524338
+ content: `REG-49 stuck-meta-analyzer fired at turn ${turn} — diagnosis="${_smaResult.directive.diagnosis.slice(0, 80)}", next=${_smaResult.directive.next_action.tool}, ${_smaResult.durationMs}ms`,
524339
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
524340
+ });
524341
+ } else {
524342
+ this.emit({
524343
+ type: "status",
524344
+ content: `REG-49 stuck-meta-analyzer parse failed at turn ${turn} — falling back to REG-44 abstract halt only`,
524345
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
524346
+ });
524347
+ }
524348
+ }).catch((_e) => {
524349
+ this.emit({
524350
+ type: "status",
524351
+ content: `REG-49 stuck-meta-analyzer threw: ${_e instanceof Error ? _e.message : String(_e)} (non-fatal)`,
524352
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
524353
+ });
524354
+ });
524355
+ }
524356
+ } catch (_e) {
524357
+ }
524028
524358
  }
524029
524359
  }
524030
524360
  }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.498",
3
+ "version": "0.187.499",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "open-agents-ai",
9
- "version": "0.187.498",
9
+ "version": "0.187.499",
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.498",
3
+ "version": "0.187.499",
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",