viber-channel 0.8.39 → 0.8.41

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.
@@ -119,6 +119,7 @@ import {
119
119
  import { startInstanceHeartbeat } from "./lib/heartbeat.ts";
120
120
  import { type PresenceGate, REASON_NO_RUNNER as REASON_STARTING, startCoverageWatch } from "./lib/coverage_watch.ts";
121
121
  import { startPresenceRecord } from "./lib/presence_record.ts";
122
+ import { CodexRuntimeWriter, runtimeFilePath } from "./lib/codex_runtime.ts";
122
123
  import { startBridgeToolHost, type BridgeToolHost } from "./lib/bridge_tool_host.ts";
123
124
  import type { AgentToolsContext } from "./lib/agent_tools.ts";
124
125
  import type { OpenDmResult } from "./lib/peers.ts";
@@ -693,6 +694,14 @@ export class CodexAppServer {
693
694
  /** Set true once we intentionally `close()` so the exit handler can tell a
694
695
  * deliberate shutdown from an unexpected child death (#298). */
695
696
  private closing = false;
697
+ /** #708: model, effort and context left for the runner. Unset = not recorded. */
698
+ private runtime?: CodexRuntimeWriter;
699
+ /** #708: threads this bridge opened — a usage for any other thread is not this agent's. */
700
+ private readonly ownThreads = new Set<string>();
701
+
702
+ setRuntime(writer: CodexRuntimeWriter): void {
703
+ this.runtime = writer;
704
+ }
696
705
 
697
706
  /**
698
707
  * @param onUnexpectedExit fired ONLY when the Codex child dies on its own (not
@@ -840,6 +849,8 @@ export class CodexAppServer {
840
849
  // leaves this try (it must not fall back to a fresh thread and hide the problem).
841
850
  resumeMismatch = pairMismatch(this.pair, resumed, "thread/resume");
842
851
  if (resumeMismatch === undefined) {
852
+ this.ownThreads.add(resumedId);
853
+ this.runtime?.onThread(resumed);
843
854
  logTiming("ensureThread", nowMs() - t0, "outcome=resume");
844
855
  return resumedId;
845
856
  }
@@ -873,6 +884,8 @@ export class CodexAppServer {
873
884
  // #665: same check on a fresh thread — what codex SAYS it runs, not what we asked.
874
885
  const startMismatch = pairMismatch(this.pair, started, "thread/start");
875
886
  if (startMismatch !== undefined) this.stopOnPairMismatch(startMismatch);
887
+ this.ownThreads.add(threadId);
888
+ this.runtime?.onThread(started);
876
889
  state.threads[key] = {
877
890
  thread_id: threadId,
878
891
  conversation_id: options.conversationId,
@@ -998,6 +1011,12 @@ export class CodexAppServer {
998
1011
  return;
999
1012
  }
1000
1013
 
1014
+ if (msg.method === "thread/tokenUsage/updated") {
1015
+ const threadId = (msg.params as { threadId?: unknown } | undefined)?.threadId;
1016
+ if (typeof threadId === "string" && this.ownThreads.has(threadId)) this.runtime?.onTokenUsage(msg.params);
1017
+ return;
1018
+ }
1019
+
1001
1020
  if (msg.method === "turn/completed") {
1002
1021
  const params = msg.params as { threadId?: string; turn?: { id?: string; status?: unknown; error?: unknown } };
1003
1022
  const turnId = params.turn?.id;
@@ -1444,6 +1463,8 @@ function setupCodexRuntime(deps: {
1444
1463
  pauseReason: () => string | null;
1445
1464
  /** #665: the template's model/effort, or undefined. */
1446
1465
  pair: CodexPair | undefined;
1466
+ /** #708: this instance's id — the runtime file the runner reads is keyed on it. */
1467
+ instanceKey: string;
1447
1468
  }): { codex: CodexAppServer; toolHost: BridgeToolHost } {
1448
1469
  const { tracker } = deps;
1449
1470
  const bridgeToolsCtx: AgentToolsContext = {
@@ -1481,6 +1502,12 @@ function setupCodexRuntime(deps: {
1481
1502
  { url: toolHost.url, bearerEnvVar: "VIBER_MCP_TOKEN", bearerValue: toolHost.bearerToken },
1482
1503
  deps.pair,
1483
1504
  );
1505
+ try {
1506
+ codex.setRuntime(new CodexRuntimeWriter(runtimeFilePath(IDENTITY_URL, deps.instanceKey, LOCK_DIR()), deps.instanceKey));
1507
+ } catch (err) {
1508
+ process.stderr.write(`${LOG_PREFIX} runtime info disabled: ${safeErrorMessage(err)}
1509
+ `);
1510
+ }
1484
1511
  return { codex, toolHost };
1485
1512
  }
1486
1513
 
@@ -1606,6 +1633,7 @@ export async function main(argv: string[] = process.argv.slice(2)): Promise<void
1606
1633
  requestShutdown: helpers.requestShutdown,
1607
1634
  pauseReason: helpers.pauseReason,
1608
1635
  pair,
1636
+ instanceKey: identity.instanceKey,
1609
1637
  });
1610
1638
  codex = rt.codex;
1611
1639
  toolHost = rt.toolHost;
@@ -1674,6 +1702,7 @@ export async function main(argv: string[] = process.argv.slice(2)): Promise<void
1674
1702
  },
1675
1703
  pauseReason: () => gateRef.gate?.reason() ?? REASON_STARTING,
1676
1704
  pair,
1705
+ instanceKey: res.instanceKey,
1677
1706
  });
1678
1707
  codex = rt.codex;
1679
1708
  toolHost = rt.toolHost;