@mupt-ai/dari-router 0.1.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 (179) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +100 -0
  3. package/dist/anonymous_actions.d.ts +55 -0
  4. package/dist/anonymous_actions.js +277 -0
  5. package/dist/anonymous_actions.js.map +1 -0
  6. package/dist/auto_router.d.ts +10 -0
  7. package/dist/auto_router.js +56 -0
  8. package/dist/auto_router.js.map +1 -0
  9. package/dist/cache_behavior.d.ts +14 -0
  10. package/dist/cache_behavior.js +112 -0
  11. package/dist/cache_behavior.js.map +1 -0
  12. package/dist/cache_scope.d.ts +5 -0
  13. package/dist/cache_scope.js +49 -0
  14. package/dist/cache_scope.js.map +1 -0
  15. package/dist/cache_switch_decision.d.ts +24 -0
  16. package/dist/cache_switch_decision.js +21 -0
  17. package/dist/cache_switch_decision.js.map +1 -0
  18. package/dist/candidate_pruning.d.ts +45 -0
  19. package/dist/candidate_pruning.js +154 -0
  20. package/dist/candidate_pruning.js.map +1 -0
  21. package/dist/candidate_resolution.d.ts +41 -0
  22. package/dist/candidate_resolution.js +111 -0
  23. package/dist/candidate_resolution.js.map +1 -0
  24. package/dist/compatibility.d.ts +22 -0
  25. package/dist/compatibility.js +76 -0
  26. package/dist/compatibility.js.map +1 -0
  27. package/dist/continuation_state.d.ts +36 -0
  28. package/dist/continuation_state.js +249 -0
  29. package/dist/continuation_state.js.map +1 -0
  30. package/dist/cost.d.ts +31 -0
  31. package/dist/cost.js +314 -0
  32. package/dist/cost.js.map +1 -0
  33. package/dist/dari_policy.d.ts +34 -0
  34. package/dist/dari_policy.js +267 -0
  35. package/dist/dari_policy.js.map +1 -0
  36. package/dist/errors.d.ts +7 -0
  37. package/dist/errors.js +14 -0
  38. package/dist/errors.js.map +1 -0
  39. package/dist/fingerprint.d.ts +13 -0
  40. package/dist/fingerprint.js +130 -0
  41. package/dist/fingerprint.js.map +1 -0
  42. package/dist/fixed_turn_cost_config.d.ts +9 -0
  43. package/dist/fixed_turn_cost_config.js +22 -0
  44. package/dist/fixed_turn_cost_config.js.map +1 -0
  45. package/dist/framework_error.d.ts +8 -0
  46. package/dist/framework_error.js +24 -0
  47. package/dist/framework_error.js.map +1 -0
  48. package/dist/framework_lifecycle.d.ts +11 -0
  49. package/dist/framework_lifecycle.js +57 -0
  50. package/dist/framework_lifecycle.js.map +1 -0
  51. package/dist/framework_models.d.ts +3 -0
  52. package/dist/framework_models.js +120 -0
  53. package/dist/framework_models.js.map +1 -0
  54. package/dist/framework_router.d.ts +2 -0
  55. package/dist/framework_router.js +384 -0
  56. package/dist/framework_router.js.map +1 -0
  57. package/dist/framework_streaming.d.ts +26 -0
  58. package/dist/framework_streaming.js +486 -0
  59. package/dist/framework_streaming.js.map +1 -0
  60. package/dist/framework_types.d.ts +272 -0
  61. package/dist/framework_types.js +5 -0
  62. package/dist/framework_types.js.map +1 -0
  63. package/dist/framework_validation.d.ts +7 -0
  64. package/dist/framework_validation.js +169 -0
  65. package/dist/framework_validation.js.map +1 -0
  66. package/dist/index.d.ts +35 -0
  67. package/dist/index.js +38 -0
  68. package/dist/index.js.map +1 -0
  69. package/dist/json.d.ts +10 -0
  70. package/dist/json.js +29 -0
  71. package/dist/json.js.map +1 -0
  72. package/dist/model_ids.d.ts +4 -0
  73. package/dist/model_ids.js +26 -0
  74. package/dist/model_ids.js.map +1 -0
  75. package/dist/pi_context.d.ts +4 -0
  76. package/dist/pi_context.js +206 -0
  77. package/dist/pi_context.js.map +1 -0
  78. package/dist/pi_options.d.ts +3 -0
  79. package/dist/pi_options.js +240 -0
  80. package/dist/pi_options.js.map +1 -0
  81. package/dist/pi_output.d.ts +4 -0
  82. package/dist/pi_output.js +328 -0
  83. package/dist/pi_output.js.map +1 -0
  84. package/dist/pi_reasoning_signature.d.ts +10 -0
  85. package/dist/pi_reasoning_signature.js +33 -0
  86. package/dist/pi_reasoning_signature.js.map +1 -0
  87. package/dist/pi_runtime.d.ts +3 -0
  88. package/dist/pi_runtime.js +155 -0
  89. package/dist/pi_runtime.js.map +1 -0
  90. package/dist/pi_types.d.ts +35 -0
  91. package/dist/pi_types.js +2 -0
  92. package/dist/pi_types.js.map +1 -0
  93. package/dist/portable_reasoning_state.d.ts +7 -0
  94. package/dist/portable_reasoning_state.js +81 -0
  95. package/dist/portable_reasoning_state.js.map +1 -0
  96. package/dist/previous_decision.d.ts +13 -0
  97. package/dist/previous_decision.js +82 -0
  98. package/dist/previous_decision.js.map +1 -0
  99. package/dist/prompts.d.ts +3 -0
  100. package/dist/prompts.js +65 -0
  101. package/dist/prompts.js.map +1 -0
  102. package/dist/protocol_anthropic.d.ts +18 -0
  103. package/dist/protocol_anthropic.js +443 -0
  104. package/dist/protocol_anthropic.js.map +1 -0
  105. package/dist/protocol_openai_chat.d.ts +25 -0
  106. package/dist/protocol_openai_chat.js +503 -0
  107. package/dist/protocol_openai_chat.js.map +1 -0
  108. package/dist/protocol_validation.d.ts +23 -0
  109. package/dist/protocol_validation.js +134 -0
  110. package/dist/protocol_validation.js.map +1 -0
  111. package/dist/route.d.ts +105 -0
  112. package/dist/route.js +226 -0
  113. package/dist/route.js.map +1 -0
  114. package/dist/routing_history.d.ts +7 -0
  115. package/dist/routing_history.js +132 -0
  116. package/dist/routing_history.js.map +1 -0
  117. package/dist/selector_input.d.ts +42 -0
  118. package/dist/selector_input.js +153 -0
  119. package/dist/selector_input.js.map +1 -0
  120. package/dist/selector_parse.d.ts +13 -0
  121. package/dist/selector_parse.js +95 -0
  122. package/dist/selector_parse.js.map +1 -0
  123. package/dist/selector_request.d.ts +26 -0
  124. package/dist/selector_request.js +85 -0
  125. package/dist/selector_request.js.map +1 -0
  126. package/dist/selector_truncation.d.ts +2 -0
  127. package/dist/selector_truncation.js +48 -0
  128. package/dist/selector_truncation.js.map +1 -0
  129. package/dist/selector_wire.d.ts +10 -0
  130. package/dist/selector_wire.js +113 -0
  131. package/dist/selector_wire.js.map +1 -0
  132. package/dist/types.d.ts +152 -0
  133. package/dist/types.js +14 -0
  134. package/dist/types.js.map +1 -0
  135. package/package.json +64 -0
  136. package/src/anonymous_actions.ts +434 -0
  137. package/src/auto_router.ts +95 -0
  138. package/src/cache_behavior.ts +130 -0
  139. package/src/cache_scope.ts +58 -0
  140. package/src/cache_switch_decision.ts +53 -0
  141. package/src/candidate_pruning.ts +257 -0
  142. package/src/candidate_resolution.ts +208 -0
  143. package/src/compatibility.ts +162 -0
  144. package/src/continuation_state.ts +368 -0
  145. package/src/cost.ts +455 -0
  146. package/src/dari_policy.ts +360 -0
  147. package/src/errors.ts +27 -0
  148. package/src/fingerprint.ts +148 -0
  149. package/src/fixed_turn_cost_config.ts +24 -0
  150. package/src/framework_error.ts +38 -0
  151. package/src/framework_lifecycle.ts +74 -0
  152. package/src/framework_models.ts +186 -0
  153. package/src/framework_router.ts +490 -0
  154. package/src/framework_streaming.ts +613 -0
  155. package/src/framework_types.ts +372 -0
  156. package/src/framework_validation.ts +235 -0
  157. package/src/index.ts +37 -0
  158. package/src/json.ts +43 -0
  159. package/src/model_ids.ts +29 -0
  160. package/src/pi_context.ts +251 -0
  161. package/src/pi_options.ts +295 -0
  162. package/src/pi_output.ts +387 -0
  163. package/src/pi_reasoning_signature.ts +41 -0
  164. package/src/pi_runtime.ts +238 -0
  165. package/src/pi_types.ts +71 -0
  166. package/src/portable_reasoning_state.ts +129 -0
  167. package/src/previous_decision.ts +109 -0
  168. package/src/prompts.ts +69 -0
  169. package/src/protocol_anthropic.ts +571 -0
  170. package/src/protocol_openai_chat.ts +645 -0
  171. package/src/protocol_validation.ts +202 -0
  172. package/src/route.ts +490 -0
  173. package/src/routing_history.ts +157 -0
  174. package/src/selector_input.ts +246 -0
  175. package/src/selector_parse.ts +138 -0
  176. package/src/selector_request.ts +130 -0
  177. package/src/selector_truncation.ts +48 -0
  178. package/src/selector_wire.ts +167 -0
  179. package/src/types.ts +231 -0
