negotium 0.2.14 → 0.2.16

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 (34) hide show
  1. package/dist/agent-helpers.js +178 -26
  2. package/dist/agent-helpers.js.map +8 -8
  3. package/dist/{chunk-5g5a63vv.js → chunk-5cpdbbeh.js} +56 -6
  4. package/dist/{chunk-5g5a63vv.js.map → chunk-5cpdbbeh.js.map} +4 -4
  5. package/dist/hosted-agent.js +118 -9
  6. package/dist/hosted-agent.js.map +6 -6
  7. package/dist/main.js +389 -50
  8. package/dist/main.js.map +15 -15
  9. package/dist/mcp-factories.js +247 -36
  10. package/dist/mcp-factories.js.map +9 -9
  11. package/dist/registry.js +3 -3
  12. package/dist/registry.js.map +2 -2
  13. package/dist/rollout.js +1 -1
  14. package/dist/runtime/src/agents/codex-provider.ts +53 -2
  15. package/dist/runtime/src/agents/rollout/codex.ts +62 -0
  16. package/dist/runtime/src/mcp/factories/token-stats.ts +33 -11
  17. package/dist/runtime/src/mcp/runtime-spec.ts +58 -1
  18. package/dist/runtime/src/node-host.ts +1 -0
  19. package/dist/runtime/src/runtime/public-helpers.ts +8 -0
  20. package/dist/runtime/src/runtime/turn-event-stream.ts +17 -2
  21. package/dist/runtime/src/storage/token-stats.ts +200 -19
  22. package/dist/runtime/src/version.ts +1 -1
  23. package/dist/runtime-helpers.js +443 -30
  24. package/dist/runtime-helpers.js.map +9 -3
  25. package/dist/storage.js +112 -11
  26. package/dist/storage.js.map +3 -3
  27. package/dist/types/packages/core/src/agents/codex-provider.d.ts +13 -0
  28. package/dist/types/packages/core/src/agents/rollout/codex.d.ts +9 -0
  29. package/dist/types/packages/core/src/mcp/factories/token-stats.d.ts +4 -2
  30. package/dist/types/packages/core/src/runtime/bashrs-completions.d.ts +50 -0
  31. package/dist/types/packages/core/src/runtime/public-helpers.d.ts +2 -0
  32. package/dist/types/packages/core/src/storage/token-stats.d.ts +35 -6
  33. package/dist/types/packages/core/src/version.d.ts +1 -1
  34. package/package.json +1 -1
@@ -531,7 +531,7 @@ var referencesRuntimeSecretStorage = defaultVaultToolPolicy.referencesRuntimeSec
531
531
  var shouldRedirectVaultTool = defaultVaultToolPolicy.shouldRedirectVaultTool;
532
532
 
533
533
  // ../../packages/core/src/mcp/runtime-spec.ts
534
- import { createHmac, timingSafeEqual } from "crypto";
534
+ import { createHash, createHmac, timingSafeEqual } from "crypto";
535
535
  var RUNTIME_MCP_KEY = "runtime";
536
536
  var RUNTIME_MCP_BASE_PATH = "/mcp/runtime";
537
537
  var TOKEN_TTL_MS = 4 * 60 * 60 * 1000;
@@ -569,19 +569,69 @@ function buildRuntimeMcpSpec(agent, ctx) {
569
569
  return {
570
570
  type: "sse",
571
571
  url: `${base}/sse?${query}`,
572
- timeout: CLAUDE_MCP_TOOL_TIMEOUT_MS
572
+ timeout: CLAUDE_MCP_TOOL_TIMEOUT_MS,
573
+ ...agent === "maestro" ? { lifecycle: "turn" } : {}
573
574
  };
574
575
  }
