@jsonstudio/llms 0.4.6 → 0.6.2
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/codecs/anthropic-openai-codec.js +28 -2
- package/dist/conversion/codecs/gemini-openai-codec.js +23 -0
- package/dist/conversion/codecs/responses-openai-codec.js +8 -1
- package/dist/conversion/hub/node-support.js +14 -1
- package/dist/conversion/hub/pipeline/hub-pipeline.d.ts +66 -0
- package/dist/conversion/hub/pipeline/hub-pipeline.js +284 -193
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage1_format_parse/index.d.ts +11 -0
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage1_format_parse/index.js +6 -0
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.d.ts +16 -0
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.js +17 -0
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/context-factories.d.ts +5 -0
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/context-factories.js +17 -0
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/index.d.ts +19 -0
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/index.js +269 -0
- package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage1_semantic_map/index.d.ts +18 -0
- package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage1_semantic_map/index.js +141 -0
- package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage2_format_build/index.d.ts +11 -0
- package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage2_format_build/index.js +29 -0
- package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage1_tool_governance/index.d.ts +16 -0
- package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage1_tool_governance/index.js +15 -0
- package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage2_route_select/index.d.ts +17 -0
- package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage2_route_select/index.js +18 -0
- package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage1_sse_decode/index.d.ts +17 -0
- package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage1_sse_decode/index.js +63 -0
- package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage2_format_parse/index.d.ts +11 -0
- package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage2_format_parse/index.js +6 -0
- package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage3_semantic_map/index.d.ts +12 -0
- package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage3_semantic_map/index.js +6 -0
- package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage1_client_remap/index.d.ts +13 -0
- package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage1_client_remap/index.js +43 -0
- package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage2_sse_stream/index.d.ts +17 -0
- package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage2_sse_stream/index.js +22 -0
- package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage1_tool_governance/index.d.ts +16 -0
- package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage1_tool_governance/index.js +19 -0
- package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage2_finalize/index.d.ts +17 -0
- package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage2_finalize/index.js +19 -0
- package/dist/conversion/hub/pipeline/stages/utils.d.ts +2 -0
- package/dist/conversion/hub/pipeline/stages/utils.js +11 -0
- package/dist/conversion/hub/pipeline/target-utils.d.ts +5 -0
- package/dist/conversion/hub/pipeline/target-utils.js +87 -0
- package/dist/conversion/hub/process/chat-process.js +23 -17
- package/dist/conversion/hub/response/provider-response.js +69 -122
- package/dist/conversion/hub/response/response-mappers.d.ts +19 -0
- package/dist/conversion/hub/response/response-mappers.js +22 -2
- package/dist/conversion/hub/response/response-runtime.d.ts +8 -0
- package/dist/conversion/hub/response/response-runtime.js +239 -6
- package/dist/conversion/hub/semantic-mappers/anthropic-mapper.d.ts +8 -0
- package/dist/conversion/hub/semantic-mappers/anthropic-mapper.js +135 -55
- package/dist/conversion/hub/semantic-mappers/chat-mapper.js +80 -40
- package/dist/conversion/hub/semantic-mappers/gemini-mapper.js +5 -29
- package/dist/conversion/hub/semantic-mappers/responses-mapper.js +16 -13
- package/dist/conversion/hub/snapshot-recorder.d.ts +13 -0
- package/dist/conversion/hub/snapshot-recorder.js +90 -50
- package/dist/conversion/hub/standardized-bridge.js +49 -38
- package/dist/conversion/hub/types/chat-envelope.d.ts +68 -0
- package/dist/conversion/hub/types/standardized.d.ts +97 -0
- package/dist/conversion/pipeline/codecs/v2/anthropic-openai-pipeline.js +29 -2
- package/dist/conversion/pipeline/codecs/v2/responses-openai-pipeline.js +68 -1
- package/dist/conversion/responses/responses-openai-bridge.d.ts +6 -1
- package/dist/conversion/responses/responses-openai-bridge.js +132 -10
- package/dist/conversion/shared/anthropic-message-utils.d.ts +9 -1
- package/dist/conversion/shared/anthropic-message-utils.js +414 -26
- package/dist/conversion/shared/bridge-actions.js +267 -95
- package/dist/conversion/shared/bridge-message-utils.js +54 -8
- package/dist/conversion/shared/bridge-policies.js +21 -2
- package/dist/conversion/shared/chat-envelope-validator.d.ts +8 -0
- package/dist/conversion/shared/chat-envelope-validator.js +128 -0
- package/dist/conversion/shared/chat-request-filters.js +109 -28
- package/dist/conversion/shared/mcp-injection.js +41 -20
- package/dist/conversion/shared/openai-finalizer.d.ts +11 -0
- package/dist/conversion/shared/openai-finalizer.js +73 -0
- package/dist/conversion/shared/openai-message-normalize.js +32 -31
- package/dist/conversion/shared/protocol-state.d.ts +4 -0
- package/dist/conversion/shared/protocol-state.js +23 -0
- package/dist/conversion/shared/reasoning-normalizer.d.ts +1 -0
- package/dist/conversion/shared/reasoning-normalizer.js +50 -18
- package/dist/conversion/shared/responses-output-builder.d.ts +1 -1
- package/dist/conversion/shared/responses-output-builder.js +76 -25
- package/dist/conversion/shared/responses-reasoning-registry.d.ts +8 -0
- package/dist/conversion/shared/responses-reasoning-registry.js +61 -0
- package/dist/conversion/shared/responses-response-utils.js +32 -2
- package/dist/conversion/shared/responses-tool-utils.js +28 -2
- package/dist/conversion/shared/snapshot-hooks.d.ts +9 -0
- package/dist/conversion/shared/snapshot-hooks.js +60 -6
- package/dist/conversion/shared/snapshot-utils.d.ts +16 -0
- package/dist/conversion/shared/snapshot-utils.js +84 -0
- package/dist/conversion/shared/tool-filter-pipeline.js +46 -7
- package/dist/conversion/shared/tool-mapping.js +13 -2
- package/dist/filters/index.d.ts +18 -0
- package/dist/filters/index.js +0 -1
- package/dist/filters/special/request-streaming-to-nonstreaming.d.ts +13 -0
- package/dist/filters/special/request-streaming-to-nonstreaming.js +13 -1
- package/dist/filters/special/request-tool-choice-policy.js +3 -1
- package/dist/filters/special/request-tool-list-filter.d.ts +11 -0
- package/dist/filters/special/request-tool-list-filter.js +20 -7
- package/dist/sse/shared/responses-output-normalizer.js +5 -4
- package/dist/sse/sse-to-json/builders/response-builder.js +24 -1
- package/dist/sse/types/responses-types.d.ts +2 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { runStandardChatRequestFilters } from '../index.js';
|
|
2
2
|
import { FilterEngine, ResponseToolTextCanonicalizeFilter, ResponseToolArgumentsStringifyFilter, ResponseFinishInvariantsFilter } from '../../filters/index.js';
|
|
3
|
-
import { buildAnthropicFromOpenAIChat, buildOpenAIChatFromAnthropic, mapAnthropicToolsToChat } from '../shared/anthropic-message-utils.js';
|
|
3
|
+
import { buildAnthropicFromOpenAIChat, buildOpenAIChatFromAnthropic, mapAnthropicToolsToChat, buildAnthropicToolAliasMap } from '../shared/anthropic-message-utils.js';
|
|
4
4
|
export { buildAnthropicFromOpenAIChat, buildOpenAIChatFromAnthropic };
|
|
5
5
|
export { buildAnthropicRequestFromOpenAIChat } from '../shared/anthropic-message-utils.js';
|
|
6
6
|
export class AnthropicOpenAIConversionCodec {
|
|
@@ -19,6 +19,11 @@ export class AnthropicOpenAIConversionCodec {
|
|
|
19
19
|
const model = String(payload?.model || 'unknown');
|
|
20
20
|
const { messages } = buildOpenAIChatFromAnthropic(payload);
|
|
21
21
|
const out = { model, messages };
|
|
22
|
+
const aliasMap = buildAnthropicToolAliasMap(payload?.tools);
|
|
23
|
+
if (aliasMap) {
|
|
24
|
+
context.metadata = context.metadata ?? {};
|
|
25
|
+
context.metadata.anthropicToolNameMap = aliasMap;
|
|
26
|
+
}
|
|
22
27
|
// 最小必要的形状转换:Anthropic tools → OpenAI Chat function 工具
|
|
23
28
|
try {
|
|
24
29
|
const normalizedTools = mapAnthropicToolsToChat(payload?.tools);
|
|
@@ -86,6 +91,27 @@ export class AnthropicOpenAIConversionCodec {
|
|
|
86
91
|
staged = await engine.run('response_map', staged, resCtxBase);
|
|
87
92
|
staged = await engine.run('response_post', staged, resCtxBase);
|
|
88
93
|
const governedChat = staged;
|
|
89
|
-
|
|
94
|
+
const aliasMap = coerceAliasMap(context.metadata?.anthropicToolNameMap);
|
|
95
|
+
return buildAnthropicFromOpenAIChat(governedChat, {
|
|
96
|
+
toolNameMap: aliasMap,
|
|
97
|
+
requestId: context.requestId
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function coerceAliasMap(candidate) {
|
|
102
|
+
if (!candidate || typeof candidate !== 'object' || Array.isArray(candidate)) {
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
let populated = false;
|
|
106
|
+
const map = {};
|
|
107
|
+
for (const [key, value] of Object.entries(candidate)) {
|
|
108
|
+
if (typeof key !== 'string' || typeof value !== 'string')
|
|
109
|
+
continue;
|
|
110
|
+
const trimmedKey = key.trim();
|
|
111
|
+
if (!trimmedKey.length)
|
|
112
|
+
continue;
|
|
113
|
+
map[trimmedKey] = value;
|
|
114
|
+
populated = true;
|
|
90
115
|
}
|
|
116
|
+
return populated ? map : undefined;
|
|
91
117
|
}
|
|
@@ -3,6 +3,7 @@ import { resolveBridgePolicy, resolvePolicyActions } from '../shared/bridge-poli
|
|
|
3
3
|
import { normalizeChatMessageContent } from '../shared/chat-output-normalizer.js';
|
|
4
4
|
import { mapBridgeToolsToChat } from '../shared/tool-mapping.js';
|
|
5
5
|
import { prepareGeminiToolsForBridge } from '../shared/gemini-tool-utils.js';
|
|
6
|
+
import { registerResponsesReasoning, consumeResponsesReasoning, registerResponsesOutputTextMeta, consumeResponsesOutputTextMeta } from '../shared/responses-reasoning-registry.js';
|
|
6
7
|
function isObject(v) {
|
|
7
8
|
return !!v && typeof v === 'object' && !Array.isArray(v);
|
|
8
9
|
}
|
|
@@ -276,6 +277,14 @@ export function buildOpenAIChatFromGeminiResponse(payload) {
|
|
|
276
277
|
if (Object.keys(usage).length > 0) {
|
|
277
278
|
chatResp.usage = usage;
|
|
278
279
|
}
|
|
280
|
+
const preservedReasoning = consumeResponsesReasoning(chatResp.id);
|
|
281
|
+
if (preservedReasoning && preservedReasoning.length) {
|
|
282
|
+
chatResp.__responses_reasoning = preservedReasoning;
|
|
283
|
+
}
|
|
284
|
+
const preservedOutputMeta = consumeResponsesOutputTextMeta(chatResp.id);
|
|
285
|
+
if (preservedOutputMeta) {
|
|
286
|
+
chatResp.__responses_output_text_meta = preservedOutputMeta;
|
|
287
|
+
}
|
|
279
288
|
return chatResp;
|
|
280
289
|
}
|
|
281
290
|
export function buildGeminiFromOpenAIChat(chatResp) {
|
|
@@ -344,6 +353,12 @@ export function buildGeminiFromOpenAIChat(chatResp) {
|
|
|
344
353
|
if (contentText && contentText.length) {
|
|
345
354
|
parts.push({ text: contentText });
|
|
346
355
|
}
|
|
356
|
+
const reasoningText = typeof msg?.reasoning_content === 'string' && msg.reasoning_content.trim().length
|
|
357
|
+
? String(msg.reasoning_content).trim()
|
|
358
|
+
: undefined;
|
|
359
|
+
if (reasoningText) {
|
|
360
|
+
parts.push({ reasoning: reasoningText });
|
|
361
|
+
}
|
|
347
362
|
const toolCalls = Array.isArray(msg.tool_calls) ? msg.tool_calls : [];
|
|
348
363
|
for (const tc of toolCalls) {
|
|
349
364
|
if (!tc || typeof tc !== 'object')
|
|
@@ -388,7 +403,9 @@ export function buildGeminiFromOpenAIChat(chatResp) {
|
|
|
388
403
|
usageMetadata.candidatesTokenCount = completionTokens;
|
|
389
404
|
if (Number.isFinite(totalTokens))
|
|
390
405
|
usageMetadata.totalTokenCount = totalTokens;
|
|
406
|
+
const responseId = typeof chatResp?.id === 'string' ? String(chatResp.id) : `chatcmpl_${Date.now()}`;
|
|
391
407
|
const out = {
|
|
408
|
+
id: responseId,
|
|
392
409
|
candidates: [candidate]
|
|
393
410
|
};
|
|
394
411
|
if (chatResp?.model) {
|
|
@@ -396,6 +413,12 @@ export function buildGeminiFromOpenAIChat(chatResp) {
|
|
|
396
413
|
}
|
|
397
414
|
if (Object.keys(usageMetadata).length > 0)
|
|
398
415
|
out.usageMetadata = usageMetadata;
|
|
416
|
+
if (Array.isArray(chatResp?.__responses_reasoning)) {
|
|
417
|
+
registerResponsesReasoning(responseId, chatResp.__responses_reasoning);
|
|
418
|
+
}
|
|
419
|
+
if (chatResp?.__responses_output_text_meta) {
|
|
420
|
+
registerResponsesOutputTextMeta(responseId, chatResp.__responses_output_text_meta);
|
|
421
|
+
}
|
|
399
422
|
return out;
|
|
400
423
|
}
|
|
401
424
|
export class GeminiOpenAIConversionCodec {
|
|
@@ -151,7 +151,14 @@ export class ResponsesOpenAIConversionCodec {
|
|
|
151
151
|
// Debug snapshot after mapping to Responses JSON (non-stream)
|
|
152
152
|
try {
|
|
153
153
|
const { writeSnapshotViaHooks } = await import('../shared/snapshot-hooks.js');
|
|
154
|
-
await writeSnapshotViaHooks({
|
|
154
|
+
await writeSnapshotViaHooks({
|
|
155
|
+
endpoint: '/v1/responses',
|
|
156
|
+
stage: 'response_mapped_json',
|
|
157
|
+
requestId: context.requestId || `req_${Date.now()}`,
|
|
158
|
+
data: responsesJson,
|
|
159
|
+
channel: 'responses',
|
|
160
|
+
verbosity: 'verbose'
|
|
161
|
+
});
|
|
155
162
|
}
|
|
156
163
|
catch { /* ignore */ }
|
|
157
164
|
return responsesJson;
|
|
@@ -102,7 +102,7 @@ function deriveAdapterContext(context, fallbackProtocol) {
|
|
|
102
102
|
(typeof metadata.providerProtocol === 'string' ? metadata.providerProtocol : undefined) ||
|
|
103
103
|
fallbackProtocol;
|
|
104
104
|
const streamingHint = metadata.stream === true ? 'force' : metadata.stream === false ? 'disable' : 'auto';
|
|
105
|
-
const toolCallIdStyle =
|
|
105
|
+
const toolCallIdStyle = normalizeToolCallIdStyleCandidate(metadata.toolCallIdStyle);
|
|
106
106
|
return {
|
|
107
107
|
requestId: context.request.id,
|
|
108
108
|
entryEndpoint: (typeof requestContext.entryEndpoint === 'string' ? requestContext.entryEndpoint : context.request.endpoint) ||
|
|
@@ -115,3 +115,16 @@ function deriveAdapterContext(context, fallbackProtocol) {
|
|
|
115
115
|
toolCallIdStyle
|
|
116
116
|
};
|
|
117
117
|
}
|
|
118
|
+
function normalizeToolCallIdStyleCandidate(value) {
|
|
119
|
+
if (typeof value !== 'string') {
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
const normalized = value.trim().toLowerCase();
|
|
123
|
+
if (normalized === 'fc') {
|
|
124
|
+
return 'fc';
|
|
125
|
+
}
|
|
126
|
+
if (normalized === 'preserve') {
|
|
127
|
+
return 'preserve';
|
|
128
|
+
}
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Readable } from 'node:stream';
|
|
2
|
+
import type { StandardizedRequest, ProcessedRequest } from '../types/standardized.js';
|
|
3
|
+
import type { JsonObject } from '../types/json.js';
|
|
4
|
+
import type { VirtualRouterConfig, RoutingDecision, RoutingDiagnostics, TargetMetadata } from '../../../router/virtual-router/types.js';
|
|
5
|
+
import { type HubProcessNodeResult } from '../process/chat-process.js';
|
|
6
|
+
export interface HubPipelineConfig {
|
|
7
|
+
virtualRouter: VirtualRouterConfig;
|
|
8
|
+
}
|
|
9
|
+
export interface HubPipelineRequestMetadata extends Record<string, unknown> {
|
|
10
|
+
entryEndpoint?: string;
|
|
11
|
+
providerProtocol?: string;
|
|
12
|
+
processMode?: 'chat' | 'passthrough';
|
|
13
|
+
stage?: 'inbound' | 'outbound';
|
|
14
|
+
direction?: 'request' | 'response';
|
|
15
|
+
stream?: boolean;
|
|
16
|
+
routeHint?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface HubPipelineRequest {
|
|
19
|
+
id?: string;
|
|
20
|
+
endpoint: string;
|
|
21
|
+
payload: Record<string, unknown> | {
|
|
22
|
+
readable?: Readable;
|
|
23
|
+
} | Readable;
|
|
24
|
+
metadata?: HubPipelineRequestMetadata;
|
|
25
|
+
}
|
|
26
|
+
type HubPipelineNodeMetadata = HubProcessNodeResult['metadata'] | Record<string, unknown>;
|
|
27
|
+
export interface HubPipelineNodeResult {
|
|
28
|
+
id: string;
|
|
29
|
+
success: boolean;
|
|
30
|
+
metadata: HubPipelineNodeMetadata;
|
|
31
|
+
error?: JsonObject;
|
|
32
|
+
}
|
|
33
|
+
export interface HubPipelineResult {
|
|
34
|
+
requestId: string;
|
|
35
|
+
providerPayload?: Record<string, unknown>;
|
|
36
|
+
standardizedRequest?: StandardizedRequest;
|
|
37
|
+
processedRequest?: ProcessedRequest;
|
|
38
|
+
routingDecision?: RoutingDecision;
|
|
39
|
+
routingDiagnostics?: RoutingDiagnostics;
|
|
40
|
+
target?: TargetMetadata;
|
|
41
|
+
metadata: Record<string, unknown>;
|
|
42
|
+
nodeResults: HubPipelineNodeResult[];
|
|
43
|
+
}
|
|
44
|
+
export declare class HubPipeline {
|
|
45
|
+
private readonly routerEngine;
|
|
46
|
+
private config;
|
|
47
|
+
constructor(config: HubPipelineConfig);
|
|
48
|
+
updateVirtualRouterConfig(nextConfig: VirtualRouterConfig): void;
|
|
49
|
+
private executeRequestStagePipeline;
|
|
50
|
+
execute(request: HubPipelineRequest): Promise<HubPipelineResult>;
|
|
51
|
+
private captureAnthropicAliasMap;
|
|
52
|
+
private shouldCaptureAnthropicAlias;
|
|
53
|
+
private resolveAliasMapFromSources;
|
|
54
|
+
private resolveProtocolHooks;
|
|
55
|
+
private buildAdapterContext;
|
|
56
|
+
private maybeCreateStageRecorder;
|
|
57
|
+
private asJsonObject;
|
|
58
|
+
private normalizeRequest;
|
|
59
|
+
private convertProcessNodeResult;
|
|
60
|
+
private materializePayload;
|
|
61
|
+
private unwrapReadable;
|
|
62
|
+
private convertSsePayload;
|
|
63
|
+
private resolveSseProtocol;
|
|
64
|
+
private extractModelHint;
|
|
65
|
+
}
|
|
66
|
+
export {};
|