@jsonstudio/llms 0.6.3551 → 0.6.3686
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/antigravity-thought-signature-cache.js +4 -115
- package/dist/conversion/compat/actions/auto-thinking.js +3 -2
- package/dist/conversion/compat/actions/deepseek-web-response.js +15 -49
- package/dist/conversion/compat/actions/gemini-cli-request.d.ts +2 -0
- package/dist/conversion/compat/actions/gemini-cli-request.js +1 -1
- package/dist/conversion/compat/actions/glm-history-image-trim.js +3 -37
- package/dist/conversion/compat/actions/glm-image-content.js +3 -32
- package/dist/conversion/compat/actions/glm-native-compat.d.ts +6 -0
- package/dist/conversion/compat/actions/glm-native-compat.js +34 -0
- package/dist/conversion/compat/actions/glm-vision-prompt.js +3 -76
- package/dist/conversion/compat/actions/glm-web-search.js +10 -43
- package/dist/conversion/compat/actions/iflow-kimi-cli-defaults.js +4 -53
- package/dist/conversion/compat/actions/iflow-kimi-history-media-placeholder.js +5 -141
- package/dist/conversion/compat/actions/iflow-kimi-thinking-reasoning-fill.js +7 -28
- package/dist/conversion/compat/actions/iflow-native-compat.d.ts +6 -0
- package/dist/conversion/compat/actions/iflow-native-compat.js +36 -0
- package/dist/conversion/compat/actions/iflow-response-body-unwrap.js +4 -119
- package/dist/conversion/compat/actions/iflow-web-search.js +14 -55
- package/dist/conversion/hub/operation-table/semantic-mappers/archive/chat-mapper.archive.js +5 -0
- package/dist/conversion/hub/operation-table/semantic-mappers/responses-mapper.js +31 -18
- package/dist/conversion/hub/pipeline/hub-pipeline.js +163 -163
- package/dist/conversion/hub/pipeline/hub-stage-timing.d.ts +6 -0
- package/dist/conversion/hub/pipeline/hub-stage-timing.js +178 -0
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage1_format_parse/index.d.ts +4 -4
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage1_format_parse/index.js +33 -14
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.d.ts +7 -6
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.js +41 -23
- package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage1_semantic_map/index.js +44 -1
- package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage1_tool_governance/index.js +4 -1
- package/dist/conversion/hub/process/chat-process-continue-execution.js +5 -4
- package/dist/conversion/hub/process/chat-process-governance-orchestration.js +3 -1
- package/dist/conversion/hub/process/chat-process-media.d.ts +3 -1
- package/dist/conversion/hub/process/chat-process-media.js +92 -2
- package/dist/conversion/hub/process/chat-process-session-usage.d.ts +7 -0
- package/dist/conversion/hub/process/chat-process-session-usage.js +147 -0
- package/dist/conversion/hub/response/provider-response.js +13 -0
- package/dist/conversion/responses/responses-openai-bridge/response-payload.js +0 -12
- package/dist/conversion/responses/responses-openai-bridge/types.d.ts +1 -9
- package/dist/conversion/responses/responses-openai-bridge.js +77 -44
- package/dist/conversion/shared/reasoning-normalizer.js +42 -0
- package/dist/conversion/shared/responses-tool-utils.js +2 -3
- package/dist/native/router_hotpath_napi.node +0 -0
- package/dist/router/virtual-router/bootstrap/profile-builder.js +1 -0
- package/dist/router/virtual-router/bootstrap/provider-normalization.d.ts +1 -0
- package/dist/router/virtual-router/bootstrap/provider-normalization.js +6 -0
- package/dist/router/virtual-router/bootstrap.js +1 -6
- package/dist/router/virtual-router/engine-legacy.js +43 -0
- package/dist/router/virtual-router/engine-logging.d.ts +3 -0
- package/dist/router/virtual-router/engine-logging.js +29 -3
- package/dist/router/virtual-router/engine-selection/native-hub-pipeline-edge-stage-semantics.d.ts +2 -2
- package/dist/router/virtual-router/engine-selection/native-hub-pipeline-edge-stage-semantics.js +96 -80
- package/dist/router/virtual-router/engine-selection/native-hub-pipeline-req-process-semantics.d.ts +1 -0
- package/dist/router/virtual-router/engine.js +34 -22
- package/dist/router/virtual-router/provider-registry.js +1 -0
- package/dist/router/virtual-router/routing-instructions/state.js +35 -3
- package/dist/router/virtual-router/routing-instructions/types.d.ts +4 -0
- package/dist/router/virtual-router/types.d.ts +7 -0
- package/dist/servertool/engine.js +3 -34
- package/dist/servertool/handlers/followup-request-builder.js +0 -6
- package/dist/servertool/handlers/gemini-empty-reply-continue.js +3 -274
- package/dist/servertool/handlers/stop-message-auto/runtime-utils.d.ts +0 -3
- package/dist/servertool/handlers/stop-message-auto/runtime-utils.js +0 -29
- package/dist/servertool/handlers/stop-message-auto.js +2 -10
- package/dist/servertool/handlers/vision.js +4 -1
- package/dist/servertool/server-side-tools.js +66 -3
- package/package.json +1 -1
package/dist/router/virtual-router/engine-selection/native-hub-pipeline-edge-stage-semantics.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { failNativeRequired, isNativeDisabledByEnv } from
|
|
2
|
-
import { loadNativeRouterHotpathBindingForInternalUse } from
|
|
1
|
+
import { failNativeRequired, isNativeDisabledByEnv, } from "./native-router-hotpath-policy.js";
|
|
2
|
+
import { loadNativeRouterHotpathBindingForInternalUse } from "./native-router-hotpath.js";
|
|
3
3
|
function readNativeFunction(name) {
|
|
4
4
|
const binding = loadNativeRouterHotpathBindingForInternalUse();
|
|
5
5
|
const fn = binding?.[name];
|
|
6
|
-
return typeof fn ===
|
|
6
|
+
return typeof fn === "function"
|
|
7
|
+
? fn
|
|
8
|
+
: null;
|
|
7
9
|
}
|
|
8
10
|
function safeStringify(value) {
|
|
9
11
|
try {
|
|
@@ -16,7 +18,7 @@ function safeStringify(value) {
|
|
|
16
18
|
function parseRecord(raw) {
|
|
17
19
|
try {
|
|
18
20
|
const parsed = JSON.parse(raw);
|
|
19
|
-
if (!parsed || typeof parsed !==
|
|
21
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
20
22
|
return null;
|
|
21
23
|
}
|
|
22
24
|
return parsed;
|
|
@@ -28,27 +30,31 @@ function parseRecord(raw) {
|
|
|
28
30
|
function parseFormatEnvelopePayload(raw, direction, fallbackProtocol, fallbackPayload) {
|
|
29
31
|
try {
|
|
30
32
|
const parsed = JSON.parse(raw);
|
|
31
|
-
if (!parsed || typeof parsed !==
|
|
33
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
32
34
|
return null;
|
|
33
35
|
}
|
|
34
36
|
const row = parsed;
|
|
35
37
|
const envelope = row.envelope;
|
|
36
|
-
if (!envelope || typeof envelope !==
|
|
38
|
+
if (!envelope || typeof envelope !== "object" || Array.isArray(envelope)) {
|
|
37
39
|
return null;
|
|
38
40
|
}
|
|
39
41
|
const env = envelope;
|
|
40
|
-
const protocol = typeof env.format ===
|
|
42
|
+
const protocol = typeof env.format === "string" && env.format.trim().length
|
|
41
43
|
? env.format.trim()
|
|
42
44
|
: fallbackProtocol;
|
|
43
|
-
const payload = env.payload &&
|
|
45
|
+
const payload = env.payload &&
|
|
46
|
+
typeof env.payload === "object" &&
|
|
47
|
+
!Array.isArray(env.payload)
|
|
44
48
|
? env.payload
|
|
45
49
|
: fallbackPayload;
|
|
46
50
|
const out = {
|
|
47
51
|
protocol,
|
|
48
52
|
direction,
|
|
49
|
-
payload
|
|
53
|
+
payload,
|
|
50
54
|
};
|
|
51
|
-
if (env.metadata &&
|
|
55
|
+
if (env.metadata &&
|
|
56
|
+
typeof env.metadata === "object" &&
|
|
57
|
+
!Array.isArray(env.metadata)) {
|
|
52
58
|
out.meta = env.metadata;
|
|
53
59
|
}
|
|
54
60
|
return out;
|
|
@@ -63,7 +69,7 @@ function parseOptionalString(raw) {
|
|
|
63
69
|
if (parsed === null) {
|
|
64
70
|
return undefined;
|
|
65
71
|
}
|
|
66
|
-
if (typeof parsed !==
|
|
72
|
+
if (typeof parsed !== "string") {
|
|
67
73
|
return null;
|
|
68
74
|
}
|
|
69
75
|
const trimmed = parsed.trim();
|
|
@@ -76,149 +82,149 @@ function parseOptionalString(raw) {
|
|
|
76
82
|
function parseBoolean(raw) {
|
|
77
83
|
try {
|
|
78
84
|
const parsed = JSON.parse(raw);
|
|
79
|
-
return typeof parsed ===
|
|
85
|
+
return typeof parsed === "boolean" ? parsed : null;
|
|
80
86
|
}
|
|
81
87
|
catch {
|
|
82
88
|
return null;
|
|
83
89
|
}
|
|
84
90
|
}
|
|
85
91
|
export function sanitizeFormatEnvelopeWithNative(candidate) {
|
|
86
|
-
const capability =
|
|
92
|
+
const capability = "sanitizeFormatEnvelopeJson";
|
|
87
93
|
const fail = (reason) => failNativeRequired(capability, reason);
|
|
88
94
|
if (isNativeDisabledByEnv()) {
|
|
89
|
-
return fail(
|
|
95
|
+
return fail("native disabled");
|
|
90
96
|
}
|
|
91
|
-
const fn = readNativeFunction(
|
|
97
|
+
const fn = readNativeFunction("sanitizeFormatEnvelopeJson");
|
|
92
98
|
if (!fn) {
|
|
93
99
|
return fail();
|
|
94
100
|
}
|
|
95
101
|
const candidateJson = safeStringify(candidate);
|
|
96
102
|
if (!candidateJson) {
|
|
97
|
-
return fail(
|
|
103
|
+
return fail("json stringify failed");
|
|
98
104
|
}
|
|
99
105
|
try {
|
|
100
106
|
const raw = fn(candidateJson);
|
|
101
|
-
if (typeof raw !==
|
|
102
|
-
return fail(
|
|
107
|
+
if (typeof raw !== "string" || !raw) {
|
|
108
|
+
return fail("empty result");
|
|
103
109
|
}
|
|
104
110
|
const parsed = parseRecord(raw);
|
|
105
|
-
return parsed ?? fail(
|
|
111
|
+
return parsed ?? fail("invalid payload");
|
|
106
112
|
}
|
|
107
113
|
catch (error) {
|
|
108
|
-
const reason = error instanceof Error ? error.message : String(error ??
|
|
114
|
+
const reason = error instanceof Error ? error.message : String(error ?? "unknown");
|
|
109
115
|
return fail(reason);
|
|
110
116
|
}
|
|
111
117
|
}
|
|
112
118
|
export function sanitizeChatCompletionLikeWithNative(candidate) {
|
|
113
|
-
const capability =
|
|
119
|
+
const capability = "sanitizeChatCompletionLikeJson";
|
|
114
120
|
const fail = (reason) => failNativeRequired(capability, reason);
|
|
115
121
|
if (isNativeDisabledByEnv()) {
|
|
116
|
-
return fail(
|
|
122
|
+
return fail("native disabled");
|
|
117
123
|
}
|
|
118
|
-
const fn = readNativeFunction(
|
|
124
|
+
const fn = readNativeFunction("sanitizeChatCompletionLikeJson");
|
|
119
125
|
if (!fn) {
|
|
120
126
|
return fail();
|
|
121
127
|
}
|
|
122
128
|
const candidateJson = safeStringify(candidate);
|
|
123
129
|
if (!candidateJson) {
|
|
124
|
-
return fail(
|
|
130
|
+
return fail("json stringify failed");
|
|
125
131
|
}
|
|
126
132
|
try {
|
|
127
133
|
const raw = fn(candidateJson);
|
|
128
|
-
if (typeof raw !==
|
|
129
|
-
return fail(
|
|
134
|
+
if (typeof raw !== "string" || !raw) {
|
|
135
|
+
return fail("empty result");
|
|
130
136
|
}
|
|
131
137
|
const parsed = parseRecord(raw);
|
|
132
|
-
return parsed ?? fail(
|
|
138
|
+
return parsed ?? fail("invalid payload");
|
|
133
139
|
}
|
|
134
140
|
catch (error) {
|
|
135
|
-
const reason = error instanceof Error ? error.message : String(error ??
|
|
141
|
+
const reason = error instanceof Error ? error.message : String(error ?? "unknown");
|
|
136
142
|
return fail(reason);
|
|
137
143
|
}
|
|
138
144
|
}
|
|
139
145
|
export function stripPrivateFieldsWithNative(payload) {
|
|
140
|
-
const capability =
|
|
146
|
+
const capability = "stripPrivateFieldsJson";
|
|
141
147
|
const fail = (reason) => failNativeRequired(capability, reason);
|
|
142
148
|
if (isNativeDisabledByEnv()) {
|
|
143
|
-
return fail(
|
|
149
|
+
return fail("native disabled");
|
|
144
150
|
}
|
|
145
|
-
const fn = readNativeFunction(
|
|
151
|
+
const fn = readNativeFunction("stripPrivateFieldsJson");
|
|
146
152
|
if (!fn) {
|
|
147
153
|
return fail();
|
|
148
154
|
}
|
|
149
155
|
const payloadJson = safeStringify(payload);
|
|
150
156
|
if (!payloadJson) {
|
|
151
|
-
return fail(
|
|
157
|
+
return fail("json stringify failed");
|
|
152
158
|
}
|
|
153
159
|
try {
|
|
154
160
|
const raw = fn(payloadJson);
|
|
155
|
-
if (typeof raw !==
|
|
156
|
-
return fail(
|
|
161
|
+
if (typeof raw !== "string" || !raw) {
|
|
162
|
+
return fail("empty result");
|
|
157
163
|
}
|
|
158
164
|
const parsed = parseRecord(raw);
|
|
159
|
-
return parsed ?? fail(
|
|
165
|
+
return parsed ?? fail("invalid payload");
|
|
160
166
|
}
|
|
161
167
|
catch (error) {
|
|
162
|
-
const reason = error instanceof Error ? error.message : String(error ??
|
|
168
|
+
const reason = error instanceof Error ? error.message : String(error ?? "unknown");
|
|
163
169
|
return fail(reason);
|
|
164
170
|
}
|
|
165
171
|
}
|
|
166
172
|
export function resolveCompatProfileWithNative(adapterContext, explicitProfile) {
|
|
167
|
-
const capability =
|
|
173
|
+
const capability = "resolveCompatProfileJson";
|
|
168
174
|
const fail = (reason) => failNativeRequired(capability, reason);
|
|
169
175
|
if (isNativeDisabledByEnv()) {
|
|
170
|
-
return fail(
|
|
176
|
+
return fail("native disabled");
|
|
171
177
|
}
|
|
172
|
-
const fn = readNativeFunction(
|
|
178
|
+
const fn = readNativeFunction("resolveCompatProfileJson");
|
|
173
179
|
if (!fn) {
|
|
174
180
|
return fail();
|
|
175
181
|
}
|
|
176
182
|
const adapterContextJson = safeStringify(adapterContext);
|
|
177
183
|
const explicitJson = safeStringify(explicitProfile ?? null);
|
|
178
184
|
if (!adapterContextJson || !explicitJson) {
|
|
179
|
-
return fail(
|
|
185
|
+
return fail("json stringify failed");
|
|
180
186
|
}
|
|
181
187
|
try {
|
|
182
188
|
const raw = fn(adapterContextJson, explicitJson);
|
|
183
|
-
if (typeof raw !==
|
|
184
|
-
return fail(
|
|
189
|
+
if (typeof raw !== "string" || !raw) {
|
|
190
|
+
return fail("empty result");
|
|
185
191
|
}
|
|
186
192
|
const parsed = parseOptionalString(raw);
|
|
187
|
-
return parsed === null ? fail(
|
|
193
|
+
return parsed === null ? fail("invalid payload") : parsed;
|
|
188
194
|
}
|
|
189
195
|
catch (error) {
|
|
190
|
-
const reason = error instanceof Error ? error.message : String(error ??
|
|
196
|
+
const reason = error instanceof Error ? error.message : String(error ?? "unknown");
|
|
191
197
|
return fail(reason);
|
|
192
198
|
}
|
|
193
199
|
}
|
|
194
200
|
export function resolveSseStreamModeWithNative(wantsStream, clientProtocol) {
|
|
195
|
-
const capability =
|
|
201
|
+
const capability = "resolveSseStreamModeJson";
|
|
196
202
|
const fail = (reason) => failNativeRequired(capability, reason);
|
|
197
203
|
if (isNativeDisabledByEnv()) {
|
|
198
|
-
return fail(
|
|
204
|
+
return fail("native disabled");
|
|
199
205
|
}
|
|
200
|
-
const fn = readNativeFunction(
|
|
206
|
+
const fn = readNativeFunction("resolveSseStreamModeJson");
|
|
201
207
|
if (!fn) {
|
|
202
208
|
return fail();
|
|
203
209
|
}
|
|
204
210
|
try {
|
|
205
|
-
const raw = fn(Boolean(wantsStream), String(clientProtocol ||
|
|
206
|
-
if (typeof raw !==
|
|
207
|
-
return fail(
|
|
211
|
+
const raw = fn(Boolean(wantsStream), String(clientProtocol || ""));
|
|
212
|
+
if (typeof raw !== "string" || !raw) {
|
|
213
|
+
return fail("empty result");
|
|
208
214
|
}
|
|
209
215
|
const parsed = parseBoolean(raw);
|
|
210
|
-
return parsed === null ? fail(
|
|
216
|
+
return parsed === null ? fail("invalid payload") : parsed;
|
|
211
217
|
}
|
|
212
218
|
catch (error) {
|
|
213
|
-
const reason = error instanceof Error ? error.message : String(error ??
|
|
219
|
+
const reason = error instanceof Error ? error.message : String(error ?? "unknown");
|
|
214
220
|
return fail(reason);
|
|
215
221
|
}
|
|
216
222
|
}
|
|
217
223
|
export function parseReqInboundFormatEnvelopeWithNative(input) {
|
|
218
|
-
const capability =
|
|
224
|
+
const capability = "parseFormatEnvelopeJson";
|
|
219
225
|
const fail = (reason) => failNativeRequired(capability, reason);
|
|
220
226
|
if (isNativeDisabledByEnv()) {
|
|
221
|
-
return fail(
|
|
227
|
+
return fail("native disabled");
|
|
222
228
|
}
|
|
223
229
|
const fn = readNativeFunction(capability);
|
|
224
230
|
if (!fn) {
|
|
@@ -226,26 +232,33 @@ export function parseReqInboundFormatEnvelopeWithNative(input) {
|
|
|
226
232
|
}
|
|
227
233
|
const inputJson = safeStringify(input);
|
|
228
234
|
if (!inputJson) {
|
|
229
|
-
return fail(
|
|
235
|
+
return fail("json stringify failed");
|
|
230
236
|
}
|
|
231
237
|
try {
|
|
232
238
|
const raw = fn(inputJson);
|
|
233
|
-
if (typeof raw !==
|
|
234
|
-
return fail(
|
|
239
|
+
if (typeof raw !== "string" || !raw) {
|
|
240
|
+
return fail("empty result");
|
|
235
241
|
}
|
|
236
|
-
const parsed =
|
|
237
|
-
|
|
242
|
+
const parsed = JSON.parse(raw);
|
|
243
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
244
|
+
return fail("invalid envelope structure");
|
|
245
|
+
}
|
|
246
|
+
const result = parsed;
|
|
247
|
+
if (!result.envelope || typeof result.envelope !== "object") {
|
|
248
|
+
return fail("missing envelope in result");
|
|
249
|
+
}
|
|
250
|
+
return result.envelope;
|
|
238
251
|
}
|
|
239
252
|
catch (error) {
|
|
240
|
-
const reason = error instanceof Error ? error.message : String(error ??
|
|
253
|
+
const reason = error instanceof Error ? error.message : String(error ?? "unknown");
|
|
241
254
|
return fail(reason);
|
|
242
255
|
}
|
|
243
256
|
}
|
|
244
257
|
export function parseRespInboundFormatEnvelopeWithNative(input) {
|
|
245
|
-
const capability =
|
|
258
|
+
const capability = "parseRespFormatEnvelopeJson";
|
|
246
259
|
const fail = (reason) => failNativeRequired(capability, reason);
|
|
247
260
|
if (isNativeDisabledByEnv()) {
|
|
248
|
-
return fail(
|
|
261
|
+
return fail("native disabled");
|
|
249
262
|
}
|
|
250
263
|
const fn = readNativeFunction(capability);
|
|
251
264
|
if (!fn) {
|
|
@@ -253,26 +266,26 @@ export function parseRespInboundFormatEnvelopeWithNative(input) {
|
|
|
253
266
|
}
|
|
254
267
|
const inputJson = safeStringify(input);
|
|
255
268
|
if (!inputJson) {
|
|
256
|
-
return fail(
|
|
269
|
+
return fail("json stringify failed");
|
|
257
270
|
}
|
|
258
271
|
try {
|
|
259
272
|
const raw = fn(inputJson);
|
|
260
|
-
if (typeof raw !==
|
|
261
|
-
return fail(
|
|
273
|
+
if (typeof raw !== "string" || !raw) {
|
|
274
|
+
return fail("empty result");
|
|
262
275
|
}
|
|
263
|
-
const parsed = parseFormatEnvelopePayload(raw,
|
|
264
|
-
return parsed ?? fail(
|
|
276
|
+
const parsed = parseFormatEnvelopePayload(raw, "response", input.protocol, input.payload);
|
|
277
|
+
return parsed ?? fail("invalid payload");
|
|
265
278
|
}
|
|
266
279
|
catch (error) {
|
|
267
|
-
const reason = error instanceof Error ? error.message : String(error ??
|
|
280
|
+
const reason = error instanceof Error ? error.message : String(error ?? "unknown");
|
|
268
281
|
return fail(reason);
|
|
269
282
|
}
|
|
270
283
|
}
|
|
271
284
|
export function validateChatEnvelopeWithNative(chatEnvelope, options) {
|
|
272
|
-
const capability =
|
|
285
|
+
const capability = "validateChatEnvelopeJson";
|
|
273
286
|
const fail = (reason) => failNativeRequired(capability, reason);
|
|
274
287
|
if (isNativeDisabledByEnv()) {
|
|
275
|
-
return fail(
|
|
288
|
+
return fail("native disabled");
|
|
276
289
|
}
|
|
277
290
|
const fn = readNativeFunction(capability);
|
|
278
291
|
if (!fn) {
|
|
@@ -280,35 +293,38 @@ export function validateChatEnvelopeWithNative(chatEnvelope, options) {
|
|
|
280
293
|
}
|
|
281
294
|
const envelopeJson = safeStringify(chatEnvelope);
|
|
282
295
|
if (!envelopeJson) {
|
|
283
|
-
return fail(
|
|
296
|
+
return fail("json stringify failed");
|
|
284
297
|
}
|
|
285
|
-
const isChatEnvelopeValidationError = (message) => typeof message ===
|
|
298
|
+
const isChatEnvelopeValidationError = (message) => typeof message === "string" &&
|
|
299
|
+
message.includes("ChatEnvelopeValidationError(");
|
|
286
300
|
try {
|
|
287
|
-
const raw = fn(envelopeJson, String(options.stage ||
|
|
301
|
+
const raw = fn(envelopeJson, String(options.stage || ""), String(options.direction || ""), options.source);
|
|
288
302
|
const nativeErrorMessage = raw instanceof Error
|
|
289
303
|
? raw.message
|
|
290
|
-
: raw &&
|
|
304
|
+
: raw &&
|
|
305
|
+
typeof raw === "object" &&
|
|
306
|
+
"message" in raw
|
|
291
307
|
? (() => {
|
|
292
308
|
const candidate = raw.message;
|
|
293
|
-
return typeof candidate ===
|
|
309
|
+
return typeof candidate === "string" ? candidate : "";
|
|
294
310
|
})()
|
|
295
|
-
:
|
|
311
|
+
: "";
|
|
296
312
|
if (nativeErrorMessage) {
|
|
297
313
|
if (isChatEnvelopeValidationError(nativeErrorMessage)) {
|
|
298
314
|
throw new Error(nativeErrorMessage);
|
|
299
315
|
}
|
|
300
316
|
return fail(nativeErrorMessage);
|
|
301
317
|
}
|
|
302
|
-
if (typeof raw !==
|
|
303
|
-
return fail(
|
|
318
|
+
if (typeof raw !== "string" || !raw) {
|
|
319
|
+
return fail("empty result");
|
|
304
320
|
}
|
|
305
321
|
const parsed = parseBoolean(raw);
|
|
306
322
|
if (parsed !== true) {
|
|
307
|
-
return fail(
|
|
323
|
+
return fail("invalid payload");
|
|
308
324
|
}
|
|
309
325
|
}
|
|
310
326
|
catch (error) {
|
|
311
|
-
const reason = error instanceof Error ? error.message : String(error ??
|
|
327
|
+
const reason = error instanceof Error ? error.message : String(error ?? "unknown");
|
|
312
328
|
if (isChatEnvelopeValidationError(reason)) {
|
|
313
329
|
throw error instanceof Error ? error : new Error(reason);
|
|
314
330
|
}
|
package/dist/router/virtual-router/engine-selection/native-hub-pipeline-req-process-semantics.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export interface NativeReqProcessToolGovernanceInput {
|
|
|
4
4
|
metadata: Record<string, unknown>;
|
|
5
5
|
entryEndpoint: string;
|
|
6
6
|
requestId: string;
|
|
7
|
+
hasActiveStopMessageForContinueExecution?: boolean;
|
|
7
8
|
}
|
|
8
9
|
export interface NativeReqProcessToolGovernanceOutput {
|
|
9
10
|
processedRequest: Record<string, unknown>;
|
|
@@ -6,6 +6,7 @@ import { ProviderRegistry } from './provider-registry.js';
|
|
|
6
6
|
import { resolveStopMessageScope } from './engine/routing-state/store.js';
|
|
7
7
|
import { loadRoutingInstructionStateSync } from './sticky-session-store.js';
|
|
8
8
|
import { mergeStopMessageFromPersisted } from './stop-message-state-sync.js';
|
|
9
|
+
import { resolveSessionColor } from './engine-logging.js';
|
|
9
10
|
export class VirtualRouterEngine {
|
|
10
11
|
nativeProxy;
|
|
11
12
|
registry;
|
|
@@ -72,6 +73,7 @@ export class VirtualRouterEngine {
|
|
|
72
73
|
parseLog?.scopedTypes.some((type) => type === 'stopMessageSet' || type === 'stopMessageMode' || type === 'stopMessageClear'));
|
|
73
74
|
emitVirtualRouterHitLog(parsed, {
|
|
74
75
|
requestId: metadata.requestId,
|
|
76
|
+
sessionId: resolveVirtualRouterLogSessionId(metadata),
|
|
75
77
|
stopScope,
|
|
76
78
|
stopState,
|
|
77
79
|
forceStopStatusLabel
|
|
@@ -176,6 +178,12 @@ function extractNativeErrorMessage(error) {
|
|
|
176
178
|
if (error instanceof Error) {
|
|
177
179
|
return error.message;
|
|
178
180
|
}
|
|
181
|
+
if (error && typeof error === 'object') {
|
|
182
|
+
const message = error.message;
|
|
183
|
+
if (typeof message === 'string') {
|
|
184
|
+
return message;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
179
187
|
return '';
|
|
180
188
|
}
|
|
181
189
|
function parseVirtualRouterErrorMessage(message) {
|
|
@@ -225,6 +233,11 @@ function buildRoutingInstructionParseLog(request, metadata) {
|
|
|
225
233
|
}
|
|
226
234
|
const latest = getLatestUserMessage(messages);
|
|
227
235
|
const latestText = latest ? extractMessageText(latest).trim() : '';
|
|
236
|
+
const latestHasMarker = /<\*\*[\s\S]*?\*\*>/.test(latestText);
|
|
237
|
+
const hasStopKeyword = /stopmessage/i.test(latestText);
|
|
238
|
+
if (!hasStopKeyword && !latestHasMarker) {
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
228
241
|
const parsedKinds = parseRoutingInstructionKindsWithNative(request);
|
|
229
242
|
const stopMessageTypes = parsedKinds.filter((type) => type === 'stopMessageSet' || type === 'stopMessageMode' || type === 'stopMessageClear');
|
|
230
243
|
const scopedTypes = parsedKinds.filter((type) => type === 'stopMessageSet' ||
|
|
@@ -232,20 +245,12 @@ function buildRoutingInstructionParseLog(request, metadata) {
|
|
|
232
245
|
type === 'stopMessageClear' ||
|
|
233
246
|
type === 'preCommandSet' ||
|
|
234
247
|
type === 'preCommandClear');
|
|
235
|
-
const markerDetected = messages.some((message) => {
|
|
236
|
-
if (!message || typeof message !== 'object') {
|
|
237
|
-
return false;
|
|
238
|
-
}
|
|
239
|
-
const record = message;
|
|
240
|
-
return record.role === 'user' && typeof record.content === 'string' && /<\*\*[\s\S]*?\*\*>/.test(record.content);
|
|
241
|
-
});
|
|
242
|
-
const hasStopKeyword = /stopmessage/i.test(latestText);
|
|
243
248
|
if (!hasStopKeyword && stopMessageTypes.length === 0 && scopedTypes.length === 0) {
|
|
244
249
|
return null;
|
|
245
250
|
}
|
|
246
251
|
return {
|
|
247
252
|
requestId: metadata.requestId || 'n/a',
|
|
248
|
-
markerDetected,
|
|
253
|
+
markerDetected: latestHasMarker,
|
|
249
254
|
preview: latestText.replace(/\s+/g, ' ').slice(0, 120),
|
|
250
255
|
stopMessageTypes,
|
|
251
256
|
scopedTypes,
|
|
@@ -274,30 +279,37 @@ function emitVirtualRouterHitLog(result, options) {
|
|
|
274
279
|
const prefixColor = '\x1b[38;5;208m';
|
|
275
280
|
const timeColor = '\x1b[90m';
|
|
276
281
|
const stopColor = '\x1b[38;5;214m';
|
|
277
|
-
const routeColorMap = {
|
|
278
|
-
multimodal: '\x1b[38;5;45m',
|
|
279
|
-
tools: '\x1b[38;5;214m',
|
|
280
|
-
thinking: '\x1b[34m',
|
|
281
|
-
coding: '\x1b[35m',
|
|
282
|
-
longcontext: '\x1b[38;5;141m',
|
|
283
|
-
web_search: '\x1b[32m',
|
|
284
|
-
search: '\x1b[38;5;34m',
|
|
285
|
-
vision: '\x1b[38;5;207m',
|
|
286
|
-
background: '\x1b[90m'
|
|
287
|
-
};
|
|
288
282
|
const now = new Date();
|
|
289
283
|
const timestamp = `${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`;
|
|
290
284
|
const routeLabel = result.decision.poolId
|
|
291
285
|
? `${result.decision.routeName}/${result.decision.poolId}`
|
|
292
286
|
: result.decision.routeName;
|
|
293
|
-
const routeColor =
|
|
287
|
+
const routeColor = resolveSessionColor(options?.sessionId);
|
|
294
288
|
const providerKey = result.decision.providerKey || result.target.providerKey;
|
|
295
289
|
const modelSuffix = result.target.modelId ? `.${result.target.modelId}` : '';
|
|
296
290
|
const reason = result.decision.reasoning ? ` reason=${result.decision.reasoning}` : '';
|
|
297
291
|
const stopStatusLabel = formatStopMessageStatusLabel(options?.stopState ?? null, options?.stopScope, Boolean(options?.forceStopStatusLabel));
|
|
298
292
|
const requestId = typeof options?.requestId === 'string' ? options.requestId : '';
|
|
299
293
|
const requestLabel = requestId && !requestId.includes('unknown') ? ` req=${requestId}` : '';
|
|
300
|
-
|
|
294
|
+
const sessionId = typeof options?.sessionId === 'string' ? options.sessionId.trim() : '';
|
|
295
|
+
const sessionLabel = sessionId ? ` sid=${sessionId}` : '';
|
|
296
|
+
console.log(`${prefixColor}[virtual-router-hit]${reset} ${timeColor}${timestamp}${reset}${requestLabel}${sessionLabel} ${routeColor}${routeLabel} -> ${providerKey}${modelSuffix}${reason}${reset}${stopStatusLabel ? ` ${stopColor}${stopStatusLabel}${reset}` : ''}`);
|
|
297
|
+
}
|
|
298
|
+
function resolveVirtualRouterLogSessionId(metadata) {
|
|
299
|
+
const candidates = [
|
|
300
|
+
metadata.sessionId,
|
|
301
|
+
metadata.clientTmuxSessionId,
|
|
302
|
+
metadata.client_tmux_session_id,
|
|
303
|
+
metadata.tmuxSessionId,
|
|
304
|
+
metadata.tmux_session_id,
|
|
305
|
+
metadata.conversationId
|
|
306
|
+
];
|
|
307
|
+
for (const value of candidates) {
|
|
308
|
+
if (typeof value === 'string' && value.trim()) {
|
|
309
|
+
return value.trim();
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return undefined;
|
|
301
313
|
}
|
|
302
314
|
function formatStopMessageStatusLabel(snapshot, scope, forceShow) {
|
|
303
315
|
const scopeLabel = scope && scope.trim() ? scope.trim() : 'none';
|
|
@@ -97,6 +97,7 @@ export class ProviderRegistry {
|
|
|
97
97
|
providerType: profile.providerType,
|
|
98
98
|
endpoint: profile.endpoint,
|
|
99
99
|
auth: profile.auth,
|
|
100
|
+
...(profile.enabled !== undefined ? { enabled: profile.enabled } : {}),
|
|
100
101
|
outboundProfile: profile.outboundProfile,
|
|
101
102
|
compatibilityProfile: profile.compatibilityProfile,
|
|
102
103
|
runtimeKey: profile.runtimeKey,
|
|
@@ -27,7 +27,11 @@ export function applyRoutingInstructions(instructions, currentState) {
|
|
|
27
27
|
: undefined,
|
|
28
28
|
preCommandSource: currentState.preCommandSource,
|
|
29
29
|
preCommandScriptPath: currentState.preCommandScriptPath,
|
|
30
|
-
preCommandUpdatedAt: currentState.preCommandUpdatedAt
|
|
30
|
+
preCommandUpdatedAt: currentState.preCommandUpdatedAt,
|
|
31
|
+
chatProcessLastTotalTokens: currentState.chatProcessLastTotalTokens,
|
|
32
|
+
chatProcessLastInputTokens: currentState.chatProcessLastInputTokens,
|
|
33
|
+
chatProcessLastMessageCount: currentState.chatProcessLastMessageCount,
|
|
34
|
+
chatProcessLastUpdatedAt: currentState.chatProcessLastUpdatedAt
|
|
31
35
|
};
|
|
32
36
|
let allowReset = false;
|
|
33
37
|
let disableReset = false;
|
|
@@ -186,7 +190,19 @@ export function serializeRoutingInstructionState(state) {
|
|
|
186
190
|
models: Array.from(models)
|
|
187
191
|
})),
|
|
188
192
|
...serializeStopMessageState(state),
|
|
189
|
-
...serializePreCommandState(state)
|
|
193
|
+
...serializePreCommandState(state),
|
|
194
|
+
...(typeof state.chatProcessLastTotalTokens === 'number'
|
|
195
|
+
? { chatProcessLastTotalTokens: state.chatProcessLastTotalTokens }
|
|
196
|
+
: {}),
|
|
197
|
+
...(typeof state.chatProcessLastInputTokens === 'number'
|
|
198
|
+
? { chatProcessLastInputTokens: state.chatProcessLastInputTokens }
|
|
199
|
+
: {}),
|
|
200
|
+
...(typeof state.chatProcessLastMessageCount === 'number'
|
|
201
|
+
? { chatProcessLastMessageCount: state.chatProcessLastMessageCount }
|
|
202
|
+
: {}),
|
|
203
|
+
...(typeof state.chatProcessLastUpdatedAt === 'number'
|
|
204
|
+
? { chatProcessLastUpdatedAt: state.chatProcessLastUpdatedAt }
|
|
205
|
+
: {})
|
|
190
206
|
};
|
|
191
207
|
}
|
|
192
208
|
export function deserializeRoutingInstructionState(data) {
|
|
@@ -208,7 +224,11 @@ export function deserializeRoutingInstructionState(data) {
|
|
|
208
224
|
stopMessageAiHistory: undefined,
|
|
209
225
|
preCommandSource: undefined,
|
|
210
226
|
preCommandScriptPath: undefined,
|
|
211
|
-
preCommandUpdatedAt: undefined
|
|
227
|
+
preCommandUpdatedAt: undefined,
|
|
228
|
+
chatProcessLastTotalTokens: undefined,
|
|
229
|
+
chatProcessLastInputTokens: undefined,
|
|
230
|
+
chatProcessLastMessageCount: undefined,
|
|
231
|
+
chatProcessLastUpdatedAt: undefined
|
|
212
232
|
};
|
|
213
233
|
if (data.forcedTarget && typeof data.forcedTarget === 'object') {
|
|
214
234
|
state.forcedTarget = data.forcedTarget;
|
|
@@ -241,5 +261,17 @@ export function deserializeRoutingInstructionState(data) {
|
|
|
241
261
|
}
|
|
242
262
|
deserializeStopMessageState(data, state);
|
|
243
263
|
deserializePreCommandState(data, state);
|
|
264
|
+
if (typeof data.chatProcessLastTotalTokens === 'number' && Number.isFinite(data.chatProcessLastTotalTokens)) {
|
|
265
|
+
state.chatProcessLastTotalTokens = Math.max(0, Math.round(data.chatProcessLastTotalTokens));
|
|
266
|
+
}
|
|
267
|
+
if (typeof data.chatProcessLastInputTokens === 'number' && Number.isFinite(data.chatProcessLastInputTokens)) {
|
|
268
|
+
state.chatProcessLastInputTokens = Math.max(0, Math.round(data.chatProcessLastInputTokens));
|
|
269
|
+
}
|
|
270
|
+
if (typeof data.chatProcessLastMessageCount === 'number' && Number.isFinite(data.chatProcessLastMessageCount)) {
|
|
271
|
+
state.chatProcessLastMessageCount = Math.max(0, Math.round(data.chatProcessLastMessageCount));
|
|
272
|
+
}
|
|
273
|
+
if (typeof data.chatProcessLastUpdatedAt === 'number' && Number.isFinite(data.chatProcessLastUpdatedAt)) {
|
|
274
|
+
state.chatProcessLastUpdatedAt = Math.max(0, Math.round(data.chatProcessLastUpdatedAt));
|
|
275
|
+
}
|
|
244
276
|
return state;
|
|
245
277
|
}
|
|
@@ -67,4 +67,8 @@ export interface RoutingInstructionState {
|
|
|
67
67
|
preCommandSource?: string;
|
|
68
68
|
preCommandScriptPath?: string;
|
|
69
69
|
preCommandUpdatedAt?: number;
|
|
70
|
+
chatProcessLastTotalTokens?: number;
|
|
71
|
+
chatProcessLastInputTokens?: number;
|
|
72
|
+
chatProcessLastMessageCount?: number;
|
|
73
|
+
chatProcessLastUpdatedAt?: number;
|
|
70
74
|
}
|
|
@@ -17,6 +17,11 @@ export interface RoutePoolLoadBalancingPolicy {
|
|
|
17
17
|
* Optional pool-local weights. Keys may target runtime keys, provider.model groups, or provider ids.
|
|
18
18
|
*/
|
|
19
19
|
weights?: Record<string, number>;
|
|
20
|
+
responsesResume?: {
|
|
21
|
+
previousRequestId?: string;
|
|
22
|
+
restoredFromResponseId?: string;
|
|
23
|
+
[key: string]: unknown;
|
|
24
|
+
};
|
|
20
25
|
}
|
|
21
26
|
export interface RoutePoolTier {
|
|
22
27
|
id: string;
|
|
@@ -69,6 +74,7 @@ export interface ProviderProfile {
|
|
|
69
74
|
providerType: string;
|
|
70
75
|
endpoint: string;
|
|
71
76
|
auth: ProviderAuthConfig;
|
|
77
|
+
enabled?: boolean;
|
|
72
78
|
outboundProfile: string;
|
|
73
79
|
compatibilityProfile?: string;
|
|
74
80
|
runtimeKey?: string;
|
|
@@ -95,6 +101,7 @@ export interface ProviderRuntimeProfile {
|
|
|
95
101
|
endpoint: string;
|
|
96
102
|
headers?: Record<string, string>;
|
|
97
103
|
auth: ProviderAuthConfig;
|
|
104
|
+
enabled?: boolean;
|
|
98
105
|
outboundProfile: string;
|
|
99
106
|
compatibilityProfile?: string;
|
|
100
107
|
modelId?: string;
|