@codehz/ai 0.2.4 → 0.4.0

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/README.md CHANGED
@@ -164,19 +164,14 @@ const mock = new MockAdapter({
164
164
  });
165
165
  ```
166
166
 
167
- 公开 adapter 接口暴露稳定标识和各维度能力:
167
+ 公开 adapter 接口暴露稳定标识和流来源:
168
168
 
169
169
  ```ts
170
170
  adapter.kind; // "responses" | "messages" | "chat-completions" | ...
171
- adapter.capabilities.textStreaming; // "native" | "synthetic" | "none"
172
- adapter.capabilities.reasoningStreaming;
173
- adapter.capabilities.toolCallStreaming;
174
- adapter.capabilities.replay; // "canonical" | "opaque" | "none"
175
- adapter.capabilities.usage; // "stream" | "final" | "none"
176
- adapter.capabilities.toolResultOutcomes;
171
+ adapter.isSyntheticStream;
177
172
  ```
178
173
 
179
- 响应级 `backend.isSyntheticStream` 根据 `textStreaming === "synthetic"` 推导;具体响应内容仍应从
174
+ 响应级 `backend.isSyntheticStream` 使用同一标记;具体响应内容仍应从
180
175
  本次事件流、warning 和 `replay` 判断。
181
176
 
182
177
  ## Mock 后端
package/dist/index.d.mts CHANGED
@@ -42,7 +42,6 @@ type ToolCallItem = {
42
42
  id: string;
43
43
  name: string;
44
44
  argumentsText: string;
45
- argumentsJson?: unknown;
46
45
  };
47
46
  type ToolResultItem = {
48
47
  type: "tool_result";
@@ -234,18 +233,9 @@ type NormalizedRequest = AIRequest & {
234
233
  model: string;
235
234
  requestId: string;
236
235
  };
237
- type StreamingCapability = "native" | "synthetic" | "none";
238
- type AdapterCapabilities = {
239
- readonly textStreaming: StreamingCapability;
240
- readonly reasoningStreaming: StreamingCapability;
241
- readonly toolCallStreaming: StreamingCapability;
242
- readonly replay: "canonical" | "opaque" | "none";
243
- readonly usage: "stream" | "final" | "none";
244
- readonly toolResultOutcomes: ReadonlyArray<"success" | "error" | "rejected">;
245
- };
246
236
  interface BackendAdapter {
247
237
  readonly kind: "chat-completions" | "messages" | "responses" | "ollama" | "mock";
248
- readonly capabilities: AdapterCapabilities;
238
+ readonly isSyntheticStream: boolean;
249
239
  stream(request: NormalizedRequest): AsyncIterable<AIStreamEvent>;
250
240
  }
251
241
  type CreateAIClientOptions = {
@@ -503,7 +493,6 @@ declare function emitMalformedStreamWarning(factory: EventFactory, options: {
503
493
  providerLabel: string;
504
494
  transportLabel: string;
505
495
  }): AIStreamEvent | undefined;
506
- declare function metadataSourceList(...groups: Array<Array<NonNullable<BackendTrace["metadataSources"]>[number]> | undefined>): string[] | undefined;
507
496
  //#endregion
508
497
  //#region src/helpers/adapter-base.d.ts
509
498
  type ProviderResponse = unknown;
@@ -525,7 +514,7 @@ type StreamResult = {
525
514
  };
526
515
  declare abstract class AdapterBase implements BackendAdapter {
527
516
  abstract readonly kind: "chat-completions" | "messages" | "responses" | "ollama" | "mock";
528
- abstract readonly capabilities: AdapterCapabilities;
517
+ abstract readonly isSyntheticStream: boolean;
529
518
  /**
530
519
  * stream 模板方法:
531
520
  * 1. 创建事件工厂,发射 response.started
@@ -550,8 +539,11 @@ declare abstract class AdapterBase implements BackendAdapter {
550
539
  * 子类可在返回前自定义覆盖。
551
540
  */
552
541
  protected buildResponse(request: NormalizedRequest, result: StreamResult, _factory: EventFactory): AIResponse;
553
- /** 从 output items 中提取文本内容。 */
554
- protected extractText(output: OutputItem[]): string;
542
+ /**
543
+ * 统一 finalize auxiliary → response.completed。
544
+ * adapter 在调用前组装 output / replay / stopReason 等业务字段。
545
+ */
546
+ protected emitStreamCompleted(factory: EventFactory, request: NormalizedRequest, auxiliary: AdapterAuxiliaryState, result: StreamResult): AsyncIterable<AIStreamEvent>;
555
547
  protected createAuxiliaryState(request: NormalizedRequest): AdapterAuxiliaryState;
556
548
  }
557
549
  //#endregion
@@ -618,7 +610,7 @@ type ResponsesTool = {
618
610
  };
619
611
  declare class ResponsesAdapter extends AdapterBase {
620
612
  readonly kind: "responses";
621
- readonly capabilities: AdapterCapabilities;
613
+ readonly isSyntheticStream = false;
622
614
  private apiKey;
623
615
  private baseUrl;
624
616
  private fetchFn;
@@ -686,7 +678,7 @@ type MessagesAPITool = {
686
678
  };
687
679
  declare class MessagesAdapter extends AdapterBase {
688
680
  readonly kind: "messages";
689
- readonly capabilities: AdapterCapabilities;
681
+ readonly isSyntheticStream = false;
690
682
  private apiKey;
691
683
  private apiVersion;
692
684
  private baseUrl;
@@ -744,7 +736,7 @@ type ChatTool = {
744
736
  };
745
737
  declare class ChatCompletionsAdapter extends AdapterBase {
746
738
  readonly kind: "chat-completions";
747
- readonly capabilities: AdapterCapabilities;
739
+ readonly isSyntheticStream = false;
748
740
  private apiKey;
749
741
  private baseUrl;
750
742
  private fetchFn;
@@ -792,7 +784,7 @@ type OllamaTool = {
792
784
  };
793
785
  declare class OllamaAdapter extends AdapterBase {
794
786
  readonly kind: "ollama";
795
- readonly capabilities: AdapterCapabilities;
787
+ readonly isSyntheticStream = false;
796
788
  private baseUrl;
797
789
  private apiKey;
798
790
  private fetchFn;
@@ -889,7 +881,6 @@ type MockToolCallStep = {
889
881
  id: string;
890
882
  name: string;
891
883
  argumentsText: string;
892
- argumentsJson?: unknown;
893
884
  streamArguments?: boolean;
894
885
  stream?: MockTextStreamOptions | false;
895
886
  };
@@ -942,14 +933,7 @@ type MockProviderRequest = {
942
933
  declare function assertMockRequest(request: NormalizedRequest, expectation: MockRequestExpectation, context: MockHandlerContext): void;
943
934
  declare class MockAdapter extends AdapterBase {
944
935
  readonly kind: "mock";
945
- readonly capabilities: {
946
- readonly textStreaming: "synthetic";
947
- readonly reasoningStreaming: "synthetic";
948
- readonly toolCallStreaming: "synthetic";
949
- readonly replay: "canonical";
950
- readonly usage: "final";
951
- readonly toolResultOutcomes: readonly ["success", "error", "rejected"];
952
- };
936
+ readonly isSyntheticStream = true;
953
937
  private readonly handler;
954
938
  private readonly providerMetadata?;
955
939
  private cursor;
@@ -982,7 +966,7 @@ declare function opaqueBlock(payload: unknown): ContentBlock & {
982
966
  };
983
967
  declare function messageItem(content: ContentBlock[], overrides?: Partial<Omit<MessageItem, "type" | "content">>): MessageItem;
984
968
  declare function reasoningItem(content: ContentBlock[], visibility?: ReasoningItem["visibility"], id?: string): ReasoningItem;
985
- declare function toolCallItem(id: string, name: string, argumentsText: string, argumentsJson?: unknown): ToolCallItem;
969
+ declare function toolCallItem(id: string, name: string, argumentsText: string): ToolCallItem;
986
970
  declare function toolResultItem(callId: string, toolName: string, outcome: ToolResultItem["outcome"], content: ContentBlock[]): ToolResultItem;
987
971
  declare function opaqueItem(source: OpaqueItem["source"], purpose: OpaqueItem["purpose"], payload: unknown, id?: string): OpaqueItem;
988
972
  /**
@@ -1000,60 +984,11 @@ declare function blockToText(b: ContentBlock): string;
1000
984
  * 将 ContentBlock 数组拼接为纯文本,块间以换行符分隔。
1001
985
  */
1002
986
  declare function contentBlocksToText(blocks: ContentBlock[]): string;
1003
- /**
1004
- * 将 instructions(string | InstructionBlock[])归一化为纯文本。
1005
- */
1006
- declare function instructionsToText(instructions: string | InstructionBlock[]): string;
1007
987
  /**
1008
988
  * 从 OutputItem 数组中提取所有 message 类型 item 的文本内容。
1009
989
  */
1010
990
  declare function extractText(output: OutputItem[]): string;
1011
991
  //#endregion
1012
- //#region src/helpers/sse-parser.d.ts
1013
- /**
1014
- * 通用 SSE (Server-Sent Events) 解析器
1015
- *
1016
- * 解析标准 SSE 格式(event: + data: 行),适用于:
1017
- * - Anthropic Messages API (messages.ts)
1018
- * - OpenAI Responses API (responses.ts)
1019
- *
1020
- * 注意:OpenAI Chat Completions API 使用简化 SSE(仅有 data: 行),
1021
- * 由 chat-completions.ts 中的 parseChatSSE 处理。
1022
- *
1023
- * 用法:
1024
- * ```ts
1025
- * const { events, rest } = parseSSEEvents(buffer);
1026
- * for (const ev of events) {
1027
- * // ev.type — 事件类型字符串
1028
- * // ev.data — 已解析的 JSON 数据
1029
- * }
1030
- * // rest 是未处理的剩余 buffer,需要累积到下次调用
1031
- * ```
1032
- */
1033
- type SSEEvent = {
1034
- type: string;
1035
- data: unknown;
1036
- };
1037
- type SSEParseResult = {
1038
- events: SSEEvent[];
1039
- rest: string;
1040
- malformedEvents: number;
1041
- };
1042
- type ParseSSEOptions = {
1043
- allowEOF?: boolean;
1044
- };
1045
- /**
1046
- * 将 SSE 文本块解析为事件数组。
1047
- * 累积事件行直到遇到空行,支持 [DONE] 标记。
1048
- * 返回已解析的事件和未处理的剩余 buffer(用于增量解析)。
1049
- *
1050
- * 关键行为:
1051
- * - 只解析完整的 event(以空行结尾)
1052
- * - 未完成的行保留在 rest 中,等待下次 chunk 补全
1053
- * - 支持跨 chunk 的 event 分片
1054
- */
1055
- declare function parseSSEEvents(chunk: string, options?: ParseSSEOptions): SSEParseResult;
1056
- //#endregion
1057
992
  //#region src/helpers/synthetic-stream.d.ts
1058
993
  type SyntheticStreamOptions = {
1059
994
  model: string;
@@ -1191,29 +1126,84 @@ declare class IncrementalStreamParser<T> {
1191
1126
  }
1192
1127
  declare function splitLines(buffer: string, allowEOF: boolean): StreamSplitResult;
1193
1128
  declare function splitSSEFrames(buffer: string, allowEOF: boolean): StreamSplitResult;
1129
+ type SseJsonEvent = {
1130
+ type: string;
1131
+ data: unknown;
1132
+ };
1133
+ /** 解析标准 SSE frame(event: + data:),用于 Messages / Responses。 */
1134
+ declare function parseSseJsonFrame(frame: string): StreamParseResult<SseJsonEvent>;
1135
+ declare function createSseJsonParser<T extends SseJsonEvent = SseJsonEvent>(): IncrementalStreamParser<T>;
1136
+ /** OpenAI Chat Completions 简化 SSE:仅 `data: ...` 行,忽略 `[DONE]`。 */
1137
+ declare function parseChatCompletionsDataLine(item: string): StreamParseResult<unknown>;
1138
+ declare function createChatCompletionsSseParser<T>(): IncrementalStreamParser<T>;
1139
+ /** NDJSON 行解析(Ollama 等):空行忽略,JSON 失败为 malformed。 */
1140
+ declare function createNdjsonLineParser<T>(isValid: (value: unknown) => value is T): IncrementalStreamParser<T>;
1194
1141
  //#endregion
1195
- //#region src/helpers/request-mapper.d.ts
1196
- type ProviderProfile = {
1197
- readonly kind: string;
1198
- readonly instructionsMode: "system_message" | "instructions_field" | "none";
1199
- readonly supportedBlockTypes: ReadonlyArray<ContentBlock["type"]>;
1200
- readonly reasoningBlockTypes: ReadonlyArray<ContentBlock["type"]>;
1201
- readonly capabilities: AdapterCapabilities;
1142
+ //#region src/helpers/provider-stream.d.ts
1143
+ type OpenProviderJsonStreamOptions = {
1144
+ fetchFn: FetchFn;
1145
+ url: string;
1146
+ headers: Record<string, string>;
1147
+ body: unknown;
1148
+ signal?: AbortSignal;
1149
+ };
1150
+ type OpenedProviderStream = {
1151
+ reader: ReadableStreamDefaultReader<Uint8Array>;
1152
+ headers: Headers;
1202
1153
  };
1154
+ /** POST JSON 并返回可读 body reader + response headers;统一网络/HTTP/空 body 错误。 */
1155
+ declare function openProviderJsonStream(options: OpenProviderJsonStreamOptions): Promise<OpenedProviderStream>;
1156
+ type ProviderStreamBatchOptions<T> = {
1157
+ reader: ReadableStreamDefaultReader<Uint8Array>;
1158
+ parser: IncrementalStreamParser<T>;
1159
+ factory: EventFactory;
1160
+ providerLabel: string;
1161
+ transportLabel: string;
1162
+ incompleteMessage: string;
1163
+ };
1164
+ type ProviderStreamBatch<T> = {
1165
+ items: T[];
1166
+ warnings: AIStreamEvent[];
1167
+ };
1168
+ /**
1169
+ * 读取并解析 provider 流。
1170
+ * 每个 batch 携带本轮解析出的 items 与(可选)malformed / incomplete warning。
1171
+ * 调用方应 `for await` 消费完毕;reader 在迭代结束时 cancel/release。
1172
+ */
1173
+ declare function iterateProviderStreamBatches<T>(options: ProviderStreamBatchOptions<T>): AsyncGenerator<ProviderStreamBatch<T>, void, undefined>;
1174
+ /** 一次性 complete 守卫:首次成功,后续返回 false。 */
1175
+ declare function createCompletionGate(): {
1176
+ readonly completed: boolean;
1177
+ tryComplete(): boolean;
1178
+ };
1179
+ //#endregion
1180
+ //#region src/helpers/request-mapper.d.ts
1203
1181
  declare class NormalizedRequestMapper {
1204
- readonly profile: ProviderProfile;
1205
- constructor(profile: ProviderProfile);
1182
+ readonly kind: string;
1183
+ constructor(kind: string);
1206
1184
  mapInstructions(instructions: string | InstructionBlock[]): string;
1207
1185
  ensureTextBlocks(blocks: ContentBlock[], field: string): ContentBlock[];
1208
1186
  ensureReasoningBlocks(blocks: ContentBlock[], field: string): Array<Extract<ContentBlock, {
1209
1187
  type: "text";
1210
1188
  }>>;
1211
- assertToolResultOutcome(outcome: ToolResultItem["outcome"]): void;
1189
+ /** ensureTextBlocks + contentBlocksToText 的常见组合。 */
1190
+ textFromBlocks(blocks: ContentBlock[], field: string): string;
1191
+ parseToolArguments(item: ToolCallItem): Record<string, unknown>;
1212
1192
  rollbackTrailingAssistantMessages<T extends {
1213
1193
  role: string;
1214
1194
  }>(messages: T[]): void;
1195
+ mapToolsIfPresent<T>(tools: ToolDefinition[] | undefined, map: (tool: ToolDefinition) => T): T[] | undefined;
1196
+ /**
1197
+ * 将 canonical toolChoice 映射为 provider 形状。
1198
+ * 返回 undefined 表示调用方无需写入 body 字段。
1199
+ */
1200
+ mapToolChoice<T>(toolChoice: ToolChoice | undefined, mappers: {
1201
+ auto: T;
1202
+ none: T;
1203
+ tool: (name: string) => T;
1204
+ }): T | undefined;
1215
1205
  private ensureBlocks;
1216
1206
  }
1217
1207
  //#endregion
1218
- export { type AIClient, AIError, AIMappingError, AIProviderError, type AIRequest, AIRequestError, type AIResponse, AIStreamError, type AIStreamEvent, AdapterAuxiliaryState, AdapterBase, type AdapterCapabilities, AuxiliaryCollector, type AuxiliaryFinalizeOptions, type AuxiliaryFinalizeResult, type AuxiliaryInfo, type BackendAdapter, type BackendTrace, type BillingInfo, type BillingPostprocessHook, type BillingSource, ChatCompletionsAdapter, type ChatCompletionsAdapterOptions, type ContentBlock, type CreateAIClientOptions, type EventFactory, type EventFactoryBackend, type EventFactoryState, type FetchFn, type IncludeSettings, IncrementalStreamParser, type InputItem, type InstructionBlock, type JsonContentBlock, type LookupResult, MAX_OPAQUE_JSON_DEPTH, MAX_OPAQUE_PAYLOAD_BYTES, type MessageCompletedEvent, type MessageDeltaEvent, type MessageItem, type MessageStartedEvent, MessagesAdapter, type MessagesAdapterOptions, MockAdapter, type MockAdapterOptions, type MockAuxiliaryStep, type MockCompleteStep, type MockErrorStep, type MockHandler, type MockHandlerContext, type MockHistoryRecord, type MockInputExpectation, type MockInterruptStep, type MockMessageStep, type MockOutputStep, type MockReasoningStep, type MockRequestExpectation, type MockStaticHandler, type MockStep, type MockTextStreamOptions, type MockThrowStep, type MockToolCallStep, type MockWarningStep, type NormalizeOptions, type NormalizedRequest, NormalizedRequestMapper, OllamaAdapter, type OllamaAdapterOptions, type OpaqueEnvelopeResult, type OpaqueItem, type OutputItem, PROVIDER_ERROR_MESSAGE_MAX_LEN, PROVIDER_ERROR_RAW_BODY_THRESHOLD, type ProviderProfile, type ReasoningCompletedEvent, type ReasoningDeltaEvent, type ReasoningItem, type ReasoningStartedEvent, type ReplayItem, type ResponseAuxiliaryEvent, type ResponseCompletedEvent, type ResponseStartedEvent, type ResponseWarningEvent, ResponsesAdapter, type ResponsesAdapterOptions, type SSEEvent, type StopReason, type StreamEventBase, type StreamParseResult, type StreamResult, type StreamSplitResult, type StreamingCapability, type SyntheticStreamOptions, type TextContentBlock, type ToolCallCompletedEvent, type ToolCallDeltaEvent, type ToolCallItem, type ToolCallStartedEvent, type ToolChoice, type ToolDefinition, type ToolResultItem, type Usage, type UsageSource, type ValidationIssue, WarningCode, aggregateEvents, assertMockRequest, assertOpaqueReplayEnvelope, assertValidRequest, blockToText, collectStream, contentBlocksToText, createAIClient, createEventFactory, emitMalformedStreamWarning, extractProviderErrorMessage, extractText, imageBlock, instructionsToText, jsonBlock, mapReasoningVisibility, mapStopReason, measureJsonDepth, messageItem, metadataSourceList, normalizeRequest, opaqueBlock, opaqueItem, parseSSEEvents, providerHttpError, reasoningItem, replayFromOutput, splitLines, splitSSEFrames, syntheticStream, textBlock, toolCallItem, toolResultItem, usageFromAnthropicMessages, usageFromChatCompletions, usageFromOllama, usageFromOpenAIResponses, validateOpaqueReplayEnvelope, validateRequest, withMockStreaming };
1208
+ export { type AIClient, AIError, AIMappingError, AIProviderError, type AIRequest, AIRequestError, type AIResponse, AIStreamError, type AIStreamEvent, AdapterAuxiliaryState, AdapterBase, AuxiliaryCollector, type AuxiliaryFinalizeOptions, type AuxiliaryFinalizeResult, type AuxiliaryInfo, type BackendAdapter, type BackendTrace, type BillingInfo, type BillingPostprocessHook, type BillingSource, ChatCompletionsAdapter, type ChatCompletionsAdapterOptions, type ContentBlock, type CreateAIClientOptions, type EventFactory, type EventFactoryBackend, type EventFactoryState, type FetchFn, type IncludeSettings, IncrementalStreamParser, type InputItem, type InstructionBlock, type JsonContentBlock, type LookupResult, MAX_OPAQUE_JSON_DEPTH, MAX_OPAQUE_PAYLOAD_BYTES, type MessageCompletedEvent, type MessageDeltaEvent, type MessageItem, type MessageStartedEvent, MessagesAdapter, type MessagesAdapterOptions, MockAdapter, type MockAdapterOptions, type MockAuxiliaryStep, type MockCompleteStep, type MockErrorStep, type MockHandler, type MockHandlerContext, type MockHistoryRecord, type MockInputExpectation, type MockInterruptStep, type MockMessageStep, type MockOutputStep, type MockReasoningStep, type MockRequestExpectation, type MockStaticHandler, type MockStep, type MockTextStreamOptions, type MockThrowStep, type MockToolCallStep, type MockWarningStep, type NormalizeOptions, type NormalizedRequest, NormalizedRequestMapper, OllamaAdapter, type OllamaAdapterOptions, type OpaqueEnvelopeResult, type OpaqueItem, type OpenProviderJsonStreamOptions, type OpenedProviderStream, type OutputItem, PROVIDER_ERROR_MESSAGE_MAX_LEN, PROVIDER_ERROR_RAW_BODY_THRESHOLD, type ProviderStreamBatch, type ProviderStreamBatchOptions, type ReasoningCompletedEvent, type ReasoningDeltaEvent, type ReasoningItem, type ReasoningStartedEvent, type ReplayItem, type ResponseAuxiliaryEvent, type ResponseCompletedEvent, type ResponseStartedEvent, type ResponseWarningEvent, ResponsesAdapter, type ResponsesAdapterOptions, type SseJsonEvent, type StopReason, type StreamEventBase, type StreamParseResult, type StreamResult, type StreamSplitResult, type SyntheticStreamOptions, type TextContentBlock, type ToolCallCompletedEvent, type ToolCallDeltaEvent, type ToolCallItem, type ToolCallStartedEvent, type ToolChoice, type ToolDefinition, type ToolResultItem, type Usage, type UsageSource, type ValidationIssue, WarningCode, aggregateEvents, assertMockRequest, assertOpaqueReplayEnvelope, assertValidRequest, blockToText, collectStream, contentBlocksToText, createAIClient, createChatCompletionsSseParser, createCompletionGate, createEventFactory, createNdjsonLineParser, createSseJsonParser, emitMalformedStreamWarning, extractProviderErrorMessage, extractText, imageBlock, iterateProviderStreamBatches, jsonBlock, mapReasoningVisibility, mapStopReason, measureJsonDepth, messageItem, normalizeRequest, opaqueBlock, opaqueItem, openProviderJsonStream, parseChatCompletionsDataLine, parseSseJsonFrame, providerHttpError, reasoningItem, replayFromOutput, splitLines, splitSSEFrames, syntheticStream, textBlock, toolCallItem, toolResultItem, usageFromAnthropicMessages, usageFromChatCompletions, usageFromOllama, usageFromOpenAIResponses, validateOpaqueReplayEnvelope, validateRequest, withMockStreaming };
1219
1209
  //# sourceMappingURL=index.d.mts.map