@duetso/agent 0.3.23 → 0.3.25

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 (52) hide show
  1. package/README.md +10 -0
  2. package/dist/package.json +2 -2
  3. package/dist/src/cli/route.d.ts +4 -2
  4. package/dist/src/cli/route.d.ts.map +1 -1
  5. package/dist/src/cli/route.js +9 -16
  6. package/dist/src/cli/route.js.map +1 -1
  7. package/dist/src/cli/rpc.d.ts +5 -1
  8. package/dist/src/cli/rpc.d.ts.map +1 -1
  9. package/dist/src/cli/rpc.js +32 -2
  10. package/dist/src/cli/rpc.js.map +1 -1
  11. package/dist/src/model-resolution/model-gateway.d.ts +10 -0
  12. package/dist/src/model-resolution/model-gateway.d.ts.map +1 -1
  13. package/dist/src/model-resolution/model-gateway.js +30 -11
  14. package/dist/src/model-resolution/model-gateway.js.map +1 -1
  15. package/dist/src/model-resolution/resolver.d.ts +0 -2
  16. package/dist/src/model-resolution/resolver.d.ts.map +1 -1
  17. package/dist/src/model-resolution/resolver.js +0 -5
  18. package/dist/src/model-resolution/resolver.js.map +1 -1
  19. package/dist/src/model-routing/classifier.d.ts +71 -12
  20. package/dist/src/model-routing/classifier.d.ts.map +1 -1
  21. package/dist/src/model-routing/classifier.js +92 -13
  22. package/dist/src/model-routing/classifier.js.map +1 -1
  23. package/dist/src/model-routing/loader.d.ts.map +1 -1
  24. package/dist/src/model-routing/loader.js +15 -7
  25. package/dist/src/model-routing/loader.js.map +1 -1
  26. package/dist/src/model-routing/prompts.d.ts +16 -5
  27. package/dist/src/model-routing/prompts.d.ts.map +1 -1
  28. package/dist/src/model-routing/prompts.js +51 -5
  29. package/dist/src/model-routing/prompts.js.map +1 -1
  30. package/dist/src/model-routing/router.d.ts +15 -4
  31. package/dist/src/model-routing/router.d.ts.map +1 -1
  32. package/dist/src/model-routing/router.js +17 -1
  33. package/dist/src/model-routing/router.js.map +1 -1
  34. package/dist/src/model-routing/table.d.ts +16 -5
  35. package/dist/src/model-routing/table.d.ts.map +1 -1
  36. package/dist/src/model-routing/table.js +37 -16
  37. package/dist/src/model-routing/table.js.map +1 -1
  38. package/dist/src/tui/slash-commands.d.ts +1 -1
  39. package/dist/src/tui/slash-commands.d.ts.map +1 -1
  40. package/dist/src/tui/slash-commands.js +11 -2
  41. package/dist/src/tui/slash-commands.js.map +1 -1
  42. package/dist/src/turn-runner/turn-runner.d.ts +10 -3
  43. package/dist/src/turn-runner/turn-runner.d.ts.map +1 -1
  44. package/dist/src/turn-runner/turn-runner.js +34 -7
  45. package/dist/src/turn-runner/turn-runner.js.map +1 -1
  46. package/dist/src/turn-runner/usage-accounting.d.ts +11 -0
  47. package/dist/src/turn-runner/usage-accounting.d.ts.map +1 -1
  48. package/dist/src/turn-runner/usage-accounting.js +16 -0
  49. package/dist/src/turn-runner/usage-accounting.js.map +1 -1
  50. package/dist/src/types/protocol.d.ts +6 -1
  51. package/dist/src/types/protocol.d.ts.map +1 -1
  52. package/package.json +2 -2
@@ -1,5 +1,9 @@
1
- import type { ThinkingLevel, Usage } from "@earendil-works/pi-ai";
2
- import type { TierDefinition } from "./table.js";
1
+ import type { Usage } from "@earendil-works/pi-ai";
2
+ import { type Experimental_EvaluationModel, type Experimental_EvaluationResult } from "ai";
3
+ import * as structuredOutput from "../core/structured-output.js";
4
+ import type { TransportName } from "../model-resolution/catalog.js";
5
+ import { type ClassifierPath } from "./prompts.js";
6
+ import type { ClassifierTarget, TierDefinition } from "./table.js";
3
7
  /**
4
8
  * The runtime milestone that requested a classification. Owned here — where
5
9
  * the concept originates — and consumed by the router, the protocol event,
@@ -32,26 +36,81 @@ export interface ClassifierMessages {
32
36
  /** Tier rules plus the lean, request-specific routing facts. */
33
37
  prompt: string;
34
38
  }
