@jsonstudio/llms 0.6.802 → 0.6.938
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/bridge/routecodex-adapter.d.ts +74 -0
- package/dist/config-unified/enhanced-path-resolver.d.ts +5 -0
- package/dist/config-unified/unified-config.d.ts +26 -0
- package/dist/conversion/codec-registry.d.ts +10 -0
- package/dist/conversion/codecs/gemini-openai-codec.d.ts +16 -0
- package/dist/conversion/codecs/openai-openai-codec.d.ts +12 -0
- package/dist/conversion/codecs/responses-openai-codec.d.ts +12 -0
- package/dist/conversion/compat/profiles/chat-gemini.json +12 -0
- package/dist/conversion/config/config-manager.d.ts +212 -0
- package/dist/conversion/hub/config/types.d.ts +26 -0
- package/dist/conversion/hub/core/detour-registry.d.ts +9 -0
- package/dist/conversion/hub/core/hub-context.d.ts +21 -0
- package/dist/conversion/hub/core/index.d.ts +3 -0
- package/dist/conversion/hub/core/stage-driver.d.ts +30 -0
- package/dist/conversion/hub/format-adapters/anthropic-format-adapter.d.ts +16 -0
- package/dist/conversion/hub/format-adapters/chat-format-adapter.d.ts +17 -0
- package/dist/conversion/hub/format-adapters/gemini-format-adapter.d.ts +16 -0
- package/dist/conversion/hub/format-adapters/index.d.ts +21 -0
- package/dist/conversion/hub/hub-feature.d.ts +1 -0
- package/dist/conversion/hub/node-support.d.ts +19 -0
- package/dist/conversion/hub/pipeline/compat/compat-pipeline-executor.js +11 -0
- package/dist/conversion/hub/pipeline/compat/compat-types.d.ts +3 -0
- package/dist/conversion/hub/pipeline/hub-pipeline.d.ts +7 -0
- package/dist/conversion/hub/pipeline/hub-pipeline.js +71 -14
- package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage1_tool_governance/index.js +4 -0
- package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage1_client_remap/index.js +23 -1
- package/dist/conversion/hub/pipelines/inbound.d.ts +22 -0
- package/dist/conversion/hub/pipelines/outbound.d.ts +22 -0
- package/dist/conversion/hub/policy/policy-engine.d.ts +46 -0
- package/dist/conversion/hub/policy/policy-engine.js +176 -0
- package/dist/conversion/hub/policy/protocol-spec.d.ts +50 -0
- package/dist/conversion/hub/policy/protocol-spec.js +105 -0
- package/dist/conversion/hub/process/chat-process.d.ts +32 -0
- package/dist/conversion/hub/registry.d.ts +28 -0
- package/dist/conversion/hub/response/chat-response-utils.d.ts +6 -0
- package/dist/conversion/hub/response/provider-response.js +31 -0
- package/dist/conversion/hub/semantic-mappers/gemini-mapper.d.ts +7 -0
- package/dist/conversion/hub/semantic-mappers/gemini-mapper.js +87 -1
- package/dist/conversion/hub/semantic-mappers/index.d.ts +4 -0
- package/dist/conversion/hub/semantic-mappers/responses-mapper.d.ts +21 -0
- package/dist/conversion/hub/standardized-bridge.d.ts +12 -0
- package/dist/conversion/hub/types/chat-schema.d.ts +112 -0
- package/dist/conversion/hub/types/errors.d.ts +5 -0
- package/dist/conversion/hub/types/format-envelope.d.ts +7 -0
- package/dist/conversion/hub/types/index.d.ts +6 -0
- package/dist/conversion/hub/types/json.d.ts +9 -0
- package/dist/conversion/hub/types/node.d.ts +31 -0
- package/dist/conversion/responses/responses-openai-bridge.js +263 -10
- package/dist/conversion/schema-validator.d.ts +7 -0
- package/dist/conversion/shared/args-mapping.d.ts +18 -0
- package/dist/conversion/shared/chat-request-filters.d.ts +9 -0
- package/dist/conversion/shared/errors.d.ts +1 -1
- package/dist/conversion/shared/gemini-tool-utils.js +61 -0
- package/dist/conversion/shared/jsonish.d.ts +3 -0
- package/dist/conversion/shared/mcp-injection.d.ts +2 -0
- package/dist/conversion/shared/media.d.ts +1 -0
- package/dist/conversion/shared/openai-message-normalize.d.ts +1 -0
- package/dist/conversion/shared/payload-budget.d.ts +13 -0
- package/dist/conversion/shared/reasoning-mapping.d.ts +5 -0
- package/dist/conversion/shared/responses-request-adapter.d.ts +1 -28
- package/dist/conversion/shared/responses-request-adapter.js +1 -430
- package/dist/conversion/shared/snapshot-hooks.js +58 -3
- package/dist/conversion/shared/tool-governor.js +8 -2
- package/dist/conversion/shared/tool-harvester.d.ts +31 -0
- package/dist/conversion/shared/tool-mapping.js +10 -29
- package/dist/conversion/types.d.ts +33 -0
- package/dist/filters/builtin/add-fields-filter.d.ts +8 -0
- package/dist/filters/builtin/blacklist-filter.d.ts +8 -0
- package/dist/filters/builtin/whitelist-filter.d.ts +8 -0
- package/dist/filters/engine.d.ts +16 -0
- package/dist/filters/special/request-tool-choice-policy.d.ts +11 -0
- package/dist/filters/special/response-finish-invariants.d.ts +11 -0
- package/dist/filters/special/response-openai-to-responses-bridge.d.ts +13 -0
- package/dist/filters/special/response-tool-arguments-blacklist.d.ts +12 -0
- package/dist/filters/special/response-tool-arguments-schema-converge.d.ts +13 -0
- package/dist/filters/special/response-tool-arguments-stringify.d.ts +9 -0
- package/dist/filters/special/response-tool-arguments-whitelist.d.ts +11 -0
- package/dist/filters/special/tool-filter-hooks.d.ts +19 -0
- package/dist/filters/special/tool-post-constraints.d.ts +31 -0
- package/dist/filters/types.d.ts +68 -0
- package/dist/filters/utils/fieldmap-loader.d.ts +2 -0
- package/dist/filters/utils/snapshot-writer.d.ts +10 -0
- package/dist/guidance/index.d.ts +3 -0
- package/dist/guidance/index.js +78 -83
- package/dist/http/sse-response.d.ts +22 -0
- package/dist/router/virtual-router/bootstrap.d.ts +6 -0
- package/dist/router/virtual-router/bootstrap.js +49 -5
- package/dist/router/virtual-router/classifier.d.ts +10 -0
- package/dist/router/virtual-router/engine-selection.js +98 -11
- package/dist/router/virtual-router/engine.js +177 -31
- package/dist/router/virtual-router/error-center.d.ts +10 -0
- package/dist/router/virtual-router/features.d.ts +3 -0
- package/dist/router/virtual-router/routing-instructions.d.ts +23 -1
- package/dist/router/virtual-router/routing-instructions.js +120 -30
- package/dist/router/virtual-router/types.d.ts +11 -0
- package/dist/servertool/engine.js +189 -16
- package/dist/servertool/handlers/apply-patch-guard.js +269 -0
- package/dist/servertool/handlers/exec-command-guard.js +558 -0
- package/dist/servertool/handlers/followup-message-trimmer.d.ts +16 -0
- package/dist/servertool/handlers/followup-message-trimmer.js +198 -0
- package/dist/servertool/handlers/followup-request-builder.d.ts +17 -0
- package/dist/servertool/handlers/followup-request-builder.js +122 -0
- package/dist/servertool/handlers/gemini-empty-reply-continue.js +252 -51
- package/dist/servertool/handlers/iflow-model-error-retry.js +12 -22
- package/dist/servertool/handlers/stop-message-auto.js +237 -75
- package/dist/servertool/handlers/vision.js +15 -27
- package/dist/servertool/handlers/web-search.js +17 -43
- package/dist/servertool/server-side-tools.d.ts +3 -0
- package/dist/servertool/server-side-tools.js +3 -0
- package/dist/sse/json-to-sse/anthropic-json-to-sse-converter.d.ts +2 -1
- package/dist/sse/json-to-sse/chat-json-to-sse-converter.d.ts +80 -0
- package/dist/sse/json-to-sse/event-generators/chat.d.ts +55 -0
- package/dist/sse/json-to-sse/event-generators/responses.d.ts +99 -0
- package/dist/sse/json-to-sse/gemini-json-to-sse-converter.d.ts +2 -1
- package/dist/sse/json-to-sse/responses-json-to-sse-converter.d.ts +80 -0
- package/dist/sse/json-to-sse/sequencers/anthropic-sequencer.d.ts +1 -1
- package/dist/sse/json-to-sse/sequencers/chat-sequencer.d.ts +2 -2
- package/dist/sse/json-to-sse/sequencers/gemini-sequencer.d.ts +1 -1
- package/dist/sse/json-to-sse/sequencers/responses-sequencer.d.ts +40 -0
- package/dist/sse/shared/chat-serializer.d.ts +4 -0
- package/dist/sse/shared/constants.d.ts +272 -0
- package/dist/sse/shared/serializers/anthropic-event-serializer.d.ts +1 -1
- package/dist/sse/shared/serializers/base-serializer.d.ts +158 -0
- package/dist/sse/shared/serializers/chat-event-serializer.d.ts +82 -0
- package/dist/sse/shared/serializers/gemini-event-serializer.d.ts +1 -1
- package/dist/sse/shared/serializers/index.d.ts +2 -1
- package/dist/sse/shared/serializers/responses-event-serializer.d.ts +123 -0
- package/dist/sse/shared/serializers/types.d.ts +51 -0
- package/dist/sse/shared/utils.d.ts +254 -0
- package/dist/sse/shared/writer.d.ts +2 -2
- package/dist/sse/sse-to-json/anthropic-sse-to-json-converter.d.ts +1 -1
- package/dist/sse/sse-to-json/builders/anthropic-response-builder.d.ts +1 -1
- package/dist/sse/sse-to-json/builders/response-builder.d.ts +1 -1
- package/dist/sse/sse-to-json/chat-sse-to-json-converter.d.ts +2 -1
- package/dist/sse/sse-to-json/gemini-sse-to-json-converter.d.ts +2 -1
- package/dist/sse/sse-to-json/parsers/sse-parser.d.ts +73 -0
- package/dist/sse/sse-to-json/responses-sse-to-json-converter.d.ts +1 -1
- package/dist/sse/types/chat-types.d.ts +1 -1
- package/dist/sse/types/responses-types.d.ts +1 -1
- package/dist/tools/apply-patch/execution-capturer.d.ts +13 -0
- package/dist/tools/apply-patch/execution-capturer.js +158 -0
- package/dist/tools/apply-patch/regression-capturer.d.ts +1 -0
- package/dist/tools/apply-patch/regression-capturer.js +5 -4
- package/dist/tools/apply-patch/structured.js +109 -13
- package/dist/tools/apply-patch/validator.js +112 -18
- package/dist/tools/tool-registry.d.ts +8 -0
- package/dist/tools/tool-registry.js +2 -1
- package/package.json +4 -4
- package/dist/conversion/compat/actions/apply-patch-format-fixer.js +0 -233
- package/dist/conversion/config/compat-profiles.json +0 -38
- package/dist/conversion/hub/pipeline/context-limit.d.ts +0 -13
- package/dist/conversion/hub/pipeline/context-limit.js +0 -55
- package/dist/conversion/hub/response/server-side-tools.d.ts +0 -26
- package/dist/conversion/hub/response/server-side-tools.js +0 -383
- package/dist/conversion/shared/bridge-conversation-store.d.ts +0 -41
- package/dist/conversion/shared/bridge-conversation-store.js +0 -279
- package/dist/conversion/shared/bridge-request-adapter.d.ts +0 -28
- package/dist/conversion/shared/bridge-request-adapter.js +0 -430
- package/dist/conversion/shared/responses-id-utils.js +0 -42
- package/dist/conversion/shared/responses-instructions.js +0 -113
- package/dist/conversion/shared/responses-message-utils.d.ts +0 -15
- package/dist/conversion/shared/responses-message-utils.js +0 -206
- package/dist/conversion/shared/responses-metadata.js +0 -1
- package/dist/conversion/shared/responses-output-utils.d.ts +0 -7
- package/dist/conversion/shared/responses-output-utils.js +0 -108
- package/dist/conversion/shared/responses-types.d.ts +0 -33
- package/dist/conversion/shared/tool-normalizers.d.ts +0 -4
- package/dist/conversion/shared/tool-normalizers.js +0 -84
- package/dist/filters/special/request-streaming-to-nonstreaming.d.ts +0 -13
- package/dist/filters/special/request-streaming-to-nonstreaming.js +0 -39
- package/dist/filters/special/response-apply-patch-toon-decode.d.ts +0 -23
- package/dist/filters/special/response-apply-patch-toon-decode.js +0 -460
- package/dist/filters/special/response-tool-arguments-toon-decode.d.ts +0 -10
- package/dist/filters/special/response-tool-arguments-toon-decode.js +0 -154
- package/dist/servertool/flow-types.d.ts +0 -40
- package/dist/servertool/flow-types.js +0 -1
- package/dist/servertool/orchestration-types.d.ts +0 -33
- package/dist/servertool/orchestration-types.js +0 -1
- package/dist/servertool/vision-tool.d.ts +0 -2
- package/dist/servertool/vision-tool.js +0 -185
- package/dist/tools/patch-args-normalizer.d.ts +0 -15
- package/dist/tools/patch-args-normalizer.js +0 -472
- package/dist/utils/toon.d.ts +0 -4
- package/dist/utils/toon.js +0 -75
- /package/dist/{conversion/compat/actions/apply-patch-format-fixer.d.ts → servertool/handlers/apply-patch-guard.d.ts} +0 -0
- /package/dist/{conversion/shared/responses-types.js → servertool/handlers/exec-command-guard.d.ts} +0 -0
|
@@ -2,6 +2,8 @@ import { registerServerToolHandler } from '../registry.js';
|
|
|
2
2
|
import { cloneJson } from '../server-side-tools.js';
|
|
3
3
|
import { loadRoutingInstructionStateSync, saveRoutingInstructionStateAsync } from '../../router/virtual-router/sticky-session-store.js';
|
|
4
4
|
import { isCompactionRequest } from './compaction-detect.js';
|
|
5
|
+
import { buildResponsesRequestFromChat, captureResponsesContext, buildChatRequestFromResponses } from '../../conversion/responses/responses-openai-bridge.js';
|
|
6
|
+
import { buildAnthropicRequestFromOpenAIChat } from '../../conversion/codecs/anthropic-openai-codec.js';
|
|
5
7
|
const STOPMESSAGE_DEBUG = (process.env.ROUTECODEX_STOPMESSAGE_DEBUG || '').trim() === '1';
|
|
6
8
|
function debugLog(message, extra) {
|
|
7
9
|
if (!STOPMESSAGE_DEBUG) {
|
|
@@ -113,17 +115,13 @@ const handler = async (ctx) => {
|
|
|
113
115
|
return null;
|
|
114
116
|
}
|
|
115
117
|
const entryEndpoint = resolveEntryEndpoint(record);
|
|
116
|
-
const followupPayload = buildStopMessageFollowupPayload(captured, text, ctx.base);
|
|
118
|
+
const followupPayload = buildStopMessageFollowupPayload(captured, text, ctx.base, entryEndpoint);
|
|
117
119
|
if (!followupPayload) {
|
|
118
120
|
debugLog('skip_failed_build_followup', {
|
|
119
121
|
stickyKey
|
|
120
122
|
});
|
|
121
123
|
return null;
|
|
122
124
|
}
|
|
123
|
-
const nextUsed = used + 1;
|
|
124
|
-
state.stopMessageUsed = nextUsed;
|
|
125
|
-
state.stopMessageLastUsedAt = Date.now();
|
|
126
|
-
saveRoutingInstructionStateAsync(stickyKey, state);
|
|
127
125
|
const followupMetadata = {
|
|
128
126
|
serverToolFollowup: true,
|
|
129
127
|
stream: false,
|
|
@@ -132,9 +130,6 @@ const handler = async (ctx) => {
|
|
|
132
130
|
serverToolOriginalEntryEndpoint: entryEndpoint,
|
|
133
131
|
...(connectionState ? { clientConnectionState: connectionState } : {})
|
|
134
132
|
};
|
|
135
|
-
if (shouldForceChatProtocol(entryEndpoint)) {
|
|
136
|
-
followupMetadata.serverToolFollowupProtocol = 'openai-chat';
|
|
137
|
-
}
|
|
138
133
|
return {
|
|
139
134
|
chatResponse: ctx.base,
|
|
140
135
|
execution: {
|
|
@@ -168,38 +163,53 @@ function isStopFinishReason(base) {
|
|
|
168
163
|
}
|
|
169
164
|
const payload = base;
|
|
170
165
|
const choicesRaw = payload.choices;
|
|
171
|
-
if (
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
166
|
+
if (Array.isArray(choicesRaw) && choicesRaw.length) {
|
|
167
|
+
const first = choicesRaw[0];
|
|
168
|
+
if (!first || typeof first !== 'object' || Array.isArray(first)) {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
const finishReasonRaw = first.finish_reason;
|
|
172
|
+
const finishReason = typeof finishReasonRaw === 'string' && finishReasonRaw.trim()
|
|
173
|
+
? finishReasonRaw.trim().toLowerCase()
|
|
174
|
+
: '';
|
|
175
|
+
// 将模型视为“自然结束”的场景:
|
|
176
|
+
// - OpenAI 兼容:finish_reason === 'stop'
|
|
177
|
+
// - 截断场景:finish_reason === 'length'(例如 Gemini/Claude 流式输出被 max token 截断)
|
|
178
|
+
// 统一视作可触发 stopMessage 的终止点;仅排除显式的 tool_calls。
|
|
179
|
+
if (!finishReason || finishReason === 'tool_calls') {
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
if (finishReason !== 'stop' && finishReason !== 'length') {
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
const message = first.message &&
|
|
186
|
+
typeof first.message === 'object' &&
|
|
187
|
+
!Array.isArray(first.message)
|
|
188
|
+
? first.message
|
|
189
|
+
: null;
|
|
190
|
+
if (!message) {
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
const toolCalls = Array.isArray(message.tool_calls) ? message.tool_calls : [];
|
|
194
|
+
if (toolCalls.length > 0) {
|
|
195
|
+
// 如果当前响应仍在发起工具调用,则由工具执行驱动后续轮次,不触发 stopMessage。
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
return true;
|
|
177
199
|
}
|
|
178
|
-
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
: '';
|
|
182
|
-
// 将模型视为“自然结束”的场景:
|
|
183
|
-
// - OpenAI 兼容:finish_reason === 'stop'
|
|
184
|
-
// - 截断场景:finish_reason === 'length'(例如 Gemini/Claude 流式输出被 max token 截断)
|
|
185
|
-
// 统一视作可触发 stopMessage 的终止点;仅排除显式的 tool_calls。
|
|
186
|
-
if (!finishReason || finishReason === 'tool_calls') {
|
|
200
|
+
// OpenAI Responses shape: status completed + no required_action + no tool-like output entries
|
|
201
|
+
const statusRaw = typeof payload.status === 'string' ? payload.status.trim().toLowerCase() : '';
|
|
202
|
+
if (statusRaw && statusRaw !== 'completed') {
|
|
187
203
|
return false;
|
|
188
204
|
}
|
|
189
|
-
if (
|
|
205
|
+
if (payload.required_action && typeof payload.required_action === 'object') {
|
|
190
206
|
return false;
|
|
191
207
|
}
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
!Array.isArray(first.message)
|
|
195
|
-
? first.message
|
|
196
|
-
: null;
|
|
197
|
-
if (!message) {
|
|
208
|
+
const outputRaw = Array.isArray(payload.output) ? payload.output : [];
|
|
209
|
+
if (!outputRaw.length) {
|
|
198
210
|
return false;
|
|
199
211
|
}
|
|
200
|
-
|
|
201
|
-
if (toolCalls.length > 0) {
|
|
202
|
-
// 如果当前响应仍在发起工具调用,则由工具执行驱动后续轮次,不触发 stopMessage。
|
|
212
|
+
if (outputRaw.some((item) => hasToolLikeOutput(item))) {
|
|
203
213
|
return false;
|
|
204
214
|
}
|
|
205
215
|
return true;
|
|
@@ -214,49 +224,211 @@ function getCapturedRequest(adapterContext) {
|
|
|
214
224
|
}
|
|
215
225
|
return captured;
|
|
216
226
|
}
|
|
217
|
-
function
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
227
|
+
function extractChatSeedFromCapturedRequest(source) {
|
|
228
|
+
const model = typeof source.model === 'string' && source.model.trim()
|
|
229
|
+
? source.model.trim()
|
|
230
|
+
: undefined;
|
|
231
|
+
const rawMessages = Array.isArray(source.messages)
|
|
232
|
+
? source.messages
|
|
233
|
+
: null;
|
|
234
|
+
if (rawMessages) {
|
|
235
|
+
const tools = Array.isArray(source.tools)
|
|
236
|
+
? cloneJson(source.tools)
|
|
237
|
+
: undefined;
|
|
238
|
+
return {
|
|
239
|
+
...(model ? { model } : {}),
|
|
240
|
+
messages: cloneJson(rawMessages),
|
|
241
|
+
...(tools ? { tools } : {})
|
|
242
|
+
};
|
|
224
243
|
}
|
|
225
|
-
const
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
const
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
primary.message &&
|
|
234
|
-
typeof primary.message === 'object' &&
|
|
235
|
-
!Array.isArray(primary.message)
|
|
236
|
-
? primary.message
|
|
237
|
-
: null;
|
|
238
|
-
if (msg) {
|
|
239
|
-
messages.push(cloneJson(msg));
|
|
244
|
+
const rawInput = Array.isArray(source.input)
|
|
245
|
+
? source.input
|
|
246
|
+
: null;
|
|
247
|
+
if (rawInput) {
|
|
248
|
+
try {
|
|
249
|
+
const ctx = captureResponsesContext(source);
|
|
250
|
+
if (!ctx.isResponsesPayload) {
|
|
251
|
+
return null;
|
|
240
252
|
}
|
|
253
|
+
const rebuilt = buildChatRequestFromResponses(source, ctx).request;
|
|
254
|
+
const rebuiltModel = typeof rebuilt.model === 'string' && rebuilt.model.trim().length ? String(rebuilt.model).trim() : model;
|
|
255
|
+
const rebuiltMessages = Array.isArray(rebuilt.messages) ? rebuilt.messages : [];
|
|
256
|
+
const rebuiltTools = Array.isArray(rebuilt.tools) ? rebuilt.tools : undefined;
|
|
257
|
+
return {
|
|
258
|
+
...(rebuiltModel ? { model: rebuiltModel } : {}),
|
|
259
|
+
messages: cloneJson(rebuiltMessages),
|
|
260
|
+
...(rebuiltTools ? { tools: cloneJson(rebuiltTools) } : {})
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
return null;
|
|
241
265
|
}
|
|
242
266
|
}
|
|
243
|
-
|
|
244
|
-
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
function buildStopMessageFollowupPayload(source, text, baseResponse, entryEndpoint) {
|
|
270
|
+
if (!source || typeof source !== 'object') {
|
|
271
|
+
return null;
|
|
245
272
|
}
|
|
273
|
+
const chatSeed = extractChatSeedFromCapturedRequest(source);
|
|
274
|
+
const model = chatSeed?.model;
|
|
275
|
+
const originalMessages = chatSeed?.messages ? cloneJson(chatSeed.messages) : [];
|
|
276
|
+
const originalTools = chatSeed?.tools ? cloneJson(chatSeed.tools) : undefined;
|
|
277
|
+
const originalParameters = (() => {
|
|
278
|
+
const direct = source.parameters;
|
|
279
|
+
if (direct && typeof direct === 'object' && !Array.isArray(direct)) {
|
|
280
|
+
return cloneJson(direct);
|
|
281
|
+
}
|
|
282
|
+
// Backward/compat: captured request might be a raw `/v1/responses` payload with
|
|
283
|
+
// top-level parameters (max_output_tokens, temperature, ...), not nested under `parameters`.
|
|
284
|
+
const record = source;
|
|
285
|
+
const allowed = new Set([
|
|
286
|
+
'temperature',
|
|
287
|
+
'top_p',
|
|
288
|
+
'max_output_tokens',
|
|
289
|
+
'seed',
|
|
290
|
+
'logit_bias',
|
|
291
|
+
'user',
|
|
292
|
+
'parallel_tool_calls',
|
|
293
|
+
'tool_choice',
|
|
294
|
+
'response_format',
|
|
295
|
+
'stream'
|
|
296
|
+
]);
|
|
297
|
+
const out = {};
|
|
298
|
+
if (record.max_output_tokens === undefined && record.max_tokens !== undefined) {
|
|
299
|
+
out.max_output_tokens = record.max_tokens;
|
|
300
|
+
}
|
|
301
|
+
for (const key of Object.keys(record)) {
|
|
302
|
+
if (!allowed.has(key))
|
|
303
|
+
continue;
|
|
304
|
+
out[key] = record[key];
|
|
305
|
+
}
|
|
306
|
+
return Object.keys(out).length ? cloneJson(out) : undefined;
|
|
307
|
+
})();
|
|
308
|
+
const parametersForFollowup = originalParameters
|
|
309
|
+
? (() => {
|
|
310
|
+
const cloned = cloneJson(originalParameters);
|
|
311
|
+
// Followup requests are always non-streaming (servertool orchestration enforces this),
|
|
312
|
+
// so remove any inherited stream hints to avoid conflicting flags.
|
|
313
|
+
delete cloned.stream;
|
|
314
|
+
return cloned;
|
|
315
|
+
})()
|
|
316
|
+
: undefined;
|
|
317
|
+
const assistantMessage = extractAssistantMessage(baseResponse);
|
|
318
|
+
const messages = assistantMessage
|
|
319
|
+
? [...originalMessages, assistantMessage]
|
|
320
|
+
: [...originalMessages];
|
|
246
321
|
messages.push({
|
|
247
322
|
role: 'user',
|
|
248
323
|
content: text
|
|
249
324
|
});
|
|
250
|
-
payload
|
|
251
|
-
|
|
252
|
-
|
|
325
|
+
// Build canonical OpenAI Chat payload first (deep cloned).
|
|
326
|
+
const chatPayload = {
|
|
327
|
+
...(model ? { model } : {}),
|
|
328
|
+
messages,
|
|
329
|
+
...(originalTools ? { tools: originalTools } : {})
|
|
330
|
+
};
|
|
331
|
+
const normalizedEntry = typeof entryEndpoint === 'string' ? entryEndpoint.trim().toLowerCase() : '';
|
|
332
|
+
if (normalizedEntry.includes('/v1/responses')) {
|
|
333
|
+
return buildResponsesRequestFromChat(chatPayload, {
|
|
334
|
+
stream: false,
|
|
335
|
+
...(parametersForFollowup ? { parameters: parametersForFollowup } : {})
|
|
336
|
+
}).request;
|
|
337
|
+
}
|
|
338
|
+
if (normalizedEntry.includes('/v1/messages')) {
|
|
339
|
+
const anthropicChatPayload = {
|
|
340
|
+
...chatPayload,
|
|
341
|
+
...(parametersForFollowup ? parametersForFollowup : {})
|
|
342
|
+
};
|
|
343
|
+
return buildAnthropicRequestFromOpenAIChat(anthropicChatPayload);
|
|
344
|
+
}
|
|
345
|
+
const openaiChatPayload = {
|
|
346
|
+
...chatPayload,
|
|
347
|
+
...(parametersForFollowup ? parametersForFollowup : {})
|
|
348
|
+
};
|
|
349
|
+
return openaiChatPayload;
|
|
350
|
+
}
|
|
351
|
+
function extractAssistantMessage(baseResponse) {
|
|
352
|
+
if (!baseResponse || typeof baseResponse !== 'object' || Array.isArray(baseResponse)) {
|
|
353
|
+
return null;
|
|
354
|
+
}
|
|
355
|
+
const base = baseResponse;
|
|
356
|
+
const choices = Array.isArray(base.choices) ? base.choices : [];
|
|
357
|
+
if (choices.length > 0) {
|
|
358
|
+
const first = choices[0] && typeof choices[0] === 'object' && !Array.isArray(choices[0])
|
|
359
|
+
? choices[0]
|
|
360
|
+
: null;
|
|
361
|
+
const msg = first &&
|
|
362
|
+
first.message &&
|
|
363
|
+
typeof first.message === 'object' &&
|
|
364
|
+
!Array.isArray(first.message)
|
|
365
|
+
? first.message
|
|
366
|
+
: null;
|
|
367
|
+
if (msg) {
|
|
368
|
+
return cloneJson(msg);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
const outputText = extractResponsesOutputText(base);
|
|
372
|
+
if (outputText.length > 0) {
|
|
373
|
+
return {
|
|
374
|
+
role: 'assistant',
|
|
375
|
+
content: outputText
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
return null;
|
|
379
|
+
}
|
|
380
|
+
function extractResponsesOutputText(base) {
|
|
381
|
+
const raw = base.output_text;
|
|
382
|
+
if (typeof raw === 'string') {
|
|
383
|
+
return raw.trim();
|
|
384
|
+
}
|
|
385
|
+
if (Array.isArray(raw)) {
|
|
386
|
+
const texts = raw
|
|
387
|
+
.map((entry) => (typeof entry === 'string' ? entry : ''))
|
|
388
|
+
.filter((entry) => entry.trim().length > 0);
|
|
389
|
+
if (texts.length > 0) {
|
|
390
|
+
return texts.join('\n').trim();
|
|
391
|
+
}
|
|
253
392
|
}
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
393
|
+
const output = Array.isArray(base.output) ? (base.output) : [];
|
|
394
|
+
const chunks = [];
|
|
395
|
+
for (const item of output) {
|
|
396
|
+
if (!item || typeof item !== 'object' || Array.isArray(item))
|
|
397
|
+
continue;
|
|
398
|
+
if (typeof item.type !== 'string')
|
|
399
|
+
continue;
|
|
400
|
+
const type = String(item.type).trim().toLowerCase();
|
|
401
|
+
if (type !== 'message')
|
|
402
|
+
continue;
|
|
403
|
+
const content = Array.isArray(item.content) ? (item.content) : [];
|
|
404
|
+
for (const part of content) {
|
|
405
|
+
if (!part || typeof part !== 'object' || Array.isArray(part))
|
|
406
|
+
continue;
|
|
407
|
+
const pType = typeof part.type === 'string'
|
|
408
|
+
? String(part.type).trim().toLowerCase()
|
|
409
|
+
: '';
|
|
410
|
+
if (pType === 'output_text') {
|
|
411
|
+
const text = typeof part.text === 'string' ? String(part.text) : '';
|
|
412
|
+
if (text.trim().length)
|
|
413
|
+
chunks.push(text.trim());
|
|
414
|
+
}
|
|
415
|
+
}
|
|
258
416
|
}
|
|
259
|
-
return
|
|
417
|
+
return chunks.join('\n').trim();
|
|
418
|
+
}
|
|
419
|
+
function hasToolLikeOutput(value) {
|
|
420
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
421
|
+
return false;
|
|
422
|
+
}
|
|
423
|
+
const typeRaw = value.type;
|
|
424
|
+
const type = typeof typeRaw === 'string' ? typeRaw.trim().toLowerCase() : '';
|
|
425
|
+
if (!type) {
|
|
426
|
+
return false;
|
|
427
|
+
}
|
|
428
|
+
return (type === 'tool_call' ||
|
|
429
|
+
type === 'tool_use' ||
|
|
430
|
+
type === 'function_call' ||
|
|
431
|
+
type.includes('tool'));
|
|
260
432
|
}
|
|
261
433
|
function resolveClientConnectionState(value) {
|
|
262
434
|
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
@@ -372,13 +544,3 @@ function resolveEntryEndpoint(record) {
|
|
|
372
544
|
}
|
|
373
545
|
return '/v1/chat/completions';
|
|
374
546
|
}
|
|
375
|
-
function shouldForceChatProtocol(entryEndpoint) {
|
|
376
|
-
if (typeof entryEndpoint !== 'string') {
|
|
377
|
-
return false;
|
|
378
|
-
}
|
|
379
|
-
const normalized = entryEndpoint.trim().toLowerCase();
|
|
380
|
-
if (!normalized) {
|
|
381
|
-
return false;
|
|
382
|
-
}
|
|
383
|
-
return !normalized.includes('/v1/chat/completions');
|
|
384
|
-
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { registerServerToolHandler } from '../registry.js';
|
|
2
2
|
import { cloneJson, extractTextFromChatLike } from '../server-side-tools.js';
|
|
3
|
+
import { buildEntryAwareFollowupPayload, dropToolByFunctionName, extractCapturedChatSeed } from './followup-request-builder.js';
|
|
3
4
|
const FLOW_ID = 'vision_flow';
|
|
4
5
|
const handler = async (ctx) => {
|
|
5
6
|
if (!ctx.options.reenterPipeline) {
|
|
@@ -36,7 +37,7 @@ const handler = async (ctx) => {
|
|
|
36
37
|
if (!visionSummary) {
|
|
37
38
|
return null;
|
|
38
39
|
}
|
|
39
|
-
const followupPayload = buildVisionFollowupPayload(captured, visionSummary);
|
|
40
|
+
const followupPayload = buildVisionFollowupPayload(captured, visionSummary, ctx.options.entryEndpoint || ctx.adapterContext?.entryEndpoint || '/v1/chat/completions');
|
|
40
41
|
if (!followupPayload) {
|
|
41
42
|
return null;
|
|
42
43
|
}
|
|
@@ -44,8 +45,7 @@ const handler = async (ctx) => {
|
|
|
44
45
|
flowId: FLOW_ID,
|
|
45
46
|
followup: {
|
|
46
47
|
requestIdSuffix: ':vision_followup',
|
|
47
|
-
payload: followupPayload
|
|
48
|
-
metadata: buildFollowupMetadata(ctx.adapterContext, 'vision')
|
|
48
|
+
payload: followupPayload
|
|
49
49
|
}
|
|
50
50
|
};
|
|
51
51
|
return {
|
|
@@ -194,24 +194,20 @@ function buildVisionUserMessage(source) {
|
|
|
194
194
|
}
|
|
195
195
|
return message;
|
|
196
196
|
}
|
|
197
|
-
function buildVisionFollowupPayload(source, summary) {
|
|
198
|
-
|
|
197
|
+
function buildVisionFollowupPayload(source, summary, entryEndpoint) {
|
|
198
|
+
const seed = extractCapturedChatSeed(source);
|
|
199
|
+
if (!seed) {
|
|
199
200
|
return null;
|
|
200
201
|
}
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
if (parameters && typeof parameters === 'object' && !Array.isArray(parameters)) {
|
|
211
|
-
const params = cloneJson(parameters);
|
|
212
|
-
Object.assign(payload, params);
|
|
213
|
-
}
|
|
214
|
-
return payload;
|
|
202
|
+
const messages = injectVisionSummary(seed.messages, summary);
|
|
203
|
+
const filteredTools = dropToolByFunctionName(seed.tools, 'vision');
|
|
204
|
+
return buildEntryAwareFollowupPayload({
|
|
205
|
+
entryEndpoint,
|
|
206
|
+
model: seed.model,
|
|
207
|
+
messages,
|
|
208
|
+
...(filteredTools ? { tools: filteredTools } : {}),
|
|
209
|
+
...(seed.parameters ? { parameters: seed.parameters } : {})
|
|
210
|
+
});
|
|
215
211
|
}
|
|
216
212
|
function injectVisionSummary(source, summary) {
|
|
217
213
|
const messages = Array.isArray(source) ? cloneJson(source) : [];
|
|
@@ -282,11 +278,3 @@ function injectVisionSummary(source, summary) {
|
|
|
282
278
|
}
|
|
283
279
|
return messages;
|
|
284
280
|
}
|
|
285
|
-
function buildFollowupMetadata(adapterContext, toolName) {
|
|
286
|
-
const ctx = adapterContext && typeof adapterContext === 'object' ? adapterContext : null;
|
|
287
|
-
const routeId = ctx && typeof ctx.routeId === 'string' && ctx.routeId.trim() ? ctx.routeId.trim() : '';
|
|
288
|
-
if (!routeId || routeId.toLowerCase() === toolName.toLowerCase()) {
|
|
289
|
-
return undefined;
|
|
290
|
-
}
|
|
291
|
-
return { routeHint: routeId };
|
|
292
|
-
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { buildOpenAIChatFromGeminiResponse } from '../../conversion/codecs/gemini-openai-codec.js';
|
|
2
2
|
import { registerServerToolHandler } from '../registry.js';
|
|
3
3
|
import { cloneJson, extractTextFromChatLike } from '../server-side-tools.js';
|
|
4
|
+
import { buildEntryAwareFollowupPayload, dropToolByFunctionName, extractCapturedChatSeed } from './followup-request-builder.js';
|
|
4
5
|
const FLOW_ID = 'web_search_flow';
|
|
5
6
|
const handler = async (ctx) => {
|
|
6
7
|
const toolCall = ctx.toolCall;
|
|
@@ -53,14 +54,17 @@ const handler = async (ctx) => {
|
|
|
53
54
|
chosenResult = lastFailure.result;
|
|
54
55
|
}
|
|
55
56
|
const patched = injectWebSearchToolResult(ctx.base, toolCall, chosenEngine, query, chosenResult);
|
|
56
|
-
const followupPayload = buildWebSearchFollowupPayload(ctx.adapterContext, patched);
|
|
57
|
+
const followupPayload = buildWebSearchFollowupPayload(ctx.adapterContext, patched, ctx.options.entryEndpoint || ctx.adapterContext?.entryEndpoint || '/v1/chat/completions');
|
|
57
58
|
const execution = {
|
|
58
59
|
flowId: FLOW_ID,
|
|
59
60
|
followup: followupPayload
|
|
60
61
|
? {
|
|
61
62
|
requestIdSuffix: ':web_search_followup',
|
|
62
63
|
payload: followupPayload,
|
|
63
|
-
metadata:
|
|
64
|
+
metadata: {
|
|
65
|
+
// keep minimal; servertool engine will inject the standard followup metadata defaults
|
|
66
|
+
serverToolFollowup: true
|
|
67
|
+
}
|
|
64
68
|
}
|
|
65
69
|
: undefined,
|
|
66
70
|
context: {
|
|
@@ -565,19 +569,14 @@ function injectWebSearchToolResult(base, toolCall, engine, query, backendResult)
|
|
|
565
569
|
];
|
|
566
570
|
return cloned;
|
|
567
571
|
}
|
|
568
|
-
function buildWebSearchFollowupPayload(adapterContext, chatResponse) {
|
|
572
|
+
function buildWebSearchFollowupPayload(adapterContext, chatResponse, entryEndpoint) {
|
|
569
573
|
const captured = adapterContext && typeof adapterContext === 'object'
|
|
570
574
|
? adapterContext.capturedChatRequest
|
|
571
575
|
: undefined;
|
|
572
|
-
|
|
576
|
+
const seed = extractCapturedChatSeed(captured);
|
|
577
|
+
if (!seed) {
|
|
573
578
|
return null;
|
|
574
579
|
}
|
|
575
|
-
const originalMessages = Array.isArray(captured.messages)
|
|
576
|
-
? cloneJson(captured.messages)
|
|
577
|
-
: [];
|
|
578
|
-
const originalTools = Array.isArray(captured.tools)
|
|
579
|
-
? cloneJson(captured.tools)
|
|
580
|
-
: [];
|
|
581
580
|
const assistantMessage = extractAssistantMessage(chatResponse);
|
|
582
581
|
if (!assistantMessage) {
|
|
583
582
|
return null;
|
|
@@ -586,32 +585,15 @@ function buildWebSearchFollowupPayload(adapterContext, chatResponse) {
|
|
|
586
585
|
if (!toolMessages.length) {
|
|
587
586
|
return null;
|
|
588
587
|
}
|
|
589
|
-
const reconstructed = [...
|
|
590
|
-
const filteredTools =
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
if (!name)
|
|
598
|
-
return true;
|
|
599
|
-
return name !== 'web_search';
|
|
588
|
+
const reconstructed = [...seed.messages, assistantMessage, ...toolMessages];
|
|
589
|
+
const filteredTools = dropToolByFunctionName(seed.tools, 'web_search');
|
|
590
|
+
return buildEntryAwareFollowupPayload({
|
|
591
|
+
entryEndpoint,
|
|
592
|
+
model: seed.model,
|
|
593
|
+
messages: reconstructed,
|
|
594
|
+
...(filteredTools ? { tools: filteredTools } : {}),
|
|
595
|
+
...(seed.parameters ? { parameters: seed.parameters } : {})
|
|
600
596
|
});
|
|
601
|
-
const payload = {
|
|
602
|
-
messages: reconstructed
|
|
603
|
-
};
|
|
604
|
-
if (typeof captured.model === 'string' && captured.model.trim()) {
|
|
605
|
-
payload.model = captured.model.trim();
|
|
606
|
-
}
|
|
607
|
-
if (filteredTools.length) {
|
|
608
|
-
payload.tools = filteredTools;
|
|
609
|
-
}
|
|
610
|
-
const parameters = captured.parameters;
|
|
611
|
-
if (parameters && typeof parameters === 'object' && !Array.isArray(parameters)) {
|
|
612
|
-
Object.assign(payload, cloneJson(parameters));
|
|
613
|
-
}
|
|
614
|
-
return payload;
|
|
615
597
|
}
|
|
616
598
|
function extractAssistantMessage(chatResponse) {
|
|
617
599
|
const choices = Array.isArray(chatResponse.choices)
|
|
@@ -680,14 +662,6 @@ function logServerToolWebSearch(engine, requestId, query) {
|
|
|
680
662
|
// eslint-disable-next-line no-console
|
|
681
663
|
console.log(`\x1b[31m${vrLine}\x1b[0m`);
|
|
682
664
|
}
|
|
683
|
-
function buildFollowupMetadata(adapterContext, toolName) {
|
|
684
|
-
const ctx = adapterContext && typeof adapterContext === 'object' ? adapterContext : null;
|
|
685
|
-
const routeId = ctx && typeof ctx.routeId === 'string' && ctx.routeId.trim() ? ctx.routeId.trim() : '';
|
|
686
|
-
if (!routeId || routeId.toLowerCase() === toolName.toLowerCase()) {
|
|
687
|
-
return undefined;
|
|
688
|
-
}
|
|
689
|
-
return { routeHint: routeId };
|
|
690
|
-
}
|
|
691
665
|
function findWebSearchArray(payload) {
|
|
692
666
|
let current = payload;
|
|
693
667
|
const visited = new Set();
|
|
@@ -3,7 +3,10 @@ import type { ServerSideToolEngineOptions, ServerSideToolEngineResult, ToolCall
|
|
|
3
3
|
import './handlers/web-search.js';
|
|
4
4
|
import './handlers/vision.js';
|
|
5
5
|
import './handlers/iflow-model-error-retry.js';
|
|
6
|
+
import './handlers/gemini-empty-reply-continue.js';
|
|
6
7
|
import './handlers/stop-message-auto.js';
|
|
8
|
+
import './handlers/exec-command-guard.js';
|
|
9
|
+
import './handlers/apply-patch-guard.js';
|
|
7
10
|
export declare function runServerSideToolEngine(options: ServerSideToolEngineOptions): Promise<ServerSideToolEngineResult>;
|
|
8
11
|
export declare function extractToolCalls(chatResponse: JsonObject): ToolCall[];
|
|
9
12
|
export declare function cloneJson<T>(value: T): T;
|
|
@@ -3,7 +3,10 @@ import { ProviderProtocolError } from '../conversion/shared/errors.js';
|
|
|
3
3
|
import './handlers/web-search.js';
|
|
4
4
|
import './handlers/vision.js';
|
|
5
5
|
import './handlers/iflow-model-error-retry.js';
|
|
6
|
+
import './handlers/gemini-empty-reply-continue.js';
|
|
6
7
|
import './handlers/stop-message-auto.js';
|
|
8
|
+
import './handlers/exec-command-guard.js';
|
|
9
|
+
import './handlers/apply-patch-guard.js';
|
|
7
10
|
export async function runServerSideToolEngine(options) {
|
|
8
11
|
const base = asObject(options.chatResponse);
|
|
9
12
|
if (!base) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { PassThrough } from 'node:stream';
|
|
2
|
-
import {
|
|
2
|
+
import { DEFAULT_ANTHROPIC_CONVERSION_CONFIG } from '../types/index.js';
|
|
3
|
+
import type { AnthropicMessageResponse, AnthropicJsonToSseOptions } from '../types/index.js';
|
|
3
4
|
export declare class AnthropicJsonToSseConverter {
|
|
4
5
|
private config;
|
|
5
6
|
private contexts;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chat JSON → SSE转换器(重构版本)
|
|
3
|
+
* 使用函数化架构:事件生成 + 序列化 + 写入分离
|
|
4
|
+
*/
|
|
5
|
+
import { DEFAULT_CHAT_CONVERSION_CONFIG } from '../types/index.js';
|
|
6
|
+
import type { ChatCompletionRequest, ChatCompletionResponse, ChatJsonToSseContext, ChatJsonToSseOptions, ChatSseEventStream } from '../types/index.js';
|
|
7
|
+
/**
|
|
8
|
+
* 重构后的Chat JSON到SSE转换器
|
|
9
|
+
* 采用函数化架构,专注于编排而非具体业务逻辑
|
|
10
|
+
*/
|
|
11
|
+
export declare class ChatJsonToSseConverterRefactored {
|
|
12
|
+
private config;
|
|
13
|
+
private contexts;
|
|
14
|
+
constructor(config?: Partial<typeof DEFAULT_CHAT_CONVERSION_CONFIG>);
|
|
15
|
+
/**
|
|
16
|
+
* 将Chat Completion请求转换为SSE流
|
|
17
|
+
*/
|
|
18
|
+
convertRequestToJsonToSse(request: ChatCompletionRequest, options: ChatJsonToSseOptions): Promise<ChatSseEventStream>;
|
|
19
|
+
/**
|
|
20
|
+
* 将Chat Completion响应转换为SSE流
|
|
21
|
+
*/
|
|
22
|
+
convertResponseToJsonToSse(response: ChatCompletionResponse, options: ChatJsonToSseOptions): Promise<ChatSseEventStream>;
|
|
23
|
+
/**
|
|
24
|
+
* 使用函数化架构处理请求转换
|
|
25
|
+
*/
|
|
26
|
+
private processRequestToSseWithFunctions;
|
|
27
|
+
/**
|
|
28
|
+
* 使用函数化架构处理响应转换
|
|
29
|
+
*/
|
|
30
|
+
private processResponseToSseWithFunctions;
|
|
31
|
+
/**
|
|
32
|
+
* 验证请求格式
|
|
33
|
+
*/
|
|
34
|
+
private validateRequest;
|
|
35
|
+
/**
|
|
36
|
+
* 验证响应格式
|
|
37
|
+
*/
|
|
38
|
+
private validateResponse;
|
|
39
|
+
/**
|
|
40
|
+
* 更新统计信息
|
|
41
|
+
*/
|
|
42
|
+
private updateStats;
|
|
43
|
+
/**
|
|
44
|
+
* 包装错误
|
|
45
|
+
*/
|
|
46
|
+
private wrapError;
|
|
47
|
+
/**
|
|
48
|
+
* 处理流错误
|
|
49
|
+
*/
|
|
50
|
+
private handleStreamError;
|
|
51
|
+
/**
|
|
52
|
+
* 完成流
|
|
53
|
+
*/
|
|
54
|
+
private completeStream;
|
|
55
|
+
/**
|
|
56
|
+
* 中止流
|
|
57
|
+
*/
|
|
58
|
+
private abortStream;
|
|
59
|
+
/**
|
|
60
|
+
* 创建请求上下文
|
|
61
|
+
*/
|
|
62
|
+
private createRequestContext;
|
|
63
|
+
/**
|
|
64
|
+
* 创建响应上下文
|
|
65
|
+
*/
|
|
66
|
+
private createResponseContext;
|
|
67
|
+
/**
|
|
68
|
+
* 获取上下文
|
|
69
|
+
*/
|
|
70
|
+
getContext(requestId: string): ChatJsonToSseContext | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* 清理上下文
|
|
73
|
+
*/
|
|
74
|
+
clearContext(requestId: string): void;
|
|
75
|
+
/**
|
|
76
|
+
* 获取所有活跃的上下文
|
|
77
|
+
*/
|
|
78
|
+
getActiveContexts(): Map<string, ChatJsonToSseContext>;
|
|
79
|
+
}
|
|
80
|
+
export declare const ChatJsonToSseConverter: typeof ChatJsonToSseConverterRefactored;
|