576
+ function hostedMcpCacheIdentity(surface, ctx) {
577
+ let semanticContext;
578
+ switch (surface) {
579
+ case "system-health":
580
+ semanticContext = {};
581
+ break;
582
+ case "token-stats":
583
+ case "agent-health":
584
+ semanticContext = { userId: ctx.userId };
585
+ break;
586
+ case "task":
587
+ semanticContext = {
588
+ userId: ctx.userId,
589
+ topicTitle: ctx.topicTitle,
590
+ topicId: ctx.topicId ?? null
591
+ };
592
+ break;
593
+ case "wiki":
594
+ case "skills":
595
+ semanticContext = {
596
+ userId: ctx.userId,
597
+ topicId: ctx.wikiTopicId ?? ctx.topicId ?? null
598
+ };
599
+ break;
600
+ case "vault":
601
+ semanticContext = { userId: ctx.userId, cwd: ctx.cwd, agent: ctx.agent };
602
+ break;
603
+ case "session-comm":
604
+ semanticContext = {
605
+ userId: ctx.userId,
606
+ topicTitle: ctx.topicTitle,
607
+ topicId: ctx.topicId ?? null,
608
+ subagentParentTopicId: ctx.subagentParentTopicId ?? null,
609
+ depth: ctx.depth ?? 0,
610
+ silent: ctx.silent ?? false,
611
+ agent: ctx.agent,
612
+ peerBridge: ctx.peerBridge ?? null
613
+ };
614
+ break;
615
+ }
616
+ const digest = createHash("sha256").update(JSON.stringify([surface, semanticContext])).digest("hex").slice(0, 24);
617
+ return `hosted:${surface}:${digest}`;
618
+ }
575
619
  function buildHostedMcpSpec(agent, surface, ctx) {
576
620
  const token = issueHostedMcpToken(surface, ctx);
577
621
  const base = `http://127.0.0.1:${runtimePort}${RUNTIME_MCP_BASE_PATH}/${surface}`;
578
622
  const query = `token=${encodeURIComponent(token)}`;
579
623
  if (agent === "codex")
580
624
  return { url: `${base}/mcp?${query}` };
625
+ const queryBound = surface === "session-comm" && (ctx.silent === true || ctx.peerBridge !== undefined);
626
+ const lifecycle = queryBound ? "turn" : surface === "session-comm" ? "session" : "process";
581
627
  return {
582
628
  type: "sse",
583
629
  url: `${base}/sse?${query}`,
584
- timeout: CLAUDE_MCP_TOOL_TIMEOUT_MS
630
+ timeout: CLAUDE_MCP_TOOL_TIMEOUT_MS,
631
+ ...agent === "maestro" ? {
632
+ lifecycle,
633
+ cacheKey: hostedMcpCacheIdentity(surface, ctx)
634
+ } : {}
585
635
  };
586
636
  }
587
637
 
@@ -1398,12 +1448,12 @@ if (isBun) {
1398
1448
  }
1399
1449
 
1400
1450
  // ../../packages/core/src/storage/vault-crypto-core.ts
1401
- import { createCipheriv, createDecipheriv, createHash, randomBytes as randomBytes3 } from "crypto";
1451
+ import { createCipheriv, createDecipheriv, createHash as createHash2, randomBytes as randomBytes3 } from "crypto";
1402
1452
  var ENVELOPE_PREFIX = "otium-vault:v1:";
1403
1453
  var IV_BYTES = 12;
1404
1454
  var KEY_BYTES = 32;
1405
1455
  function encryptionKey(masterKey) {
1406
- return createHash("sha256").update("otium-vault-value-v1\x00", "utf8").update(masterKey, "utf8").digest().subarray(0, KEY_BYTES);
1456
+ return createHash2("sha256").update("otium-vault-value-v1\x00", "utf8").update(masterKey, "utf8").digest().subarray(0, KEY_BYTES);
1407
1457
  }
1408
1458
  function aad(userId, key) {
1409
1459
  return Buffer.from(`${userId}\x00${key.toUpperCase()}`, "utf8");
@@ -2185,7 +2235,7 @@ import { tmpdir } from "os";
2185
2235
  import { dirname as dirname4, join as join3 } from "path";
2186
2236
 
2187
2237
  // ../../packages/core/src/version.ts
2188
- var NEGOTIUM_VERSION = "0.2.14";
2238
+ var NEGOTIUM_VERSION = "0.2.16";
2189
2239
 
2190
2240
  // ../../packages/core/src/agents/codex-native-multi-agent.ts
2191
2241
  var moduleRequire = createRequire2(import.meta.url);
@@ -2769,6 +2819,36 @@ function extractLatestCodexContextUsage(jsonl) {
2769
2819
  }
2770
2820
  return;
2771
2821
  }
2822
+ function extractLatestCodexTokenTotals(jsonl) {
2823
+ const lines = jsonl.trimEnd().split(`
2824
+ `);
2825
+ for (let index = lines.length - 1;index >= 0; index -= 1) {
2826
+ try {
2827
+ const entry = JSON.parse(lines[index] ?? "");
2828
+ if (entry.type !== "event_msg" || entry.payload?.type !== "token_count")
2829
+ continue;
2830
+ const usage = entry.payload.info?.total_token_usage;
2831
+ if (!usage)
2832
+ continue;
2833
+ const values = [
2834
+ usage.input_tokens,
2835
+ usage.output_tokens,
2836
+ usage.cached_input_tokens,
2837
+ usage.cache_write_input_tokens
2838
+ ];
2839
+ if (values.some((value) => value !== undefined && (!Number.isFinite(value) || value < 0))) {
2840
+ continue;
2841
+ }
2842
+ return {
2843
+ inputTokens: usage.input_tokens ?? 0,
2844
+ outputTokens: usage.output_tokens ?? 0,
2845
+ cachedInputTokens: usage.cached_input_tokens ?? 0,
2846
+ cacheWriteInputTokens: usage.cache_write_input_tokens ?? 0
2847
+ };
2848
+ } catch {}
2849
+ }
2850
+ return;
2851
+ }
2772
2852
  function readLatestCodexContextUsage(threadId) {
2773
2853
  const path = latestCodexRolloutPath(threadId);
2774
2854
  if (!path)
@@ -2780,6 +2860,17 @@ function readLatestCodexContextUsage(threadId) {
2780
2860
  return;
2781
2861
  }
2782
2862
  }
