open-agents-ai 0.101.4 → 0.101.6

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
@@ -5952,35 +5952,35 @@ function discoverSkills(repoRoot) {
5952
5952
  if (pkgRoot) {
5953
5953
  const pkgFrameworks = join14(pkgRoot, "agentic", "code", "frameworks");
5954
5954
  if (existsSync11(pkgFrameworks)) {
5955
- for (const fw of safeReaddir(pkgFrameworks)) {
5955
+ for (const fw of safeReaddir(pkgFrameworks, true)) {
5956
5956
  loadComponent(join14(pkgFrameworks, fw), `framework:${fw}`);
5957
5957
  }
5958
5958
  }
5959
5959
  const pkgAddons = join14(pkgRoot, "agentic", "code", "addons");
5960
5960
  if (existsSync11(pkgAddons)) {
5961
- for (const addon of safeReaddir(pkgAddons)) {
5961
+ for (const addon of safeReaddir(pkgAddons, true)) {
5962
5962
  loadComponent(join14(pkgAddons, addon), `addon:${addon}`);
5963
5963
  }
5964
5964
  }
5965
5965
  const pkgPlugins = join14(pkgRoot, "plugins");
5966
5966
  if (existsSync11(pkgPlugins)) {
5967
- for (const plugin of safeReaddir(pkgPlugins)) {
5967
+ for (const plugin of safeReaddir(pkgPlugins, true)) {
5968
5968
  loadComponent(join14(pkgPlugins, plugin), `plugin:${plugin}`);
5969
5969
  }
5970
5970
  }
5971
5971
  }
5972
5972
  if (existsSync11(frameworksDir)) {
5973
- for (const framework of safeReaddir(frameworksDir)) {
5973
+ for (const framework of safeReaddir(frameworksDir, true)) {
5974
5974
  loadComponent(join14(frameworksDir, framework), `framework:${framework}`);
5975
5975
  }
5976
5976
  }
5977
5977
  if (existsSync11(addonsDir)) {
5978
- for (const addon of safeReaddir(addonsDir)) {
5978
+ for (const addon of safeReaddir(addonsDir, true)) {
5979
5979
  loadComponent(join14(addonsDir, addon), `addon:${addon}`);
5980
5980
  }
5981
5981
  }
5982
5982
  if (existsSync11(pluginsDir)) {
5983
- for (const plugin of safeReaddir(pluginsDir)) {
5983
+ for (const plugin of safeReaddir(pluginsDir, true)) {
5984
5984
  loadComponent(join14(pluginsDir, plugin), `plugin:${plugin}`);
5985
5985
  }
5986
5986
  }
@@ -6025,9 +6025,10 @@ function buildSkillsSummary(skills) {
6025
6025
  lines.push("Use `skill_execute` with a skill name to load its full instructions when a task matches a trigger pattern.");
6026
6026
  return lines.join("\n");
6027
6027
  }
6028
- function safeReaddir(dir) {
6028
+ function safeReaddir(dir, dirsOnly = false) {
6029
6029
  try {
6030
- return readdirSync5(dir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
6030
+ const entries = readdirSync5(dir, { withFileTypes: true });
6031
+ return dirsOnly ? entries.filter((d) => d.isDirectory()).map((d) => d.name) : entries.map((d) => d.name);
6031
6032
  } catch {
6032
6033
  return [];
6033
6034
  }
@@ -6039,18 +6040,34 @@ function loadSkillsFromDir(dir, source, out) {
6039
6040
  const entries = safeReaddir(dir);
6040
6041
  for (const entry of entries) {
6041
6042
  const skillMd = join14(dir, entry, "SKILL.md");
6042
- if (!existsSync11(skillMd))
6043
+ if (existsSync11(skillMd)) {
6044
+ const manifestEntry = manifest.get(entry);
6045
+ const info = {
6046
+ name: entry,
6047
+ description: manifestEntry?.description ?? parseDescription(skillMd),
6048
+ triggers: manifestEntry?.triggers ?? parseTriggers(skillMd),
6049
+ source,
6050
+ filePath: skillMd,
6051
+ compactionStrategy: parseCompactionStrategy(skillMd)
6052
+ };
6053
+ out.set(entry, info);
6043
6054
  continue;
6044
- const manifestEntry = manifest.get(entry);
6045
- const info = {
6046
- name: entry,
6047
- description: manifestEntry?.description ?? parseDescription(skillMd),
6048
- triggers: manifestEntry?.triggers ?? parseTriggers(skillMd),
6049
- source,
6050
- filePath: skillMd,
6051
- compactionStrategy: parseCompactionStrategy(skillMd)
6052
- };
6053
- out.set(entry, info);
6055
+ }
6056
+ if (entry.endsWith(".md") && entry !== "manifest.json") {
6057
+ const flatPath = join14(dir, entry);
6058
+ const name = entry.replace(/\.md$/, "");
6059
+ if (out.has(name))
6060
+ continue;
6061
+ const info = {
6062
+ name,
6063
+ description: parseDescription(flatPath),
6064
+ triggers: parseTriggers(flatPath),
6065
+ source,
6066
+ filePath: flatPath,
6067
+ compactionStrategy: parseCompactionStrategy(flatPath)
6068
+ };
6069
+ out.set(name, info);
6070
+ }
6054
6071
  }
6055
6072
  }
6056
6073
  function loadCommandsFromDir(dir, source, out) {
@@ -6205,7 +6222,8 @@ var init_skill_tools = __esm({
6205
6222
  }
6206
6223
  async execute(args) {
6207
6224
  const start = performance.now();
6208
- const filter = typeof args["filter"] === "string" ? args["filter"].toLowerCase() : "";
6225
+ const filterRaw = args["filter"] ?? args["pattern"] ?? args["query"] ?? args["search"] ?? "";
6226
+ const filter = typeof filterRaw === "string" ? filterRaw.toLowerCase() : "";
6209
6227
  const sourceFilter = typeof args["source"] === "string" ? args["source"] : "";
6210
6228
  let skills = discoverSkills(this.repoRoot);
6211
6229
  if (filter) {
@@ -6258,7 +6276,7 @@ var init_skill_tools = __esm({
6258
6276
  }
6259
6277
  async execute(args) {
6260
6278
  const start = performance.now();
6261
- const name = String(args["name"] ?? args["skill_name"] ?? args["skillName"] ?? "").trim();
6279
+ const name = String(args["name"] ?? args["skill_name"] ?? args["skillName"] ?? args["skill"] ?? "").trim();
6262
6280
  if (!name) {
6263
6281
  return {
6264
6282
  success: false,
@@ -17625,10 +17643,19 @@ Take a DIFFERENT action now.`
17625
17643
  });
17626
17644
  break;
17627
17645
  }
17628
- messages.push({
17629
- role: "user",
17630
- content: "Continue working. Use tools to read files, make changes, and run validation. Call task_complete when done."
17631
- });
17646
+ const narratedToolPattern = /(?:```(?:bash|json)?\s*\n?)?\b(file_read|file_write|file_edit|shell|skill_execute|skill_list|skill_build|grep_search|find_files|web_search|web_fetch|task_complete|memory_read|memory_write)\b[(\s]/;
17647
+ const narratedMatch = content.match(narratedToolPattern);
17648
+ if (narratedMatch) {
17649
+ messages.push({
17650
+ role: "user",
17651
+ content: `You wrote "${narratedMatch[1]}" as text but did NOT actually call the tool. Do NOT write tool names as text or code blocks. Instead, invoke the tool directly through the function calling interface. Try again \u2014 call ${narratedMatch[1]}() as an actual tool call.`
17652
+ });
17653
+ } else {
17654
+ messages.push({
17655
+ role: "user",
17656
+ content: "Continue working. Use tools to read files, make changes, and run validation. Call task_complete when done."
17657
+ });
17658
+ }
17632
17659
  }
17633
17660
  }
17634
17661
  let prevCycleToolCalls = toolCallCount;
@@ -39818,6 +39845,8 @@ var init_status_bar = __esm({
39818
39845
  active = false;
39819
39846
  scrollRegionTop = 1;
39820
39847
  stdinHooked = false;
39848
+ /** Track previous terminal rows to clear ghost separators on resize */
39849
+ _prevTermRows = 0;
39821
39850
  /**
39822
39851
  * Depth-counted content write guard. Incremented by beginContentWrite(),
39823
39852
  * decremented by endContentWrite(). Footer is only redrawn and cursor
@@ -40099,6 +40128,7 @@ var init_status_bar = __esm({
40099
40128
  activate(scrollRegionTop) {
40100
40129
  this.scrollRegionTop = scrollRegionTop ?? 1;
40101
40130
  this.active = true;
40131
+ this._prevTermRows = process.stdout.rows ?? 24;
40102
40132
  this.applyScrollRegion();
40103
40133
  this.renderFooterAndPositionInput();
40104
40134
  this.hookStdin();
@@ -40142,12 +40172,18 @@ var init_status_bar = __esm({
40142
40172
  return;
40143
40173
  this.updateFooterHeight();
40144
40174
  const rows = process.stdout.rows ?? 24;
40175
+ const prevRows = this._prevTermRows;
40176
+ this._prevTermRows = rows;
40145
40177
  const pos = this.rowPositions(rows);
40146
40178
  const w = getTermWidth();
40147
40179
  const sep = c2.dim("\u2500".repeat(w));
40180
+ let clearGhosts = "";
40181
+ if (prevRows > 0 && rows < prevRows) {
40182
+ clearGhosts = "\x1B[1;" + rows + `r\x1B[${pos.bufferRow};1H\x1B[J`;
40183
+ }
40148
40184
  if (this.writeDepth > 0) {
40149
40185
  const inputWrap = this.wrapInput(w);
40150
- let buf = `\x1B[${this.scrollRegionTop};${pos.scrollEnd}r\x1B[?25l\x1B[?7l\x1B[${pos.bufferRow};1H\x1B[2K${this.buildBufferContent(w)}\x1B[${pos.topSepRow};1H\x1B[2K${sep}`;
40186
+ let buf = clearGhosts + `\x1B[${this.scrollRegionTop};${pos.scrollEnd}r\x1B[?25l\x1B[?7l\x1B[${pos.bufferRow};1H\x1B[2K${this.buildBufferContent(w)}\x1B[${pos.topSepRow};1H\x1B[2K${sep}`;
40151
40187
  for (let i = 0; i < inputWrap.lines.length; i++) {
40152
40188
  const row = pos.inputStartRow + i;
40153
40189
  const prefix = i === 0 ? this.promptText : " ".repeat(this.promptWidth);
@@ -40156,6 +40192,8 @@ var init_status_bar = __esm({
40156
40192
  buf += `\x1B[${pos.bottomSepRow};1H\x1B[2K${sep}\x1B[${pos.metricsRow};1H\x1B[2K${this.buildMetricsLine()}\x1B[?7h\x1B[${pos.scrollEnd};1H`;
40157
40193
  process.stdout.write(buf);
40158
40194
  } else {
40195
+ if (clearGhosts)
40196
+ process.stdout.write(clearGhosts);
40159
40197
  this.applyScrollRegion();
40160
40198
  this.renderFooterAndPositionInput();
40161
40199
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.101.4",
3
+ "version": "0.101.6",
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",
@@ -154,6 +154,7 @@ You are **Open Agent** (open-agents-ai), an autonomous AI coding agent running o
154
154
  - Skills: 250+ behavioral skills (skill_list), build new ones (skill_build)
155
155
  - P2P: connect to other agents via nexus (libp2p + NATS mesh)
156
156
  - Background tasks: run long commands in background, check status later
157
+ - Voice/TTS: text-to-speech via ONNX (cross-platform) or MLX (Apple Silicon) — use /voice to enable
157
158
  - Desktop/Vision: screenshot, click UI, OCR (via explore_tools)
158
159
  - Scheduling: cron jobs, reminders, agenda (via explore_tools)
159
160
  - Custom tools: create reusable tools from repeated workflows
@@ -69,6 +69,7 @@ You are **Open Agent** (open-agents-ai), an autonomous AI coding agent running o
69
69
  - Skills: 250+ behavioral skills (skill_list), build new ones (skill_build)
70
70
  - P2P: connect to other agents via nexus (libp2p + NATS mesh)
71
71
  - Background tasks: run long commands in background, check status later
72
+ - Voice/TTS: text-to-speech via ONNX (cross-platform) or MLX (Apple Silicon) — use /voice to enable
72
73
  - Desktop/Vision: screenshot, click UI, OCR (via explore_tools)
73
74
  - Scheduling: cron jobs, reminders, agenda (via explore_tools)
74
75
  - Custom tools: create reusable tools from repeated workflows