@codehz/ai 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +16 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/adapters/chat-completions.ts +1 -9
- package/src/core/aggregator.ts +18 -4
package/package.json
CHANGED
|
@@ -458,9 +458,7 @@ export class ChatCompletionsAdapter extends AdapterBase {
|
|
|
458
458
|
if (hasMessageStarted) {
|
|
459
459
|
const message = messageItem([textBlock(accumulatedContent)], { id: currentMessageId });
|
|
460
460
|
events.push(factory.messageCompleted(currentMessageId));
|
|
461
|
-
|
|
462
|
-
output.push(message);
|
|
463
|
-
}
|
|
461
|
+
output.push(message);
|
|
464
462
|
}
|
|
465
463
|
|
|
466
464
|
for (const pending of finalizedToolCalls) {
|
|
@@ -599,12 +597,6 @@ export class ChatCompletionsAdapter extends AdapterBase {
|
|
|
599
597
|
accumulatedContent = "";
|
|
600
598
|
};
|
|
601
599
|
|
|
602
|
-
// 处理 role: assistant(首块标识;不要求 content)
|
|
603
|
-
if (delta.role === "assistant" && !hasMessageStarted) {
|
|
604
|
-
ensureMessageStarted();
|
|
605
|
-
yield factory.messageStarted(currentMessageId);
|
|
606
|
-
}
|
|
607
|
-
|
|
608
600
|
// 处理 third-party reasoning delta
|
|
609
601
|
if (reasoningDeltas.length > 0) {
|
|
610
602
|
if (!hasReasoningStarted) {
|
package/src/core/aggregator.ts
CHANGED
|
@@ -78,6 +78,8 @@ export interface AggregatorState {
|
|
|
78
78
|
completed: boolean;
|
|
79
79
|
nextSequence?: number;
|
|
80
80
|
activeItems: Map<string, ActiveItem>;
|
|
81
|
+
itemOrder: string[];
|
|
82
|
+
completedItems: Map<string, OutputItem>;
|
|
81
83
|
|
|
82
84
|
/** adapter 在 response.completed 中提供的 replay */
|
|
83
85
|
replayFromAdapter?: import("../types/index.js").ReplayItem[];
|
|
@@ -96,6 +98,8 @@ export function createAggregatorState(): AggregatorState {
|
|
|
96
98
|
started: false,
|
|
97
99
|
completed: false,
|
|
98
100
|
activeItems: new Map(),
|
|
101
|
+
itemOrder: [],
|
|
102
|
+
completedItems: new Map(),
|
|
99
103
|
};
|
|
100
104
|
}
|
|
101
105
|
|
|
@@ -178,6 +182,7 @@ function handleMessageStarted(state: AggregatorState, event: AIStreamEvent & { t
|
|
|
178
182
|
role: event.item.role,
|
|
179
183
|
content: [],
|
|
180
184
|
});
|
|
185
|
+
state.itemOrder.push(id);
|
|
181
186
|
}
|
|
182
187
|
|
|
183
188
|
function handleMessageDelta(state: AggregatorState, event: AIStreamEvent & { type: "message.delta" }): void {
|
|
@@ -189,7 +194,7 @@ function handleMessageCompleted(state: AggregatorState, event: AIStreamEvent & {
|
|
|
189
194
|
const active = getActiveItem(state, event.itemId, "message") as ActiveMessage;
|
|
190
195
|
state.activeItems.delete(event.itemId);
|
|
191
196
|
const item = finalizeMessage(active);
|
|
192
|
-
state.
|
|
197
|
+
state.completedItems.set(event.itemId, item);
|
|
193
198
|
pushMessageText(state, item);
|
|
194
199
|
}
|
|
195
200
|
|
|
@@ -204,6 +209,7 @@ function handleReasoningStarted(state: AggregatorState, event: AIStreamEvent & {
|
|
|
204
209
|
visibility: event.item.visibility,
|
|
205
210
|
content: [],
|
|
206
211
|
});
|
|
212
|
+
state.itemOrder.push(id);
|
|
207
213
|
}
|
|
208
214
|
|
|
209
215
|
function handleReasoningDelta(state: AggregatorState, event: AIStreamEvent & { type: "reasoning.delta" }): void {
|
|
@@ -217,7 +223,7 @@ function handleReasoningCompleted(
|
|
|
217
223
|
): void {
|
|
218
224
|
const active = getActiveItem(state, event.itemId, "reasoning") as ActiveReasoning;
|
|
219
225
|
state.activeItems.delete(event.itemId);
|
|
220
|
-
state.
|
|
226
|
+
state.completedItems.set(event.itemId, finalizeReasoning(active));
|
|
221
227
|
}
|
|
222
228
|
|
|
223
229
|
function handleToolCallStarted(state: AggregatorState, event: AIStreamEvent & { type: "tool_call.started" }): void {
|
|
@@ -231,6 +237,7 @@ function handleToolCallStarted(state: AggregatorState, event: AIStreamEvent & {
|
|
|
231
237
|
name: event.item.name,
|
|
232
238
|
argumentsText: "",
|
|
233
239
|
});
|
|
240
|
+
state.itemOrder.push(id);
|
|
234
241
|
}
|
|
235
242
|
|
|
236
243
|
function handleToolCallDelta(state: AggregatorState, event: AIStreamEvent & { type: "tool_call.delta" }): void {
|
|
@@ -244,7 +251,7 @@ function handleToolCallCompleted(state: AggregatorState, event: AIStreamEvent &
|
|
|
244
251
|
const active = getActiveItem(state, event.itemId, "tool_call") as ActiveToolCall;
|
|
245
252
|
state.activeItems.delete(event.itemId);
|
|
246
253
|
const item = finalizeToolCall(active);
|
|
247
|
-
state.
|
|
254
|
+
state.completedItems.set(event.itemId, item);
|
|
248
255
|
state.toolCalls.push(item);
|
|
249
256
|
}
|
|
250
257
|
|
|
@@ -275,10 +282,17 @@ function buildResponse(state: AggregatorState): AIResponse {
|
|
|
275
282
|
metadataSources: backendFromCompleted?.metadataSources,
|
|
276
283
|
warnings: backendFromCompleted?.warnings,
|
|
277
284
|
};
|
|
285
|
+
const orderedOutput = state.itemOrder.map((id) => {
|
|
286
|
+
const item = state.completedItems.get(id);
|
|
287
|
+
if (!item) {
|
|
288
|
+
throw streamProtocolError(`Item ${id} was started but not completed`);
|
|
289
|
+
}
|
|
290
|
+
return item;
|
|
291
|
+
});
|
|
278
292
|
|
|
279
293
|
return {
|
|
280
294
|
id: state.responseId,
|
|
281
|
-
output: state.output,
|
|
295
|
+
output: [...orderedOutput, ...state.output],
|
|
282
296
|
replay: state.replayFromAdapter ?? [],
|
|
283
297
|
text: state.textParts.join(""),
|
|
284
298
|
toolCalls: state.toolCalls,
|