mixdog 0.9.175 → 1.0.0

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 (44) hide show
  1. package/package.json +1 -1
  2. package/scripts/context-renewal-live-check.mjs +2 -1
  3. package/scripts/plan-runtime-release-tag.mjs +57 -0
  4. package/src/defaults/skills/xlsx/SKILL.md +1 -0
  5. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +7 -12
  6. package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +6 -1
  7. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request.mjs +2 -0
  8. package/src/runtime/agent/orchestrator/providers/cursor.mjs +20 -2
  9. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +3 -0
  10. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +2 -0
  11. package/src/runtime/agent/orchestrator/runtime-core/goal-tasks.mjs +12 -1
  12. package/src/runtime/agent/orchestrator/session/result-classification.mjs +1 -1
  13. package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-status.mjs +7 -3
  14. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/benign-exit.mjs +7 -3
  15. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +1 -0
  16. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +39 -3
  17. package/src/runtime/memory/lib/runtime-fetcher.mjs +94 -23
  18. package/src/runtime/office/capabilities-catalog.mjs +2 -0
  19. package/src/runtime/office/capabilities-signatures.mjs +12 -6
  20. package/src/runtime/office/capabilities.mjs +30 -10
  21. package/src/runtime/office/core/office-actions-open.mjs +1 -6
  22. package/src/runtime/office/core/office-sessions.mjs +9 -0
  23. package/src/runtime/office/portable/portable-xlsx-operations.mjs +2 -49
  24. package/src/runtime/office/portable/xlsx-contract.mjs +37 -3
  25. package/src/runtime/office/tool-defs.mjs +2 -2
  26. package/src/runtime/shared/llm/cost.mjs +16 -4
  27. package/src/runtime/shared/llm/model-catalog-projection.mjs +3 -2
  28. package/src/runtime/shared/llm/model-catalog.mjs +48 -0
  29. package/src/runtime/shared/llm/model-pricing-rates.mjs +11 -4
  30. package/src/runtime/shared/llm/usage-accounting.mjs +12 -11
  31. package/src/runtime/shared/llm/usage-context.mjs +7 -0
  32. package/src/runtime/shared/llm/usage-ledger-repair.mjs +3 -1
  33. package/src/runtime/shared/llm/usage-ledger.mjs +1 -1
  34. package/src/runtime/shared/tool-card-model/card-status.mjs +7 -5
  35. package/src/runtime/shared/tool-card-model/git-result.mjs +10 -0
  36. package/src/runtime/shared/tool-card-model/terminal-status.mjs +6 -2
  37. package/src/runtime/shared/tool-card-model.golden-cases.mjs +2 -1
  38. package/src/runtime/shared/tool-result-summary.mjs +1 -0
  39. package/src/runtime/shared/tool-status.mjs +35 -2
  40. package/src/runtime/tidy/report.mjs +2 -2
  41. package/src/runtime/tidy/tool.mjs +6 -1
  42. package/src/tui/dist/index.mjs +88 -37
  43. package/src/tui/session/session-api/settings.mjs +16 -10
  44. package/src/vendor/statusline/src/gateway/route-meta.mjs +7 -2
@@ -1,3 +1,5 @@
1
+ import { hasBenignExitOutcome } from '../tool-status.mjs';
2
+
1
3
  // Only command result headers, not arbitrary lines in a patch, carry exits.
