@codehz/ai 0.4.6 → 0.7.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.
Files changed (46) hide show
  1. package/README.md +221 -75
  2. package/dist/index.d.mts +662 -523
  3. package/dist/index.mjs +3626 -2202
  4. package/dist/index.mjs.map +1 -1
  5. package/package.json +19 -8
  6. package/.github/workflows/publish.yml +0 -56
  7. package/.oxfmtrc.json +0 -12
  8. package/.oxlintrc.json +0 -34
  9. package/AGENTS.md +0 -37
  10. package/src/adapters/chat-completions.ts +0 -624
  11. package/src/adapters/index.ts +0 -44
  12. package/src/adapters/messages.ts +0 -635
  13. package/src/adapters/mock.ts +0 -934
  14. package/src/adapters/ollama.ts +0 -526
  15. package/src/adapters/responses.ts +0 -818
  16. package/src/core/aggregator.ts +0 -428
  17. package/src/core/client.ts +0 -36
  18. package/src/core/collect-stream.ts +0 -19
  19. package/src/core/errors.ts +0 -105
  20. package/src/core/event-factory.ts +0 -151
  21. package/src/core/index.ts +0 -18
  22. package/src/core/merge-auxiliary.ts +0 -22
  23. package/src/core/normalize.ts +0 -65
  24. package/src/core/validation.ts +0 -404
  25. package/src/helpers/adapter-auxiliary.ts +0 -155
  26. package/src/helpers/adapter-base.ts +0 -218
  27. package/src/helpers/adapter-security.ts +0 -126
  28. package/src/helpers/auxiliary-collector.ts +0 -166
  29. package/src/helpers/incremental-stream-parser.ts +0 -142
  30. package/src/helpers/index.ts +0 -87
  31. package/src/helpers/mapping.ts +0 -192
  32. package/src/helpers/provider-request-options.ts +0 -25
  33. package/src/helpers/provider-stream.ts +0 -147
  34. package/src/helpers/reasoning-level.ts +0 -86
  35. package/src/helpers/request-mapper.ts +0 -94
  36. package/src/helpers/synthetic-stream.ts +0 -188
  37. package/src/helpers/usage-mapping.ts +0 -110
  38. package/src/index.ts +0 -17
  39. package/src/types/adapter.ts +0 -42
  40. package/src/types/content.ts +0 -15
  41. package/src/types/events.ts +0 -138
  42. package/src/types/index.ts +0 -49
  43. package/src/types/items.ts +0 -57
  44. package/src/types/request.ts +0 -52
  45. package/src/types/response.ts +0 -68
  46. package/tsdown.config.ts +0 -10
package/dist/index.d.mts CHANGED
@@ -1,3 +1,15 @@
1
+ //#region src/types/kind.d.ts
2
+ /**
3
+ * Adapter kind 标识
4
+ *
5
+ * KnownAdapterKind 覆盖内置 adapter;
6
+ * AdapterKind 额外接受任意 string,便于自定义 backend 扩展(无需改库联合类型)。
7
+ */
8
+ declare const KNOWN_ADAPTER_KINDS: readonly ["chat-completions", "messages", "responses", "ollama", "gemini", "mock"];
9
+ type KnownAdapterKind = (typeof KNOWN_ADAPTER_KINDS)[number];
10
+ /** 内置 kind 自动补全 + 自定义 string 扩展 */
11
+ type AdapterKind = KnownAdapterKind | (string & {});
12
+ //#endregion
1
13
  //#region src/types/content.d.ts
2
14
  /**
3
15
  * ContentBlock — 统一内容块类型
@@ -25,11 +37,28 @@ type ContentBlock = InstructionBlock | {
25
37
  };
26
38
  //#endregion
27
39
  //#region src/types/items.d.ts
40
+ type UrlCitation = {
41
+ type: "url";
42
+ url: string;
43
+ title?: string;
44
+ startIndex?: number;
45
+ endIndex?: number;
46
+ };
47
+ type ContainerFileCitation = {
48
+ type: "container_file";
49
+ containerId: string;
50
+ fileId: string;
51
+ filename?: string;
52
+ startIndex?: number;
53
+ endIndex?: number;
54
+ };
55
+ type Citation = UrlCitation | ContainerFileCitation;
28
56
  type MessageItem = {
29
57
  type: "message";
30
58
  id?: string;
31
59
  role: "user" | "assistant";
32
60
  content: ContentBlock[];
61
+ citations?: Citation[];
33
62
  };
34
63
  type ReasoningItem = {
35
64
  type: "reasoning";
@@ -57,10 +86,44 @@ type OpaqueItem = {
57
86
  purpose: "replay" | "provider_state" | "unknown";
58
87
  payload: unknown;
59
88
  };
89
+ /** Provider 托管工具调用(调用方不执行) */
90
+ type ServerToolCallItem = {
91
+ type: "server_tool_call";
92
+ id: string;
93
+ tool: "web_search" | "code_execution" | "mcp" | string;
94
+ name?: string;
95
+ argumentsText?: string;
96
+ status?: "in_progress" | "completed" | "failed";
97
+ serverLabel?: string;
98
+ providerPayload?: unknown;
99
+ };
100
+ /** Provider 托管工具结果 */
101
+ type ServerToolResultItem = {
102
+ type: "server_tool_result";
103
+ id?: string;
104
+ callId: string;
105
+ tool: string;
106
+ outcome: "success" | "error";
107
+ content: ContentBlock[];
108
+ providerPayload?: unknown;
109
+ };
110
+ /** MCP 等远端工具发现列表 */
111
+ type ServerToolDiscoveryItem = {
112
+ type: "server_tool_discovery";
113
+ id: string;
114
+ tool: "mcp";
115
+ serverLabel: string;
116
+ tools: Array<{
117
+ name: string;
118
+ description?: string;
119
+ inputSchema?: unknown;
120
+ }>;
121
+ providerPayload?: unknown;
122
+ };
60
123
  /** 可出现在请求 input 中的 item 类型 */
61
- type InputItem = MessageItem | ReasoningItem | ToolCallItem | ToolResultItem | OpaqueItem;
62
- /** 可出现在响应 output 中的 item 类型(不含 ToolResultItem) */
63
- type OutputItem = MessageItem | ReasoningItem | ToolCallItem | OpaqueItem;
124
+ type InputItem = MessageItem | ReasoningItem | ToolCallItem | ToolResultItem | OpaqueItem | ServerToolCallItem | ServerToolResultItem | ServerToolDiscoveryItem;
125
+ /** 可出现在响应 output 中的 item 类型(不含客户端 ToolResultItem) */
126
+ type OutputItem = MessageItem | ReasoningItem | ToolCallItem | OpaqueItem | ServerToolCallItem | ServerToolResultItem | ServerToolDiscoveryItem;
64
127
  /** replay 材料的类型等价于 InputItem */
65
128
  type ReplayItem = InputItem;
66
129
  //#endregion
@@ -74,6 +137,39 @@ type ToolChoice = "auto" | "none" | {
74
137
  type: "tool";
75
138
  name: string;
76
139
  };
