@jsonstudio/llms 0.6.3379 → 0.6.3409

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 (38) hide show
  1. package/dist/conversion/compat/actions/claude-thinking-tools.d.ts +1 -14
  2. package/dist/conversion/compat/actions/claude-thinking-tools.js +3 -71
  3. package/dist/conversion/compat/actions/lmstudio-responses-fc-ids.d.ts +0 -8
  4. package/dist/conversion/compat/actions/lmstudio-responses-fc-ids.js +2 -57
  5. package/dist/conversion/compat/actions/normalize-tool-call-ids.d.ts +0 -9
  6. package/dist/conversion/compat/actions/normalize-tool-call-ids.js +6 -136
  7. package/dist/conversion/compat/actions/request-rules.js +2 -61
  8. package/dist/conversion/compat/actions/response-blacklist.d.ts +0 -4
  9. package/dist/conversion/compat/actions/response-blacklist.js +2 -77
  10. package/dist/conversion/compat/actions/response-normalize.js +2 -119
  11. package/dist/conversion/compat/actions/response-validate.js +2 -74
  12. package/dist/conversion/compat/actions/strip-orphan-function-calls-tag.js +2 -150
  13. package/dist/conversion/hub/operation-table/semantic-mappers/anthropic-mapper.js +24 -1
  14. package/dist/conversion/hub/pipeline/hub-pipeline.js +91 -0
  15. package/dist/conversion/shared/reasoning-tool-parser.js +7 -8
  16. package/dist/conversion/shared/responses-response-utils.js +3 -48
  17. package/dist/conversion/shared/responses-tool-utils.js +22 -126
  18. package/dist/conversion/shared/tool-call-id-manager.js +18 -21
  19. package/dist/native/router_hotpath_napi.node +0 -0
  20. package/dist/router/virtual-router/bootstrap/routing-config.d.ts +2 -1
  21. package/dist/router/virtual-router/bootstrap/routing-config.js +47 -2
  22. package/dist/router/virtual-router/bootstrap/web-search-config.js +25 -0
  23. package/dist/router/virtual-router/bootstrap.js +21 -16
  24. package/dist/router/virtual-router/engine-selection/native-compat-action-semantics.d.ts +6 -0
  25. package/dist/router/virtual-router/engine-selection/native-compat-action-semantics.js +171 -0
  26. package/dist/router/virtual-router/engine-selection/native-router-hotpath-loader.js +11 -0
  27. package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.d.ts +5 -0
  28. package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.js +137 -0
  29. package/dist/router/virtual-router/engine-selection/tier-load-balancing.d.ts +16 -0
  30. package/dist/router/virtual-router/engine-selection/tier-load-balancing.js +120 -0
  31. package/dist/router/virtual-router/engine-selection/tier-selection-quota-integration.d.ts +2 -0
  32. package/dist/router/virtual-router/engine-selection/tier-selection-quota-integration.js +44 -66
  33. package/dist/router/virtual-router/engine-selection/tier-selection-select.js +53 -84
  34. package/dist/router/virtual-router/types.d.ts +39 -0
  35. package/dist/servertool/handlers/web-search.js +26 -1
  36. package/dist/servertool/server-side-tools.js +11 -2
  37. package/dist/servertool/types.d.ts +4 -0
  38. package/package.json +1 -1
