@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.
- package/LICENSE +202 -0
- package/README.md +100 -0
- package/dist/anonymous_actions.d.ts +55 -0
- package/dist/anonymous_actions.js +277 -0
- package/dist/anonymous_actions.js.map +1 -0
- package/dist/auto_router.d.ts +10 -0
- package/dist/auto_router.js +56 -0
- package/dist/auto_router.js.map +1 -0
- package/dist/cache_behavior.d.ts +14 -0
- package/dist/cache_behavior.js +112 -0
- package/dist/cache_behavior.js.map +1 -0
- package/dist/cache_scope.d.ts +5 -0
- package/dist/cache_scope.js +49 -0
- package/dist/cache_scope.js.map +1 -0
- package/dist/cache_switch_decision.d.ts +24 -0
- package/dist/cache_switch_decision.js +21 -0
- package/dist/cache_switch_decision.js.map +1 -0
- package/dist/candidate_pruning.d.ts +45 -0
- package/dist/candidate_pruning.js +154 -0
- package/dist/candidate_pruning.js.map +1 -0
- package/dist/candidate_resolution.d.ts +41 -0
- package/dist/candidate_resolution.js +111 -0
- package/dist/candidate_resolution.js.map +1 -0
- package/dist/compatibility.d.ts +22 -0
- package/dist/compatibility.js +76 -0
- package/dist/compatibility.js.map +1 -0
- package/dist/continuation_state.d.ts +36 -0
- package/dist/continuation_state.js +249 -0
- package/dist/continuation_state.js.map +1 -0
- package/dist/cost.d.ts +31 -0
- package/dist/cost.js +314 -0
- package/dist/cost.js.map +1 -0
- package/dist/dari_policy.d.ts +34 -0
- package/dist/dari_policy.js +267 -0
- package/dist/dari_policy.js.map +1 -0
- package/dist/errors.d.ts +7 -0
- package/dist/errors.js +14 -0
- package/dist/errors.js.map +1 -0
- package/dist/fingerprint.d.ts +13 -0
- package/dist/fingerprint.js +130 -0
- package/dist/fingerprint.js.map +1 -0
- package/dist/fixed_turn_cost_config.d.ts +9 -0
- package/dist/fixed_turn_cost_config.js +22 -0
- package/dist/fixed_turn_cost_config.js.map +1 -0
- package/dist/framework_error.d.ts +8 -0
- package/dist/framework_error.js +24 -0
- package/dist/framework_error.js.map +1 -0
- package/dist/framework_lifecycle.d.ts +11 -0
- package/dist/framework_lifecycle.js +57 -0
- package/dist/framework_lifecycle.js.map +1 -0
- package/dist/framework_models.d.ts +3 -0
- package/dist/framework_models.js +120 -0
- package/dist/framework_models.js.map +1 -0
- package/dist/framework_router.d.ts +2 -0
- package/dist/framework_router.js +384 -0
- package/dist/framework_router.js.map +1 -0
- package/dist/framework_streaming.d.ts +26 -0
- package/dist/framework_streaming.js +486 -0
- package/dist/framework_streaming.js.map +1 -0
- package/dist/framework_types.d.ts +272 -0
- package/dist/framework_types.js +5 -0
- package/dist/framework_types.js.map +1 -0
- package/dist/framework_validation.d.ts +7 -0
- package/dist/framework_validation.js +169 -0
- package/dist/framework_validation.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/json.d.ts +10 -0
- package/dist/json.js +29 -0
- package/dist/json.js.map +1 -0
- package/dist/model_ids.d.ts +4 -0
- package/dist/model_ids.js +26 -0
- package/dist/model_ids.js.map +1 -0
- package/dist/pi_context.d.ts +4 -0
- package/dist/pi_context.js +206 -0
- package/dist/pi_context.js.map +1 -0
- package/dist/pi_options.d.ts +3 -0
- package/dist/pi_options.js +240 -0
- package/dist/pi_options.js.map +1 -0
- package/dist/pi_output.d.ts +4 -0
- package/dist/pi_output.js +328 -0
- package/dist/pi_output.js.map +1 -0
- package/dist/pi_reasoning_signature.d.ts +10 -0
- package/dist/pi_reasoning_signature.js +33 -0
- package/dist/pi_reasoning_signature.js.map +1 -0
- package/dist/pi_runtime.d.ts +3 -0
- package/dist/pi_runtime.js +155 -0
- package/dist/pi_runtime.js.map +1 -0
- package/dist/pi_types.d.ts +35 -0
- package/dist/pi_types.js +2 -0
- package/dist/pi_types.js.map +1 -0
- package/dist/portable_reasoning_state.d.ts +7 -0
- package/dist/portable_reasoning_state.js +81 -0
- package/dist/portable_reasoning_state.js.map +1 -0
- package/dist/previous_decision.d.ts +13 -0
- package/dist/previous_decision.js +82 -0
- package/dist/previous_decision.js.map +1 -0
- package/dist/prompts.d.ts +3 -0
- package/dist/prompts.js +65 -0
- package/dist/prompts.js.map +1 -0
- package/dist/protocol_anthropic.d.ts +18 -0
- package/dist/protocol_anthropic.js +443 -0
- package/dist/protocol_anthropic.js.map +1 -0
- package/dist/protocol_openai_chat.d.ts +25 -0
- package/dist/protocol_openai_chat.js +503 -0
- package/dist/protocol_openai_chat.js.map +1 -0
- package/dist/protocol_validation.d.ts +23 -0
- package/dist/protocol_validation.js +134 -0
- package/dist/protocol_validation.js.map +1 -0
- package/dist/route.d.ts +105 -0
- package/dist/route.js +226 -0
- package/dist/route.js.map +1 -0
- package/dist/routing_history.d.ts +7 -0
- package/dist/routing_history.js +132 -0
- package/dist/routing_history.js.map +1 -0
- package/dist/selector_input.d.ts +42 -0
- package/dist/selector_input.js +153 -0
- package/dist/selector_input.js.map +1 -0
- package/dist/selector_parse.d.ts +13 -0
- package/dist/selector_parse.js +95 -0
- package/dist/selector_parse.js.map +1 -0
- package/dist/selector_request.d.ts +26 -0
- package/dist/selector_request.js +85 -0
- package/dist/selector_request.js.map +1 -0
- package/dist/selector_truncation.d.ts +2 -0
- package/dist/selector_truncation.js +48 -0
- package/dist/selector_truncation.js.map +1 -0
- package/dist/selector_wire.d.ts +10 -0
- package/dist/selector_wire.js +113 -0
- package/dist/selector_wire.js.map +1 -0
- package/dist/types.d.ts +152 -0
- package/dist/types.js +14 -0
- package/dist/types.js.map +1 -0
- package/package.json +64 -0
- package/src/anonymous_actions.ts +434 -0
- package/src/auto_router.ts +95 -0
- package/src/cache_behavior.ts +130 -0
- package/src/cache_scope.ts +58 -0
- package/src/cache_switch_decision.ts +53 -0
- package/src/candidate_pruning.ts +257 -0
- package/src/candidate_resolution.ts +208 -0
- package/src/compatibility.ts +162 -0
- package/src/continuation_state.ts +368 -0
- package/src/cost.ts +455 -0
- package/src/dari_policy.ts +360 -0
- package/src/errors.ts +27 -0
- package/src/fingerprint.ts +148 -0
- package/src/fixed_turn_cost_config.ts +24 -0
- package/src/framework_error.ts +38 -0
- package/src/framework_lifecycle.ts +74 -0
- package/src/framework_models.ts +186 -0
- package/src/framework_router.ts +490 -0
- package/src/framework_streaming.ts +613 -0
- package/src/framework_types.ts +372 -0
- package/src/framework_validation.ts +235 -0
- package/src/index.ts +37 -0
- package/src/json.ts +43 -0
- package/src/model_ids.ts +29 -0
- package/src/pi_context.ts +251 -0
- package/src/pi_options.ts +295 -0
- package/src/pi_output.ts +387 -0
- package/src/pi_reasoning_signature.ts +41 -0
- package/src/pi_runtime.ts +238 -0
- package/src/pi_types.ts +71 -0
- package/src/portable_reasoning_state.ts +129 -0
- package/src/previous_decision.ts +109 -0
- package/src/prompts.ts +69 -0
- package/src/protocol_anthropic.ts +571 -0
- package/src/protocol_openai_chat.ts +645 -0
- package/src/protocol_validation.ts +202 -0
- package/src/route.ts +490 -0
- package/src/routing_history.ts +157 -0
- package/src/selector_input.ts +246 -0
- package/src/selector_parse.ts +138 -0
- package/src/selector_request.ts +130 -0
- package/src/selector_truncation.ts +48 -0
- package/src/selector_wire.ts +167 -0
- package/src/types.ts +231 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { MIN_SWITCH_SAVINGS_RATIO, pruneSwitchCandidates, } from "./candidate_pruning.js";
|
|
2
|
+
import { routingCandidateKey, } from "./types.js";
|
|
3
|
+
export function resolveStrategyCandidates(args) {
|
|
4
|
+
if (args.strategy === "slm") {
|
|
5
|
+
const pruned = pruneSwitchCandidates({
|
|
6
|
+
candidates: args.candidates,
|
|
7
|
+
costEstimates: args.costEstimates,
|
|
8
|
+
previousDecision: args.previousDecision,
|
|
9
|
+
minSwitchSavingsRatio: MIN_SWITCH_SAVINGS_RATIO,
|
|
10
|
+
});
|
|
11
|
+
return {
|
|
12
|
+
strategy: "slm",
|
|
13
|
+
candidates: pruned.candidates,
|
|
14
|
+
costEstimates: pruned.costEstimates,
|
|
15
|
+
pruning: pruned.audit,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
const config = args.customConfig;
|
|
19
|
+
if (!config || !Array.isArray(config.rules) || config.rules.length === 0) {
|
|
20
|
+
return {
|
|
21
|
+
strategy: "custom",
|
|
22
|
+
candidates: [],
|
|
23
|
+
costEstimates: [],
|
|
24
|
+
pruning: null,
|
|
25
|
+
custom: null,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
return resolveCustomCandidates(args, config);
|
|
29
|
+
}
|
|
30
|
+
function resolveCustomCandidates(args, config) {
|
|
31
|
+
const usableRules = config.rules.filter((rule) => args.candidates.some((candidate) => matchesRule(candidate, rule)));
|
|
32
|
+
const defaultModel = typeof config.default === "string" ? config.default : null;
|
|
33
|
+
const defaultTarget = defaultModel !== null &&
|
|
34
|
+
args.candidates.some((candidate) => matchesTarget(candidate, defaultModel, config.default_thinking_level))
|
|
35
|
+
? {
|
|
36
|
+
model: defaultModel,
|
|
37
|
+
thinkingLevel: config.default_thinking_level ?? null,
|
|
38
|
+
}
|
|
39
|
+
: null;
|
|
40
|
+
const matchesDefault = (candidate) => defaultTarget !== null &&
|
|
41
|
+
matchesTarget(candidate, defaultTarget.model, defaultTarget.thinkingLevel);
|
|
42
|
+
const configuredCandidates = orderCandidatesByCostDesc(args.candidates.filter((candidate) => usableRules.some((rule) => matchesRule(candidate, rule)) ||
|
|
43
|
+
matchesDefault(candidate)), args.modelPrices);
|
|
44
|
+
const pruned = pruneSwitchCandidates({
|
|
45
|
+
candidates: configuredCandidates,
|
|
46
|
+
costEstimates: reorderEstimates(args.costEstimates, configuredCandidates),
|
|
47
|
+
previousDecision: args.previousDecision,
|
|
48
|
+
minSwitchSavingsRatio: MIN_SWITCH_SAVINGS_RATIO,
|
|
49
|
+
});
|
|
50
|
+
const ruleOrder = (rule) => pruned.candidates.findIndex((candidate) => matchesRule(candidate, rule));
|
|
51
|
+
return {
|
|
52
|
+
strategy: "custom",
|
|
53
|
+
candidates: pruned.candidates,
|
|
54
|
+
costEstimates: pruned.costEstimates,
|
|
55
|
+
pruning: pruned.audit,
|
|
56
|
+
custom: {
|
|
57
|
+
rules: usableRules
|
|
58
|
+
.filter((rule) => ruleOrder(rule) >= 0)
|
|
59
|
+
.sort((a, b) => ruleOrder(a) - ruleOrder(b)),
|
|
60
|
+
defaultTarget: pruned.candidates.some(matchesDefault)
|
|
61
|
+
? defaultTarget
|
|
62
|
+
: null,
|
|
63
|
+
audit: {
|
|
64
|
+
dropped_rules: config.rules.filter((rule) => !usableRules.includes(rule)),
|
|
65
|
+
fallback_all_candidates: false,
|
|
66
|
+
no_routable_rule_models: configuredCandidates.length === 0,
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function matchesRule(candidate, rule) {
|
|
72
|
+
return matchesTarget(candidate, rule.use, rule.thinking_level);
|
|
73
|
+
}
|
|
74
|
+
function matchesTarget(candidate, model, thinkingLevel) {
|
|
75
|
+
return candidate.model === model &&
|
|
76
|
+
(thinkingLevel == null || candidate.reasoningEffort === thinkingLevel);
|
|
77
|
+
}
|
|
78
|
+
// Catalog rates are model-scoped, so sorting remains stable across a model's
|
|
79
|
+
// thinking-level variants.
|
|
80
|
+
function orderCandidatesByCostDesc(candidates, modelPrices) {
|
|
81
|
+
return [...candidates].sort((a, b) => {
|
|
82
|
+
const priceA = usablePrice(modelPrices[a.model]);
|
|
83
|
+
const priceB = usablePrice(modelPrices[b.model]);
|
|
84
|
+
if (priceA === null && priceB === null)
|
|
85
|
+
return 0;
|
|
86
|
+
if (priceA === null)
|
|
87
|
+
return 1;
|
|
88
|
+
if (priceB === null)
|
|
89
|
+
return -1;
|
|
90
|
+
return priceB.output - priceA.output || priceB.input - priceA.input;
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
function usablePrice(price) {
|
|
94
|
+
return price && Number.isFinite(price.input) && Number.isFinite(price.output)
|
|
95
|
+
? price
|
|
96
|
+
: null;
|
|
97
|
+
}
|
|
98
|
+
function reorderEstimates(estimates, candidates) {
|
|
99
|
+
const byCandidate = new Map(estimates.map((estimate) => [
|
|
100
|
+
routingCandidateKey({
|
|
101
|
+
model: estimate.model,
|
|
102
|
+
reasoningEffort: estimate.reasoning_effort,
|
|
103
|
+
}),
|
|
104
|
+
estimate,
|
|
105
|
+
]));
|
|
106
|
+
return candidates.flatMap((candidate) => {
|
|
107
|
+
const estimate = byCandidate.get(routingCandidateKey(candidate));
|
|
108
|
+
return estimate ? [estimate] : [];
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=candidate_resolution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"candidate_resolution.js","sourceRoot":"","sources":["../src/candidate_resolution.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type HardCapability, type ReasoningEffort, type RoutingCandidate } from "./types.js";
|
|
2
|
+
export type CandidateModelMetadata = {
|
|
3
|
+
provider: string;
|
|
4
|
+
api: string;
|
|
5
|
+
supportsImageInput: boolean;
|
|
6
|
+
supportsHostedWebSearch: boolean;
|
|
7
|
+
supportsStructuredOutput: boolean;
|
|
8
|
+
supportedThinkingLevels: string[];
|
|
9
|
+
};
|
|
10
|
+
export type CandidateMetadataLookup = (modelId: string) => CandidateModelMetadata;
|
|
11
|
+
export type CompatibleCandidates = {
|
|
12
|
+
candidates: RoutingCandidate[];
|
|
13
|
+
};
|
|
14
|
+
export declare function resolveCompatibleCandidates(args: {
|
|
15
|
+
requiredCapabilities: readonly HardCapability[];
|
|
16
|
+
requestedReasoningEffort?: ReasoningEffort;
|
|
17
|
+
thinkingEnabled?: boolean;
|
|
18
|
+
toolChoice?: unknown;
|
|
19
|
+
candidateModels: string[];
|
|
20
|
+
metadataLookup: CandidateMetadataLookup;
|
|
21
|
+
modelThinkingLevels?: Readonly<Record<string, ReasoningEffort[]>>;
|
|
22
|
+
}): CompatibleCandidates;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { RouterCoreError } from "./errors.js";
|
|
2
|
+
import { isReasoningEffort, } from "./types.js";
|
|
3
|
+
export function resolveCompatibleCandidates(args) {
|
|
4
|
+
const compatible = [];
|
|
5
|
+
let anthropicToolChoiceRejected = false;
|
|
6
|
+
let metaToolChoiceRejected = false;
|
|
7
|
+
let candidates = args.candidateModels.map((model) => ({
|
|
8
|
+
model,
|
|
9
|
+
metadata: args.metadataLookup(model),
|
|
10
|
+
}));
|
|
11
|
+
if (args.requiredCapabilities.includes("image_input")) {
|
|
12
|
+
candidates = candidates.filter(({ metadata }) => metadata.supportsImageInput);
|
|
13
|
+
if (candidates.length === 0) {
|
|
14
|
+
throw new RouterCoreError("invalid_request", "Image input is not supported by any enabled model for this router.", "unsupported_input_modality");
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
if (args.requiredCapabilities.includes("structured_output")) {
|
|
18
|
+
candidates = candidates.filter(({ metadata }) => metadata.supportsStructuredOutput);
|
|
19
|
+
if (candidates.length === 0) {
|
|
20
|
+
throw new RouterCoreError("invalid_request", "Structured output is not supported by any enabled model for this router.", "unsupported_response_format", "response_format");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (args.requiredCapabilities.includes("openai_hosted_web_search")) {
|
|
24
|
+
candidates = candidates.filter(({ metadata }) => metadata.supportsHostedWebSearch);
|
|
25
|
+
if (candidates.length === 0) {
|
|
26
|
+
throw new RouterCoreError("invalid_request", "Hosted web search requires an enabled OpenAI or Azure Responses model for this router.", "unsupported_tool", "tools");
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const requested = args.requestedReasoningEffort;
|
|
30
|
+
for (const { model, metadata } of candidates) {
|
|
31
|
+
if (metadata.provider === "meta" &&
|
|
32
|
+
args.toolChoice !== undefined &&
|
|
33
|
+
args.toolChoice !== "auto") {
|
|
34
|
+
metaToolChoiceRejected = true;
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
const supportedLevels = metadata.supportedThinkingLevels.filter(isReasoningEffort);
|
|
38
|
+
const configuredLevels = args.modelThinkingLevels?.[model] ?? supportedLevels;
|
|
39
|
+
const enabledLevels = configuredLevels.filter((level) => isReasoningEffort(level) && supportedLevels.includes(level));
|
|
40
|
+
const levels = requested === undefined
|
|
41
|
+
? args.thinkingEnabled
|
|
42
|
+
? enabledLevels.filter((level) => level !== "off")
|
|
43
|
+
: enabledLevels
|
|
44
|
+
: enabledLevels.includes(requested)
|
|
45
|
+
? [requested]
|
|
46
|
+
: [];
|
|
47
|
+
for (const reasoningEffort of levels) {
|
|
48
|
+
if (reasoningEffort !== "off" &&
|
|
49
|
+
metadata.api === "anthropic-messages" &&
|
|
50
|
+
forcesToolUse(args.toolChoice)) {
|
|
51
|
+
anthropicToolChoiceRejected = true;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
compatible.push({ model, reasoningEffort });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (compatible.length > 0)
|
|
58
|
+
return { candidates: compatible };
|
|
59
|
+
if (anthropicToolChoiceRejected) {
|
|
60
|
+
throw new RouterCoreError("invalid_request", "Forced tool choice is not supported by any enabled model at the requested reasoning setting.", "unsupported_tool_choice", "tool_choice");
|
|
61
|
+
}
|
|
62
|
+
if (metaToolChoiceRejected) {
|
|
63
|
+
throw new RouterCoreError("invalid_request", "Meta models currently support only omitted or 'auto' tool_choice.", "unsupported_tool_choice", "tool_choice");
|
|
64
|
+
}
|
|
65
|
+
throw new RouterCoreError("invalid_request", requested === undefined
|
|
66
|
+
? args.thinkingEnabled
|
|
67
|
+
? "Thinking is enabled, but no enabled non-off model/thinking-level pair is compatible with this request."
|
|
68
|
+
: "No enabled model/thinking-level pair is compatible with this request."
|
|
69
|
+
: `reasoning_effort '${requested}' is not supported by any enabled model for this router.`, "unsupported_reasoning_effort", requested === undefined ? undefined : "reasoning_effort");
|
|
70
|
+
}
|
|
71
|
+
function forcesToolUse(choice) {
|
|
72
|
+
return choice === "required" ||
|
|
73
|
+
choice === "any" ||
|
|
74
|
+
(typeof choice === "object" && choice !== null);
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=compatibility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compatibility.js","sourceRoot":"","sources":["../src/compatibility.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EACL,iBAAiB,GAIlB,MAAM,YAAY,CAAC;AAwBpB,MAAM,UAAU,2BAA2B,CAAC,IAc3C;IACC,MAAM,UAAU,GAAuB,EAAE,CAAC;IAC1C,IAAI,2BAA2B,GAAG,KAAK,CAAC;IACxC,IAAI,sBAAsB,GAAG,KAAK,CAAC;IACnC,IAAI,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACpD,KAAK;QACL,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC;KACrC,CAAC,CAAC,CAAC;IAEJ,IAAI,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QACtD,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;QAC9E,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,eAAe,CACvB,iBAAiB,EACjB,oEAAoE,EACpE,4BAA4B,CAC7B,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;QAC5D,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAC;QACpF,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,eAAe,CACvB,iBAAiB,EACjB,0EAA0E,EAC1E,6BAA6B,EAC7B,iBAAiB,CAClB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,0BAA0B,CAAC,EAAE,CAAC;QACnE,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAAC;QACnF,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,eAAe,CACvB,iBAAiB,EACjB,wFAAwF,EACxF,kBAAkB,EAClB,OAAO,CACR,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,wBAAwB,CAAC;IAChD,KAAK,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,UAAU,EAAE,CAAC;QAC7C,IACE,QAAQ,CAAC,QAAQ,KAAK,MAAM;YAC5B,IAAI,CAAC,UAAU,KAAK,SAAS;YAC7B,IAAI,CAAC,UAAU,KAAK,MAAM,EAC1B,CAAC;YACD,sBAAsB,GAAG,IAAI,CAAC;YAC9B,SAAS;QACX,CAAC;QACD,MAAM,eAAe,GAAG,QAAQ,CAAC,uBAAuB,CAAC,MAAM,CAC7D,iBAAiB,CAClB,CAAC;QACF,MAAM,gBAAgB,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC,KAAK,CAAC,IAAI,eAAe,CAAC;QAC9E,MAAM,aAAa,GAAG,gBAAgB,CAAC,MAAM,CAC3C,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC,IAAI,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,CACvE,CAAC;QACF,MAAM,MAAM,GAAG,SAAS,KAAK,SAAS;YACpC,CAAC,CAAC,IAAI,CAAC,eAAe;gBACpB,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC;gBAClD,CAAC,CAAC,aAAa;YACjB,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC;gBACjC,CAAC,CAAC,CAAC,SAAS,CAAC;gBACb,CAAC,CAAC,EAAE,CAAC;QACT,KAAK,MAAM,eAAe,IAAI,MAAM,EAAE,CAAC;YACrC,IACE,eAAe,KAAK,KAAK;gBACzB,QAAQ,CAAC,GAAG,KAAK,oBAAoB;gBACrC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,EAC9B,CAAC;gBACD,2BAA2B,GAAG,IAAI,CAAC;gBACnC,SAAS;YACX,CAAC;YACD,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC;IAE7D,IAAI,2BAA2B,EAAE,CAAC;QAChC,MAAM,IAAI,eAAe,CACvB,iBAAiB,EACjB,8FAA8F,EAC9F,yBAAyB,EACzB,aAAa,CACd,CAAC;IACJ,CAAC;IAED,IAAI,sBAAsB,EAAE,CAAC;QAC3B,MAAM,IAAI,eAAe,CACvB,iBAAiB,EACjB,mEAAmE,EACnE,yBAAyB,EACzB,aAAa,CACd,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,eAAe,CACvB,iBAAiB,EACjB,SAAS,KAAK,SAAS;QACrB,CAAC,CAAC,IAAI,CAAC,eAAe;YACpB,CAAC,CAAC,wGAAwG;YAC1G,CAAC,CAAC,uEAAuE;QAC3E,CAAC,CAAC,qBAAqB,SAAS,0DAA0D,EAC5F,8BAA8B,EAC9B,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,kBAAkB,CACzD,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,MAAe;IACpC,OAAO,MAAM,KAAK,UAAU;QAC1B,MAAM,KAAK,KAAK;QAChB,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export type ProviderIdentity = {
|
|
2
|
+
provider: string;
|
|
3
|
+
api: string;
|
|
4
|
+
model: string;
|
|
5
|
+
};
|
|
6
|
+
export type ProviderContinuationState = {
|
|
7
|
+
kind: "openai_reasoning";
|
|
8
|
+
source: ProviderIdentity;
|
|
9
|
+
encryptedContent: string;
|
|
10
|
+
providerItemId?: string;
|
|
11
|
+
hostedToolCallIds?: string[];
|
|
12
|
+
hostedToolCallOffsets?: number[];
|
|
13
|
+
} | {
|
|
14
|
+
kind: "anthropic_thinking";
|
|
15
|
+
source: ProviderIdentity;
|
|
16
|
+
thinking: string;
|
|
17
|
+
signature: string;
|
|
18
|
+
} | {
|
|
19
|
+
kind: "anthropic_redacted_thinking";
|
|
20
|
+
source: ProviderIdentity;
|
|
21
|
+
data: string;
|
|
22
|
+
};
|
|
23
|
+
/** @deprecated Alias kept for the framework-prefixed vocabulary; use {@link ProviderIdentity}. */
|
|
24
|
+
export type RouterProviderIdentity = ProviderIdentity;
|
|
25
|
+
/** @deprecated Alias kept for the framework-prefixed vocabulary; use {@link ProviderContinuationState}. */
|
|
26
|
+
export type RouterContinuationState = ProviderContinuationState;
|
|
27
|
+
export declare function encodeProviderContinuationState(value: ProviderContinuationState): string;
|
|
28
|
+
export declare function decodeUntrustedProviderContinuationState(value: string): ProviderContinuationState | null;
|
|
29
|
+
export declare function isOpenAIResponsesApi(api: string): boolean;
|
|
30
|
+
export declare function compatibleProviderContinuation(continuation: ProviderContinuationState | undefined, target: ProviderIdentity | null): ProviderContinuationState | null;
|
|
31
|
+
export declare function sameProviderIdentity(a: ProviderIdentity, b: ProviderIdentity): boolean;
|
|
32
|
+
export declare function providerIdentityFromModel(model: {
|
|
33
|
+
provider?: unknown;
|
|
34
|
+
api?: unknown;
|
|
35
|
+
id?: unknown;
|
|
36
|
+
}): ProviderIdentity;
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { RouterFrameworkError } from "./framework_error.js";
|
|
2
|
+
import { isRecord } from "./types.js";
|
|
3
|
+
const PREFIX = "dari-pcs-v1.";
|
|
4
|
+
const FAMILY_PREFIX = "dari-pcs-";
|
|
5
|
+
const MAX_JSON_BYTES = 4 * 1024 * 1024;
|
|
6
|
+
const MAX_ENCODED_CHARS = Math.ceil(MAX_JSON_BYTES / 3) * 4;
|
|
7
|
+
const MAX_PROVIDER_LENGTH = 128;
|
|
8
|
+
const MAX_API_LENGTH = 128;
|
|
9
|
+
const MAX_MODEL_LENGTH = 512;
|
|
10
|
+
const MAX_ITEM_ID_LENGTH = 512;
|
|
11
|
+
const MAX_HOSTED_TOOL_CALL_IDS = 256;
|
|
12
|
+
const MAX_HOSTED_TOOL_CALL_OFFSET = 1_000_000;
|
|
13
|
+
export function encodeProviderContinuationState(value) {
|
|
14
|
+
const envelope = envelopeFor(value);
|
|
15
|
+
validateEnvelope(envelope, "configuration");
|
|
16
|
+
const json = JSON.stringify(envelope);
|
|
17
|
+
if (Buffer.byteLength(json, "utf8") > MAX_JSON_BYTES) {
|
|
18
|
+
throw invalidState("configuration", "Provider continuation state exceeds the encoded size limit.");
|
|
19
|
+
}
|
|
20
|
+
return `${PREFIX}${Buffer.from(json, "utf8").toString("base64url")}`;
|
|
21
|
+
}
|
|
22
|
+
export function decodeUntrustedProviderContinuationState(value) {
|
|
23
|
+
if (!value.startsWith(FAMILY_PREFIX))
|
|
24
|
+
return null;
|
|
25
|
+
if (!value.startsWith(PREFIX)) {
|
|
26
|
+
throw invalidState("invalid_request", "Provider continuation state version is not supported.");
|
|
27
|
+
}
|
|
28
|
+
const encoded = value.slice(PREFIX.length);
|
|
29
|
+
if (!encoded || encoded.length > MAX_ENCODED_CHARS || !/^[A-Za-z0-9_-]+$/.test(encoded)) {
|
|
30
|
+
throw invalidState("invalid_request", "Provider continuation state encoding is invalid.");
|
|
31
|
+
}
|
|
32
|
+
const bytes = Buffer.from(encoded, "base64url");
|
|
33
|
+
if (bytes.length > MAX_JSON_BYTES || bytes.toString("base64url") !== encoded) {
|
|
34
|
+
throw invalidState("invalid_request", "Provider continuation state encoding is invalid.");
|
|
35
|
+
}
|
|
36
|
+
let decoded;
|
|
37
|
+
try {
|
|
38
|
+
decoded = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
throw invalidState("invalid_request", "Provider continuation state payload is invalid.");
|
|
42
|
+
}
|
|
43
|
+
return stateFromEnvelope(validateEnvelope(decoded, "invalid_request"));
|
|
44
|
+
}
|
|
45
|
+
export function isOpenAIResponsesApi(api) {
|
|
46
|
+
return api === "openai-responses" || api === "azure-openai-responses";
|
|
47
|
+
}
|
|
48
|
+
export function compatibleProviderContinuation(continuation, target) {
|
|
49
|
+
if (!continuation || !target || !sameProviderIdentity(continuation.source, target))
|
|
50
|
+
return null;
|
|
51
|
+
if (continuation.kind === "openai_reasoning") {
|
|
52
|
+
return isOpenAIResponsesApi(target.api) ? continuation : null;
|
|
53
|
+
}
|
|
54
|
+
return target.api === "anthropic-messages" ? continuation : null;
|
|
55
|
+
}
|
|
56
|
+
export function sameProviderIdentity(a, b) {
|
|
57
|
+
return a.provider === b.provider && a.api === b.api && a.model === b.model;
|
|
58
|
+
}
|
|
59
|
+
export function providerIdentityFromModel(model) {
|
|
60
|
+
if (typeof model.provider !== "string" || typeof model.api !== "string" || typeof model.id !== "string") {
|
|
61
|
+
throw new RouterFrameworkError("configuration", "Selected model metadata is missing provider identity.", "provider_configuration_error");
|
|
62
|
+
}
|
|
63
|
+
return { provider: model.provider, api: model.api, model: model.id };
|
|
64
|
+
}
|
|
65
|
+
function envelopeFor(value) {
|
|
66
|
+
if (value.kind === "openai_reasoning") {
|
|
67
|
+
return {
|
|
68
|
+
v: 1,
|
|
69
|
+
kind: value.kind,
|
|
70
|
+
source: value.source,
|
|
71
|
+
state: {
|
|
72
|
+
encrypted_content: value.encryptedContent,
|
|
73
|
+
...(value.providerItemId ? { item_id: value.providerItemId } : {}),
|
|
74
|
+
...(value.hostedToolCallIds?.length
|
|
75
|
+
? { hosted_tool_call_ids: JSON.stringify(value.hostedToolCallIds) }
|
|
76
|
+
: {}),
|
|
77
|
+
...(value.hostedToolCallOffsets?.length
|
|
78
|
+
? { hosted_tool_call_offsets: JSON.stringify(value.hostedToolCallOffsets) }
|
|
79
|
+
: {}),
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (value.kind === "anthropic_thinking") {
|
|
84
|
+
return {
|
|
85
|
+
v: 1,
|
|
86
|
+
kind: value.kind,
|
|
87
|
+
source: value.source,
|
|
88
|
+
state: { thinking: value.thinking, signature: value.signature },
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
return { v: 1, kind: value.kind, source: value.source, state: { data: value.data } };
|
|
92
|
+
}
|
|
93
|
+
function stateFromEnvelope(envelope) {
|
|
94
|
+
if (envelope.kind === "openai_reasoning") {
|
|
95
|
+
return {
|
|
96
|
+
kind: envelope.kind,
|
|
97
|
+
source: envelope.source,
|
|
98
|
+
encryptedContent: envelope.state.encrypted_content,
|
|
99
|
+
...(envelope.state.item_id ? { providerItemId: envelope.state.item_id } : {}),
|
|
100
|
+
...(envelope.state.hosted_tool_call_ids
|
|
101
|
+
? {
|
|
102
|
+
hostedToolCallIds: hostedToolCallIds(envelope.state.hosted_tool_call_ids, "invalid_request"),
|
|
103
|
+
...(envelope.state.hosted_tool_call_offsets
|
|
104
|
+
? {
|
|
105
|
+
hostedToolCallOffsets: hostedToolCallOffsets(envelope.state.hosted_tool_call_offsets, "invalid_request"),
|
|
106
|
+
}
|
|
107
|
+
: {}),
|
|
108
|
+
}
|
|
109
|
+
: {}),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
if (envelope.kind === "anthropic_thinking") {
|
|
113
|
+
return {
|
|
114
|
+
kind: envelope.kind,
|
|
115
|
+
source: envelope.source,
|
|
116
|
+
thinking: envelope.state.thinking,
|
|
117
|
+
signature: envelope.state.signature,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
return { kind: envelope.kind, source: envelope.source, data: envelope.state.data };
|
|
121
|
+
}
|
|
122
|
+
function validateEnvelope(value, kind) {
|
|
123
|
+
if (!isRecord(value) || !hasExactKeys(value, ["v", "kind", "source", "state"]) || value.v !== 1) {
|
|
124
|
+
throw invalidState(kind, "Provider continuation state schema is invalid.");
|
|
125
|
+
}
|
|
126
|
+
if (value.kind !== "openai_reasoning" &&
|
|
127
|
+
value.kind !== "anthropic_thinking" &&
|
|
128
|
+
value.kind !== "anthropic_redacted_thinking") {
|
|
129
|
+
throw invalidState(kind, "Provider continuation state kind is invalid.");
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
v: 1,
|
|
133
|
+
kind: value.kind,
|
|
134
|
+
source: validateSource(value.source, kind),
|
|
135
|
+
state: validateState(value.kind, value.state, kind),
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function validateSource(value, kind) {
|
|
139
|
+
if (!isRecord(value) || !hasExactKeys(value, ["provider", "api", "model"])) {
|
|
140
|
+
throw invalidState(kind, "Provider continuation state source is invalid.");
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
provider: boundedString(value.provider, MAX_PROVIDER_LENGTH, kind, "provider"),
|
|
144
|
+
api: boundedString(value.api, MAX_API_LENGTH, kind, "api"),
|
|
145
|
+
model: boundedString(value.model, MAX_MODEL_LENGTH, kind, "model"),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function validateState(continuationKind, value, errorKind) {
|
|
149
|
+
if (!isRecord(value)) {
|
|
150
|
+
throw invalidState(errorKind, "Provider continuation state payload is invalid.");
|
|
151
|
+
}
|
|
152
|
+
if (continuationKind === "openai_reasoning") {
|
|
153
|
+
const keys = Object.keys(value);
|
|
154
|
+
const keysValid = keys.includes("encrypted_content")
|
|
155
|
+
&& keys.every((key) => key === "encrypted_content"
|
|
156
|
+
|| key === "item_id"
|
|
157
|
+
|| key === "hosted_tool_call_ids"
|
|
158
|
+
|| key === "hosted_tool_call_offsets");
|
|
159
|
+
if (!keysValid || (value.hosted_tool_call_offsets !== undefined && value.hosted_tool_call_ids === undefined)) {
|
|
160
|
+
throw invalidState(errorKind, "OpenAI continuation state schema is invalid.");
|
|
161
|
+
}
|
|
162
|
+
const ids = value.hosted_tool_call_ids === undefined
|
|
163
|
+
? undefined
|
|
164
|
+
: hostedToolCallIds(nonEmptyString(value.hosted_tool_call_ids, errorKind, "hosted_tool_call_ids"), errorKind);
|
|
165
|
+
const offsets = value.hosted_tool_call_offsets === undefined
|
|
166
|
+
? undefined
|
|
167
|
+
: hostedToolCallOffsets(nonEmptyString(value.hosted_tool_call_offsets, errorKind, "hosted_tool_call_offsets"), errorKind);
|
|
168
|
+
if (ids && offsets && ids.length !== offsets.length) {
|
|
169
|
+
throw invalidState(errorKind, "OpenAI hosted tool continuation state is invalid.");
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
encrypted_content: nonEmptyString(value.encrypted_content, errorKind, "encrypted_content"),
|
|
173
|
+
...(value.item_id === undefined
|
|
174
|
+
? {}
|
|
175
|
+
: { item_id: boundedString(value.item_id, MAX_ITEM_ID_LENGTH, errorKind, "item_id") }),
|
|
176
|
+
...(ids ? { hosted_tool_call_ids: JSON.stringify(ids) } : {}),
|
|
177
|
+
...(offsets ? { hosted_tool_call_offsets: JSON.stringify(offsets) } : {}),
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
if (continuationKind === "anthropic_thinking") {
|
|
181
|
+
if (!hasExactKeys(value, ["thinking", "signature"])) {
|
|
182
|
+
throw invalidState(errorKind, "Anthropic thinking state schema is invalid.");
|
|
183
|
+
}
|
|
184
|
+
if (typeof value.thinking !== "string") {
|
|
185
|
+
throw invalidState(errorKind, "Anthropic thinking text is invalid.");
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
thinking: value.thinking,
|
|
189
|
+
signature: nonEmptyString(value.signature, errorKind, "signature"),
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
if (!hasExactKeys(value, ["data"])) {
|
|
193
|
+
throw invalidState(errorKind, "Anthropic redacted thinking state schema is invalid.");
|
|
194
|
+
}
|
|
195
|
+
return { data: nonEmptyString(value.data, errorKind, "data") };
|
|
196
|
+
}
|
|
197
|
+
function hostedToolCallIds(value, kind) {
|
|
198
|
+
let parsed;
|
|
199
|
+
try {
|
|
200
|
+
parsed = JSON.parse(value);
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
throw invalidState(kind, "OpenAI hosted tool continuation state is invalid.");
|
|
204
|
+
}
|
|
205
|
+
if (!Array.isArray(parsed) || parsed.length === 0 || parsed.length > MAX_HOSTED_TOOL_CALL_IDS) {
|
|
206
|
+
throw invalidState(kind, "OpenAI hosted tool continuation state is invalid.");
|
|
207
|
+
}
|
|
208
|
+
return parsed.map((id) => boundedString(id, MAX_ITEM_ID_LENGTH, kind, "hosted_tool_call_id"));
|
|
209
|
+
}
|
|
210
|
+
function hostedToolCallOffsets(value, kind) {
|
|
211
|
+
let parsed;
|
|
212
|
+
try {
|
|
213
|
+
parsed = JSON.parse(value);
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
throw invalidState(kind, "OpenAI hosted tool continuation state is invalid.");
|
|
217
|
+
}
|
|
218
|
+
if (!Array.isArray(parsed) || parsed.length === 0 || parsed.length > MAX_HOSTED_TOOL_CALL_IDS) {
|
|
219
|
+
throw invalidState(kind, "OpenAI hosted tool continuation state is invalid.");
|
|
220
|
+
}
|
|
221
|
+
return parsed.map((offset) => {
|
|
222
|
+
if (!Number.isSafeInteger(offset) || offset === 0 || Math.abs(offset) > MAX_HOSTED_TOOL_CALL_OFFSET) {
|
|
223
|
+
throw invalidState(kind, "OpenAI hosted tool continuation state is invalid.");
|
|
224
|
+
}
|
|
225
|
+
return offset;
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
function boundedString(value, maxLength, kind, field) {
|
|
229
|
+
const text = nonEmptyString(value, kind, field);
|
|
230
|
+
if (text.length > maxLength) {
|
|
231
|
+
throw invalidState(kind, `Provider continuation state ${field} is too long.`);
|
|
232
|
+
}
|
|
233
|
+
return text;
|
|
234
|
+
}
|
|
235
|
+
function nonEmptyString(value, kind, field) {
|
|
236
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
237
|
+
throw invalidState(kind, `Provider continuation state ${field} must be a non-empty string.`);
|
|
238
|
+
}
|
|
239
|
+
return value;
|
|
240
|
+
}
|
|
241
|
+
function hasExactKeys(value, expected) {
|
|
242
|
+
const keys = Object.keys(value).sort();
|
|
243
|
+
const expectedKeys = [...expected].sort();
|
|
244
|
+
return keys.length === expectedKeys.length && keys.every((key, index) => key === expectedKeys[index]);
|
|
245
|
+
}
|
|
246
|
+
function invalidState(kind, message) {
|
|
247
|
+
return new RouterFrameworkError(kind, message, "invalid_provider_continuation_state", "input.reasoning.encrypted_content");
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=continuation_state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"continuation_state.js","sourceRoot":"","sources":["../src/continuation_state.ts"],"names":[],"mappings":"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"}
|
package/dist/cost.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type ReasoningCacheScopeLookup } from "./cache_scope.js";
|
|
2
|
+
import type { CandidateCostEstimate, ChainHits, FixedTurnCostEstimate, PrefixHit, ReasoningEffort, RouterPrefixHit, RoutingCandidate } from "./types.js";
|
|
3
|
+
export declare const CHARS_PER_TOKEN = 4;
|
|
4
|
+
export type ModelPricing = {
|
|
5
|
+
input: number;
|
|
6
|
+
output: number;
|
|
7
|
+
cacheRead: number;
|
|
8
|
+
cacheWrite: number;
|
|
9
|
+
};
|
|
10
|
+
export type PricingLookup = (model: string) => ModelPricing | null;
|
|
11
|
+
export type CandidatePromptEstimate = {
|
|
12
|
+
chars: number;
|
|
13
|
+
reusesStoredPromptTokens: boolean;
|
|
14
|
+
};
|
|
15
|
+
export declare function deriveModelChainHits(chainsByModel: ReadonlyMap<string, string[]>, hits: RouterPrefixHit[] | undefined): ChainHits;
|
|
16
|
+
export declare function deepestIdentityHit(chainsByModel: ReadonlyMap<string, string[]>, looseChain: readonly string[] | undefined, hits: RouterPrefixHit[] | undefined): PrefixHit | undefined;
|
|
17
|
+
export declare function selectPrefixHit(hits: ChainHits, model: string, reasoningBucket: string, cacheScope?: ReasoningCacheScopeLookup): PrefixHit | undefined;
|
|
18
|
+
export declare function selectPromptAnchor(hits: ChainHits, model: string, reasoningBucket: string, cacheScope?: ReasoningCacheScopeLookup): PrefixHit | undefined;
|
|
19
|
+
export declare function estimateCandidateCosts(args: {
|
|
20
|
+
candidates: RoutingCandidate[];
|
|
21
|
+
hits: ChainHits;
|
|
22
|
+
incomingBlockCount: number;
|
|
23
|
+
incomingProviderBlockCountFor?: (model: string) => number;
|
|
24
|
+
promptEstimatesByCandidate: ReadonlyMap<string, CandidatePromptEstimate>;
|
|
25
|
+
toolChoiceFp: string;
|
|
26
|
+
responseFormatFp: string;
|
|
27
|
+
pricing: PricingLookup;
|
|
28
|
+
averageOutputTokensByModel?: Readonly<Record<string, Partial<Record<ReasoningEffort, number>> | null>>;
|
|
29
|
+
cacheScope?: ReasoningCacheScopeLookup;
|
|
30
|
+
}): CandidateCostEstimate[];
|
|
31
|
+
export declare function turnCostUsdAt(estimate: FixedTurnCostEstimate | null | undefined, turns: number): number | null;
|