2
4
  export function gitResultExitCode(text) {
3
5
  const match = /(?:^(?:## [^\n]+\n)?|\n## [^\n]+\n)exit ([1-9]\d*)\r?(?:\n|$)/.exec(String(text ?? ''));
@@ -7,3 +9,11 @@ export function gitResultExitCode(text) {
7
9
  export function gitResultError(text) {
8
10
  return /(?:^|\n)error: command failed: [^\n]+|^error: [^\n]+/.exec(String(text ?? ''))?.[0].trim() || '';
9
11
  }
12
+
13
+ // A tool error fails the call; a git process that ran and exited non-zero is
14
+ // a command exit, like the shell's, unless the tool marked the exit a signal.
15
+ export function gitTerminalStatus(text) {
16
+ if (gitResultError(text)) return 'failed';
17
+ if (gitResultExitCode(text) !== null && !hasBenignExitOutcome(text)) return 'exit';
18
+ return '';
19
+ }
@@ -2,11 +2,11 @@
2
2
  * terminal-status.mjs — terminal status words, their outcome tone, status
3
3
  * marker stripping and the ` · <time>` detail conventions.
4
4
  */
5
- import { normalizeToolTerminalStatus, toolResultTerminalStatus } from '../tool-status.mjs';
5
+ import { leadingResultBlock, normalizeToolTerminalStatus, toolResultTerminalStatus } from '../tool-status.mjs';
6
6
  import { formatElapsed } from '../time-format.mjs';
7
7
 
8
8
  export function shellResultStatus(value) {
9
- const match = String(value || '').match(
9
+ const match = leadingResultBlock(value).match(
10
10
  /(?:^|\b)status:\s*(running|pending|queued|completed|failed|cancelled|canceled)\b/im
11
11
  );
12
12
  return match ? String(match[1] || '').toLowerCase() : '';
@@ -48,6 +48,7 @@ const TERMINAL_STATUS_LABELS = new Map([
48
48
  ['cancelled', 'Cancelled'],
49
49
  ['denied', 'Denied'],
50
50
  ]);
51
+ const BARE_STATUS_WORDS = new Set([...TERMINAL_STATUS_LABELS.values()].map((label) => label.toLowerCase()));
51
52
 
52
53
  export function displayTerminalStatus(value) {
53
54
  // 'exit' is a shell-only pseudo-status (command RAN but exited non-zero); it
@@ -107,5 +108,8 @@ export function mergeTerminalDetail(status, detail = '') {
107
108
  if (label === 'Finished' && text) return text;
108
109
  if (!text) return label;
109
110
  if (text.toLowerCase().startsWith(label.toLowerCase())) return text;
111
+ // A bare status word (the generic "Failed" of an error without a body) is
112
+ // superseded by the resolved status, e.g. a user-takeover "Cancelled".
113
+ if (BARE_STATUS_WORDS.has(text.toLowerCase())) return label;
110
114
  return `${label} · ${text}`;
111
115
  }
@@ -16,7 +16,8 @@ export const GIT_GOLDEN_CASES = [
16
16
  summary: 'diff --git a/a.txt b/a.txt',
17
17
  status: 'completed',
18
18
  },
19
- { result: 'exit 128\nfatal: missing ref\n', summary: 'Exit 128', status: 'failed' },
19
+ { result: 'exit 128\nfatal: missing ref\n', summary: 'Exit 128', status: 'exit' },
20
+ { result: 'exit 1\n[outcome: no-match]\ndiff --git a/a.txt b/a.txt\n', summary: 'Exit 1', status: 'completed' },
20
21
  {
21
22
  result: '## git show missing\nexit 128\nfatal: missing\nerror: command failed: git show missing',
22
23
  summary: 'Exit 128',
@@ -312,6 +312,7 @@ function summarizeLineCount({ text, trimmed }, { zero, singular, plural }) {
312
312
  function summarizeReadResult({ text, trimmed }) {
313
313
  if (/^\[image:/i.test(trimmed)) return 'Image';
314
314
  if (!trimmed) return null;
315
+ if (trimmed.startsWith('(no lines in range')) return '0 lines';
315
316
  const n = text.split('\n').length;
316
317
  return `${n} ${pluralize(n, 'line')}`;
317
318
  }
@@ -23,15 +23,48 @@ export function normalizeToolTerminalStatus(value) {
23
23
  return '';
24
24
  }
25
25
 
26
+ // Status markers live in the result's leading block: the cancel marker, the
27
+ // shell exit header, a background-task header, a task/agent status line.
28
+ // Command output and fetched documents follow a blank line and can carry
29
+ // `status:` text of their own, which says nothing about the tool call.
30
+ export function leadingResultBlock(text) {
31
+ const lines = String(text || '').split('\n');
32
+ let index = 0;
33
+ if (/^\[tool output offloaded:/i.test(String(lines[0] || '').trim())) {
34
+ index = 1;
35
+ while (index < lines.length && !lines[index].trim()) index += 1;
36
+ }
37
+ const block = [];
38
+ for (; index < lines.length && lines[index].trim(); index += 1) block.push(lines[index]);
39
+ return block.join('\n');
40
+ }
41
+
42
+ // The user taking over the browser/desktop, or the session cancelling a
43
+ // computer command, stops the call on purpose; it is not a failed invocation.
44
+ const USER_CONTROL_CANCELLATION_RE =
45
+ /^(?:Error:\s*)?(?:Browser command interrupted by local user input\.|computer_session_aborted:|computer_user_control_active:)/i;
46
+
47
+ export function isUserControlCancellation(text) {
48
+ return USER_CONTROL_CANCELLATION_RE.test(String(text || '').trimStart());
49
+ }
50
+
51
+ // A non-zero exit the tool itself marked as a signal (search no-match, a
52
+ // `git diff --exit-code` difference) rather than a command failure.
53
+ export function hasBenignExitOutcome(text) {
54
+ return /^\[outcome:\s*(?:no-match|no-change)\]\s*$/im.test(String(text || ''));
55
+ }
56
+
26
57
  export function toolResultTerminalStatus(text) {
27
58
  const body = String(text || '');
28
59
  const tagged = body.match(/<status[^>]*>([\s\S]*?)<\/status>/i)?.[1]?.trim();
29
60
  if (tagged) return normalizeToolTerminalStatus(tagged);
30
- const bracketed = body.match(/^\[status:\s*([^\]]*)\]/im)?.[1]?.trim();
61
+ const head = leadingResultBlock(body);
62
+ const bracketed = head.match(/^\[status:\s*([^\]]*)\]/im)?.[1]?.trim();
31
63
  if (bracketed) return normalizeToolTerminalStatus(bracketed);
32
- const inline = body.match(/^(?:status|state):\s*([^\s·,;]+)/im)?.[1]?.trim();
64
+ const inline = head.match(/^(?:status|state):\s*([^\s·,;]+)/im)?.[1]?.trim();
33
65
  const fromInline = normalizeToolTerminalStatus(inline);
34
66
  if (fromInline) return fromInline;
67
+ if (isUserControlCancellation(body)) return 'cancelled';
35
68
  // Bare control bodies written on cancel/crash (current + legacy).
36
69
  const trimmed = body.trim();
37
70
  if (/^(?:cancelled|canceled)$/i.test(trimmed)) return 'cancelled';
@@ -11,10 +11,10 @@ const FILE_LIST_CAP = 25;
11
11
  export const RESULTS_PAGE_MAX = 100;
12
12
  const TRIM_STEPS = [8, 3, 0];
13
13
 
14
- export function tidyToolResult(value, isError = false) {
14
+ export function tidyToolResult(value, isError = value?.ok === false) {
15
15
  return {
16
16
  content: [{ type: 'text', text: JSON.stringify(value) }],
17
- ...(isError || value?.ok === false ? { isError: true } : {}),
17
+ ...(isError ? { isError: true } : {}),
18
18
  };
19
19
  }
20
20
 
@@ -571,7 +571,12 @@ export async function executeTidyTool(args = {}, { cwd = process.cwd(), signal =
571
571
  return tidyToolResult(await rulesAction({ cwd, signal, startedAt }));
572
572
  }
573
573
  if (action === 'results') {
574
- return tidyToolResult(await resultsAction({ args, cwd, sessionId, engineFilter, pathFilter: scope, startedAt }));
574
+ // Paging a stored run succeeds even when that run was incomplete; the
575
+ // report's ok/status still describe the run itself.
576
+ return tidyToolResult(
577
+ await resultsAction({ args, cwd, sessionId, engineFilter, pathFilter: scope, startedAt }),
578
+ false
579
+ );
575
580
  }
576
581
  return tidyToolResult(
577
582
  await runAction({
@@ -37476,6 +37476,58 @@ function parseTaskNotification(text) {
37476
37476
  };
37477
37477
  }
37478
37478
 
37479
+ // src/runtime/shared/tool-status.mjs
37480
+ function normalizeToolTerminalStatus(value) {
37481
+ const raw = String(value || "").trim().toLowerCase();
37482
+ if (!raw) return "";
37483
+ if (/^(running|pending|queued|in_progress|in-progress)$/.test(raw)) return "running";
37484
+ if (/^(completed|complete|done|success|succeeded|ok)$/.test(raw)) return "completed";
37485
+ if (/^(failed|fail|error|errored|timeout|timed_out|killed)$/.test(raw)) return "failed";
37486
+ if (/^(cancelled|canceled|cancel|cancel[-_ ]unconfirmed|cancel[-_ ]pending|cancelling|canceling)$/.test(raw))
37487
+ return "cancelled";
37488
+ if (/^(denied|deny|refused|rejected)$/.test(raw)) return "denied";
37489
+ return "";
37490
+ }
37491
+ function leadingResultBlock(text) {
37492
+ const lines = String(text || "").split("\n");
37493
+ let index = 0;
37494
+ if (/^\[tool output offloaded:/i.test(String(lines[0] || "").trim())) {
37495
+ index = 1;
37496
+ while (index < lines.length && !lines[index].trim()) index += 1;
37497
+ }
37498
+ const block = [];
37499
+ for (; index < lines.length && lines[index].trim(); index += 1) block.push(lines[index]);
37500
+ return block.join("\n");
37501
+ }
37502
+ var USER_CONTROL_CANCELLATION_RE = /^(?:Error:\s*)?(?:Browser command interrupted by local user input\.|computer_session_aborted:|computer_user_control_active:)/i;
37503
+ function isUserControlCancellation(text) {
37504
+ return USER_CONTROL_CANCELLATION_RE.test(String(text || "").trimStart());
37505
+ }
37506
+ function hasBenignExitOutcome(text) {
37507
+ return /^\[outcome:\s*(?:no-match|no-change)\]\s*$/im.test(String(text || ""));
37508
+ }
37509
+ function toolResultTerminalStatus(text) {
37510
+ const body = String(text || "");
37511
+ const tagged = body.match(/<status[^>]*>([\s\S]*?)<\/status>/i)?.[1]?.trim();
37512
+ if (tagged) return normalizeToolTerminalStatus(tagged);
37513
+ const head = leadingResultBlock(body);
37514
+ const bracketed = head.match(/^\[status:\s*([^\]]*)\]/im)?.[1]?.trim();
37515
+ if (bracketed) return normalizeToolTerminalStatus(bracketed);
37516
+ const inline = head.match(/^(?:status|state):\s*([^\s·,;]+)/im)?.[1]?.trim();
37517
+ const fromInline = normalizeToolTerminalStatus(inline);
37518
+ if (fromInline) return fromInline;
37519
+ if (isUserControlCancellation(body)) return "cancelled";
37520
+ const trimmed = body.trim();
37521
+ if (/^(?:cancelled|canceled)$/i.test(trimmed)) return "cancelled";
37522
+ if (/^(?:interrupted by (?:user|process restart)|tool execution aborted|\[tool execution was interrupted\])$/i.test(
37523
+ trimmed
37524
+ )) {
37525
+ return "cancelled";
37526
+ }
37527
+ if (/^the user doesn't want to proceed with this tool use\b/i.test(trimmed)) return "cancelled";
37528
+ return "";
37529
+ }
37530
+
37479
37531
  // src/runtime/shared/tool-card-model/git-result.mjs
37480
37532
  function gitResultExitCode(text) {
37481
37533
  const match = /(?:^(?:## [^\n]+\n)?|\n## [^\n]+\n)exit ([1-9]\d*)\r?(?:\n|$)/.exec(String(text ?? ""));
@@ -37484,6 +37536,11 @@ function gitResultExitCode(text) {
37484
37536
  function gitResultError(text) {
37485
37537
  return /(?:^|\n)error: command failed: [^\n]+|^error: [^\n]+/.exec(String(text ?? ""))?.[0].trim() || "";
37486
37538
  }
37539
+ function gitTerminalStatus(text) {
37540
+ if (gitResultError(text)) return "failed";
37541
+ if (gitResultExitCode(text) !== null && !hasBenignExitOutcome(text)) return "exit";
37542
+ return "";
37543
+ }
37487
37544
 
37488
37545
  // src/runtime/shared/tool-result-summary.mjs
37489
37546
  function countNonEmptyLines(text) {
@@ -37686,6 +37743,7 @@ function summarizeLineCount({ text, trimmed }, { zero, singular, plural }) {
37686
37743
  function summarizeReadResult({ text, trimmed }) {
37687
37744
  if (/^\[image:/i.test(trimmed)) return "Image";
37688
37745
  if (!trimmed) return null;
37746
+ if (trimmed.startsWith("(no lines in range")) return "0 lines";
37689
37747
  const n = text.split("\n").length;
37690
37748
  return `${n} ${pluralize(n, "line")}`;
37691
37749
  }
@@ -39661,41 +39719,9 @@ function normalizeCountMap(value = {}) {
39661
39719
  return out;
39662
39720
  }
39663
39721
 
39664
- // src/runtime/shared/tool-status.mjs
39665
- function normalizeToolTerminalStatus(value) {
39666
- const raw = String(value || "").trim().toLowerCase();
39667
- if (!raw) return "";
39668
- if (/^(running|pending|queued|in_progress|in-progress)$/.test(raw)) return "running";
39669
- if (/^(completed|complete|done|success|succeeded|ok)$/.test(raw)) return "completed";
39670
- if (/^(failed|fail|error|errored|timeout|timed_out|killed)$/.test(raw)) return "failed";
39671
- if (/^(cancelled|canceled|cancel|cancel[-_ ]unconfirmed|cancel[-_ ]pending|cancelling|canceling)$/.test(raw))
39672
- return "cancelled";
39673
- if (/^(denied|deny|refused|rejected)$/.test(raw)) return "denied";
39674
- return "";
39675
- }
39676
- function toolResultTerminalStatus(text) {
39677
- const body = String(text || "");
39678
- const tagged = body.match(/<status[^>]*>([\s\S]*?)<\/status>/i)?.[1]?.trim();
39679
- if (tagged) return normalizeToolTerminalStatus(tagged);
39680
- const bracketed = body.match(/^\[status:\s*([^\]]*)\]/im)?.[1]?.trim();
39681
- if (bracketed) return normalizeToolTerminalStatus(bracketed);
39682
- const inline = body.match(/^(?:status|state):\s*([^\s·,;]+)/im)?.[1]?.trim();
39683
- const fromInline = normalizeToolTerminalStatus(inline);
39684
- if (fromInline) return fromInline;
39685
- const trimmed = body.trim();
39686
- if (/^(?:cancelled|canceled)$/i.test(trimmed)) return "cancelled";
39687
- if (/^(?:interrupted by (?:user|process restart)|tool execution aborted|\[tool execution was interrupted\])$/i.test(
39688
- trimmed
39689
- )) {
39690
- return "cancelled";
39691
- }
39692
- if (/^the user doesn't want to proceed with this tool use\b/i.test(trimmed)) return "cancelled";
39693
- return "";
39694
- }
39695
-
39696
39722
  // src/runtime/shared/tool-card-model/terminal-status.mjs
39697
39723
  function shellResultStatus(value) {
39698
- const match = String(value || "").match(
39724
+ const match = leadingResultBlock(value).match(
39699
39725
  /(?:^|\b)status:\s*(running|pending|queued|completed|failed|cancelled|canceled)\b/im
39700
39726
  );
39701
39727
  return match ? String(match[1] || "").toLowerCase() : "";
@@ -39730,6 +39756,7 @@ var TERMINAL_STATUS_LABELS = /* @__PURE__ */ new Map([
39730
39756
  ["cancelled", "Cancelled"],
39731
39757
  ["denied", "Denied"]
39732
39758
  ]);
39759
+ var BARE_STATUS_WORDS = new Set([...TERMINAL_STATUS_LABELS.values()].map((label) => label.toLowerCase()));
39733
39760
  function displayTerminalStatus(value) {
39734
39761
  if (String(value || "").trim().toLowerCase() === "exit")
39735
39762
  return "Exited";
@@ -39772,6 +39799,7 @@ function mergeTerminalDetail(status, detail = "") {
39772
39799
  if (label === "Finished" && text) return text;
39773
39800
  if (!text) return label;
39774
39801
  if (text.toLowerCase().startsWith(label.toLowerCase())) return text;
39802
+ if (BARE_STATUS_WORDS.has(text.toLowerCase())) return label;
39775
39803
  return `${label} \xB7 ${text}`;
39776
39804
  }
39777
39805
 
@@ -40275,9 +40303,10 @@ function deriveCardStatus(base, { normalizedName, parsedArgs, isShellSurface },
40275
40303
  parsedArgs
40276
40304
  );
40277
40305
  const agentCompletionDetail = !pending && isAgentTool(normalizedName) && !agentHeaderFailure ? agentTerminalDetail(parsedArgs?.status, isError, elapsed, parsedArgs?.error) : "";
40278
- const gitFailed = normalizedName === "git" && (gitResultExitCode(display.displayedResultText) !== null || Boolean(gitResultError(display.displayedResultText)));
40279
- const failedOrCompleted = isError || failedCount > 0 || gitFailed ? "failed" : "completed";
40280
- const terminalStatus = pending ? "running" : shellStatus || normalizeTerminalStatus(display.backgroundMeta?.status) || normalizeTerminalStatus(parsedArgs?.status) || resultTerminalStatus(display.displayedResultText) || failedOrCompleted;
40306
+ const gitStatus = normalizedName === "git" ? gitTerminalStatus(display.displayedResultText) : "";
40307
+ const failedOrCompleted = isError || failedCount > 0 ? "failed" : "completed";
40308
+ const terminalStatus = pending ? "running" : shellStatus || gitStatus || normalizeTerminalStatus(display.backgroundMeta?.status) || normalizeTerminalStatus(parsedArgs?.status) || resultTerminalStatus(display.displayedResultText) || // A one-line error body is hidden from display, so read the raw result.
40309
+ (isUserControlCancellation(base.rt) ? "cancelled" : "") || failedOrCompleted;
40281
40310
  return {
40282
40311
  shellStatus,
40283
40312
  shellElapsed,
@@ -47659,7 +47688,7 @@ function projectLitellmRow(row) {
47659
47688
  if (typeof value === "number" && Number.isFinite(value)) out[field] = value;
47660
47689
  }
47661
47690
  for (const [field, value] of Object.entries(row)) {
47662
- if (/^(?:input_cost_per_token|output_cost_per_token|cache_read_input_token_cost|cache_creation_input_token_cost)_above_\d+k_tokens$/.test(
47691
+ if (/^(?:input_cost_per_token|output_cost_per_token|cache_read_input_token_cost|cache_creation_input_token_cost)(?:_above_\d+k_tokens)?(?:_priority)?$/.test(
47663
47692
  field
47664
47693
  ) && typeof value === "number" && Number.isFinite(value))
47665
47694
  out[field] = value;
@@ -47803,6 +47832,28 @@ var PRICED_VARIANTS = Object.freeze({
47803
47832
  "grok-4.7-build-fast": Object.freeze({ base: "grok-4.7", rateMultiplier: 2 })
47804
47833
  })
47805
47834
  });
47835
+ var CURSOR_PRICING = Object.freeze({
47836
+ "composer-2.5": {
47837
+ inputCostPerM: 0.5,
47838
+ cacheReadCostPerM: 0.2,
47839
+ outputCostPerM: 2.5,
47840
+ fast: { inputCostPerM: 3, cacheReadCostPerM: 0.5, outputCostPerM: 15 }
47841
+ },
47842
+ "grok-4.7": {
47843
+ fast: {
47844
+ inputCostPerM: 4,
47845
+ cacheReadCostPerM: 1,
47846
+ outputCostPerM: 12,
47847
+ // Fast long context (>256k input) bills at 3x the standard rates.
47848
+ pricingTiers: [{ aboveInputTokens: 256e3, inputCostPerM: 6, cacheReadCostPerM: 1.5, outputCostPerM: 18 }]
47849
+ }
47850
+ },
47851
+ "grok-4.6": { fast: { inputCostPerM: 4, cacheReadCostPerM: 1, outputCostPerM: 12 } },
47852
+ "grok-4.5": { fast: { inputCostPerM: 4, cacheReadCostPerM: 1, outputCostPerM: 18 } },
47853
+ "claude-opus-4-7": {
47854
+ fast: { inputCostPerM: 30, cacheWriteCostPerM: 37.5, cacheReadCostPerM: 3, outputCostPerM: 150 }
47855
+ }
47856
+ });
47806
47857
 
47807
47858
  // src/runtime/shared/statusline/statusline-format.mjs
47808
47859
  var statusText = rgb(198, 198, 198);
@@ -49,16 +49,22 @@ export function createSessionSettingsApi(bag) {
49
49
  },
50
50
  { busyResult: false, onRelease: flushEmitImmediate }
51
51
  ),
52
- setFast: withCommandLock(async (value) => {
53
- const enabled = await runtime.setFast(value);
54
- set({ ...routeState() });
55
- return enabled;
56
- }),
57
- toggleFast: withCommandLock(async () => {
58
- const enabled = await runtime.toggleFast();
59
- set({ ...routeState() });
60
- return enabled;
61
- }),
52
+ setFast: withCommandLock(
53
+ async (value) => {
54
+ const enabled = await runtime.setFast(value);
55
+ set({ ...routeState() });
56
+ return enabled;
57
+ },
58
+ { onRelease: flushEmitImmediate }
59
+ ),
60
+ toggleFast: withCommandLock(
61
+ async () => {
62
+ const enabled = await runtime.toggleFast();
63
+ set({ ...routeState() });
64
+ return enabled;
65
+ },
66
+ { onRelease: flushEmitImmediate }
67
+ ),
62
68
  setToolMode: (m) => {
63
69
  void runtime
64
70
  .setToolMode(m)
@@ -478,11 +478,16 @@ function promptFootprintTokens(provider, usage) {
478
478
  return isInclusiveProvider(provider) ? input : input + cacheRead + cacheWrite;
479
479
  }
480
480
 
481
- function usageCostUsd(routeInfo, usage) {
481
+ function usageCostUsd(routeInfo, providerOut) {
482
+ const usage = providerOut?.usage || {};
482
483
  if (Number.isFinite(Number(usage?.costUsd))) return round(Number(usage.costUsd), 6);
483
484
  return computeCostUsd({
484
485
  provider: routeInfo?.provider,
485
486
  model: routeInfo?.model,
487
+ pricingModel: providerOut?.pricingModel,
488
+ kind: routeInfo?.providerKind || providerKind(routeInfo?.provider),
489
+ requestServiceTier: providerOut?.requestServiceTier,
490
+ serviceTier: cleanString(providerOut?.serviceTier) || cleanString(usage?.raw?.service_tier) || undefined,
486
491
  inputTokens: num(usage?.inputTokens, 0),
487
492
  outputTokens: num(usage?.outputTokens, 0),
488
493
  cacheReadTokens: num(usage?.cachedTokens ?? usage?.cacheReadTokens, 0),
@@ -516,7 +521,7 @@ export function summarizeGatewayUsage(routeInfo, providerOut, compact = null, du
516
521
  contextUsedPct = Math.min(100, round(promptTokens * 100 / boundaryTokens, 2));
517
522
  }
518
523
  }
519
- const costUsd = usageCostUsd(routeInfo, u);
524
+ const costUsd = usageCostUsd(routeInfo, providerOut);
520
525
  const usageCompact = compact && typeof compact === 'object' ? { ...compact } : compact;
521
526
  return {
522
527
  at: Date.now(),