@jsonstudio/llms 0.6.3238 → 0.6.3275
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/bridge-actions.js +37 -322
- package/dist/conversion/bridge-instructions.js +12 -109
- package/dist/conversion/codecs/anthropic-openai-codec.js +1 -1
- package/dist/conversion/compat/actions/anthropic-claude-code-system-prompt.js +38 -0
- package/dist/conversion/compat/actions/deepseek-web-request.js +43 -110
- package/dist/conversion/compat/actions/deepseek-web-response.d.ts +3 -0
- package/dist/conversion/compat/actions/deepseek-web-response.js +150 -11
- package/dist/conversion/hub/response/response-runtime.d.ts +1 -0
- package/dist/conversion/hub/response/response-runtime.js +26 -0
- package/dist/conversion/shared/anthropic-message-utils.d.ts +3 -1
- package/dist/conversion/shared/anthropic-message-utils.js +23 -15
- package/dist/conversion/shared/openai-finalizer.d.ts +0 -3
- package/dist/conversion/shared/openai-finalizer.js +11 -169
- package/dist/conversion/shared/openai-message-normalize.js +11 -72
- package/dist/conversion/shared/tool-mapping.js +5 -0
- package/dist/native/router_hotpath_napi.node +0 -0
- package/dist/router/virtual-router/bootstrap/provider-normalization.js +11 -3
- package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.d.ts +20 -0
- package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.js +71 -0
- package/dist/router/virtual-router/engine-selection/native-hub-pipeline-req-inbound-semantics.d.ts +1 -0
- package/dist/router/virtual-router/engine-selection/native-hub-pipeline-req-inbound-semantics.js +30 -0
- package/dist/router/virtual-router/engine-selection/native-router-hotpath-loader.js +6 -0
- package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.d.ts +2 -0
- package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.js +61 -0
- package/dist/router/virtual-router/engine.js +58 -1
- package/dist/router/virtual-router/types.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,180 +1,22 @@
|
|
|
1
1
|
// OpenAI Chat finalizer: enforce canonical shapes without the legacy hook system.
|
|
2
2
|
// - Ensures tool_calls use stringified JSON arguments and sets finish_reason='tool_calls' when applicable
|
|
3
3
|
// - Normalizes potential tool messages (role:'tool') content to strict strings (JSON-stringify for objects)
|
|
4
|
-
import {
|
|
4
|
+
import { finalizeRespProcessChatResponseWithNative } from '../../router/virtual-router/engine-selection/native-chat-process-governance-semantics.js';
|
|
5
5
|
function asObject(v) {
|
|
6
6
|
return v && typeof v === 'object' && !Array.isArray(v) ? v : null;
|
|
7
7
|
}
|
|
8
|
-
|
|
9
|
-
if (typeof argVal === 'string')
|
|
10
|
-
return argVal;
|
|
11
|
-
try {
|
|
12
|
-
return JSON.stringify(argVal ?? {});
|
|
13
|
-
}
|
|
14
|
-
catch {
|
|
15
|
-
return '{}';
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
function toStringContent(val, emptyFallback = 'Command succeeded (no output).') {
|
|
19
|
-
if (val == null)
|
|
20
|
-
return emptyFallback;
|
|
21
|
-
if (typeof val === 'string') {
|
|
22
|
-
const s = val.trim();
|
|
23
|
-
return s.length ? s : emptyFallback;
|
|
24
|
-
}
|
|
25
|
-
if (Array.isArray(val) || typeof val === 'object') {
|
|
26
|
-
try {
|
|
27
|
-
const s = JSON.stringify(val);
|
|
28
|
-
return s && s.trim().length ? s : emptyFallback;
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
return emptyFallback;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
try {
|
|
35
|
-
const s = String(val);
|
|
36
|
-
return s.trim().length ? s : emptyFallback;
|
|
37
|
-
}
|
|
38
|
-
catch {
|
|
39
|
-
return emptyFallback;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
8
|
+
// Canonicalization handled by native finalizeChatResponseJson.
|
|
42
9
|
export async function finalizeOpenAIChatResponse(chatLike, opts) {
|
|
43
|
-
const streamingIntent = opts?.stream === true;
|
|
44
10
|
const obj = asObject(chatLike);
|
|
45
11
|
if (!obj)
|
|
46
12
|
return chatLike;
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
try {
|
|
56
|
-
const fn = tc?.function || {};
|
|
57
|
-
if (fn && typeof fn === 'object') {
|
|
58
|
-
fn.arguments = stringifyArgs(fn.arguments);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
catch { /* ignore */ }
|
|
62
|
-
}
|
|
63
|
-
if (String(first.finish_reason || '').toLowerCase() !== 'tool_calls') {
|
|
64
|
-
first.finish_reason = 'tool_calls';
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
// nothing more to do for Chat completion response
|
|
69
|
-
}
|
|
70
|
-
// Case B: Chat-style messages array ({ messages: [...] })
|
|
71
|
-
if (Array.isArray(obj.messages)) {
|
|
72
|
-
const msgs = obj.messages;
|
|
73
|
-
// Build latest assistant tool_call id->name map
|
|
74
|
-
const idToName = new Map();
|
|
75
|
-
for (let i = msgs.length - 1; i >= 0; i--) {
|
|
76
|
-
const m = msgs[i];
|
|
77
|
-
if (m && m.role === 'assistant' && Array.isArray(m.tool_calls) && m.tool_calls.length) {
|
|
78
|
-
for (const tc of m.tool_calls) {
|
|
79
|
-
const id = typeof tc?.id === 'string' ? tc.id : undefined;
|
|
80
|
-
const nm = typeof tc?.function?.name === 'string' ? tc.function.name : undefined;
|
|
81
|
-
if (id && nm)
|
|
82
|
-
idToName.set(id, nm);
|
|
83
|
-
if (tc?.function)
|
|
84
|
-
tc.function.arguments = stringifyArgs(tc.function.arguments);
|
|
85
|
-
}
|
|
86
|
-
break;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
// Normalize tool role messages: ensure string content + name (if known)
|
|
90
|
-
for (const m of msgs) {
|
|
91
|
-
if (!m || typeof m !== 'object')
|
|
92
|
-
continue;
|
|
93
|
-
if (String(m.role || '').toLowerCase() !== 'tool')
|
|
94
|
-
continue;
|
|
95
|
-
const cid = typeof m.tool_call_id === 'string' ? m.tool_call_id : undefined;
|
|
96
|
-
// add name when available
|
|
97
|
-
const nm = cid ? idToName.get(cid) : undefined;
|
|
98
|
-
if (nm && typeof m.name !== 'string')
|
|
99
|
-
m.name = nm;
|
|
100
|
-
m.content = toStringContent(m.content);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
catch { /* ignore normalization errors */ }
|
|
105
|
-
applyChatReasoningPolicy(obj, opts?.reasoningMode);
|
|
106
|
-
return obj;
|
|
107
|
-
}
|
|
108
|
-
function applyChatReasoningPolicy(target, mode) {
|
|
109
|
-
if (!mode || mode === 'keep') {
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
const containers = [];
|
|
113
|
-
if (Array.isArray(target.messages)) {
|
|
114
|
-
target.messages.forEach(entry => {
|
|
115
|
-
if (entry && typeof entry === 'object') {
|
|
116
|
-
containers.push(entry);
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
if (Array.isArray(target.choices)) {
|
|
121
|
-
target.choices.forEach(choice => {
|
|
122
|
-
if (!choice || typeof choice !== 'object') {
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
const record = choice;
|
|
126
|
-
if (record.message && typeof record.message === 'object') {
|
|
127
|
-
containers.push(record.message);
|
|
128
|
-
}
|
|
129
|
-
if (record.delta && typeof record.delta === 'object') {
|
|
130
|
-
containers.push(record.delta);
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
containers.forEach(container => normalizeReasoningField(container, mode));
|
|
135
|
-
}
|
|
136
|
-
function normalizeReasoningField(container, mode) {
|
|
137
|
-
const bag = container;
|
|
138
|
-
const rawValue = typeof bag.reasoning_content === 'string' ? bag.reasoning_content : '';
|
|
139
|
-
const trimmed = sanitizeReasoningTaggedTextWithNative(rawValue).trim();
|
|
140
|
-
if (!trimmed && Object.prototype.hasOwnProperty.call(bag, 'reasoning_content')) {
|
|
141
|
-
delete bag.reasoning_content;
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
if (!trimmed) {
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
if (mode === 'drop') {
|
|
148
|
-
delete bag.reasoning_content;
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
if (mode === 'append_to_content') {
|
|
152
|
-
appendReasoningToContent(bag, trimmed);
|
|
153
|
-
delete bag.reasoning_content;
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
function appendReasoningToContent(container, reasoning) {
|
|
158
|
-
const separator = reasoning.startsWith('\n') ? '' : '\n';
|
|
159
|
-
if (typeof container.content === 'string') {
|
|
160
|
-
const base = container.content.trim().length ? container.content : '';
|
|
161
|
-
container.content = base ? `${base}${separator}${reasoning}` : reasoning;
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
if (Array.isArray(container.content)) {
|
|
165
|
-
const list = container.content;
|
|
166
|
-
list.push({ type: 'text', text: reasoning });
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
if (container.content && typeof container.content === 'object') {
|
|
170
|
-
try {
|
|
171
|
-
const serialized = JSON.stringify(container.content);
|
|
172
|
-
container.content = serialized ? `${serialized}${separator}${reasoning}` : reasoning;
|
|
173
|
-
}
|
|
174
|
-
catch {
|
|
175
|
-
container.content = reasoning;
|
|
176
|
-
}
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
container.content = reasoning;
|
|
13
|
+
const finalized = await finalizeRespProcessChatResponseWithNative({
|
|
14
|
+
payload: obj,
|
|
15
|
+
stream: opts?.stream === true,
|
|
16
|
+
reasoningMode: opts?.reasoningMode,
|
|
17
|
+
endpoint: opts?.endpoint,
|
|
18
|
+
requestId: opts?.requestId
|
|
19
|
+
});
|
|
20
|
+
return finalized;
|
|
180
21
|
}
|
|
22
|
+
// All canonicalization + reasoning policy handled by native finalizeChatResponseJson.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { injectMcpToolsForChat } from '../mcp-injection.js';
|
|
2
2
|
import { normalizeOpenaiChatMessagesWithNative, normalizeOpenaiMessageWithNative, normalizeOpenaiToolCallWithNative, normalizeOpenaiToolWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
|
|
3
|
+
import { enforceChatBudgetWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
|
|
3
4
|
// Message normalization utilities for OpenAI chat payloads (renamed to avoid confusion
|
|
4
5
|
// with the deprecated "openai-normalizer" module entry). This file contains the
|
|
5
6
|
// previously-implemented logic from openai-normalize.ts.
|
|
@@ -7,47 +8,14 @@ import { normalizeOpenaiChatMessagesWithNative, normalizeOpenaiMessageWithNative
|
|
|
7
8
|
export function normalizeChatRequest(request) {
|
|
8
9
|
if (!request || typeof request !== 'object')
|
|
9
10
|
return request;
|
|
10
|
-
|
|
11
|
+
let normalized = { ...request };
|
|
11
12
|
if (Array.isArray(normalized.messages)) {
|
|
12
13
|
normalized.messages = normalized.messages.map((msg) => normalizeMessage(msg));
|
|
13
14
|
}
|
|
14
15
|
if (Array.isArray(normalized.tools)) {
|
|
15
16
|
normalized.tools = normalized.tools.map((tool) => normalizeTool(tool));
|
|
16
17
|
}
|
|
17
|
-
//
|
|
18
|
-
// - Do not remove messages; avoid truncating tool output content.
|
|
19
|
-
try {
|
|
20
|
-
const msgs = Array.isArray(normalized.messages) ? normalized.messages : [];
|
|
21
|
-
if (msgs.length) {
|
|
22
|
-
const asstLimitRaw = process?.env?.RCC_ASSISTANT_TEXT_LIMIT;
|
|
23
|
-
const ASST_LIMIT = (asstLimitRaw === '0') ? 0 : Math.max(0, Number(asstLimitRaw ?? 8192));
|
|
24
|
-
const clamp = (s, n) => {
|
|
25
|
-
try {
|
|
26
|
-
const t = String(s);
|
|
27
|
-
return (n > 0 && t.length > n) ? (t.slice(0, n) + '...(truncated)') : t;
|
|
28
|
-
}
|
|
29
|
-
catch {
|
|
30
|
-
return s;
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
for (let i = 0; i < msgs.length; i++) {
|
|
34
|
-
const m = msgs[i];
|
|
35
|
-
if (!m || typeof m !== 'object')
|
|
36
|
-
continue;
|
|
37
|
-
const role = String(m.role || '').toLowerCase();
|
|
38
|
-
if (role === 'assistant') {
|
|
39
|
-
if (ASST_LIMIT > 0) {
|
|
40
|
-
if (typeof m.content === 'string')
|
|
41
|
-
m.content = clamp(m.content, ASST_LIMIT);
|
|
42
|
-
else if (Array.isArray(m.content)) {
|
|
43
|
-
m.content = m.content.map((p) => (p && typeof p.text === 'string') ? { ...p, text: clamp(p.text, ASST_LIMIT) } : p);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
catch { /* ignore limit errors */ }
|
|
18
|
+
// Assistant text limit handling has been moved into native budget enforcement.
|
|
51
19
|
// MCP 注入(两步法)统一走共享实现,避免路径分叉
|
|
52
20
|
const disableMcpTools = Boolean(normalized.__rcc_disable_mcp_tools);
|
|
53
21
|
if (!disableMcpTools) {
|
|
@@ -141,48 +109,19 @@ export function normalizeChatRequest(request) {
|
|
|
141
109
|
}
|
|
142
110
|
catch { /* ignore message normalization */ }
|
|
143
111
|
// 注意:不合并/删除多条 system(与 统一标准,避免高风险修改)。
|
|
144
|
-
//
|
|
112
|
+
// 基于“载荷预算”(配置驱动)进行裁剪,统一走 native。
|
|
145
113
|
try {
|
|
146
114
|
const msgs = Array.isArray(normalized.messages) ? normalized.messages : [];
|
|
147
115
|
if (msgs.length) {
|
|
148
116
|
const modelId = String(normalized?.model || '').trim();
|
|
149
117
|
const budget = resolveBudgetForModelSync(modelId);
|
|
150
|
-
const allowed = Math.max(32 * 1024, Math.floor(budget.allowedBytes));
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
let total = sizeBytes(normalized.messages);
|
|
158
|
-
if (total > allowed) {
|
|
159
|
-
// 分层裁剪:最近 3 条工具消息额度更大,其余更严格;若仍超限,再统一降到最小额度。
|
|
160
|
-
const toolIdx = [];
|
|
161
|
-
for (let i = 0; i < msgs.length; i++) {
|
|
162
|
-
const m = msgs[i];
|
|
163
|
-
if (m && m.role === 'tool' && typeof m.content === 'string')
|
|
164
|
-
toolIdx.push(i);
|
|
165
|
-
}
|
|
166
|
-
if (toolIdx.length) {
|
|
167
|
-
// Disable shrinking/truncation of tool outputs to avoid altering content
|
|
168
|
-
const shrinkTo = (_idx, _limit) => { };
|
|
169
|
-
const recentLimitChars = Number(process?.env?.RCC_TOOL_TEXT_RECENT || 1024);
|
|
170
|
-
const olderLimitChars = Number(process?.env?.RCC_TOOL_TEXT_OLDER || 256);
|
|
171
|
-
const minimalLimitChars = Number(process?.env?.RCC_TOOL_TEXT_MIN || 128);
|
|
172
|
-
const recent = toolIdx.slice(-3);
|
|
173
|
-
const older = toolIdx.slice(0, Math.max(0, toolIdx.length - recent.length));
|
|
174
|
-
// No-op shrink to keep content intact
|
|
175
|
-
for (const i of older)
|
|
176
|
-
shrinkTo(i, olderLimitChars);
|
|
177
|
-
for (const i of recent)
|
|
178
|
-
shrinkTo(i, recentLimitChars);
|
|
179
|
-
total = sizeBytes(normalized.messages);
|
|
180
|
-
if (total > allowed) {
|
|
181
|
-
for (const i of toolIdx)
|
|
182
|
-
shrinkTo(i, minimalLimitChars);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
118
|
+
const allowed = Math.max(32 * 1024, Math.floor(budget.allowedBytes));
|
|
119
|
+
const sysLimit = (() => {
|
|
120
|
+
const raw = process?.env?.RCC_SYSTEM_TEXT_LIMIT;
|
|
121
|
+
const n = Number(raw);
|
|
122
|
+
return Number.isFinite(n) && n >= 0 ? n : 8192;
|
|
123
|
+
})();
|
|
124
|
+
normalized = enforceChatBudgetWithNative(normalized, allowed, sysLimit);
|
|
186
125
|
}
|
|
187
126
|
}
|
|
188
127
|
catch { /* ignore budget enforcement */ }
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { sanitizeResponsesFunctionNameWithNative } from '../../router/virtual-router/engine-selection/native-hub-pipeline-resp-semantics.js';
|
|
2
|
+
import { mapChatToolsToBridgeWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
|
|
2
3
|
export function stringifyArgs(args) {
|
|
3
4
|
if (typeof args === 'string')
|
|
4
5
|
return args;
|
|
@@ -209,6 +210,10 @@ export function mapChatToolsToBridge(rawTools, options) {
|
|
|
209
210
|
if (!Array.isArray(rawTools) || rawTools.length === 0) {
|
|
210
211
|
return undefined;
|
|
211
212
|
}
|
|
213
|
+
if (!options?.sanitizeName) {
|
|
214
|
+
const mapped = mapChatToolsToBridgeWithNative(rawTools);
|
|
215
|
+
return mapped && mapped.length ? mapped : undefined;
|
|
216
|
+
}
|
|
212
217
|
const mapped = rawTools
|
|
213
218
|
.map((entry) => chatToolToBridgeDefinition(entry, options))
|
|
214
219
|
.filter((entry) => !!entry);
|
|
Binary file
|
|
@@ -116,17 +116,25 @@ function normalizeDeepSeekOptions(provider) {
|
|
|
116
116
|
: typeof source.strictToolRequired === 'string'
|
|
117
117
|
? source.strictToolRequired.trim().toLowerCase() === 'true'
|
|
118
118
|
: undefined;
|
|
119
|
-
const
|
|
119
|
+
const toolProtocolRaw = typeof source.toolProtocol === 'string' ? source.toolProtocol.trim().toLowerCase() : '';
|
|
120
|
+
let toolProtocol;
|
|
121
|
+
if (toolProtocolRaw === 'text' || toolProtocolRaw === 'native') {
|
|
122
|
+
toolProtocol = toolProtocolRaw;
|
|
123
|
+
}
|
|
124
|
+
const legacyTextToolFallback = typeof source.textToolFallback === 'boolean'
|
|
120
125
|
? source.textToolFallback
|
|
121
126
|
: typeof source.textToolFallback === 'string'
|
|
122
127
|
? source.textToolFallback.trim().toLowerCase() === 'true'
|
|
123
128
|
: undefined;
|
|
124
|
-
if (
|
|
129
|
+
if (toolProtocol === undefined && legacyTextToolFallback !== undefined) {
|
|
130
|
+
toolProtocol = legacyTextToolFallback ? 'text' : 'native';
|
|
131
|
+
}
|
|
132
|
+
if (strictToolRequired === undefined && toolProtocol === undefined) {
|
|
125
133
|
return undefined;
|
|
126
134
|
}
|
|
127
135
|
return {
|
|
128
136
|
...(strictToolRequired !== undefined ? { strictToolRequired } : {}),
|
|
129
|
-
...(
|
|
137
|
+
...(toolProtocol !== undefined ? { toolProtocol } : {})
|
|
130
138
|
};
|
|
131
139
|
}
|
|
132
140
|
function resolveCompatibilityProfile(providerId, provider) {
|
|
@@ -113,6 +113,25 @@ export interface NativeApplyBridgeEnsureSystemInstructionOutput {
|
|
|
113
113
|
messages: unknown[];
|
|
114
114
|
metadata?: Record<string, unknown>;
|
|
115
115
|
}
|
|
116
|
+
export interface NativeBridgeActionPipelineInput {
|
|
117
|
+
stage: 'request_inbound' | 'request_outbound' | 'response_inbound' | 'response_outbound';
|
|
118
|
+
actions?: Array<{
|
|
119
|
+
name: string;
|
|
120
|
+
options?: Record<string, unknown>;
|
|
121
|
+
}>;
|
|
122
|
+
protocol?: string;
|
|
123
|
+
moduleType?: string;
|
|
124
|
+
requestId?: string;
|
|
125
|
+
state: NativeBridgeActionState;
|
|
126
|
+
}
|
|
127
|
+
export interface NativeBridgeActionState {
|
|
128
|
+
messages: unknown[];
|
|
129
|
+
requiredAction?: Record<string, unknown>;
|
|
130
|
+
capturedToolResults?: Array<Record<string, unknown>>;
|
|
131
|
+
rawRequest?: Record<string, unknown>;
|
|
132
|
+
rawResponse?: Record<string, unknown>;
|
|
133
|
+
metadata?: Record<string, unknown>;
|
|
134
|
+
}
|
|
116
135
|
export interface NativeNormalizeMessageReasoningToolsOutput {
|
|
117
136
|
message: Record<string, unknown>;
|
|
118
137
|
toolCallsAdded: number;
|
|
@@ -130,5 +149,6 @@ export declare function applyBridgeReasoningExtractWithNative(input: NativeApply
|
|
|
130
149
|
export declare function applyBridgeResponsesOutputReasoningWithNative(input: NativeApplyBridgeResponsesOutputReasoningInput): NativeApplyBridgeResponsesOutputReasoningOutput;
|
|
131
150
|
export declare function applyBridgeInjectSystemInstructionWithNative(input: NativeApplyBridgeInjectSystemInstructionInput): NativeApplyBridgeInjectSystemInstructionOutput;
|
|
132
151
|
export declare function applyBridgeEnsureSystemInstructionWithNative(input: NativeApplyBridgeEnsureSystemInstructionInput): NativeApplyBridgeEnsureSystemInstructionOutput;
|
|
152
|
+
export declare function runBridgeActionPipelineWithNative(input: NativeBridgeActionPipelineInput): NativeBridgeActionState | null;
|
|
133
153
|
export declare function normalizeMessageReasoningToolsWithNative(message: Record<string, unknown>, idPrefix?: string): NativeNormalizeMessageReasoningToolsOutput;
|
|
134
154
|
export declare function normalizeChatResponseReasoningToolsWithNative(response: Record<string, unknown>, idPrefixBase?: string): Record<string, unknown>;
|
|
@@ -68,6 +68,40 @@ function parseBridgeHistoryOutput(raw) {
|
|
|
68
68
|
return null;
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
|
+
function parseBridgeActionState(raw) {
|
|
72
|
+
try {
|
|
73
|
+
const parsed = JSON.parse(raw);
|
|
74
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
const row = parsed;
|
|
78
|
+
if (!Array.isArray(row.messages)) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
const output = {
|
|
82
|
+
messages: row.messages
|
|
83
|
+
};
|
|
84
|
+
if (row.requiredAction && typeof row.requiredAction === 'object' && !Array.isArray(row.requiredAction)) {
|
|
85
|
+
output.requiredAction = row.requiredAction;
|
|
86
|
+
}
|
|
87
|
+
if (Array.isArray(row.capturedToolResults)) {
|
|
88
|
+
output.capturedToolResults = row.capturedToolResults.filter((entry) => Boolean(entry) && typeof entry === 'object' && !Array.isArray(entry));
|
|
89
|
+
}
|
|
90
|
+
if (row.rawRequest && typeof row.rawRequest === 'object' && !Array.isArray(row.rawRequest)) {
|
|
91
|
+
output.rawRequest = row.rawRequest;
|
|
92
|
+
}
|
|
93
|
+
if (row.rawResponse && typeof row.rawResponse === 'object' && !Array.isArray(row.rawResponse)) {
|
|
94
|
+
output.rawResponse = row.rawResponse;
|
|
95
|
+
}
|
|
96
|
+
if (row.metadata && typeof row.metadata === 'object' && !Array.isArray(row.metadata)) {
|
|
97
|
+
output.metadata = row.metadata;
|
|
98
|
+
}
|
|
99
|
+
return output;
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
71
105
|
function parseApplyBridgeNormalizeHistoryOutput(raw) {
|
|
72
106
|
try {
|
|
73
107
|
const parsed = JSON.parse(raw);
|
|
@@ -673,6 +707,43 @@ export function applyBridgeEnsureSystemInstructionWithNative(input) {
|
|
|
673
707
|
return fail(reason);
|
|
674
708
|
}
|
|
675
709
|
}
|
|
710
|
+
export function runBridgeActionPipelineWithNative(input) {
|
|
711
|
+
const capability = 'runBridgeActionPipelineJson';
|
|
712
|
+
const fail = (reason) => failNativeRequired(capability, reason);
|
|
713
|
+
if (isNativeDisabledByEnv()) {
|
|
714
|
+
return fail('native disabled');
|
|
715
|
+
}
|
|
716
|
+
const fn = readNativeFunction(capability);
|
|
717
|
+
if (!fn) {
|
|
718
|
+
return fail();
|
|
719
|
+
}
|
|
720
|
+
const payloadJson = safeStringify({
|
|
721
|
+
stage: input.stage,
|
|
722
|
+
actions: input.actions,
|
|
723
|
+
protocol: input.protocol,
|
|
724
|
+
moduleType: input.moduleType,
|
|
725
|
+
requestId: input.requestId,
|
|
726
|
+
state: input.state
|
|
727
|
+
});
|
|
728
|
+
if (!payloadJson) {
|
|
729
|
+
return fail('json stringify failed');
|
|
730
|
+
}
|
|
731
|
+
try {
|
|
732
|
+
const raw = fn(payloadJson);
|
|
733
|
+
if (typeof raw !== 'string' || !raw) {
|
|
734
|
+
return fail('empty result');
|
|
735
|
+
}
|
|
736
|
+
const parsed = parseBridgeActionState(raw);
|
|
737
|
+
if (!parsed) {
|
|
738
|
+
return null;
|
|
739
|
+
}
|
|
740
|
+
return parsed;
|
|
741
|
+
}
|
|
742
|
+
catch (error) {
|
|
743
|
+
const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
|
|
744
|
+
return fail(reason);
|
|
745
|
+
}
|
|
746
|
+
}
|
|
676
747
|
export function normalizeMessageReasoningToolsWithNative(message, idPrefix) {
|
|
677
748
|
const capability = 'normalizeMessageReasoningToolsJson';
|
|
678
749
|
const fail = (reason) => failNativeRequired(capability, reason);
|
package/dist/router/virtual-router/engine-selection/native-hub-pipeline-req-inbound-semantics.d.ts
CHANGED
|
@@ -29,6 +29,7 @@ export declare function resolveReqInboundServerToolFollowupSnapshotWithNative(ad
|
|
|
29
29
|
export declare function augmentReqInboundContextSnapshotWithNative(context: Record<string, unknown>, fallbackSnapshot: Record<string, unknown>): Record<string, unknown>;
|
|
30
30
|
export declare function normalizeReqInboundToolCallIdStyleWithNative(value: unknown): 'fc' | 'preserve' | undefined;
|
|
31
31
|
export declare function mapReqInboundBridgeToolsToChatWithNative(rawTools: unknown): Array<Record<string, unknown>>;
|
|
32
|
+
export declare function mapChatToolsToBridgeWithNative(rawTools: unknown): Array<Record<string, unknown>>;
|
|
32
33
|
export declare function captureReqInboundResponsesContextSnapshotWithNative(input: {
|
|
33
34
|
rawRequest: Record<string, unknown>;
|
|
34
35
|
requestId?: string;
|
package/dist/router/virtual-router/engine-selection/native-hub-pipeline-req-inbound-semantics.js
CHANGED
|
@@ -339,6 +339,36 @@ export function mapReqInboundBridgeToolsToChatWithNative(rawTools) {
|
|
|
339
339
|
return fail(reason);
|
|
340
340
|
}
|
|
341
341
|
}
|
|
342
|
+
export function mapChatToolsToBridgeWithNative(rawTools) {
|
|
343
|
+
const capability = 'mapChatToolsToBridgeJson';
|
|
344
|
+
const fail = (reason) => failNativeRequired(capability, reason);
|
|
345
|
+
if (isNativeDisabledByEnv()) {
|
|
346
|
+
return fail('native disabled');
|
|
347
|
+
}
|
|
348
|
+
const fn = readNativeFunction(capability);
|
|
349
|
+
if (!fn) {
|
|
350
|
+
return fail();
|
|
351
|
+
}
|
|
352
|
+
const payloadJson = safeStringify(Array.isArray(rawTools) ? rawTools : []);
|
|
353
|
+
if (!payloadJson) {
|
|
354
|
+
return fail('json stringify failed');
|
|
355
|
+
}
|
|
356
|
+
try {
|
|
357
|
+
const raw = fn(payloadJson);
|
|
358
|
+
if (typeof raw !== 'string' || !raw) {
|
|
359
|
+
return fail('empty result');
|
|
360
|
+
}
|
|
361
|
+
const parsed = parseArray(raw);
|
|
362
|
+
if (!parsed) {
|
|
363
|
+
return fail('invalid payload');
|
|
364
|
+
}
|
|
365
|
+
return parsed.filter((entry) => Boolean(entry) && typeof entry === 'object' && !Array.isArray(entry));
|
|
366
|
+
}
|
|
367
|
+
catch (error) {
|
|
368
|
+
const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
|
|
369
|
+
return fail(reason);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
342
372
|
export function captureReqInboundResponsesContextSnapshotWithNative(input) {
|
|
343
373
|
const capability = 'captureReqInboundResponsesContextSnapshotJson';
|
|
344
374
|
const fail = (reason) => failNativeRequired(capability, reason);
|
|
@@ -29,6 +29,7 @@ const REQUIRED_NATIVE_EXPORTS = [
|
|
|
29
29
|
'augmentContextSnapshotJson',
|
|
30
30
|
'annotatePassthroughGovernanceSkipJson',
|
|
31
31
|
'buildAnthropicToolAliasMapJson',
|
|
32
|
+
'buildAnthropicResponseFromChatJson',
|
|
32
33
|
'buildChatNodeResultMetadataJson',
|
|
33
34
|
'buildProcessedRequestFromChatResponseJson',
|
|
34
35
|
'applyChatProcessedRequestJson',
|
|
@@ -65,6 +66,7 @@ const REQUIRED_NATIVE_EXPORTS = [
|
|
|
65
66
|
'mapBridgeToolsToChatJson',
|
|
66
67
|
'mapOpenaiChatToChatJson',
|
|
67
68
|
'mapOpenaiChatFromChatJson',
|
|
69
|
+
'mapChatToolsToBridgeJson',
|
|
68
70
|
'captureReqInboundResponsesContextSnapshotJson',
|
|
69
71
|
'computeQuotaBucketsJson',
|
|
70
72
|
'deserializeStopMessageStateJson',
|
|
@@ -112,6 +114,8 @@ const REQUIRED_NATIVE_EXPORTS = [
|
|
|
112
114
|
'injectTimeTagIntoMessagesJson',
|
|
113
115
|
'injectMcpToolsForChatJson',
|
|
114
116
|
'injectMcpToolsForResponsesJson',
|
|
117
|
+
'mapOpenaiChatToChatJson',
|
|
118
|
+
'mapOpenaiChatFromChatJson',
|
|
115
119
|
'isStopMessageStateActiveJson',
|
|
116
120
|
'isContextLengthExceededSignalJson',
|
|
117
121
|
'isCompactionRequestJson',
|
|
@@ -207,9 +211,11 @@ const REQUIRED_NATIVE_EXPORTS = [
|
|
|
207
211
|
'resolveSseStreamModeJson',
|
|
208
212
|
'resolveSseProtocolFromMetadataJson',
|
|
209
213
|
'repairArgumentsToStringJsonishJson',
|
|
214
|
+
'runBridgeActionPipelineJson',
|
|
210
215
|
'sanitizeChatCompletionLikeJson',
|
|
211
216
|
'sanitizeFormatEnvelopeJson',
|
|
212
217
|
'sanitizeReasoningTaggedTextJson',
|
|
218
|
+
'ensureBridgeInstructionsJson',
|
|
213
219
|
'sanitizeResponsesFunctionNameJson',
|
|
214
220
|
'shouldRecordSnapshotsJson',
|
|
215
221
|
'writeSnapshotViaHooksJson',
|
|
@@ -4,7 +4,9 @@ export declare function extractToolCallsFromReasoningTextWithNative(text: string
|
|
|
4
4
|
cleanedText: string;
|
|
5
5
|
toolCalls: Array<Record<string, unknown>>;
|
|
6
6
|
};
|
|
7
|
+
export declare function mapChatToolsToBridgeWithNative(rawTools: unknown): Array<Record<string, unknown>>;
|
|
7
8
|
export declare function sanitizeReasoningTaggedTextWithNative(text: string): string;
|
|
9
|
+
export declare function ensureBridgeInstructionsWithNative(payload: Record<string, unknown>): Record<string, unknown>;
|
|
8
10
|
export declare function deriveToolCallKeyWithNative(call: Record<string, unknown> | null | undefined): string | null;
|
|
9
11
|
export declare function buildProviderProtocolErrorWithNative(input: {
|
|
10
12
|
message: string;
|
|
@@ -80,6 +80,10 @@ function parseToolCallLiteArray(raw) {
|
|
|
80
80
|
}
|
|
81
81
|
return out;
|
|
82
82
|
}
|
|
83
|
+
function parseArray(raw) {
|
|
84
|
+
const parsed = parseJson(raw);
|
|
85
|
+
return Array.isArray(parsed) ? parsed : null;
|
|
86
|
+
}
|
|
83
87
|
export function parseLenientJsonishWithNative(value) {
|
|
84
88
|
const capability = 'parseLenientJsonishJson';
|
|
85
89
|
const fail = (reason) => failNativeRequired(capability, reason);
|
|
@@ -156,6 +160,36 @@ export function extractToolCallsFromReasoningTextWithNative(text, idPrefix) {
|
|
|
156
160
|
return fail(reason);
|
|
157
161
|
}
|
|
158
162
|
}
|
|
163
|
+
export function mapChatToolsToBridgeWithNative(rawTools) {
|
|
164
|
+
const capability = 'mapChatToolsToBridgeJson';
|
|
165
|
+
const fail = (reason) => failNativeRequired(capability, reason);
|
|
166
|
+
if (isNativeDisabledByEnv()) {
|
|
167
|
+
return fail('native disabled');
|
|
168
|
+
}
|
|
169
|
+
const fn = readNativeFunction(capability);
|
|
170
|
+
if (!fn) {
|
|
171
|
+
return fail();
|
|
172
|
+
}
|
|
173
|
+
const payloadJson = safeStringify(Array.isArray(rawTools) ? rawTools : []);
|
|
174
|
+
if (!payloadJson) {
|
|
175
|
+
return fail('json stringify failed');
|
|
176
|
+
}
|
|
177
|
+
try {
|
|
178
|
+
const raw = fn(payloadJson);
|
|
179
|
+
if (typeof raw !== 'string' || !raw) {
|
|
180
|
+
return fail('empty result');
|
|
181
|
+
}
|
|
182
|
+
const parsed = parseArray(raw);
|
|
183
|
+
if (!parsed) {
|
|
184
|
+
return fail('invalid payload');
|
|
185
|
+
}
|
|
186
|
+
return parsed.filter((entry) => !!entry && typeof entry === 'object' && !Array.isArray(entry));
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
|
|
190
|
+
return fail(reason);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
159
193
|
export function sanitizeReasoningTaggedTextWithNative(text) {
|
|
160
194
|
const capability = 'sanitizeReasoningTaggedTextJson';
|
|
161
195
|
const fail = (reason) => failNativeRequired(capability, reason);
|
|
@@ -178,6 +212,33 @@ export function sanitizeReasoningTaggedTextWithNative(text) {
|
|
|
178
212
|
return fail(reason);
|
|
179
213
|
}
|
|
180
214
|
}
|
|
215
|
+
export function ensureBridgeInstructionsWithNative(payload) {
|
|
216
|
+
const capability = 'ensureBridgeInstructionsJson';
|
|
217
|
+
const fail = (reason) => failNativeRequired(capability, reason);
|
|
218
|
+
if (isNativeDisabledByEnv()) {
|
|
219
|
+
return fail('native disabled');
|
|
220
|
+
}
|
|
221
|
+
const fn = readNativeFunction(capability);
|
|
222
|
+
if (!fn) {
|
|
223
|
+
return fail();
|
|
224
|
+
}
|
|
225
|
+
const payloadJson = safeStringify(payload ?? {});
|
|
226
|
+
if (!payloadJson) {
|
|
227
|
+
return fail('json stringify failed');
|
|
228
|
+
}
|
|
229
|
+
try {
|
|
230
|
+
const raw = fn(payloadJson);
|
|
231
|
+
if (typeof raw !== 'string' || !raw) {
|
|
232
|
+
return fail('empty result');
|
|
233
|
+
}
|
|
234
|
+
const parsed = parseRecord(raw);
|
|
235
|
+
return parsed ?? fail('invalid payload');
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
|
|
239
|
+
return fail(reason);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
181
242
|
export function deriveToolCallKeyWithNative(call) {
|
|
182
243
|
const capability = 'deriveToolCallKeyJson';
|
|
183
244
|
const fail = (reason) => failNativeRequired(capability, reason);
|