@jsonstudio/llms 0.6.3275 → 0.6.3405

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.
Files changed (72) hide show
  1. package/dist/conversion/bridge-message-utils.d.ts +4 -4
  2. package/dist/conversion/bridge-message-utils.js +28 -538
  3. package/dist/conversion/compat/actions/claude-thinking-tools.d.ts +1 -14
  4. package/dist/conversion/compat/actions/claude-thinking-tools.js +3 -71
  5. package/dist/conversion/compat/actions/lmstudio-responses-fc-ids.d.ts +0 -8
  6. package/dist/conversion/compat/actions/lmstudio-responses-fc-ids.js +2 -57
  7. package/dist/conversion/compat/actions/normalize-tool-call-ids.d.ts +0 -9
  8. package/dist/conversion/compat/actions/normalize-tool-call-ids.js +6 -136
  9. package/dist/conversion/compat/actions/request-rules.js +2 -61
  10. package/dist/conversion/compat/actions/response-blacklist.d.ts +0 -4
  11. package/dist/conversion/compat/actions/response-blacklist.js +2 -77
  12. package/dist/conversion/compat/actions/response-normalize.js +2 -119
  13. package/dist/conversion/compat/actions/response-validate.js +2 -74
  14. package/dist/conversion/compat/actions/strip-orphan-function-calls-tag.js +2 -150
  15. package/dist/conversion/compat/profiles/responses-crs.json +15 -0
  16. package/dist/conversion/hub/operation-table/semantic-mappers/anthropic-mapper.js +24 -1
  17. package/dist/conversion/hub/operation-table/semantic-mappers/chat-mapper.js +16 -5
  18. package/dist/conversion/hub/pipeline/hub-pipeline.js +91 -0
  19. package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage1_tool_governance/index.js +1 -6
  20. package/dist/conversion/hub/response/response-runtime.js +14 -6
  21. package/dist/conversion/responses/responses-openai-bridge/response-payload.js +11 -11
  22. package/dist/conversion/shared/anthropic-message-utils.js +2 -12
  23. package/dist/conversion/shared/chat-request-filters.js +2 -61
  24. package/dist/conversion/shared/reasoning-mapping.js +3 -0
  25. package/dist/conversion/shared/reasoning-normalizer.d.ts +1 -0
  26. package/dist/conversion/shared/reasoning-normalizer.js +35 -388
  27. package/dist/conversion/shared/reasoning-tool-normalizer.js +8 -15
  28. package/dist/conversion/shared/reasoning-tool-parser.js +7 -8
  29. package/dist/conversion/shared/reasoning-utils.js +13 -35
  30. package/dist/conversion/shared/responses-response-utils.js +3 -48
  31. package/dist/conversion/shared/responses-tool-utils.d.ts +1 -1
  32. package/dist/conversion/shared/responses-tool-utils.js +74 -180
  33. package/dist/conversion/shared/streaming-text-extractor.d.ts +0 -5
  34. package/dist/conversion/shared/streaming-text-extractor.js +18 -111
  35. package/dist/conversion/shared/text-markup-normalizer/normalize.d.ts +1 -1
  36. package/dist/conversion/shared/text-markup-normalizer/normalize.js +3 -91
  37. package/dist/conversion/shared/thought-signature-validator.js +19 -133
  38. package/dist/conversion/shared/tool-argument-repairer.js +16 -19
  39. package/dist/conversion/shared/tool-call-id-manager.d.ts +1 -5
  40. package/dist/conversion/shared/tool-call-id-manager.js +74 -98
  41. package/dist/conversion/shared/tool-harvester.js +19 -382
  42. package/dist/conversion/shared/tool-mapping.d.ts +2 -3
  43. package/dist/conversion/shared/tool-mapping.js +28 -184
  44. package/dist/conversion/shared/tooling.js +20 -151
  45. package/dist/filters/special/response-tool-arguments-stringify.js +9 -1
  46. package/dist/guidance/index.js +2 -2
  47. package/dist/native/router_hotpath_napi.node +0 -0
  48. package/dist/router/virtual-router/bootstrap/web-search-config.js +25 -0
  49. package/dist/router/virtual-router/bootstrap.js +21 -16
  50. package/dist/router/virtual-router/engine-legacy/helpers.js +1 -1
  51. package/dist/router/virtual-router/engine-selection/native-compat-action-semantics.d.ts +6 -0
  52. package/dist/router/virtual-router/engine-selection/native-compat-action-semantics.js +171 -0
  53. package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.d.ts +39 -0
  54. package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.js +196 -0
  55. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-req-inbound-semantics.d.ts +1 -0
  56. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-req-inbound-semantics.js +27 -0
  57. package/dist/router/virtual-router/engine-selection/native-router-hotpath-loader.js +45 -0
  58. package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.d.ts +70 -1
  59. package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.js +993 -55
  60. package/dist/router/virtual-router/engine.js +3 -2
  61. package/dist/router/virtual-router/routing-instructions/parse.js +30 -3
  62. package/dist/router/virtual-router/types.d.ts +23 -0
  63. package/dist/servertool/handlers/web-search.js +26 -1
  64. package/dist/servertool/server-side-tools.js +11 -2
  65. package/dist/servertool/types.d.ts +4 -0
  66. package/dist/sse/sse-to-json/builders/anthropic-response-builder.js +28 -3
  67. package/dist/sse/types/anthropic-types.d.ts +3 -1
  68. package/dist/tools/apply-patch/args-normalizer/extract-patch.js +2 -2
  69. package/dist/tools/apply-patch/patch-text/looks-like-patch.js +3 -6
  70. package/dist/tools/apply-patch/patch-text/normalize.js +14 -3
  71. package/dist/tools/tool-registry.js +12 -0
  72. package/package.json +6 -1
