open-agents-ai 0.185.57 → 0.185.59

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
@@ -40431,6 +40431,23 @@ function saveSessionContext(repoRoot, entry) {
40431
40431
  }
40432
40432
  ctx.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
40433
40433
  writeFileSync15(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
40434
+ try {
40435
+ const diaryLines = ["# Session Diary", ""];
40436
+ for (const e of ctx.entries.slice(-10)) {
40437
+ const date = e.savedAt ? new Date(e.savedAt).toISOString().slice(0, 16).replace("T", " ") : "unknown";
40438
+ const status = e.completed ? "\u2713" : "\u25CB";
40439
+ const task = (e.task || "untitled").slice(0, 120);
40440
+ diaryLines.push(`## ${date} \u2014 ${task} ${status}`);
40441
+ if (e.filesModified?.length) {
40442
+ diaryLines.push(`Files: ${e.filesModified.slice(0, 5).join(", ")}${e.filesModified.length > 5 ? ` (+${e.filesModified.length - 5} more)` : ""}`);
40443
+ }
40444
+ if (e.summary)
40445
+ diaryLines.push(`Summary: ${e.summary.slice(0, 200)}`);
40446
+ diaryLines.push("");
40447
+ }
40448
+ writeFileSync15(join53(contextDir, "session-diary.md"), diaryLines.join("\n"), "utf-8");
40449
+ } catch {
40450
+ }
40434
40451
  }
40435
40452
  function loadSessionContext(repoRoot) {
40436
40453
  const filePath = join53(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
@@ -51832,23 +51849,13 @@ async function showCohereDashboard(ctx) {
51832
51849
  }
51833
51850
  }
51834
51851
  async function showModelPicker(ctx, local = false) {
51835
- const BRAILLE_CYCLE = ["\u2800", "\u2840", "\u28C0", "\u28C4", "\u28E4", "\u28E6", "\u28F6", "\u28F7", "\u28FF", "\u28F7", "\u28F6", "\u28E6", "\u28E4", "\u28C4", "\u28C0", "\u2840"];
51836
- let spinFrame = 0;
51837
- const spinTimer = setInterval(() => {
51838
- process.stdout.write(`\r ${c2.cyan("\u25CF")} Loading models ${c2.cyan(BRAILLE_CYCLE[spinFrame++ % BRAILLE_CYCLE.length])}`);
51839
- }, 80);
51852
+ renderInfo("Loading models...");
51840
51853
  try {
51841
51854
  let models;
51842
- try {
51843
- const fetchPromise = fetchModels(ctx.config.backendUrl, ctx.config.apiKey);
51844
- const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error(`Timed out fetching models from ${ctx.config.backendUrl} (10s). The endpoint may be down. Use /endpoint to switch.`)), 1e4));
51845
- models = await Promise.race([fetchPromise, timeoutPromise]);
51846
- } finally {
51847
- clearInterval(spinTimer);
51848
- process.stdout.write(`\r${" ".repeat(40)}\r`);
51849
- }
51850
- process.stdout.write(` ${c2.green("\u2714")} ${models.length} models loaded
51851
- `);
51855
+ const fetchPromise = fetchModels(ctx.config.backendUrl, ctx.config.apiKey);
51856
+ const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error(`Timed out fetching models from ${ctx.config.backendUrl} (10s). The endpoint may be down. Use /endpoint to switch.`)), 1e4));
51857
+ models = await Promise.race([fetchPromise, timeoutPromise]);
51858
+ renderInfo(`${models.length} models loaded`);
51852
51859
  if (models.length === 0) {
51853
51860
  renderWarning("No models found.");
51854
51861
  return;
@@ -53247,26 +53254,6 @@ async function handleUpdate(subcommand, ctx) {
53247
53254
  }
53248
53255
  };
53249
53256
  }
