@jsonstudio/llms 0.6.1399 → 0.6.1402
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/gemini-openai-codec.d.ts +1 -3
- package/dist/conversion/codecs/gemini-openai-codec.js +4 -10
- package/dist/conversion/compat/actions/gemini-cli-request.d.ts +2 -0
- package/dist/conversion/compat/actions/gemini-cli-request.js +490 -0
- package/dist/conversion/compat/profiles/chat-gemini-cli.json +27 -0
- package/dist/conversion/hub/operation-table/semantic-mappers/gemini-mapper.js +76 -348
- package/dist/conversion/hub/pipeline/compat/compat-pipeline-executor.js +6 -0
- package/dist/conversion/hub/pipeline/compat/compat-types.d.ts +2 -0
- package/dist/conversion/hub/pipeline/hub-pipeline.d.ts +95 -3
- package/dist/conversion/hub/pipeline/hub-pipeline.js +1365 -19
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/index.js +22 -0
- package/dist/conversion/hub/policy/policy-engine.js +50 -3
- package/dist/conversion/hub/process/chat-process.js +5 -146
- package/dist/conversion/hub/response/provider-response.js +11 -10
- package/dist/conversion/hub/response/response-mappers.d.ts +1 -3
- package/dist/conversion/hub/response/response-mappers.js +2 -20
- package/dist/conversion/hub/tool-surface/tool-surface-engine.js +2 -1
- package/dist/conversion/responses/responses-openai-bridge.js +4 -3
- package/dist/conversion/shared/gemini-tool-utils.d.ts +1 -6
- package/dist/conversion/shared/gemini-tool-utils.js +164 -542
- package/dist/conversion/shared/mcp-injection.js +29 -0
- package/dist/conversion/shared/openai-message-normalize.js +3 -17
- package/dist/filters/special/request-tool-list-filter.js +21 -13
- package/dist/filters/special/tool-filter-hooks.js +60 -3
- package/dist/router/virtual-router/bootstrap.js +8 -6
- package/dist/router/virtual-router/engine-health.d.ts +1 -1
- package/dist/router/virtual-router/engine-health.js +110 -11
- package/dist/router/virtual-router/engine-selection/alias-selection.d.ts +0 -15
- package/dist/router/virtual-router/engine-selection/alias-selection.js +4 -85
- package/dist/router/virtual-router/engine-selection/route-utils.js +6 -12
- package/dist/router/virtual-router/engine-selection/tier-selection-select.js +17 -40
- package/dist/router/virtual-router/engine-selection/tier-selection.js +2 -5
- package/dist/router/virtual-router/engine.js +6 -21
- package/dist/router/virtual-router/types.d.ts +1 -14
- package/dist/servertool/clock/config.d.ts +1 -1
- package/dist/servertool/clock/config.js +5 -9
- package/dist/servertool/engine.js +11 -88
- package/dist/servertool/handlers/gemini-empty-reply-continue.js +1 -2
- package/dist/sse/sse-to-json/builders/response-builder.js +0 -16
- package/package.json +1 -1
- package/dist/conversion/hub/pipeline/hub-pipeline/adapter-context.d.ts +0 -10
- package/dist/conversion/hub/pipeline/hub-pipeline/adapter-context.js +0 -142
- package/dist/conversion/hub/pipeline/hub-pipeline/anthropic-alias-map.d.ts +0 -6
- package/dist/conversion/hub/pipeline/hub-pipeline/anthropic-alias-map.js +0 -79
- package/dist/conversion/hub/pipeline/hub-pipeline/apply-patch-tool-mode.d.ts +0 -3
- package/dist/conversion/hub/pipeline/hub-pipeline/apply-patch-tool-mode.js +0 -46
- package/dist/conversion/hub/pipeline/hub-pipeline/execute-chat-process-entry.d.ts +0 -8
- package/dist/conversion/hub/pipeline/hub-pipeline/execute-chat-process-entry.js +0 -366
- package/dist/conversion/hub/pipeline/hub-pipeline/execute-request-stage.d.ts +0 -9
- package/dist/conversion/hub/pipeline/hub-pipeline/execute-request-stage.js +0 -390
- package/dist/conversion/hub/pipeline/hub-pipeline/node-results.d.ts +0 -3
- package/dist/conversion/hub/pipeline/hub-pipeline/node-results.js +0 -14
- package/dist/conversion/hub/pipeline/hub-pipeline/payload-normalize.d.ts +0 -2
- package/dist/conversion/hub/pipeline/hub-pipeline/payload-normalize.js +0 -144
- package/dist/conversion/hub/pipeline/hub-pipeline/policy.d.ts +0 -4
- package/dist/conversion/hub/pipeline/hub-pipeline/policy.js +0 -32
- package/dist/conversion/hub/pipeline/hub-pipeline/protocol.d.ts +0 -8
- package/dist/conversion/hub/pipeline/hub-pipeline/protocol.js +0 -63
- package/dist/conversion/hub/pipeline/hub-pipeline/resolve-protocol-hooks.d.ts +0 -2
- package/dist/conversion/hub/pipeline/hub-pipeline/resolve-protocol-hooks.js +0 -43
- package/dist/conversion/hub/pipeline/hub-pipeline/semantic-gate.d.ts +0 -1
- package/dist/conversion/hub/pipeline/hub-pipeline/semantic-gate.js +0 -29
- package/dist/conversion/hub/pipeline/hub-pipeline/servertool-runtime-config.d.ts +0 -2
- package/dist/conversion/hub/pipeline/hub-pipeline/servertool-runtime-config.js +0 -16
- package/dist/conversion/hub/pipeline/hub-pipeline/types.d.ts +0 -116
- package/dist/conversion/hub/pipeline/hub-pipeline/types.js +0 -1
- package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage2_thought_signature_inject/index.d.ts +0 -10
- package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage2_thought_signature_inject/index.js +0 -172
- package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage3_thought_signature_capture/index.d.ts +0 -10
- package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage3_thought_signature_capture/index.js +0 -71
- package/dist/conversion/hub/pipeline/thought-signature/thought-signature-center.d.ts +0 -14
- package/dist/conversion/hub/pipeline/thought-signature/thought-signature-center.js +0 -289
|
@@ -1,390 +0,0 @@
|
|
|
1
|
-
import { jsonClone } from '../../types/json.js';
|
|
2
|
-
import { ensureRuntimeMetadata, readRuntimeMetadata } from '../../../shared/runtime-metadata.js';
|
|
3
|
-
import { computeRequestTokens } from '../../../../router/virtual-router/token-estimator.js';
|
|
4
|
-
import { isCompactionRequest } from '../../../shared/compaction-detect.js';
|
|
5
|
-
import { recordHubPolicyObservation, applyHubProviderOutboundPolicy } from '../../policy/policy-engine.js';
|
|
6
|
-
import { applyProviderOutboundToolSurface } from '../../tool-surface/tool-surface-engine.js';
|
|
7
|
-
import { runReqInboundStage1FormatParse } from '../stages/req_inbound/req_inbound_stage1_format_parse/index.js';
|
|
8
|
-
import { runReqInboundStage2SemanticMap } from '../stages/req_inbound/req_inbound_stage2_semantic_map/index.js';
|
|
9
|
-
import { runReqProcessStage1ToolGovernance } from '../stages/req_process/req_process_stage1_tool_governance/index.js';
|
|
10
|
-
import { runReqProcessStage2RouteSelect } from '../stages/req_process/req_process_stage2_route_select/index.js';
|
|
11
|
-
import { runReqOutboundStage1SemanticMap } from '../stages/req_outbound/req_outbound_stage1_semantic_map/index.js';
|
|
12
|
-
import { runReqOutboundStage2FormatBuild } from '../stages/req_outbound/req_outbound_stage2_format_build/index.js';
|
|
13
|
-
import { runReqOutboundStage2ThoughtSignatureInject } from '../stages/req_outbound/req_outbound_stage2_thought_signature_inject/index.js';
|
|
14
|
-
import { runReqOutboundStage3Compat } from '../stages/req_outbound/req_outbound_stage3_compat/index.js';
|
|
15
|
-
import { extractSessionIdentifiersFromMetadata } from '../session-identifiers.js';
|
|
16
|
-
import { buildAdapterContext, maybeCreateStageRecorder, resolveOutboundStreamIntent, applyOutboundStreamPreference } from './adapter-context.js';
|
|
17
|
-
import { resolveClientProtocolFromEntryEndpoint } from './protocol.js';
|
|
18
|
-
import { assertNoMappableSemanticsInMetadata } from './semantic-gate.js';
|
|
19
|
-
import { convertProcessNodeResult } from './node-results.js';
|
|
20
|
-
import { resolveApplyPatchToolModeFromEnv, resolveApplyPatchToolModeFromTools } from './apply-patch-tool-mode.js';
|
|
21
|
-
import { injectServerToolRuntimeConfig } from './servertool-runtime-config.js';
|
|
22
|
-
function asJsonObject(value) {
|
|
23
|
-
if (!value || typeof value !== 'object') {
|
|
24
|
-
throw new Error('Responses pipeline requires JSON object payload');
|
|
25
|
-
}
|
|
26
|
-
return value;
|
|
27
|
-
}
|
|
28
|
-
function readResponsesResumeFromSemantics(request) {
|
|
29
|
-
try {
|
|
30
|
-
const semantics = request?.semantics;
|
|
31
|
-
const node = semantics && typeof semantics === 'object' && !Array.isArray(semantics) ? semantics.responses : undefined;
|
|
32
|
-
const resume = node && typeof node === 'object' && !Array.isArray(node) ? node.resume : undefined;
|
|
33
|
-
return resume && typeof resume === 'object' && !Array.isArray(resume) ? resume : undefined;
|
|
34
|
-
}
|
|
35
|
-
catch {
|
|
36
|
-
return undefined;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
export async function executeRequestStagePipeline(options) {
|
|
40
|
-
const { config, routerEngine, normalized, hooks } = options;
|
|
41
|
-
const formatAdapter = hooks.createFormatAdapter();
|
|
42
|
-
const semanticMapper = hooks.createSemanticMapper();
|
|
43
|
-
const rawRequest = asJsonObject(normalized.payload);
|
|
44
|
-
// Detect applyPatchToolMode (runtime/tooling hint). Client tool schemas are captured as chat semantics
|
|
45
|
-
// in req_inbound_stage2_semantic_map; they must not be stored in metadata.
|
|
46
|
-
try {
|
|
47
|
-
const toolsRaw = Array.isArray(rawRequest?.tools) ? rawRequest.tools : null;
|
|
48
|
-
const applyPatchToolMode = resolveApplyPatchToolModeFromEnv() ?? resolveApplyPatchToolModeFromTools(toolsRaw);
|
|
49
|
-
if (applyPatchToolMode) {
|
|
50
|
-
normalized.metadata = normalized.metadata || {};
|
|
51
|
-
const rt = ensureRuntimeMetadata(normalized.metadata);
|
|
52
|
-
rt.applyPatchToolMode = applyPatchToolMode;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
catch {
|
|
56
|
-
// best-effort: do not block request handling due to tool scan failures
|
|
57
|
-
}
|
|
58
|
-
if (isCompactionRequest(rawRequest)) {
|
|
59
|
-
normalized.metadata = normalized.metadata || {};
|
|
60
|
-
const rt = ensureRuntimeMetadata(normalized.metadata);
|
|
61
|
-
rt.compactionRequest = true;
|
|
62
|
-
}
|
|
63
|
-
const effectivePolicy = normalized.policyOverride ?? config.policy;
|
|
64
|
-
const shadowCompareBaselineMode = normalized.shadowCompare?.baselineMode;
|
|
65
|
-
const inboundAdapterContext = buildAdapterContext(normalized);
|
|
66
|
-
const inboundRecorder = maybeCreateStageRecorder(inboundAdapterContext, normalized.entryEndpoint, {
|
|
67
|
-
disableSnapshots: normalized.disableSnapshots === true
|
|
68
|
-
});
|
|
69
|
-
const inboundStart = Date.now();
|
|
70
|
-
recordHubPolicyObservation({
|
|
71
|
-
policy: effectivePolicy,
|
|
72
|
-
providerProtocol: resolveClientProtocolFromEntryEndpoint(normalized.entryEndpoint),
|
|
73
|
-
payload: rawRequest,
|
|
74
|
-
phase: 'client_inbound',
|
|
75
|
-
stageRecorder: inboundRecorder,
|
|
76
|
-
requestId: normalized.id
|
|
77
|
-
});
|
|
78
|
-
const formatEnvelope = await runReqInboundStage1FormatParse({
|
|
79
|
-
rawRequest,
|
|
80
|
-
adapterContext: inboundAdapterContext,
|
|
81
|
-
formatAdapter,
|
|
82
|
-
stageRecorder: inboundRecorder
|
|
83
|
-
});
|
|
84
|
-
const responsesResumeFromMetadata = normalized.metadata && typeof normalized.metadata.responsesResume === 'object'
|
|
85
|
-
? normalized.metadata.responsesResume
|
|
86
|
-
: undefined;
|
|
87
|
-
const inboundStage2 = await runReqInboundStage2SemanticMap({
|
|
88
|
-
adapterContext: inboundAdapterContext,
|
|
89
|
-
formatEnvelope,
|
|
90
|
-
semanticMapper,
|
|
91
|
-
...(responsesResumeFromMetadata ? { responsesResume: responsesResumeFromMetadata } : {}),
|
|
92
|
-
stageRecorder: inboundRecorder
|
|
93
|
-
});
|
|
94
|
-
if (responsesResumeFromMetadata &&
|
|
95
|
-
normalized.metadata &&
|
|
96
|
-
Object.prototype.hasOwnProperty.call(normalized.metadata, 'responsesResume')) {
|
|
97
|
-
delete normalized.metadata.responsesResume;
|
|
98
|
-
}
|
|
99
|
-
const contextSnapshot = await hooks.captureContext({
|
|
100
|
-
rawRequest,
|
|
101
|
-
adapterContext: inboundAdapterContext,
|
|
102
|
-
stageRecorder: inboundRecorder
|
|
103
|
-
});
|
|
104
|
-
const standardizedRequest = inboundStage2.standardizedRequest;
|
|
105
|
-
try {
|
|
106
|
-
const rt = readRuntimeMetadata(normalized.metadata);
|
|
107
|
-
const mode = String(rt?.applyPatchToolMode || '').trim().toLowerCase();
|
|
108
|
-
if (mode === 'freeform' || mode === 'schema') {
|
|
109
|
-
standardizedRequest.metadata.applyPatchToolMode = mode;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
catch {
|
|
113
|
-
// best-effort: do not block request handling due to metadata propagation failures
|
|
114
|
-
}
|
|
115
|
-
const inboundEnd = Date.now();
|
|
116
|
-
const nodeResults = [];
|
|
117
|
-
nodeResults.push({
|
|
118
|
-
id: 'req_inbound',
|
|
119
|
-
success: true,
|
|
120
|
-
metadata: {
|
|
121
|
-
node: 'req_inbound',
|
|
122
|
-
executionTime: inboundEnd - inboundStart,
|
|
123
|
-
startTime: inboundStart,
|
|
124
|
-
endTime: inboundEnd,
|
|
125
|
-
dataProcessed: {
|
|
126
|
-
messages: standardizedRequest.messages.length,
|
|
127
|
-
tools: standardizedRequest.tools?.length ?? 0
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
const metaBase = {
|
|
132
|
-
...(normalized.metadata ?? {})
|
|
133
|
-
};
|
|
134
|
-
injectServerToolRuntimeConfig(config, metaBase);
|
|
135
|
-
normalized.metadata = metaBase;
|
|
136
|
-
let processedRequest;
|
|
137
|
-
if (normalized.processMode !== 'passthrough') {
|
|
138
|
-
assertNoMappableSemanticsInMetadata(metaBase, 'chat_process.request.entry');
|
|
139
|
-
const processResult = await runReqProcessStage1ToolGovernance({
|
|
140
|
-
request: standardizedRequest,
|
|
141
|
-
rawPayload: rawRequest,
|
|
142
|
-
metadata: metaBase,
|
|
143
|
-
entryEndpoint: normalized.entryEndpoint,
|
|
144
|
-
requestId: normalized.id,
|
|
145
|
-
stageRecorder: inboundRecorder
|
|
146
|
-
});
|
|
147
|
-
processedRequest = processResult.processedRequest;
|
|
148
|
-
try {
|
|
149
|
-
const reservation = processedRequest?.metadata?.__clockReservation;
|
|
150
|
-
if (reservation && typeof reservation === 'object') {
|
|
151
|
-
metaBase.__clockReservation = reservation;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
catch {
|
|
155
|
-
// best-effort: do not block request handling due to metadata propagation failures
|
|
156
|
-
}
|
|
157
|
-
if (processResult.nodeResult) {
|
|
158
|
-
nodeResults.push(convertProcessNodeResult('chat_process.req.stage4.tool_governance', processResult.nodeResult));
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
let workingRequest = processedRequest ?? standardizedRequest;
|
|
162
|
-
try {
|
|
163
|
-
const estimatedTokens = computeRequestTokens(workingRequest, '');
|
|
164
|
-
if (typeof estimatedTokens === 'number' && Number.isFinite(estimatedTokens) && estimatedTokens > 0) {
|
|
165
|
-
normalized.metadata = normalized.metadata || {};
|
|
166
|
-
normalized.metadata.estimatedInputTokens = estimatedTokens;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
catch {
|
|
170
|
-
// ignore
|
|
171
|
-
}
|
|
172
|
-
const normalizedMeta = normalized.metadata;
|
|
173
|
-
const responsesResume = readResponsesResumeFromSemantics(workingRequest);
|
|
174
|
-
const stdMetadata = workingRequest?.metadata;
|
|
175
|
-
const hasImageAttachment = (stdMetadata?.hasImageAttachment === true || stdMetadata?.hasImageAttachment === 'true') ||
|
|
176
|
-
(normalizedMeta?.hasImageAttachment === true || normalizedMeta?.hasImageAttachment === 'true');
|
|
177
|
-
const serverToolRequired = stdMetadata?.webSearchEnabled === true || stdMetadata?.serverToolRequired === true;
|
|
178
|
-
const sessionIdentifiers = extractSessionIdentifiersFromMetadata(normalized.metadata);
|
|
179
|
-
if (sessionIdentifiers.sessionId && normalized.metadata && typeof normalized.metadata === 'object') {
|
|
180
|
-
normalized.metadata.sessionId = sessionIdentifiers.sessionId;
|
|
181
|
-
}
|
|
182
|
-
if (sessionIdentifiers.conversationId && normalized.metadata && typeof normalized.metadata === 'object') {
|
|
183
|
-
normalized.metadata.conversationId = sessionIdentifiers.conversationId;
|
|
184
|
-
}
|
|
185
|
-
const disableStickyRoutes = readRuntimeMetadata(normalized.metadata)?.disableStickyRoutes === true;
|
|
186
|
-
const shadowCompareForcedProviderKey = normalizedMeta && typeof normalizedMeta.__shadowCompareForcedProviderKey === 'string'
|
|
187
|
-
? String(normalizedMeta.__shadowCompareForcedProviderKey)
|
|
188
|
-
: '';
|
|
189
|
-
const disabledProviderKeyAliases = normalizedMeta && Array.isArray(normalizedMeta.disabledProviderKeyAliases)
|
|
190
|
-
? normalizedMeta.disabledProviderKeyAliases
|
|
191
|
-
: null;
|
|
192
|
-
const metadataInput = {
|
|
193
|
-
requestId: normalized.id,
|
|
194
|
-
entryEndpoint: normalized.entryEndpoint,
|
|
195
|
-
processMode: normalized.processMode,
|
|
196
|
-
stream: normalized.stream,
|
|
197
|
-
direction: normalized.direction,
|
|
198
|
-
providerProtocol: normalized.providerProtocol,
|
|
199
|
-
routeHint: normalized.routeHint,
|
|
200
|
-
stage: normalized.stage,
|
|
201
|
-
responsesResume: responsesResume,
|
|
202
|
-
...(disableStickyRoutes ? { disableStickyRoutes: true } : {}),
|
|
203
|
-
...(serverToolRequired ? { serverToolRequired: true } : {}),
|
|
204
|
-
...(sessionIdentifiers.sessionId ? { sessionId: sessionIdentifiers.sessionId } : {}),
|
|
205
|
-
...(sessionIdentifiers.conversationId ? { conversationId: sessionIdentifiers.conversationId } : {}),
|
|
206
|
-
...(shadowCompareForcedProviderKey.trim().length
|
|
207
|
-
? { __shadowCompareForcedProviderKey: shadowCompareForcedProviderKey.trim() }
|
|
208
|
-
: {}),
|
|
209
|
-
...(disabledProviderKeyAliases && disabledProviderKeyAliases.length
|
|
210
|
-
? { disabledProviderKeyAliases: disabledProviderKeyAliases }
|
|
211
|
-
: {})
|
|
212
|
-
};
|
|
213
|
-
const routing = runReqProcessStage2RouteSelect({
|
|
214
|
-
routerEngine,
|
|
215
|
-
request: workingRequest,
|
|
216
|
-
metadataInput,
|
|
217
|
-
normalizedMetadata: normalized.metadata,
|
|
218
|
-
stageRecorder: inboundRecorder
|
|
219
|
-
});
|
|
220
|
-
const stopMessageState = routerEngine.getStopMessageState(metadataInput);
|
|
221
|
-
if (stopMessageState && normalized.metadata && typeof normalized.metadata === 'object') {
|
|
222
|
-
const rt = ensureRuntimeMetadata(normalized.metadata);
|
|
223
|
-
rt.stopMessageState = stopMessageState;
|
|
224
|
-
}
|
|
225
|
-
try {
|
|
226
|
-
const routeName = routing.decision?.routeName;
|
|
227
|
-
const providerKey = routing.target?.providerKey;
|
|
228
|
-
const modelId = workingRequest.model;
|
|
229
|
-
const logger = (normalized.metadata && normalized.metadata.logger);
|
|
230
|
-
if (logger && typeof logger.logVirtualRouterHit === 'function' && routeName && providerKey) {
|
|
231
|
-
logger.logVirtualRouterHit(routeName, providerKey, typeof modelId === 'string' ? modelId : undefined);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
catch {
|
|
235
|
-
// ignore
|
|
236
|
-
}
|
|
237
|
-
const outboundStream = resolveOutboundStreamIntent(routing.target?.streaming);
|
|
238
|
-
workingRequest = applyOutboundStreamPreference(workingRequest, outboundStream);
|
|
239
|
-
const outboundAdapterContext = buildAdapterContext(normalized, routing.target);
|
|
240
|
-
if (routing.target?.compatibilityProfile) {
|
|
241
|
-
outboundAdapterContext.compatibilityProfile = routing.target.compatibilityProfile;
|
|
242
|
-
}
|
|
243
|
-
const outboundProtocol = outboundAdapterContext.providerProtocol;
|
|
244
|
-
const protocolSwitch = outboundProtocol !== normalized.providerProtocol;
|
|
245
|
-
const outboundHooks = protocolSwitch ? options.resolveProtocolHooks(outboundProtocol) : hooks;
|
|
246
|
-
if (!outboundHooks) {
|
|
247
|
-
throw new Error(`[HubPipeline] Unsupported provider protocol for hub pipeline: ${outboundProtocol}`);
|
|
248
|
-
}
|
|
249
|
-
const outboundSemanticMapper = protocolSwitch ? outboundHooks.createSemanticMapper() : semanticMapper;
|
|
250
|
-
const outboundFormatAdapter = protocolSwitch ? outboundHooks.createFormatAdapter() : formatAdapter;
|
|
251
|
-
const outboundContextMetadataKey = protocolSwitch ? outboundHooks.contextMetadataKey : hooks.contextMetadataKey;
|
|
252
|
-
const outboundContextSnapshot = protocolSwitch ? undefined : contextSnapshot;
|
|
253
|
-
const outboundRecorder = maybeCreateStageRecorder(outboundAdapterContext, normalized.entryEndpoint, {
|
|
254
|
-
disableSnapshots: normalized.disableSnapshots === true
|
|
255
|
-
});
|
|
256
|
-
const outboundStart = Date.now();
|
|
257
|
-
const outboundStage1 = await runReqOutboundStage1SemanticMap({
|
|
258
|
-
request: workingRequest,
|
|
259
|
-
adapterContext: outboundAdapterContext,
|
|
260
|
-
semanticMapper: outboundSemanticMapper,
|
|
261
|
-
contextSnapshot: outboundContextSnapshot,
|
|
262
|
-
contextMetadataKey: outboundContextMetadataKey,
|
|
263
|
-
stageRecorder: outboundRecorder
|
|
264
|
-
});
|
|
265
|
-
let formattedPayload = await runReqOutboundStage2FormatBuild({
|
|
266
|
-
formatEnvelope: outboundStage1.formatEnvelope,
|
|
267
|
-
adapterContext: outboundAdapterContext,
|
|
268
|
-
formatAdapter: outboundFormatAdapter,
|
|
269
|
-
stageRecorder: outboundRecorder
|
|
270
|
-
});
|
|
271
|
-
formattedPayload = await runReqOutboundStage2ThoughtSignatureInject({
|
|
272
|
-
payload: formattedPayload,
|
|
273
|
-
adapterContext: outboundAdapterContext,
|
|
274
|
-
stageRecorder: outboundRecorder
|
|
275
|
-
});
|
|
276
|
-
formattedPayload = await runReqOutboundStage3Compat({
|
|
277
|
-
payload: formattedPayload,
|
|
278
|
-
adapterContext: outboundAdapterContext,
|
|
279
|
-
stageRecorder: outboundRecorder
|
|
280
|
-
});
|
|
281
|
-
let shadowBaselineProviderPayload;
|
|
282
|
-
if (shadowCompareBaselineMode) {
|
|
283
|
-
const baselinePolicy = {
|
|
284
|
-
...(effectivePolicy ?? {}),
|
|
285
|
-
mode: shadowCompareBaselineMode
|
|
286
|
-
};
|
|
287
|
-
const baselineFormatted = typeof globalThis.structuredClone === 'function'
|
|
288
|
-
? globalThis.structuredClone(formattedPayload)
|
|
289
|
-
: jsonClone(formattedPayload);
|
|
290
|
-
let baselinePayload = applyHubProviderOutboundPolicy({
|
|
291
|
-
policy: baselinePolicy,
|
|
292
|
-
providerProtocol: outboundProtocol,
|
|
293
|
-
payload: baselineFormatted,
|
|
294
|
-
stageRecorder: undefined,
|
|
295
|
-
requestId: normalized.id
|
|
296
|
-
});
|
|
297
|
-
baselinePayload = applyProviderOutboundToolSurface({
|
|
298
|
-
config: config.toolSurface,
|
|
299
|
-
providerProtocol: outboundProtocol,
|
|
300
|
-
payload: baselinePayload,
|
|
301
|
-
stageRecorder: undefined,
|
|
302
|
-
requestId: normalized.id
|
|
303
|
-
});
|
|
304
|
-
shadowBaselineProviderPayload = baselinePayload;
|
|
305
|
-
}
|
|
306
|
-
recordHubPolicyObservation({
|
|
307
|
-
policy: effectivePolicy,
|
|
308
|
-
providerProtocol: outboundProtocol,
|
|
309
|
-
payload: formattedPayload,
|
|
310
|
-
stageRecorder: outboundRecorder,
|
|
311
|
-
requestId: normalized.id
|
|
312
|
-
});
|
|
313
|
-
let providerPayload = applyHubProviderOutboundPolicy({
|
|
314
|
-
policy: effectivePolicy,
|
|
315
|
-
providerProtocol: outboundProtocol,
|
|
316
|
-
payload: formattedPayload,
|
|
317
|
-
stageRecorder: outboundRecorder,
|
|
318
|
-
requestId: normalized.id
|
|
319
|
-
});
|
|
320
|
-
providerPayload = applyProviderOutboundToolSurface({
|
|
321
|
-
config: config.toolSurface,
|
|
322
|
-
providerProtocol: outboundProtocol,
|
|
323
|
-
payload: providerPayload,
|
|
324
|
-
stageRecorder: outboundRecorder,
|
|
325
|
-
requestId: normalized.id
|
|
326
|
-
});
|
|
327
|
-
recordHubPolicyObservation({
|
|
328
|
-
policy: effectivePolicy,
|
|
329
|
-
providerProtocol: outboundProtocol,
|
|
330
|
-
payload: providerPayload,
|
|
331
|
-
stageRecorder: outboundRecorder,
|
|
332
|
-
requestId: normalized.id
|
|
333
|
-
});
|
|
334
|
-
const outboundEnd = Date.now();
|
|
335
|
-
nodeResults.push({
|
|
336
|
-
id: 'req_outbound',
|
|
337
|
-
success: true,
|
|
338
|
-
metadata: {
|
|
339
|
-
node: 'req_outbound',
|
|
340
|
-
executionTime: outboundEnd - outboundStart,
|
|
341
|
-
startTime: outboundStart,
|
|
342
|
-
endTime: outboundEnd,
|
|
343
|
-
dataProcessed: {
|
|
344
|
-
messages: workingRequest.messages.length,
|
|
345
|
-
tools: workingRequest.tools?.length ?? 0
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
});
|
|
349
|
-
const capturedChatRequest = {
|
|
350
|
-
model: workingRequest.model,
|
|
351
|
-
messages: jsonClone(workingRequest.messages),
|
|
352
|
-
tools: workingRequest.tools ? jsonClone(workingRequest.tools) : workingRequest.tools,
|
|
353
|
-
parameters: workingRequest.parameters
|
|
354
|
-
? jsonClone(workingRequest.parameters)
|
|
355
|
-
: workingRequest.parameters
|
|
356
|
-
};
|
|
357
|
-
const metadata = {
|
|
358
|
-
...normalized.metadata,
|
|
359
|
-
...(hasImageAttachment ? { hasImageAttachment: true } : {}),
|
|
360
|
-
capturedChatRequest,
|
|
361
|
-
entryEndpoint: normalized.entryEndpoint,
|
|
362
|
-
providerProtocol: outboundProtocol,
|
|
363
|
-
stream: normalized.stream,
|
|
364
|
-
processMode: normalized.processMode,
|
|
365
|
-
routeHint: normalized.routeHint,
|
|
366
|
-
target: routing.target,
|
|
367
|
-
...(typeof outboundStream === 'boolean' ? { providerStream: outboundStream } : {}),
|
|
368
|
-
...(shadowBaselineProviderPayload
|
|
369
|
-
? {
|
|
370
|
-
hubShadowCompare: {
|
|
371
|
-
baselineMode: shadowCompareBaselineMode,
|
|
372
|
-
candidateMode: (effectivePolicy?.mode ?? 'off'),
|
|
373
|
-
providerProtocol: outboundProtocol,
|
|
374
|
-
baselineProviderPayload: shadowBaselineProviderPayload
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
: {})
|
|
378
|
-
};
|
|
379
|
-
return {
|
|
380
|
-
requestId: normalized.id,
|
|
381
|
-
providerPayload,
|
|
382
|
-
standardizedRequest,
|
|
383
|
-
processedRequest,
|
|
384
|
-
routingDecision: routing.decision,
|
|
385
|
-
routingDiagnostics: routing.diagnostics,
|
|
386
|
-
target: routing.target,
|
|
387
|
-
metadata,
|
|
388
|
-
nodeResults
|
|
389
|
-
};
|
|
390
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export function convertProcessNodeResult(id, result) {
|
|
2
|
-
return {
|
|
3
|
-
id,
|
|
4
|
-
success: result.success,
|
|
5
|
-
metadata: result.metadata,
|
|
6
|
-
error: result.error
|
|
7
|
-
? {
|
|
8
|
-
code: result.error.code ?? 'hub_chat_process_error',
|
|
9
|
-
message: result.error.message,
|
|
10
|
-
details: result.error.details
|
|
11
|
-
}
|
|
12
|
-
: undefined
|
|
13
|
-
};
|
|
14
|
-
}
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import { Readable } from 'node:stream';
|
|
2
|
-
import { defaultSseCodecRegistry } from '../../../../sse/index.js';
|
|
3
|
-
import { extractHubPolicyOverride, extractHubShadowCompareConfig } from './policy.js';
|
|
4
|
-
import { normalizeEndpoint, resolveProviderProtocol, resolveSseProtocolFromMetadata } from './protocol.js';
|
|
5
|
-
function unwrapReadable(payload) {
|
|
6
|
-
if (!payload) {
|
|
7
|
-
return null;
|
|
8
|
-
}
|
|
9
|
-
if (payload instanceof Readable) {
|
|
10
|
-
return payload;
|
|
11
|
-
}
|
|
12
|
-
if (payload && typeof payload === 'object' && 'readable' in payload) {
|
|
13
|
-
const candidate = payload.readable;
|
|
14
|
-
if (candidate instanceof Readable) {
|
|
15
|
-
return candidate;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
return null;
|
|
19
|
-
}
|
|
20
|
-
function resolveSseProtocol(context) {
|
|
21
|
-
const explicitProtocol = resolveSseProtocolFromMetadata(context.metadata);
|
|
22
|
-
if (explicitProtocol) {
|
|
23
|
-
return explicitProtocol;
|
|
24
|
-
}
|
|
25
|
-
return context.providerProtocol;
|
|
26
|
-
}
|
|
27
|
-
function extractModelHint(metadata) {
|
|
28
|
-
if (typeof metadata.model === 'string' && metadata.model.trim()) {
|
|
29
|
-
return metadata.model;
|
|
30
|
-
}
|
|
31
|
-
const provider = metadata.provider;
|
|
32
|
-
const candidates = [provider?.model, provider?.modelId, provider?.defaultModel];
|
|
33
|
-
for (const candidate of candidates) {
|
|
34
|
-
if (typeof candidate === 'string' && candidate.trim()) {
|
|
35
|
-
return candidate;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return undefined;
|
|
39
|
-
}
|
|
40
|
-
async function convertSsePayload(stream, context) {
|
|
41
|
-
const protocol = resolveSseProtocol(context);
|
|
42
|
-
const codec = defaultSseCodecRegistry.get(protocol);
|
|
43
|
-
try {
|
|
44
|
-
const result = await codec.convertSseToJson(stream, {
|
|
45
|
-
requestId: context.requestId,
|
|
46
|
-
model: extractModelHint(context.metadata),
|
|
47
|
-
direction: 'request'
|
|
48
|
-
});
|
|
49
|
-
if (!result || typeof result !== 'object') {
|
|
50
|
-
throw new Error('SSE conversion returned empty payload');
|
|
51
|
-
}
|
|
52
|
-
return result;
|
|
53
|
-
}
|
|
54
|
-
catch (error) {
|
|
55
|
-
const message = error instanceof Error ? error.message : String(error ?? 'Unknown error');
|
|
56
|
-
throw new Error(`Failed to convert SSE payload for protocol ${protocol}: ${message}`);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
async function materializePayload(payload, context, resolvedStream) {
|
|
60
|
-
const stream = resolvedStream ?? unwrapReadable(payload);
|
|
61
|
-
if (stream) {
|
|
62
|
-
return await convertSsePayload(stream, context);
|
|
63
|
-
}
|
|
64
|
-
if (!payload || typeof payload !== 'object') {
|
|
65
|
-
throw new Error('HubPipeline requires JSON object payload');
|
|
66
|
-
}
|
|
67
|
-
return payload;
|
|
68
|
-
}
|
|
69
|
-
export async function normalizeHubPipelineRequest(request) {
|
|
70
|
-
if (!request || typeof request !== 'object') {
|
|
71
|
-
throw new Error('HubPipeline requires request payload');
|
|
72
|
-
}
|
|
73
|
-
const id = request.id || `req_${Date.now()}`;
|
|
74
|
-
const endpoint = normalizeEndpoint(request.endpoint);
|
|
75
|
-
const metadataRecord = {
|
|
76
|
-
...(request.metadata ?? {})
|
|
77
|
-
};
|
|
78
|
-
const policyOverride = extractHubPolicyOverride(metadataRecord);
|
|
79
|
-
if (Object.prototype.hasOwnProperty.call(metadataRecord, '__hubPolicyOverride')) {
|
|
80
|
-
delete metadataRecord.__hubPolicyOverride;
|
|
81
|
-
}
|
|
82
|
-
const shadowCompare = extractHubShadowCompareConfig(metadataRecord);
|
|
83
|
-
if (Object.prototype.hasOwnProperty.call(metadataRecord, '__hubShadowCompare')) {
|
|
84
|
-
delete metadataRecord.__hubShadowCompare;
|
|
85
|
-
}
|
|
86
|
-
const disableSnapshots = metadataRecord.__disableHubSnapshots === true;
|
|
87
|
-
if (Object.prototype.hasOwnProperty.call(metadataRecord, '__disableHubSnapshots')) {
|
|
88
|
-
delete metadataRecord.__disableHubSnapshots;
|
|
89
|
-
}
|
|
90
|
-
const hubEntryRaw = typeof metadataRecord.__hubEntry === 'string'
|
|
91
|
-
? String(metadataRecord.__hubEntry).trim().toLowerCase()
|
|
92
|
-
: '';
|
|
93
|
-
const hubEntryMode = hubEntryRaw === 'chat_process' || hubEntryRaw === 'chat-process' || hubEntryRaw === 'chatprocess'
|
|
94
|
-
? 'chat_process'
|
|
95
|
-
: undefined;
|
|
96
|
-
if (Object.prototype.hasOwnProperty.call(metadataRecord, '__hubEntry')) {
|
|
97
|
-
delete metadataRecord.__hubEntry;
|
|
98
|
-
}
|
|
99
|
-
const entryEndpoint = typeof metadataRecord.entryEndpoint === 'string' ? normalizeEndpoint(metadataRecord.entryEndpoint) : endpoint;
|
|
100
|
-
const providerProtocol = resolveProviderProtocol(metadataRecord.providerProtocol);
|
|
101
|
-
const processMode = metadataRecord.processMode === 'passthrough' ? 'passthrough' : 'chat';
|
|
102
|
-
const direction = metadataRecord.direction === 'response' ? 'response' : 'request';
|
|
103
|
-
const stage = metadataRecord.stage === 'outbound' ? 'outbound' : 'inbound';
|
|
104
|
-
const resolvedReadable = unwrapReadable(request.payload);
|
|
105
|
-
const stream = Boolean(metadataRecord.stream ||
|
|
106
|
-
resolvedReadable ||
|
|
107
|
-
(request.payload && typeof request.payload === 'object' && request.payload.stream));
|
|
108
|
-
const payload = await materializePayload(request.payload, {
|
|
109
|
-
requestId: id,
|
|
110
|
-
entryEndpoint,
|
|
111
|
-
providerProtocol,
|
|
112
|
-
metadata: metadataRecord
|
|
113
|
-
}, resolvedReadable);
|
|
114
|
-
const normalizedMetadata = {
|
|
115
|
-
...metadataRecord,
|
|
116
|
-
entryEndpoint,
|
|
117
|
-
providerProtocol,
|
|
118
|
-
processMode,
|
|
119
|
-
direction,
|
|
120
|
-
stage,
|
|
121
|
-
stream
|
|
122
|
-
};
|
|
123
|
-
const routeHint = typeof metadataRecord.routeHint === 'string' ? metadataRecord.routeHint : undefined;
|
|
124
|
-
if (routeHint) {
|
|
125
|
-
normalizedMetadata.routeHint = routeHint;
|
|
126
|
-
}
|
|
127
|
-
return {
|
|
128
|
-
id,
|
|
129
|
-
endpoint,
|
|
130
|
-
entryEndpoint,
|
|
131
|
-
providerProtocol,
|
|
132
|
-
payload,
|
|
133
|
-
metadata: normalizedMetadata,
|
|
134
|
-
policyOverride: policyOverride ?? undefined,
|
|
135
|
-
shadowCompare: shadowCompare ?? undefined,
|
|
136
|
-
disableSnapshots,
|
|
137
|
-
processMode,
|
|
138
|
-
direction,
|
|
139
|
-
stage,
|
|
140
|
-
stream,
|
|
141
|
-
routeHint,
|
|
142
|
-
...(hubEntryMode ? { hubEntryMode } : {})
|
|
143
|
-
};
|
|
144
|
-
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { HubPolicyConfig } from '../../policy/policy-engine.js';
|
|
2
|
-
import type { HubShadowCompareRequestConfig } from './types.js';
|
|
3
|
-
export declare function extractHubPolicyOverride(metadata: Record<string, unknown> | undefined): HubPolicyConfig | undefined;
|
|
4
|
-
export declare function extractHubShadowCompareConfig(metadata: Record<string, unknown> | undefined): HubShadowCompareRequestConfig | undefined;
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
export function extractHubPolicyOverride(metadata) {
|
|
2
|
-
const raw = metadata ? metadata.__hubPolicyOverride : undefined;
|
|
3
|
-
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
4
|
-
return undefined;
|
|
5
|
-
}
|
|
6
|
-
const obj = raw;
|
|
7
|
-
const mode = typeof obj.mode === 'string' ? obj.mode.trim().toLowerCase() : '';
|
|
8
|
-
const sampleRate = typeof obj.sampleRate === 'number' && Number.isFinite(obj.sampleRate) ? obj.sampleRate : undefined;
|
|
9
|
-
if (mode !== 'off' && mode !== 'observe' && mode !== 'enforce') {
|
|
10
|
-
return undefined;
|
|
11
|
-
}
|
|
12
|
-
return {
|
|
13
|
-
mode: mode,
|
|
14
|
-
...(sampleRate !== undefined ? { sampleRate } : {})
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
export function extractHubShadowCompareConfig(metadata) {
|
|
18
|
-
const raw = metadata ? metadata.__hubShadowCompare : undefined;
|
|
19
|
-
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
20
|
-
return undefined;
|
|
21
|
-
}
|
|
22
|
-
const obj = raw;
|
|
23
|
-
const modeCandidate = typeof obj.baselineMode === 'string'
|
|
24
|
-
? obj.baselineMode.trim().toLowerCase()
|
|
25
|
-
: typeof obj.mode === 'string'
|
|
26
|
-
? obj.mode.trim().toLowerCase()
|
|
27
|
-
: '';
|
|
28
|
-
if (modeCandidate !== 'off' && modeCandidate !== 'observe' && modeCandidate !== 'enforce') {
|
|
29
|
-
return undefined;
|
|
30
|
-
}
|
|
31
|
-
return { baselineMode: modeCandidate };
|
|
32
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { SseProtocol } from '../../../../sse/index.js';
|
|
2
|
-
import type { ProviderProtocol } from './types.js';
|
|
3
|
-
export declare function normalizeEndpoint(endpoint: string): string;
|
|
4
|
-
export declare function resolveProviderProtocol(value: unknown): ProviderProtocol;
|
|
5
|
-
export declare const PROVIDER_PROTOCOL_ALIASES: Record<string, ProviderProtocol>;
|
|
6
|
-
export declare function resolveEndpointForProviderProtocol(protocol?: string): string | undefined;
|
|
7
|
-
export declare function resolveSseProtocolFromMetadata(metadata: Record<string, unknown>): SseProtocol | undefined;
|
|
8
|
-
export declare function resolveClientProtocolFromEntryEndpoint(entryEndpoint: string): ProviderProtocol;
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
export function normalizeEndpoint(endpoint) {
|
|
2
|
-
if (!endpoint)
|
|
3
|
-
return '/v1/chat/completions';
|
|
4
|
-
const trimmed = endpoint.trim();
|
|
5
|
-
if (!trimmed)
|
|
6
|
-
return '/v1/chat/completions';
|
|
7
|
-
const normalized = trimmed.startsWith('/') ? trimmed : `/${trimmed}`;
|
|
8
|
-
return normalized.replace(/\/{2,}/g, '/');
|
|
9
|
-
}
|
|
10
|
-
export function resolveProviderProtocol(value) {
|
|
11
|
-
if (typeof value !== 'string' || !value.trim()) {
|
|
12
|
-
return 'openai-chat';
|
|
13
|
-
}
|
|
14
|
-
const normalized = value.trim().toLowerCase();
|
|
15
|
-
const mapped = PROVIDER_PROTOCOL_ALIASES[normalized];
|
|
16
|
-
if (mapped) {
|
|
17
|
-
return mapped;
|
|
18
|
-
}
|
|
19
|
-
throw new Error(`[HubPipeline] Unsupported providerProtocol "${value}". Configure a valid protocol (openai-chat|openai-responses|anthropic-messages|gemini-chat).`);
|
|
20
|
-
}
|
|
21
|
-
export const PROVIDER_PROTOCOL_ALIASES = {
|
|
22
|
-
'openai-chat': 'openai-chat',
|
|
23
|
-
openai: 'openai-chat',
|
|
24
|
-
chat: 'openai-chat',
|
|
25
|
-
responses: 'openai-responses',
|
|
26
|
-
'openai-responses': 'openai-responses',
|
|
27
|
-
anthropic: 'anthropic-messages',
|
|
28
|
-
'anthropic-messages': 'anthropic-messages',
|
|
29
|
-
messages: 'anthropic-messages',
|
|
30
|
-
gemini: 'gemini-chat',
|
|
31
|
-
'google-gemini': 'gemini-chat',
|
|
32
|
-
'gemini-chat': 'gemini-chat'
|
|
33
|
-
};
|
|
34
|
-
export function resolveEndpointForProviderProtocol(protocol) {
|
|
35
|
-
if (!protocol) {
|
|
36
|
-
return undefined;
|
|
37
|
-
}
|
|
38
|
-
const value = protocol.toLowerCase();
|
|
39
|
-
if (value === 'openai-responses')
|
|
40
|
-
return '/v1/responses';
|
|
41
|
-
if (value === 'openai-chat')
|
|
42
|
-
return '/v1/chat/completions';
|
|
43
|
-
if (value === 'anthropic-messages' || value === 'anthropic')
|
|
44
|
-
return '/v1/messages';
|
|
45
|
-
if (value === 'gemini-chat' || value === 'gemini' || value === 'google-gemini')
|
|
46
|
-
return '/v1/responses';
|
|
47
|
-
return undefined;
|
|
48
|
-
}
|
|
49
|
-
export function resolveSseProtocolFromMetadata(metadata) {
|
|
50
|
-
const candidate = metadata.sseProtocol ?? metadata.clientSseProtocol ?? metadata.routeSseProtocol;
|
|
51
|
-
if (typeof candidate !== 'string' || !candidate.trim()) {
|
|
52
|
-
return undefined;
|
|
53
|
-
}
|
|
54
|
-
return resolveProviderProtocol(candidate);
|
|
55
|
-
}
|
|
56
|
-
export function resolveClientProtocolFromEntryEndpoint(entryEndpoint) {
|
|
57
|
-
const lowered = String(entryEndpoint || '').toLowerCase();
|
|
58
|
-
if (lowered.includes('/v1/responses'))
|
|
59
|
-
return 'openai-responses';
|
|
60
|
-
if (lowered.includes('/v1/messages'))
|
|
61
|
-
return 'anthropic-messages';
|
|
62
|
-
return 'openai-chat';
|
|
63
|
-
}
|