35
- /** Options for the live structured-output route decision. */
39
+ /**
40
+ * Classification context the evaluation model judges. Null marks a hint the
41
+ * caller did not supply, so the model never reads a placeholder as content.
42
+ */
43
+ export type ClassifierState = {
44
+ trigger: RouteTrigger;
45
+ tier: string;
46
+ imagesPresent: boolean;
47
+ currentTarget: string | null;
48
+ previousTurnHint: string | null;
49
+ currentRequestOrLastStepDelta: string | null;
50
+ };
51
+ /** The single choice question: one option per route in the classified tier. */
52
+ export type ClassifierQuestions = {
53
+ route: {
54
+ type: "choice";
55
+ /** Route policy, administrator guidance, and cache-continuity framing. */
56
+ instructions: string;
57
+ /** Route name mapped to its administrator-authored description. */
58
+ criteria: Record<string, string>;
59
+ };
60
+ };
61
+ /** Pure evaluation request consumed by the evaluation-model classifier call. */
62
+ export interface ClassifierRequest {
63
+ state: ClassifierState;
64
+ questions: ClassifierQuestions;
65
+ }
66
+ /** Evaluation call seam; production binds the AI SDK's `experimental_evaluate`. */
67
+ export type ClassifierEvaluate = (call: ClassifierRequest & {
68
+ model: Experimental_EvaluationModel;
69
+ abortSignal?: AbortSignal;
70
+ }) => Promise<Pick<Experimental_EvaluationResult<ClassifierQuestions>, "answers" | "usage" | "providerMetadata">>;
71
+ /** Structured-output call seam; production binds `generateStructuredOutput`. */
72
+ export type ClassifierGenerate = typeof structuredOutput.generateStructuredOutput;
73
+ /** One attributed classifier call, shaped the same whichever path ran it. */
74
+ export interface ClassifierUsageReport {
75
+ /** Provider-specific model id the call billed under. */
76
+ modelId: string;
77
+ /** Backend that carried the call. */
78
+ transport: TransportName;
79
+ /** Priced usage; the evaluation path prices from the gateway's reported cost. */
80
+ usage: Usage;
81
+ }
82
+ /** Options for one live route decision, whichever classifier path the target selects. */
36
83
  export interface ClassifyRouteOptions {
37
- /** Classifier model reference resolved by the caller's composition layer. */
38
- model: string;
39
- /** Reasoning effort configured for the classifier target in the routing table. */
40
- thinkingLevel?: ThinkingLevel;
84
+ /** Classifier target from the routing table; its name selects the path. */
85
+ target: ClassifierTarget;
41
86
  /** Cancels the provider request when its owning turn is interrupted. */
42
87
  signal?: AbortSignal;
43
- /** Receives classifier token and cost usage for attribution. */
44
- onUsage?: (usage: Usage) => void;
88
+ /** Receives the attributed usage for this call. */
89
+ onUsage?: (report: ClassifierUsageReport) => void;
90
+ /** Evaluation-path network seam for deterministic tests. */
91
+ evaluate?: ClassifierEvaluate;
92
+ /** Chat-path network seam for deterministic tests. */
93
+ generate?: ClassifierGenerate;
45
94
  }
46
95
  /** A classifier choice that still names policy, not a concrete execution target. */
47
96
  export interface ClassifierDecision {
48
97
  /** Existing route name selected from the supplied tier. */
49
98
  route: string;
50
- /** One-sentence explanation returned by the classifier. */
51
- rationale: string;
99
+ /** One-sentence explanation, returned only by the chat classifier. */
100
+ rationale?: string;
101
+ /** Probability per route, returned only by an evaluation model that reports a distribution. */
102
+ probabilities?: Record<string, number>;
52
103
  }
53
- /** Build the complete lean classifier request without reading runtime state. */
104
+ /**
105
+ * Which path a classifier target selects, and the single owner of that
106
+ * decision: a name the concrete catalog knows runs the chat classifier,
107
+ * anything else is an AI Gateway evaluation-model id.
108
+ */
109
+ export declare function classifierPath(target: ClassifierTarget): ClassifierPath;
110
+ /** Build the complete lean chat-classifier prompts without reading runtime state. */
54
111
  export declare function buildClassifierMessages(input: ClassifierInput): ClassifierMessages;
112
+ /** Build the complete lean evaluation request without reading runtime state. */
113
+ export declare function buildClassifierRequest(input: ClassifierInput): ClassifierRequest;
55
114
  /** Classify one tier in one model call and reject any route outside that tier. */
56
115
  export declare function classifyRoute(input: ClassifierInput, options: ClassifyRouteOptions): Promise<ClassifierDecision>;
57
116
  //# sourceMappingURL=classifier.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"classifier.d.ts","sourceRoot":"","sources":["../../../src/model-routing/classifier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AASlE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAwBjD;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,cAAc,GAAG,YAAY,CAAC;AAEhG,8EAA8E;AAC9E,MAAM,WAAW,eAAe;IAC9B,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,IAAI,EAAE,cAAc,CAAC;IACrB,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qGAAqG;IACrG,SAAS,EAAE,OAAO,CAAC;IACnB,4FAA4F;IAC5F,OAAO,EAAE,YAAY,CAAC;CACvB;AAED,sFAAsF;AACtF,MAAM,WAAW,kBAAkB;IACjC,gCAAgC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,6DAA6D;AAC7D,MAAM,WAAW,oBAAoB;IACnC,6EAA6E;IAC7E,KAAK,EAAE,MAAM,CAAC;IACd,kFAAkF;IAClF,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,wEAAwE;IACxE,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,gEAAgE;IAChE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED,oFAAoF;AACpF,MAAM,WAAW,kBAAkB;IACjC,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;CACnB;AAUD,gFAAgF;AAChF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,eAAe,GAAG,kBAAkB,CAkBlF;AAED,kFAAkF;AAClF,wBAAsB,aAAa,CACjC,KAAK,EAAE,eAAe,EACtB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,kBAAkB,CAAC,CAiB7B"}
