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
@@ -474,7 +474,7 @@ var init_canonical_bridge_config = __esm(() => {
474
474
  });
475
475
 
476
476
  // ../../packages/core/src/mcp/runtime-spec.ts
477
- import { createHmac, timingSafeEqual } from "crypto";
477
+ import { createHash, createHmac, timingSafeEqual } from "crypto";
478
478
  function encodeTokenPart(value) {
479
479
  return Buffer.from(JSON.stringify(value), "utf-8").toString("base64url");
480
480
  }
@@ -507,19 +507,69 @@ function buildRuntimeMcpSpec(agent, ctx) {
507
507
  return {
508
508
  type: "sse",
509
509
  url: `${base}/sse?${query}`,
510
- timeout: CLAUDE_MCP_TOOL_TIMEOUT_MS
510
+ timeout: CLAUDE_MCP_TOOL_TIMEOUT_MS,
511
+ ...agent === "maestro" ? { lifecycle: "turn" } : {}
511
512
  };
512
513
  }
514
+ function hostedMcpCacheIdentity(surface, ctx) {
515
+ let semanticContext;
516
+ switch (surface) {
517
+ case "system-health":
518
+ semanticContext = {};
519
+ break;
520
+ case "token-stats":
521
+ case "agent-health":
522
+ semanticContext = { userId: ctx.userId };
523
+ break;
524
+ case "task":
525
+ semanticContext = {
526
+ userId: ctx.userId,
527
+ topicTitle: ctx.topicTitle,
528
+ topicId: ctx.topicId ?? null
529
+ };
530
+ break;
531
+ case "wiki":
532
+ case "skills":
533
+ semanticContext = {
534
+ userId: ctx.userId,
535
+ topicId: ctx.wikiTopicId ?? ctx.topicId ?? null
536
+ };
537
+ break;
538
+ case "vault":
539
+ semanticContext = { userId: ctx.userId, cwd: ctx.cwd, agent: ctx.agent };
540
+ break;
541
+ case "session-comm":
542
+ semanticContext = {
543
+ userId: ctx.userId,
544
+ topicTitle: ctx.topicTitle,
545
+ topicId: ctx.topicId ?? null,
546
+ subagentParentTopicId: ctx.subagentParentTopicId ?? null,
547
+ depth: ctx.depth ?? 0,
548
+ silent: ctx.silent ?? false,
549
+ agent: ctx.agent,
550
+ peerBridge: ctx.peerBridge ?? null
551
+ };
552
+ break;
553
+ }
554
+ const digest = createHash("sha256").update(JSON.stringify([surface, semanticContext])).digest("hex").slice(0, 24);
555
+ return `hosted:${surface}:${digest}`;
556
+ }
513
557
  function buildHostedMcpSpec(agent, surface, ctx) {
514
558
  const token = issueHostedMcpToken(surface, ctx);
515
559
  const base = `http://127.0.0.1:${runtimePort}${RUNTIME_MCP_BASE_PATH}/${surface}`;
516
560
  const query = `token=${encodeURIComponent(token)}`;
517
561
  if (agent === "codex")
518
562
  return { url: `${base}/mcp?${query}` };
563
+ const queryBound = surface === "session-comm" && (ctx.silent === true || ctx.peerBridge !== undefined);
564
+ const lifecycle = queryBound ? "turn" : surface === "session-comm" ? "session" : "process";
519
565
  return {
520
566
  type: "sse",
521
567
  url: `${base}/sse?${query}`,
522
- timeout: CLAUDE_MCP_TOOL_TIMEOUT_MS
568
+ timeout: CLAUDE_MCP_TOOL_TIMEOUT_MS,
569
+ ...agent === "maestro" ? {
570
+ lifecycle,
571
+ cacheKey: hostedMcpCacheIdentity(surface, ctx)
572
+ } : {}
523
573
  };
524
574
  }
525
575
  var RUNTIME_MCP_KEY = "runtime", RUNTIME_MCP_BASE_PATH = "/mcp/runtime", TOKEN_TTL_MS, CLAUDE_MCP_TOOL_TIMEOUT_MS = 600000, runtimePort;
@@ -1372,9 +1422,9 @@ var init_sqlite = __esm(async () => {
1372
1422
  });
1373
1423
 