2863
+ function readLatestCodexTokenTotals(threadId) {
2864
+ const path = latestCodexRolloutPath(threadId);
2865
+ if (!path)
2866
+ return;
2867
+ try {
2868
+ return extractLatestCodexTokenTotals(readFileSync5(path, "utf8"));
2869
+ } catch (error) {
2870
+ logger.debug({ error, threadId }, "codex token totals: rollout read failed");
2871
+ return;
2872
+ }
2873
+ }
2783
2874
  function migrateCodexRolloutNativeMultiAgentMetadata(threadId) {
2784
2875
  const path = latestCodexRolloutPath(threadId);
2785
2876
  if (!path)
@@ -2949,6 +3040,20 @@ function buildNumberedDiffSummary(before, after, startLine = 1) {
2949
3040
  }
2950
3041
 
2951
3042
  // ../../packages/core/src/agents/codex-provider.ts
3043
+ function sameCodexUsage(usage, total) {
3044
+ return usage.input_tokens === total.inputTokens && usage.output_tokens === total.outputTokens && (usage.cached_input_tokens ?? 0) === total.cachedInputTokens && (usage.cache_write_input_tokens ?? 0) === total.cacheWriteInputTokens;
3045
+ }
3046
+ function normalizeCodexTurnUsage(usage, baseline, rolloutTotal) {
3047
+ if (!baseline || !rolloutTotal || !sameCodexUsage(usage, rolloutTotal))
3048
+ return usage;
3049
+ const delta = (current, previous) => current >= previous ? current - previous : current;
3050
+ return {
3051
+ input_tokens: delta(rolloutTotal.inputTokens, baseline.inputTokens),
3052
+ output_tokens: delta(rolloutTotal.outputTokens, baseline.outputTokens),
3053
+ cached_input_tokens: delta(rolloutTotal.cachedInputTokens, baseline.cachedInputTokens),
3054
+ cache_write_input_tokens: delta(rolloutTotal.cacheWriteInputTokens, baseline.cacheWriteInputTokens)
3055
+ };
3056
+ }
2952
3057
  function mapEffort(effort) {
2953
3058
  if (!effort)
2954
3059
  return;
@@ -3355,6 +3460,7 @@ async function* codexProvider(opts) {
3355
3460
  ...opts.effort ? { modelReasoningEffort: mapEffort(opts.effort) } : {}
3356
3461
  };
3357
3462
  let currentSessionId = opts.sessionId;
3463
+ let usageBaseline = currentSessionId ? readLatestCodexTokenTotals(currentSessionId) : undefined;
3358
3464
  let thread = currentSessionId ? codex.resumeThread(currentSessionId, threadOptions) : codex.startThread(threadOptions);
3359
3465
  let prompt = promptForThread(opts, true);
3360
3466
  let agentTextSoFar = "";
@@ -3413,6 +3519,7 @@ async function* codexProvider(opts) {
3413
3519
  thread = codex.startThread(threadOptions);
3414
3520
  prompt = promptForThread(opts, true);
3415
3521
  currentSessionId = undefined;
3522
+ usageBaseline = undefined;
3416
3523
  startResult = await startStreamedWithTracking(thread, prompt, attemptAbort.signal, trackedPids);
3417
3524
  }
3418
3525
  if (attemptAbort.signal.aborted) {
@@ -3513,10 +3620,11 @@ async function* codexProvider(opts) {
3513
3620
  break;
3514
3621
  }
3515
3622
  case "turn.completed": {
3516
- const usage = event.usage;
3517
- if (!usage)
3623
+ const rawUsage = event.usage;
3624
+ if (!rawUsage)
3518
3625
  break;
3519
3626
  attemptCompleted = true;
3627
+ const usage = normalizeCodexTurnUsage(rawUsage, usageBaseline, currentSessionId ? readLatestCodexTokenTotals(currentSessionId) : undefined);
3520
3628
  const contextUsage = currentSessionId ? readLatestCodexContextUsage(currentSessionId) : undefined;
3521
3629
  yield {
3522
3630
  type: "result",
@@ -3525,6 +3633,7 @@ async function* codexProvider(opts) {
3525
3633
  usage: {
3526
3634
  inputTokens: usage.input_tokens,
3527
3635
  outputTokens: usage.output_tokens,
3636
+ cacheCreationInputTokens: usage.cache_write_input_tokens,
3528
3637
  cacheReadInputTokens: usage.cached_input_tokens,
3529
3638
  ...contextUsage
3530
3639
  }
@@ -3816,4 +3925,4 @@ export {
3816
3925
  buildClaudeDisallowedTools
3817
3926
  };
3818
3927
 
3819
- //# debugId=61393A8287FDB3CB64756E2164756E21
3928
+ //# debugId=76B59F2AB62704F364756E2164756E21