open-agents-ai 0.187.183 → 0.187.184

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.
Files changed (2) hide show
  1. package/dist/index.js +80 -14
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2652,14 +2652,16 @@ var init_glob_find = __esm({
2652
2652
  });
2653
2653
 
2654
2654
  // packages/execution/dist/tools/web-fetch.js
2655
- var DEFAULT_MAX_LENGTH, SHORT_CONTENT_THRESHOLD, WebFetchTool;
2655
+ var DEFAULT_MAX_LENGTH, SHORT_CONTENT_THRESHOLD, CACHE_TTL_MS, WebFetchTool;
2656
2656
  var init_web_fetch = __esm({
2657
2657
  "packages/execution/dist/tools/web-fetch.js"() {
2658
2658
  "use strict";
2659
2659
  DEFAULT_MAX_LENGTH = 5e3;
2660
2660
  SHORT_CONTENT_THRESHOLD = 200;
2661
+ CACHE_TTL_MS = 6e4;
2661
2662
  WebFetchTool = class {
2662
2663
  name = "web_fetch";
2664
+ _fetchCache = /* @__PURE__ */ new Map();
2663
2665
  description = "Fetch a single web page and return its text content (HTML stripped to plain text). FASTEST web tool \u2014 use this for reading any single URL: documentation, articles, README files, API references, Stack Overflow answers. Limitations: no JavaScript rendering (SPAs/React apps return empty), no link following, no cookies/auth, no structured data extraction. If the page is blank or incomplete, switch to web_crawl with strategy='playwright'. For scraping/extracting structured data (prices, listings, tables), use web_crawl instead. For search engine queries, use web_search instead. For interactive browser sessions (login, form filling, clicking), use browser_action instead.";
2664
2666
  parameters = {
2665
2667
  type: "object",
@@ -2679,6 +2681,19 @@ var init_web_fetch = __esm({
2679
2681
  const url = args["url"];
2680
2682
  const maxLength = args["max_length"] ?? DEFAULT_MAX_LENGTH;
2681
2683
  const start2 = performance.now();
2684
+ const cached = this._fetchCache.get(url);
2685
+ if (cached && Date.now() - cached.fetchedAt < CACHE_TTL_MS) {
2686
+ const slicedCache = cached.text.length > maxLength ? `${cached.text.slice(0, maxLength)}
2687
+
2688
+ [Content truncated to ${maxLength} characters]` : cached.text;
2689
+ return {
2690
+ success: true,
2691
+ output: `[CACHED \u2014 already fetched this URL in this session; the content below is the full response. Do NOT re-fetch the same URL. If the content seems short, the page may just be short or require JavaScript \u2014 use browser_action with a headless browser instead.]
2692
+
2693
+ ` + slicedCache,
2694
+ durationMs: performance.now() - start2
2695
+ };
2696
+ }
2682
2697
  try {
2683
2698
  const response = await fetch(url, {
2684
2699
  headers: {
@@ -2697,6 +2712,7 @@ var init_web_fetch = __esm({
2697
2712
  }
2698
2713
  const html = await response.text();
2699
2714
  const text = this.#stripHtml(html);
2715
+ this._fetchCache.set(url, { text, fetchedAt: Date.now() });
2700
2716
  if (text.length < SHORT_CONTENT_THRESHOLD) {
2701
2717
  return {
2702
2718
  success: true,
@@ -2711,7 +2727,7 @@ var init_web_fetch = __esm({
2711
2727
  success: true,
2712
2728
  output: truncated ? `${text.slice(0, maxLength)}
2713
2729
 
2714
- [Content truncated to ${maxLength} characters]` : text,
2730
+ [Content truncated to ${maxLength} characters. The full response is cached for this session \u2014 subsequent calls to the same URL return the cached content.]` : text,
2715
2731
  durationMs: performance.now() - start2
2716
2732
  };
2717
2733
  } catch (error) {
@@ -265405,6 +265421,35 @@ function cleanForStorage(text) {
265405
265421
  out = out.replace(/\s+/g, " ").trim();
265406
265422
  return out;
265407
265423
  }
265424
+ function extractTaskCompleteSummary(args) {
265425
+ if (args == null)
265426
+ return "";
265427
+ if (typeof args === "string")
265428
+ return stripThinkTags(args);
265429
+ if (typeof args === "object") {
265430
+ const obj = args;
265431
+ if (typeof obj.summary === "string" && obj.summary.trim().length > 0) {
265432
+ return stripThinkTags(obj.summary);
265433
+ }
265434
+ for (const alt of ["text", "message", "result", "output", "content", "response", "answer"]) {
265435
+ if (typeof obj[alt] === "string" && obj[alt].trim().length > 0) {
265436
+ return stripThinkTags(obj[alt]);
265437
+ }
265438
+ }
265439
+ if (typeof obj[""] === "string" && obj[""].trim().length > 0) {
265440
+ let value2 = obj[""];
265441
+ value2 = value2.replace(/^[^>]*>\s*\n?/, "");
265442
+ value2 = value2.replace(/\s*<\/[^>]+>\s*$/, "");
265443
+ return stripThinkTags(value2.trim());
265444
+ }
265445
+ const stringValues = Object.values(obj).filter((v) => typeof v === "string" && v.trim().length > 0);
265446
+ if (stringValues.length > 0) {
265447
+ const longest = stringValues.reduce((a2, b) => a2.length >= b.length ? a2 : b);
265448
+ return stripThinkTags(longest);
265449
+ }
265450
+ }
265451
+ return "";
265452
+ }
265408
265453
  var SIGNPOST_RE, NEW_TASK_RE, RESTORED_BLOCK_RE, SYSTEM_BLOCK_RE, THINK_BLOCK_RE, ANSI_ESCAPE_RE;
265409
265454
  var init_textSanitize = __esm({
265410
265455
  "packages/orchestrator/dist/textSanitize.js"() {
@@ -266103,6 +266148,15 @@ import { join as join63 } from "node:path";
266103
266148
  import { mkdirSync as mkdirSync24, existsSync as existsSync47 } from "node:fs";
266104
266149
  import { randomUUID as randomUUID5 } from "node:crypto";
266105
266150
  import { createHash as createHash3 } from "node:crypto";
266151
+ function sanitizeImportance(raw, fallback = 5) {
266152
+ if (typeof raw !== "number" || !Number.isFinite(raw))
266153
+ return fallback;
266154
+ if (raw < 0)
266155
+ return 0;
266156
+ if (raw > 10)
266157
+ return 10;
266158
+ return raw;
266159
+ }
266106
266160
  function autoImportance(toolName, modality, content) {
266107
266161
  if (toolName === "task_complete")
266108
266162
  return 9;
@@ -266203,7 +266257,8 @@ var init_episodeStore = __esm({
266203
266257
  const now = Date.now();
266204
266258
  const contentHash = createHash3("sha256").update(ep.content).digest("hex").slice(0, 16);
266205
266259
  const modality = ep.modality ?? "text";
266206
- const importance = ep.importance ?? autoImportance(ep.toolName ?? null, modality, ep.content);
266260
+ const rawImportance = ep.importance ?? autoImportance(ep.toolName ?? null, modality, ep.content);
266261
+ const importance = sanitizeImportance(rawImportance);
266207
266262
  const decayClass = ep.decayClass ?? autoDecayClass(ep.toolName ?? null, modality, ep.content);
266208
266263
  const existing = this.db.prepare("SELECT id FROM episodes WHERE content_hash = ? AND session_id = ? LIMIT 1").get(contentHash, ep.sessionId ?? null);
266209
266264
  if (existing)
@@ -266335,9 +266390,12 @@ var init_episodeStore = __esm({
266335
266390
  contentHash: row.content_hash,
266336
266391
  metadata: row.metadata ? JSON.parse(row.metadata) : null,
266337
266392
  embedding: row.embedding ? new Float32Array(new Uint8Array(row.embedding).buffer) : null,
266338
- importance: row.importance,
266393
+ // Belt-and-braces: rows from pre-fix DBs may have null importance
266394
+ // (from legacy inserts with NaN that SQLite coerced to NULL).
266395
+ // Re-sanitize on read so downstream code always sees a valid number.
266396
+ importance: sanitizeImportance(row.importance),
266339
266397
  decayClass: row.decay_class,
266340
- strength: row.strength,
266398
+ strength: typeof row.strength === "number" && Number.isFinite(row.strength) ? row.strength : 1,
266341
266399
  lastRetrieved: row.last_retrieved,
266342
266400
  gist: row.gist,
266343
266401
  sourceEpisodeId: row.source_episode_id
@@ -269441,7 +269499,7 @@ ${sr.result.output}`;
269441
269499
  messages2.push(this.buildToolMessage(output, matchTc.id));
269442
269500
  if (matchTc.name === "task_complete") {
269443
269501
  completed = true;
269444
- summary = matchTc.arguments.summary || "";
269502
+ summary = extractTaskCompleteSummary(matchTc.arguments);
269445
269503
  if (summary && !this._assistantTextEmitted) {
269446
269504
  this.emit({ type: "assistant_text", content: summary, turn, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
269447
269505
  this._assistantTextEmitted = true;
@@ -269460,7 +269518,7 @@ ${sr.result.output}`;
269460
269518
  messages2.push(this.buildToolMessage(r2.output, r2.tc.id));
269461
269519
  if (r2.tc.name === "task_complete") {
269462
269520
  completed = true;
269463
- summary = r2.tc.arguments.summary || "";
269521
+ summary = extractTaskCompleteSummary(r2.tc.arguments);
269464
269522
  if (summary && !this._assistantTextEmitted) {
269465
269523
  this.emit({ type: "assistant_text", content: summary, turn, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
269466
269524
  this._assistantTextEmitted = true;
@@ -269489,7 +269547,7 @@ ${sr.result.output}`;
269489
269547
  messages2.push(this.buildToolMessage(r2.output, r2.tc.id));
269490
269548
  if (r2.tc.name === "task_complete") {
269491
269549
  completed = true;
269492
- summary = r2.tc.arguments.summary || "";
269550
+ summary = extractTaskCompleteSummary(r2.tc.arguments);
269493
269551
  if (summary && !this._assistantTextEmitted) {
269494
269552
  this.emit({ type: "assistant_text", content: summary, turn, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
269495
269553
  this._assistantTextEmitted = true;
@@ -269889,7 +269947,7 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
269889
269947
  messages2.push(toolMsg);
269890
269948
  if (tc.name === "task_complete") {
269891
269949
  completed = true;
269892
- summary = tc.arguments.summary || "";
269950
+ summary = extractTaskCompleteSummary(tc.arguments);
269893
269951
  if (summary && !this._assistantTextEmitted) {
269894
269952
  this.emit({ type: "assistant_text", content: summary, turn, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
269895
269953
  this._assistantTextEmitted = true;
@@ -274045,6 +274103,7 @@ var init_coordinator = __esm({
274045
274103
  "use strict";
274046
274104
  init_agent_types();
274047
274105
  init_agent_task();
274106
+ init_textSanitize();
274048
274107
  }
274049
274108
  });
274050
274109
 
@@ -307892,6 +307951,7 @@ var init_dmn_engine = __esm({
307892
307951
  "packages/cli/src/tui/dmn-engine.ts"() {
307893
307952
  "use strict";
307894
307953
  init_dist8();
307954
+ init_dist8();
307895
307955
  init_dist4();
307896
307956
  init_project_context();
307897
307957
  init_render();
@@ -307951,7 +308011,9 @@ var init_dmn_engine = __esm({
307951
308011
  }
307952
308012
  /** Record a task failure for Reflexion-style learning */
307953
308013
  recordTaskFailure(summary, errorContext, category) {
307954
- const reflection = errorContext ? `FAILED: ${summary.slice(0, 200)} \u2014 Error: ${errorContext.slice(0, 300)}` : `FAILED: ${summary.slice(0, 500)}`;
308014
+ const cleanSummary = cleanForStorage(summary);
308015
+ const cleanError = errorContext ? cleanForStorage(errorContext) : "";
308016
+ const reflection = cleanError ? `FAILED: ${cleanSummary.slice(0, 200)} \u2014 Error: ${cleanError.slice(0, 300)}` : `FAILED: ${cleanSummary.slice(0, 500)}`;
307955
308017
  this.state.reflectionBuffer.push(reflection);
307956
308018
  if (this.state.reflectionBuffer.length > 5) {
307957
308019
  this.state.reflectionBuffer.shift();
@@ -315295,7 +315357,8 @@ function createSubAgentTool(config, repoRoot, ctxWindowSize) {
315295
315357
  return { success: false, output: "", error: "task is required" };
315296
315358
  }
315297
315359
  const agentId = `sub-agent-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
315298
- const agentLabel = `sub_agent: ${task.slice(0, 40)}${task.length > 40 ? "..." : ""}`;
315360
+ const cleanedLabelTask = cleanForStorage(task) || task;
315361
+ const agentLabel = `sub_agent: ${cleanedLabelTask.slice(0, 40)}${cleanedLabelTask.length > 40 ? "..." : ""}`;
315299
315362
  if (onViewRegister) {
315300
315363
  onViewRegister(agentId, agentLabel);
315301
315364
  }
@@ -315355,7 +315418,7 @@ function createSubAgentTool(config, repoRoot, ctxWindowSize) {
315355
315418
  if (onComplete) onComplete(agentId, task, result2.completed ? 0 : 1, output2);
315356
315419
  return output2;
315357
315420
  });
315358
- const taskId = taskManager.trackPromise(`sub_agent: ${task.slice(0, 80)}`, promise);
315421
+ const taskId = taskManager.trackPromise(`sub_agent: ${cleanedLabelTask.slice(0, 80)}`, promise);
315359
315422
  return {
315360
315423
  success: true,
315361
315424
  output: `Sub-agent started in background: ${taskId}
@@ -320982,7 +321045,8 @@ function statusCommand(jobId, repoPath) {
320982
321045
  const runtime = job.completedAt ? `${((new Date(job.completedAt).getTime() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s` : `${((Date.now() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s`;
320983
321046
  const icon = job.status === "completed" ? "\u2713" : job.status === "failed" ? "\u2717" : "\u25CF";
320984
321047
  console.log(`${icon} ${job.id} [${job.status}] ${runtime}`);
320985
- console.log(` Task: ${job.task.slice(0, 80)}`);
321048
+ const cleanTask = cleanForStorage(job.task) || job.task;
321049
+ console.log(` Task: ${cleanTask.slice(0, 80)}`);
320986
321050
  console.log(` PID: ${job.pid}`);
320987
321051
  if (job.summary) console.log(` Summary: ${job.summary}`);
320988
321052
  if (job.error) console.log(` Error: ${job.error}`);
@@ -321001,7 +321065,8 @@ function jobsCommand(repoPath) {
321001
321065
  const job = JSON.parse(readFileSync61(join95(dir, file), "utf-8"));
321002
321066
  const icon = job.status === "completed" ? "\u2713" : job.status === "failed" ? "\u2717" : "\u25CF";
321003
321067
  const runtime = job.completedAt ? `${((new Date(job.completedAt).getTime() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s` : `${((Date.now() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s`;
321004
- console.log(` ${icon} ${job.id} [${job.status}] ${runtime} \u2014 ${job.task.slice(0, 60)}`);
321068
+ const cleanListTask = cleanForStorage(job.task) || job.task;
321069
+ console.log(` ${icon} ${job.id} [${job.status}] ${runtime} \u2014 ${cleanListTask.slice(0, 60)}`);
321005
321070
  } catch {
321006
321071
  }
321007
321072
  }
@@ -321010,6 +321075,7 @@ var init_run = __esm({
321010
321075
  "packages/cli/src/commands/run.ts"() {
321011
321076
  "use strict";
321012
321077
  init_interactive();
321078
+ init_dist8();
321013
321079
  }
321014
321080
  });
321015
321081
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.183",
3
+ "version": "0.187.184",
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",