@jsonstudio/llms 0.6.954 → 0.6.1172
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/hub/operation-table/operation-table-runner.d.ts +18 -0
- package/dist/conversion/hub/operation-table/operation-table-runner.js +158 -0
- package/dist/conversion/hub/operation-table/semantic-mappers/anthropic-mapper.d.ts +8 -0
- package/dist/conversion/hub/operation-table/semantic-mappers/anthropic-mapper.js +303 -0
- package/dist/conversion/hub/operation-table/semantic-mappers/chat-mapper.d.ts +8 -0
- package/dist/conversion/hub/operation-table/semantic-mappers/chat-mapper.js +413 -0
- package/dist/conversion/hub/operation-table/semantic-mappers/gemini-mapper.d.ts +7 -0
- package/dist/conversion/hub/operation-table/semantic-mappers/gemini-mapper.js +841 -0
- package/dist/conversion/hub/operation-table/semantic-mappers/responses-mapper.d.ts +21 -0
- package/dist/conversion/hub/operation-table/semantic-mappers/responses-mapper.js +535 -0
- package/dist/conversion/hub/ops/operations.d.ts +19 -0
- package/dist/conversion/hub/ops/operations.js +126 -0
- package/dist/conversion/hub/pipeline/hub-pipeline.d.ts +9 -0
- package/dist/conversion/hub/pipeline/hub-pipeline.js +489 -19
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.js +6 -0
- package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage1_semantic_map/index.js +11 -0
- package/dist/conversion/hub/policy/policy-engine.js +41 -9
- package/dist/conversion/hub/policy/protocol-spec.d.ts +25 -0
- package/dist/conversion/hub/policy/protocol-spec.js +73 -23
- package/dist/conversion/hub/process/chat-process.js +252 -41
- package/dist/conversion/hub/response/provider-response.js +175 -2
- package/dist/conversion/hub/response/response-runtime.js +1 -1
- package/dist/conversion/hub/semantic-mappers/anthropic-mapper.d.ts +1 -8
- package/dist/conversion/hub/semantic-mappers/anthropic-mapper.js +1 -365
- package/dist/conversion/hub/semantic-mappers/chat-mapper.d.ts +1 -8
- package/dist/conversion/hub/semantic-mappers/chat-mapper.js +1 -467
- package/dist/conversion/hub/semantic-mappers/gemini-mapper.d.ts +1 -7
- package/dist/conversion/hub/semantic-mappers/gemini-mapper.js +1 -903
- package/dist/conversion/hub/semantic-mappers/responses-mapper.d.ts +1 -21
- package/dist/conversion/hub/semantic-mappers/responses-mapper.js +1 -593
- package/dist/conversion/hub/tool-surface/tool-surface-engine.d.ts +18 -0
- package/dist/conversion/hub/tool-surface/tool-surface-engine.js +571 -0
- package/dist/conversion/responses/responses-openai-bridge.js +14 -2
- package/dist/conversion/shared/bridge-message-utils.js +2 -8
- package/dist/conversion/shared/bridge-policies.js +5 -105
- package/dist/conversion/shared/gemini-tool-utils.js +89 -15
- package/dist/conversion/shared/protocol-field-allowlists.d.ts +7 -0
- package/dist/conversion/shared/protocol-field-allowlists.js +145 -0
- package/dist/conversion/shared/reasoning-tool-normalizer.js +4 -2
- package/dist/conversion/shared/snapshot-hooks.js +166 -3
- package/dist/conversion/shared/text-markup-normalizer.d.ts +2 -0
- package/dist/conversion/shared/text-markup-normalizer.js +345 -9
- package/dist/conversion/shared/thought-signature-validator.d.ts +52 -0
- package/dist/conversion/shared/thought-signature-validator.js +170 -0
- package/dist/conversion/shared/tool-argument-repairer.d.ts +39 -0
- package/dist/conversion/shared/tool-argument-repairer.js +56 -0
- package/dist/conversion/shared/tool-call-id-manager.d.ts +113 -0
- package/dist/conversion/shared/tool-call-id-manager.js +231 -0
- package/dist/conversion/shared/tool-canonicalizer.js +2 -11
- package/dist/router/virtual-router/bootstrap.js +70 -5
- package/dist/router/virtual-router/context-advisor.d.ts +4 -0
- package/dist/router/virtual-router/context-advisor.js +3 -0
- package/dist/router/virtual-router/context-weighted.d.ts +31 -0
- package/dist/router/virtual-router/context-weighted.js +54 -0
- package/dist/router/virtual-router/engine-selection.js +284 -47
- package/dist/router/virtual-router/engine.d.ts +3 -0
- package/dist/router/virtual-router/engine.js +142 -33
- package/dist/router/virtual-router/health-weighted.d.ts +25 -0
- package/dist/router/virtual-router/health-weighted.js +63 -0
- package/dist/router/virtual-router/load-balancer.d.ts +2 -0
- package/dist/router/virtual-router/load-balancer.js +45 -16
- package/dist/router/virtual-router/routing-instructions.js +17 -1
- package/dist/router/virtual-router/sticky-session-store.js +136 -24
- package/dist/router/virtual-router/stop-message-file-resolver.d.ts +1 -0
- package/dist/router/virtual-router/stop-message-file-resolver.js +74 -0
- package/dist/router/virtual-router/stop-message-state-sync.d.ts +15 -0
- package/dist/router/virtual-router/stop-message-state-sync.js +57 -0
- package/dist/router/virtual-router/types.d.ts +98 -0
- package/dist/servertool/clock/config.d.ts +7 -0
- package/dist/servertool/clock/config.js +27 -0
- package/dist/servertool/clock/daemon.d.ts +3 -0
- package/dist/servertool/clock/daemon.js +79 -0
- package/dist/servertool/clock/io.d.ts +2 -0
- package/dist/servertool/clock/io.js +13 -0
- package/dist/servertool/clock/paths.d.ts +4 -0
- package/dist/servertool/clock/paths.js +25 -0
- package/dist/servertool/clock/session-store.d.ts +3 -0
- package/dist/servertool/clock/session-store.js +56 -0
- package/dist/servertool/clock/state.d.ts +5 -0
- package/dist/servertool/clock/state.js +62 -0
- package/dist/servertool/clock/task-store.d.ts +5 -0
- package/dist/servertool/clock/task-store.js +4 -0
- package/dist/servertool/clock/tasks.d.ts +17 -0
- package/dist/servertool/clock/tasks.js +221 -0
- package/dist/servertool/clock/types.d.ts +36 -0
- package/dist/servertool/clock/types.js +1 -0
- package/dist/servertool/engine.d.ts +2 -0
- package/dist/servertool/engine.js +161 -7
- package/dist/servertool/followup-shadow.d.ts +16 -0
- package/dist/servertool/followup-shadow.js +145 -0
- package/dist/servertool/handlers/apply-patch-guard.js +1 -265
- package/dist/servertool/handlers/clock-auto.d.ts +1 -0
- package/dist/servertool/handlers/clock-auto.js +160 -0
- package/dist/servertool/handlers/clock.d.ts +1 -0
- package/dist/servertool/handlers/clock.js +197 -0
- package/dist/servertool/handlers/exec-command-guard.js +7 -555
- package/dist/servertool/handlers/followup-request-builder.d.ts +15 -7
- package/dist/servertool/handlers/followup-request-builder.js +248 -28
- package/dist/servertool/handlers/gemini-empty-reply-continue.js +62 -169
- package/dist/servertool/handlers/iflow-model-error-retry.js +18 -28
- package/dist/servertool/handlers/recursive-detection-guard.d.ts +1 -0
- package/dist/servertool/handlers/recursive-detection-guard.js +333 -0
- package/dist/servertool/handlers/stop-message-auto.js +47 -175
- package/dist/servertool/handlers/vision.d.ts +7 -1
- package/dist/servertool/handlers/vision.js +61 -117
- package/dist/servertool/handlers/web-search.d.ts +7 -1
- package/dist/servertool/handlers/web-search.js +122 -105
- package/dist/servertool/reenter-backend.d.ts +23 -0
- package/dist/servertool/reenter-backend.js +18 -0
- package/dist/servertool/server-side-tools.d.ts +3 -2
- package/dist/servertool/server-side-tools.js +64 -10
- package/dist/servertool/types.d.ts +92 -3
- package/dist/sse/json-to-sse/event-generators/responses.js +3 -21
- package/dist/sse/shared/serializers/responses-event-serializer.d.ts +8 -0
- package/dist/sse/shared/serializers/responses-event-serializer.js +19 -0
- package/dist/sse/shared/writer.js +24 -7
- package/dist/tools/apply-patch/execution-capturer.js +3 -1
- package/dist/tools/apply-patch/json/parse-loose.d.ts +3 -0
- package/dist/tools/apply-patch/json/parse-loose.js +139 -0
- package/dist/tools/apply-patch/patch-text/context-diff.d.ts +1 -0
- package/dist/tools/apply-patch/patch-text/context-diff.js +173 -0
- package/dist/tools/apply-patch/patch-text/git-diff.d.ts +1 -0
- package/dist/tools/apply-patch/patch-text/git-diff.js +138 -0
- package/dist/tools/apply-patch/patch-text/looks-like-patch.d.ts +1 -0
- package/dist/tools/apply-patch/patch-text/looks-like-patch.js +13 -0
- package/dist/tools/apply-patch/patch-text/normalize.d.ts +3 -0
- package/dist/tools/apply-patch/patch-text/normalize.js +262 -0
- package/dist/tools/apply-patch/structured/coercion.d.ts +3 -0
- package/dist/tools/apply-patch/structured/coercion.js +82 -0
- package/dist/tools/apply-patch/validation/shared.d.ts +3 -0
- package/dist/tools/apply-patch/validation/shared.js +6 -0
- package/dist/tools/apply-patch/validator.d.ts +2 -2
- package/dist/tools/apply-patch/validator.js +6 -556
- package/package.json +1 -1
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { getServerToolHandler, listAutoServerToolHandlers } from './registry.js';
|
|
2
2
|
import { ProviderProtocolError } from '../conversion/shared/errors.js';
|
|
3
|
-
import './handlers/web-search.js';
|
|
4
|
-
import './handlers/vision.js';
|
|
3
|
+
import { executeWebSearchBackendPlan } from './handlers/web-search.js';
|
|
4
|
+
import { executeVisionBackendPlan } from './handlers/vision.js';
|
|
5
5
|
import './handlers/iflow-model-error-retry.js';
|
|
6
6
|
import './handlers/gemini-empty-reply-continue.js';
|
|
7
7
|
import './handlers/stop-message-auto.js';
|
|
8
|
+
import './handlers/clock.js';
|
|
9
|
+
import './handlers/clock-auto.js';
|
|
8
10
|
import './handlers/exec-command-guard.js';
|
|
9
11
|
import './handlers/apply-patch-guard.js';
|
|
12
|
+
import './handlers/recursive-detection-guard.js';
|
|
10
13
|
export async function runServerSideToolEngine(options) {
|
|
11
14
|
const base = asObject(options.chatResponse);
|
|
12
15
|
if (!base) {
|
|
@@ -20,14 +23,21 @@ export async function runServerSideToolEngine(options) {
|
|
|
20
23
|
base,
|
|
21
24
|
toolCalls,
|
|
22
25
|
adapterContext: options.adapterContext,
|
|
23
|
-
options
|
|
26
|
+
requestId: options.requestId,
|
|
27
|
+
entryEndpoint: options.entryEndpoint,
|
|
28
|
+
providerProtocol: options.providerProtocol,
|
|
29
|
+
capabilities: {
|
|
30
|
+
reenterPipeline: typeof options.reenterPipeline === 'function',
|
|
31
|
+
providerInvoker: typeof options.providerInvoker === 'function'
|
|
32
|
+
}
|
|
24
33
|
};
|
|
25
34
|
for (const toolCall of toolCalls) {
|
|
26
35
|
const entry = getServerToolHandler(toolCall.name);
|
|
27
36
|
if (!entry || entry.trigger !== 'tool_call')
|
|
28
37
|
continue;
|
|
29
38
|
const ctx = { ...contextBase, toolCall };
|
|
30
|
-
const
|
|
39
|
+
const planned = await runHandler(entry.handler, ctx);
|
|
40
|
+
const result = planned ? await materializePlannedResult(planned, options) : null;
|
|
31
41
|
if (result) {
|
|
32
42
|
return {
|
|
33
43
|
mode: 'tool_flow',
|
|
@@ -37,7 +47,8 @@ export async function runServerSideToolEngine(options) {
|
|
|
37
47
|
}
|
|
38
48
|
}
|
|
39
49
|
for (const entry of listAutoServerToolHandlers()) {
|
|
40
|
-
const
|
|
50
|
+
const planned = await runHandler(entry.handler, contextBase);
|
|
51
|
+
const result = planned ? await materializePlannedResult(planned, options) : null;
|
|
41
52
|
if (result) {
|
|
42
53
|
return {
|
|
43
54
|
mode: 'tool_flow',
|
|
@@ -62,9 +73,9 @@ async function runHandler(handler, ctx) {
|
|
|
62
73
|
category: 'INTERNAL_ERROR',
|
|
63
74
|
details: {
|
|
64
75
|
toolName,
|
|
65
|
-
requestId: ctx.
|
|
66
|
-
entryEndpoint: ctx.
|
|
67
|
-
providerProtocol: ctx.
|
|
76
|
+
requestId: ctx.requestId,
|
|
77
|
+
entryEndpoint: ctx.entryEndpoint,
|
|
78
|
+
providerProtocol: ctx.providerProtocol,
|
|
68
79
|
error: message
|
|
69
80
|
}
|
|
70
81
|
});
|
|
@@ -73,6 +84,27 @@ async function runHandler(handler, ctx) {
|
|
|
73
84
|
throw wrapped;
|
|
74
85
|
}
|
|
75
86
|
}
|
|
87
|
+
async function materializePlannedResult(planned, options) {
|
|
88
|
+
if (planned && typeof planned === 'object' && !Array.isArray(planned) && typeof planned.finalize === 'function') {
|
|
89
|
+
const plan = planned;
|
|
90
|
+
const backendResult = plan.backend ? await executeBackendPlan(plan.backend, options) : undefined;
|
|
91
|
+
return await plan.finalize({ ...(backendResult ? { backendResult } : {}) });
|
|
92
|
+
}
|
|
93
|
+
return planned;
|
|
94
|
+
}
|
|
95
|
+
async function executeBackendPlan(plan, options) {
|
|
96
|
+
if (!plan)
|
|
97
|
+
return undefined;
|
|
98
|
+
if (plan.kind === 'vision_analysis') {
|
|
99
|
+
if (!options.reenterPipeline)
|
|
100
|
+
return undefined;
|
|
101
|
+
return await executeVisionBackendPlan({ plan, options });
|
|
102
|
+
}
|
|
103
|
+
if (plan.kind === 'web_search') {
|
|
104
|
+
return await executeWebSearchBackendPlan({ plan, options });
|
|
105
|
+
}
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
76
108
|
export function extractToolCalls(chatResponse) {
|
|
77
109
|
const choices = getArray(chatResponse.choices);
|
|
78
110
|
const calls = [];
|
|
@@ -89,9 +121,31 @@ export function extractToolCalls(chatResponse) {
|
|
|
89
121
|
if (!tc)
|
|
90
122
|
continue;
|
|
91
123
|
const id = typeof tc.id === 'string' && tc.id.trim() ? tc.id.trim() : '';
|
|
92
|
-
const fn = asObject(tc.function)
|
|
124
|
+
const fn = asObject(tc.function) ??
|
|
125
|
+
asObject(tc.functionCall) ??
|
|
126
|
+
asObject(tc.function_call);
|
|
93
127
|
const name = fn && typeof fn.name === 'string' && fn.name.trim() ? fn.name.trim() : '';
|
|
94
|
-
const
|
|
128
|
+
const rawArgs = (fn ? fn.arguments : undefined) ??
|
|
129
|
+
(fn ? fn.args : undefined) ??
|
|
130
|
+
(fn ? fn.input : undefined) ??
|
|
131
|
+
tc.arguments ??
|
|
132
|
+
tc.args ??
|
|
133
|
+
tc.input;
|
|
134
|
+
let args = '';
|
|
135
|
+
if (typeof rawArgs === 'string') {
|
|
136
|
+
args = rawArgs;
|
|
137
|
+
}
|
|
138
|
+
else if (rawArgs && typeof rawArgs === 'object') {
|
|
139
|
+
try {
|
|
140
|
+
args = JSON.stringify(rawArgs);
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
args = '';
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else if (rawArgs !== undefined && rawArgs !== null) {
|
|
147
|
+
args = String(rawArgs);
|
|
148
|
+
}
|
|
95
149
|
if (!id || !name)
|
|
96
150
|
continue;
|
|
97
151
|
calls.push({ id, name, arguments: args });
|
|
@@ -49,11 +49,94 @@ export interface ServerSideToolEngineOptions {
|
|
|
49
49
|
format?: string;
|
|
50
50
|
}>;
|
|
51
51
|
}
|
|
52
|
-
export
|
|
52
|
+
export type ServerToolFollowupInjectionOp = {
|
|
53
|
+
op: 'append_assistant_message';
|
|
54
|
+
required?: boolean;
|
|
55
|
+
} | {
|
|
56
|
+
op: 'append_tool_messages_from_tool_outputs';
|
|
57
|
+
required?: boolean;
|
|
58
|
+
} | {
|
|
59
|
+
op: 'inject_system_text';
|
|
60
|
+
text: string;
|
|
61
|
+
} | {
|
|
62
|
+
op: 'append_user_text';
|
|
63
|
+
text: string;
|
|
64
|
+
} | {
|
|
65
|
+
op: 'drop_tool_by_name';
|
|
66
|
+
name: string;
|
|
67
|
+
} | {
|
|
68
|
+
op: 'inject_vision_summary';
|
|
69
|
+
summary: string;
|
|
70
|
+
} | {
|
|
71
|
+
op: 'trim_openai_messages';
|
|
72
|
+
maxNonSystemMessages: number;
|
|
73
|
+
};
|
|
74
|
+
export type ServerToolFollowupInjectionPlan = {
|
|
75
|
+
ops: ServerToolFollowupInjectionOp[];
|
|
76
|
+
};
|
|
77
|
+
export type ServerToolFollowupPlan = {
|
|
53
78
|
requestIdSuffix: string;
|
|
54
79
|
payload: JsonObject;
|
|
55
80
|
metadata?: JsonObject;
|
|
56
81
|
entryEndpoint?: string;
|
|
82
|
+
} | {
|
|
83
|
+
requestIdSuffix: string;
|
|
84
|
+
injection: ServerToolFollowupInjectionPlan;
|
|
85
|
+
metadata?: JsonObject;
|
|
86
|
+
entryEndpoint?: string;
|
|
87
|
+
};
|
|
88
|
+
export type ServerToolBackendPlan = {
|
|
89
|
+
kind: 'vision_analysis';
|
|
90
|
+
requestIdSuffix: string;
|
|
91
|
+
entryEndpoint: string;
|
|
92
|
+
payload: JsonObject;
|
|
93
|
+
} | {
|
|
94
|
+
kind: 'web_search';
|
|
95
|
+
requestIdSuffix: string;
|
|
96
|
+
query: string;
|
|
97
|
+
recency?: string;
|
|
98
|
+
resultCount: number;
|
|
99
|
+
engines: {
|
|
100
|
+
id: string;
|
|
101
|
+
providerKey: string;
|
|
102
|
+
description?: string;
|
|
103
|
+
default?: boolean;
|
|
104
|
+
serverToolsDisabled?: boolean;
|
|
105
|
+
searchEngineList?: string[];
|
|
106
|
+
}[];
|
|
107
|
+
};
|
|
108
|
+
export type ServerToolBackendResult = {
|
|
109
|
+
kind: 'vision_analysis';
|
|
110
|
+
response: {
|
|
111
|
+
body?: JsonObject;
|
|
112
|
+
__sse_responses?: unknown;
|
|
113
|
+
format?: string;
|
|
114
|
+
};
|
|
115
|
+
} | {
|
|
116
|
+
kind: 'web_search';
|
|
117
|
+
chosenEngine?: {
|
|
118
|
+
id: string;
|
|
119
|
+
providerKey: string;
|
|
120
|
+
};
|
|
121
|
+
result: {
|
|
122
|
+
ok: boolean;
|
|
123
|
+
summary: string;
|
|
124
|
+
hits: {
|
|
125
|
+
title?: string;
|
|
126
|
+
link: string;
|
|
127
|
+
media?: string;
|
|
128
|
+
publish_date?: string;
|
|
129
|
+
content?: string;
|
|
130
|
+
refer?: string;
|
|
131
|
+
}[];
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
export interface ServerToolHandlerPlan {
|
|
135
|
+
flowId: string;
|
|
136
|
+
backend?: ServerToolBackendPlan;
|
|
137
|
+
finalize: (args: {
|
|
138
|
+
backendResult?: ServerToolBackendResult;
|
|
139
|
+
}) => Promise<ServerToolHandlerResult | null>;
|
|
57
140
|
}
|
|
58
141
|
export interface ServerToolExecution {
|
|
59
142
|
flowId: string;
|
|
@@ -81,7 +164,13 @@ export interface ServerToolHandlerContext {
|
|
|
81
164
|
toolCall?: ToolCall;
|
|
82
165
|
toolCalls: ToolCall[];
|
|
83
166
|
adapterContext: AdapterContext;
|
|
84
|
-
|
|
167
|
+
requestId: string;
|
|
168
|
+
entryEndpoint: string;
|
|
169
|
+
providerProtocol: string;
|
|
170
|
+
capabilities: {
|
|
171
|
+
reenterPipeline: boolean;
|
|
172
|
+
providerInvoker: boolean;
|
|
173
|
+
};
|
|
85
174
|
}
|
|
86
175
|
export interface ServerToolHandlerResult {
|
|
87
176
|
chatResponse: JsonObject;
|
|
@@ -91,5 +180,5 @@ export interface ServerToolHandlerResult {
|
|
|
91
180
|
* ServerToolHandler:统一的 ServerTool handler 接口。
|
|
92
181
|
* 后续 web_search / vision / 其它工具都会以 handler 形式挂载到注册表。
|
|
93
182
|
*/
|
|
94
|
-
export type ServerToolHandler = (ctx: ServerToolHandlerContext) => Promise<
|
|
183
|
+
export type ServerToolHandler = (ctx: ServerToolHandlerContext) => Promise<ServerToolHandlerPlan | null>;
|
|
95
184
|
export type { JsonObject, JsonValue } from '../conversion/hub/types/json.js';
|
|
@@ -512,30 +512,12 @@ export function buildReasoningDoneEvent(reasoning, context, config = DEFAULT_RES
|
|
|
512
512
|
*/
|
|
513
513
|
export function buildOutputItemDoneEvent(outputItem, context, config = DEFAULT_RESPONSES_EVENT_GENERATOR_CONFIG) {
|
|
514
514
|
const baseEvent = createBaseEvent(context, config);
|
|
515
|
+
// NOTE: Codex CLI expects `output_item.done` to contain a fully-formed output item
|
|
516
|
+
// (e.g. message includes role/content). A minimal `{id,type,status}` breaks parsing.
|
|
515
517
|
const itemDescriptor = {
|
|
516
|
-
|
|
517
|
-
type: outputItem.type,
|
|
518
|
+
...outputItem,
|
|
518
519
|
status: 'completed'
|
|
519
520
|
};
|
|
520
|
-
if (outputItem.name) {
|
|
521
|
-
itemDescriptor.name = outputItem.name;
|
|
522
|
-
}
|
|
523
|
-
if (outputItem.arguments) {
|
|
524
|
-
itemDescriptor.arguments = outputItem.arguments;
|
|
525
|
-
}
|
|
526
|
-
if (outputItem.call_id) {
|
|
527
|
-
itemDescriptor.call_id = outputItem.call_id;
|
|
528
|
-
}
|
|
529
|
-
if (outputItem.type === 'function_call_output') {
|
|
530
|
-
const result = outputItem;
|
|
531
|
-
if (result.call_id) {
|
|
532
|
-
itemDescriptor.call_id = result.call_id;
|
|
533
|
-
}
|
|
534
|
-
if (result.tool_call_id) {
|
|
535
|
-
itemDescriptor.tool_call_id = result.tool_call_id;
|
|
536
|
-
}
|
|
537
|
-
itemDescriptor.output = result.output;
|
|
538
|
-
}
|
|
539
521
|
return {
|
|
540
522
|
type: 'response.output_item.done',
|
|
541
523
|
timestamp: baseEvent.timestamp,
|
|
@@ -55,6 +55,14 @@ export declare class ResponsesEventSerializer implements EventSerializer<Respons
|
|
|
55
55
|
* 序列化response.output_item.done事件
|
|
56
56
|
*/
|
|
57
57
|
private serializeOutputItemDone;
|
|
58
|
+
/**
|
|
59
|
+
* 序列化response.output_text.delta事件
|
|
60
|
+
*/
|
|
61
|
+
private serializeOutputTextDelta;
|
|
62
|
+
/**
|
|
63
|
+
* 序列化response.output_text.done事件
|
|
64
|
+
*/
|
|
65
|
+
private serializeOutputTextDone;
|
|
58
66
|
/**
|
|
59
67
|
* 序列化response.function_call_arguments.delta事件
|
|
60
68
|
*/
|
|
@@ -28,6 +28,10 @@ export class ResponsesEventSerializer {
|
|
|
28
28
|
return this.serializeOutputItemAdded(event);
|
|
29
29
|
case 'response.output_item.done':
|
|
30
30
|
return this.serializeOutputItemDone(event);
|
|
31
|
+
case 'response.output_text.delta':
|
|
32
|
+
return this.serializeOutputTextDelta(event);
|
|
33
|
+
case 'response.output_text.done':
|
|
34
|
+
return this.serializeOutputTextDone(event);
|
|
31
35
|
case 'response.function_call_arguments.delta':
|
|
32
36
|
return this.serializeFunctionCallArgumentsDelta(event);
|
|
33
37
|
case 'response.function_call_arguments.done':
|
|
@@ -43,6 +47,9 @@ export class ResponsesEventSerializer {
|
|
|
43
47
|
case 'response.cancelled':
|
|
44
48
|
return this.serializeResponseCancelled(event);
|
|
45
49
|
default:
|
|
50
|
+
if (typeof event.type === 'string' && event.type.startsWith('response.')) {
|
|
51
|
+
return this.buildSSEEvent(event.type, event.data, event.timestamp, event.sequenceNumber);
|
|
52
|
+
}
|
|
46
53
|
throw new Error(`Unsupported ResponsesSseEvent type: ${event.type}`);
|
|
47
54
|
}
|
|
48
55
|
}
|
|
@@ -159,6 +166,18 @@ export class ResponsesEventSerializer {
|
|
|
159
166
|
serializeOutputItemDone(event) {
|
|
160
167
|
return this.buildSSEEvent('response.output_item.done', event.data, event.timestamp, event.sequenceNumber);
|
|
161
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* 序列化response.output_text.delta事件
|
|
171
|
+
*/
|
|
172
|
+
serializeOutputTextDelta(event) {
|
|
173
|
+
return this.buildSSEEvent('response.output_text.delta', event.data, event.timestamp, event.sequenceNumber);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* 序列化response.output_text.done事件
|
|
177
|
+
*/
|
|
178
|
+
serializeOutputTextDone(event) {
|
|
179
|
+
return this.buildSSEEvent('response.output_text.done', event.data, event.timestamp, event.sequenceNumber);
|
|
180
|
+
}
|
|
162
181
|
/**
|
|
163
182
|
* 序列化response.function_call_arguments.delta事件
|
|
164
183
|
*/
|
|
@@ -156,14 +156,31 @@ export class StreamWriter {
|
|
|
156
156
|
catch {
|
|
157
157
|
// ignore and fallback
|
|
158
158
|
}
|
|
159
|
+
const eventType = String(event.type ?? 'response.unknown');
|
|
159
160
|
const rawData = event.data;
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
161
|
+
const timestamp = typeof event.timestamp === 'number' ? event.timestamp : undefined;
|
|
162
|
+
const sequenceNumber = typeof event.sequenceNumber === 'number' ? event.sequenceNumber : undefined;
|
|
163
|
+
let wire = `event: ${eventType}\n`;
|
|
164
|
+
if (rawData === '[DONE]') {
|
|
165
|
+
wire += 'data: [DONE]\n';
|
|
166
|
+
}
|
|
167
|
+
else if (typeof rawData === 'string') {
|
|
168
|
+
wire += `data: ${rawData}\n`;
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
const payload = rawData && typeof rawData === 'object' ? { ...rawData } : {};
|
|
172
|
+
if (!Object.prototype.hasOwnProperty.call(payload, 'type'))
|
|
173
|
+
payload.type = eventType;
|
|
174
|
+
if (sequenceNumber !== undefined && !Object.prototype.hasOwnProperty.call(payload, 'sequence_number')) {
|
|
175
|
+
payload.sequence_number = sequenceNumber;
|
|
176
|
+
}
|
|
177
|
+
wire += `data: ${JSON.stringify(payload)}\n`;
|
|
178
|
+
}
|
|
179
|
+
if (timestamp !== undefined) {
|
|
180
|
+
wire += `id: ${timestamp}\n`;
|
|
181
|
+
}
|
|
182
|
+
wire += '\n';
|
|
183
|
+
return wire;
|
|
167
184
|
}
|
|
168
185
|
/**
|
|
169
186
|
* 异步写入事件流
|
|
@@ -112,6 +112,8 @@ export function captureApplyPatchExecutionFailuresFromProcessedRequest(processed
|
|
|
112
112
|
const entryEndpoint = typeof metadata?.originalEndpoint === 'string' ? metadata.originalEndpoint : undefined;
|
|
113
113
|
const providerKey = typeof metadata?.providerKey === 'string' ? metadata.providerKey : undefined;
|
|
114
114
|
const model = typeof anyReq?.model === 'string' ? anyReq.model : undefined;
|
|
115
|
+
const applyPatchToolMode = typeof metadata?.applyPatchToolMode === 'string' ? String(metadata.applyPatchToolMode).trim().toLowerCase() : '';
|
|
116
|
+
const resolvedMode = applyPatchToolMode === 'schema' ? 'schema' : 'freeform';
|
|
115
117
|
const toolCallArgsById = new Map();
|
|
116
118
|
for (const msg of messages) {
|
|
117
119
|
if (!msg || typeof msg !== 'object')
|
|
@@ -146,7 +148,7 @@ export function captureApplyPatchExecutionFailuresFromProcessedRequest(processed
|
|
|
146
148
|
providerKey,
|
|
147
149
|
model,
|
|
148
150
|
source: 'req_process_stage1_tool_governance',
|
|
149
|
-
meta: { applyPatchToolMode:
|
|
151
|
+
meta: { applyPatchToolMode: resolvedMode },
|
|
150
152
|
toolCallId,
|
|
151
153
|
toolCallArgs
|
|
152
154
|
});
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
const tryParseJson = (value) => {
|
|
2
|
+
if (typeof value !== 'string')
|
|
3
|
+
return undefined;
|
|
4
|
+
const trimmed = value.trim();
|
|
5
|
+
if (!trimmed)
|
|
6
|
+
return undefined;
|
|
7
|
+
if (!(trimmed.startsWith('{') || trimmed.startsWith('[')))
|
|
8
|
+
return undefined;
|
|
9
|
+
try {
|
|
10
|
+
return JSON.parse(trimmed);
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
const escapeUnescapedQuotesInJsonStrings = (input) => {
|
|
17
|
+
// Best-effort: when JSON is almost valid but contains unescaped `"` inside string values
|
|
18
|
+
// (e.g. JSX snippets like className="..."), escape quotes that are not followed by a
|
|
19
|
+
// valid JSON token delimiter. Deterministic; does not attempt to fix structural issues.
|
|
20
|
+
let out = '';
|
|
21
|
+
let inString = false;
|
|
22
|
+
let escaped = false;
|
|
23
|
+
for (let i = 0; i < input.length; i += 1) {
|
|
24
|
+
const ch = input[i] ?? '';
|
|
25
|
+
if (!inString) {
|
|
26
|
+
if (ch === '"') {
|
|
27
|
+
inString = true;
|
|
28
|
+
escaped = false;
|
|
29
|
+
}
|
|
30
|
+
out += ch;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (escaped) {
|
|
34
|
+
out += ch;
|
|
35
|
+
escaped = false;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (ch === '\\') {
|
|
39
|
+
out += ch;
|
|
40
|
+
escaped = true;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (ch === '"') {
|
|
44
|
+
let j = i + 1;
|
|
45
|
+
while (j < input.length && /\s/.test(input[j] ?? ''))
|
|
46
|
+
j += 1;
|
|
47
|
+
const next = j < input.length ? input[j] : '';
|
|
48
|
+
if (next === '' || next === ':' || next === ',' || next === '}' || next === ']') {
|
|
49
|
+
inString = false;
|
|
50
|
+
out += ch;
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
out += '\\"';
|
|
54
|
+
}
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
out += ch;
|
|
58
|
+
}
|
|
59
|
+
return out;
|
|
60
|
+
};
|
|
61
|
+
const balanceJsonContainers = (input) => {
|
|
62
|
+
// Best-effort bracket/brace balancing for JSON-like strings.
|
|
63
|
+
// Only operates outside string literals. When encountering a closing token that doesn't
|
|
64
|
+
// match the current stack top, inserts the missing closer(s) to recover.
|
|
65
|
+
let out = '';
|
|
66
|
+
let inString = false;
|
|
67
|
+
let escaped = false;
|
|
68
|
+
const stack = [];
|
|
69
|
+
const closeFor = (open) => (open === '{' ? '}' : ']');
|
|
70
|
+
for (let i = 0; i < input.length; i += 1) {
|
|
71
|
+
const ch = input[i] ?? '';
|
|
72
|
+
if (inString) {
|
|
73
|
+
out += ch;
|
|
74
|
+
if (escaped) {
|
|
75
|
+
escaped = false;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (ch === '\\') {
|
|
79
|
+
escaped = true;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (ch === '"') {
|
|
83
|
+
inString = false;
|
|
84
|
+
}
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (ch === '"') {
|
|
88
|
+
inString = true;
|
|
89
|
+
out += ch;
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (ch === '{' || ch === '[') {
|
|
93
|
+
stack.push(ch);
|
|
94
|
+
out += ch;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (ch === '}' || ch === ']') {
|
|
98
|
+
const expectedOpen = ch === '}' ? '{' : '[';
|
|
99
|
+
while (stack.length && stack[stack.length - 1] !== expectedOpen) {
|
|
100
|
+
const open = stack.pop();
|
|
101
|
+
out += closeFor(open);
|
|
102
|
+
}
|
|
103
|
+
if (stack.length && stack[stack.length - 1] === expectedOpen) {
|
|
104
|
+
stack.pop();
|
|
105
|
+
}
|
|
106
|
+
out += ch;
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
out += ch;
|
|
110
|
+
}
|
|
111
|
+
while (stack.length) {
|
|
112
|
+
const open = stack.pop();
|
|
113
|
+
out += closeFor(open);
|
|
114
|
+
}
|
|
115
|
+
return out;
|
|
116
|
+
};
|
|
117
|
+
const tryParseJsonLoose = (value) => {
|
|
118
|
+
const parsed = tryParseJson(value);
|
|
119
|
+
if (parsed !== undefined)
|
|
120
|
+
return parsed;
|
|
121
|
+
if (typeof value !== 'string')
|
|
122
|
+
return undefined;
|
|
123
|
+
const trimmed = value.trim();
|
|
124
|
+
if (!trimmed)
|
|
125
|
+
return undefined;
|
|
126
|
+
if (!(trimmed.startsWith('{') || trimmed.startsWith('[')))
|
|
127
|
+
return undefined;
|
|
128
|
+
let repaired = escapeUnescapedQuotesInJsonStrings(trimmed);
|
|
129
|
+
repaired = balanceJsonContainers(repaired);
|
|
130
|
+
if (!repaired || repaired === trimmed)
|
|
131
|
+
return undefined;
|
|
132
|
+
try {
|
|
133
|
+
return JSON.parse(repaired);
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
export { tryParseJson, tryParseJsonLoose };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const convertContextDiffToApplyPatch: (text: string) => string | null;
|