53250
- function startInlineSpinner(prefix) {
53251
- let frame = 0;
53252
- const nvActive = isNeovimActive();
53253
- const timer = setInterval(() => {
53254
- if (nvActive)
53255
- return;
53256
- const braille = BRAILLE_CYCLE[frame % BRAILLE_CYCLE.length];
53257
- process.stdout.write(`\r ${c2.cyan("\u25CF")} ${prefix} ${c2.cyan(braille)}`);
53258
- frame++;
53259
- }, 80);
53260
- safeWrite(` ${c2.cyan("\u25CF")} ${prefix} ${c2.cyan(BRAILLE_CYCLE[0])}
53261
- `);
53262
- return {
53263
- stop(completionText) {
53264
- clearInterval(timer);
53265
- safeWrite(`\r ${c2.green("\u2714")} ${completionText}${" ".repeat(20)}
53266
- `);
53267
- }
53268
- };
53269
- }
53270
53257
  const { exec: exec4, execSync: es2 } = await import("node:child_process");
53271
53258
  const execA = (cmd, opts) => new Promise((res, rej) => exec4(cmd, { encoding: "utf8", timeout: opts?.timeout ?? 3e4, cwd: opts?.cwd }, (err, stdout) => err ? rej(err) : res((stdout || "").trim())));
53272
53259
  renderInfo("Checking for updates...");
@@ -54256,19 +54243,24 @@ ${ctx.memoryContext}
54256
54243
 
54257
54244
  Use this context to avoid re-learning known patterns. Update with memory_write if you discover new insights.`);
54258
54245
  }
54259
- if (modelTier !== "small") {
54260
- if (ctx.sessionHistory) {
54246
+ if (ctx.sessionHistory) {
54247
+ if (modelTier === "small") {
54248
+ const compactHistory = ctx.sessionHistory.split("\n").slice(0, 6).join("\n");
54249
+ sections.push(`## Session History
54250
+
54251
+ ${compactHistory}`);
54252
+ } else {
54261
54253
  sections.push(`## Session History
54262
54254
 
54263
54255
  ${ctx.sessionHistory}`);
54264
54256
  }
54265
- if (ctx.taskMemories) {
54266
- sections.push(`## Cross-Session Task Memory
54257
+ }
54258
+ if (modelTier !== "small" && ctx.taskMemories) {
54259
+ sections.push(`## Cross-Session Task Memory
54267
54260
 
54268
54261
  ${ctx.taskMemories}
54269
54262
 
54270
54263
  Use this history to avoid re-doing completed work and to learn from past approaches.`);
54271
- }
54272
54264
  }