@@ -2,7 +2,16 @@
2
2
  * Shared helpers for standard tool normalization (shell packing rules).
3
3
  * The goal is deterministic, minimal shaping so executors succeed consistently.
4
4
  */
5
- import { parseLenientJsonishWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
5
+ import { chunkStringWithNative, flattenByCommaWithNative, packShellArgsWithNative, repairFindMetaWithNative, splitCommandStringWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
6
+ function assertToolingNativeAvailable() {
7
+ if (typeof repairFindMetaWithNative !== 'function' ||
8
+ typeof splitCommandStringWithNative !== 'function' ||
9
+ typeof packShellArgsWithNative !== 'function' ||
10
+ typeof flattenByCommaWithNative !== 'function' ||
11
+ typeof chunkStringWithNative !== 'function') {
12
+ throw new Error('[tooling] native bindings unavailable');
13
+ }
14
+ }
6
15
  // We intentionally do NOT evaluate shell control operators (&&, |, etc.).
7
16
  // Codex CLI executor runs argv directly (execvp-like), not through a shell.
8
17
  // So we avoid wrapping with "bash -lc" and leave such tokens as-is.
@@ -13,103 +22,12 @@ import { parseLenientJsonishWithNative } from '../../router/virtual-router/engin
13
22
  * - escape bare parentheses used in predicates: `(` / `)` → `\(` / `\)`
14
23
  */
15
24
  export function repairFindMeta(script) {
16
- try {
17
- const s = String(script ?? '');
18
- if (!s)
19
- return s;
20
- const hasFind = /(^|\s)find\s/.test(s);
21
- if (!hasFind)
22
- return s;
23
- let out = s;
24
- // Only escape semicolon not already escaped (negative lookbehind)
25
- out = out.replace(/-exec([^;]*?)(?<!\\);/g, (_m, g1) => `-exec${g1} \\;`);
26
- // Collapse multiple backslashes immediately before ; into a single backslash
27
- out = out.replace(/-exec([^;]*?)\\+;/g, (_m, g1) => `-exec${g1} \\;`);
28
- // Escape parentheses only when not already escaped
29
- out = out.replace(/(?<!\\)\(/g, '\\(').replace(/(?<!\\)\)/g, '\\)');
30
- return out;
31
- }
32
- catch {
33
- return script;
34
- }
35
- }
36
- function toStringArray(v) {
37
- if (Array.isArray(v))
38
- return v.map((x) => String(x));
39
- if (typeof v === 'string')
40
- return [v];
41
- if (v == null)
42
- return [];
43
- return [String(v)];
25
+ assertToolingNativeAvailable();
26
+ return repairFindMetaWithNative(script ?? '');
44
27
  }
45
28
  export function splitCommandString(input) {
46
- const s = input.trim();
47
- if (!s)
48
- return [];
49
- try {
50
- if (s.startsWith('{') || s.startsWith('[')) {
51
- const parsed = parseLenientJsonishWithNative(s);
52
- if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
53
- const command = parsed.command;
54
- if (Array.isArray(command)) {
55
- const tokens = command.map((entry) => String(entry ?? '')).map((entry) => entry.trim()).filter(Boolean);
56
- if (tokens.length) {
57
- return tokens;
58
- }
59
- }
60
- }
61
- }
62
- }
63
- catch {
64
- // Keep legacy parser path when native parse returns non-command payload.
65
- }
66
- const out = [];
67
- let cur = '';
68
- let inSingle = false;
69
- let inDouble = false;
70
- for (let i = 0; i < s.length; i++) {
71
- const ch = s[i];
72
- if (inSingle) {
73
- if (ch === "'") {
74
- inSingle = false;
75
- continue;
76
- }
77
- cur += ch;
78
- continue;
79
- }
80
- if (inDouble) {
81
- if (ch === '"') {
82
- inDouble = false;
83
- continue;
84
- }
85
- if (ch === '\\' && i + 1 < s.length) { // simple escape in double quotes
86
- i++;
87
- cur += s[i];
88
- continue;
89
- }
90
- cur += ch;
91
- continue;
92
- }
93
- if (ch === "'") {
94
- inSingle = true;
95
- continue;
96
- }
97
- if (ch === '"') {
98
- inDouble = true;
99
- continue;
100
- }
101
- if (/\s/.test(ch)) {
102
- if (cur) {
103
- out.push(cur);
104
- cur = '';
105
- }
106
- continue;
107
- }
108
- cur += ch;
109
- }
110
- if (cur)
111
- out.push(cur);
112
- return out;
29
+ assertToolingNativeAvailable();
30
+ return splitCommandStringWithNative(input ?? '');
113
31
  }
114
32
  /**
115
33
  * Pack shell arguments per unified rules:
@@ -125,64 +43,15 @@ export function splitCommandString(input) {
125
43
  * - join(rest) uses single-space join without extra quoting
126
44
  */
127
45
  export function packShellArgs(input) {
128
- const out = { ...input };
129
- const cmdRaw = out.command;
130
- const workdir = out.workdir;
131
- // string => split into argv tokens (no shell wrapping)
132
- if (typeof cmdRaw === 'string') {
133
- const tokens = splitCommandString(cmdRaw);
134
- // handle leading cd as cwd switch
135
- if (tokens[0] === 'cd' && typeof tokens[1] === 'string' && tokens[1]) {
136
- const dir = tokens[1];
137
- let rest = tokens.slice(2);
138
- // tolerate common chain operator right after cd
139
- if (rest[0] === '&&' || rest[0] === ';') {
140
- rest = rest.slice(1);
141
- }
142
- if (!workdir)
143
- out.workdir = dir;
144
- out.command = rest.length ? rest : ['pwd'];
145
- return out;
146
- }
147
- out.command = tokens.length ? tokens : ['pwd'];
148
- if (typeof workdir === 'string' && workdir)
149
- out.workdir = workdir;
150
- return out;
151
- }
152
- // array tokens
153
- const tokens = toStringArray(cmdRaw);
154
- if (tokens.length === 0) {
155
- out.command = ['pwd'];
156
- if (typeof workdir === 'string' && workdir)
157
- out.workdir = workdir;
158
- return out;
159
- }
160
- // cd chain for argv input
161
- if (tokens[0] === 'cd' && typeof tokens[1] === 'string' && tokens[1]) {
162
- const dir = tokens[1];
163
- const rest = tokens.slice(2);
164
- if (!workdir)
165
- out.workdir = dir;
166
- out.command = rest.length ? rest : ['pwd'];
167
- return out;
168
- }
169
- // argv straight
170
- out.command = tokens;
171
- if (typeof workdir === 'string' && workdir)
172
- out.workdir = workdir;
173
- return out;
46
+ assertToolingNativeAvailable();
47
+ return packShellArgsWithNative(input);
174
48
  }
175
49
  export function flattenByComma(arr) {
176
- return arr.flatMap((t) => String(t).split(',').map(s => s.trim()).filter(Boolean));
50
+ assertToolingNativeAvailable();
51
+ return flattenByCommaWithNative(arr);
177
52
  }
178
53
  // Helper to chunk a long string into N parts (bounded)
179
54
  export function chunkString(s, minParts = 3, maxParts = 12, targetChunk = 12) {
180
- if (typeof s !== 'string' || !s.length)
181
- return [];
182
- const parts = Math.max(minParts, Math.min(maxParts, Math.ceil(s.length / targetChunk)));
183
- const step = Math.max(1, Math.ceil(s.length / parts));
184
- const out = [];
185
- for (let i = 0; i < s.length; i += step)
186
- out.push(s.slice(i, i + step));
187
- return out;
55
+ assertToolingNativeAvailable();
56
+ return chunkStringWithNative(s, minParts, maxParts, targetChunk);
188
57
  }
@@ -82,7 +82,7 @@ export class ResponseToolArgumentsStringifyFilter {
82
82
  fn.arguments = '{}';
83
83
  }
84
84
  }
