open-agents-ai 0.187.181 → 0.187.183

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 +113 -32
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3480,13 +3480,32 @@ ${JSON.stringify(entries, null, 2)}`,
3480
3480
  });
3481
3481
 
3482
3482
  // packages/execution/dist/tools/memory-write.js
3483
- import { readFile as readFile4, writeFile as writeFile3, mkdir as mkdir2 } from "node:fs/promises";
3483
+ import { readFile as readFile4, writeFile as writeFile3, mkdir as mkdir2, rename } from "node:fs/promises";
3484
3484
  import { resolve as resolve8, join as join7 } from "node:path";
3485
3485
  import { randomBytes as randomBytes3 } from "node:crypto";
3486
- var MemoryWriteTool;
3486
+ async function withTopicLock(topicFile, fn) {
3487
+ const prev = _writeLocks.get(topicFile) ?? Promise.resolve();
3488
+ let release2 = () => {
3489
+ };
3490
+ const current = new Promise((resolve39) => {
3491
+ release2 = resolve39;
3492
+ });
3493
+ _writeLocks.set(topicFile, prev.then(() => current));
3494
+ try {
3495
+ await prev;
3496
+ return await fn();
3497
+ } finally {
3498
+ release2();
3499
+ if (_writeLocks.get(topicFile) === prev.then(() => current)) {
3500
+ _writeLocks.delete(topicFile);
3501
+ }
3502
+ }
3503
+ }
3504
+ var _writeLocks, MemoryWriteTool;
3487
3505
  var init_memory_write = __esm({
3488
3506
  "packages/execution/dist/tools/memory-write.js"() {
3489
3507
  "use strict";
3508
+ _writeLocks = /* @__PURE__ */ new Map();
3490
3509
  MemoryWriteTool = class {
3491
3510
  name = "memory_write";
3492
3511
  description = "Store a fact or pattern in the agent's persistent memory. Use this to remember solutions, code patterns, or debugging insights for future tasks.";
@@ -3523,19 +3542,23 @@ var init_memory_write = __esm({
3523
3542
  for (const memoryDir of [oaMemDir, legacyMemDir]) {
3524
3543
  await mkdir2(memoryDir, { recursive: true });
3525
3544
  const topicFile = join7(memoryDir, `${topic}.json`);
3526
- let entries = {};
3527
- try {
3528
- const raw = await readFile4(topicFile, "utf-8");
3529
- entries = JSON.parse(raw);
3530
- } catch {
3531
- }
3532
- const artifactId = `mem-${randomBytes3(6).toString("hex")}`;
3533
- entries[key] = {
3534
- value: value2,
3535
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
3536
- artifactId
3537
- };
3538
- await writeFile3(topicFile, JSON.stringify(entries, null, 2), "utf-8");
3545
+ await withTopicLock(topicFile, async () => {
3546
+ let entries = {};
3547
+ try {
3548
+ const raw = await readFile4(topicFile, "utf-8");
3549
+ entries = JSON.parse(raw);
3550
+ } catch {
3551
+ }
3552
+ const artifactId = `mem-${randomBytes3(6).toString("hex")}`;
3553
+ entries[key] = {
3554
+ value: value2,
3555
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
3556
+ artifactId
3557
+ };
3558
+ const tempFile = `${topicFile}.tmp-${randomBytes3(4).toString("hex")}`;
3559
+ await writeFile3(tempFile, JSON.stringify(entries, null, 2), "utf-8");
3560
+ await rename(tempFile, topicFile);
3561
+ });
3539
3562
  }
3540
3563
  const provenanceDir = resolve8(this.workingDir, ".oa", "provenance");
3541
3564
  try {
@@ -244487,7 +244510,7 @@ var init_src107 = __esm({
244487
244510
  });
244488
244511
 
244489
244512
  // ../node_modules/steno/lib/index.js
244490
- import { rename, writeFile as writeFile9 } from "node:fs/promises";
244513
+ import { rename as rename2, writeFile as writeFile9 } from "node:fs/promises";
244491
244514
  import { basename as basename5, dirname as dirname6, join as join22 } from "node:path";
244492
244515
  import { fileURLToPath as fileURLToPath2 } from "node:url";
244493
244516
  function getTempFilename(file) {
@@ -244534,7 +244557,7 @@ var init_lib3 = __esm({
244534
244557
  try {
244535
244558
  await writeFile9(this.#tempFilename, data, "utf-8");
244536
244559
  await retryAsyncOperation(async () => {
244537
- await rename(this.#tempFilename, this.#filename);
244560
+ await rename2(this.#tempFilename, this.#filename);
244538
244561
  }, 10, 100);
244539
244562
  this.#prev?.[0]();
244540
244563
  } catch (err) {
@@ -265356,6 +265379,45 @@ var init_ralphLoop = __esm({
265356
265379
  }
265357
265380
  });
265358
265381
 
265382
+ // packages/orchestrator/dist/textSanitize.js
265383
+ function cleanScaffolding(text) {
265384
+ if (text == null)
265385
+ return "";
265386
+ let out = String(text);
265387
+ out = out.replace(SIGNPOST_RE, "");
265388
+ out = out.replace(RESTORED_BLOCK_RE, "");
265389
+ out = out.replace(NEW_TASK_RE, "");
265390
+ out = out.replace(SYSTEM_BLOCK_RE, "");
265391
+ return out.trim();
265392
+ }
265393
+ function stripThinkTags(text) {
265394
+ if (text == null)
265395
+ return "";
265396
+ return String(text).replace(THINK_BLOCK_RE, "").trim();
265397
+ }
265398
+ function cleanForStorage(text) {
265399
+ if (text == null)
265400
+ return "";
265401
+ let out = String(text);
265402
+ out = cleanScaffolding(out);
265403
+ out = stripThinkTags(out);
265404
+ out = out.replace(ANSI_ESCAPE_RE, "");
265405
+ out = out.replace(/\s+/g, " ").trim();
265406
+ return out;
265407
+ }
265408
+ var SIGNPOST_RE, NEW_TASK_RE, RESTORED_BLOCK_RE, SYSTEM_BLOCK_RE, THINK_BLOCK_RE, ANSI_ESCAPE_RE;
265409
+ var init_textSanitize = __esm({
265410
+ "packages/orchestrator/dist/textSanitize.js"() {
265411
+ "use strict";
265412
+ SIGNPOST_RE = /^\[Previous sessions exist[^\]]*\]\s*\n*/m;
265413
+ NEW_TASK_RE = /^NEW TASK:\s*/m;
265414
+ RESTORED_BLOCK_RE = /^[\s\S]*?\n---\s*\n\s*NEW TASK:\s*/m;
265415
+ SYSTEM_BLOCK_RE = /^<system>[\s\S]*?<\/system>\s*\n*/m;
265416
+ THINK_BLOCK_RE = /<think>[\s\S]*?<\/think>/g;
265417
+ ANSI_ESCAPE_RE = /\x1b\[[0-9;]*[a-zA-Z]|\x1b\][^\x07]*\x07/g;
265418
+ }
265419
+ });
265420
+
265359
265421
  // packages/orchestrator/dist/personality.js
265360
265422
  function compilePersonalityPrompt(profile, presetName) {
265361
265423
  if (presetName === "stark") {
@@ -266224,10 +266286,18 @@ var init_episodeStore = __esm({
266224
266286
  const params = sessionId ? [sessionId, limit] : [limit];
266225
266287
  return this.db.prepare(sql).all(...params).map((r2) => this.rowToEpisode(r2));
266226
266288
  }
266227
- /** Count episodes. */
266289
+ /** Count episodes.
266290
+ *
266291
+ * BUG FIX (2026-04-07): previously passed `sessionId` to `.get()` even
266292
+ * when the SQL had no placeholder, causing `RangeError: Too many
266293
+ * parameter values were provided` on every `count()` call without args.
266294
+ * Now we only bind when the placeholder is actually present.
266295
+ */
266228
266296
  count(sessionId) {
266229
- const sql = sessionId ? "SELECT COUNT(*) as n FROM episodes WHERE session_id = ?" : "SELECT COUNT(*) as n FROM episodes";
266230
- return this.db.prepare(sql).get(sessionId).n;
266297
+ if (sessionId) {
266298
+ return this.db.prepare("SELECT COUNT(*) as n FROM episodes WHERE session_id = ?").get(sessionId).n;
266299
+ }
266300
+ return this.db.prepare("SELECT COUNT(*) as n FROM episodes").get().n;
266231
266301
  }
266232
266302
  /** Prune expired session-class episodes (call at session end). */
266233
266303
  pruneExpired() {
@@ -267638,6 +267708,7 @@ var SYSTEM_PROMPT, SYSTEM_PROMPT_MEDIUM, SYSTEM_PROMPT_SMALL, AgenticRunner, Oll
267638
267708
  var init_agenticRunner = __esm({
267639
267709
  "packages/orchestrator/dist/agenticRunner.js"() {
267640
267710
  "use strict";
267711
+ init_textSanitize();
267641
267712
  init_dist();
267642
267713
  init_personality();
267643
267714
  init_promptLoader();
@@ -268279,6 +268350,7 @@ Respond with your assessment, then take action.`;
268279
268350
  if (typeof this.backend.setAbortSignal === "function") {
268280
268351
  this.backend.setAbortSignal(this._abortController.signal);
268281
268352
  }