@@ -35,11 +35,9 @@ export class ToolCallIdManager {
35
35
  */
36
36
  generateId() {
37
37
  assertToolCallIdManagerNativeAvailable();
38
- if (this.options.style === 'fc') {
39
- const next = transformToolCallIdWithNative(this.state, '').id;
40
- return next;
41
- }
42
- return normalizeIdValueWithNative(undefined, true);
38
+ const output = transformToolCallIdWithNative(this.state, '');
39
+ this.state = output.state;
40
+ return output.id;
43
41
  }
44
42
  /**
45
43
  * 规范化工具调用 ID
@@ -50,13 +48,9 @@ export class ToolCallIdManager {
50
48
  normalizeId(id) {
51
49
  assertToolCallIdManagerNativeAvailable();
52
50
  const raw = typeof id === 'string' ? id : '';
53
- if (this.options.style === 'fc') {
54
- const output = transformToolCallIdWithNative(this.state, raw);
55
- this.state = output.state;
56
- return output.id;
57
- }
58
- const trimmed = raw.trim();
59
- return trimmed ? trimmed : normalizeIdValueWithNative(undefined, true);
51
+ const output = transformToolCallIdWithNative(this.state, raw);
52
+ this.state = output.state;
53
+ return output.id;
60
54
  }
61
55
  /**
62
56
  * 规范化工具调用 ID(带别名注册)
@@ -68,18 +62,21 @@ export class ToolCallIdManager {
68
62
  normalizeIdWithAlias(id, aliasMap) {
69
63
  assertToolCallIdManagerNativeAvailable();
70
64
  const raw = typeof id === 'string' ? id : '';
71
- if (this.options.style !== 'preserve') {
72
- return this.normalizeId(raw);
73
- }
74
65
  const trimmed = raw.trim();
75
- if (trimmed && aliasMap && aliasMap.has(trimmed)) {
76
- return aliasMap.get(trimmed);
66
+ if (this.options.style === 'preserve' && trimmed && aliasMap?.has(trimmed)) {
67
+ const existing = aliasMap.get(trimmed);
68
+ const aliasState = this.state.aliasMap;
69
+ if (aliasState && typeof aliasState === 'object') {
70
+ aliasState[trimmed] = existing;
71
+ }
72
+ return existing;
77
73
  }
78
- const value = trimmed || normalizeIdValueWithNative(undefined, true);
79
- if (trimmed && aliasMap) {
80
- aliasMap.set(trimmed, value);
74
+ const output = transformToolCallIdWithNative(this.state, raw);
75
+ this.state = output.state;
76
+ if (this.options.style === 'preserve' && trimmed && aliasMap) {
77
+ aliasMap.set(trimmed, output.id);
81
78
  }
82
- return value;
79
+ return output.id;
83
80
  }
84
81
  /**
85
82
  * 批量规范化工具调用 ID
@@ -1,4 +1,4 @@
1
- import { type RoutingPools } from '../types.js';
1
+ import { type RoutingPools, type RoutePoolLoadBalancingPolicy } from '../types.js';
2
2
  export interface NormalizedRoutePoolConfig {
3
3
  id: string;
4
4
  priority: number;
@@ -6,6 +6,7 @@ export interface NormalizedRoutePoolConfig {
6
6
  targets: string[];
7
7
  mode?: 'round-robin' | 'priority';
8
8
  force?: boolean;
9
+ loadBalancing?: RoutePoolLoadBalancingPolicy;
9
10
  }
10
11
  export declare function normalizeRouting(source: Record<string, unknown>): Record<string, NormalizedRoutePoolConfig[]>;
11
12
  export declare function expandRoutingTable(routingSource: Record<string, NormalizedRoutePoolConfig[]>, aliasIndex: Map<string, string[]>, modelIndex: Map<string, {
@@ -91,7 +91,8 @@ export function expandRoutingTable(routingSource, aliasIndex, modelIndex) {
91
91
  backup: pool.backup,
92
92
  targets: sortedTargets,
93
93
  ...(pool.mode ? { mode: pool.mode } : {}),
94
- ...(pool.force ? { force: true } : {})
94
+ ...(pool.force ? { force: true } : {}),
95
+ ...(pool.loadBalancing ? { loadBalancing: pool.loadBalancing } : {})
95
96
  });
96
97
  }
97
98
  }
@@ -134,6 +135,7 @@ function normalizeRoutePoolEntry(routeName, entry, index, total) {
134
135
  const mode = normalizeRoutePoolMode(record.mode ?? record.strategy ?? record.routingMode);
135
136
  const force = record.force === true ||
136
137
  (typeof record.force === 'string' && record.force.trim().toLowerCase() === 'true');
138
+ const loadBalancing = normalizeRoutePoolLoadBalancing(record.loadBalancing);
137
139
  return targets.length
138
140
  ? {
139
141
  id,
@@ -141,10 +143,53 @@ function normalizeRoutePoolEntry(routeName, entry, index, total) {
141
143
  backup,
142
144
  targets,
143
145
  ...(mode ? { mode } : {}),
144
- ...(force ? { force: true } : {})
146
+ ...(force ? { force: true } : {}),
147
+ ...(loadBalancing ? { loadBalancing } : {})
145
148
  }
146
149
  : null;
147
150
  }
151
+ function normalizeRoutePoolLoadBalancing(input) {
152
+ if (!input || typeof input !== 'object' || Array.isArray(input)) {
153
+ return undefined;
154
+ }
155
+ const record = input;
156
+ const strategy = normalizeWeightedStrategy(record.strategy);
157
+ const weightsRaw = record.weights && typeof record.weights === 'object' && !Array.isArray(record.weights)
158
+ ? record.weights
159
+ : {};
160
+ const weights = {};
161
+ for (const [key, value] of Object.entries(weightsRaw)) {
162
+ if (typeof value === 'number' && Number.isFinite(value) && value > 0) {
163
+ weights[key] = value;
164
+ }
165
+ }
166
+ if (!strategy && Object.keys(weights).length === 0) {
167
+ return undefined;
168
+ }
169
+ return {
170
+ ...(strategy ? { strategy } : {}),
171
+ ...(Object.keys(weights).length ? { weights } : {})
172
+ };
173
+ }
174
+ function normalizeWeightedStrategy(value) {
175
+ if (typeof value !== 'string') {
176
+ return undefined;
177
+ }
178
+ const normalized = value.trim().toLowerCase();
179
+ if (!normalized) {
180
+ return undefined;
181
+ }
182
+ if (normalized === 'weighted') {
183
+ return 'weighted';
184
+ }
185
+ if (normalized === 'sticky') {
186
+ return 'sticky';
187
+ }
188
+ if (normalized === 'round-robin' || normalized === 'round_robin' || normalized === 'roundrobin' || normalized === 'rr') {
189
+ return 'round-robin';
190
+ }
191
+ return undefined;
192
+ }
148
193
  function normalizeRoutePoolMode(value) {
149
194
  if (typeof value !== 'string') {
150
195
  return undefined;
@@ -37,6 +37,27 @@ export function normalizeWebSearch(input, routingSource) {
37
37
  const resolvedProviderKey = resolveWebSearchEngineProviderKey(providerKey, webSearchRouteTargets) ?? providerKey;
38
38
  const description = typeof node.description === 'string' && node.description.trim() ? node.description.trim() : undefined;
39
39
  const isDefault = node.default === true || (typeof node.default === 'string' && node.default.trim().toLowerCase() === 'true');
40
+ const rawExecutionMode = typeof node.executionMode === 'string'
41
+ ? node.executionMode.trim().toLowerCase()
42
+ : typeof node.mode === 'string'
43
+ ? node.mode.trim().toLowerCase()
44
+ : '';
45
+ const executionMode = rawExecutionMode === 'direct' ? 'direct' : 'servertool';
46
+ const rawDirectActivation = typeof node.directActivation === 'string'
47
+ ? node.directActivation.trim().toLowerCase()
48
+ : typeof node.activation === 'string'
49
+ ? node.activation.trim().toLowerCase()
50
+ : '';
51
+ const directActivation = rawDirectActivation === 'builtin'
52
+ ? 'builtin'
53
+ : rawDirectActivation === 'route'
54
+ ? 'route'
55
+ : executionMode === 'direct'
56
+ ? 'route'
57
+ : undefined;
58
+ const modelId = typeof node.modelId === 'string' && node.modelId.trim() ? node.modelId.trim() : undefined;
59
+ const maxUsesRaw = typeof node.maxUses === 'number' ? node.maxUses : Number(node.maxUses);
60
+ const maxUses = Number.isFinite(maxUsesRaw) && maxUsesRaw > 0 ? Math.floor(maxUsesRaw) : undefined;
40
61
  const serverToolsDisabled = node.serverToolsDisabled === true ||
41
62
  (typeof node.serverToolsDisabled === 'string' &&
42
63
  node.serverToolsDisabled.trim().toLowerCase() === 'true') ||
@@ -51,6 +72,10 @@ export function normalizeWebSearch(input, routingSource) {
51
72
  providerKey: resolvedProviderKey,
52
73
  description,
53
74
  default: isDefault,
75
+ executionMode,
76
+ ...(directActivation ? { directActivation } : {}),
77
+ ...(modelId ? { modelId } : {}),
78
+ ...(maxUses ? { maxUses } : {}),
54
79
  ...(serverToolsDisabled ? { serverToolsDisabled: true } : {})
55
80
  });
56
81
  }
@@ -140,26 +140,31 @@ function buildProviderRuntimeEntries(providers) {
140
140
  }
141
141
  return { runtimeEntries, aliasIndex, modelIndex };
142
142
  }
143
- function collectProviderModels(providerRaw, normalizedProvider) {
143
+ function collectProviderModels(providerRaw, _normalizedProvider) {
144
144
  const rawModelsNode = providerRaw.models;
145
145
  const modelsDeclared = rawModelsNode !== undefined;
146
146
  const modelsNode = asRecord(rawModelsNode);
147
- const baseModels = Object.keys(modelsNode).filter(Boolean);
148
- if (normalizedProvider.compatibilityProfile !== 'chat:deepseek-web') {
149
- return { declared: modelsDeclared, models: baseModels };
150
- }
151
- const withAliases = new Set(baseModels);
152
- const hasChatBase = withAliases.has('deepseek-chat') || withAliases.has('deepseek-v3');
153
- const hasReasonerBase = withAliases.has('deepseek-reasoner') || withAliases.has('deepseek-r1');
154
- if (hasChatBase) {
155
- withAliases.add('deepseek-chat-search');
156
- withAliases.add('deepseek-v3-search');
157
- }
158
- if (hasReasonerBase) {
159
- withAliases.add('deepseek-reasoner-search');
160
- withAliases.add('deepseek-r1-search');
147
+ const collected = new Set();
148
+ for (const [modelName, modelConfigRaw] of Object.entries(modelsNode)) {
149
+ const normalizedModelName = typeof modelName === 'string' ? modelName.trim() : '';
150
+ if (normalizedModelName) {
151
+ collected.add(normalizedModelName);
152
+ }
153
+ const modelConfig = asRecord(modelConfigRaw);
154
+ const aliasesNode = Array.isArray(modelConfig.aliases)
155
+ ? modelConfig.aliases
156
+ : [];
157
+ for (const alias of aliasesNode) {
158
+ if (typeof alias !== 'string') {
159
+ continue;
160
+ }
161
+ const normalizedAlias = alias.trim();
162
+ if (normalizedAlias) {
163
+ collected.add(normalizedAlias);
164
+ }
165
+ }
161
166
  }
162
- return { declared: modelsDeclared, models: Array.from(withAliases) };
167
+ return { declared: modelsDeclared, models: Array.from(collected) };
163
168
  }
164
169
  function normalizeClassifier(input) {
165
170
  const normalized = asRecord(input);
@@ -0,0 +1,6 @@
1
+ export declare function normalizeResponsePayloadWithNative(payload: Record<string, unknown>, config?: Record<string, unknown>): Record<string, unknown>;
2
+ export declare function validateResponsePayloadWithNative(payload: Record<string, unknown>): void;
3
+ export declare function applyRequestRulesWithNative(payload: Record<string, unknown>, config?: Record<string, unknown>): Record<string, unknown>;
4
+ export declare function applyResponseBlacklistWithNative(payload: Record<string, unknown>, config?: Record<string, unknown>): Record<string, unknown>;
5
+ export declare function normalizeToolCallIdsWithNative(payload: Record<string, unknown>): Record<string, unknown>;
6
+ export declare function enforceLmstudioResponsesFcToolCallIdsWithNative(payload: Record<string, unknown>): Record<string, unknown>;
@@ -0,0 +1,171 @@
1
+ import { failNativeRequired, isNativeDisabledByEnv } from './native-router-hotpath-policy.js';
2
+ import { loadNativeRouterHotpathBindingForInternalUse } from './native-router-hotpath.js';
3
+ function readNativeFunction(name) {
4
+ const binding = loadNativeRouterHotpathBindingForInternalUse();
5
+ const fn = binding?.[name];
6
+ return typeof fn === 'function' ? fn : null;
7
+ }
8
+ function safeStringify(value) {
9
+ try {
10
+ return JSON.stringify(value);
11
+ }
12
+ catch {
13
+ return undefined;
14
+ }
15
+ }
16
+ function parseRecord(raw) {
17
+ try {
18
+ const parsed = JSON.parse(raw);
19
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
20
+ return null;
21
+ }
22
+ return parsed;
23
+ }
24
+ catch {
25
+ return null;
26
+ }
27
+ }
28
+ export function normalizeResponsePayloadWithNative(payload, config) {
29
+ const capability = 'normalizeResponsePayloadJson';
30
+ const fail = (reason) => failNativeRequired(capability, reason);
31
+ if (isNativeDisabledByEnv()) {
32
+ return fail('native disabled');
33
+ }
34
+ const fn = readNativeFunction(capability);
35
+ if (!fn) {
36
+ return fail();
37
+ }
38
+ const payloadJson = safeStringify(payload);
39
+ const configJson = config ? safeStringify(config) : '{}';
40
+ if (!payloadJson || !configJson) {
41
+ return fail('json stringify failed');
42
+ }
43
+ try {
44
+ const raw = fn(payloadJson, configJson);
45
+ if (typeof raw !== 'string' || !raw) {
46
+ return fail('empty result');
47
+ }
48
+ const parsed = parseRecord(raw);
49
+ return parsed ?? fail('invalid payload');
50
+ }
51
+ catch (error) {
52
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
53
+ return fail(reason);
54
+ }
55
+ }
56
+ export function validateResponsePayloadWithNative(payload) {
57
+ const capability = 'validateResponsePayloadJson';
58
+ const fail = (reason) => failNativeRequired(capability, reason);
59
+ if (isNativeDisabledByEnv()) {
60
+ return fail('native disabled');
61
+ }
62
+ const fn = readNativeFunction(capability);
63
+ if (!fn) {
64
+ return fail();
65
+ }
66
+ const payloadJson = safeStringify(payload);
67
+ if (!payloadJson) {
68
+ return fail('json stringify failed');
69
+ }
70
+ try {
71
+ fn(payloadJson);
72
+ }
73
+ catch (error) {
74
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
75
+ throw new Error(reason);
76
+ }
77
+ }
78
+ export function applyRequestRulesWithNative(payload, config) {
79
+ const capability = 'applyRequestRulesJson';
80
+ const fail = (reason) => failNativeRequired(capability, reason);
81
+ if (isNativeDisabledByEnv())
82
+ return fail('native disabled');
83
+ const fn = readNativeFunction(capability);
84
+ if (!fn)
85
+ return fail();
86
+ const payloadJson = safeStringify(payload);
87
+ const configJson = config ? safeStringify(config) : '{}';
88
+ if (!payloadJson || !configJson)
89
+ return fail('json stringify failed');
90
+ try {
91
+ const raw = fn(payloadJson, configJson);
92
+ if (typeof raw !== 'string' || !raw)
93
+ return fail('empty result');
94
+ const parsed = parseRecord(raw);
95
+ return parsed ?? fail('invalid payload');
96
+ }
97
+ catch (error) {
98
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
99
+ return fail(reason);
100
+ }
101
+ }
102
+ export function applyResponseBlacklistWithNative(payload, config) {
103
+ const capability = 'applyResponseBlacklistJson';
104
+ const fail = (reason) => failNativeRequired(capability, reason);
105
+ if (isNativeDisabledByEnv())
106
+ return fail('native disabled');
107
+ const fn = readNativeFunction(capability);
108
+ if (!fn)
109
+ return fail();
110
+ const payloadJson = safeStringify(payload);
111
+ const configJson = config ? safeStringify(config) : '{}';
112
+ if (!payloadJson || !configJson)
113
+ return fail('json stringify failed');
114
+ try {
115
+ const raw = fn(payloadJson, configJson);
116
+ if (typeof raw !== 'string' || !raw)
117
+ return fail('empty result');
118
+ const parsed = parseRecord(raw);
119
+ return parsed ?? fail('invalid payload');
120
+ }
121
+ catch (error) {
122
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
123
+ return fail(reason);
124
+ }
125
+ }
126
+ export function normalizeToolCallIdsWithNative(payload) {
127
+ const capability = 'normalizeToolCallIdsJson';
128
+ const fail = (reason) => failNativeRequired(capability, reason);
129
+ if (isNativeDisabledByEnv())
130
+ return fail('native disabled');
131
+ const fn = readNativeFunction(capability);
132
+ if (!fn)
133
+ return fail();
134
+ const payloadJson = safeStringify(payload);
135
+ if (!payloadJson)
136
+ return fail('json stringify failed');
137
+ try {
138
+ const raw = fn(payloadJson);
139
+ if (typeof raw !== 'string' || !raw)
140
+ return fail('empty result');
141
+ const parsed = parseRecord(raw);
142
+ return parsed ?? fail('invalid payload');
143
+ }
144
+ catch (error) {
145
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
146
+ return fail(reason);
147
+ }
148
+ }
149
+ export function enforceLmstudioResponsesFcToolCallIdsWithNative(payload) {
150
+ const capability = 'enforceLmstudioResponsesFcToolCallIdsJson';
151
+ const fail = (reason) => failNativeRequired(capability, reason);
152
+ if (isNativeDisabledByEnv())
153
+ return fail('native disabled');
154
+ const fn = readNativeFunction(capability);
155
+ if (!fn)
156
+ return fail();
157
+ const payloadJson = safeStringify(payload);
158
+ if (!payloadJson)
159
+ return fail('json stringify failed');
160
+ try {
161
+ const raw = fn(payloadJson);
162
+ if (typeof raw !== 'string' || !raw)
163
+ return fail('empty result');
164
+ const parsed = parseRecord(raw);
165
+ return parsed ?? fail('invalid payload');
166
+ }
167
+ catch (error) {
168
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
169
+ return fail(reason);
170
+ }
171
+ }
@@ -98,6 +98,8 @@ const REQUIRED_NATIVE_EXPORTS = [
98
98
  'chatToolToBridgeDefinitionJson',
99
99
  'mapBridgeToolsToChatWithOptionsJson',
100
100
  'mapChatToolsToBridgeWithOptionsJson',
101
+ 'collectToolCallsFromResponsesJson',
102
+ 'resolveFinishReasonJson',
101
103
  'captureReqInboundResponsesContextSnapshotJson',
102
104
  'computeQuotaBucketsJson',
103
105
  'extractReasoningSegmentsJson',
@@ -167,6 +169,15 @@ const REQUIRED_NATIVE_EXPORTS = [
167
169
  'normalizeChatResponseReasoningToolsJson',
168
170
  'normalizeBridgeToolCallIdsJson',
169
171
  'normalizeChatMessageContentJson',
172
+ 'validateResponsePayloadJson',
173
+ 'normalizeResponsePayloadJson',
174
+ 'applyResponseBlacklistJson',
175
+ 'normalizeToolCallIdsJson',
176
+ 'normalizeResponsesToolCallIdsJson',
177
+ 'resolveToolCallIdStyleJson',
178
+ 'stripInternalToolingMetadataJson',
179
+ 'enforceLmstudioResponsesFcToolCallIdsJson',
180
+ 'applyRequestRulesJson',
170
181
  'normalizeArgsBySchemaJson',
171
182
  'normalizeToolsJson',
172
183
  'normalizeFunctionCallIdJson',
@@ -26,6 +26,8 @@ export declare function mapBridgeToolsToChatWithNative(rawTools: unknown, option
26
26
  export declare function mapChatToolsToBridgeWithNative(rawTools: unknown, options?: {
27
27
  sanitizeMode?: string;
28
28
  }): Array<Record<string, unknown>>;
29
+ export declare function collectToolCallsFromResponsesWithNative(response: Record<string, unknown>): Array<Record<string, unknown>>;
30
+ export declare function resolveFinishReasonWithNative(response: Record<string, unknown>, toolCalls: Array<Record<string, unknown>>): string;
29
31
  export declare function hasValidThoughtSignatureWithNative(block: unknown, options?: Record<string, unknown>): boolean;
30
32
  export declare function sanitizeThinkingBlockWithNative(block: unknown): Record<string, unknown>;
31
33
  export declare function filterInvalidThinkingBlocksWithNative(messages: unknown, options?: Record<string, unknown>): unknown[];
@@ -49,6 +51,9 @@ export declare function enforceToolCallIdStyleWithNative(messages: unknown[], st
49
51
  messages: unknown[];
50
52
  state: Record<string, unknown>;
51
53
  };
54
+ export declare function normalizeResponsesToolCallIdsWithNative(payload: unknown): Record<string, unknown> | null;
55
+ export declare function resolveToolCallIdStyleWithNative(metadata: unknown): string;
56
+ export declare function stripInternalToolingMetadataWithNative(metadata: unknown): Record<string, unknown> | null;
52
57
  export declare function buildProviderProtocolErrorWithNative(input: {
53
58
  message: string;
54
59
  code: string;
@@ -123,6 +123,10 @@ function parseToolDefinitionArray(raw) {
123
123
  }
124
124
  return output;
125
125
  }
126
+ function parseString(raw) {
127
+ const parsed = parseJson(raw);
128
+ return typeof parsed === 'string' ? parsed : null;
129
+ }
126
130
  function parseStringArray(raw) {
127
131
  const parsed = parseArray(raw);
128
132
  if (!parsed)
@@ -510,6 +514,60 @@ export function mapChatToolsToBridgeWithNative(rawTools, options) {
510
514
  return fail(reason);
511
515
  }
512
516
  }
517
+ export function collectToolCallsFromResponsesWithNative(response) {
518
+ const capability = 'collectToolCallsFromResponsesJson';
519
+ const fail = (reason) => failNativeRequired(capability, reason);
520
+ if (isNativeDisabledByEnv()) {
521
+ return fail('native disabled');
522
+ }
523
+ const fn = readNativeFunction(capability);
524
+ if (!fn) {
525
+ return fail();
526
+ }
527
+ const payloadJson = safeStringify(response ?? {});
528
+ if (!payloadJson) {
529
+ return fail('json stringify failed');
530
+ }
531
+ try {
532
+ const raw = fn(payloadJson);
533
+ if (typeof raw !== 'string' || !raw) {
534
+ return fail('empty result');
535
+ }
536
+ const parsed = parseToolDefinitionArray(raw);
537
+ return parsed ?? fail('invalid payload');
538
+ }
539
+ catch (error) {
540
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
541
+ return fail(reason);
542
+ }
543
+ }
544
+ export function resolveFinishReasonWithNative(response, toolCalls) {
545
+ const capability = 'resolveFinishReasonJson';
546
+ const fail = (reason) => failNativeRequired(capability, reason);
547
+ if (isNativeDisabledByEnv()) {
548
+ return fail('native disabled');
549
+ }
550
+ const fn = readNativeFunction(capability);
551
+ if (!fn) {
552
+ return fail();
553
+ }
554
+ const responseJson = safeStringify(response ?? {});
555
+ const toolCallsJson = safeStringify(Array.isArray(toolCalls) ? toolCalls : []);
556
+ if (!responseJson || !toolCallsJson) {
557
+ return fail('json stringify failed');
558
+ }
559
+ try {
560
+ const raw = fn(responseJson, toolCallsJson);
561
+ if (typeof raw !== 'string' || !raw) {
562
+ return fail('empty result');
563
+ }
564
+ return parseString(raw) ?? fail('invalid payload');
565
+ }
566
+ catch (error) {
567
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
568
+ return fail(reason);
569
+ }
570
+ }
513
571
  export function hasValidThoughtSignatureWithNative(block, options) {
514
572
  const capability = 'hasValidThoughtSignatureJson';
515
573
  const fail = (reason) => failNativeRequired(capability, reason);
@@ -973,6 +1031,85 @@ export function enforceToolCallIdStyleWithNative(messages, state) {
973
1031
  return fail(reason);
974
1032
  }
975
1033
  }
1034
+ export function normalizeResponsesToolCallIdsWithNative(payload) {
1035
+ const capability = 'normalizeResponsesToolCallIdsJson';
1036
+ const fail = (reason) => failNativeRequired(capability, reason);
1037
+ if (isNativeDisabledByEnv()) {
1038
+ return fail('native disabled');
1039
+ }
1040
+ const fn = readNativeFunction(capability);
1041
+ if (!fn) {
1042
+ return fail();
1043
+ }
1044
+ const payloadJson = safeStringify(payload ?? null);
1045
+ if (!payloadJson) {
1046
+ return fail('json stringify failed');
1047
+ }
1048
+ try {
1049
+ const raw = fn(payloadJson);
1050
+ if (typeof raw !== 'string' || !raw) {
1051
+ return fail('empty result');
1052
+ }
1053
+ return parseRecord(raw) ?? fail('invalid payload');
1054
+ }
1055
+ catch (error) {
1056
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
1057
+ return fail(reason);
1058
+ }
1059
+ }
1060
+ export function resolveToolCallIdStyleWithNative(metadata) {
1061
+ const capability = 'resolveToolCallIdStyleJson';
1062
+ const fail = (reason) => failNativeRequired(capability, reason);
1063
+ if (isNativeDisabledByEnv()) {
1064
+ return fail('native disabled');
1065
+ }
1066
+ const fn = readNativeFunction(capability);
1067
+ if (!fn) {
1068
+ return fail();
1069
+ }
1070
+ const metadataJson = safeStringify(metadata ?? null);
1071
+ if (!metadataJson) {
1072
+ return fail('json stringify failed');
1073
+ }
1074
+ try {
1075
+ const raw = fn(metadataJson);
1076
+ if (typeof raw !== 'string' || !raw) {
1077
+ return fail('empty result');
1078
+ }
1079
+ const parsed = parseJson(raw);
1080
+ return typeof parsed === 'string' ? parsed : fail('invalid payload');
1081
+ }
1082
+ catch (error) {
1083
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
1084
+ return fail(reason);
1085
+ }
1086
+ }
1087
+ export function stripInternalToolingMetadataWithNative(metadata) {
1088
+ const capability = 'stripInternalToolingMetadataJson';
1089
+ const fail = (reason) => failNativeRequired(capability, reason);
1090
+ if (isNativeDisabledByEnv()) {
1091
+ return fail('native disabled');
1092
+ }
1093
+ const fn = readNativeFunction(capability);
1094
+ if (!fn) {
1095
+ return fail();
1096
+ }
1097
+ const metadataJson = safeStringify(metadata ?? null);
1098
+ if (!metadataJson) {
1099
+ return fail('json stringify failed');
1100
+ }
1101
+ try {
1102
+ const raw = fn(metadataJson);
1103
+ if (typeof raw !== 'string' || !raw) {
1104
+ return fail('empty result');
1105
+ }
1106
+ return parseRecord(raw) ?? fail('invalid payload');
1107
+ }
1108
+ catch (error) {
1109
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
1110
+ return fail(reason);
1111
+ }
1112
+ }
976
1113
  export function buildProviderProtocolErrorWithNative(input) {
977
1114
  const capability = 'buildProviderProtocolErrorJson';
978
1115
  const fail = (reason) => failNativeRequired(capability, reason);
@@ -0,0 +1,16 @@
1
+ import type { LoadBalancingPolicy, RoutePoolTier } from '../types.js';
2
+ import type { ProviderRegistry } from '../provider-registry.js';
3
+ export type ResolvedTierLoadBalancing = {
4
+ strategy: LoadBalancingPolicy['strategy'];
5
+ weights?: Record<string, number>;
6
+ };
7
+ export declare function resolveTierLoadBalancing(tier: RoutePoolTier, globalPolicy?: LoadBalancingPolicy): ResolvedTierLoadBalancing;
8
+ export declare function resolveGroupWeight(groupId: string, weights?: Record<string, number>): number;
9
+ export declare function buildGroupWeights(groups: Map<string, string[]>, weights?: Record<string, number>): Record<string, number> | undefined;
10
+ export declare function hasNonUniformWeights(candidates: string[], weights?: Record<string, number>): boolean;
11
+ export declare function buildCandidateWeights(opts: {
12
+ candidates: string[];
13
+ providerRegistry: ProviderRegistry;
14
+ staticWeights?: Record<string, number>;
15
+ dynamicWeights?: Record<string, number>;
16
+ }): Record<string, number> | undefined;