1374
1424
  // ../../packages/core/src/storage/vault-crypto-core.ts
1375
- import { createCipheriv, createDecipheriv, createHash, randomBytes as randomBytes3 } from "crypto";
1425
+ import { createCipheriv, createDecipheriv, createHash as createHash2, randomBytes as randomBytes3 } from "crypto";
1376
1426
  function encryptionKey(masterKey) {
1377
- return createHash("sha256").update("otium-vault-value-v1\x00", "utf8").update(masterKey, "utf8").digest().subarray(0, KEY_BYTES);
1427
+ return createHash2("sha256").update("otium-vault-value-v1\x00", "utf8").update(masterKey, "utf8").digest().subarray(0, KEY_BYTES);
1378
1428
  }
1379
1429
  function aad(userId, key) {
1380
1430
  return Buffer.from(`${userId}\x00${key.toUpperCase()}`, "utf8");
@@ -2173,7 +2223,7 @@ var init_claude_registry = __esm(() => {
2173
2223
  });
2174
2224
 
2175
2225
  // ../../packages/core/src/version.ts
2176
- var NEGOTIUM_VERSION = "0.2.14";
2226
+ var NEGOTIUM_VERSION = "0.2.16";
2177
2227
 
2178
2228
  // ../../packages/core/src/agents/codex-native-multi-agent.ts
2179
2229
  import { spawn as spawn2 } from "child_process";
@@ -2631,6 +2681,36 @@ function extractLatestCodexContextUsage(jsonl) {
2631
2681
  }
2632
2682
  return;
2633
2683
  }
2684
+ function extractLatestCodexTokenTotals(jsonl) {
2685
+ const lines = jsonl.trimEnd().split(`
2686
+ `);
2687
+ for (let index = lines.length - 1;index >= 0; index -= 1) {
2688
+ try {
2689
+ const entry = JSON.parse(lines[index] ?? "");
2690
+ if (entry.type !== "event_msg" || entry.payload?.type !== "token_count")
2691
+ continue;
2692
+ const usage = entry.payload.info?.total_token_usage;
2693
+ if (!usage)
2694
+ continue;
2695
+ const values = [
2696
+ usage.input_tokens,
2697
+ usage.output_tokens,
2698
+ usage.cached_input_tokens,
2699
+ usage.cache_write_input_tokens
2700
+ ];
2701
+ if (values.some((value) => value !== undefined && (!Number.isFinite(value) || value < 0))) {
2702
+ continue;
2703
+ }
2704
+ return {
2705
+ inputTokens: usage.input_tokens ?? 0,
2706
+ outputTokens: usage.output_tokens ?? 0,
2707
+ cachedInputTokens: usage.cached_input_tokens ?? 0,
2708
+ cacheWriteInputTokens: usage.cache_write_input_tokens ?? 0
2709
+ };
2710
+ } catch {}
2711
+ }
2712
+ return;
2713
+ }
2634
2714
  function readLatestCodexContextUsage(threadId) {
2635
2715
  const path = latestCodexRolloutPath(threadId);
2636
2716
  if (!path)
@@ -2642,6 +2722,17 @@ function readLatestCodexContextUsage(threadId) {
2642
2722
  return;
2643
2723
  }
2644
2724
  }