268353
+ const cleanedTask = cleanForStorage(task) || task.slice(0, 500);
268282
268354
  const start2 = Date.now();
268283
268355
  const taskTimeoutMs = this.options.taskTimeoutMs;
268284
268356
  const selfEvalInterval = taskTimeoutMs;
@@ -268328,7 +268400,7 @@ Respond with your assessment, then take action.`;
268328
268400
  this._pauseResolve = null;
268329
268401
  this.pendingUserMessages.length = 0;
268330
268402
  this._taskState = {
268331
- goal: task.slice(0, 500),
268403
+ goal: cleanedTask.slice(0, 500),
268332
268404
  completedSteps: [],
268333
268405
  pendingSteps: [],
268334
268406
  currentStep: "",
@@ -268652,7 +268724,7 @@ If you're stuck, try a completely different approach. Do NOT repeat what failed
268652
268724
  }
268653
268725
  if (turn > 0 && turn % 3 === 0 && this._temporalGraph && this._episodeStore) {
268654
268726
  try {
268655
- const taskGoal = this._taskState.goal || task.slice(0, 200);
268727
+ const taskGoal = this._taskState.goal || cleanedTask.slice(0, 200);
268656
268728
  const pprResult = retrieveByPPR(taskGoal, this._temporalGraph, this._episodeStore, { topK: 3 });
268657
268729
  if (pprResult.episodes.length > 0) {
268658
268730
  const memoryLines = pprResult.episodes.map(({ episode, pprScore, matchedNodes }) => `- [${episode.toolName ?? episode.modality}] ${episode.content.slice(0, 120)} (via: ${matchedNodes.slice(0, 2).join(", ")})`);
@@ -269907,7 +269979,7 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
269907
269979
  };
269908
269980
  const consolidation = {
269909
269981
  sessionId: this._sessionId,
269910
- task: task.slice(0, 500),
269982
+ task: cleanedTask.slice(0, 500),
269911
269983
  outcome: completed ? "success" : this.aborted ? "aborted" : "timeout",
269912
269984
  turns: messages2.filter((m2) => m2.role === "assistant").length,
269913
269985
  toolsUsed: [...new Set(toolCallLog.map((tc) => tc.name))],
@@ -269926,7 +269998,7 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
269926
269998
  fs4.mkdirSync(provenanceDir, { recursive: true });
269927
269999
  const provenanceGraph = {
269928
270000
  sessionId: this._sessionId,
269929
- task: task.slice(0, 500),
270001
+ task: cleanedTask.slice(0, 500),
269930
270002
  outcome: consolidation.outcome,
269931
270003
  timestamp: consolidation.timestamp,
269932
270004
  // Full action trace — every tool call with sequence ordering
@@ -269970,7 +270042,7 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
269970
270042
  fs4.writeFileSync(path5.join(provenanceDir, `${this._sessionId}.json`), JSON.stringify(provenanceGraph, null, 2));
269971
270043
  if (completed && this.tools.has("memory_write")) {
269972
270044
  const memTool = this.tools.get("memory_write");
269973
- const lessonContent = `Task "${task.slice(0, 100)}" completed successfully. Tools: ${consolidation.toolsUsed.join(", ")}. Files: ${consolidation.filesModified.slice(0, 3).join(", ")}. Duration: ${Math.round(durationMs / 1e3)}s, ${consolidation.turns} turns.`;
270045
+ const lessonContent = `Task "${cleanedTask.slice(0, 100)}" completed successfully. Tools: ${consolidation.toolsUsed.join(", ")}. Files: ${consolidation.filesModified.slice(0, 3).join(", ")}. Duration: ${Math.round(durationMs / 1e3)}s, ${consolidation.turns} turns.`;
269974
270046
  try {
269975
270047
  await memTool.execute({
269976
270048
  topic: "task_lessons",
@@ -269993,7 +270065,7 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
269993
270065
  sessionId: this._sessionId,
269994
270066
  modality: "gist",
269995
270067
  toolName: "task_complete",
269996
- content: `Task "${task.slice(0, 200)}" ${completed ? "completed" : "ended"}: ${summary.slice(0, 300)}`,
270068
+ content: `Task "${cleanedTask.slice(0, 200)}" ${completed ? "completed" : "ended"}: ${cleanForStorage(summary).slice(0, 300)}`,
269997
270069
  importance: 9,
269998
270070
  decayClass: "procedural"
269999
270071
  });
@@ -270040,7 +270112,10 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
270040
270112
  fs4.mkdirSync(trajDir, { recursive: true });
270041
270113
  const trajectory = {
270042
270114
  id: this._sessionId,
270043
- task: task.slice(0, 1e3),
270115
+ // CLEAN task — this file is the prerequisite for ALL future RL/RFT
270116
+ // training. Storing the scaffolded version would teach future models
270117
+ // to reproduce signpost text as part of their task understanding.
270118
+ task: cleanedTask.slice(0, 1e3),
270044
270119
  outcome: completed ? "pass" : this.aborted ? "aborted" : "timeout",
270045
270120
  model: this.backend.model ?? "unknown",
270046
270121
  modelTier: this.options.modelTier ?? "large",
@@ -273597,6 +273672,7 @@ var init_sessionMetrics = __esm({
273597
273672
  var init_taskLearning = __esm({
273598
273673
  "packages/orchestrator/dist/taskLearning.js"() {
273599
273674
  "use strict";
273675
+ init_textSanitize();
273600
273676
  }
273601
273677
  });
273602
273678
 
@@ -274200,6 +274276,7 @@ var init_dist8 = __esm({
274200
274276
  init_skill_fork();
274201
274277
  init_streaming_executor();
274202
274278
  init_app_state();
274279
+ init_textSanitize();
274203
274280
  }
274204
274281
  });
274205
274282
 
@@ -303940,9 +304017,11 @@ function loadSessionHistory2(repoRoot) {
303940
304017
  if (!s2.startedAt || !s2.task) continue;
303941
304018
  const status = s2.completed ? "completed" : "incomplete";
303942
304019
  const date = s2.startedAt.split("T")[0];
303943
- lines.push(`- [${date}] ${s2.task.slice(0, 80)} (${status}, ${s2.turns ?? 0} turns)`);
304020
+ const cleanTask = cleanForStorage(s2.task) || s2.task;
304021
+ lines.push(`- [${date}] ${cleanTask.slice(0, 80)} (${status}, ${s2.turns ?? 0} turns)`);
303944
304022
  if (s2.summary) {
303945
- lines.push(` Summary: ${s2.summary.slice(0, 120)}`);
304023
+ const cleanSummary = cleanForStorage(s2.summary) || s2.summary;
304024
+ lines.push(` Summary: ${cleanSummary.slice(0, 120)}`);
303946
304025
  }
303947
304026
  }
303948
304027
  return lines.join("\n");
@@ -304111,6 +304190,7 @@ These patterns have been repeated 3+ times. Consider using create_tool to automa
304111
304190
  var init_project_context = __esm({
304112
304191
  "packages/cli/src/tui/project-context.ts"() {
304113
304192
  "use strict";
304193
+ init_dist8();
304114
304194
  init_oa_directory();
304115
304195
  init_dist4();
304116
304196
  }
@@ -316618,7 +316698,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
316618
316698
  ikState.stats.tool_use_count = (ikState.stats.tool_use_count || 0) + result.toolCalls;
316619
316699
  }
316620
316700
  ikState.version = (ikState.version || 1) + 1;
316621
- ikState.version_history.push({ version: ikState.version, change: "query_served: " + result.summary.slice(0, 60), timestamp: (/* @__PURE__ */ new Date()).toISOString() });
316701
+ ikState.version_history.push({ version: ikState.version, change: "query_served: " + cleanForStorage(result.summary).slice(0, 60), timestamp: (/* @__PURE__ */ new Date()).toISOString() });
316622
316702
  if (ikState.version_history.length > 200) ikState.version_history = ikState.version_history.slice(-200);
316623
316703
  if (ikState.version % 10 === 0) {
316624
316704
  const specList = (ikState.specializations || []).join(", ") || "general-purpose";
@@ -316674,11 +316754,11 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
316674
316754
  id: sessionId,
316675
316755
  startedAt: new Date(Date.now() - result.durationMs).toISOString(),
316676
316756
  completedAt: (/* @__PURE__ */ new Date()).toISOString(),
316677
- task,
316757
+ task: cleanForStorage(task) || task.slice(0, 500),
316678
316758
  turns: result.turns,
316679
316759
  toolCalls: result.toolCalls,
316680
316760
  completed: result.completed,
316681
- summary: result.summary.slice(0, 500)
316761
+ summary: cleanForStorage(result.summary).slice(0, 500)
316682
316762
  });
316683
316763
  } catch {
316684
316764
  }
@@ -320672,6 +320752,7 @@ var init_interactive = __esm({
320672
320752
  init_dist8();
320673
320753
  init_dist8();
320674
320754
  init_dist8();
320755
+ init_dist8();
320675
320756
  init_dist4();
320676
320757
  init_dist();
320677
320758
  init_listen();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.181",
3
+ "version": "0.187.183",
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",