140
+ type WebSearchUserLocation = {
141
+ type: "approximate";
142
+ country?: string;
143
+ city?: string;
144
+ region?: string;
145
+ timezone?: string;
146
+ };
147
+ type WebSearchServerTool = {
148
+ type: "web_search";
149
+ allowedDomains?: string[];
150
+ blockedDomains?: string[];
151
+ userLocation?: WebSearchUserLocation;
152
+ searchContextSize?: "low" | "medium" | "high";
153
+ };
154
+ type CodeExecutionServerTool = {
155
+ type: "code_execution";
156
+ container?: {
157
+ type: "auto";
158
+ memoryLimit?: "1g" | "4g" | "16g" | "64g";
159
+ fileIds?: string[];
160
+ };
161
+ };
162
+ type McpServerTool = {
163
+ type: "mcp";
164
+ serverLabel: string;
165
+ serverUrl: string;
166
+ serverDescription?: string; /** 每请求由调用方提供;不得写入日志或 opaque 回放。 */
167
+ authorization?: string;
168
+ allowedTools?: string[]; /** 首版仅支持 never */
169
+ requireApproval: "never";
170
+ };
171
+ /** Provider 托管执行的工具声明(不进客户端 tool loop) */
172
+ type ServerToolDefinition = WebSearchServerTool | CodeExecutionServerTool | McpServerTool;
77
173
  type IncludeSettings = {
78
174
  usage?: "off" | "best_effort";
79
175
  billing?: "off" | "best_effort";
@@ -81,10 +177,15 @@ type IncludeSettings = {
81
177
  };
82
178
  /** Portable reasoning / thinking effort. Mapped per-adapter to provider wire fields. */
83
179
  type ReasoningLevel = "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
180
+ /** 可移植 reasoning level 枚举(单源;validation / provider 共用)。 */
181
+ declare const REASONING_LEVELS: readonly ["none", "minimal", "low", "medium", "high", "xhigh", "max"];
182
+ /** 用于校验任意字符串 membership;值域与 REASONING_LEVELS 一致。 */
183
+ declare const REASONING_LEVEL_SET: ReadonlySet<string>;
84
184
  type AIRequest = {
85
185
  instructions?: string | InstructionBlock[];
86
186
  input: InputItem[];
87
- tools?: ToolDefinition[];
187
+ tools?: ToolDefinition[]; /** Provider 托管工具(web_search / code_execution / mcp 等);与 tools 可共存 */
188
+ serverTools?: ServerToolDefinition[];
88
189
  toolChoice?: ToolChoice;
89
190
  include?: IncludeSettings;
90
191
  metadata?: Record<string, string>;
@@ -93,12 +194,57 @@ type AIRequest = {
93
194
  /**
94
195
  * Portable reasoning effort. Adapters map this to provider-native fields
95
196
  * (e.g. Responses `reasoning.effort`, Chat Completions `reasoning_effort`,
96
- * Messages `thinking`, Ollama `think`). Unsupported levels throw.
197
+ * Messages `thinking`, Ollama `think`, Gemini `thinkingConfig`).
198
+ * Unsupported levels throw.
97
199
  */
98
200
  reasoningLevel?: ReasoningLevel; /** AbortSignal 用于打断请求。abort 时 fetch 调用会被取消,流迭代器抛出 AbortError。 */
99
201
  signal?: AbortSignal;
100
202
  };
101
203
  //#endregion
204
+ //#region src/types/warning-codes.d.ts
205
+ /**
206
+ * 标准 warning 代码 — types 层单源
207
+ *
208
+ * runtime.errors 与 events 均从此导出,避免手工双表漂移。
209
+ */
210
+ declare const WarningCode: {
211
+ /** replay fidelity 低于预期 */readonly REPLAY_FIDELITY_LOW: "REPLAY_FIDELITY_LOW"; /** usage 字段缺失 */
212
+ readonly USAGE_MISSING: "USAGE_MISSING"; /** billing 字段缺失 */
213
+ readonly BILLING_MISSING: "BILLING_MISSING"; /** billing 只能给估算值 */
214
+ readonly BILLING_ESTIMATED: "BILLING_ESTIMATED"; /** follow-up lookup 失败 */
215
+ readonly LOOKUP_FAILED: "LOOKUP_FAILED"; /** lookup 超时 */
216
+ readonly LOOKUP_TIMEOUT: "LOOKUP_TIMEOUT"; /** 流提前中断 */
217
+ readonly STREAM_INCOMPLETE: "STREAM_INCOMPLETE"; /** 流帧/行解析失败 */
218
+ readonly STREAM_ERROR: "STREAM_ERROR"; /** 能力降级 */
219
+ readonly CAPABILITY_DOWNGRADE: "CAPABILITY_DOWNGRADE"; /** 模拟流式 */
220
+ readonly SYNTHETIC_STREAM: "SYNTHETIC_STREAM"; /** 工具调用以批量方式到达(非 token 级流式) */
221
+ readonly TOOL_CALL_BATCHED: "TOOL_CALL_BATCHED"; /** AIMappingError 降级为 warning */
222
+ readonly MAPPING_ERROR: "MAPPING_ERROR"; /** 入站 tool_call.argumentsText 非合法 JSON object(object-wire adapter soft-complete) */
223
+ readonly TOOL_CALL_ARGUMENTS_INVALID: "TOOL_CALL_ARGUMENTS_INVALID"; /** 请求 metadata 不被该 adapter 支持 */
224
+ readonly UNSUPPORTED_METADATA: "UNSUPPORTED_METADATA"; /** 重复 finish / done 信号被忽略 */
225
+ readonly DUPLICATE_FINISH: "DUPLICATE_FINISH"; /** provider 发出未知事件类型 */
226
+ readonly UNKNOWN_PROVIDER_EVENT: "UNKNOWN_PROVIDER_EVENT"; /** 内容被安全/策略过滤 */
227
+ readonly CONTENT_FILTER: "CONTENT_FILTER"; /** 多 choice 仅支持 index 0,其余忽略 */
228
+ readonly MULTIPLE_CHOICES_IGNORED: "MULTIPLE_CHOICES_IGNORED"; /** MCP 审批流不被支持 */
229
+ readonly MCP_APPROVAL_REQUIRED: "MCP_APPROVAL_REQUIRED"; /** provider 侧 response.failed 等失败 */
230
+ readonly PROVIDER_FAILURE: "PROVIDER_FAILURE";
231
+ };
232
+ type WarningCodeName = (typeof WarningCode)[keyof typeof WarningCode];
233
+ /** 与 WarningCodeName 同义;保留以兼容既有 KnownWarningCode 命名 */
234
+ type KnownWarningCode = WarningCodeName;
235
+ /** 已知码 + 开放字符串扩展 */
236
+ type WarningCodeValue = KnownWarningCode | (string & {});
237
+ /** 结构化 warning(AIResponse / response.completed / factory 共用) */
238
+ type StreamWarning = {
239
+ message: string;
240
+ code?: WarningCodeValue;
241
+ };
242
+ /**
243
+ * 去重键:以 message 为主(与旧 string[] 行为一致)。
244
+ * 同一 message 若先无 code 后有 code,保留先到的那条。
245
+ */
246
+ declare function streamWarningKey(warning: StreamWarning): string;
247
+ //#endregion
102
248
  //#region src/types/response.d.ts
103
249
  type StopReason = "end_turn" | "tool_call" | "max_output_tokens" | "content_filter" | "error" | "unknown";
104
250
  type Usage = {
@@ -126,22 +272,24 @@ type AuxiliaryInfo = {
126
272
  type BackendTrace = {
127
273
  requestId?: string;
128
274
  rawResponseId?: string;
129
- adapter: "chat-completions" | "messages" | "responses" | "ollama" | "mock";
275
+ adapter: AdapterKind;
130
276
  isSyntheticStream: boolean;
131
277
  metadataSources?: string[];
132
- warnings?: string[];
278
+ warnings?: StreamWarning[];
133
279
  };
134
280
  type AIResponse = {
135
281
  id?: string;
136
282
  output: OutputItem[];
137
283
  replay: ReplayItem[];
138
284
  text: string;
139
- toolCalls: ToolCallItem[];
285
+ toolCalls: ToolCallItem[]; /** Provider 托管工具调用列表(web_search / code_execution / mcp 等) */
286
+ serverToolCalls: ServerToolCallItem[]; /** Provider 托管工具结果列表 */
287
+ serverToolResults: ServerToolResultItem[];
140
288
  stopReason?: StopReason;
141
289
  usage?: Usage;
142
290
  billing?: BillingInfo;
143
- auxiliary?: AuxiliaryInfo;
144
- warnings?: string[];
291
+ auxiliary?: AuxiliaryInfo; /** 结构化 warning;权威源含 message + 可选 code */
292
+ warnings?: StreamWarning[];
145
293
  backend: BackendTrace;
146
294
  };
147
295
  //#endregion
@@ -152,7 +300,7 @@ type StreamEventBase = {
152
300
  sequence: number;
153
301
  timestamp: string;
154
302
  backend: {
155
- kind: "chat-completions" | "messages" | "responses" | "ollama" | "mock";
303
+ kind: AdapterKind;
156
304
  isSynthetic: boolean;
157
305
  };
158
306
  };
@@ -163,7 +311,7 @@ type ResponseStartedEvent = StreamEventBase & {
163
311
  type ResponseWarningEvent = StreamEventBase & {
164
312
  type: "response.warning";
165
313
  message: string;
166
- code?: string;
314
+ code?: WarningCodeValue;
167
315
  };
168
316
  type ResponseAuxiliaryEvent = StreamEventBase & {
169
317
  type: "response.auxiliary";
@@ -178,7 +326,7 @@ type ResponseCompletedEvent = StreamEventBase & {
178
326
  usage?: Usage;
179
327
  billing?: BillingInfo;
180
328
  auxiliary?: AuxiliaryInfo;
181
- warnings?: string[];
329
+ warnings?: StreamWarning[];
182
330
  opaqueOutput?: OpaqueItem[];
183
331
  trace?: Partial<BackendTrace>;
184
332
  };
@@ -197,6 +345,7 @@ type MessageDeltaEvent = StreamEventBase & {
197
345
  type MessageCompletedEvent = StreamEventBase & {
198
346
  type: "message.completed";
199
347
  itemId: string;
348
+ citations?: Citation[];
200
349
  };
201
350
  type ReasoningStartedEvent = StreamEventBase & {
202
351
  type: "reasoning.started";
@@ -232,7 +381,37 @@ type ToolCallCompletedEvent = StreamEventBase & {
232
381
  type: "tool_call.completed";
233
382
  itemId: string;
234
383
  };
235
- type AIStreamEvent = ResponseStartedEvent | ResponseWarningEvent | ResponseAuxiliaryEvent | MessageStartedEvent | MessageDeltaEvent | MessageCompletedEvent | ReasoningStartedEvent | ReasoningDeltaEvent | ReasoningCompletedEvent | ToolCallStartedEvent | ToolCallDeltaEvent | ToolCallCompletedEvent | ResponseCompletedEvent;
384
+ type ServerToolStartedEvent = StreamEventBase & {
385
+ type: "server_tool.started";
386
+ item: {
387
+ id: string;
388
+ tool: string;
389
+ name?: string;
390
+ serverLabel?: string;
391
+ };
392
+ };
393
+ type ServerToolDeltaEvent = StreamEventBase & {
394
+ type: "server_tool.delta";
395
+ itemId: string;
396
+ delta: {
397
+ argumentsText?: string;
398
+ };
399
+ };
400
+ type ServerToolCompletedEvent = StreamEventBase & {
401
+ type: "server_tool.completed";
402
+ itemId: string;
403
+ status?: "completed" | "failed";
404
+ providerPayload?: unknown;
405
+ };
406
+ type ServerToolResultCompletedEvent = StreamEventBase & {
407
+ type: "server_tool_result.completed";
408
+ item: ServerToolResultItem;
409
+ };
410
+ type ServerToolDiscoveryCompletedEvent = StreamEventBase & {
411
+ type: "server_tool_discovery.completed";
412
+ item: ServerToolDiscoveryItem;
413
+ };
414
+ type AIStreamEvent = ResponseStartedEvent | ResponseWarningEvent | ResponseAuxiliaryEvent | MessageStartedEvent | MessageDeltaEvent | MessageCompletedEvent | ReasoningStartedEvent | ReasoningDeltaEvent | ReasoningCompletedEvent | ToolCallStartedEvent | ToolCallDeltaEvent | ToolCallCompletedEvent | ServerToolStartedEvent | ServerToolDeltaEvent | ServerToolCompletedEvent | ServerToolResultCompletedEvent | ServerToolDiscoveryCompletedEvent | ResponseCompletedEvent;
236
415
  //#endregion
237
416
  //#region src/types/adapter.d.ts
238
417
  /** HTTP fetch 函数签名,用于注入自定义请求实现(测试/代理) */
@@ -242,7 +421,7 @@ type NormalizedRequest = AIRequest & {
242
421
  requestId: string;
243
422
  };
244
423
  interface BackendAdapter {
245
- readonly kind: "chat-completions" | "messages" | "responses" | "ollama" | "mock";
424
+ readonly kind: AdapterKind;
246
425
  readonly isSyntheticStream: boolean;
247
426
  stream(request: NormalizedRequest): AsyncIterable<AIStreamEvent>;
248
427
  }
@@ -256,50 +435,39 @@ interface AIClient {
256
435
  stream(request: AIRequest): AsyncIterable<AIStreamEvent>;
257
436
  }
258
437
  //#endregion
259
- //#region src/core/client.d.ts
260
- declare function createAIClient(options: CreateAIClientOptions): AIClient;
261
- //#endregion
262
- //#region src/core/normalize.d.ts
263
- type NormalizeOptions = {
438
+ //#region src/types/compress.d.ts
439
+ /** 显式上下文压缩请求(独立于 stream) */
440
+ type CompressRequest = {
264
441
  model: string;
265
- defaults?: Partial<AIRequest>;
442
+ input: InputItem[];
443
+ instructions?: string | InstructionBlock[];
444
+ include?: IncludeSettings; /** AbortSignal 用于打断压缩请求。 */
445
+ signal?: AbortSignal;
266
446
  };
267
- /**
268
- * 归一化请求:
269
- * 1. 合并 defaults
270
- * 2. 填充 include 默认值
271
- * 3. 生成 requestId
272
- * 4. 校验请求合法性
273
- */
274
- declare function normalizeRequest(request: AIRequest, options: NormalizeOptions): NormalizedRequest;
275
- //#endregion
276
- //#region src/core/validation.d.ts
277
- type ValidationIssue = {
278
- field: string;
279
- code: string;
280
- message: string;
447
+ /** 压缩结果:调用方用 replay 替换旧 transcript(非 append 全文) */
448
+ type CompressResult = {
449
+ replay: ReplayItem[];
450
+ usage?: Usage;
451
+ auxiliary?: AuxiliaryInfo;
452
+ rawResponseId?: string;
281
453
  };
282
- /**
283
- * 校验 AIRequest,返回校验问题列表。
284
- * 空数组表示无问题。
285
- */
286
- declare function validateRequest(request: AIRequest): ValidationIssue[];
287
- /**
288
- * 校验请求并抛出首个问题。
289
- * 适用于客户端入口的快速失败检查。
290
- */
291
- declare function assertValidRequest(request: AIRequest): void;
454
+ /** Adapter 可选能力:原生上下文压缩 */
455
+ interface ContextCompressCapable {
456
+ compress(request: CompressRequest): Promise<CompressResult>;
457
+ }
458
+ /** 探测 adapter 是否实现 compress(不依赖 kind 硬编码)。 */
459
+ declare function supportsContextCompress(adapter: BackendAdapter): adapter is BackendAdapter & ContextCompressCapable;
292
460
  //#endregion
293
- //#region src/core/errors.d.ts
461
+ //#region src/runtime/client.d.ts
462
+ declare function createAIClient(options: CreateAIClientOptions): AIClient;
463
+ //#endregion
464
+ //#region src/runtime/errors.d.ts
294
465
  /**
295
- * 公共错误模型
296
- *
297
- * 把失败、降级、断流三类情况明确区分:
298
- * - 致命错误 → 同步抛错或迭代器抛错
299
- * - 非致命差异 → warning 通道
300
- * - 流中断 → 不伪造 response.completed
466
+ * 已知错误码。保留补全;未知码用 `string & {}` 扩展,避免 `| string` 吞掉字面量提示。
467
+ * ValidationIssue.code 可更细,不强制全部列入此处;以作为 AIError.code 传入的码为主。
301
468
  */
302
- type ErrorCode = "INPUT_EMPTY" | "TEMPERATURE_OUT_OF_RANGE" | "MAX_OUTPUT_TOKENS_INVALID" | "TOOL_CHOICE_NO_TOOLS" | "TOOL_CHOICE_UNKNOWN_TOOL" | "PROVIDER_ERROR" | "AUTH_ERROR" | "STREAM_ERROR" | "MAPPING_ERROR" | "STREAM_INCOMPLETE" | "LOOKUP_FAILED" | "LOOKUP_TIMEOUT" | string;
469
+ type KnownErrorCode = "INPUT_EMPTY" | "TEMPERATURE_OUT_OF_RANGE" | "MAX_OUTPUT_TOKENS_INVALID" | "TOOL_CHOICE_NO_TOOLS" | "TOOL_CHOICE_UNKNOWN_TOOL" | "TOOL_CALL_ARGUMENTS_INVALID" | "PROVIDER_ERROR" | "AUTH_ERROR" | "STREAM_ERROR" | "STREAM_PROTOCOL_ERROR" | "MAPPING_ERROR" | "STREAM_INCOMPLETE" | "LOOKUP_FAILED" | "LOOKUP_TIMEOUT" | "INVALID_OPAQUE_REPLAY" | "UNSUPPORTED_CONTENT_BLOCK" | "UNSUPPORTED_SERVER_TOOL" | "UNSUPPORTED_REASONING_LEVEL" | "UNSUPPORTED_COMPRESS" | "MOCK_CONCURRENT_STREAM" | "MOCK_COMPRESS_NOT_CONFIGURED" | "MOCK_EXPECTATION_FAILED" | "MOCK_STREAM_CONFIG_INVALID" | "MOCK_OPAQUE_OUTPUT" | "MOCK_MESSAGE_ID_MISSING" | "MOCK_REASONING_ID_MISSING";
470
+ type ErrorCode = KnownErrorCode | (string & {});
303
471
  declare class AIError extends Error {
304
472
  readonly code: ErrorCode;
305
473
  readonly name: string;
@@ -318,40 +486,109 @@ declare class AIRequestError extends AIError {
318
486
  message: string;
319
487
  }[] | undefined);
320
488
  }
321
- /** Provider 调用失败 — HTTP 非 2xx、网络错误。由 AdapterBase 捕获转为 warning。 */
489
+ /**
490
+ * Provider 调用失败 — HTTP 非 2xx、网络错误。
491
+ * AdapterBase **rethrow**(致命),不会转为 warning。
492
+ */
322
493
  declare class AIProviderError extends AIError {
323
494
  readonly statusCode?: number | undefined;
324
495
  readonly responseBody?: string | undefined;
325
496
  constructor(message: string, code: ErrorCode, statusCode?: number | undefined, responseBody?: string | undefined);
326
497
  }
327
- /** 流协议损坏 — SSE 解析失败、chunk 格式异常。 */
498
+ /**
499
+ * 流协议/传输损坏 — SSE 解析失败、chunk 格式异常、body 不可读等。
500
+ * 致命:同步或在异步迭代中抛出,不伪造 response.completed。
501
+ */
328
502
  declare class AIStreamError extends AIError {
329
503
  constructor(message: string, code: ErrorCode);
330
504
  }
331
- /** Canonical 映射失败 — 无法将 provider 响应映射到 canonical 类型。 */
505
+ /**
506
+ * Canonical 映射失败 — 无法将 provider 响应映射到 canonical 类型。
507
+ *
508
+ * AdapterBase 捕获后降级为:
509
+ * - `response.warning`(code = MAPPING_ERROR)
510
+ * - 空 output 的 `response.completed`
511
+ *
512
+ * 生产 adapter 原则上不应抛出;此路径是协议级降级通道(测试 / 防御性边界)。
513
+ */
332
514
  declare class AIMappingError extends AIError {
333
515
  constructor(message: string, code: ErrorCode);
334
516
  }
335
517
  /**
336
- * 标准 warning 代码列表。
337
- * 用于非致命差异的记录。
518
+ * 可恢复的回合失败 buildRequest / runStream 中可安全 soft-complete 的语义错误。
519
+ *
520
+ * AdapterBase 在 `response.started` 之后捕获后降级为:
521
+ * - `response.warning`(code = 错误 code,通常对齐 WarningCode)
522
+ * - 空 replay 的 `response.completed`(`stopReason` 默认 `"error"`)
523
+ *
524
+ * 与 AIMappingError 的区别:recoverable 携带显式 stopReason,表示调用方应清理
525
+ * 中毒历史后重试;mapping 是协议级降级通道,通常不带 stopReason。
338
526
  */
339
- declare const WarningCode: {
340
- /** replay fidelity 低于预期 */readonly REPLAY_FIDELITY_LOW: "REPLAY_FIDELITY_LOW"; /** usage 字段缺失 */
341
- readonly USAGE_MISSING: "USAGE_MISSING"; /** billing 字段缺失 */
342
- readonly BILLING_MISSING: "BILLING_MISSING"; /** billing 只能给估算值 */
343
- readonly BILLING_ESTIMATED: "BILLING_ESTIMATED"; /** follow-up lookup 失败 */
344
- readonly LOOKUP_FAILED: "LOOKUP_FAILED"; /** lookup 超时 */
345
- readonly LOOKUP_TIMEOUT: "LOOKUP_TIMEOUT"; /** 流提前中断 */
346
- readonly STREAM_INCOMPLETE: "STREAM_INCOMPLETE"; /** 能力降级 */
347
- readonly CAPABILITY_DOWNGRADE: "CAPABILITY_DOWNGRADE"; /** 模拟流式 */
348
- readonly SYNTHETIC_STREAM: "SYNTHETIC_STREAM"; /** 工具调用以批量方式到达(非 token 级流式) */
349
- readonly TOOL_CALL_BATCHED: "TOOL_CALL_BATCHED";
527
+ declare class AIRecoverableError extends AIError {
528
+ readonly stopReason: StopReason;
529
+ constructor(message: string, code: ErrorCode, stopReason?: StopReason);
530
+ }
531
+ //#endregion
532
+ //#region src/stream/collect-stream.d.ts
533
+ declare function collectStream(stream: AsyncIterable<AIStreamEvent>): Promise<AIResponse>;
534
+ //#endregion
535
+ //#region src/canonical/stop-reason.d.ts
536
+ declare function mapStopReason(providerReason: string): StopReason;
537
+ declare function mapReasoningVisibility(hasThinking: boolean, hasRedacted: boolean): ReasoningItem["visibility"];
538
+ //#endregion
539
+ //#region src/canonical/content.d.ts
540
+ declare function textBlock(text: string): ContentBlock & {
541
+ type: "text";
350
542
  };
543
+ declare function jsonBlock(json: unknown): ContentBlock & {
544
+ type: "json";
545
+ };
546
+ declare function imageBlock(imageUrl: string): ContentBlock & {
547
+ type: "image";
548
+ };
549
+ declare function opaqueBlock(payload: unknown): ContentBlock & {
550
+ type: "opaque";
551
+ };
552
+ /**
553
+ * 将单个 ContentBlock 转为纯文本。
554
+ * text 块直接返回文本,json 块序列化,其余返回空串。
555
+ */
556
+ declare function blockToText(b: ContentBlock): string;
557
+ /**
558
+ * 将 ContentBlock 数组拼接为纯文本,块间以换行符分隔。
559
+ */
560
+ declare function contentBlocksToText(blocks: ContentBlock[]): string;
561
+ /**
562
+ * 合并相邻 text content blocks(直接拼接、不插入分隔符)。
563
+ * 非 text block 保留边界。供 aggregator 与 StreamingItemSession 共用。
564
+ */
565
+ declare function coalesceContentBlocks(blocks: readonly ContentBlock[]): ContentBlock[];
566
+ //#endregion
567
+ //#region src/canonical/items.d.ts
568
+ declare function messageItem(content: ContentBlock[], overrides?: Partial<Omit<MessageItem, "type" | "content">>): MessageItem;
569
+ declare function reasoningItem(content: ContentBlock[], visibility?: ReasoningItem["visibility"], id?: string): ReasoningItem;
570
+ declare function toolCallItem(id: string, name: string, argumentsText: string): ToolCallItem;
571
+ declare function toolResultItem(callId: string, toolName: string, outcome: ToolResultItem["outcome"], content: ContentBlock[]): ToolResultItem;
572
+ declare function opaqueItem(source: OpaqueItem["source"], purpose: OpaqueItem["purpose"], payload: unknown, id?: string): OpaqueItem;
573
+ declare function serverToolCallItem(id: string, tool: ServerToolCallItem["tool"], overrides?: Partial<Omit<ServerToolCallItem, "type" | "id" | "tool">>): ServerToolCallItem;
574
+ declare function serverToolResultItem(callId: string, tool: string, outcome: ServerToolResultItem["outcome"], content: ContentBlock[], overrides?: Partial<Omit<ServerToolResultItem, "type" | "callId" | "tool" | "outcome" | "content">>): ServerToolResultItem;
575
+ declare function serverToolDiscoveryItem(id: string, serverLabel: string, tools: ServerToolDiscoveryItem["tools"], overrides?: Partial<Omit<ServerToolDiscoveryItem, "type" | "id" | "tool" | "serverLabel" | "tools">>): ServerToolDiscoveryItem;
351
576
  //#endregion
352
- //#region src/core/event-factory.d.ts
577
+ //#region src/canonical/replay.d.ts
578
+ /**
579
+ * 从 output items 构建标准 replay items。
580
+ * 简单场景下 replay 与 output 一致。
581
+ * 复杂场景(需要 opaque continuation)由 adapter 自行扩展。
582
+ */
583
+ declare function replayFromOutput(output: readonly OutputItem[]): ReplayItem[];
584
+ /**
585
+ * 从 OutputItem 数组中提取所有 message 类型 item 的文本内容。
586
+ */
587
+ declare function extractText(output: OutputItem[]): string;
588
+ //#endregion
589
+ //#region src/stream/event-factory.d.ts
353
590
  type EventFactoryBackend = {
354
- kind: "chat-completions" | "messages" | "responses" | "ollama" | "mock";
591
+ kind: AdapterKind;
355
592
  isSynthetic: boolean;
356
593
  };
357
594
  type EventFactoryState = {
@@ -360,7 +597,7 @@ type EventFactoryState = {
360
597
  };
361
598
  declare function createEventFactory(state: EventFactoryState): {
362
599
  responseStarted(model: string): ResponseStartedEvent;
363
- responseWarning(message: string, code?: string): ResponseWarningEvent;
600
+ responseWarning(message: string, code?: WarningCodeValue): ResponseWarningEvent;
364
601
  responseAuxiliary(data: {
365
602
  usage?: Usage;
366
603
  billing?: BillingInfo;
@@ -372,13 +609,15 @@ declare function createEventFactory(state: EventFactoryState): {
372
609
  usage?: Usage;
373
610
  billing?: BillingInfo;
374
611
  auxiliary?: AuxiliaryInfo;
375
- warnings?: string[];
612
+ warnings?: StreamWarning[];
376
613
  opaqueOutput?: OpaqueItem[];
377
614
  trace?: Partial<BackendTrace>;
378
615
  }): ResponseCompletedEvent;
379
616
  messageStarted(id: string): MessageStartedEvent;
380
617
  messageDelta(itemId: string, delta: ContentBlock): MessageDeltaEvent;
381
- messageCompleted(itemId: string): MessageCompletedEvent;
618
+ messageCompleted(itemId: string, options?: {
619
+ citations?: Citation[];
620
+ }): MessageCompletedEvent;
382
621
  reasoningStarted(id: string, visibility: ReasoningItem["visibility"]): ReasoningStartedEvent;
383
622
  reasoningDelta(itemId: string, delta: ContentBlock): ReasoningDeltaEvent;
384
623
  reasoningCompleted(itemId: string): ReasoningCompletedEvent;
@@ -386,23 +625,26 @@ declare function createEventFactory(state: EventFactoryState): {
386
625
  toolCallDelta(itemId: string, delta: {
387
626
  argumentsText?: string;
388
627
  }): ToolCallDeltaEvent;
389
- toolCallCompleted(itemId: string): ToolCallCompletedEvent; /** 返回当前已发出的 sequence 计数(用于断言) */
628
+ toolCallCompleted(itemId: string): ToolCallCompletedEvent;
629
+ serverToolStarted(id: string, tool: string, options?: {
630
+ name?: string;
631
+ serverLabel?: string;
632
+ }): ServerToolStartedEvent;
633
+ serverToolDelta(itemId: string, delta: {
634
+ argumentsText?: string;
635
+ }): ServerToolDeltaEvent;
636
+ serverToolCompleted(itemId: string, options?: {
637
+ status?: "completed" | "failed";
638
+ providerPayload?: unknown;
639
+ }): ServerToolCompletedEvent;
640
+ serverToolResultCompleted(item: ServerToolResultItem): ServerToolResultCompletedEvent;
641
+ serverToolDiscoveryCompleted(item: ServerToolDiscoveryItem): ServerToolDiscoveryCompletedEvent; /** 返回当前已发出的 sequence 计数(用于断言) */
390
642
  readonly sequence: number; /** 返回当前已记录的 warning 副本。 */
391
- readonly warnings: string[];
643
+ readonly warnings: StreamWarning[];
392
644
  };
393
645
  type EventFactory = ReturnType<typeof createEventFactory>;
394
646
  //#endregion
395
- //#region src/core/aggregator.d.ts
396
- /**
397
- * 将事件数组聚合为 AIResponse。
398
- * 适用于测试和离线处理场景。
399
- */
400
- declare function aggregateEvents(events: readonly AIStreamEvent[]): AIResponse;
401
- //#endregion
402
- //#region src/core/collect-stream.d.ts
403
- declare function collectStream(stream: AsyncIterable<AIStreamEvent>): Promise<AIResponse>;
404
- //#endregion
405
- //#region src/helpers/auxiliary-collector.d.ts
647
+ //#region src/provider/auxiliary-collector.d.ts
406
648
  type UsageSource = NonNullable<AuxiliaryInfo["usageSource"]>;
407
649
  type BillingSource = NonNullable<AuxiliaryInfo["billingSource"]>;
408
650
  type LookupResult = {
@@ -410,70 +652,26 @@ type LookupResult = {
410
652
  billing?: Partial<BillingInfo>;
411
653
  providerMetadata?: Record<string, unknown>;
412
654
  };
413
- declare class AuxiliaryCollector {
414
- private usage;
415
- private usageSource;
416
- private billing;
417
- private billingSource;
418
- private providerMetadata;
419
- private providerUsage;
420
- private providerBilling;
421
- private warnings;
422
- private lookupAttempted;
423
- /**
424
- * 记录 usage 信息。
425
- * 后调用的覆盖先调用的(优先级由调用方控制)。
426
- */
427
- recordUsage(usage: Partial<Usage>, source: UsageSource, raw?: unknown): this;
428
- /**
429
- * 记录 billing 信息。
430
- * 后调用的覆盖先调用的。
431
- */
432
- recordBilling(billing: Partial<BillingInfo>, source: BillingSource, raw?: unknown): this;
433
- /**
434
- * 记录 provider 元数据(非 canonical 的 key-value 信息)。
435
- */
436
- recordMetadata(metadata: Record<string, unknown>): this;
437
- /**
438
- * 记录一条 warning。
439
- */
440
- recordWarning(message: string): this;
441
- /**
442
- * 执行一次有界 follow-up lookup。
443
- * 最多调用一次;后续调用被忽略。
444
- * lookup 失败(抛错)仅记录 warning,不传播异常。
445
- */
446
- tryLookup(lookupFn: () => Promise<LookupResult>, timeoutMs?: number): Promise<void>;
447
- /**
448
- * 构建最终的 usage / billing / auxiliary。
449
- * 所有字段均为可选的 — 拿不到就不给。
450
- */
451
- build(): {
452
- usage?: Usage;
453
- billing?: BillingInfo;
454
- auxiliary?: AuxiliaryInfo;
455
- warnings?: string[];
456
- };
457
- /**
458
- * 已使用的来源列表(用于 debugging)。
459
- */
460
- get sources(): {
461
- usage?: UsageSource;
462
- billing?: BillingSource;
463
- };
464
- }
465
655
  //#endregion
466
- //#region src/helpers/adapter-auxiliary.d.ts
656
+ //#region src/provider/auxiliary.d.ts
467
657
  type MaybePromise<T> = T | Promise<T>;
658
+ /**
659
+ * 实验性:由调用方接线;库内 HTTP adapter **未**默认启用。
660
+ * 用于从 usage/auxiliary 派生 billing 的后处理钩子。
661
+ */
468
662
  type BillingPostprocessHook = (context: {
469
663
  request: NormalizedRequest;
470
664
  usage?: Usage;
471
665
  billing?: BillingInfo;
472
666
  auxiliary?: AuxiliaryInfo;
473
667
  }) => MaybePromise<Partial<BillingInfo> | undefined>;
668
+ /**
669
+ * finalize 选项。`lookup` / `postprocessBilling` 为 experimental unused 扩展点:
670
+ * 生产 adapter 当前不传入;仅测试或宿主自定义 wiring 使用。
671
+ */
474
672
  type AuxiliaryFinalizeOptions = {
475
- lookup?: () => Promise<LookupResult>;
476
- lookupTimeoutMs?: number;
673
+ /** experimental:异步补查 usage/billing */lookup?: () => Promise<LookupResult>;
674
+ lookupTimeoutMs?: number; /** experimental:在尚无 billing 时派生估算账单 */
477
675
  postprocessBilling?: BillingPostprocessHook;
478
676
  postprocessBillingSource?: BillingSource;
479
677
  };
@@ -482,7 +680,7 @@ type AuxiliaryFinalizeResult = {
482
680
  usage?: Usage;
483
681
  billing?: BillingInfo;
484
682
  auxiliary?: AuxiliaryInfo;
485
- warnings?: string[];
683
+ warnings?: StreamWarning[];
486
684
  metadataSources?: string[];
487
685
  };
488
686
  declare class AdapterAuxiliaryState {
@@ -496,32 +694,36 @@ declare class AdapterAuxiliaryState {
496
694
  finalize(factory: EventFactory, options?: AuxiliaryFinalizeOptions): Promise<AuxiliaryFinalizeResult>;
497
695
  private shouldAttemptLookup;
498
696
  }
499
- declare function emitMalformedStreamWarning(factory: EventFactory, options: {
500
- count: number;
501
- providerLabel: string;
502
- transportLabel: string;
503
- }): AIStreamEvent | undefined;
504
697
  //#endregion
505
- //#region src/helpers/adapter-base.d.ts
698
+ //#region src/provider/base.d.ts
506
699
  type ProviderResponse = unknown;
507
700
  /**
508
- * adapter 完成一轮处理后返回的最终结果。
509
- * 用于 buildResponse() 构建 AIResponse。
701
+ * adapter 完成一轮流处理后交给 emitStreamCompleted 的元数据。
702
+ * 不含 output/text/toolCalls 那些由事件聚合得到。
510
703
  */
511
704
  type StreamResult = {
512
- output: OutputItem[];
513
705
  replay: ReplayItem[];
514
706
  stopReason?: StopReason;
515
707
  usage?: Usage;
516
708
  billing?: BillingInfo;
517
709
  providerMetadata?: Record<string, unknown>;
518
710
  auxiliary?: Partial<AuxiliaryInfo>;
519
- warnings?: string[];
711
+ warnings?: StreamWarning[];
520
712
  metadataSources?: string[];
521
713
  rawResponseId?: string;
522
714
  };
715
+ /** response.completed 所需的完成元数据(无 output 账本) */
716
+ type StreamCompletedPayload = {
717
+ replay: ReplayItem[];
718
+ stopReason?: StopReason;
719
+ usage?: Usage;
720
+ billing?: BillingInfo;
721
+ auxiliary?: AuxiliaryInfo;
722
+ warnings?: StreamWarning[] | undefined;
723
+ trace: Partial<BackendTrace>;
724
+ };
523
725
  declare abstract class AdapterBase implements BackendAdapter {
524
- abstract readonly kind: "chat-completions" | "messages" | "responses" | "ollama" | "mock";
726
+ abstract readonly kind: AdapterKind;
525
727
  abstract readonly isSyntheticStream: boolean;
526
728
  /**
527
729
  * stream 模板方法:
@@ -537,32 +739,133 @@ declare abstract class AdapterBase implements BackendAdapter {
537
739
  * 子类负责:
538
740
  * - 调用 provider
539
741
  * - 解析每个 chunk
540
- * - 通过 factory 发射 item 事件
541
- * - 构建 StreamResult
542
- * - 发射 factory.responseCompleted(buildResponse(…))
742
+ * - 通过 StreamingItemSession / factory 发射 item 事件
743
+ * - 组装 StreamResult(replay + 元数据)
744
+ * - 发射 response.completed(通常经 emitStreamCompleted)
543
745
  */
544
746
  protected abstract runStream(providerRequest: ProviderResponse, factory: EventFactory, request: NormalizedRequest): AsyncIterable<AIStreamEvent>;
545
747
  /**
546
- * 从 StreamResult 构建完整 AIResponse。
547
- * 子类可在返回前自定义覆盖。
748
+ * 从 StreamResult 构建 response.completed 载荷(无 output/text/toolCalls)。
548
749
  */
549
- protected buildResponse(request: NormalizedRequest, result: StreamResult, _factory: EventFactory): AIResponse;
750
+ protected buildCompletedPayload(request: NormalizedRequest, result: StreamResult, factory: EventFactory): StreamCompletedPayload;
550
751
  /**
551
752
  * 统一 finalize auxiliary → response.completed。
552
- * adapter 在调用前组装 output / replay / stopReason 等业务字段。
753
+ * adapter 在调用前组装 replay / stopReason 等业务字段(不含 output 账本)。
553
754
  */
554
755
  protected emitStreamCompleted(factory: EventFactory, request: NormalizedRequest, auxiliary: AdapterAuxiliaryState, result: StreamResult): AsyncIterable<AIStreamEvent>;
555
756
  protected createAuxiliaryState(request: NormalizedRequest): AdapterAuxiliaryState;
556
757
  }
557
758
  //#endregion
558
- //#region src/adapters/responses.d.ts
559
- type ResponsesAdapterOptions = {
560
- apiKey: string;
561
- baseUrl?: string; /** 可注入自定义 fetch 实现(用于测试/代理) */
562
- fetch?: FetchFn; /** 额外请求头;后写覆盖内置 Authorization / Content-Type */
759
+ //#region src/provider/transport/parser.d.ts
760
+ type StreamSplitResult = {
761
+ items: string[];
762
+ rest: string;
763
+ };
764
+ type StreamParseResult<T> = {
765
+ status: "parsed";
766
+ value: T;
767
+ } | {
768
+ status: "ignored";
769
+ } | {
770
+ status: "malformed";
771
+ };
772
+ declare class IncrementalStreamParser<T> {
773
+ private readonly split;
774
+ private readonly parse;
775
+ /** Pending decoded fragments; compacted to at most one rest string after each consume. */
776
+ private chunks;
777
+ private readonly decoder;
778
+ constructor(split: (buffer: string, allowEOF: boolean) => StreamSplitResult, parse: (item: string) => StreamParseResult<T>);
779
+ feed(value: Uint8Array): {
780
+ items: T[];
781
+ malformed: number;
782
+ };
783
+ flush(): {
784
+ items: T[];
785
+ malformed: number;
786
+ };
787
+ getRemaining(): string;
788
+ private materializeBuffer;
789
+ private consume;
790
+ }
791
+ //#endregion
792
+ //#region src/provider/transport/open-stream.d.ts
793
+ type ProviderStreamBatch<T> = {
794
+ items: T[];
795
+ warnings: AIStreamEvent[];
796
+ };
797
+ //#endregion
798
+ //#region src/provider/transport/run-json-stream.d.ts
799
+ type ProviderJsonStreamOpenOptions = {
800
+ url: string;
801
+ headers: Record<string, string>;
802
+ body: unknown;
803
+ };
804
+ type ProviderJsonStreamBatchOptions<T> = {
805
+ parser: IncrementalStreamParser<T>;
806
+ providerLabel: string;
807
+ transportLabel: string;
808
+ incompleteMessage: string;
809
+ };
810
+ type ProviderJsonStreamCompleteOptions = {
811
+ /**
812
+ * 重复 complete 时:`warn` 发 DUPLICATE_FINISH(默认,对齐 chat/gemini/ollama);
813
+ * `silent` 静默忽略(messages/responses 历史路径几乎不会触发)。
814
+ */
815
+ onDuplicate?: "warn" | "silent";
816
+ };
817
+ type ProviderJsonStreamSession = {
818
+ readonly auxiliary: AdapterAuxiliaryState;
819
+ readonly gate: {
820
+ readonly completed: boolean;
821
+ tryComplete(): boolean;
822
+ }; /** open 成功后填充的 response headers */
823
+ readonly headers: Headers | undefined;
824
+ open(options: ProviderJsonStreamOpenOptions): Promise<{
825
+ headers: Headers;
826
+ }>;
827
+ batches<T>(options: ProviderJsonStreamBatchOptions<T>): AsyncGenerator<ProviderStreamBatch<T>, void, undefined>;
828
+ complete(result: StreamResult, options?: ProviderJsonStreamCompleteOptions): AsyncIterable<AIStreamEvent>;
829
+ };
830
+ //#endregion
831
+ //#region src/provider/http-adapter.d.ts
832
+ /** 真实 HTTP adapter 的公共构造选项;apiKey 由各 adapter 收紧或保持可选。 */
833
+ type HttpAdapterOptions = {
834
+ apiKey?: string;
835
+ baseUrl?: string; /** 可注入自定义 fetch 实现(测试 / 代理) */
836
+ fetch?: FetchFn; /** 额外请求头;后写覆盖内置鉴权 / Content-Type 等 */
563
837
  headers?: Record<string, string>; /** 额外 body 顶层字段;浅层合并,同名键可覆盖 */
564
838
  extraBody?: Record<string, unknown>;
565
839
  };
840
+ type HttpAdapterDefaults = {
841
+ baseUrl: string;
842
+ };
843
+ /**
844
+ * HTTP adapter 薄基类:统一字段、默认值与 JSON 流 session。
845
+ */
846
+ declare abstract class HttpAdapterBase extends AdapterBase {
847
+ protected apiKey: string | undefined;
848
+ protected baseUrl: string;
849
+ protected fetchFn: FetchFn;
850
+ protected headers: Record<string, string> | undefined;
851
+ protected extraBody: Record<string, unknown> | undefined;
852
+ constructor(options: HttpAdapterOptions, defaults: HttpAdapterDefaults);
853
+ /** 合并内置 headers 与构造期自定义 headers。 */
854
+ protected mergeHeaders(base: Record<string, string>): Record<string, string>;
855
+ /** 将构造期 extraBody 浅层合并进已构建 body。 */
856
+ protected withExtraBody<T extends object>(body: T): T;
857
+ /**
858
+ * 开启 JSON provider 流 session(auxiliary + gate + open/batches/complete)。
859
+ * 不自动 complete;调用方在业务 finish 点 `yield* session.complete(...)`。
860
+ */
861
+ protected beginJsonStream(factory: EventFactory, request: NormalizedRequest): ProviderJsonStreamSession;
862
+ }
863
+ //#endregion
864
+ //#region src/adapters/responses/types.d.ts
865
+ /** apiKey 必填;默认 baseUrl https://api.openai.com/v1 */
866
+ type ResponsesAdapterOptions = HttpAdapterOptions & {
867
+ apiKey: string;
868
+ };
566
869
  type ResponsesAPIRequest = {
567
870
  model: string;
568
871
  input: ResponsesInputItem[];
@@ -636,36 +939,83 @@ type ResponsesItemReference = {
636
939
  type: "item_reference";
637
940
  id: string;
638
941
  };
639
- type ResponsesInputItem = ResponsesEasyMessage | ResponsesFunctionCall | ResponsesFunctionCallOutput | ResponsesReasoningInput | ResponsesItemReference;
640
- type ResponsesTool = {
942
+ /** compact 输出中的加密 compaction 项(可原样回传为 input) */
943
+ type ResponsesCompactionInput = {
944
+ type: "compaction";
945
+ id?: string;
946
+ encrypted_content?: string;
947
+ [key: string]: unknown;
948
+ };
949
+ /**
950
+ * 保真透传的 wire item(compact window 中可能含 message/function_call/compaction 等)。
951
+ * 用于 compacted_window 原样展开,不在此做严格 shape 收窄。
952
+ */
953
+ type ResponsesWirePassthroughItem = {
954
+ type: string;
955
+ [key: string]: unknown;
956
+ };
957
+ type ResponsesInputItem = ResponsesEasyMessage | ResponsesFunctionCall | ResponsesFunctionCallOutput | ResponsesReasoningInput | ResponsesItemReference | ResponsesCompactionInput | ResponsesWirePassthroughItem;
958
+ type ResponsesFunctionTool = {
641
959
  type: "function";
642
960
  name: string;
643
961
  description?: string;
644
962
  parameters: Record<string, unknown>;
645
963
  strict?: boolean | null;
646
964
  };
647
- declare class ResponsesAdapter extends AdapterBase {
965
+ type ResponsesWebSearchTool = {
966
+ type: "web_search";
967
+ filters?: {
968
+ allowed_domains?: string[];
969
+ blocked_domains?: string[];
970
+ };
971
+ user_location?: {
972
+ type: "approximate";
973
+ country?: string;
974
+ city?: string;
975
+ region?: string;
976
+ timezone?: string;
977
+ };
978
+ search_context_size?: "low" | "medium" | "high";
979
+ };
980
+ type ResponsesCodeInterpreterTool = {
981
+ type: "code_interpreter";
982
+ container: string | {
983
+ type: "auto";
984
+ memory_limit?: "1g" | "4g" | "16g" | "64g";
985
+ file_ids?: string[];
986
+ };
987
+ };
988
+ type ResponsesMcpTool = {
989
+ type: "mcp";
990
+ server_label: string;
991
+ server_url: string;
992
+ server_description?: string;
993
+ authorization?: string;
994
+ allowed_tools?: string[];
995
+ require_approval: "never";
996
+ };
997
+ /** Responses API tools 联合:客户端 function + 内置 server tools */
998
+ type ResponsesTool = ResponsesFunctionTool | ResponsesWebSearchTool | ResponsesCodeInterpreterTool | ResponsesMcpTool;
999
+ //#endregion
1000
+ //#region src/adapters/responses/adapter.d.ts
1001
+ declare class ResponsesAdapter extends HttpAdapterBase implements ContextCompressCapable {
648
1002
  readonly kind: "responses";
649
1003
  readonly isSyntheticStream = false;
650
- private apiKey;
651
- private baseUrl;
652
- private fetchFn;
653
- private headers;
654
- private extraBody;
655
1004
  constructor(options: ResponsesAdapterOptions);
656
1005
  protected buildRequest(request: NormalizedRequest): ResponsesAPIRequest;
1006
+ /**
1007
+ * 原生上下文压缩:POST /responses/compact。
1008
+ * 结果以单个 opaque(kind=compacted_window) 回传;调用方用 replay 替换旧 transcript。
1009
+ */
1010
+ compress(request: CompressRequest): Promise<CompressResult>;
657
1011
  protected runStream(providerRequest: ResponsesAPIRequest, factory: EventFactory, request: NormalizedRequest): AsyncIterable<AIStreamEvent>;
658
- private inferStopReason;
659
1012
  }
660
1013
  //#endregion
661
- //#region src/adapters/messages.d.ts
662
- type MessagesAdapterOptions = {
663
- apiKey: string;
1014
+ //#region src/adapters/messages/types.d.ts
1015
+ /** apiKey 必填;默认 baseUrl https://api.anthropic.com/v1 */
1016
+ type MessagesAdapterOptions = HttpAdapterOptions & {
1017
+ apiKey: string; /** Anthropic API 版本头,默认 2023-06-01 */
664
1018
  apiVersion?: string;
665
- baseUrl?: string; /** 可注入自定义 fetch 实现(用于测试/代理) */
666
- fetch?: FetchFn; /** 额外请求头;后写覆盖内置 x-api-key / Content-Type / anthropic-version */
667
- headers?: Record<string, string>; /** 额外 body 顶层字段;浅层合并,同名键可覆盖 */
668
- extraBody?: Record<string, unknown>;
669
1019
  };
670
1020
  type MessagesAPIRequest = {
671
1021
  model: string;
@@ -718,27 +1068,21 @@ type MessagesAPITool = {
718
1068
  description?: string;
719
1069
  input_schema: Record<string, unknown>;
720
1070
  };
721
- declare class MessagesAdapter extends AdapterBase {
1071
+ //#endregion
1072
+ //#region src/adapters/messages/adapter.d.ts
1073
+ declare class MessagesAdapter extends HttpAdapterBase {
722
1074
  readonly kind: "messages";
723
1075
  readonly isSyntheticStream = false;
724
- private apiKey;
725
1076
  private apiVersion;
726
- private baseUrl;
727
- private fetchFn;
728
- private headers;
729
- private extraBody;
730
1077
  constructor(options: MessagesAdapterOptions);
731
1078
  protected buildRequest(request: NormalizedRequest): MessagesAPIRequest;
732
1079
  protected runStream(providerRequest: MessagesAPIRequest, factory: EventFactory, request: NormalizedRequest): AsyncIterable<AIStreamEvent>;
733
1080
  }
734
1081
  //#endregion
735
- //#region src/adapters/chat-completions.d.ts
736
- type ChatCompletionsAdapterOptions = {
1082
+ //#region src/adapters/chat-completions/types.d.ts
1083
+ /** apiKey 必填;默认 baseUrl https://api.openai.com/v1 */
1084
+ type ChatCompletionsAdapterOptions = HttpAdapterOptions & {
737
1085
  apiKey: string;
738
- baseUrl?: string;
739
- fetch?: FetchFn; /** 额外请求头;后写覆盖内置 Authorization / Content-Type */
740
- headers?: Record<string, string>; /** 额外 body 顶层字段;浅层合并,同名键可覆盖 */
741
- extraBody?: Record<string, unknown>;
742
1086
  };
743
1087
  type ChatRequest = {
744
1088
  model: string;
@@ -781,27 +1125,21 @@ type ChatTool = {
781
1125
  parameters: Record<string, unknown>;
782
1126
  };
783
1127
  };
784
- declare class ChatCompletionsAdapter extends AdapterBase {
1128
+ //#endregion
1129
+ //#region src/adapters/chat-completions/adapter.d.ts
1130
+ declare class ChatCompletionsAdapter extends HttpAdapterBase {
785
1131
  readonly kind: "chat-completions";
786
1132
  readonly isSyntheticStream = false;
787
- private apiKey;
788
- private baseUrl;
789
- private fetchFn;
790
- private headers;
791
- private extraBody;
792
1133
  constructor(options: ChatCompletionsAdapterOptions);
793
1134
  protected buildRequest(request: NormalizedRequest): ChatRequest;
794
1135
  protected runStream(providerRequest: ChatRequest, factory: EventFactory, request: NormalizedRequest): AsyncIterable<AIStreamEvent>;
795
1136
  }
796
1137
  //#endregion
797
- //#region src/adapters/ollama.d.ts
798
- type OllamaAdapterOptions = {
799
- /** Ollama 服务地址,默认 http://localhost:11434 */baseUrl?: string; /** 可选 API key(用于需要认证的代理场景) */
800
- apiKey?: string; /** 可注入自定义 fetch 实现 */
801
- fetch?: FetchFn; /** 额外请求头;后写覆盖内置 Content-Type / Authorization */
802
- headers?: Record<string, string>; /** 额外 body 顶层字段;浅层合并,同名键可覆盖 */
803
- extraBody?: Record<string, unknown>;
804
- };
1138
+ //#region src/adapters/ollama/types.d.ts
1139
+ /**
1140
+ * apiKey 可选(代理鉴权);默认 baseUrl http://localhost:11434
1141
+ */
1142
+ type OllamaAdapterOptions = HttpAdapterOptions;
805
1143
  type OllamaChatRequest = {
806
1144
  model: string;
807
1145
  messages: OllamaMessage[];
@@ -834,20 +1172,86 @@ type OllamaTool = {
834
1172
  parameters: Record<string, unknown>;
835
1173
  };
836
1174
  };
837
- declare class OllamaAdapter extends AdapterBase {
1175
+ //#endregion
1176
+ //#region src/adapters/ollama/adapter.d.ts
1177
+ declare class OllamaAdapter extends HttpAdapterBase {
838
1178
  readonly kind: "ollama";
839
1179
  readonly isSyntheticStream = false;
840
- private baseUrl;
841
- private apiKey;
842
- private fetchFn;
843
- private headers;
844
- private extraBody;
845
1180
  constructor(options?: OllamaAdapterOptions);
846
1181
  protected buildRequest(request: NormalizedRequest): OllamaChatRequest;
847
1182
  protected runStream(providerRequest: OllamaChatRequest, factory: EventFactory, request: NormalizedRequest): AsyncIterable<AIStreamEvent>;
848
1183
  }
849
1184
  //#endregion
850
- //#region src/adapters/mock.d.ts
1185
+ //#region src/adapters/gemini/types.d.ts
1186
+ /** apiKey 必填;默认 baseUrl https://generativelanguage.googleapis.com/v1beta */
1187
+ type GeminiAdapterOptions = HttpAdapterOptions & {
1188
+ apiKey: string;
1189
+ };
1190
+ type GeminiPart = {
1191
+ text?: string;
1192
+ thought?: boolean;
1193
+ thoughtSignature?: string;
1194
+ functionCall?: {
1195
+ name: string;
1196
+ args?: Record<string, unknown>;
1197
+ id?: string;
1198
+ };
1199
+ functionResponse?: {
1200
+ name: string;
1201
+ response?: Record<string, unknown>;
1202
+ id?: string;
1203
+ };
1204
+ [key: string]: unknown;
1205
+ };
1206
+ type GeminiContent = {
1207
+ role: "user" | "model";
1208
+ parts: GeminiPart[];
1209
+ };
1210
+ type GeminiFunctionDeclaration = {
1211
+ name: string;
1212
+ description?: string;
1213
+ parameters: Record<string, unknown>;
1214
+ };
1215
+ type GeminiTool = {
1216
+ functionDeclarations: GeminiFunctionDeclaration[];
1217
+ };
1218
+ type GeminiFunctionCallingConfig = {
1219
+ mode: "AUTO" | "ANY" | "NONE";
1220
+ allowedFunctionNames?: string[];
1221
+ };
1222
+ type GeminiGenerateContentRequest = {
1223
+ contents: GeminiContent[];
1224
+ systemInstruction?: {
1225
+ parts: Array<{
1226
+ text: string;
1227
+ }>;
1228
+ };
1229
+ tools?: GeminiTool[];
1230
+ toolConfig?: {
1231
+ functionCallingConfig: GeminiFunctionCallingConfig;
1232
+ };
1233
+ generationConfig?: {
1234
+ temperature?: number;
1235
+ maxOutputTokens?: number;
1236
+ thinkingConfig?: {
1237
+ includeThoughts: false;
1238
+ } | {
1239
+ includeThoughts: true;
1240
+ thinkingLevel: "MINIMAL" | "LOW" | "MEDIUM" | "HIGH";
1241
+ };
1242
+ };
1243
+ };
1244
+ //#endregion
1245
+ //#region src/adapters/gemini/adapter.d.ts
1246
+ declare class GeminiAdapter extends HttpAdapterBase {
1247
+ readonly kind: "gemini";
1248
+ readonly isSyntheticStream = false;
1249
+ constructor(options: GeminiAdapterOptions);
1250
+ protected buildRequest(request: NormalizedRequest): GeminiGenerateContentRequest;
1251
+ protected runStream(providerRequest: GeminiGenerateContentRequest, factory: EventFactory, request: NormalizedRequest): AsyncIterable<AIStreamEvent>;
1252
+ }
1253
+ //#endregion
1254
+ //#region src/adapters/mock/types.d.ts
851
1255
  type MockInputExpectation = {
852
1256
  type: InputItem["type"];
853
1257
  id?: string;
@@ -855,7 +1259,7 @@ type MockInputExpectation = {
855
1259
  name?: string;
856
1260
  toolName?: string;
857
1261
  callId?: string;
858
- outcome?: ToolResultItem["outcome"];
1262
+ outcome?: ToolResultItem["outcome"] | ServerToolResultItem["outcome"];
859
1263
  visibility?: Extract<InputItem, {
860
1264
  type: "reasoning";
861
1265
  }>["visibility"];
@@ -874,6 +1278,7 @@ type MockRequestExpectation = {
874
1278
  requireReplayFromPreviousTurn?: boolean;
875
1279
  requireToolResultsForPendingCalls?: boolean;
876
1280
  tools?: "ignore" | "present" | "absent";
1281
+ serverTools?: "ignore" | "present" | "absent";
877
1282
  toolChoice?: "ignore" | "present" | "absent";
878
1283
  items?: MockInputExpectation[];
879
1284
  };
@@ -920,8 +1325,29 @@ type MockMessageStep = {
920
1325
  type: "message";
921
1326
  id?: string;
922
1327
  content: string | ContentBlock[];
1328
+ citations?: Citation[];
923
1329
  stream?: MockTextStreamOptions | false;
924
1330
  };
1331
+ type MockServerToolCallStep = {
1332
+ type: "server_tool_call";
1333
+ id: string;
1334
+ tool: ServerToolCallItem["tool"];
1335
+ name?: string;
1336
+ argumentsText?: string;
1337
+ serverLabel?: string;
1338
+ status?: ServerToolCallItem["status"];
1339
+ providerPayload?: unknown;
1340
+ streamArguments?: boolean;
1341
+ stream?: MockTextStreamOptions | false;
1342
+ };
1343
+ type MockServerToolResultStep = {
1344
+ type: "server_tool_result";
1345
+ item: ServerToolResultItem;
1346
+ };
1347
+ type MockServerToolDiscoveryStep = {
1348
+ type: "server_tool_discovery";
1349
+ item: ServerToolDiscoveryItem;
1350
+ };
925
1351
  type MockReasoningStep = {
926
1352
  type: "reasoning";
927
1353
  id?: string;
@@ -955,7 +1381,7 @@ type MockCompleteStep = {
955
1381
  auxiliary?: Partial<AuxiliaryInfo>;
956
1382
  providerMetadata?: Record<string, unknown>;
957
1383
  rawResponseId?: string;
958
- warnings?: string[];
1384
+ warnings?: StreamWarning[];
959
1385
  };
960
1386
  type MockErrorStep = {
961
1387
  type: "error";
@@ -971,13 +1397,16 @@ type MockThrowStep = {
971
1397
  type: "throw";
972
1398
  error: string | Error;
973
1399
  };
974
- type MockStep = MockWarningStep | MockAuxiliaryStep | MockMessageStep | MockReasoningStep | MockToolCallStep | MockOutputStep | MockCompleteStep | MockErrorStep | MockInterruptStep | MockThrowStep;
1400
+ type MockStep = MockWarningStep | MockAuxiliaryStep | MockMessageStep | MockReasoningStep | MockToolCallStep | MockServerToolCallStep | MockServerToolResultStep | MockServerToolDiscoveryStep | MockOutputStep | MockCompleteStep | MockErrorStep | MockInterruptStep | MockThrowStep;
975
1401
  type MockHandler = (request: NormalizedRequest, context: MockHandlerContext) => AsyncIterable<MockStep>;
976
1402
  type MockHandlerSource = Iterable<MockStep> | AsyncIterable<MockStep>;
977
1403
  type MockStaticHandler = (request: NormalizedRequest, context: MockHandlerContext) => MockHandlerSource | Promise<MockHandlerSource>;
1404
+ /** Mock compress 夹具;未配置时 compress() 抛 MOCK_COMPRESS_NOT_CONFIGURED */
1405
+ type MockCompressHandler = (request: CompressRequest) => CompressResult | Promise<CompressResult>;
978
1406
  type MockAdapterOptions = {
979
1407
  handler: MockHandler;
980
- providerMetadata?: Record<string, unknown>;
1408
+ providerMetadata?: Record<string, unknown>; /** 可选:实现 ContextCompressCapable 供 compress 契约测试 */
1409
+ compressHandler?: MockCompressHandler;
981
1410
  };
982
1411
  type MockProviderRequest = {
983
1412
  request: NormalizedRequest;
@@ -985,326 +1414,36 @@ type MockProviderRequest = {
985
1414
  turnIndex: number;
986
1415
  remainingPendingToolCalls: ToolCallItem[];
987
1416
  };
988
- declare function assertMockRequest(request: NormalizedRequest, expectation: MockRequestExpectation, context: MockHandlerContext): void;
989
- declare class MockAdapter extends AdapterBase {
1417
+ //#endregion
1418
+ //#region src/adapters/mock/adapter.d.ts
1419
+ declare class MockAdapter extends AdapterBase implements ContextCompressCapable {
990
1420
  readonly kind: "mock";
991
1421
  readonly isSyntheticStream = true;
992
1422
  private readonly handler;
993
1423
  private readonly providerMetadata?;
1424
+ private readonly compressHandler?;
994
1425
  private cursor;
995
1426
  private previousReplay;
996
1427
  private pendingToolCalls;
997
1428
  private history;
998
1429
  private activeStream;
999
1430
  constructor(options: MockAdapterOptions);
1431
+ /**
1432
+ * 可选压缩夹具:需构造时提供 compressHandler,否则抛 MOCK_COMPRESS_NOT_CONFIGURED。
1433
+ * 始终存在 compress 方法以便 supportsContextCompress(mock) === true。
1434
+ */
1435
+ compress(request: CompressRequest): Promise<CompressResult>;
1000
1436
  protected buildRequest(request: NormalizedRequest): Promise<MockProviderRequest>;
1001
1437
  protected runStream(providerRequest: unknown, factory: EventFactory, request: NormalizedRequest): AsyncIterable<AIStreamEvent>;
1002
1438
  private finalizeTurn;
1003
1439
  private buildHandlerContext;
1004
1440
  }
1005
- declare function withMockStreaming(handler: MockStaticHandler, options: MockTextStreamOptions): MockHandler;
1006
1441
  //#endregion
1007
- //#region src/helpers/mapping.d.ts
1008
- declare function mapStopReason(providerReason: string): StopReason;
1009
- declare function mapReasoningVisibility(hasThinking: boolean, hasRedacted: boolean): ReasoningItem["visibility"];
1010
- declare function textBlock(text: string): ContentBlock & {
1011
- type: "text";
1012
- };
1013
- declare function jsonBlock(json: unknown): ContentBlock & {
1014
- type: "json";
1015
- };
1016
- declare function imageBlock(imageUrl: string): ContentBlock & {
1017
- type: "image";
1018
- };
1019
- declare function opaqueBlock(payload: unknown): ContentBlock & {
1020
- type: "opaque";
1021
- };
1022
- declare function messageItem(content: ContentBlock[], overrides?: Partial<Omit<MessageItem, "type" | "content">>): MessageItem;
1023
- declare function reasoningItem(content: ContentBlock[], visibility?: ReasoningItem["visibility"], id?: string): ReasoningItem;
1024
- declare function toolCallItem(id: string, name: string, argumentsText: string): ToolCallItem;
1025
- declare function toolResultItem(callId: string, toolName: string, outcome: ToolResultItem["outcome"], content: ContentBlock[]): ToolResultItem;
1026
- declare function opaqueItem(source: OpaqueItem["source"], purpose: OpaqueItem["purpose"], payload: unknown, id?: string): OpaqueItem;
1027
- /**
1028
- * 从 output items 构建标准 replay items。
1029
- * 简单场景下 replay 与 output 一致。
1030
- * 复杂场景(需要 opaque continuation)由 adapter 自行扩展。
1031
- */
1032
- declare function replayFromOutput(output: readonly OutputItem[]): ReplayItem[];
1033
- /**
1034
- * 将单个 ContentBlock 转为纯文本。
1035
- * text 块直接返回文本,json 块序列化,其余返回空串。
1036
- */
1037
- declare function blockToText(b: ContentBlock): string;
1038
- /**
1039
- * 将 ContentBlock 数组拼接为纯文本,块间以换行符分隔。
1040
- */
1041
- declare function contentBlocksToText(blocks: ContentBlock[]): string;
1042
- /**
1043
- * 从 OutputItem 数组中提取所有 message 类型 item 的文本内容。
1044
- */
1045
- declare function extractText(output: OutputItem[]): string;
1046
- //#endregion
1047
- //#region src/helpers/synthetic-stream.d.ts
1048
- type SyntheticStreamOptions = {
1049
- model: string;
1050
- responseId: string;
1051
- backend: {
1052
- kind: "chat-completions" | "messages" | "responses" | "mock";
1053
- };
1054
- output: OutputItem[];
1055
- replay?: ReplayItem[];
1056
- stopReason?: StopReason;
1057
- usage?: Usage;
1058
- billing?: BillingInfo;
1059
- providerMetadata?: Record<string, unknown>;
1060
- rawResponseId?: string;
1061
- warnings?: string[];
1062
- };
1063
- /**
1064
- * 将已解析的 output items 包装为完整规范事件流。
1065
- *
1066
- * 用法示例(在 adapter 的 runStream 中):
1067
- * ```ts
1068
- * const result = parseNonStreamingResponse(data);
1069
- * yield* syntheticStream({
1070
- * model: request.model,
1071
- * responseId: request.requestId,
1072
- * backend: { kind: "chat-completions" },
1073
- * output: result.output,
1074
- * stopReason: result.stopReason,
1075
- * usage: result.usage,
1076
- * });
1077
- * ```
1078
- */
1079
- declare function syntheticStream(options: SyntheticStreamOptions): AsyncIterable<AIStreamEvent>;
1080
- //#endregion
1081
- //#region src/helpers/usage-mapping.d.ts
1082
- /** OpenAI Chat Completions `usage` */
1083
- declare function usageFromChatCompletions(raw: {
1084
- prompt_tokens?: number;
1085
- completion_tokens?: number;
1086
- total_tokens?: number;
1087
- prompt_tokens_details?: {
1088
- cached_tokens?: number;
1089
- [key: string]: unknown;
1090
- };
1091
- completion_tokens_details?: {
1092
- reasoning_tokens?: number;
1093
- [key: string]: unknown;
1094
- };
1095
- }): Partial<Usage>;
1096
- /** OpenAI Responses API `usage` */
1097
- declare function usageFromOpenAIResponses(raw: {
1098
- input_tokens?: number;
1099
- output_tokens?: number;
1100
- total_tokens?: number;
1101
- input_tokens_details?: {
1102
- cached_tokens?: number;
1103
- [key: string]: unknown;
1104
- };
1105
- output_tokens_details?: {
1106
- reasoning_tokens?: number;
1107
- [key: string]: unknown;
1108
- };
1109
- [key: string]: unknown;
1110
- }): Partial<Usage>;
1111
- /** Anthropic Messages `usage`(message_start / message_delta) */
1112
- declare function usageFromAnthropicMessages(raw: {
1113
- input_tokens?: number;
1114
- output_tokens?: number;
1115
- cache_creation_input_tokens?: number;
1116
- cache_read_input_tokens?: number;
1117
- [key: string]: unknown;
1118
- }): Partial<Usage>;
1119
- /** Ollama 流式 chunk */
1120
- declare function usageFromOllama(raw: {
1121
- prompt_eval_count?: number;
1122
- eval_count?: number;
1123
- }): Partial<Usage>;
1124
- //#endregion
1125
- //#region src/helpers/adapter-security.d.ts
1126
- declare const MAX_OPAQUE_PAYLOAD_BYTES = 65536;
1127
- declare const MAX_OPAQUE_JSON_DEPTH = 8;
1128
- declare const PROVIDER_ERROR_MESSAGE_MAX_LEN = 500;
1129
- declare const PROVIDER_ERROR_RAW_BODY_THRESHOLD = 200;
1130
- type OpaqueEnvelopeResult = {
1131
- ok: true;
1132
- } | {
1133
- ok: false;
1134
- reason: string;
1135
- };
1136
- /** 测量 JSON 值嵌套深度(对象/数组);循环引用按已访问节点深度计。 */
1137
- declare function measureJsonDepth(value: unknown, seen?: WeakSet<object>): number;
1138
- /**
1139
- * Opaque replay 通用 envelope:必须是 object、体积 ≤ 64KB、深度 ≤ 8。
1140
- * 不校验 adapter 专用字段形状。
1141
- */
1142
- declare function validateOpaqueReplayEnvelope(payload: unknown): OpaqueEnvelopeResult;
1143
- /** envelope 失败时抛 AIRequestError。 */
1144
- declare function assertOpaqueReplayEnvelope(payload: unknown): void;
1145
- /**
1146
- * 从 provider HTTP 错误 body 提取可对外暴露的短消息,避免泄漏 HTML / 内部路径等。
1147
- */
1148
- declare function extractProviderErrorMessage(body: string, status: number): string;
1149
- /** 统一构造脱敏后的 AIProviderError。 */
1150
- declare function providerHttpError(status: number, body: string): AIProviderError;
1151
- //#endregion
1152
- //#region src/helpers/incremental-stream-parser.d.ts
1153
- type StreamSplitResult = {
1154
- items: string[];
1155
- rest: string;
1156
- };
1157
- type StreamParseResult<T> = {
1158
- status: "parsed";
1159
- value: T;
1160
- } | {
1161
- status: "ignored";
1162
- } | {
1163
- status: "malformed";
1164
- };
1165
- declare class IncrementalStreamParser<T> {
1166
- private readonly split;
1167
- private readonly parse;
1168
- private buffer;
1169
- private readonly decoder;
1170
- constructor(split: (buffer: string, allowEOF: boolean) => StreamSplitResult, parse: (item: string) => StreamParseResult<T>);
1171
- feed(value: Uint8Array): {
1172
- items: T[];
1173
- malformed: number;
1174
- };
1175
- flush(): {
1176
- items: T[];
1177
- malformed: number;
1178
- };
1179
- getRemaining(): string;
1180
- private consume;
1181
- }
1182
- declare function splitLines(buffer: string, allowEOF: boolean): StreamSplitResult;
1183
- declare function splitSSEFrames(buffer: string, allowEOF: boolean): StreamSplitResult;
1184
- type SseJsonEvent = {
1185
- type: string;
1186
- data: unknown;
1187
- };
1188
- /** 解析标准 SSE frame(event: + data:),用于 Messages / Responses。 */
1189
- declare function parseSseJsonFrame(frame: string): StreamParseResult<SseJsonEvent>;
1190
- declare function createSseJsonParser<T extends SseJsonEvent = SseJsonEvent>(): IncrementalStreamParser<T>;
1191
- /** OpenAI Chat Completions 简化 SSE:仅 `data: ...` 行,忽略 `[DONE]`。 */
1192
- declare function parseChatCompletionsDataLine(item: string): StreamParseResult<unknown>;
1193
- declare function createChatCompletionsSseParser<T>(): IncrementalStreamParser<T>;
1194
- /** NDJSON 行解析(Ollama 等):空行忽略,JSON 失败为 malformed。 */
1195
- declare function createNdjsonLineParser<T>(isValid: (value: unknown) => value is T): IncrementalStreamParser<T>;
1196
- //#endregion
1197
- //#region src/helpers/provider-stream.d.ts
1198
- type OpenProviderJsonStreamOptions = {
1199
- fetchFn: FetchFn;
1200
- url: string;
1201
- headers: Record<string, string>;
1202
- body: unknown;
1203
- signal?: AbortSignal;
1204
- };
1205
- type OpenedProviderStream = {
1206
- reader: ReadableStreamDefaultReader<Uint8Array>;
1207
- headers: Headers;
1208
- };
1209
- /** POST JSON 并返回可读 body reader + response headers;统一网络/HTTP/空 body 错误。 */
1210
- declare function openProviderJsonStream(options: OpenProviderJsonStreamOptions): Promise<OpenedProviderStream>;
1211
- type ProviderStreamBatchOptions<T> = {
1212
- reader: ReadableStreamDefaultReader<Uint8Array>;
1213
- parser: IncrementalStreamParser<T>;
1214
- factory: EventFactory;
1215
- providerLabel: string;
1216
- transportLabel: string;
1217
- incompleteMessage: string;
1218
- };
1219
- type ProviderStreamBatch<T> = {
1220
- items: T[];
1221
- warnings: AIStreamEvent[];
1222
- };
1223
- /**
1224
- * 读取并解析 provider 流。
1225
- * 每个 batch 携带本轮解析出的 items 与(可选)malformed / incomplete warning。
1226
- * 调用方应 `for await` 消费完毕;reader 在迭代结束时 cancel/release。
1227
- */
1228
- declare function iterateProviderStreamBatches<T>(options: ProviderStreamBatchOptions<T>): AsyncGenerator<ProviderStreamBatch<T>, void, undefined>;
1229
- /** 一次性 complete 守卫:首次成功,后续返回 false。 */
1230
- declare function createCompletionGate(): {
1231
- readonly completed: boolean;
1232
- tryComplete(): boolean;
1233
- };
1234
- //#endregion
1235
- //#region src/helpers/provider-request-options.d.ts
1236
- /**
1237
- * Provider 请求 headers / body 扩展合并
1238
- *
1239
- * 供真实后端 adapter 构造选项 `headers` / `extraBody` 使用:
1240
- * - headers:内置鉴权头为基,自定义后写覆盖
1241
- * - extraBody:已构建 body 为基,额外字段浅层 spread,同名顶层键可覆盖
1242
- */
1243
- /** 合并内置 headers 与自定义 headers;自定义后写覆盖同名键。 */
1244
- declare function mergeProviderHeaders(base: Record<string, string>, custom?: Record<string, string>): Record<string, string>;
1245
- /**
1246
- * 将构造期 extraBody 浅层合并到已构建的 provider body。
1247
- * 无 extraBody 时原样返回;有则允许覆盖同名顶层键。
1248
- */
1249
- declare function applyExtraBody<T extends object>(body: T, extraBody?: Record<string, unknown>): T;
1250
- //#endregion
1251
- //#region src/helpers/reasoning-level.d.ts
1252
- declare const REASONING_LEVELS: readonly ["none", "minimal", "low", "medium", "high", "xhigh", "max"];
1253
- declare const REASONING_LEVEL_SET: ReadonlySet<string>;
1254
- type OpenAIReasoningEffort = ReasoningLevel;
1255
- type MessagesThinkingConfig = {
1256
- type: "disabled";
1257
- } | {
1258
- type: "enabled";
1259
- budget_tokens: number;
1260
- };
1261
- type OllamaThinkValue = false | "low" | "medium" | "high";
1262
- /** 若 level 不在 supported 集合内则抛 AIRequestError。 */
1263
- declare function assertSupportedReasoningLevel(level: ReasoningLevel, supported: ReadonlySet<ReasoningLevel>, adapterKind: string): void;
1264
- /** Responses API:`reasoning: { effort }` */
1265
- declare function mapResponsesReasoning(level: ReasoningLevel): {
1266
- effort: OpenAIReasoningEffort;
1267
- };
1268
- /** Chat Completions:顶层 `reasoning_effort` */
1269
- declare function mapChatCompletionsReasoningEffort(level: ReasoningLevel): OpenAIReasoningEffort;
1270
- /**
1271
- * Messages thinking budget。
1272
- * 基于 maxTokens 按比例推导,clamp 到 [1024, max(1024, maxTokens - 1)],
1273
- * 满足 Anthropic budget_tokens < max_tokens。
1274
- */
1275
- declare function mapMessagesThinkingBudget(level: Exclude<ReasoningLevel, "none">, maxTokens: number): number;
1276
- /** Messages API:`thinking` 字段 */
1277
- declare function mapMessagesThinking(level: ReasoningLevel, maxTokens: number): MessagesThinkingConfig;
1278
- /** Ollama:`think` 字段;minimal/xhigh/max 不支持 */
1279
- declare function mapOllamaThink(level: ReasoningLevel): OllamaThinkValue;
1442
+ //#region src/adapters/mock/expectations.d.ts
1443
+ declare function assertMockRequest(request: NormalizedRequest, expectation: MockRequestExpectation, context: MockHandlerContext): void;
1280
1444
  //#endregion
1281
- //#region src/helpers/request-mapper.d.ts
1282
- declare class NormalizedRequestMapper {
1283
- readonly kind: string;
1284
- constructor(kind: string);
1285
- mapInstructions(instructions: string | InstructionBlock[]): string;
1286
- ensureTextBlocks(blocks: ContentBlock[], field: string): ContentBlock[];
1287
- ensureReasoningBlocks(blocks: ContentBlock[], field: string): Array<Extract<ContentBlock, {
1288
- type: "text";
1289
- }>>;
1290
- /** ensureTextBlocks + contentBlocksToText 的常见组合。 */
1291
- textFromBlocks(blocks: ContentBlock[], field: string): string;
1292
- parseToolArguments(item: ToolCallItem): Record<string, unknown>;
1293
- rollbackTrailingAssistantMessages<T extends {
1294
- role: string;
1295
- }>(messages: T[]): void;
1296
- mapToolsIfPresent<T>(tools: ToolDefinition[] | undefined, map: (tool: ToolDefinition) => T): T[] | undefined;
1297
- /**
1298
- * 将 canonical toolChoice 映射为 provider 形状。
1299
- * 返回 undefined 表示调用方无需写入 body 字段。
1300
- */
1301
- mapToolChoice<T>(toolChoice: ToolChoice | undefined, mappers: {
1302
- auto: T;
1303
- none: T;
1304
- tool: (name: string) => T;
1305
- }): T | undefined;
1306
- private ensureBlocks;
1307
- }
1445
+ //#region src/adapters/mock/streaming.d.ts
1446
+ declare function withMockStreaming(handler: MockStaticHandler, options: MockTextStreamOptions): MockHandler;
1308
1447
  //#endregion
1309
- 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, type MessagesThinkingConfig, 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 OllamaThinkValue, type OpaqueEnvelopeResult, type OpaqueItem, type OpenAIReasoningEffort, type OpenProviderJsonStreamOptions, type OpenedProviderStream, type OutputItem, PROVIDER_ERROR_MESSAGE_MAX_LEN, PROVIDER_ERROR_RAW_BODY_THRESHOLD, type ProviderStreamBatch, type ProviderStreamBatchOptions, REASONING_LEVELS, REASONING_LEVEL_SET, type ReasoningCompletedEvent, type ReasoningDeltaEvent, type ReasoningItem, type ReasoningLevel, 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, applyExtraBody, assertMockRequest, assertOpaqueReplayEnvelope, assertSupportedReasoningLevel, assertValidRequest, blockToText, collectStream, contentBlocksToText, createAIClient, createChatCompletionsSseParser, createCompletionGate, createEventFactory, createNdjsonLineParser, createSseJsonParser, emitMalformedStreamWarning, extractProviderErrorMessage, extractText, imageBlock, iterateProviderStreamBatches, jsonBlock, mapChatCompletionsReasoningEffort, mapMessagesThinking, mapMessagesThinkingBudget, mapOllamaThink, mapReasoningVisibility, mapResponsesReasoning, mapStopReason, measureJsonDepth, mergeProviderHeaders, messageItem, normalizeRequest, opaqueBlock, opaqueItem, openProviderJsonStream, parseChatCompletionsDataLine, parseSseJsonFrame, providerHttpError, reasoningItem, replayFromOutput, splitLines, splitSSEFrames, syntheticStream, textBlock, toolCallItem, toolResultItem, usageFromAnthropicMessages, usageFromChatCompletions, usageFromOllama, usageFromOpenAIResponses, validateOpaqueReplayEnvelope, validateRequest, withMockStreaming };
1448
+ export { type AIClient, AIError, AIMappingError, AIProviderError, AIRecoverableError, type AIRequest, AIRequestError, type AIResponse, AIStreamError, type AIStreamEvent, type AdapterKind, type AuxiliaryInfo, type BackendAdapter, type BackendTrace, type BillingInfo, ChatCompletionsAdapter, type ChatCompletionsAdapterOptions, type Citation, type CodeExecutionServerTool, type CompressRequest, type CompressResult, type ContainerFileCitation, type ContentBlock, type ContextCompressCapable, type CreateAIClientOptions, type ErrorCode, type FetchFn, GeminiAdapter, type GeminiAdapterOptions, type IncludeSettings, type InputItem, type InstructionBlock, type JsonContentBlock, KNOWN_ADAPTER_KINDS, type KnownAdapterKind, type KnownErrorCode, type KnownWarningCode, type McpServerTool, type MessageCompletedEvent, type MessageDeltaEvent, type MessageItem, type MessageStartedEvent, MessagesAdapter, type MessagesAdapterOptions, MockAdapter, type MockAdapterOptions, type MockAuxiliaryStep, type MockCompleteStep, type MockCompressHandler, type MockErrorStep, type MockHandler, type MockHandlerContext, type MockHistoryRecord, type MockInputExpectation, type MockInterruptStep, type MockMessageStep, type MockOutputStep, type MockReasoningStep, type MockRequestExpectation, type MockServerToolCallStep, type MockServerToolDiscoveryStep, type MockServerToolResultStep, type MockStaticHandler, type MockStep, type MockTextStreamOptions, type MockThrowStep, type MockToolCallStep, type MockWarningStep, type NormalizedRequest, OllamaAdapter, type OllamaAdapterOptions, type OpaqueItem, type OutputItem, REASONING_LEVELS, REASONING_LEVEL_SET, type ReasoningCompletedEvent, type ReasoningDeltaEvent, type ReasoningItem, type ReasoningLevel, type ReasoningStartedEvent, type ReplayItem, type ResponseAuxiliaryEvent, type ResponseCompletedEvent, type ResponseStartedEvent, type ResponseWarningEvent, ResponsesAdapter, type ResponsesAdapterOptions, type ServerToolCallItem, type ServerToolCompletedEvent, type ServerToolDefinition, type ServerToolDeltaEvent, type ServerToolDiscoveryCompletedEvent, type ServerToolDiscoveryItem, type ServerToolResultCompletedEvent, type ServerToolResultItem, type ServerToolStartedEvent, type StopReason, type StreamEventBase, type StreamWarning, type TextContentBlock, type ToolCallCompletedEvent, type ToolCallDeltaEvent, type ToolCallItem, type ToolCallStartedEvent, type ToolChoice, type ToolDefinition, type ToolResultItem, type UrlCitation, type Usage, WarningCode, type WarningCodeName, type WarningCodeValue, type WebSearchServerTool, type WebSearchUserLocation, assertMockRequest, blockToText, coalesceContentBlocks, collectStream, contentBlocksToText, createAIClient, extractText, imageBlock, jsonBlock, mapReasoningVisibility, mapStopReason, messageItem, opaqueBlock, opaqueItem, reasoningItem, replayFromOutput, serverToolCallItem, serverToolDiscoveryItem, serverToolResultItem, streamWarningKey, supportsContextCompress, textBlock, toolCallItem, toolResultItem, withMockStreaming };
1310
1449
  //# sourceMappingURL=index.d.mts.map