2725
+ function readLatestCodexTokenTotals(threadId) {
2726
+ const path = latestCodexRolloutPath(threadId);
2727
+ if (!path)
2728
+ return;
2729
+ try {
2730
+ return extractLatestCodexTokenTotals(readFileSync5(path, "utf8"));
2731
+ } catch (error) {
2732
+ logger.debug({ error, threadId }, "codex token totals: rollout read failed");
2733
+ return;
2734
+ }
2735
+ }
2645
2736
  function migrateCodexRolloutNativeMultiAgentMetadata(threadId) {
2646
2737
  const path = latestCodexRolloutPath(threadId);
2647
2738
  if (!path)
@@ -4956,6 +5047,7 @@ var init_tool_format = __esm(() => {
4956
5047
  var exports_codex_provider = {};
4957
5048
  __export(exports_codex_provider, {
4958
5049
  toCodexMcpServers: () => toCodexMcpServers,
5050
+ normalizeCodexTurnUsage: () => normalizeCodexTurnUsage,
4959
5051
  codexProvider: () => codexProvider
4960
5052
  });
4961
5053
  import { execFileSync as execFileSync4 } from "child_process";
@@ -4963,6 +5055,20 @@ import { existsSync as existsSync11, readFileSync as readFileSync11, realpathSyn
4963
5055
  import { homedir as homedir6 } from "os";
4964
5056
  import { dirname as dirname9, isAbsolute as isAbsolute2, join as join12, relative, resolve as resolve8 } from "path";
4965
5057
  import { Codex } from "@openai/codex-sdk";
5058
+ function sameCodexUsage(usage, total) {
5059
+ 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;
5060
+ }
5061
+ function normalizeCodexTurnUsage(usage, baseline, rolloutTotal) {
5062
+ if (!baseline || !rolloutTotal || !sameCodexUsage(usage, rolloutTotal))
5063
+ return usage;
5064
+ const delta = (current, previous) => current >= previous ? current - previous : current;
5065
+ return {
5066
+ input_tokens: delta(rolloutTotal.inputTokens, baseline.inputTokens),
5067
+ output_tokens: delta(rolloutTotal.outputTokens, baseline.outputTokens),
5068
+ cached_input_tokens: delta(rolloutTotal.cachedInputTokens, baseline.cachedInputTokens),
5069
+ cache_write_input_tokens: delta(rolloutTotal.cacheWriteInputTokens, baseline.cacheWriteInputTokens)
5070
+ };
5071
+ }
4966
5072
  function mapEffort(effort) {
4967
5073
  if (!effort)
4968
5074
  return;
@@ -5362,6 +5468,7 @@ async function* codexProvider(opts) {
5362
5468
  ...opts.effort ? { modelReasoningEffort: mapEffort(opts.effort) } : {}
5363
5469
  };
5364
5470
  let currentSessionId = opts.sessionId;
5471
+ let usageBaseline = currentSessionId ? readLatestCodexTokenTotals(currentSessionId) : undefined;
5365
5472
  let thread = currentSessionId ? codex.resumeThread(currentSessionId, threadOptions) : codex.startThread(threadOptions);
5366
5473
  let prompt = promptForThread(opts, true);
5367
5474
  let agentTextSoFar = "";
@@ -5420,6 +5527,7 @@ async function* codexProvider(opts) {
5420
5527
  thread = codex.startThread(threadOptions);
5421
5528
  prompt = promptForThread(opts, true);
5422
5529
  currentSessionId = undefined;
5530
+ usageBaseline = undefined;
5423
5531
  startResult = await startStreamedWithTracking(thread, prompt, attemptAbort.signal, trackedPids);
5424
5532
  }
5425
5533
  if (attemptAbort.signal.aborted) {
@@ -5520,10 +5628,11 @@ async function* codexProvider(opts) {
5520
5628
  break;
5521
5629
  }
5522
5630
  case "turn.completed": {
5523
- const usage = event.usage;
5524
- if (!usage)
5631
+ const rawUsage = event.usage;
5632
+ if (!rawUsage)
5525
5633
  break;
5526
5634
  attemptCompleted = true;
5635
+ const usage = normalizeCodexTurnUsage(rawUsage, usageBaseline, currentSessionId ? readLatestCodexTokenTotals(currentSessionId) : undefined);
5527
5636
  const contextUsage = currentSessionId ? readLatestCodexContextUsage(currentSessionId) : undefined;
5528
5637
  yield {
5529
5638
  type: "result",
@@ -5532,6 +5641,7 @@ async function* codexProvider(opts) {
5532
5641
  usage: {
5533
5642
  inputTokens: usage.input_tokens,
5534
5643
  outputTokens: usage.output_tokens,
5644
+ cacheCreationInputTokens: usage.cache_write_input_tokens,
5535
5645
  cacheReadInputTokens: usage.cached_input_tokens,
5536
5646
  ...contextUsage
5537
5647
  }
@@ -9750,7 +9860,7 @@ var init_runtime_process_leases = __esm(async () => {
9750
9860
  });
9751
9861
 
9752
9862
  // ../../packages/core/src/agents/mcp-tools/ask-user.ts
9753
- import { createHash as createHash2, randomUUID as randomUUID9 } from "crypto";
9863
+ import { createHash as createHash3, randomUUID as randomUUID9 } from "crypto";
9754
9864
  import { z } from "zod";
9755
9865
  function normalizeAskText(value, maxChars) {
9756
9866
  if (typeof value !== "string")
@@ -9787,7 +9897,7 @@ function normalizeAskUserQuestionInput(input) {
9787
9897
  return { question, choices };
9788
9898
  }
9789
9899
  function askBodyHash(question, choices) {
9790
- return createHash2("sha256").update(JSON.stringify({ question, choices })).digest("hex");
9900
+ return createHash3("sha256").update(JSON.stringify({ question, choices })).digest("hex");
9791
9901
  }
9792
9902
  function answerToolResult(answer) {
9793
9903
  if (!answer.userId)
@@ -10807,7 +10917,7 @@ var init_browser_profiles = __esm(async () => {
10807
10917
 
10808
10918
  // ../../packages/core/src/platform/playwright/manager.ts
10809
10919
  import { execFileSync as execFileSync7, spawn as spawn5 } from "child_process";
10810
- import { createHash as createHash3, randomBytes as randomBytes6, timingSafeEqual as timingSafeEqual3 } from "crypto";
10920
+ import { createHash as createHash4, randomBytes as randomBytes6, timingSafeEqual as timingSafeEqual3 } from "crypto";
10811
10921
  import {
10812
10922
  cpSync,
10813
10923
  existsSync as existsSync17,
@@ -10902,7 +11012,7 @@ function parseInstanceKey(instanceKey) {
10902
11012
  };
10903
11013
  }
10904
11014
  function portFileName(instanceKey) {
10905
- return createHash3("sha256").update(instanceKey).digest("hex").slice(0, 24);
11015
+ return createHash4("sha256").update(instanceKey).digest("hex").slice(0, 24);
10906
11016
  }
10907
11017
  function writePortFile(instanceKey, port) {
10908
11018
  try {
@@ -12495,7 +12605,7 @@ __export(exports_derive, {
12495
12605
  TopicForkCompactionError: () => TopicForkCompactionError,
12496
12606
  TopicDeriveBusyError: () => TopicDeriveBusyError
12497
12607
  });
12498
- import { createHash as createHash4, randomUUID as randomUUID12 } from "crypto";
12608
+ import { createHash as createHash5, randomUUID as randomUUID12 } from "crypto";
12499
12609
  import { mkdirSync as mkdirSync13, rmSync as rmSync5, unlinkSync as unlinkSync13 } from "fs";
12500
12610
  function getTopics() {
12501
12611
  return listTopics().filter((topic) => !isLegacySharedGeneral(topic.id));
@@ -12561,7 +12671,7 @@ function captureForkSnapshot(sourceTopicId, userId, topicTitle) {
12561
12671
  maxRowid: messageRows.at(-1)?.rowid ?? 0
12562
12672
  },
12563
12673
  active: isTopicRunning(sourceTopicId),
12564
- canonicalDigest: createHash4("sha256").update(entries.map((entry) => JSON.stringify(entry)).join(`
12674
+ canonicalDigest: createHash5("sha256").update(entries.map((entry) => JSON.stringify(entry)).join(`
12565
12675
  `)).digest("hex")
12566
12676
  };
12567
12677
  }
@@ -13054,7 +13164,7 @@ __export(exports_session_asks, {
13054
13164
  clearPendingAsk: () => clearPendingAsk,
13055
13165
  PENDING_ASK_TTL_MS: () => PENDING_ASK_TTL_MS
13056
13166
  });
13057
- import { createHash as createHash5 } from "crypto";
13167
+ import { createHash as createHash6 } from "crypto";
13058
13168
  import {
13059
13169
  closeSync as closeSync2,
13060
13170
  mkdirSync as mkdirSync15,
@@ -13068,14 +13178,14 @@ import {
13068
13178
  import { dirname as dirname13, join as join24 } from "path";
13069
13179
  function pendingAskDir(userId) {
13070
13180
  const rawUserId = String(userId);
13071
- const safeUserId = /^[A-Za-z0-9][A-Za-z0-9_.@-]{0,255}$/.test(rawUserId) && !rawUserId.includes("..") ? rawUserId : `sha256-${createHash5("sha256").update(rawUserId).digest("hex")}`;
13181
+ const safeUserId = /^[A-Za-z0-9][A-Za-z0-9_.@-]{0,255}$/.test(rawUserId) && !rawUserId.includes("..") ? rawUserId : `sha256-${createHash6("sha256").update(rawUserId).digest("hex")}`;
13072
13182
  return join24(resolveStorageSessionAsksDir(), safeUserId);
13073
13183
  }
13074
13184
  function encodeAskKey(key) {
13075
13185
  return JSON.stringify([key.from, key.to]);
13076
13186
  }
13077
13187
  function pendingAskPath(key) {
13078
- const digest = createHash5("sha256").update(encodeAskKey(key)).digest("hex");
13188
+ const digest = createHash6("sha256").update(encodeAskKey(key)).digest("hex");
13079
13189
  return join24(pendingAskDir(key.userId), `${ASK_FILENAME_PREFIX}${digest}.pending`);
13080
13190
  }
13081
13191
  function v2PendingAskPath(key) {
@@ -14654,12 +14764,12 @@ var init_visuals = __esm(async () => {
14654
14764
  });
14655
14765
 
14656
14766
  // ../../packages/core/src/storage/token-stats.ts
14657
- import { createHash as createHash6 } from "crypto";
14767
+ import { createHash as createHash7 } from "crypto";
14658
14768
  import { mkdirSync as mkdirSync17 } from "fs";
14659
14769
  import { join as join26 } from "path";
14660
14770
  function tokenStatsFileId(userId) {
14661
14771
  const rawUserId = String(userId);
14662
- return /^[A-Za-z0-9][A-Za-z0-9_.@-]{0,255}$/.test(rawUserId) && !rawUserId.includes("..") ? rawUserId : `sha256-${createHash6("sha256").update(rawUserId).digest("hex")}`;
14772
+ return /^[A-Za-z0-9][A-Za-z0-9_.@-]{0,255}$/.test(rawUserId) && !rawUserId.includes("..") ? rawUserId : `sha256-${createHash7("sha256").update(rawUserId).digest("hex")}`;
14663
14773
  }
14664
14774
  function queriesPath(userId) {
14665
14775
  const fileId = tokenStatsFileId(userId);
@@ -14667,14 +14777,33 @@ function queriesPath(userId) {
14667
14777
  mkdirSync17(logDir, { recursive: true });
14668
14778
  return join26(logDir, `token-queries-${fileId}.jsonl`);
14669
14779
  }
14670
- function recordUsage(userId, session, usage) {
14780
+ function estimateUsageCost(agent, model, usage) {
14781
+ const prices = TOKEN_PRICES[`${agent}:${model}`];
14782
+ if (!prices)
14783
+ return 0;
14784
+ return (usage.inputTokens * prices.input + usage.outputTokens * prices.output + (agent === "claude" ? usage.cacheCreationInputTokens * (prices.cacheWrite ?? prices.input) : 0) + usage.cacheReadInputTokens * prices.cacheRead) / 1e6;
14785
+ }
14786
+ function recordUsage(userId, session, usage, context) {
14787
+ const cacheReadInputTokens = usage.cacheReadInputTokens ?? 0;
14788
+ const inputTokens = context.agent === "claude" ? usage.inputTokens : Math.max(0, usage.inputTokens - cacheReadInputTokens);
14789
+ const normalized = {
14790
+ inputTokens,
14791
+ outputTokens: usage.outputTokens,
14792
+ cacheCreationInputTokens: usage.cacheCreationInputTokens ?? 0,
14793
+ cacheReadInputTokens
14794
+ };
14671
14795
  const record = {
14796
+ schemaVersion: 2,
14672
14797
  timestamp: new Date().toISOString(),
14673
14798
  session,
14674
- inputTokens: usage.inputTokens,
14675
- outputTokens: usage.outputTokens,
14676
- cacheCreationInputTokens: usage.cacheCreationInputTokens ?? 0,
14677
- cacheReadInputTokens: usage.cacheReadInputTokens ?? 0
14799
+ topicId: context.topicId,
14800
+ ...context.providerSessionId ? { providerSessionId: context.providerSessionId } : {},
14801
+ agent: context.agent,
14802
+ model: context.model,
14803
+ ...normalized,
14804
+ ...usage.contextTokens !== undefined ? { contextTokens: usage.contextTokens } : {},
14805
+ ...usage.contextWindow !== undefined ? { contextWindow: usage.contextWindow } : {},
14806
+ estimatedCostUsd: usage.costUsd ?? estimateUsageCost(context.agent, context.model, normalized)
14678
14807
  };
14679
14808
  try {
14680
14809
  appendJsonlEntry(queriesPath(userId), record);
@@ -14682,10 +14811,23 @@ function recordUsage(userId, session, usage) {
14682
14811
  logger.warn({ err: e, userId }, "token-stats: Failed to record");
14683
14812
  }
14684
14813
  }
14814
+ var TOKEN_PRICES;
14685
14815
  var init_token_stats = __esm(async () => {
14686
14816
  init_jsonl();
14687
14817
  init_logger();
14688
14818
  await init_storage_host();
14819
+ TOKEN_PRICES = {
14820
+ "codex:gpt-5.6-sol": { input: 5, cacheRead: 0.5, output: 30 },
14821
+ "codex:gpt-5.6-terra": { input: 2.5, cacheRead: 0.25, output: 15 },
14822
+ "codex:gpt-5.6-luna": { input: 1, cacheRead: 0.1, output: 6 },
14823
+ "claude:fable": { input: 10, cacheWrite: 12.5, cacheRead: 1, output: 50 },
14824
+ "claude:opus": { input: 5, cacheWrite: 6.25, cacheRead: 0.5, output: 25 },
14825
+ "claude:sonnet": { input: 2, cacheWrite: 2.5, cacheRead: 0.2, output: 10 },
14826
+ "maestro:kimi-k3": { input: 3, cacheRead: 0.3, output: 15 },
14827
+ "maestro:kimi-k2.7-code": { input: 0.95, cacheRead: 0.19, output: 4 },
14828
+ "maestro:deepseek-pro": { input: 0.435, cacheRead: 0.003625, output: 0.87 },
14829
+ "maestro:deepseek-flash": { input: 0.14, cacheRead: 0.0028, output: 0.28 }
14830
+ };
14689
14831
  });
14690
14832
 
14691
14833
  // ../../packages/core/src/runtime/turn-event-stream.ts
@@ -14724,6 +14866,14 @@ async function runTurnEventStream(topicId, topicTitle, queryId, events, control,
14724
14866
  const toolSummaryOptions = {
14725
14867
  cwd: control.injectParams?.cwd ?? workspaceCwdFor(topicId)
14726
14868
  };
14869
+ const recordEventUsage = (usage) => {
14870
+ recordUsage(userId, topicTitle, usage, {
14871
+ topicId,
14872
+ ...control.sessionId ? { providerSessionId: control.sessionId } : {},
14873
+ agent: agentType,
14874
+ model
14875
+ });
14876
+ };
14727
14877
  const nextSyntheticToolUseId = () => `tool-${queryId}-${++syntheticToolCounter}`;
14728
14878
  const bindToolUseId = (providerToolUseId, fallback) => {
14729
14879
  const providerId = normalizeToolUseId(providerToolUseId);
@@ -15042,7 +15192,7 @@ async function runTurnEventStream(topicId, topicTitle, queryId, events, control,
15042
15192
  break;
15043
15193
  case "result":
15044
15194
  if (event.usage)
15045
- recordUsage(userId, topicTitle, event.usage);
15195
+ recordEventUsage(event.usage);
15046
15196
  {
15047
15197
  const usage = event.usage ? {
15048
15198
  input: event.usage.inputTokens,
@@ -15092,6 +15242,8 @@ async function runTurnEventStream(topicId, topicTitle, queryId, events, control,
15092
15242
  }
15093
15243
  break;
15094
15244
  case "error":
15245
+ if (event.usage)
15246
+ recordEventUsage(event.usage);
15095
15247
  logger.warn({ topicId, queryId, agentType, model, silent, error: event.content }, "ai: provider returned error");
15096
15248
  terminalEmitted = true;
15097
15249
  errorOccurred = true;
@@ -18579,4 +18731,4 @@ export {
18579
18731
  DEFAULT_SELF_CONFIG_PRODUCT
18580
18732
  };
18581
18733
 
18582
- //# debugId=1F2C27A2871EECB564756E2164756E21
18734
+ //# debugId=969112A1E458C75264756E2164756E21