@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.
- package/dist/conversion/compat/actions/claude-thinking-tools.d.ts +1 -14
- package/dist/conversion/compat/actions/claude-thinking-tools.js +3 -71
- package/dist/conversion/compat/actions/lmstudio-responses-fc-ids.d.ts +0 -8
- package/dist/conversion/compat/actions/lmstudio-responses-fc-ids.js +2 -57
- package/dist/conversion/compat/actions/normalize-tool-call-ids.d.ts +0 -9
- package/dist/conversion/compat/actions/normalize-tool-call-ids.js +6 -136
- package/dist/conversion/compat/actions/request-rules.js +2 -61
- package/dist/conversion/compat/actions/response-blacklist.d.ts +0 -4
- package/dist/conversion/compat/actions/response-blacklist.js +2 -77
- package/dist/conversion/compat/actions/response-normalize.js +2 -119
- package/dist/conversion/compat/actions/response-validate.js +2 -74
- package/dist/conversion/compat/actions/strip-orphan-function-calls-tag.js +2 -150
- package/dist/conversion/hub/operation-table/semantic-mappers/anthropic-mapper.js +24 -1
- package/dist/conversion/hub/pipeline/hub-pipeline.js +91 -0
- package/dist/conversion/shared/reasoning-tool-parser.js +7 -8
- package/dist/conversion/shared/responses-response-utils.js +3 -48
- package/dist/conversion/shared/responses-tool-utils.js +22 -126
- package/dist/conversion/shared/tool-call-id-manager.js +18 -21
- package/dist/native/router_hotpath_napi.node +0 -0
- package/dist/router/virtual-router/bootstrap/routing-config.d.ts +2 -1
- package/dist/router/virtual-router/bootstrap/routing-config.js +47 -2
- package/dist/router/virtual-router/bootstrap/web-search-config.js +25 -0
- package/dist/router/virtual-router/bootstrap.js +21 -16
- package/dist/router/virtual-router/engine-selection/native-compat-action-semantics.d.ts +6 -0
- package/dist/router/virtual-router/engine-selection/native-compat-action-semantics.js +171 -0
- package/dist/router/virtual-router/engine-selection/native-router-hotpath-loader.js +11 -0
- package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.d.ts +5 -0
- package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.js +137 -0
- package/dist/router/virtual-router/engine-selection/tier-load-balancing.d.ts +16 -0
- package/dist/router/virtual-router/engine-selection/tier-load-balancing.js +120 -0
- package/dist/router/virtual-router/engine-selection/tier-selection-quota-integration.d.ts +2 -0
- package/dist/router/virtual-router/engine-selection/tier-selection-quota-integration.js +44 -66
- package/dist/router/virtual-router/engine-selection/tier-selection-select.js +53 -84
- package/dist/router/virtual-router/types.d.ts +39 -0
- package/dist/servertool/handlers/web-search.js +26 -1
- package/dist/servertool/server-side-tools.js +11 -2
- package/dist/servertool/types.d.ts +4 -0
- package/package.json +1 -1
|
@@ -35,11 +35,9 @@ export class ToolCallIdManager {
|
|
|
35
35
|
*/
|
|
36
36
|
generateId() {
|
|
37
37
|
assertToolCallIdManagerNativeAvailable();
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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 (
|
|
76
|
-
|
|
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
|
|
79
|
-
|
|
80
|
-
|
|
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
|
|
79
|
+
return output.id;
|
|
83
80
|
}
|
|
84
81
|
/**
|
|
85
82
|
* 批量规范化工具调用 ID
|
|
Binary file
|
|
@@ -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,
|
|
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
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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(
|
|
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;
|