85
- else if ((name === 'exec_command' || name === 'shell_command' || name === 'bash') && isObject(parsed)) {
85
+ else if (name === 'exec_command' && isObject(parsed)) {
86
86
  const normalized = normalizeExecCommandArgs(parsed);
87
87
  const next = normalized.ok ? normalized.normalized : parsed;
88
88
  try {
@@ -92,6 +92,14 @@ export class ResponseToolArgumentsStringifyFilter {
92
92
  fn.arguments = '{}';
93
93
  }
94
94
  }
95
+ else if ((name === 'shell_command' || name === 'bash') && isObject(parsed)) {
96
+ try {
97
+ fn.arguments = JSON.stringify(parsed ?? {});
98
+ }
99
+ catch {
100
+ fn.arguments = '{}';
101
+ }
102
+ }
95
103
  else {
96
104
  if (typeof argIn !== 'string') {
97
105
  try {
@@ -67,7 +67,7 @@ function buildApplyPatchGuidanceText() {
67
67
  '*** End Patch',
68
68
  '```',
69
69
  '',
70
- 'Paths must stay relative to the workspace root (no leading "/" or drive letters).'
70
+ 'Paths must be workspace-relative ONLY (no leading "/" or drive letters). Absolute paths will be rejected by the sandbox.'
71
71
  ].join('\n');
72
72
  return { marker, text };
73
73
  }
@@ -127,7 +127,7 @@ function augmentApplyPatch(fn) {
127
127
  const props = params.properties;
128
128
  props.patch = {
129
129
  type: 'string',
130
- description: 'Patch text. Supports "*** Begin Patch" format or GNU unified diff. Paths must be workspace-relative.'
130
+ description: 'Patch text. Supports "*** Begin Patch" format or GNU unified diff. Paths must be workspace-relative (absolute paths are rejected).'
131
131
  };
132
132
  props.input = {
133
133
  type: 'string',
@@ -37,6 +37,27 @@ export function normalizeWebSearch(input, routingSource) {
37
37
  const resolvedProviderKey = resolveWebSearchEngineProviderKey(providerKey, webSearchRouteTargets) ?? providerKey;
38
38
  const description = typeof node.description === 'string' && node.description.trim() ? node.description.trim() : undefined;
39
39
  const isDefault = node.default === true || (typeof node.default === 'string' && node.default.trim().toLowerCase() === 'true');
40
+ const rawExecutionMode = typeof node.executionMode === 'string'
41
+ ? node.executionMode.trim().toLowerCase()
42
+ : typeof node.mode === 'string'
43
+ ? node.mode.trim().toLowerCase()
44
+ : '';
45
+ const executionMode = rawExecutionMode === 'direct' ? 'direct' : 'servertool';
46
+ const rawDirectActivation = typeof node.directActivation === 'string'
47
+ ? node.directActivation.trim().toLowerCase()
48
+ : typeof node.activation === 'string'
49
+ ? node.activation.trim().toLowerCase()
50
+ : '';
51
+ const directActivation = rawDirectActivation === 'builtin'
52
+ ? 'builtin'
53
+ : rawDirectActivation === 'route'
54
+ ? 'route'
55
+ : executionMode === 'direct'
56
+ ? 'route'
57
+ : undefined;
58
+ const modelId = typeof node.modelId === 'string' && node.modelId.trim() ? node.modelId.trim() : undefined;
59
+ const maxUsesRaw = typeof node.maxUses === 'number' ? node.maxUses : Number(node.maxUses);
60
+ const maxUses = Number.isFinite(maxUsesRaw) && maxUsesRaw > 0 ? Math.floor(maxUsesRaw) : undefined;
40
61
  const serverToolsDisabled = node.serverToolsDisabled === true ||
41
62
  (typeof node.serverToolsDisabled === 'string' &&
42
63
  node.serverToolsDisabled.trim().toLowerCase() === 'true') ||
@@ -51,6 +72,10 @@ export function normalizeWebSearch(input, routingSource) {
51
72
  providerKey: resolvedProviderKey,
52
73
  description,
53
74
  default: isDefault,
75
+ executionMode,
76
+ ...(directActivation ? { directActivation } : {}),
77
+ ...(modelId ? { modelId } : {}),
78
+ ...(maxUses ? { maxUses } : {}),
54
79
  ...(serverToolsDisabled ? { serverToolsDisabled: true } : {})
55
80
  });
56
81
  }
@@ -140,26 +140,31 @@ function buildProviderRuntimeEntries(providers) {
140
140
  }
141
141
  return { runtimeEntries, aliasIndex, modelIndex };
142
142
  }
143
- function collectProviderModels(providerRaw, normalizedProvider) {
143
+ function collectProviderModels(providerRaw, _normalizedProvider) {
144
144
  const rawModelsNode = providerRaw.models;
145
145
  const modelsDeclared = rawModelsNode !== undefined;
146
146
  const modelsNode = asRecord(rawModelsNode);
147
- const baseModels = Object.keys(modelsNode).filter(Boolean);
148
- if (normalizedProvider.compatibilityProfile !== 'chat:deepseek-web') {
149
- return { declared: modelsDeclared, models: baseModels };
150
- }
151
- const withAliases = new Set(baseModels);
152
- const hasChatBase = withAliases.has('deepseek-chat') || withAliases.has('deepseek-v3');
153
- const hasReasonerBase = withAliases.has('deepseek-reasoner') || withAliases.has('deepseek-r1');
154
- if (hasChatBase) {
155
- withAliases.add('deepseek-chat-search');
156
- withAliases.add('deepseek-v3-search');
157
- }
158
- if (hasReasonerBase) {
159
- withAliases.add('deepseek-reasoner-search');
160
- withAliases.add('deepseek-r1-search');
147
+ const collected = new Set();
148
+ for (const [modelName, modelConfigRaw] of Object.entries(modelsNode)) {
149
+ const normalizedModelName = typeof modelName === 'string' ? modelName.trim() : '';
150
+ if (normalizedModelName) {
151
+ collected.add(normalizedModelName);
152
+ }
153
+ const modelConfig = asRecord(modelConfigRaw);
154
+ const aliasesNode = Array.isArray(modelConfig.aliases)
155
+ ? modelConfig.aliases
156
+ : [];
157
+ for (const alias of aliasesNode) {
158
+ if (typeof alias !== 'string') {
159
+ continue;
160
+ }
161
+ const normalizedAlias = alias.trim();
162
+ if (normalizedAlias) {
163
+ collected.add(normalizedAlias);
164
+ }
165
+ }
161
166
  }
162
- return { declared: modelsDeclared, models: Array.from(withAliases) };
167
+ return { declared: modelsDeclared, models: Array.from(collected) };
163
168
  }
164
169
  function normalizeClassifier(input) {
165
170
  const normalized = asRecord(input);
@@ -91,7 +91,7 @@ export function hasLatestUserRoutingInstructionMarker(messages) {
91
91
  continue;
92
92
  }
93
93
  if (message.role !== 'user') {
94
- return false;
94
+ continue;
95
95
  }
96
96
  const content = extractMessageText(message);
97
97
  if (!content) {
@@ -0,0 +1,6 @@
1
+ export declare function normalizeResponsePayloadWithNative(payload: Record<string, unknown>, config?: Record<string, unknown>): Record<string, unknown>;
2
+ export declare function validateResponsePayloadWithNative(payload: Record<string, unknown>): void;
3
+ export declare function applyRequestRulesWithNative(payload: Record<string, unknown>, config?: Record<string, unknown>): Record<string, unknown>;
4
+ export declare function applyResponseBlacklistWithNative(payload: Record<string, unknown>, config?: Record<string, unknown>): Record<string, unknown>;
5
+ export declare function normalizeToolCallIdsWithNative(payload: Record<string, unknown>): Record<string, unknown>;
6
+ export declare function enforceLmstudioResponsesFcToolCallIdsWithNative(payload: Record<string, unknown>): Record<string, unknown>;
@@ -0,0 +1,171 @@
1
+ import { failNativeRequired, isNativeDisabledByEnv } from './native-router-hotpath-policy.js';
2
+ import { loadNativeRouterHotpathBindingForInternalUse } from './native-router-hotpath.js';
3
+ function readNativeFunction(name) {
4
+ const binding = loadNativeRouterHotpathBindingForInternalUse();
5
+ const fn = binding?.[name];
6
+ return typeof fn === 'function' ? fn : null;
7
+ }
8
+ function safeStringify(value) {
9
+ try {
10
+ return JSON.stringify(value);
11
+ }
12
+ catch {
13
+ return undefined;
14
+ }
15
+ }
16
+ function parseRecord(raw) {
17
+ try {
18
+ const parsed = JSON.parse(raw);
19
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
20
+ return null;
21
+ }
22
+ return parsed;
23
+ }
24
+ catch {
25
+ return null;
26
+ }
27
+ }
28
+ export function normalizeResponsePayloadWithNative(payload, config) {
29
+ const capability = 'normalizeResponsePayloadJson';
30
+ const fail = (reason) => failNativeRequired(capability, reason);
31
+ if (isNativeDisabledByEnv()) {
32
+ return fail('native disabled');
33
+ }
34
+ const fn = readNativeFunction(capability);
35
+ if (!fn) {
36
+ return fail();
37
+ }
38
+ const payloadJson = safeStringify(payload);
39
+ const configJson = config ? safeStringify(config) : '{}';
40
+ if (!payloadJson || !configJson) {
41
+ return fail('json stringify failed');
42
+ }
43
+ try {
44
+ const raw = fn(payloadJson, configJson);
45
+ if (typeof raw !== 'string' || !raw) {
46
+ return fail('empty result');
47
+ }
48
+ const parsed = parseRecord(raw);
49
+ return parsed ?? fail('invalid payload');
50
+ }
51
+ catch (error) {
52
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
53
+ return fail(reason);
54
+ }
55
+ }
56
+ export function validateResponsePayloadWithNative(payload) {
57
+ const capability = 'validateResponsePayloadJson';
58
+ const fail = (reason) => failNativeRequired(capability, reason);
59
+ if (isNativeDisabledByEnv()) {
60
+ return fail('native disabled');
61
+ }
62
+ const fn = readNativeFunction(capability);
63
+ if (!fn) {
64
+ return fail();
65
+ }
66
+ const payloadJson = safeStringify(payload);
67
+ if (!payloadJson) {
68
+ return fail('json stringify failed');
69
+ }
70
+ try {
71
+ fn(payloadJson);
72
+ }
73
+ catch (error) {
74
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
75
+ throw new Error(reason);
76
+ }
77
+ }
78
+ export function applyRequestRulesWithNative(payload, config) {
79
+ const capability = 'applyRequestRulesJson';
80
+ const fail = (reason) => failNativeRequired(capability, reason);
81
+ if (isNativeDisabledByEnv())
82
+ return fail('native disabled');
83
+ const fn = readNativeFunction(capability);
84
+ if (!fn)
85
+ return fail();
86
+ const payloadJson = safeStringify(payload);
87
+ const configJson = config ? safeStringify(config) : '{}';
88
+ if (!payloadJson || !configJson)
89
+ return fail('json stringify failed');
90
+ try {
91
+ const raw = fn(payloadJson, configJson);
92
+ if (typeof raw !== 'string' || !raw)
93
+ return fail('empty result');
94
+ const parsed = parseRecord(raw);
95
+ return parsed ?? fail('invalid payload');
96
+ }
97
+ catch (error) {
98
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
99
+ return fail(reason);
100
+ }
101
+ }
102
+ export function applyResponseBlacklistWithNative(payload, config) {
103
+ const capability = 'applyResponseBlacklistJson';
104
+ const fail = (reason) => failNativeRequired(capability, reason);
105
+ if (isNativeDisabledByEnv())
106
+ return fail('native disabled');
107
+ const fn = readNativeFunction(capability);
108
+ if (!fn)
109
+ return fail();
110
+ const payloadJson = safeStringify(payload);
111
+ const configJson = config ? safeStringify(config) : '{}';
112
+ if (!payloadJson || !configJson)
113
+ return fail('json stringify failed');
114
+ try {
115
+ const raw = fn(payloadJson, configJson);
116
+ if (typeof raw !== 'string' || !raw)
117
+ return fail('empty result');
118
+ const parsed = parseRecord(raw);
119
+ return parsed ?? fail('invalid payload');
120
+ }
121
+ catch (error) {
122
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
123
+ return fail(reason);
124
+ }
125
+ }
126
+ export function normalizeToolCallIdsWithNative(payload) {
127
+ const capability = 'normalizeToolCallIdsJson';
128
+ const fail = (reason) => failNativeRequired(capability, reason);
129
+ if (isNativeDisabledByEnv())
130
+ return fail('native disabled');
131
+ const fn = readNativeFunction(capability);
132
+ if (!fn)
133
+ return fail();
134
+ const payloadJson = safeStringify(payload);
135
+ if (!payloadJson)
136
+ return fail('json stringify failed');
137
+ try {
138
+ const raw = fn(payloadJson);
139
+ if (typeof raw !== 'string' || !raw)
140
+ return fail('empty result');
141
+ const parsed = parseRecord(raw);
142
+ return parsed ?? fail('invalid payload');
143
+ }
144
+ catch (error) {
145
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
146
+ return fail(reason);
147
+ }
148
+ }
149
+ export function enforceLmstudioResponsesFcToolCallIdsWithNative(payload) {
150
+ const capability = 'enforceLmstudioResponsesFcToolCallIdsJson';
151
+ const fail = (reason) => failNativeRequired(capability, reason);
152
+ if (isNativeDisabledByEnv())
153
+ return fail('native disabled');
154
+ const fn = readNativeFunction(capability);
155
+ if (!fn)
156
+ return fail();
157
+ const payloadJson = safeStringify(payload);
158
+ if (!payloadJson)
159
+ return fail('json stringify failed');
160
+ try {
161
+ const raw = fn(payloadJson);
162
+ if (typeof raw !== 'string' || !raw)
163
+ return fail('empty result');
164
+ const parsed = parseRecord(raw);
165
+ return parsed ?? fail('invalid payload');
166
+ }
167
+ catch (error) {
168
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
169
+ return fail(reason);
170
+ }
171
+ }
@@ -58,6 +58,30 @@ export interface NativeApplyBridgeEnsureToolPlaceholdersOutput {
58
58
  messages: unknown[];
59
59
  toolOutputs?: Array<Record<string, unknown>>;
60
60
  }
61
+ export interface NativeBridgeInputToChatInput {
62
+ input: unknown[];
63
+ tools?: Array<Record<string, unknown>>;
64
+ toolResultFallbackText?: string;
65
+ normalizeFunctionName?: string;
66
+ }
67
+ export interface NativeBridgeInputToChatOutput {
68
+ messages: Array<Record<string, unknown>>;
69
+ }
70
+ export interface NativeCoerceBridgeRoleInput {
71
+ role: unknown;
72
+ }
73
+ export interface NativeSerializeToolArgumentsInput {
74
+ args?: unknown;
75
+ }
76
+ export interface NativeSerializeToolOutputInput {
77
+ output?: unknown;
78
+ }
79
+ export interface NativeEnsureMessagesArrayInput {
80
+ state?: unknown;
81
+ }
82
+ export interface NativeEnsureMessagesArrayOutput {
83
+ messages: Array<Record<string, unknown>>;
84
+ }
61
85
  export interface NativeEnsureBridgeOutputFieldsInput {
62
86
  messages: unknown[];
63
87
  toolFallback?: string;
@@ -137,12 +161,27 @@ export interface NativeNormalizeMessageReasoningToolsOutput {
137
161
  toolCallsAdded: number;
138
162
  cleanedReasoning?: string;
139
163
  }
164
+ export interface NativeHarvestToolsInput {
165
+ signal: Record<string, unknown>;
166
+ context?: Record<string, unknown>;
167
+ }
168
+ export interface NativeHarvestToolsOutput {
169
+ deltaEvents: Array<Record<string, unknown>>;
170
+ normalized?: Record<string, unknown>;
171
+ stats?: Record<string, unknown>;
172
+ }
140
173
  export declare function normalizeBridgeToolCallIdsWithNative(input: NativeBridgeToolCallIdsInput): NativeBridgeToolCallIdsOutput;
141
174
  export declare function applyBridgeNormalizeToolIdentifiersWithNative(input: NativeApplyBridgeNormalizeToolIdentifiersInput): NativeBridgeToolCallIdsOutput;
142
175
  export declare function buildBridgeHistoryWithNative(input: NativeBridgeHistoryInput): NativeBridgeHistoryOutput;
143
176
  export declare function applyBridgeNormalizeHistoryWithNative(input: NativeApplyBridgeNormalizeHistoryInput): NativeApplyBridgeNormalizeHistoryOutput;
144
177
  export declare function applyBridgeCaptureToolResultsWithNative(input: NativeApplyBridgeCaptureToolResultsInput): NativeApplyBridgeCaptureToolResultsOutput;
145
178
  export declare function applyBridgeEnsureToolPlaceholdersWithNative(input: NativeApplyBridgeEnsureToolPlaceholdersInput): NativeApplyBridgeEnsureToolPlaceholdersOutput;
179
+ export declare function convertBridgeInputToChatMessagesWithNative(input: NativeBridgeInputToChatInput): NativeBridgeInputToChatOutput;
180
+ export declare function coerceBridgeRoleWithNative(role: unknown): string;
181
+ export declare function serializeToolOutputWithNative(input: NativeSerializeToolOutputInput): string | null;
182
+ export declare function serializeToolArgumentsWithNative(input: NativeSerializeToolArgumentsInput): string;
183
+ export declare function ensureMessagesArrayWithNative(input: NativeEnsureMessagesArrayInput): NativeEnsureMessagesArrayOutput;
184
+ export declare function harvestToolsWithNative(input: NativeHarvestToolsInput): NativeHarvestToolsOutput;
146
185
  export declare function ensureBridgeOutputFieldsWithNative(input: NativeEnsureBridgeOutputFieldsInput): NativeEnsureBridgeOutputFieldsOutput;
147
186
  export declare function applyBridgeMetadataActionWithNative(input: NativeApplyBridgeMetadataActionInput): NativeApplyBridgeMetadataActionOutput;
148
187
  export declare function applyBridgeReasoningExtractWithNative(input: NativeApplyBridgeReasoningExtractInput): NativeApplyBridgeReasoningExtractOutput;