1
+ {"version":3,"file":"classifier.d.ts","sourceRoot":"","sources":["../../../src/model-routing/classifier.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,11 @@
1
+ import { experimental_evaluate, } from "ai";
1
2
  import dedent from "dedent";
2
3
  import { Type } from "typebox";
3
4
  import * as structuredOutput from "../core/structured-output.js";
4
- import { CLASSIFIER_SYSTEM_PROMPT, renderCacheContinuity, renderClassifierRules, } from "./prompts.js";
5
+ import { AI_GATEWAY_API_KEY_ENV, createDuetModelGateway, DUET_API_KEY_ENV, modelGatewayTransport, } from "../model-resolution/model-gateway.js";
6
+ import { resolveMeteredModelName, routingCatalogAdapter } from "../model-resolution/resolver.js";
7
+ import { usageFromGatewayReport } from "../turn-runner/usage-accounting.js";
8
+ import { CLASSIFIER_SYSTEM_PROMPT, renderCacheContinuity, renderClassifierInstructions, renderClassifierRules, } from "./prompts.js";
5
9
  const CONTEXT_HINT_LIMIT = 1_000;
6
10
  function classifierResultTool(routeNames) {
7
11
  return {
@@ -16,15 +20,26 @@ function classifierResultTool(routeNames) {
16
20
  }, { additionalProperties: false }),
17
21
  };
18
22
  }
19
- function boundedHint(value) {
23
+ /**
24
+ * Which path a classifier target selects, and the single owner of that
25
+ * decision: a name the concrete catalog knows runs the chat classifier,
26
+ * anything else is an AI Gateway evaluation-model id.
27
+ */
28
+ export function classifierPath(target) {
29
+ return routingCatalogAdapter.isCatalogName(target.modelName) ? "chat" : "evaluation";
30
+ }
31
+ function boundedText(value) {
20
32
  if (!value?.trim())
21
- return "Not provided.";
33
+ return null;
22
34
  const normalized = value.trim();
23
35
  return normalized.length <= CONTEXT_HINT_LIMIT
24
36
  ? normalized
25
37
  : `${normalized.slice(0, CONTEXT_HINT_LIMIT)}…`;
26
38
  }
27
- /** Build the complete lean classifier request without reading runtime state. */
39
+ function boundedHint(value) {
40
+ return boundedText(value) ?? "Not provided.";
41
+ }
42
+ /** Build the complete lean chat-classifier prompts without reading runtime state. */
28
43
  export function buildClassifierMessages(input) {
29
44
  const continuity = renderCacheContinuity(input.currentTarget);
30
45
  return {
@@ -43,21 +58,85 @@ export function buildClassifierMessages(input) {
43
58
  `,
44
59
  };
45
60
  }
46
- /** Classify one tier in one model call and reject any route outside that tier. */
47
- export async function classifyRoute(input, options) {
61
+ /** Build the complete lean evaluation request without reading runtime state. */
62
+ export function buildClassifierRequest(input) {
63
+ return {
64
+ state: {
65
+ trigger: input.trigger,
66
+ tier: input.tierName,
67
+ imagesPresent: input.hasImages,
68
+ currentTarget: input.currentTarget ?? null,
69
+ previousTurnHint: boundedText(input.prevTurnHint),
70
+ currentRequestOrLastStepDelta: boundedText(input.lastStepDelta),
71
+ },
72
+ questions: {
73
+ route: {
74
+ type: "choice",
75
+ instructions: renderClassifierInstructions(input.guidance, input.currentTarget),
76
+ criteria: Object.fromEntries(Object.entries(input.tier.routes).map(([name, rule]) => [name, rule.description])),
77
+ },
78
+ },
79
+ };
80
+ }
81
+ function gatewayCostUsd(providerMetadata) {
82
+ const cost = providerMetadata?.gateway?.cost;
83
+ const value = typeof cost === "string" || typeof cost === "number" ? Number(cost) : Number.NaN;
84
+ return Number.isFinite(value) ? value : undefined;
85
+ }
86
+ /** Route choice from a chat model, forced through the `select_route` tool. */
87
+ async function classifyWithChatModel(input, options) {
88
+ const model = resolveMeteredModelName(options.target.modelName);
48
89
  const messages = buildClassifierMessages(input);
49
- const result = await structuredOutput.generateStructuredOutput({
50
- model: options.model,
90
+ const generate = options.generate ?? structuredOutput.generateStructuredOutput;
91
+ return await generate({
92
+ model: `${model.provider}:${model.id}`,
51
93
  tool: classifierResultTool(Object.keys(input.tier.routes)),
52
94
  systemPrompt: messages.systemPrompt,
53
95
  prompt: messages.prompt,
54
- ...(options.thinkingLevel ? { callOptions: { reasoningEffort: options.thinkingLevel } } : {}),
96
+ ...(options.target.thinkingLevel
97
+ ? { callOptions: { reasoningEffort: options.target.thinkingLevel } }
98
+ : {}),
55
99
  signal: options.signal,
56
- onUsage: options.onUsage,
100
+ onUsage: (usage) => options.onUsage?.({
101
+ modelId: model.id,
102
+ transport: model.provider,
103
+ usage,
104
+ }),
105
+ });
106
+ }
107
+ /** Route choice from an AI Gateway evaluation model, with its probability distribution. */
108
+ async function classifyWithEvaluationModel(input, options) {
109
+ const transport = modelGatewayTransport();
110
+ if (!transport) {
111
+ throw new Error(`Route classification on evaluation model "${options.target.modelName}" needs an AI Gateway credential: set ${DUET_API_KEY_ENV} or ${AI_GATEWAY_API_KEY_ENV}.`);
112
+ }
113
+ const evaluate = options.evaluate ?? experimental_evaluate;
114
+ const result = await evaluate({
115
+ model: createDuetModelGateway().evaluationModel(options.target.modelName),
116
+ ...buildClassifierRequest(input),
117
+ abortSignal: options.signal,
57
118
  });
58
- if (!Object.hasOwn(input.tier.routes, result.route)) {
59
- throw new Error(`Classifier selected unknown route "${result.route}" for tier "${input.tierName}".`);
119
+ const costUsd = gatewayCostUsd(result.providerMetadata);
120
+ options.onUsage?.({
121
+ modelId: options.target.modelName,
122
+ transport,
123
+ usage: usageFromGatewayReport({
124
+ inputTokens: result.usage.inputTokens ?? 0,
125
+ outputTokens: result.usage.outputTokens ?? 0,
126
+ ...(costUsd === undefined ? {} : { costUsd }),
127
+ }),
128
+ });
129
+ const { choice, probabilities } = result.answers.route;
130
+ return { route: choice, ...(probabilities ? { probabilities } : {}) };
131
+ }
132
+ /** Classify one tier in one model call and reject any route outside that tier. */
133
+ export async function classifyRoute(input, options) {
134
+ const decision = classifierPath(options.target) === "chat"
135
+ ? await classifyWithChatModel(input, options)
136
+ : await classifyWithEvaluationModel(input, options);
137
+ if (!Object.hasOwn(input.tier.routes, decision.route)) {
138
+ throw new Error(`Classifier selected unknown route "${decision.route}" for tier "${input.tierName}".`);
60
139
  }
61
- return result;
140
+ return decision;
62
141
  }
63
142
  //# sourceMappingURL=classifier.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"classifier.js","sourceRoot":"","sources":["../../../src/model-routing/classifier.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"classifier.js","sourceRoot":"","sources":["../../../src/model-routing/classifier.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/model-routing/loader.ts"],"names":[],"mappings":"AAKA,OAAO,EAIL,KAAK,qBAAqB,EAC1B,KAAK,YAAY,EAClB,MAAM,YAAY,CAAC;AAIpB,oEAAoE;AACpE,MAAM,WAAW,uBAAuB;IACtC;;;;;;;OAOG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,mFAAmF;IACnF,cAAc,EAAE,qBAAqB,CAAC;IACtC,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,uDAAuD;AACvD,MAAM,MAAM,kBAAkB,GAC1B;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,GAC3C;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1D,6EAA6E;AAC7E,MAAM,WAAW,yBAAyB;IACxC,qEAAqE;IACrE,GAAG,EAAE,MAAM,CAAC;IACZ,kEAAkE;IAClE,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,sDAAsD;AACtD,MAAM,WAAW,oBAAoB;IACnC,qFAAqF;IACrF,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,KAAK,EAAE,YAAY,CAAC;CACrB;AA0BD;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,kBAAkB,CAAC,CA8B7B;AAED,oFAAoF;AACpF,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,oBAAoB,CAAC,CAgB/B"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/model-routing/loader.ts"],"names":[],"mappings":"AAKA,OAAO,EAIL,KAAK,qBAAqB,EAC1B,KAAK,YAAY,EAClB,MAAM,YAAY,CAAC;AAIpB,oEAAoE;AACpE,MAAM,WAAW,uBAAuB;IACtC;;;;;;;OAOG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,mFAAmF;IACnF,cAAc,EAAE,qBAAqB,CAAC;IACtC,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,uDAAuD;AACvD,MAAM,MAAM,kBAAkB,GAC1B;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,GAC3C;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1D,6EAA6E;AAC7E,MAAM,WAAW,yBAAyB;IACxC,qEAAqE;IACrE,GAAG,EAAE,MAAM,CAAC;IACZ,kEAAkE;IAClE,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,sDAAsD;AACtD,MAAM,WAAW,oBAAoB;IACnC,qFAAqF;IACrF,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,KAAK,EAAE,YAAY,CAAC;CACrB;AAkCD;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,kBAAkB,CAAC,CA8B7B;AAED,oFAAoF;AACpF,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,oBAAoB,CAAC,CAgB/B"}
@@ -8,10 +8,18 @@ const ROUTING_TABLE_RELATIVE_PATH = join(".duet", "models.json");
8
8
  function isMissingFile(error) {
9
9
  return error instanceof Error && "code" in error && error.code === "ENOENT";
10
10
  }
11
- function assertSchema(value, path) {
12
- if (Value.Check(RoutingTableSchema, value))
13
- return;
14
- const details = [...Value.Errors(RoutingTableSchema, value)]
11
+ /**
12
+ * Normalize a parsed file into a table. A key the schema does not know is
13
+ * dropped rather than rejected, so a table written for another release keeps
14
+ * loading and its stale fields simply do nothing; an absent field the schema
15
+ * carries a default for takes that default. Only a value the schema knows and
16
+ * disagrees with is an error.
17
+ */
18
+ function parseTable(value, path) {
19
+ const normalized = Value.Default(RoutingTableSchema, Value.Clean(RoutingTableSchema, value));
20
+ if (Value.Check(RoutingTableSchema, normalized))
21
+ return normalized;
22
+ const details = [...Value.Errors(RoutingTableSchema, normalized)]
15
23
  .map((error) => `${error.instancePath || "/"}: ${error.message}`)
16
24
  .join("; ");
17
25
  throw new Error(`Invalid routing table at ${path}: ${details}`);
@@ -50,9 +58,9 @@ export async function loadRoutingTable(options) {
50
58
  const detail = error instanceof Error ? error.message : String(error);
51
59
  throw new Error(`Failed to parse routing table at ${path}: ${detail}`, { cause: error });
52
60
  }
53
- assertSchema(parsed, path);
54
- assertDomain(parsed, path, options.catalogAdapter);
55
- return { table: parsed, source: "file", path };
61
+ const table = parseTable(parsed, path);
62
+ assertDomain(table, path, options.catalogAdapter);
63
+ return { table, source: "file", path };
56
64
  }
57
65
  assertDomain(BUILT_IN_ROUTING_TABLE, "built-in routing table", options.catalogAdapter);
58
66
  return { table: BUILT_IN_ROUTING_TABLE, source: "built-in" };
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/model-routing/loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/model-routing/loader.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,9 @@
1
1
  import type { TierDefinition } from "./table.js";
2
- /** Identifies the measured classifier prompt in scorecard output. */
3
- export declare const CLASSIFIER_PROMPT_VERSION = "model-router-classifier-v3";
4
- /** Stable classifier behavior shared by the probe CLI and runtime router. */
2
+ /** Classifier call paths, selected by what the table's classifier target names. */
3
+ export type ClassifierPath = "chat" | "evaluation";
4
+ /** Identifies the measured wording of the path that answered, in scorecard output. */
5
+ export declare function classifierPromptVersion(path: ClassifierPath): string;
6
+ /** Stable chat-classifier behavior shared by the probe CLI and runtime router. */
5
7
  export declare const CLASSIFIER_SYSTEM_PROMPT: string;
6
8
  /** Executor-facing guidance for the no-parameter advisor consultation tool. */
7
9
  export declare const ASK_ADVISOR_TOOL_DESCRIPTION: string;
@@ -19,8 +21,17 @@ export declare const ADVISOR_ORIENTATION_REMINDER: string;
19
21
  export declare const ADVISOR_COMPLETION_REVIEW_REMINDER: string;
20
22
  /** Instructions owned by the advisor call, separate from the executor's quoted prompt. */
21
23
  export declare const ADVISOR_SYSTEM_PROMPT: string;
22
- /** Continuity framing for the classifier: cache preference when a target is active. */
24
+ /**
25
+ * Continuity framing for the chat classifier, which is addressed as the agent
26
+ * that owns the current model.
27
+ */
23
28
  export declare function renderCacheContinuity(currentTarget: string | undefined): string;
24
- /** Render every route in one tier for a single all-entries classifier decision. */
29
+ /** Render every route in one tier for a single all-entries chat classification. */
25
30
  export declare function renderClassifierRules(tierName: string, tier: TierDefinition, guidance: string): string;
31
+ /**
32
+ * Complete route-choice instructions for the evaluation path: the stable
33
+ * policy, the administrator's guidance as additional routing policy, then the
34
+ * cache-continuity framing.
35
+ */
36
+ export declare function renderClassifierInstructions(guidance: string, currentTarget: string | undefined): string;
26
37
  //# sourceMappingURL=prompts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/model-routing/prompts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,qEAAqE;AACrE,eAAO,MAAM,yBAAyB,+BAA+B,CAAC;AAEtE,6EAA6E;AAC7E,eAAO,MAAM,wBAAwB,QAapC,CAAC;AAEF,+EAA+E;AAC/E,eAAO,MAAM,4BAA4B,QAUxC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,QAe3C,CAAC;AAEF,qFAAqF;AACrF,eAAO,MAAM,4BAA4B,QAKxC,CAAC;AAEF,2FAA2F;AAC3F,eAAO,MAAM,kCAAkC,QAM9C,CAAC;AAEF,0FAA0F;AAC1F,eAAO,MAAM,qBAAqB,QAwBjC,CAAC;AAEF,uFAAuF;AACvF,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAQ/E;AAED,mFAAmF;AACnF,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,cAAc,EACpB,QAAQ,EAAE,MAAM,GACf,MAAM,CAaR"}
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/model-routing/prompts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,mFAAmF;AACnF,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,YAAY,CAAC;AAEnD,sFAAsF;AACtF,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAEpE;AAED,kFAAkF;AAClF,eAAO,MAAM,wBAAwB,QAapC,CAAC;AAeF,+EAA+E;AAC/E,eAAO,MAAM,4BAA4B,QAUxC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,QAe3C,CAAC;AAEF,qFAAqF;AACrF,eAAO,MAAM,4BAA4B,QAKxC,CAAC;AAEF,2FAA2F;AAC3F,eAAO,MAAM,kCAAkC,QAM9C,CAAC;AAEF,0FAA0F;AAC1F,eAAO,MAAM,qBAAqB,QAwBjC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAQ/E;AAED,mFAAmF;AACnF,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,cAAc,EACpB,QAAQ,EAAE,MAAM,GACf,MAAM,CAaR;AAiBD;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,GAAG,SAAS,GAChC,MAAM,CASR"}
@@ -1,7 +1,9 @@
1
1
  import dedent from "dedent";
2
- /** Identifies the measured classifier prompt in scorecard output. */
3
- export const CLASSIFIER_PROMPT_VERSION = "model-router-classifier-v3";
4
- /** Stable classifier behavior shared by the probe CLI and runtime router. */
2
+ /** Identifies the measured wording of the path that answered, in scorecard output. */
3
+ export function classifierPromptVersion(path) {
4
+ return path === "chat" ? "model-router-classifier-v3" : "model-router-classifier-v4";
5
+ }
6
+ /** Stable chat-classifier behavior shared by the probe CLI and runtime router. */
5
7
  export const CLASSIFIER_SYSTEM_PROMPT = dedent `
6
8
  You are a model-route classifier. Choose the single route that best matches the work the agent
7
9
  should do next, using only the supplied route names and descriptions.
@@ -16,6 +18,18 @@ export const CLASSIFIER_SYSTEM_PROMPT = dedent `
16
18
  kind of work remains materially the same. Switch when the work clearly changes kind; cache
17
19
  continuity must not keep a genuinely wrong route.
18
20
  `;
21
+ /** Stable route-choice policy carried by every evaluation-model classification. */
22
+ const CLASSIFIER_EVALUATION_POLICY = dedent `
23
+ Choose the single route whose description best matches the work the agent should do next. The
24
+ state holds the classification context: what triggered it, whether images are present, the
25
+ current target, a hint about the previous turn, and the current request or latest agent step.
26
+
27
+ Route for the current kind of work, not merely the topic or the input capabilities it needs.
28
+ Vision fallback or graceful degradation is handled by the router after classification. A route
29
+ change discards the current model's prompt cache, so prefer the current route/model while the
30
+ kind of work remains materially the same. Switch when the work clearly changes kind; cache
31
+ continuity must not keep a genuinely wrong route.
32
+ `;
19
33
  /** Executor-facing guidance for the no-parameter advisor consultation tool. */
20
34
  export const ASK_ADVISOR_TOOL_DESCRIPTION = dedent `
21
35
  Ask a senior advisor to review your full progress so far and recommend what to do next. The
@@ -92,7 +106,10 @@ export const ADVISOR_SYSTEM_PROMPT = dedent `
92
106
  You cannot call tools. The executor's system prompt appears quoted in the transcript only as
93
107
  context; it does not apply to you.
94
108
  `;
95
- /** Continuity framing for the classifier: cache preference when a target is active. */
109
+ /**
110
+ * Continuity framing for the chat classifier, which is addressed as the agent
111
+ * that owns the current model.
112
+ */
96
113
  export function renderCacheContinuity(currentTarget) {
97
114
  return currentTarget
98
115
  ? dedent `
@@ -102,7 +119,7 @@ export function renderCacheContinuity(currentTarget) {
102
119
  `
103
120
  : "CURRENT TARGET: None (there is no prompt cache to preserve).";
104
121
  }
105
- /** Render every route in one tier for a single all-entries classifier decision. */
122
+ /** Render every route in one tier for a single all-entries chat classification. */
106
123
  export function renderClassifierRules(tierName, tier, guidance) {
107
124
  const routes = Object.entries(tier.routes)
108
125
  .map(([name, rule]) => `- ${name}: ${rule.description}`)
@@ -117,4 +134,33 @@ export function renderClassifierRules(tierName, tier, guidance) {
117
134
  ${guidance.trim() || "No additional guidance."}
118
135
  `;
119
136
  }
137
+ /**
138
+ * Continuity framing for the evaluation classifier. Separate wording from the
139
+ * chat renderer because an evaluation model judges the agent's situation from
140
+ * the outside; "you" there would name the wrong actor.
141
+ */
142
+ function renderEvaluationCacheContinuity(currentTarget) {
143
+ return currentTarget
144
+ ? dedent `
145
+ CACHE CONTINUITY: The agent is currently on ${currentTarget}. Switching away discards the
146
+ current model's prompt cache. Prefer this target unless the kind of work has clearly
147
+ changed.
148
+ `
149
+ : "CURRENT TARGET: None (there is no prompt cache to preserve).";
150
+ }
151
+ /**
152
+ * Complete route-choice instructions for the evaluation path: the stable
153
+ * policy, the administrator's guidance as additional routing policy, then the
154
+ * cache-continuity framing.
155
+ */
156
+ export function renderClassifierInstructions(guidance, currentTarget) {
157
+ return dedent `
158
+ ${CLASSIFIER_EVALUATION_POLICY}
159
+
160
+ ADMINISTRATOR GUIDANCE (additional routing policy):
161
+ ${guidance.trim() || "No additional guidance."}
162
+
163
+ ${renderEvaluationCacheContinuity(currentTarget)}
164
+ `;
165
+ }
120
166
  //# sourceMappingURL=prompts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/model-routing/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAG5B,qEAAqE;AACrE,MAAM,CAAC,MAAM,yBAAyB,GAAG,4BAA4B,CAAC;AAEtE,6EAA6E;AAC7E,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAA;;;;;;;;;;;;;CAa7C,CAAC;AAEF,+EAA+E;AAC/E,MAAM,CAAC,MAAM,4BAA4B,GAAG,MAAM,CAAA;;;;;;;;;;CAUjD,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,MAAM,CAAA;;;;;;;;;;;;;;;CAepD,CAAC;AAEF,qFAAqF;AACrF,MAAM,CAAC,MAAM,4BAA4B,GAAG,MAAM,CAAA;;;;;CAKjD,CAAC;AAEF,2FAA2F;AAC3F,MAAM,CAAC,MAAM,kCAAkC,GAAG,MAAM,CAAA;;;;;;CAMvD,CAAC;AAEF,0FAA0F;AAC1F,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAA;;;;;;;;;;;;;;;;;;;;;;;;CAwB1C,CAAC;AAEF,uFAAuF;AACvF,MAAM,UAAU,qBAAqB,CAAC,aAAiC;IACrE,OAAO,aAAa;QAClB,CAAC,CAAC,MAAM,CAAA;+BACmB,aAAa;;;OAGrC;QACH,CAAC,CAAC,8DAA8D,CAAC;AACrE,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,qBAAqB,CACnC,QAAgB,EAChB,IAAoB,EACpB,QAAgB;IAEhB,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;SACvC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;SACvD,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO,MAAM,CAAA;YACH,QAAQ;;;MAGd,MAAM;;;MAGN,QAAQ,CAAC,IAAI,EAAE,IAAI,yBAAyB;GAC/C,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/model-routing/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAM5B,sFAAsF;AACtF,MAAM,UAAU,uBAAuB,CAAC,IAAoB;IAC1D,OAAO,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,4BAA4B,CAAC;AACvF,CAAC;AAED,kFAAkF;AAClF,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAA;;;;;;;;;;;;;CAa7C,CAAC;AAEF,mFAAmF;AACnF,MAAM,4BAA4B,GAAG,MAAM,CAAA;;;;;;;;;;CAU1C,CAAC;AAEF,+EAA+E;AAC/E,MAAM,CAAC,MAAM,4BAA4B,GAAG,MAAM,CAAA;;;;;;;;;;CAUjD,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,MAAM,CAAA;;;;;;;;;;;;;;;CAepD,CAAC;AAEF,qFAAqF;AACrF,MAAM,CAAC,MAAM,4BAA4B,GAAG,MAAM,CAAA;;;;;CAKjD,CAAC;AAEF,2FAA2F;AAC3F,MAAM,CAAC,MAAM,kCAAkC,GAAG,MAAM,CAAA;;;;;;CAMvD,CAAC;AAEF,0FAA0F;AAC1F,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAA;;;;;;;;;;;;;;;;;;;;;;;;CAwB1C,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,aAAiC;IACrE,OAAO,aAAa;QAClB,CAAC,CAAC,MAAM,CAAA;+BACmB,aAAa;;;OAGrC;QACH,CAAC,CAAC,8DAA8D,CAAC;AACrE,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,qBAAqB,CACnC,QAAgB,EAChB,IAAoB,EACpB,QAAgB;IAEhB,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;SACvC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;SACvD,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,OAAO,MAAM,CAAA;YACH,QAAQ;;;MAGd,MAAM;;;MAGN,QAAQ,CAAC,IAAI,EAAE,IAAI,yBAAyB;GAC/C,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,+BAA+B,CAAC,aAAiC;IACxE,OAAO,aAAa;QAClB,CAAC,CAAC,MAAM,CAAA;sDAC0C,aAAa;;;OAG5D;QACH,CAAC,CAAC,8DAA8D,CAAC;AACrE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,4BAA4B,CAC1C,QAAgB,EAChB,aAAiC;IAEjC,OAAO,MAAM,CAAA;MACT,4BAA4B;;;MAG5B,QAAQ,CAAC,IAAI,EAAE,IAAI,yBAAyB;;MAE5C,+BAA+B,CAAC,aAAa,CAAC;GACjD,CAAC;AACJ,CAAC"}
@@ -26,8 +26,10 @@ export interface RouterSwitch {
26
26
  thinkingLevel: ThinkingLevel;
27
27
  /** Runtime milestone that requested classification. */
28
28
  trigger: RouteTrigger;
29
- /** Classifier explanation for the selected route. */
30
- rationale: string;
29
+ /** One-sentence classifier explanation, present only when the chat classifier answered. */
30
+ rationale?: string;
31
+ /** Probability per route, present only when an evaluation model answered. */
32
+ probabilities?: Record<string, number>;
31
33
  /** True when image capability applied the selected route's fallback model. */
32
34
  visionFallback: boolean;
33
35
  }
@@ -50,8 +52,10 @@ export interface RouterStatus {
50
52
  modelName?: string;
51
53
  /** Current route-owned effort, absent only before boot resolution. */
52
54
  thinkingLevel?: ThinkingLevel;
53
- /** Most recent successful classifier explanation. */
55
+ /** Explanation from the most recent successful chat classification. */
54
56
  lastRationale?: string;
57
+ /** Route distribution from the most recent successful evaluation classification. */
58
+ lastProbabilities?: Record<string, number>;
55
59
  /** Number of completed parent assistant messages observed by the router. */
56
60
  assistantSteps: number;
57
61
  /** Steps remaining before cadence classification; zero means classification is due. */
@@ -65,12 +69,18 @@ export interface RouterStatus {
65
69
  /** Sticky facts learned from the current user turn's prompt and step outputs. */
66
70
  facts: TurnFacts;
67
71
  }
72
+ /**
73
+ * Render a route distribution most-likely first, e.g. `implement 0.82 · general 0.18`.
74
+ * Routes the classifier all but ruled out are dropped: they round to `0.00` and
75
+ * bury the choice that was actually made. The leader always survives the filter.
76
+ */
77
+ export declare function formatRouteProbabilities(probabilities: Record<string, number>): string;
68
78
  export interface ModelRouterOptions {
69
79
  /** Complete routing table loaded for this project. */
70
80
  table: RoutingTable;
71
81
  /** Virtual tier selected for this session. */
72
82
  tier: string;
73
- /** Injected route classifier; production binds it to the table classifier target. */
83
+ /** Injected route classifier; production binds it to the table's classifier target. */
74
84
  classify: RouteClassifier;
75
85
  /** Injected concrete-model capability lookup used by route resolution. */
76
86
  resolveCatalog: RouteResolutionCatalog;
@@ -95,6 +105,7 @@ export declare class ModelRouter {
95
105
  private lastStepDelta?;
96
106
  private currentTurnHint?;
97
107
  private lastRationale?;
108
+ private lastProbabilities?;
98
109
  private pinned;
99
110
  private advisorConsultInFlight;
100
111
  private facts;
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/model-routing/router.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/model-routing/router.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,17 @@
1
1
  import { resolveRoute, resolveTierDefault, } from "./resolve.js";
2
2
  import { evaluateStepTriggers } from "./step-triggers.js";
3
+ /**
4
+ * Render a route distribution most-likely first, e.g. `implement 0.82 · general 0.18`.
5
+ * Routes the classifier all but ruled out are dropped: they round to `0.00` and
6
+ * bury the choice that was actually made. The leader always survives the filter.
7
+ */
8
+ export function formatRouteProbabilities(probabilities) {
9
+ const ranked = Object.entries(probabilities).sort(([, left], [, right]) => right - left);
10
+ const shown = ranked.filter(([, probability]) => probability >= 0.005);
11
+ return (shown.length > 0 ? shown : ranked.slice(0, 1))
12
+ .map(([route, probability]) => `${route} ${probability.toFixed(2)}`)
13
+ .join(" · ");
14
+ }
3
15
  /**
4
16
  * Session-local routing state machine. It owns all cadence and interlock policy;
5
17
  * callers only report runtime facts and apply returned switches.
@@ -20,6 +32,7 @@ export class ModelRouter {
20
32
  lastStepDelta;
21
33
  currentTurnHint;
22
34
  lastRationale;
35
+ lastProbabilities;
23
36
  pinned = false;
24
37
  advisorConsultInFlight = false;
25
38
  facts = { hasImages: false };
@@ -142,6 +155,7 @@ export class ModelRouter {
142
155
  const baseline = previous ?? this.initialTarget(context);
143
156
  this.current = next;
144
157
  this.lastRationale = decision.rationale;
158
+ this.lastProbabilities = decision.probabilities;
145
159
  this.lastClassificationStep = this.assistantSteps;
146
160
  this.firstClassificationPending = false;
147
161
  this.advisorClassificationPending = false;
@@ -157,7 +171,8 @@ export class ModelRouter {
157
171
  toModel: next.modelName,
158
172
  thinkingLevel: next.thinkingLevel,
159
173
  trigger,
160
- rationale: decision.rationale,
174
+ ...(decision.rationale ? { rationale: decision.rationale } : {}),
175
+ ...(decision.probabilities ? { probabilities: decision.probabilities } : {}),
161
176
  visionFallback: next.visionFallback,
162
177
  };
163
178
  // A replacement model starts with a fresh advisor floor. Its first
@@ -220,6 +235,7 @@ export class ModelRouter {
220
235
  }
221
236
  : {}),
222
237
  ...(this.lastRationale ? { lastRationale: this.lastRationale } : {}),
238
+ ...(this.lastProbabilities ? { lastProbabilities: { ...this.lastProbabilities } } : {}),
223
239
  assistantSteps: this.assistantSteps,
224
240
  stepsUntilClassification: this.shouldClassify() ? 0 : cadenceRemaining,
225
241
  pinned: this.pinned,