54273
54265
  if (ctx.failurePatterns) {
54274
54266
  sections.push(`## Known Failure Patterns
@@ -70103,18 +70095,10 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
70103
70095
  p2pGateway = null;
70104
70096
  }
70105
70097
  const nexusTool = new NexusTool(repoRoot);
70106
- let exposeSpinnerMsg = passthrough ? `Connecting to nexus P2P network (passthrough \u2192 ${targetUrl})...` : "Connecting to nexus P2P network...";
70107
- const exposeFrames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
70108
- let exposeFrame = 0;
70109
- const exposeSpinner = setInterval(() => {
70110
- if (isNeovimActive()) {
70111
- writeToNeovimOutput(`${c2.cyan(exposeFrames[exposeFrame % exposeFrames.length])} ${c2.dim(exposeSpinnerMsg)}\r
70112
- `);
70113
- } else {
70114
- process.stdout.write(`\r ${c2.cyan(exposeFrames[exposeFrame % exposeFrames.length])} ${c2.dim(exposeSpinnerMsg)}`);
70115
- }
70116
- exposeFrame++;
70117
- }, 80);
70098
+ const exposeSpinnerMsg = passthrough ? `Connecting to nexus P2P network (passthrough \u2192 ${targetUrl})...` : "Connecting to nexus P2P network...";
70099
+ writeContent(() => {
70100
+ renderInfo(exposeSpinnerMsg);
70101
+ });
70118
70102
  const newP2P = new ExposeP2PGateway({
70119
70103
  kind,
70120
70104
  targetUrl,
@@ -70124,10 +70108,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
70124
70108
  loadbalance: loadbalance ?? false,
70125
70109
  endpointAuth: passthrough ? currentConfig.apiKey : void 0,
70126
70110
  onInfo: (msg) => {
70127
- exposeSpinnerMsg = msg;
70111
+ writeContent(() => {
70112
+ renderInfo(msg);
70113
+ });
70128
70114
  },
70129
70115
  onError: (msg) => {
70130
- exposeSpinnerMsg = msg;
70116
+ writeContent(() => {
70117
+ renderWarning(msg);
70118
+ });
70131
70119
  }
70132
70120
  }, nexusTool);
70133
70121
  newP2P.on("stats", (stats) => {
@@ -70141,18 +70129,12 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
70141
70129
  newP2P.on("token_flash", () => statusBar.flashExposeToken());
70142
70130
  try {
70143
70131
  const peerId = await newP2P.start();
70144
- clearInterval(exposeSpinner);
70145
- if (!isNeovimActive())
70146
- process.stdout.write(`\r\x1B[2K`);
70147
70132
  p2pGateway = newP2P;
70148
70133
  writeContent(() => {
70149
70134
  process.stdout.write("\n" + newP2P.formatConnectionInfo() + "\n\n");
70150
70135
  });
70151
70136
  return peerId;
70152
70137
  } catch (err) {
70153
- clearInterval(exposeSpinner);
70154
- if (!isNeovimActive())
70155
- process.stdout.write(`\r\x1B[2K`);
70156
70138
  if (!transport) {
70157
70139
  writeContent(() => {
70158
70140
  renderWarning(`libp2p expose failed: ${err instanceof Error ? err.message : String(err)}`);
@@ -71172,6 +71154,10 @@ Summarize or analyze this transcription as appropriate.`;
71172
71154
 
71173
71155
  NEW TASK: ${fullInput}`;
71174
71156
  restoredSessionContext = null;
71157
+ } else if (existsSync54(join71(repoRoot, ".oa", "context", "session-diary.md"))) {
71158
+ taskInput = `[Previous sessions exist \u2014 file_read(".oa/context/session-diary.md") to recall]
71159
+
71160
+ ${fullInput}`;
71175
71161
  }
71176
71162
  try {
71177
71163
  statusBar.setProcessing(true);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.185.57",
3
+ "version": "0.185.59",
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",
@@ -80,7 +80,7 @@ You are **Open Agent** (open-agents-ai), an autonomous AI coding agent running o
80
80
  - Code: read, write, edit, search, patch files across any language
81
81
  - Shell: run any command — tests, builds, git, npm, docker, etc.
82
82
  - Web: search documentation and fetch web pages
83
- - Memory: persistent cross-session knowledge (memory_read/memory_write)
83
+ - Memory: persistent cross-session knowledge (memory_read/memory_write). Your memories live in .oa/memory/ — use memory_read(topic) to recall, memory_write(topic, key, value) to save insights for future sessions. Session history: file_read(".oa/context/session-diary.md")
84
84
  - Skills: 250+ behavioral skills (skill_list), build new ones (skill_build)
85
85
  - P2P: nexus agent mesh — ALWAYS call nexus(action='connect') FIRST, then join_room/send_message/discover_peers/expose
86
86
  - Background tasks: run long commands in background, check status later
@@ -25,6 +25,7 @@ Rules:
25
25
  - Use list_directory for directories, NOT file_read. Prefer list_directory over shell ls.
26
26
  - You are **Open Agent** (open-agents-ai) — an AI coding agent running locally via Ollama/vLLM. No cloud APIs.
27
27
  - Core: code editing, shell commands, web search, memory, 250+ skills (skill_list), P2P mesh (nexus — call connect FIRST), background tasks.
28
+ - Memory: your persistent memories live in .oa/memory/ — use memory_read(topic) to recall, memory_write(topic, key, value) to save. Session history: file_read(".oa/context/session-diary.md")
28
29
  - When asked "what can you do?", use explore_tools() and skill_list() to discover and report your actual capabilities. Do NOT hallucinate.
29
30
 
30
31
  Debugging — OBSERVE before reasoning: