open-agents-ai 0.184.16 → 0.184.18

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 +167 -42
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -41798,6 +41798,23 @@ function tuiSelect(opts) {
41798
41798
  }
41799
41799
  } else if (seq === "\r" || seq === "\n") {
41800
41800
  if (!isSkippable(cursor) && matchSet.has(cursor)) {
41801
+ if (opts.onEnter) {
41802
+ const consumed = opts.onEnter(items[cursor], {
41803
+ done: () => render(),
41804
+ resolve: (result) => {
41805
+ cleanup();
41806
+ resolve35(result);
41807
+ },
41808
+ getInput: (prompt, prefill) => getInputFromUser(prompt, prefill),
41809
+ render: () => render(),
41810
+ updateItem: (index, updates) => {
41811
+ Object.assign(items[index], updates);
41812
+ render();
41813
+ }
41814
+ });
41815
+ if (consumed)
41816
+ return;
41817
+ }
41801
41818
  cleanup();
41802
41819
  resolve35({ confirmed: true, key: items[cursor].key, index: cursor });
41803
41820
  }
@@ -43172,6 +43189,20 @@ async function stepEndpoints(config, ollamaUrl, rl, availableRows, repoRoot) {
43172
43189
  }
43173
43190
  return false;
43174
43191
  },
43192
+ // Enter on toggle items → toggle (same as space). Only "next" exits.
43193
+ onEnter: (item, _helpers) => {
43194
+ if (item.isToggleable && item.endpoint) {
43195
+ item.endpoint.enabled = !item.endpoint.enabled;
43196
+ item.label = `${item.endpoint.enabled ? "[x]" : "[ ]"} ${item.endpoint.label}`;
43197
+ _helpers.render();
43198
+ return true;
43199
+ }
43200
+ if (item.key === "add_custom") {
43201
+ _helpers.render();
43202
+ return true;
43203
+ }
43204
+ return false;
43205
+ },
43175
43206
  renderRow: (item, focused, _isActive) => {
43176
43207
  const prefix = focused ? selectColors.orange("\u276F ") : " ";
43177
43208
  if (item.key === "hdr") {
@@ -43194,13 +43225,6 @@ async function stepEndpoints(config, ollamaUrl, rl, availableRows, repoRoot) {
43194
43225
  }
43195
43226
  return true;
43196
43227
  }
43197
- if (result.key && result.key !== "add_custom") {
43198
- const ep = config.endpoints.find((e) => e.url === result.key);
43199
- if (ep) {
43200
- ep.enabled = !ep.enabled;
43201
- return stepEndpoints(config, ollamaUrl, rl, availableRows, repoRoot);
43202
- }
43203
- }
43204
43228
  if (result.key === "add_custom") {
43205
43229
  renderInfo("Custom endpoint support coming soon. Use /endpoint to configure external APIs.");
43206
43230
  return stepEndpoints(config, ollamaUrl, rl, availableRows);
@@ -43324,9 +43348,51 @@ async function stepHeader(config, rl, availableRows) {
43324
43348
  }
43325
43349
  return false;
43326
43350
  },
43327
- // Use onCustomKey + helpers.getInput() for proper inline text capture
43328
- // (same pattern as TTS clone rename in voice list)
43329
- customKeyHint: " e edit space toggle",
43351
+ // Enter on toggle items → toggle. Enter on input items → open editor. Only "next" exits.
43352
+ onEnter: (item, helpers) => {
43353
+ if (item.key === "message_toggle") {
43354
+ config.header.messageEnabled = true;
43355
+ helpers.getInput("Header message:", config.header.message).then((text) => {
43356
+ if (text !== null && text.trim()) {
43357
+ config.header.message = text.trim().slice(0, 80);
43358
+ }
43359
+ helpers.updateItem(msgIdx, { label: `${config.header.messageEnabled ? "[x]" : "[ ]"} Header Message`, detail: msgDetail() });
43360
+ helpers.render();
43361
+ });
43362
+ return true;
43363
+ }
43364
+ if (item.key === "link_toggle") {
43365
+ config.header.linkEnabled = true;
43366
+ helpers.getInput("Link URL:", config.header.linkUrl).then((url) => {
43367
+ if (url !== null && url.trim()) {
43368
+ config.header.linkUrl = url.trim();
43369
+ helpers.getInput("Link text:", config.header.linkText).then((text) => {
43370
+ if (text !== null && text.trim())
43371
+ config.header.linkText = text.trim();
43372
+ helpers.updateItem(linkIdx, { label: `[x] Link`, detail: linkDetail() });
43373
+ helpers.render();
43374
+ });
43375
+ } else {
43376
+ helpers.render();
43377
+ }
43378
+ });
43379
+ return true;
43380
+ }
43381
+ if (item.key === "color_primary") {
43382
+ const ci = COLOR_PRESETS.findIndex((p) => p.code === (config.header.primaryColor || 214));
43383
+ const ni = (ci + 1) % COLOR_PRESETS.length;
43384
+ config.header.primaryColor = COLOR_PRESETS[ni].code;
43385
+ helpers.updateItem(colorPrimaryIdx, { label: ` Primary color: ${colorPreview(config.header.primaryColor)}`, detail: COLOR_PRESETS[ni].name });
43386
+ return true;
43387
+ }
43388
+ if (item.key === "color_gradient") {
43389
+ config.header.gradientEnabled = !config.header.gradientEnabled;
43390
+ helpers.updateItem(colorGradientIdx, { label: ` Gradient: ${config.header.gradientEnabled ? "[x] " + gradientPreview(config.header.gradientStart || 196, config.header.gradientEnd || 226) : "[ ] disabled"}` });
43391
+ return true;
43392
+ }
43393
+ return false;
43394
+ },
43395
+ customKeyHint: " e edit/cycle space toggle Enter edit/toggle",
43330
43396
  onCustomKey: (item, key, helpers) => {
43331
43397
  if ((key === "e" || key === "E") && item.key === "message_toggle") {
43332
43398
  config.header.messageEnabled = true;
@@ -43432,7 +43498,7 @@ async function stepTransport(config, rl, availableRows) {
43432
43498
  rl,
43433
43499
  skipKeys: ["hdr_transport", "hdr_limits", "sep"],
43434
43500
  availableRows,
43435
- customKeyHint: " e edit space toggle",
43501
+ customKeyHint: " e edit space/Enter toggle",
43436
43502
  onAction: (item, action) => {
43437
43503
  if (action === "space") {
43438
43504
  if (item.key === "cf_toggle") {
@@ -43448,6 +43514,55 @@ async function stepTransport(config, rl, availableRows) {
43448
43514
  }
43449
43515
  return false;
43450
43516
  },
43517
+ // Enter on toggle → toggle. Enter on rate limit → edit. Only "next" exits.
43518
+ onEnter: (item, helpers) => {
43519
+ if (item.key === "cf_toggle") {
43520
+ config.transport.cloudflared = !config.transport.cloudflared;
43521
+ item.label = `${config.transport.cloudflared ? "[x]" : "[ ]"} Cloudflared Tunnel (HTTPS)`;
43522
+ helpers.render();
43523
+ return true;
43524
+ }
43525
+ if (item.key === "p2p_toggle") {
43526
+ config.transport.libp2p = !config.transport.libp2p;
43527
+ item.label = `${config.transport.libp2p ? "[x]" : "[ ]"} libp2p P2P Mesh`;
43528
+ helpers.render();
43529
+ return true;
43530
+ }
43531
+ if (item.key === "rpm") {
43532
+ helpers.getInput("Max req/min:", String(config.rateLimits.maxRequestsPerMinute)).then((val) => {
43533
+ if (val !== null) {
43534
+ const n = parseInt(val, 10);
43535
+ if (!isNaN(n) && n > 0)
43536
+ config.rateLimits.maxRequestsPerMinute = n;
43537
+ }
43538
+ helpers.updateItem(rpmIdx, { label: ` Max requests/min: ${config.rateLimits.maxRequestsPerMinute}` });
43539
+ });
43540
+ return true;
43541
+ }
43542
+ if (item.key === "tpd") {
43543
+ helpers.getInput("Max tokens/day:", String(config.rateLimits.maxTokensPerDay)).then((val) => {
43544
+ if (val !== null) {
43545
+ const n = parseInt(val, 10);
43546
+ if (!isNaN(n) && n > 0)
43547
+ config.rateLimits.maxTokensPerDay = n;
43548
+ }
43549
+ helpers.updateItem(tpdIdx, { label: ` Max tokens/day: ${config.rateLimits.maxTokensPerDay.toLocaleString()}` });
43550
+ });
43551
+ return true;
43552
+ }
43553
+ if (item.key === "conc") {
43554
+ helpers.getInput("Max concurrent:", String(config.rateLimits.maxConcurrent)).then((val) => {
43555
+ if (val !== null) {
43556
+ const n = parseInt(val, 10);
43557
+ if (!isNaN(n) && n > 0)
43558
+ config.rateLimits.maxConcurrent = n;
43559
+ }
43560
+ helpers.updateItem(concIdx, { label: ` Max concurrent: ${config.rateLimits.maxConcurrent}` });
43561
+ });
43562
+ return true;
43563
+ }
43564
+ return false;
43565
+ },
43451
43566
  onCustomKey: (item, key, helpers) => {
43452
43567
  if ((key === "e" || key === "E") && item.key === "rpm") {
43453
43568
  helpers.getInput("Max req/min:", String(config.rateLimits.maxRequestsPerMinute)).then((val) => {
@@ -47904,45 +48019,56 @@ async function handleSlashCommand(input, ctx) {
47904
48019
  ollamaUrl: "http://localhost:11434",
47905
48020
  availableRows: ctx.availableContentRows?.(),
47906
48021
  onGoLive: async (config) => {
47907
- if (config.transport.libp2p) {
47908
- try {
47909
- const nexus = new NexusTool(projectDir);
47910
- renderInfo("Connecting to nexus P2P mesh...");
47911
- await nexus.execute({ action: "connect" });
47912
- await new Promise((r) => setTimeout(r, 3e3));
47913
- renderInfo("Nexus daemon connected.");
47914
- } catch (err) {
47915
- renderWarning(`Nexus auto-connect: ${err instanceof Error ? err.message : String(err)}`);
47916
- }
47917
- }
48022
+ const existingGateway = ctx.getExposeGateway?.();
48023
+ const tunnelAlreadyActive = existingGateway?.isActive && existingGateway?.tunnelUrl;
48024
+ const p2pAlreadyActive = ctx.isExposeActive?.() && !existingGateway?.tunnelUrl;
47918
48025
  if (config.transport.cloudflared && ctx.exposeStart) {
47919
- try {
47920
- const url = await ctx.exposeStart("ollama", void 0, "tunnel");
47921
- if (url) {
47922
- renderInfo(`Tunnel: ${url}`);
47923
- const gateway = ctx.getExposeGateway?.();
47924
- if (gateway && "setSponsorLimits" in gateway) {
47925
- gateway.setSponsorLimits(config.rateLimits);
47926
- renderInfo(`Rate limits active: ${config.rateLimits.maxRequestsPerMinute} req/min, ${config.rateLimits.maxTokensPerDay.toLocaleString()} tokens/day`);
48026
+ if (tunnelAlreadyActive) {
48027
+ renderInfo(`Tunnel already active: ${existingGateway.tunnelUrl}`);
48028
+ if ("setSponsorLimits" in existingGateway) {
48029
+ existingGateway.setSponsorLimits(config.rateLimits);
48030
+ }
48031
+ renderInfo(`Rate limits updated: ${config.rateLimits.maxRequestsPerMinute} req/min, ${config.rateLimits.maxTokensPerDay.toLocaleString()} tokens/day`);
48032
+ } else {
48033
+ try {
48034
+ const url = await ctx.exposeStart("ollama", void 0, "tunnel");
48035
+ if (url) {
48036
+ renderInfo(`Tunnel: ${url}`);
48037
+ const gw = ctx.getExposeGateway?.();
48038
+ if (gw && "setSponsorLimits" in gw) {
48039
+ gw.setSponsorLimits(config.rateLimits);
48040
+ renderInfo(`Rate limits active: ${config.rateLimits.maxRequestsPerMinute} req/min, ${config.rateLimits.maxTokensPerDay.toLocaleString()} tokens/day`);
48041
+ }
47927
48042
  }
48043
+ } catch (err) {
48044
+ renderError(`Tunnel start failed: ${err instanceof Error ? err.message : String(err)}`);
47928
48045
  }
47929
- } catch (err) {
47930
- renderError(`Tunnel start failed: ${err instanceof Error ? err.message : String(err)}`);
47931
48046
  }
47932
48047
  }
47933
48048
  if (config.transport.libp2p && ctx.exposeStart) {
47934
48049
  try {
47935
- const url = await ctx.exposeStart("ollama", void 0, "libp2p");
47936
- if (url) {
47937
- renderInfo(`P2P: ${url}`);
47938
- const gateway = ctx.getExposeGateway?.();
47939
- if (gateway && "setSponsorLimits" in gateway) {
47940
- gateway.setSponsorLimits(config.rateLimits);
47941
- }
47942
- }
48050
+ const nexus = new NexusTool(projectDir);
48051
+ renderInfo("Ensuring nexus daemon is connected...");
48052
+ await nexus.execute({ action: "connect" });
48053
+ await new Promise((r) => setTimeout(r, 2e3));
47943
48054
  } catch (err) {
47944
- renderError(`P2P start failed: ${err instanceof Error ? err.message : String(err)}`);
48055
+ renderWarning(`Nexus: ${err instanceof Error ? err.message : String(err)}`);
47945
48056
  }
48057
+ if (!p2pAlreadyActive) {
48058
+ try {
48059
+ const url = await ctx.exposeStart("ollama", void 0, "libp2p");
48060
+ if (url)
48061
+ renderInfo(`P2P: ${url}`);
48062
+ } catch (err) {
48063
+ renderError(`P2P start failed: ${err instanceof Error ? err.message : String(err)}`);
48064
+ }
48065
+ } else {
48066
+ renderInfo("P2P gateway already active.");
48067
+ }
48068
+ }
48069
+ const activeGw = ctx.getExposeGateway?.();
48070
+ if (activeGw && "setSponsorLimits" in activeGw) {
48071
+ activeGw.setSponsorLimits(config.rateLimits);
47946
48072
  }
47947
48073
  try {
47948
48074
  const nexus = new NexusTool(projectDir);
@@ -47950,7 +48076,6 @@ async function handleSlashCommand(input, ctx) {
47950
48076
  await nexus.execute({ action: "connect" });
47951
48077
  } catch {
47952
48078
  }
47953
- await new Promise((r) => setTimeout(r, 2e3));
47954
48079
  const tunnelGw = ctx.getExposeGateway?.();
47955
48080
  const enabledEps = config.endpoints.filter((e) => e.enabled);
47956
48081
  const allModels = enabledEps.flatMap((e) => e.models || []);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.184.16",
3
+ "version": "0.184.18",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) \u2014 interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",