talon-agent 3.23.0 → 3.23.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "talon-agent",
3
- "version": "3.23.0",
3
+ "version": "3.23.1",
4
4
  "description": "Multi-frontend AI agent with full tool access, streaming, cron jobs, and plugin system",
5
5
  "author": "Dylan Neve",
6
6
  "license": "MIT",
@@ -90,7 +90,14 @@ interface CodexCacheFile {
90
90
 
91
91
  /** Where the Codex CLI writes its model cache. Exported for tests. */
92
92
  export function getCodexCachePath(): string {
93
- return join(homedir(), ".codex", "models_cache.json");
93
+ // Honor CODEX_HOME like token-usage.ts and plan-usage.ts do — the CLI
94
+ // itself relocates with it, so a pinned deployment would otherwise
95
+ // read a cache the CLI never writes. (Also what lets tests fake the
96
+ // path under bun, whose os.homedir() ignores $HOME.)
97
+ const home = process.env.CODEX_HOME?.trim();
98
+ return home && home.length > 0
99
+ ? join(home, "models_cache.json")
100
+ : join(homedir(), ".codex", "models_cache.json");
94
101
  }
95
102
 
96
103
  /** Default soft timeout when callers await an in-flight discovery. */
@@ -596,16 +596,28 @@ export class Gateway {
596
596
  resolve();
597
597
  return;
598
598
  }
599
- this.server.close(() => {
599
+ const server = this.server;
600
+ const settle = (): void => {
600
601
  this.server = null;
601
602
  this.port = 0;
602
603
  resolve();
604
+ };
605
+ // Bun's closeAllConnections() (≤1.3.x) doesn't sever live SSE
606
+ // streams, so close()'s callback can never fire there and stop()
607
+ // would hang shutdown (and every test teardown). Resolve on a
608
+ // deadline either way: by then no new connections are accepted,
609
+ // and the process this runs in is exiting anyway.
610
+ const deadline = setTimeout(settle, 2_000);
611
+ deadline.unref?.();
612
+ server.close(() => {
613
+ clearTimeout(deadline);
614
+ settle();
603
615
  });
604
616
  // `close()` only stops NEW connections; MCP hub sessions hold
605
617
  // long-lived SSE streams that would keep the close callback from
606
618
  // ever firing. Terminate them — everything on this server is
607
619
  // localhost request/response or SSE, safe to drop at stop time.
608
- this.server.closeAllConnections();
620
+ server.closeAllConnections();
609
621
  });
610
622
  }
611
623
  }
@@ -6,6 +6,7 @@
6
6
  */
7
7
 
8
8
  import { Agent, fetch as undiciFetch } from "undici";
9
+ import { isBunRuntime } from "../../util/runtime.js";
9
10
  import type { BridgeFunction } from "./types.js";
10
11
 
11
12
  /** Default wall-clock budget for a bridge action. */
@@ -95,8 +96,13 @@ export function createBridge(
95
96
  json(): Promise<unknown>;
96
97
  };
97
98
  try {
99
+ // Bun has no 300s header watchdog and aliases the npm undici
100
+ // module to its own internals (so the Agent knobs do nothing
101
+ // there anyway) — its global fetch serves long-haul calls fine,
102
+ // governed by the AbortSignal alone. The undici detour is a
103
+ // Node-only workaround.
98
104
  resp =
99
- timeoutMs > BUILTIN_FETCH_HEADERS_CEILING_MS
105
+ timeoutMs > BUILTIN_FETCH_HEADERS_CEILING_MS && !isBunRuntime()
100
106
  ? await undiciFetch(`${bridgeUrl}/action`, {
101
107
  ...init,
102
108
  dispatcher: dispatcher(),