@danypops/jittor 0.5.0 → 0.6.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.
@@ -15,11 +15,16 @@ import {
15
15
  import { CodexRecoveryPolicy, classifyCodexFailure, type CodexFailureKind, type CodexFailureMetadata } from "../../src/domain/codex-recovery.ts";
16
16
  import { CompactionTelemetry, papyrusContextMetric, validatePapyrusContextInjection } from "../../src/domain/context-telemetry.ts";
17
17
  import type { MetricObservation, StoredMetricObservation } from "../../src/domain/metric.ts";
18
+ import { classifyTaskFromTools, modelRunMetrics, TASK_CLASSES, type ModelRunObservation, type ModelTaskClass } from "../../src/domain/model-observation.ts";
19
+ import type { ModelCandidate } from "../../src/domain/model-ranking.ts";
18
20
  import { USAGE_PERIODS, type UsagePeriod } from "../../src/domain/usage.ts";
19
21
  import type { PolicyDecision, Route } from "../../src/policy.ts";
20
22
  import type { RouterStatus } from "../../src/ports/router-controller.ts";
23
+ import { hasAnthropicRateLimitHeaders, parseAnthropicRateLimitHeaders } from "../../src/providers/anthropic-contracts.ts";
21
24
  import { parseCodexRateLimitHeaders } from "../../src/providers/codex.ts";
22
- import { installIntegratedFooter, type IntegratedFooterState } from "./footer.ts";
25
+ import { classifyGoogleVertexFailure, googleVertexFailureMetrics, type GoogleVertexFailureMetadata } from "../../src/providers/google-vertex-contracts.ts";
26
+ import { showBenchmarkPanel } from "./benchmark-tui.ts";
27
+ import { installIntegratedFooter, type CompactionProgress, type IntegratedFooterState } from "./footer.ts";
23
28
  import { callJittor } from "./service-client.ts";
24
29
  import { persistentEnforcementControl, type CodexRecoveryControl, type EnforcementControl, type UsageBudgetControl } from "./settings.ts";
25
30
  import { showSettingsPanel } from "./settings-tui.ts";
@@ -83,6 +88,16 @@ async function recordMetrics(client: JittorExtensionClient, metrics: MetricObser
83
88
  for (const metric of metrics) await client.call("metrics.record", metric);
84
89
  }
85
90
 
91
+ interface ActiveLocalModelRun {
92
+ runId: string;
93
+ startedAt: number;
94
+ firstTokenAt: number | null;
95
+ providerResponses: number;
96
+ toolNames: string[];
97
+ toolCalls: number;
98
+ toolFailures: number;
99
+ }
100
+
86
101
  async function refreshFooter(client: JittorExtensionClient, state: IntegratedFooterState): Promise<void> {
87
102
  const status = await client.call("router.status", {}) as RouterStatus;
88
103
  const provider = status.currentRoute?.provider;
@@ -139,6 +154,17 @@ function modelCost(model: PiRouteModel): number {
139
154
  return (model.cost?.input ?? 0) + (model.cost?.output ?? 0);
140
155
  }
141
156
 
157
+ export function benchmarkCandidatesFromPi(models: PiRouteModel[], thinking: string): ModelCandidate[] {
158
+ const candidates: ModelCandidate[] = [];
159
+ for (const model of models) {
160
+ if (!model.provider || !model.id || candidates.some((candidate) => candidate.provider === model.provider && candidate.model === model.id)) continue;
161
+ const level = supportsThinking(model, thinking) ? thinking : "off";
162
+ candidates.push({ provider: model.provider, model: model.id, thinking: level });
163
+ if (candidates.length >= MAX_DYNAMIC_ROUTES) break;
164
+ }
165
+ return candidates;
166
+ }
167
+
142
168
  export function routesFromPi(models: PiRouteModel[], current: PiRouteModel, thinking: string): Route[] {
143
169
  const sameProvider = models
144
170
  .filter((model) => model.provider === current.provider)
@@ -231,6 +257,9 @@ export function registerJittorExtension(
231
257
  const footerState: IntegratedFooterState = { providerBudget: null };
232
258
  const usageBudgets = usageBudgetControl(enforcement);
233
259
  let compactionTelemetry = new CompactionTelemetry();
260
+ let localRunSequence = 0;
261
+ let activeLocalRun: ActiveLocalModelRun | undefined;
262
+ let lastCompletedLocalRun: ModelRunObservation | undefined;
234
263
  const contextObservations = new Set<string>();
235
264
  const stopPapyrusContext = pi.events?.on?.(PAPYRUS_CONTEXT_INJECTION_CHANNEL, (payload) => {
236
265
  try {
@@ -255,6 +284,7 @@ export function registerJittorExtension(
255
284
  let recoveryTimer: unknown;
256
285
  let recoveryCooldown: { until: number; attempt: number; failureKind: CodexFailureKind } | undefined;
257
286
  let lastCodexResponse: CodexFailureMetadata = {};
287
+ let lastGoogleVertexResponse: GoogleVertexFailureMetadata = {};
258
288
  const cancelRecovery = (resetPolicy: boolean): void => {
259
289
  if (recoveryTimer !== undefined) recoveryRuntime.clearTimeout(recoveryTimer);
260
290
  recoveryTimer = undefined;
@@ -314,10 +344,21 @@ export function registerJittorExtension(
314
344
  const beginCompactionUi = (ctx: ExtensionContext, signal: AbortSignal): void => {
315
345
  finishCompactionUi();
316
346
  const usage = ctx.getContextUsage();
317
- footerState.compaction = {
347
+ const compaction: CompactionProgress = {
318
348
  startedAt: Date.now(),
319
349
  initialFraction: usage?.percent === null || usage?.percent === undefined ? 1 : usage.percent / 100,
350
+ estimatedMs: null,
351
+ confidence: "cold-start",
320
352
  };
353
+ footerState.compaction = compaction;
354
+ // Non-blocking: compaction UI starts immediately as cold-start; if a learned estimate resolves
355
+ // before this compaction finishes (and this is still the active compaction, not a later one),
356
+ // upgrade the same progress object in place so the drain bar and status text switch to "learned".
357
+ void client.call("compaction.estimate", {}).then((estimate) => {
358
+ if (footerState.compaction !== compaction || estimate.confidence !== "learned" || estimate.ms === null) return;
359
+ footerState.compaction = { ...compaction, estimatedMs: estimate.ms, confidence: "learned" };
360
+ footerState.requestRender?.();
361
+ }).catch(() => undefined);
321
362
  compactionTimer = setInterval(() => footerState.requestRender?.(), FOOTER_COMPACTION_RENDER_INTERVAL_MS);
322
363
  signal.addEventListener("abort", finishCompactionUi, { once: true });
323
364
  if (signal.aborted) finishCompactionUi();
@@ -353,9 +394,50 @@ export function registerJittorExtension(
353
394
  };
354
395
 
355
396
  pi.registerCommand("jittor", {
356
- description: "Inspect or control Jittor routing, budgets, and usage",
397
+ description: "Jittor settings, routing status, benchmarks, and Codex recovery controls",
357
398
  handler: async (args, ctx) => {
358
399
  const action = args.trim().toLowerCase();
400
+ if (action === "" || action === "settings") {
401
+ await showSettingsPanel(ctx, enforcement, codexRecovery, usageBudgets, {
402
+ setEnforcement: async (enabled) => enabled ? enable(ctx) : disable(ctx),
403
+ setFooter: async (enabled) => {
404
+ enforcement.setFooterEnabled(enabled);
405
+ showFooter(ctx);
406
+ if (enabled) await refreshFooter(client, footerState).catch(() => undefined);
407
+ },
408
+ setRecovery: (enabled) => {
409
+ if (!enabled) cancelRecovery(true);
410
+ codexRecovery.setCodexRecoveryEnabled(enabled);
411
+ },
412
+ });
413
+ return;
414
+ }
415
+ if (action === "benchmarks" || action.startsWith("benchmarks ")) {
416
+ if (!ctx.model) {
417
+ ctx.ui.notify("No active Pi model is available for benchmark recommendations.", "warning");
418
+ return;
419
+ }
420
+ const requestedTask = action.split(/\s+/)[1] ?? "general";
421
+ if (!TASK_CLASSES.includes(requestedTask as ModelTaskClass)) {
422
+ ctx.ui.notify("Usage: /jittor benchmarks [coding|research|planning|general]", "warning");
423
+ return;
424
+ }
425
+ const candidates = benchmarkCandidatesFromPi(ctx.modelRegistry.getAvailable() as PiRouteModel[], pi.getThinkingLevel());
426
+ await showBenchmarkPanel(ctx, client, candidates, `${ctx.model.provider}/${ctx.model.id}`, requestedTask as ModelTaskClass);
427
+ return;
428
+ }
429
+ if (action === "outcome accepted" || action === "outcome rejected") {
430
+ if (!lastCompletedLocalRun) {
431
+ ctx.ui.notify("No completed local model run is available for an explicit outcome.", "warning");
432
+ return;
433
+ }
434
+ const explicitOutcome = action.endsWith("accepted") ? "accepted" as const : "rejected" as const;
435
+ const outcomeMetric = modelRunMetrics({ ...lastCompletedLocalRun, explicitOutcome }).find((metric) => metric.metric === "outcome-accepted")!;
436
+ outcomeMetric.observedAt = Date.now();
437
+ await recordMetrics(client, [outcomeMetric]);
438
+ ctx.ui.notify(`Recorded explicit ${explicitOutcome} outcome for the latest local model run.`, "info");
439
+ return;
440
+ }
359
441
  if (action === "recovery" || action === "recovery status") {
360
442
  ctx.ui.notify(recoveryStatusText(), "info");
361
443
  return;
@@ -403,23 +485,22 @@ export function registerJittorExtension(
403
485
  ].join("\n"), "info");
404
486
  return;
405
487
  }
406
- if (action === "settings") {
407
- await showSettingsPanel(ctx, enforcement, codexRecovery, usageBudgets, {
408
- setEnforcement: async (enabled) => enabled ? enable(ctx) : disable(ctx),
409
- setFooter: async (enabled) => {
410
- enforcement.setFooterEnabled(enabled);
411
- showFooter(ctx);
412
- if (enabled) await refreshFooter(client, footerState).catch(() => undefined);
413
- },
414
- setRecovery: (enabled) => {
415
- if (!enabled) cancelRecovery(true);
416
- codexRecovery.setCodexRecoveryEnabled(enabled);
417
- },
418
- });
488
+ // Reached only for the explicit "status" keyword or any other unrecognized text; bare "" is
489
+ // handled above by the settings branch, so this always has a non-empty, non-settings action.
490
+ if (!enforcement.isEnabled()) {
491
+ ctx.ui.notify("Jittor is monitor-only. Run /jittor on to re-enable blocking.", "info");
419
492
  return;
420
493
  }
421
- if (action === "usage budget" || action.startsWith("usage budget ")) {
422
- const [, , periodText, valueText] = action.split(/\s+/);
494
+ await showJittorPanel(ctx, client);
495
+ },
496
+ });
497
+
498
+ pi.registerCommand("usage", {
499
+ description: "Cumulative token/cost usage graph with hourly/daily/weekly/monthly/quarterly views",
500
+ handler: async (args, ctx) => {
501
+ const action = args.trim().toLowerCase();
502
+ if (action === "budget" || action.startsWith("budget ")) {
503
+ const [, periodText, valueText] = action.split(/\s+/);
423
504
  const period = USAGE_PERIODS.some((candidate) => candidate.id === periodText) ? periodText as UsagePeriod : undefined;
424
505
  if (!period) {
425
506
  const values = USAGE_PERIODS.map(({ id, label }) => `${label}: ${usageBudgets.getUsageTokenBudget(id)?.toLocaleString() ?? "not configured"}`).join(" · ");
@@ -437,30 +518,29 @@ export function registerJittorExtension(
437
518
  }
438
519
  const tokens = Number(valueText.replaceAll(",", ""));
439
520
  if (!Number.isFinite(tokens) || tokens <= 0) {
440
- ctx.ui.notify("Usage: /jittor usage budget <hourly|daily|weekly|monthly> <positive-tokens|off>", "warning");
521
+ ctx.ui.notify("Usage: /usage budget <hourly|daily|weekly|monthly|quarterly> <positive-tokens|off>", "warning");
441
522
  return;
442
523
  }
443
524
  usageBudgets.setUsageTokenBudget(period, tokens);
444
525
  ctx.ui.notify(`${USAGE_PERIODS.find((candidate) => candidate.id === period)!.label} token budget set to ${tokens.toLocaleString()} tokens.`, "info");
445
526
  return;
446
527
  }
447
- if (action === "usage") {
448
- await showUsagePanel(ctx, client, usageBudgets);
528
+ if (action !== "" && action !== "cost" && action !== "tokens") {
529
+ ctx.ui.notify("Usage: /usage [cost] | /usage budget <hourly|daily|weekly|monthly|quarterly> <positive-tokens|off>", "warning");
449
530
  return;
450
531
  }
451
- if (!enforcement.isEnabled()) {
452
- ctx.ui.notify("Jittor is monitor-only. Run /jittor on to re-enable blocking.", "info");
453
- return;
454
- }
455
- await showJittorPanel(ctx, client);
532
+ await showUsagePanel(ctx, client, usageBudgets, Date.now(), action === "cost" ? "cost" : "tokens");
456
533
  },
457
534
  });
458
535
 
459
536
  pi.on("session_start", async (_event, ctx) => {
460
537
  finishCompactionUi();
461
538
  compactionTelemetry = new CompactionTelemetry();
539
+ activeLocalRun = undefined;
540
+ lastCompletedLocalRun = undefined;
462
541
  cancelRecovery(true);
463
542
  lastCodexResponse = {};
543
+ lastGoogleVertexResponse = {};
464
544
  ctx.ui.setStatus("jittor", undefined);
465
545
  showFooter(ctx);
466
546
  try {
@@ -533,9 +613,19 @@ export function registerJittorExtension(
533
613
  await syncCurrentRoute(pi, client, ctx, ctx.model, event.level).catch(() => undefined);
534
614
  });
535
615
 
536
- pi.on("turn_start", async (_event, ctx) => {
616
+ pi.on("turn_start", async (event, ctx) => {
537
617
  compactionTelemetry.observeTurn();
538
618
  lastCodexResponse = {};
619
+ lastGoogleVertexResponse = {};
620
+ activeLocalRun = {
621
+ runId: `local-${event.timestamp}-${++localRunSequence}`,
622
+ startedAt: event.timestamp,
623
+ firstTokenAt: null,
624
+ providerResponses: 0,
625
+ toolNames: [],
626
+ toolCalls: 0,
627
+ toolFailures: 0,
628
+ };
539
629
  if (!enforcement.isEnabled()) return;
540
630
  try {
541
631
  await syncCurrentRoute(pi, client, ctx);
@@ -547,20 +637,84 @@ export function registerJittorExtension(
547
637
  }
548
638
  });
549
639
 
640
+ pi.on("message_update", async (event) => {
641
+ if (!activeLocalRun || activeLocalRun.firstTokenAt !== null) return;
642
+ if (["text_delta", "thinking_delta", "toolcall_delta"].includes(event.assistantMessageEvent.type)) activeLocalRun.firstTokenAt = Date.now();
643
+ });
644
+
645
+ pi.on("tool_execution_end", async (event) => {
646
+ if (!activeLocalRun) return;
647
+ activeLocalRun.toolCalls += 1;
648
+ if (event.isError) activeLocalRun.toolFailures += 1;
649
+ if (activeLocalRun.toolNames.length < 100) activeLocalRun.toolNames.push(event.toolName);
650
+ });
651
+
550
652
  pi.on("after_provider_response", async (event, ctx) => {
653
+ if (activeLocalRun) activeLocalRun.providerResponses += 1;
551
654
  if (ctx.model?.provider === "openai-codex") {
552
655
  lastCodexResponse = { status: event.status, ...(header(event.headers, "retry-after") ? { retryAfter: header(event.headers, "retry-after") } : {}) };
553
656
  }
554
- if (!Object.keys(event.headers).some((name) => name.toLowerCase().startsWith("x-codex-"))) return;
555
- try {
556
- const updates = parseCodexRateLimitHeaders(new Headers(event.headers), Date.now());
557
- await recordMetrics(client, updates.flatMap((update) => update.metrics));
558
- } catch {
559
- if (enforcement.isEnabled()) ctx.ui.notify(`Jittor detected Codex telemetry schema drift. ${RECOVERY_GUIDANCE}.`, "error");
657
+ if (ctx.model?.provider === "anthropic") {
658
+ const headers = new Headers(event.headers);
659
+ if (hasAnthropicRateLimitHeaders(headers)) {
660
+ try {
661
+ await recordMetrics(client, parseAnthropicRateLimitHeaders(headers, Date.now()).metrics);
662
+ } catch {
663
+ if (enforcement.isEnabled()) ctx.ui.notify(`Jittor detected Anthropic telemetry schema drift. ${RECOVERY_GUIDANCE}.`, "error");
664
+ }
665
+ }
666
+ }
667
+ if (ctx.model?.provider === "google-vertex") {
668
+ lastGoogleVertexResponse = { status: event.status, ...(header(event.headers, "retry-after") ? { retryAfter: header(event.headers, "retry-after") } : {}) };
669
+ }
670
+ if (Object.keys(event.headers).some((name) => name.toLowerCase().startsWith("x-codex-"))) {
671
+ try {
672
+ const updates = parseCodexRateLimitHeaders(new Headers(event.headers), Date.now());
673
+ await recordMetrics(client, updates.flatMap((update) => update.metrics));
674
+ } catch {
675
+ if (enforcement.isEnabled()) ctx.ui.notify(`Jittor detected Codex telemetry schema drift. ${RECOVERY_GUIDANCE}.`, "error");
676
+ }
560
677
  }
561
678
  if (enforcement.isFooterEnabled()) await refreshFooter(client, footerState).catch(() => undefined);
562
679
  });
563
680
 
681
+ pi.on("turn_end", async (event) => {
682
+ const active = activeLocalRun;
683
+ activeLocalRun = undefined;
684
+ const message = event.message as unknown;
685
+ if (!active || typeof message !== "object" || message === null || Array.isArray(message)) return;
686
+ const value = message as Record<string, unknown>;
687
+ if (value["role"] !== "assistant" || typeof value["provider"] !== "string" || typeof value["model"] !== "string") return;
688
+ const usage = typeof value["usage"] === "object" && value["usage"] !== null ? value["usage"] as Record<string, unknown> : {};
689
+ const amount = (name: string): number => typeof usage[name] === "number" && Number.isFinite(usage[name]) ? usage[name] as number : 0;
690
+ const cost = typeof usage["cost"] === "object" && usage["cost"] !== null && typeof (usage["cost"] as Record<string, unknown>)["total"] === "number"
691
+ ? (usage["cost"] as Record<string, number>)["total"] ?? 0 : 0;
692
+ const stopReason = ["stop", "length", "toolUse", "error", "aborted"].includes(String(value["stopReason"]))
693
+ ? value["stopReason"] as ModelRunObservation["stopReason"] : "unknown";
694
+ const completedAt = Math.max(Date.now(), active.firstTokenAt ?? active.startedAt, active.startedAt);
695
+ lastCompletedLocalRun = {
696
+ runId: active.runId,
697
+ provider: value["provider"],
698
+ model: value["model"],
699
+ thinking: pi.getThinkingLevel(),
700
+ taskClass: classifyTaskFromTools(active.toolNames),
701
+ startedAt: active.startedAt,
702
+ firstTokenAt: active.firstTokenAt,
703
+ completedAt,
704
+ inputTokens: amount("input"),
705
+ outputTokens: amount("output"),
706
+ cacheReadTokens: amount("cacheRead"),
707
+ cacheWriteTokens: amount("cacheWrite"),
708
+ costUsd: Number.isFinite(cost) && cost >= 0 ? cost : 0,
709
+ providerResponses: Math.max(1, active.providerResponses),
710
+ toolCalls: active.toolCalls,
711
+ toolFailures: active.toolFailures,
712
+ stopReason,
713
+ explicitOutcome: "unknown",
714
+ };
715
+ await recordMetrics(client, modelRunMetrics(lastCompletedLocalRun)).catch(() => undefined);
716
+ });
717
+
564
718
  pi.on("message_end", async (event, _ctx) => {
565
719
  if (event.message.role === "assistant" && event.message.provider === "openai-codex") {
566
720
  if (event.message.stopReason === "error") {
@@ -572,6 +726,13 @@ export function registerJittorExtension(
572
726
  }
573
727
  lastCodexResponse = {};
574
728
  }
729
+ if (event.message.role === "assistant" && event.message.provider === "google-vertex") {
730
+ if (event.message.stopReason === "error") {
731
+ const failure = classifyGoogleVertexFailure(event.message.errorMessage, lastGoogleVertexResponse);
732
+ await recordMetrics(client, googleVertexFailureMetrics(failure, Date.now())).catch(() => undefined);
733
+ }
734
+ lastGoogleVertexResponse = {};
735
+ }
575
736
  const metrics = assistantUsageMetrics(event.message, Date.now());
576
737
  if (metrics.length > 0) {
577
738
  const amount = (name: string): number => metrics.filter((metric) => metric.metric === name && typeof metric.value === "number").reduce((sum, metric) => sum + (metric.value ?? 0), 0);
@@ -587,6 +748,8 @@ export function registerJittorExtension(
587
748
  stopPapyrusContext?.();
588
749
  cancelRecovery(true);
589
750
  lastCodexResponse = {};
751
+ activeLocalRun = undefined;
752
+ lastCompletedLocalRun = undefined;
590
753
  ctx.ui.setStatus("jittor", undefined);
591
754
  ctx.ui.setFooter(undefined);
592
755
  });
@@ -1,5 +1,6 @@
1
1
  import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
2
2
  import { matchesKey, truncateToWidth } from "@earendil-works/pi-tui";
3
+ import { HUMAN_STATUS_MAX_SOURCES, HUMAN_TEXT_FIELD_MAX_CHARACTERS } from "../../src/constants.ts";
3
4
  import type { StoredMetricObservation } from "../../src/domain/metric.ts";
4
5
  import type { PolicyAction, Route } from "../../src/policy.ts";
5
6
  import type { RouterStatus } from "../../src/ports/router-controller.ts";
@@ -16,7 +17,11 @@ function latest(rows: StoredMetricObservation[], predicate: (row: StoredMetricOb
16
17
  }
17
18
 
18
19
  function sanitizedText(value: string): string {
19
- return value.replace(/[\r\n\t]/g, " ").replace(/ +/g, " ").trim();
20
+ return value.replace(/[\r\n\t]/g, " ").replace(/ +/g, " ").trim().slice(0, HUMAN_TEXT_FIELD_MAX_CHARACTERS);
21
+ }
22
+
23
+ function routeText(route: Route): string {
24
+ return `${sanitizedText(route.provider)}/${sanitizedText(route.model)} · ${sanitizedText(route.thinking)}`;
20
25
  }
21
26
 
22
27
  function normalizedIdentity(value: unknown): string {
@@ -72,6 +77,19 @@ export function buildFooterBudget(status: RouterStatus, metrics: StoredMetricObs
72
77
  ...(Number.isFinite(resetsAtSeconds) && resetsAtSeconds > 0 ? { resetsAt: resetsAtSeconds * 1_000 } : {}),
73
78
  };
74
79
  }
80
+ if (status.currentRoute.provider === "anthropic") {
81
+ const anthropic = latest(metrics, (row) => row.source === "anthropic" && row.metric === "used-fraction" && row.scope === "tokens" && typeof row.value === "number")
82
+ ?? latest(metrics, (row) => row.source === "anthropic" && row.metric === "used-fraction" && row.scope === "requests" && typeof row.value === "number");
83
+ if (!anthropic || typeof anthropic.value !== "number") return null;
84
+ const resetsAt = Number(anthropic.attributes["resetsAt"]);
85
+ return {
86
+ kind: "bounded",
87
+ label: anthropic.scope === "tokens" ? "tok" : "req",
88
+ remainingFraction: 1 - anthropic.value,
89
+ observedAt: anthropic.observedAt,
90
+ ...(Number.isFinite(resetsAt) && resetsAt > 0 ? { resetsAt } : {}),
91
+ };
92
+ }
75
93
  if (status.currentRoute.provider === "openrouter") {
76
94
  const openRouter = latest(metrics, (row) => row.source === "openrouter" && row.metric === "usage" && typeof row.value === "number");
77
95
  const remaining = latest(metrics, (row) => row.source === "openrouter" && row.metric === "remaining-fraction" && typeof row.value === "number");
@@ -135,15 +153,22 @@ export function buildStatusView(status: RouterStatus, metrics: StoredMetricObser
135
153
  ? latest(metrics, (row) => row.source === "openrouter" && row.metric === "usage" && typeof row.value === "number")
136
154
  : undefined;
137
155
  if (openRouter && typeof openRouter.value === "number") lines.push(`OpenRouter spend: $${openRouter.value.toFixed(3)}`);
138
- if (status.currentRoute) lines.push(`Route: ${status.currentRoute.provider}/${status.currentRoute.model} · ${status.currentRoute.thinking}`);
156
+ const anthropic = status.currentRoute?.provider === "anthropic"
157
+ ? latest(metrics, (row) => row.source === "anthropic" && row.metric === "used-fraction" && row.scope === "tokens" && typeof row.value === "number")
158
+ ?? latest(metrics, (row) => row.source === "anthropic" && row.metric === "used-fraction" && row.scope === "requests" && typeof row.value === "number")
159
+ : undefined;
160
+ if (anthropic && typeof anthropic.value === "number") lines.push(`Anthropic ${anthropic.scope}: ${((1 - anthropic.value) * 100).toFixed(1)}% left`);
161
+ if (status.currentRoute) lines.push(`Route: ${routeText(status.currentRoute)}`);
139
162
  if (status.lastDecision) lines.push(`Pressure: ${Number.isFinite(status.lastDecision.pressure) ? status.lastDecision.pressure.toFixed(3) : "∞"} · ${status.lastDecision.action}`);
140
163
  lines.push(`Next: ${nextAction(status.lastDecision?.action)}`);
141
164
  lines.push("Telemetry:");
142
- for (const source of status.sources.filter((source) => source.provider === status.currentRoute?.provider)) {
165
+ const providerSources = status.sources.filter((source) => source.provider === status.currentRoute?.provider);
166
+ for (const source of providerSources.slice(0, HUMAN_STATUS_MAX_SOURCES)) {
143
167
  const freshness = !source.ok ? "failed" : source.observedAt !== undefined && now - source.observedAt > 120_000 ? "stale" : "fresh";
144
- lines.push(` ${source.id}: ${freshness} · ${source.metrics} metrics`);
168
+ lines.push(` ${sanitizedText(source.id)}: ${freshness} · ${source.metrics} metrics`);
145
169
  }
146
- if (status.override) lines.push(`Override: ${status.override.route.provider}/${status.override.route.model} · ${status.override.route.thinking}`);
170
+ if (providerSources.length > HUMAN_STATUS_MAX_SOURCES) lines.push(` ${providerSources.length - HUMAN_STATUS_MAX_SOURCES} more telemetry sources omitted`);
171
+ if (status.override) lines.push(`Override: ${routeText(status.override.route)}`);
147
172
  if (status.paused) lines.push("Emergency halt is active");
148
173
  return lines;
149
174
  }
@@ -160,7 +185,7 @@ async function snapshot(client: JittorPanelClient): Promise<{ status: RouterStat
160
185
 
161
186
  async function chooseOverride(ctx: ExtensionCommandContext, routes: Route[]): Promise<Route | undefined> {
162
187
  if (routes.length === 0) { ctx.ui.notify("Pi reports no authenticated routes for the current provider.", "warning"); return undefined; }
163
- const labels = routes.map((route) => `${route.provider}/${route.model} · ${route.thinking}`);
188
+ const labels = routes.map(routeText);
164
189
  const selected = await ctx.ui.select("Override route", labels);
165
190
  const index = selected ? labels.indexOf(selected) : -1;
166
191
  return index >= 0 ? routes[index] : undefined;
@@ -211,7 +236,7 @@ export async function showJittorPanel(ctx: ExtensionCommandContext, client: Jitt
211
236
  continue;
212
237
  }
213
238
  const route = await chooseOverride(ctx, current.status.availableRoutes);
214
- if (route && await ctx.ui.confirm("Apply route override?", `${route.provider}/${route.model} · ${route.thinking} for one hour`)) {
239
+ if (route && await ctx.ui.confirm("Apply route override?", `${routeText(route)} for one hour`)) {
215
240
  await client.call("router.override", { route, expiresAt: Date.now() + 60 * 60 * 1_000 });
216
241
  }
217
242
  }