@@ -0,0 +1,272 @@
1
+ import type { ReasoningEffort, RoutingDecision } from "./types.js";
2
+ import type { RouterContinuationState, RouterProviderIdentity } from "./continuation_state.js";
3
+ import type { RouterFrameworkError } from "./framework_error.js";
4
+ export type { RouterContinuationState, RouterProviderIdentity } from "./continuation_state.js";
5
+ export type RouterProtocol = "openai_chat_completions" | "anthropic_messages";
6
+ export type RouterTextContent = {
7
+ type: "text";
8
+ text: string;
9
+ };
10
+ export type RouterImageContent = {
11
+ type: "image";
12
+ url: string;
13
+ detail?: "auto" | "low" | "high";
14
+ };
15
+ export type RouterContent = RouterTextContent | RouterImageContent;
16
+ export type RouterMessageItem = {
17
+ type: "message";
18
+ role: "system" | "developer" | "user" | "assistant";
19
+ content: RouterContent[];
20
+ };
21
+ export type RouterToolCallItem = {
22
+ type: "tool_call";
23
+ id: string;
24
+ name: string;
25
+ arguments: string | Record<string, unknown>;
26
+ };
27
+ export type RouterToolResultItem = {
28
+ type: "tool_result";
29
+ toolCallId: string;
30
+ content: RouterContent[];
31
+ isError?: boolean;
32
+ };
33
+ export type RouterHostedToolCallStatus = "in_progress" | "searching" | "completed" | "incomplete" | "failed";
34
+ export declare function isRouterHostedToolCallStatus(value: unknown): value is RouterHostedToolCallStatus;
35
+ export type RouterHostedToolCallItem = {
36
+ type: "hosted_tool_call";
37
+ id: string;
38
+ tool: "web_search";
39
+ providerType: "web_search_call";
40
+ status?: RouterHostedToolCallStatus;
41
+ payload: Record<string, unknown>;
42
+ source?: RouterProviderIdentity;
43
+ };
44
+ export type RouterReasoningItem = {
45
+ type: "reasoning";
46
+ id?: string;
47
+ summary?: string[];
48
+ content: string[];
49
+ source?: RouterProviderIdentity;
50
+ continuation?: RouterContinuationState;
51
+ };
52
+ export type RouterInputItem = RouterMessageItem | RouterToolCallItem | RouterToolResultItem | RouterReasoningItem | RouterHostedToolCallItem;
53
+ export type RouterTool = {
54
+ name: string;
55
+ description?: string;
56
+ inputSchema: Record<string, unknown>;
57
+ strict?: boolean;
58
+ };
59
+ export type RouterToolChoice = "none" | "auto" | "required" | {
60
+ type: "tool";
61
+ name: string;
62
+ };
63
+ export type RouterResponseFormat = {
64
+ type: "text";
65
+ } | {
66
+ type: "json_object";
67
+ } | {
68
+ type: "json_schema";
69
+ name: string;
70
+ schema: Record<string, unknown>;
71
+ description?: string;
72
+ strict?: boolean;
73
+ };
74
+ export type RouterRequest = {
75
+ protocol: RouterProtocol;
76
+ requestedModel: string;
77
+ items: RouterInputItem[];
78
+ tools: RouterTool[];
79
+ toolChoice?: RouterToolChoice;
80
+ parallelToolCalls?: boolean;
81
+ generation: {
82
+ temperature?: number;
83
+ topP?: number;
84
+ maxOutputTokens?: number;
85
+ stop?: string | string[];
86
+ };
87
+ reasoning?: {
88
+ effort?: ReasoningEffort;
89
+ enabled?: boolean;
90
+ budgetTokens?: number;
91
+ };
92
+ responseFormat?: RouterResponseFormat;
93
+ cacheKey?: string;
94
+ stream: boolean;
95
+ metadata?: Record<string, unknown>;
96
+ user?: string;
97
+ };
98
+ export type RouterModelCapabilities = {
99
+ imageInput?: boolean;
100
+ toolUse?: boolean;
101
+ structuredOutput?: boolean;
102
+ streaming?: boolean;
103
+ };
104
+ export type RouterModel<Metadata = unknown> = {
105
+ id: string;
106
+ executor?: string;
107
+ provider?: string;
108
+ api?: string;
109
+ reasoningEfforts?: readonly ReasoningEffort[];
110
+ defaultReasoningEffort?: ReasoningEffort;
111
+ capabilities?: RouterModelCapabilities;
112
+ metadata?: Metadata;
113
+ };
114
+ export type RouterCandidate<Metadata = unknown> = {
115
+ id: string;
116
+ executor: string;
117
+ provider: string;
118
+ api: string;
119
+ reasoningEfforts: readonly ReasoningEffort[];
120
+ defaultReasoningEffort: ReasoningEffort;
121
+ capabilities: Required<RouterModelCapabilities>;
122
+ metadata?: Metadata;
123
+ };
124
+ export type RoutingPolicyInput<Metadata = unknown> = {
125
+ request: RouterRequest;
126
+ candidates: readonly RouterCandidate<Metadata>[];
127
+ signal: AbortSignal;
128
+ };
129
+ export type RoutingPolicyDecision = {
130
+ model: string;
131
+ reasoningEffort?: ReasoningEffort;
132
+ reason?: string;
133
+ leaseTurnsRemaining?: number;
134
+ details?: unknown;
135
+ };
136
+ export type RoutingPolicy<Metadata = unknown> = ((input: RoutingPolicyInput<Metadata>) => RoutingPolicyDecision | Promise<RoutingPolicyDecision>) | {
137
+ select(input: RoutingPolicyInput<Metadata>): RoutingPolicyDecision | Promise<RoutingPolicyDecision>;
138
+ };
139
+ export type RouterSelection<Metadata = unknown> = {
140
+ decision: RoutingDecision;
141
+ candidates: readonly RouterCandidate<Metadata>[];
142
+ policyDetails?: unknown;
143
+ };
144
+ export type RouterUsage = {
145
+ inputTokens: number;
146
+ outputTokens: number;
147
+ cacheReadTokens?: number;
148
+ cacheWriteTokens?: number;
149
+ totalTokens?: number;
150
+ };
151
+ export type RouterFinishReason = "stop" | "length" | "tool_calls";
152
+ export type RouterOutputText = {
153
+ type: "text";
154
+ text: string;
155
+ };
156
+ export type RouterOutputToolCall = {
157
+ type: "tool_call";
158
+ id: string;
159
+ name: string;
160
+ arguments: string | Record<string, unknown>;
161
+ };
162
+ export type RouterOutputReasoning = {
163
+ type: "reasoning";
164
+ text: string;
165
+ redacted?: boolean;
166
+ source?: RouterProviderIdentity;
167
+ continuation?: RouterContinuationState;
168
+ };
169
+ export type RouterOutputHostedToolCall = {
170
+ type: "hosted_tool_call";
171
+ id: string;
172
+ tool: "web_search";
173
+ providerType: "web_search_call";
174
+ status?: RouterHostedToolCallStatus;
175
+ payload: Record<string, unknown>;
176
+ source?: RouterProviderIdentity;
177
+ };
178
+ export type RouterOutputItem = RouterOutputText | RouterOutputToolCall | RouterOutputReasoning | RouterOutputHostedToolCall;
179
+ export type RouterCompletion = {
180
+ id?: string;
181
+ createdAtMs?: number;
182
+ content: RouterOutputItem[];
183
+ finishReason: RouterFinishReason;
184
+ usage?: RouterUsage;
185
+ };
186
+ export type RouterStreamEvent = {
187
+ type: "text_delta";
188
+ index: number;
189
+ delta: string;
190
+ } | {
191
+ type: "tool_call_start";
192
+ index: number;
193
+ id: string;
194
+ name: string;
195
+ } | {
196
+ type: "tool_call_delta";
197
+ index: number;
198
+ delta: string;
199
+ } | {
200
+ type: "tool_call_end";
201
+ index: number;
202
+ } | {
203
+ type: "reasoning_delta";
204
+ index: number;
205
+ delta: string;
206
+ } | (RouterOutputHostedToolCall & {
207
+ index: number;
208
+ }) | {
209
+ type: "reasoning_end";
210
+ index: number;
211
+ redacted?: boolean;
212
+ source?: RouterProviderIdentity;
213
+ itemId?: string;
214
+ continuation?: import("./continuation_state.js").ProviderContinuationState;
215
+ } | {
216
+ type: "finish";
217
+ finishReason: RouterFinishReason;
218
+ usage?: RouterUsage;
219
+ };
220
+ export type RouterExecutorResult = {
221
+ type: "complete";
222
+ output: RouterCompletion;
223
+ } | {
224
+ type: "stream";
225
+ events: AsyncIterable<RouterStreamEvent>;
226
+ };
227
+ export type RouterExecutorInput<Metadata = unknown> = {
228
+ request: RouterRequest;
229
+ model: RouterCandidate<Metadata>;
230
+ decision: RoutingDecision;
231
+ signal: AbortSignal;
232
+ };
233
+ export type RouterExecutor<Metadata = unknown> = {
234
+ execute(input: RouterExecutorInput<Metadata>): RouterExecutorResult | Promise<RouterExecutorResult>;
235
+ };
236
+ export type CreateRouterOptions<Metadata = unknown> = {
237
+ models: readonly RouterModel<Metadata>[];
238
+ policy: RoutingPolicy<Metadata>;
239
+ runtime?: RouterExecutor<Metadata>;
240
+ executors?: Readonly<Record<string, RouterExecutor<Metadata>>>;
241
+ generateId?: () => string;
242
+ leaseStore?: LeaseStore;
243
+ hooks?: RouterHooks<Metadata>;
244
+ fallback?: RouterFallbackConfig;
245
+ };
246
+ export type Router<Metadata = unknown> = {
247
+ readonly models: readonly RouterCandidate<Metadata>[];
248
+ select(request: RouterRequest, signal?: AbortSignal): Promise<RouterSelection<Metadata>>;
249
+ fetch(request: Request): Promise<Response>;
250
+ };
251
+ export type RouterLease = {
252
+ model: string;
253
+ reasoningEffort: ReasoningEffort;
254
+ turnsRemaining: number;
255
+ expiresAt: number;
256
+ };
257
+ export interface LeaseStore {
258
+ get(cacheKey: string): RouterLease | undefined | Promise<RouterLease | undefined>;
259
+ set(cacheKey: string, lease: RouterLease): void | Promise<void>;
260
+ delete(cacheKey: string): void | Promise<void>;
261
+ pruneExpired(nowMs: number): void | Promise<void>;
262
+ }
263
+ export type RouterHooks<Metadata = unknown> = {
264
+ onSelection?(selection: RouterSelection<Metadata>, request: RouterRequest): void;
265
+ onCompletion?(completion: RouterCompletion, selection: RouterSelection<Metadata>): void;
266
+ onStreamClose?(completion: RouterCompletion | null, selection: RouterSelection<Metadata>, error: RouterFrameworkError | null): void;
267
+ onError?(error: RouterFrameworkError, selection: RouterSelection<Metadata>): void;
268
+ };
269
+ export type RouterFallbackConfig = {
270
+ enabled?: boolean;
271
+ requiresDifferentProvider?: boolean;
272
+ };
@@ -0,0 +1,5 @@
1
+ export function isRouterHostedToolCallStatus(value) {
2
+ return value === "in_progress" || value === "searching" || value === "completed" ||
3
+ value === "incomplete" || value === "failed";
4
+ }
5
+ //# sourceMappingURL=framework_types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framework_types.js","sourceRoot":"","sources":["../src/framework_types.ts"],"names":[],"mappings":"AAqDA,MAAM,UAAU,4BAA4B,CAC1C,KAAc;IAEd,OAAO,KAAK,KAAK,aAAa,IAAI,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,WAAW;QAC9E,KAAK,KAAK,YAAY,IAAI,KAAK,KAAK,QAAQ,CAAC;AACjD,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { RouterCandidate, RouterCompletion, RouterSelection, RouterStreamEvent, RoutingPolicyDecision } from "./framework_types.js";
2
+ export declare function validateStreamSequence(event: Exclude<RouterStreamEvent, {
3
+ type: "finish";
4
+ }>, openIndexes: Map<number, "text" | "tool" | "reasoning">): void;
5
+ export declare function validateStreamEvent(event: RouterStreamEvent): void;
6
+ export declare function validateCompletion(output: RouterCompletion): void;
7
+ export declare function validatePolicyDecision<Metadata>(value: RoutingPolicyDecision, candidates: readonly RouterCandidate<Metadata>[]): RouterSelection<Metadata>;
@@ -0,0 +1,169 @@
1
+ import { RouterFrameworkError } from "./framework_error.js";
2
+ import { completionContract, streamContract, } from "./framework_lifecycle.js";
3
+ import { isReasoningEffort } from "./types.js";
4
+ export function validateStreamSequence(event, openIndexes) {
5
+ const current = openIndexes.get(event.index);
6
+ if (event.type === "text_delta") {
7
+ if (current === "tool" || current === "reasoning")
8
+ throw streamContract(`Stream index ${event.index} is already a ${current} block.`);
9
+ if (current === undefined)
10
+ openIndexes.set(event.index, "text");
11
+ return;
12
+ }
13
+ if (event.type === "reasoning_delta") {
14
+ if (current === "tool" || current === "text")
15
+ throw streamContract(`Stream index ${event.index} is already a ${current} block.`);
16
+ if (current === undefined)
17
+ openIndexes.set(event.index, "reasoning");
18
+ return;
19
+ }
20
+ if (event.type === "reasoning_end") {
21
+ if (current === "text" || current === "tool")
22
+ throw streamContract(`Stream index ${event.index} is already a ${current} block.`);
23
+ if (current === "reasoning")
24
+ openIndexes.delete(event.index);
25
+ // If current is undefined, reasoning_end opens and immediately closes a
26
+ // reasoning block (empty or redacted thinking with no prior delta).
27
+ return;
28
+ }
29
+ if (event.type === "tool_call_start") {
30
+ if (current !== undefined)
31
+ throw streamContract(`Stream index ${event.index} is already in use.`);
32
+ openIndexes.set(event.index, "tool");
33
+ return;
34
+ }
35
+ if (event.type === "hosted_tool_call") {
36
+ // Hosted tool calls arrive complete: the event opens and closes its
37
+ // block, so the index only needs to be unused.
38
+ if (current !== undefined)
39
+ throw streamContract(`Stream index ${event.index} is already in use.`);
40
+ return;
41
+ }
42
+ if (current !== "tool") {
43
+ throw streamContract(`Stream index ${event.index} has no open tool call.`);
44
+ }
45
+ if (event.type === "tool_call_end")
46
+ openIndexes.delete(event.index);
47
+ }
48
+ export function validateStreamEvent(event) {
49
+ if (!event || typeof event !== "object" || typeof event.type !== "string") {
50
+ throw streamContract("Executor emitted an invalid stream event.");
51
+ }
52
+ if (event.type === "finish") {
53
+ validateFinishReason(event.finishReason);
54
+ if (event.usage !== undefined)
55
+ validateUsage(event.usage);
56
+ return;
57
+ }
58
+ if (!Number.isSafeInteger(event.index) || event.index < 0) {
59
+ throw streamContract("Executor stream event index must be a non-negative integer.");
60
+ }
61
+ if (event.type === "text_delta" || event.type === "tool_call_delta" || event.type === "reasoning_delta") {
62
+ if (typeof event.delta !== "string" || event.delta.length === 0) {
63
+ throw streamContract("Executor stream deltas must be non-empty strings.");
64
+ }
65
+ return;
66
+ }
67
+ if (event.type === "tool_call_start") {
68
+ if (typeof event.id !== "string" || !event.id.trim() ||
69
+ typeof event.name !== "string" || !event.name.trim()) {
70
+ throw streamContract("Executor tool-call starts require non-empty id and name.");
71
+ }
72
+ return;
73
+ }
74
+ if (event.type === "hosted_tool_call") {
75
+ if (typeof event.id !== "string" || event.id.length === 0 ||
76
+ event.tool !== "web_search" ||
77
+ event.providerType !== "web_search_call" ||
78
+ typeof event.payload !== "object" || event.payload === null || Array.isArray(event.payload)) {
79
+ throw streamContract("Executor hosted tool calls require id, tool, providerType, and payload.");
80
+ }
81
+ return;
82
+ }
83
+ if (event.type !== "tool_call_end" && event.type !== "reasoning_end") {
84
+ throw streamContract(`Executor emitted unsupported stream event '${String(event.type)}'.`);
85
+ }
86
+ }
87
+ export function validateCompletion(output) {
88
+ if (!output || typeof output !== "object" || !Array.isArray(output.content)) {
89
+ throw new RouterFrameworkError("executor", "Executor returned an invalid completion.", "executor_output_invalid");
90
+ }
91
+ validateFinishReason(output.finishReason, completionContract);
92
+ if (output.usage !== undefined)
93
+ validateUsage(output.usage, completionContract);
94
+ for (const item of output.content) {
95
+ if (item && typeof item === "object" && ((item.type === "text" && typeof item.text === "string") ||
96
+ (item.type === "reasoning" &&
97
+ typeof item.text === "string" &&
98
+ (item.redacted === undefined || typeof item.redacted === "boolean") &&
99
+ (item.source === undefined || (typeof item.source.provider === "string" &&
100
+ typeof item.source.api === "string" &&
101
+ typeof item.source.model === "string")) &&
102
+ (item.continuation === undefined || (typeof item.continuation === "object" && item.continuation !== null))) ||
103
+ (item.type === "tool_call" &&
104
+ typeof item.id === "string" && item.id.length > 0 &&
105
+ typeof item.name === "string" && item.name.length > 0 &&
106
+ (typeof item.arguments === "string" || (typeof item.arguments === "object" && item.arguments !== null && !Array.isArray(item.arguments)))) ||
107
+ (item.type === "hosted_tool_call" &&
108
+ typeof item.id === "string" && item.id.length > 0 &&
109
+ item.tool === "web_search" &&
110
+ item.providerType === "web_search_call" &&
111
+ typeof item.payload === "object" && item.payload !== null && !Array.isArray(item.payload))))
112
+ continue;
113
+ throw new RouterFrameworkError("executor", "Executor returned an invalid completion content item.", "executor_output_invalid");
114
+ }
115
+ }
116
+ function validateFinishReason(value, contractError = streamContract) {
117
+ if (value !== "stop" && value !== "length" && value !== "tool_calls") {
118
+ throw contractError("Executor returned an invalid finish reason.");
119
+ }
120
+ }
121
+ function validateUsage(usage, contractError = streamContract) {
122
+ if (!usage || typeof usage !== "object") {
123
+ throw contractError("Executor usage must be an object.");
124
+ }
125
+ for (const [name, value, required] of [
126
+ ["inputTokens", usage.inputTokens, true],
127
+ ["outputTokens", usage.outputTokens, true],
128
+ ["cacheReadTokens", usage.cacheReadTokens, false],
129
+ ["cacheWriteTokens", usage.cacheWriteTokens, false],
130
+ ["totalTokens", usage.totalTokens, false],
131
+ ]) {
132
+ if ((required && value === undefined) || (value !== undefined && (!Number.isSafeInteger(value) || value < 0))) {
133
+ throw contractError(`Executor usage ${name} must be ${required ? "a" : "an optional"} non-negative integer.`);
134
+ }
135
+ }
136
+ }
137
+ export function validatePolicyDecision(value, candidates) {
138
+ if (!value || typeof value !== "object" || typeof value.model !== "string") {
139
+ throw new RouterFrameworkError("policy", "Routing policy returned an invalid decision.", "policy_invalid_decision");
140
+ }
141
+ const candidate = candidates.find((item) => item.id === value.model);
142
+ if (candidate === undefined) {
143
+ throw new RouterFrameworkError("policy", `Routing policy selected unconfigured or ineligible model '${value.model}'.`, "policy_invalid_model");
144
+ }
145
+ const reasoningEffort = value.reasoningEffort ?? candidate.defaultReasoningEffort;
146
+ if (!isReasoningEffort(reasoningEffort) || !candidate.reasoningEfforts.includes(reasoningEffort)) {
147
+ throw new RouterFrameworkError("policy", `Routing policy selected unsupported reasoning effort '${String(reasoningEffort)}' for '${candidate.id}'.`, "policy_invalid_reasoning_effort");
148
+ }
149
+ const reason = typeof value.reason === "string" && value.reason.trim()
150
+ ? value.reason.trim()
151
+ : `Routing policy selected ${candidate.id}/${reasoningEffort}.`;
152
+ const leaseTurnsRemaining = value.leaseTurnsRemaining;
153
+ if (leaseTurnsRemaining !== undefined && (typeof leaseTurnsRemaining !== "number" ||
154
+ !Number.isInteger(leaseTurnsRemaining) ||
155
+ leaseTurnsRemaining < 0)) {
156
+ throw new RouterFrameworkError("policy", `Routing policy returned invalid leaseTurnsRemaining '${String(leaseTurnsRemaining)}'.`, "policy_invalid_lease_turns");
157
+ }
158
+ return {
159
+ decision: {
160
+ selectedModel: candidate.id,
161
+ reasoningEffort,
162
+ reason,
163
+ ...(leaseTurnsRemaining === undefined ? {} : { leaseTurnsRemaining }),
164
+ },
165
+ candidates,
166
+ ...(value.details === undefined ? {} : { policyDetails: value.details }),
167
+ };
168
+ }
169
+ //# sourceMappingURL=framework_validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framework_validation.js","sourceRoot":"","sources":["../src/framework_validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ export * from "./types.js";
2
+ export * from "./errors.js";
3
+ export * from "./json.js";
4
+ export * from "./model_ids.js";
5
+ export * from "./cache_behavior.js";
6
+ export * from "./cache_scope.js";
7
+ export * from "./fixed_turn_cost_config.js";
8
+ export * from "./cost.js";
9
+ export * from "./fingerprint.js";
10
+ export * from "./compatibility.js";
11
+ export * from "./cache_switch_decision.js";
12
+ export * from "./candidate_pruning.js";
13
+ export * from "./candidate_resolution.js";
14
+ export * from "./previous_decision.js";
15
+ export * from "./prompts.js";
16
+ export * from "./selector_input.js";
17
+ export * from "./selector_truncation.js";
18
+ export * from "./routing_history.js";
19
+ export * from "./selector_request.js";
20
+ export * from "./selector_wire.js";
21
+ export * from "./selector_parse.js";
22
+ export * from "./anonymous_actions.js";
23
+ export * from "./route.js";
24
+ export * from "./framework_error.js";
25
+ export * from "./framework_types.js";
26
+ export * from "./continuation_state.js";
27
+ export * from "./portable_reasoning_state.js";
28
+ export * from "./framework_models.js";
29
+ export * from "./framework_router.js";
30
+ export * from "./pi_runtime.js";
31
+ export * from "./pi_reasoning_signature.js";
32
+ export { openAIChatRequest, openAIChatResponse } from "./protocol_openai_chat.js";
33
+ export { anthropicRequest, anthropicResponse } from "./protocol_anthropic.js";
34
+ export * from "./dari_policy.js";
35
+ export * from "./auto_router.js";
package/dist/index.js ADDED
@@ -0,0 +1,38 @@
1
+ export * from "./types.js";
2
+ export * from "./errors.js";
3
+ export * from "./json.js";
4
+ export * from "./model_ids.js";
5
+ export * from "./cache_behavior.js";
6
+ export * from "./cache_scope.js";
7
+ export * from "./fixed_turn_cost_config.js";
8
+ export * from "./cost.js";
9
+ export * from "./fingerprint.js";
10
+ export * from "./compatibility.js";
11
+ export * from "./cache_switch_decision.js";
12
+ export * from "./candidate_pruning.js";
13
+ export * from "./candidate_resolution.js";
14
+ export * from "./previous_decision.js";
15
+ export * from "./prompts.js";
16
+ export * from "./selector_input.js";
17
+ export * from "./selector_truncation.js";
18
+ export * from "./routing_history.js";
19
+ export * from "./selector_request.js";
20
+ export * from "./selector_wire.js";
21
+ export * from "./selector_parse.js";
22
+ export * from "./anonymous_actions.js";
23
+ export * from "./route.js";
24
+ export * from "./framework_error.js";
25
+ export * from "./framework_types.js";
26
+ export * from "./continuation_state.js";
27
+ export * from "./portable_reasoning_state.js";
28
+ export * from "./framework_models.js";
29
+ export * from "./framework_router.js";
30
+ export * from "./pi_runtime.js";
31
+ export * from "./pi_reasoning_signature.js";
32
+ // The protocol modules' SSE stream writers are framework_router plumbing, not
33
+ // public API; only the request/response codecs are re-exported.
34
+ export { openAIChatRequest, openAIChatResponse } from "./protocol_openai_chat.js";
35
+ export { anthropicRequest, anthropicResponse } from "./protocol_anthropic.js";
36
+ export * from "./dari_policy.js";
37
+ export * from "./auto_router.js";
38
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,6BAA6B,CAAC;AAC5C,8EAA8E;AAC9E,gEAAgE;AAChE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAClF,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC9E,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC"}
package/dist/json.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ export type JsonValue = string | number | boolean | null | JsonValue[] | {
2
+ [key: string]: JsonValue;
3
+ };
4
+ export type JsonObject = {
5
+ [key: string]: JsonValue;
6
+ };
7
+ export declare function requiredString(value: unknown, label: string): string;
8
+ export declare function jsonValue(value: unknown, label: string): JsonValue;
9
+ export declare function jsonRecord(value: unknown, label: string): Record<string, JsonValue>;
10
+ export declare function withoutKeys(value: Readonly<Record<string, JsonValue>>, keys: readonly string[]): JsonObject;
package/dist/json.js ADDED
@@ -0,0 +1,29 @@
1
+ // Small JSON-shape validators shared by modules that consume data across a
2
+ // serialization boundary (recorded routing states, selector inputs, policy
3
+ // completions). Errors read as `<label> <requirement>` so callers can pass
4
+ // precise field paths.
5
+ export function requiredString(value, label) {
6
+ if (typeof value !== "string" || value.length === 0) {
7
+ throw new Error(`${label} must be a non-empty string`);
8
+ }
9
+ return value;
10
+ }
11
+ export function jsonValue(value, label) {
12
+ if (value === undefined)
13
+ throw new Error(`${label} is missing`);
14
+ const serialized = JSON.stringify(value);
15
+ if (serialized === undefined)
16
+ throw new Error(`${label} is not JSON serializable`);
17
+ return JSON.parse(serialized);
18
+ }
19
+ export function jsonRecord(value, label) {
20
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
21
+ throw new Error(`${label} must be an object`);
22
+ }
23
+ return value;
24
+ }
25
+ export function withoutKeys(value, keys) {
26
+ const omitted = new Set(keys);
27
+ return Object.fromEntries(Object.entries(value).filter(([key]) => !omitted.has(key)));
28
+ }
29
+ //# sourceMappingURL=json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["../src/json.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,2EAA2E;AAC3E,2EAA2E;AAC3E,uBAAuB;AAYvB,MAAM,UAAU,cAAc,CAAC,KAAc,EAAE,KAAa;IAC1D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,6BAA6B,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAc,EAAE,KAAa;IACrD,IAAI,KAAK,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,aAAa,CAAC,CAAC;IAChE,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACzC,IAAI,UAAU,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,2BAA2B,CAAC,CAAC;IACnF,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAc,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAc,EAAE,KAAa;IACtD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACxE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,oBAAoB,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,KAAkC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,KAA0C,EAC1C,IAAuB;IAEvB,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACxF,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Provider } from "./types.js";
2
+ export declare function providerForModel(model: string): Provider;
3
+ export declare function nativeModelId(model: string): string;
4
+ export declare function canonicalModelId(modelId: string): string;
@@ -0,0 +1,26 @@
1
+ import { RouterCoreError } from "./errors.js";
2
+ const PROVIDER_PATTERN = /^[a-z][a-z0-9_.-]{0,119}$/;
3
+ export function providerForModel(model) {
4
+ const slash = model.indexOf("/");
5
+ if (slash <= 0) {
6
+ throw new RouterCoreError("invalid_request", `Unsupported model provider for ${model}`, "unsupported_model", "model");
7
+ }
8
+ const provider = model.slice(0, slash).toLowerCase();
9
+ if (!PROVIDER_PATTERN.test(provider)) {
10
+ throw new RouterCoreError("invalid_request", `Unsupported model provider for ${model}`, "unsupported_model", "model");
11
+ }
12
+ return provider;
13
+ }
14
+ export function nativeModelId(model) {
15
+ return model.slice(`${providerForModel(model)}/`.length);
16
+ }
17
+ // providerForModel() lowercases the provider prefix, so lookups keyed on
18
+ // model ids must use the same canonical spelling; the model segment stays
19
+ // case-sensitive (native ids can be), matching providerForModel semantics.
20
+ export function canonicalModelId(modelId) {
21
+ const slash = modelId.indexOf("/");
22
+ if (slash <= 0)
23
+ return modelId;
24
+ return modelId.slice(0, slash).toLowerCase() + modelId.slice(slash);
25
+ }
26
+ //# sourceMappingURL=model_ids.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model_ids.js","sourceRoot":"","sources":["../src/model_ids.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9C,MAAM,gBAAgB,GAAG,2BAA2B,CAAC;AAErD,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QACf,MAAM,IAAI,eAAe,CAAC,iBAAiB,EAAE,kCAAkC,KAAK,EAAE,EAAE,mBAAmB,EAAE,OAAO,CAAC,CAAC;IACxH,CAAC;IACD,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;IACrD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,eAAe,CAAC,iBAAiB,EAAE,kCAAkC,KAAK,EAAE,EAAE,mBAAmB,EAAE,OAAO,CAAC,CAAC;IACxH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,OAAO,KAAK,CAAC,KAAK,CAAC,GAAG,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC3D,CAAC;AAED,yEAAyE;AACzE,0EAA0E;AAC1E,2EAA2E;AAC3E,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,OAAO,CAAC;IAC/B,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,WAAW,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AACtE,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Context } from "@mupt-ai/pi-ai";
2
+ import type { RouterRequest } from "./framework_types.js";
3
+ import type { PiModel } from "./pi_types.js";
4
+ export declare function piContext(request: RouterRequest, model: PiModel): Context;