@codehz/ai 0.1.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.
@@ -0,0 +1,978 @@
1
+ //#region src/types/content.d.ts
2
+ /**
3
+ * ContentBlock — 统一内容块类型
4
+ *
5
+ * 覆盖文本、JSON、图片、二进制引用和后端私有内容。
6
+ */
7
+ type ContentBlock = {
8
+ type: "text";
9
+ text: string;
10
+ } | {
11
+ type: "json";
12
+ json: unknown;
13
+ } | {
14
+ type: "image";
15
+ imageUrl: string;
16
+ } | {
17
+ type: "binary_ref";
18
+ ref: string;
19
+ } | {
20
+ type: "opaque";
21
+ payload: unknown;
22
+ };
23
+ //#endregion
24
+ //#region src/types/items.d.ts
25
+ type MessageItem = {
26
+ type: "message";
27
+ id?: string;
28
+ role: "user" | "assistant" | "system" | "developer";
29
+ content: ContentBlock[];
30
+ };
31
+ type ReasoningItem = {
32
+ type: "reasoning";
33
+ id?: string;
34
+ visibility: "full" | "summary" | "redacted" | "opaque";
35
+ content: ContentBlock[];
36
+ };
37
+ type ToolCallItem = {
38
+ type: "tool_call";
39
+ id: string;
40
+ name: string;
41
+ argumentsText: string;
42
+ argumentsJson?: unknown;
43
+ };
44
+ type ToolResultItem = {
45
+ type: "tool_result";
46
+ callId: string;
47
+ toolName: string;
48
+ outcome: "success" | "error" | "rejected";
49
+ content: ContentBlock[];
50
+ };
51
+ type OpaqueItem = {
52
+ type: "opaque";
53
+ id?: string;
54
+ source: "responses" | "messages" | "chat.completions" | string;
55
+ purpose: "replay" | "provider_state" | "unknown";
56
+ payload: unknown;
57
+ };
58
+ /** 可出现在请求 input 中的 item 类型 */
59
+ type InputItem = MessageItem | ReasoningItem | ToolCallItem | ToolResultItem | OpaqueItem;
60
+ /** 可出现在响应 output 中的 item 类型(不含 ToolResultItem) */
61
+ type OutputItem = MessageItem | ReasoningItem | ToolCallItem | OpaqueItem;
62
+ /** replay 材料的类型等价于 InputItem */
63
+ type ReplayItem = InputItem;
64
+ //#endregion
65
+ //#region src/types/request.d.ts
66
+ type ToolDefinition = {
67
+ name: string;
68
+ description?: string;
69
+ inputSchema: Record<string, unknown>;
70
+ };
71
+ type ToolChoice = "auto" | "none" | {
72
+ type: "tool";
73
+ name: string;
74
+ };
75
+ type IncludeSettings = {
76
+ usage?: "off" | "best_effort";
77
+ billing?: "off" | "best_effort";
78
+ providerMetadata?: "off" | "best_effort";
79
+ };
80
+ type AIRequest = {
81
+ instructions?: string | ContentBlock[];
82
+ input: InputItem[];
83
+ tools?: ToolDefinition[];
84
+ toolChoice?: ToolChoice;
85
+ include?: IncludeSettings;
86
+ metadata?: Record<string, string>;
87
+ temperature?: number;
88
+ maxOutputTokens?: number;
89
+ };
90
+ //#endregion
91
+ //#region src/types/response.d.ts
92
+ type StopReason = "end_turn" | "tool_call" | "max_output_tokens" | "content_filter" | "error" | "unknown";
93
+ type Usage = {
94
+ inputTokens?: number;
95
+ outputTokens?: number;
96
+ reasoningTokens?: number;
97
+ totalTokens?: number;
98
+ cachedInputTokens?: number;
99
+ cacheWriteInputTokens?: number;
100
+ billableInputTokens?: number;
101
+ billableOutputTokens?: number;
102
+ };
103
+ type BillingInfo = {
104
+ amount?: number;
105
+ currency?: string;
106
+ isEstimated: boolean;
107
+ source: "provider" | "lookup" | "derived" | "unknown";
108
+ raw?: unknown;
109
+ };
110
+ type AuxiliaryInfo = {
111
+ usageSource?: "stream" | "final" | "header" | "lookup" | "derived";
112
+ billingSource?: "stream" | "final" | "header" | "lookup" | "derived";
113
+ providerUsage?: unknown;
114
+ providerBilling?: unknown;
115
+ providerMetadata?: Record<string, unknown>;
116
+ };
117
+ type BackendTrace = {
118
+ requestId?: string;
119
+ rawResponseId?: string;
120
+ adapter: "chat-completions" | "messages" | "responses" | "ollama";
121
+ isSyntheticStream: boolean;
122
+ metadataSources?: string[];
123
+ warnings?: string[];
124
+ };
125
+ type AIResponse = {
126
+ id?: string;
127
+ output: OutputItem[];
128
+ replay: ReplayItem[];
129
+ text: string;
130
+ toolCalls: ToolCallItem[];
131
+ stopReason?: StopReason;
132
+ usage?: Usage;
133
+ billing?: BillingInfo;
134
+ auxiliary?: AuxiliaryInfo;
135
+ warnings?: string[];
136
+ backend: BackendTrace;
137
+ };
138
+ //#endregion
139
+ //#region src/types/events.d.ts
140
+ type StreamEventBase = {
141
+ type: string;
142
+ responseId?: string;
143
+ sequence: number;
144
+ timestamp: string;
145
+ backend: {
146
+ kind: "chat-completions" | "messages" | "responses" | "ollama";
147
+ isSynthetic: boolean;
148
+ };
149
+ };
150
+ type ResponseStartedEvent = StreamEventBase & {
151
+ type: "response.started";
152
+ model: string;
153
+ };
154
+ type ResponseWarningEvent = StreamEventBase & {
155
+ type: "response.warning";
156
+ message: string;
157
+ code?: string;
158
+ };
159
+ type ResponseAuxiliaryEvent = StreamEventBase & {
160
+ type: "response.auxiliary";
161
+ usage?: Usage;
162
+ billing?: BillingInfo;
163
+ auxiliary?: Partial<AuxiliaryInfo>;
164
+ };
165
+ type ResponseCompletedEvent = StreamEventBase & {
166
+ type: "response.completed";
167
+ response: AIResponse;
168
+ };
169
+ type MessageStartedEvent = StreamEventBase & {
170
+ type: "message.started";
171
+ item: {
172
+ id: string;
173
+ role: "assistant";
174
+ };
175
+ };
176
+ type MessageDeltaEvent = StreamEventBase & {
177
+ type: "message.delta";
178
+ itemId: string;
179
+ delta: {
180
+ type: "text";
181
+ text: string;
182
+ };
183
+ };
184
+ type MessageCompletedEvent = StreamEventBase & {
185
+ type: "message.completed";
186
+ item: MessageItem;
187
+ };
188
+ type ReasoningStartedEvent = StreamEventBase & {
189
+ type: "reasoning.started";
190
+ item: {
191
+ id: string;
192
+ visibility: "full" | "summary" | "redacted" | "opaque";
193
+ };
194
+ };
195
+ type ReasoningDeltaEvent = StreamEventBase & {
196
+ type: "reasoning.delta";
197
+ itemId: string;
198
+ delta: ContentBlock;
199
+ };
200
+ type ReasoningCompletedEvent = StreamEventBase & {
201
+ type: "reasoning.completed";
202
+ item: ReasoningItem;
203
+ };
204
+ type ToolCallStartedEvent = StreamEventBase & {
205
+ type: "tool_call.started";
206
+ item: {
207
+ id: string;
208
+ name: string;
209
+ };
210
+ };
211
+ type ToolCallDeltaEvent = StreamEventBase & {
212
+ type: "tool_call.delta";
213
+ itemId: string;
214
+ delta: {
215
+ argumentsText?: string;
216
+ };
217
+ };
218
+ type ToolCallCompletedEvent = StreamEventBase & {
219
+ type: "tool_call.completed";
220
+ item: ToolCallItem;
221
+ };
222
+ type AIStreamEvent = ResponseStartedEvent | ResponseWarningEvent | ResponseAuxiliaryEvent | MessageStartedEvent | MessageDeltaEvent | MessageCompletedEvent | ReasoningStartedEvent | ReasoningDeltaEvent | ReasoningCompletedEvent | ToolCallStartedEvent | ToolCallDeltaEvent | ToolCallCompletedEvent | ResponseCompletedEvent;
223
+ //#endregion
224
+ //#region src/types/adapter.d.ts
225
+ /** HTTP fetch 函数签名,用于注入自定义请求实现(测试/代理) */
226
+ type FetchFn = (url: string, init: RequestInit) => Promise<Response>;
227
+ type NormalizedRequest = AIRequest & {
228
+ model: string;
229
+ requestId: string;
230
+ };
231
+ type AdapterCapabilities = {
232
+ nativeStreaming: boolean;
233
+ messageStreaming: boolean;
234
+ reasoningStreaming: boolean;
235
+ toolCallStreaming: boolean;
236
+ hiddenReasoningReplay: "full" | "partial" | "none";
237
+ replayFidelity: "high" | "medium" | "low";
238
+ tools: boolean;
239
+ usage: "full" | "partial" | "none";
240
+ billing: "direct" | "lookup" | "derived" | "none";
241
+ providerMetadata: boolean;
242
+ };
243
+ declare const CAPABILITY_MATRIX: {
244
+ readonly responses: {
245
+ readonly nativeStreaming: true;
246
+ readonly messageStreaming: true;
247
+ readonly reasoningStreaming: true;
248
+ readonly toolCallStreaming: true;
249
+ readonly hiddenReasoningReplay: "full";
250
+ readonly replayFidelity: "high";
251
+ readonly tools: true;
252
+ readonly usage: "full";
253
+ readonly billing: "lookup";
254
+ readonly providerMetadata: true;
255
+ };
256
+ readonly messages: {
257
+ readonly nativeStreaming: true;
258
+ readonly messageStreaming: true;
259
+ readonly reasoningStreaming: false;
260
+ readonly toolCallStreaming: true;
261
+ readonly hiddenReasoningReplay: "partial";
262
+ readonly replayFidelity: "medium";
263
+ readonly tools: true;
264
+ readonly usage: "full";
265
+ readonly billing: "lookup";
266
+ readonly providerMetadata: true;
267
+ };
268
+ readonly "chat.completions": {
269
+ readonly nativeStreaming: true;
270
+ readonly messageStreaming: true;
271
+ readonly reasoningStreaming: false;
272
+ readonly toolCallStreaming: false;
273
+ readonly hiddenReasoningReplay: "none";
274
+ readonly replayFidelity: "low";
275
+ readonly tools: true;
276
+ readonly usage: "full";
277
+ readonly billing: "derived";
278
+ readonly providerMetadata: false;
279
+ };
280
+ readonly ollama: {
281
+ readonly nativeStreaming: true;
282
+ readonly messageStreaming: true;
283
+ readonly reasoningStreaming: false;
284
+ readonly toolCallStreaming: false;
285
+ readonly hiddenReasoningReplay: "none";
286
+ readonly replayFidelity: "low";
287
+ readonly tools: true;
288
+ readonly usage: "partial";
289
+ readonly billing: "none";
290
+ readonly providerMetadata: false;
291
+ };
292
+ };
293
+ interface BackendAdapter {
294
+ readonly kind: "chat-completions" | "messages" | "responses" | "ollama";
295
+ readonly capabilities: AdapterCapabilities;
296
+ stream(request: NormalizedRequest): AsyncIterable<AIStreamEvent>;
297
+ }
298
+ type CreateAIClientOptions = {
299
+ adapter: BackendAdapter;
300
+ model: string;
301
+ defaults?: Partial<AIRequest>;
302
+ };
303
+ interface AIClient {
304
+ stream(request: AIRequest): AsyncIterable<AIStreamEvent>;
305
+ }
306
+ //#endregion
307
+ //#region src/core/client.d.ts
308
+ declare function createAIClient(options: CreateAIClientOptions): AIClient;
309
+ //#endregion
310
+ //#region src/core/normalize.d.ts
311
+ type NormalizeOptions = {
312
+ model: string;
313
+ defaults?: Partial<AIRequest>;
314
+ };
315
+ /**
316
+ * 归一化请求:
317
+ * 1. 合并 defaults
318
+ * 2. 填充 include 默认值
319
+ * 3. 生成 requestId
320
+ * 4. 校验请求合法性
321
+ */
322
+ declare function normalizeRequest(request: AIRequest, options: NormalizeOptions): NormalizedRequest;
323
+ //#endregion
324
+ //#region src/core/validation.d.ts
325
+ type ValidationIssue = {
326
+ field: string;
327
+ code: string;
328
+ message: string;
329
+ };
330
+ /**
331
+ * 校验 AIRequest,返回校验问题列表。
332
+ * 空数组表示无问题。
333
+ */
334
+ declare function validateRequest(request: AIRequest): ValidationIssue[];
335
+ /**
336
+ * 校验请求并抛出首个问题。
337
+ * 适用于客户端入口的快速失败检查。
338
+ */
339
+ declare function assertValidRequest(request: AIRequest): void;
340
+ //#endregion
341
+ //#region src/core/errors.d.ts
342
+ /**
343
+ * 公共错误模型
344
+ *
345
+ * 把失败、降级、断流三类情况明确区分:
346
+ * - 致命错误 → 同步抛错或迭代器抛错
347
+ * - 非致命差异 → warning 通道
348
+ * - 流中断 → 不伪造 response.completed
349
+ */
350
+ 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;
351
+ declare class AIError extends Error {
352
+ readonly code: ErrorCode;
353
+ readonly name: string;
354
+ constructor(message: string, code: ErrorCode, name?: string);
355
+ }
356
+ /** 请求构造失败 — 参数校验不通过。在进入 adapter 前同步抛错。 */
357
+ declare class AIRequestError extends AIError {
358
+ constructor(message: string, code: ErrorCode);
359
+ }
360
+ /** Provider 调用失败 — HTTP 非 2xx、网络错误。由 AdapterBase 捕获转为 warning。 */
361
+ declare class AIProviderError extends AIError {
362
+ readonly statusCode?: number | undefined;
363
+ readonly responseBody?: string | undefined;
364
+ constructor(message: string, code: ErrorCode, statusCode?: number | undefined, responseBody?: string | undefined);
365
+ }
366
+ /** 流协议损坏 — SSE 解析失败、chunk 格式异常。 */
367
+ declare class AIStreamError extends AIError {
368
+ constructor(message: string, code: ErrorCode);
369
+ }
370
+ /** Canonical 映射失败 — 无法将 provider 响应映射到 canonical 类型。 */
371
+ declare class AIMappingError extends AIError {
372
+ constructor(message: string, code: ErrorCode);
373
+ }
374
+ /**
375
+ * 标准 warning 代码列表。
376
+ * 用于非致命差异的记录。
377
+ */
378
+ declare const WarningCode: {
379
+ /** replay fidelity 低于预期 */readonly REPLAY_FIDELITY_LOW: "REPLAY_FIDELITY_LOW"; /** usage 字段缺失 */
380
+ readonly USAGE_MISSING: "USAGE_MISSING"; /** billing 字段缺失 */
381
+ readonly BILLING_MISSING: "BILLING_MISSING"; /** billing 只能给估算值 */
382
+ readonly BILLING_ESTIMATED: "BILLING_ESTIMATED"; /** follow-up lookup 失败 */
383
+ readonly LOOKUP_FAILED: "LOOKUP_FAILED"; /** lookup 超时 */
384
+ readonly LOOKUP_TIMEOUT: "LOOKUP_TIMEOUT"; /** 流提前中断 */
385
+ readonly STREAM_INCOMPLETE: "STREAM_INCOMPLETE"; /** 能力降级 */
386
+ readonly CAPABILITY_DOWNGRADE: "CAPABILITY_DOWNGRADE"; /** 模拟流式 */
387
+ readonly SYNTHETIC_STREAM: "SYNTHETIC_STREAM";
388
+ };
389
+ //#endregion
390
+ //#region src/core/event-factory.d.ts
391
+ type EventFactoryBackend = {
392
+ kind: "chat-completions" | "messages" | "responses" | "ollama";
393
+ isSynthetic: boolean;
394
+ };
395
+ type EventFactoryState = {
396
+ responseId: string;
397
+ backend: EventFactoryBackend;
398
+ };
399
+ declare function createEventFactory(state: EventFactoryState): {
400
+ responseStarted(model: string): ResponseStartedEvent;
401
+ responseWarning(message: string, code?: string): ResponseWarningEvent;
402
+ responseAuxiliary(data: {
403
+ usage?: Usage;
404
+ billing?: BillingInfo;
405
+ auxiliary?: Partial<AuxiliaryInfo>;
406
+ }): ResponseAuxiliaryEvent;
407
+ responseCompleted(response: AIResponse): ResponseCompletedEvent;
408
+ messageStarted(id: string): MessageStartedEvent;
409
+ messageDelta(itemId: string, text: string): MessageDeltaEvent;
410
+ messageCompleted(item: MessageItem): MessageCompletedEvent;
411
+ reasoningStarted(id: string, visibility: ReasoningItem["visibility"]): ReasoningStartedEvent;
412
+ reasoningDelta(itemId: string, delta: ContentBlock): ReasoningDeltaEvent;
413
+ reasoningCompleted(item: ReasoningItem): ReasoningCompletedEvent;
414
+ toolCallStarted(id: string, name: string): ToolCallStartedEvent;
415
+ toolCallDelta(itemId: string, delta: {
416
+ argumentsText?: string;
417
+ }): ToolCallDeltaEvent;
418
+ toolCallCompleted(item: ToolCallItem): ToolCallCompletedEvent; /** 返回当前已发出的 sequence 计数(用于断言) */
419
+ readonly sequence: number; /** 返回当前已记录的 warning 副本。 */
420
+ readonly warnings: string[];
421
+ };
422
+ type EventFactory = ReturnType<typeof createEventFactory>;
423
+ //#endregion
424
+ //#region src/core/aggregator.d.ts
425
+ /**
426
+ * 将事件数组聚合为 AIResponse。
427
+ * 适用于测试和离线处理场景。
428
+ */
429
+ declare function aggregateEvents(events: AIStreamEvent[]): AIResponse;
430
+ //#endregion
431
+ //#region src/core/collect-stream.d.ts
432
+ declare function collectStream(stream: AsyncIterable<AIStreamEvent>): Promise<AIResponse>;
433
+ //#endregion
434
+ //#region src/helpers/auxiliary-collector.d.ts
435
+ type UsageSource = NonNullable<AuxiliaryInfo["usageSource"]>;
436
+ type BillingSource = NonNullable<AuxiliaryInfo["billingSource"]>;
437
+ type LookupResult = {
438
+ usage?: Partial<Usage>;
439
+ billing?: Partial<BillingInfo>;
440
+ providerMetadata?: Record<string, unknown>;
441
+ };
442
+ declare class AuxiliaryCollector {
443
+ private usage;
444
+ private usageSource;
445
+ private billing;
446
+ private billingSource;
447
+ private providerMetadata;
448
+ private providerUsage;
449
+ private providerBilling;
450
+ private warnings;
451
+ private lookupAttempted;
452
+ /**
453
+ * 记录 usage 信息。
454
+ * 后调用的覆盖先调用的(优先级由调用方控制)。
455
+ */
456
+ recordUsage(usage: Partial<Usage>, source: UsageSource, raw?: unknown): this;
457
+ /**
458
+ * 记录 billing 信息。
459
+ * 后调用的覆盖先调用的。
460
+ */
461
+ recordBilling(billing: Partial<BillingInfo>, source: BillingSource, raw?: unknown): this;
462
+ /**
463
+ * 记录 provider 元数据(非 canonical 的 key-value 信息)。
464
+ */
465
+ recordMetadata(metadata: Record<string, unknown>): this;
466
+ /**
467
+ * 记录一条 warning。
468
+ */
469
+ recordWarning(message: string): this;
470
+ /**
471
+ * 执行一次有界 follow-up lookup。
472
+ * 最多调用一次;后续调用被忽略。
473
+ * lookup 失败(抛错)仅记录 warning,不传播异常。
474
+ */
475
+ tryLookup(lookupFn: () => Promise<LookupResult>, timeoutMs?: number): Promise<void>;
476
+ /**
477
+ * 构建最终的 usage / billing / auxiliary。
478
+ * 所有字段均为可选的 — 拿不到就不给。
479
+ */
480
+ build(): {
481
+ usage?: Usage;
482
+ billing?: BillingInfo;
483
+ auxiliary?: AuxiliaryInfo;
484
+ warnings?: string[];
485
+ };
486
+ /**
487
+ * 已使用的来源列表(用于 debugging)。
488
+ */
489
+ get sources(): {
490
+ usage?: UsageSource;
491
+ billing?: BillingSource;
492
+ };
493
+ }
494
+ //#endregion
495
+ //#region src/helpers/adapter-auxiliary.d.ts
496
+ type MaybePromise<T> = T | Promise<T>;
497
+ type BillingPostprocessHook = (context: {
498
+ request: NormalizedRequest;
499
+ usage?: Usage;
500
+ billing?: BillingInfo;
501
+ auxiliary?: AuxiliaryInfo;
502
+ capabilities: AdapterCapabilities;
503
+ }) => MaybePromise<Partial<BillingInfo> | undefined>;
504
+ type AuxiliaryFinalizeOptions = {
505
+ lookup?: () => Promise<LookupResult>;
506
+ lookupTimeoutMs?: number;
507
+ postprocessBilling?: BillingPostprocessHook;
508
+ postprocessBillingSource?: BillingSource;
509
+ };
510
+ type AuxiliaryFinalizeResult = {
511
+ events: AIStreamEvent[];
512
+ usage?: Usage;
513
+ billing?: BillingInfo;
514
+ auxiliary?: AuxiliaryInfo;
515
+ warnings?: string[];
516
+ metadataSources?: string[];
517
+ };
518
+ declare class AdapterAuxiliaryState {
519
+ private readonly request;
520
+ private readonly capabilities;
521
+ private readonly collector;
522
+ private readonly metadataSources;
523
+ constructor(request: NormalizedRequest, capabilities: AdapterCapabilities);
524
+ recordUsage(usage: Partial<Usage>, source: UsageSource, raw?: unknown): void;
525
+ recordBilling(billing: Partial<BillingInfo>, source: BillingSource, raw?: unknown): void;
526
+ recordProviderMetadata(source: string, metadata: Record<string, unknown> | undefined): void;
527
+ finalize(factory: EventFactory, options?: AuxiliaryFinalizeOptions): Promise<AuxiliaryFinalizeResult>;
528
+ private shouldAttemptLookup;
529
+ }
530
+ declare function emitMalformedStreamWarning(factory: EventFactory, options: {
531
+ count: number;
532
+ providerLabel: string;
533
+ transportLabel: string;
534
+ }): AIStreamEvent | undefined;
535
+ declare function metadataSourceList(...groups: Array<Array<NonNullable<BackendTrace["metadataSources"]>[number]> | undefined>): string[] | undefined;
536
+ //#endregion
537
+ //#region src/helpers/adapter-base.d.ts
538
+ type ProviderResponse = unknown;
539
+ /**
540
+ * adapter 完成一轮处理后返回的最终结果。
541
+ * 用于 buildResponse() 构建 AIResponse。
542
+ */
543
+ type StreamResult = {
544
+ output: OutputItem[];
545
+ replay: ReplayItem[];
546
+ stopReason?: StopReason;
547
+ usage?: Usage;
548
+ billing?: BillingInfo;
549
+ providerMetadata?: Record<string, unknown>;
550
+ auxiliary?: Partial<AuxiliaryInfo>;
551
+ warnings?: string[];
552
+ metadataSources?: string[];
553
+ rawResponseId?: string;
554
+ };
555
+ declare abstract class AdapterBase implements BackendAdapter {
556
+ abstract readonly kind: "chat-completions" | "messages" | "responses" | "ollama";
557
+ abstract readonly capabilities: AdapterCapabilities;
558
+ /**
559
+ * stream 模板方法:
560
+ * 1. 创建事件工厂,发射 response.started
561
+ * 2. 构建 provider 请求
562
+ * 3. 委托 runStream 发射全部流事件(含 response.completed)
563
+ */
564
+ stream(request: NormalizedRequest): AsyncIterable<AIStreamEvent>;
565
+ /** 将 NormalizedRequest 转换为 provider 请求格式。 */
566
+ protected abstract buildRequest(request: NormalizedRequest): ProviderResponse | Promise<ProviderResponse>;
567
+ /**
568
+ * 执行流式请求,发射全部事件(含 response.completed)。
569
+ * 子类负责:
570
+ * - 调用 provider
571
+ * - 解析每个 chunk
572
+ * - 通过 factory 发射 item 事件
573
+ * - 构建 StreamResult
574
+ * - 发射 factory.responseCompleted(buildResponse(…))
575
+ */
576
+ protected abstract runStream(providerRequest: ProviderResponse, factory: EventFactory, request: NormalizedRequest): AsyncIterable<AIStreamEvent>;
577
+ /**
578
+ * 从 StreamResult 构建完整 AIResponse。
579
+ * 子类可在返回前自定义覆盖。
580
+ */
581
+ protected buildResponse(request: NormalizedRequest, result: StreamResult, _factory: EventFactory): AIResponse;
582
+ /** 从 output items 中提取文本内容。 */
583
+ protected extractText(output: OutputItem[]): string;
584
+ protected createAuxiliaryState(request: NormalizedRequest): AdapterAuxiliaryState;
585
+ }
586
+ //#endregion
587
+ //#region src/adapters/responses.d.ts
588
+ type ResponsesAdapterOptions = {
589
+ apiKey: string;
590
+ baseUrl?: string; /** 可注入自定义 fetch 实现(用于测试/代理) */
591
+ fetch?: FetchFn;
592
+ };
593
+ type ResponsesAPIRequest = {
594
+ model: string;
595
+ input: ResponsesInputItem[];
596
+ instructions?: string;
597
+ tools?: ResponsesTool[];
598
+ tool_choice?: "auto" | "none" | {
599
+ type: "function";
600
+ name: string;
601
+ };
602
+ metadata?: Record<string, string>;
603
+ temperature?: number;
604
+ max_output_tokens?: number;
605
+ stream: true;
606
+ };
607
+ type ResponsesInputItem = {
608
+ type: "message";
609
+ role: "user" | "assistant" | "system" | "developer";
610
+ content: string;
611
+ } | {
612
+ type: "message";
613
+ role: "assistant";
614
+ content: ResponsesContentBlock[];
615
+ } | {
616
+ type: "function_call";
617
+ id: string;
618
+ name: string;
619
+ arguments: string;
620
+ call_id?: string;
621
+ } | {
622
+ type: "function_call_output";
623
+ call_id: string;
624
+ output: string;
625
+ } | {
626
+ type: "reasoning";
627
+ content: ResponsesContentBlock[];
628
+ } | {
629
+ type: "item_reference";
630
+ id: string;
631
+ };
632
+ type ResponsesContentBlock = {
633
+ type: "text";
634
+ text: string;
635
+ } | {
636
+ type: "reasoning";
637
+ text: string;
638
+ } | {
639
+ type: "refusal";
640
+ refusal: string;
641
+ };
642
+ type ResponsesTool = {
643
+ type: "function";
644
+ name: string;
645
+ description?: string;
646
+ input_schema: Record<string, unknown>;
647
+ };
648
+ declare class ResponsesAdapter extends AdapterBase {
649
+ readonly kind: "responses";
650
+ readonly capabilities: {
651
+ readonly nativeStreaming: true;
652
+ readonly messageStreaming: true;
653
+ readonly reasoningStreaming: true;
654
+ readonly toolCallStreaming: true;
655
+ readonly hiddenReasoningReplay: "full";
656
+ readonly replayFidelity: "high";
657
+ readonly tools: true;
658
+ readonly usage: "full";
659
+ readonly billing: "lookup";
660
+ readonly providerMetadata: true;
661
+ };
662
+ private apiKey;
663
+ private baseUrl;
664
+ private fetchFn;
665
+ constructor(options: ResponsesAdapterOptions);
666
+ protected buildRequest(request: NormalizedRequest): ResponsesAPIRequest;
667
+ protected runStream(providerRequest: ResponsesAPIRequest, factory: EventFactory, request: NormalizedRequest): AsyncIterable<AIStreamEvent>;
668
+ private inferStopReason;
669
+ }
670
+ //#endregion
671
+ //#region src/adapters/messages.d.ts
672
+ type MessagesAdapterOptions = {
673
+ apiKey: string;
674
+ apiVersion?: string;
675
+ baseUrl?: string; /** 可注入自定义 fetch 实现(用于测试/代理) */
676
+ fetch?: FetchFn;
677
+ };
678
+ type MessagesAPIRequest = {
679
+ model: string;
680
+ max_tokens: number;
681
+ messages: MessagesAPIMessage[];
682
+ system?: string;
683
+ tools?: MessagesAPITool[];
684
+ tool_choice?: {
685
+ type: "auto" | "none";
686
+ } | {
687
+ type: "tool";
688
+ name: string;
689
+ };
690
+ temperature?: number;
691
+ thinking?: {
692
+ type: "enabled";
693
+ budget_tokens: number;
694
+ };
695
+ stream: true;
696
+ };
697
+ type MessagesAPIMessage = {
698
+ role: "user" | "assistant";
699
+ content: string | MessagesAPIContentBlock[];
700
+ };
701
+ type MessagesAPIContentBlock = {
702
+ type: "text";
703
+ text: string;
704
+ } | {
705
+ type: "thinking";
706
+ thinking: string;
707
+ signature?: string;
708
+ } | {
709
+ type: "redacted_thinking";
710
+ data: string;
711
+ } | {
712
+ type: "tool_use";
713
+ id: string;
714
+ name: string;
715
+ input: Record<string, unknown>;
716
+ } | {
717
+ type: "tool_result";
718
+ tool_use_id: string;
719
+ content: string | MessagesAPIContentBlock[];
720
+ is_error?: boolean;
721
+ };
722
+ type MessagesAPITool = {
723
+ name: string;
724
+ description?: string;
725
+ input_schema: Record<string, unknown>;
726
+ };
727
+ declare class MessagesAdapter extends AdapterBase {
728
+ readonly kind: "messages";
729
+ readonly capabilities: {
730
+ readonly nativeStreaming: true;
731
+ readonly messageStreaming: true;
732
+ readonly reasoningStreaming: false;
733
+ readonly toolCallStreaming: true;
734
+ readonly hiddenReasoningReplay: "partial";
735
+ readonly replayFidelity: "medium";
736
+ readonly tools: true;
737
+ readonly usage: "full";
738
+ readonly billing: "lookup";
739
+ readonly providerMetadata: true;
740
+ };
741
+ private apiKey;
742
+ private apiVersion;
743
+ private baseUrl;
744
+ private fetchFn;
745
+ private warningAccumulator;
746
+ constructor(options: MessagesAdapterOptions);
747
+ protected warn(message: string, _code?: string): void;
748
+ protected buildRequest(request: NormalizedRequest): MessagesAPIRequest;
749
+ protected runStream(providerRequest: MessagesAPIRequest, factory: EventFactory, request: NormalizedRequest): AsyncIterable<AIStreamEvent>;
750
+ }
751
+ //#endregion
752
+ //#region src/adapters/chat-completions.d.ts
753
+ type ChatCompletionsAdapterOptions = {
754
+ apiKey: string;
755
+ baseUrl?: string;
756
+ fetch?: FetchFn;
757
+ };
758
+ type ChatRequest = {
759
+ model: string;
760
+ messages: ChatMessage[];
761
+ tools?: ChatTool[];
762
+ tool_choice?: "auto" | "none" | {
763
+ type: "function";
764
+ function: {
765
+ name: string;
766
+ };
767
+ };
768
+ metadata?: Record<string, string>;
769
+ temperature?: number;
770
+ max_tokens?: number;
771
+ stream: true;
772
+ };
773
+ type ChatMessage = {
774
+ role: "system" | "user" | "assistant" | "tool";
775
+ content: string | null;
776
+ tool_calls?: ChatToolCall[];
777
+ tool_call_id?: string;
778
+ name?: string;
779
+ [key: string]: unknown;
780
+ };
781
+ type ChatToolCall = {
782
+ id: string;
783
+ type: "function";
784
+ function: {
785
+ name: string;
786
+ arguments: string;
787
+ };
788
+ };
789
+ type ChatTool = {
790
+ type: "function";
791
+ function: {
792
+ name: string;
793
+ description?: string;
794
+ parameters: Record<string, unknown>;
795
+ };
796
+ };
797
+ declare class ChatCompletionsAdapter extends AdapterBase {
798
+ readonly kind: "chat-completions";
799
+ readonly capabilities: AdapterCapabilities;
800
+ private apiKey;
801
+ private baseUrl;
802
+ private fetchFn;
803
+ private markReasoningCompatibility;
804
+ constructor(options: ChatCompletionsAdapterOptions);
805
+ protected buildRequest(request: NormalizedRequest): ChatRequest;
806
+ protected runStream(providerRequest: ChatRequest, factory: EventFactory, request: NormalizedRequest): AsyncIterable<AIStreamEvent>;
807
+ }
808
+ //#endregion
809
+ //#region src/adapters/ollama.d.ts
810
+ type OllamaAdapterOptions = {
811
+ /** Ollama 服务地址,默认 http://localhost:11434 */baseUrl?: string; /** 可选 API key(用于需要认证的代理场景) */
812
+ apiKey?: string; /** 可注入自定义 fetch 实现 */
813
+ fetch?: FetchFn;
814
+ };
815
+ type OllamaChatRequest = {
816
+ model: string;
817
+ messages: OllamaMessage[];
818
+ stream: true;
819
+ tools?: OllamaTool[];
820
+ options?: {
821
+ temperature?: number;
822
+ num_predict?: number;
823
+ [key: string]: unknown;
824
+ };
825
+ };
826
+ type OllamaMessage = {
827
+ role: "system" | "user" | "assistant" | "tool";
828
+ content: string;
829
+ images?: string[];
830
+ tool_calls?: OllamaToolCall[];
831
+ };
832
+ type OllamaToolCall = {
833
+ function: {
834
+ name: string;
835
+ arguments: Record<string, unknown>;
836
+ };
837
+ };
838
+ type OllamaTool = {
839
+ type: "function";
840
+ function: {
841
+ name: string;
842
+ description?: string;
843
+ parameters: Record<string, unknown>;
844
+ };
845
+ };
846
+ declare class OllamaAdapter extends AdapterBase {
847
+ readonly kind: "ollama";
848
+ readonly capabilities: AdapterCapabilities;
849
+ private baseUrl;
850
+ private apiKey;
851
+ private fetchFn;
852
+ constructor(options?: OllamaAdapterOptions);
853
+ protected buildRequest(request: NormalizedRequest): OllamaChatRequest;
854
+ protected runStream(providerRequest: OllamaChatRequest, factory: EventFactory, request: NormalizedRequest): AsyncIterable<AIStreamEvent>;
855
+ }
856
+ //#endregion
857
+ //#region src/helpers/mapping.d.ts
858
+ declare function mapStopReason(providerReason: string): StopReason;
859
+ declare function mapReasoningVisibility(hasThinking: boolean, hasRedacted: boolean): ReasoningItem["visibility"];
860
+ declare function textBlock(text: string): ContentBlock & {
861
+ type: "text";
862
+ };
863
+ declare function jsonBlock(json: unknown): ContentBlock & {
864
+ type: "json";
865
+ };
866
+ declare function imageBlock(imageUrl: string): ContentBlock & {
867
+ type: "image";
868
+ };
869
+ declare function opaqueBlock(payload: unknown): ContentBlock & {
870
+ type: "opaque";
871
+ };
872
+ declare function messageItem(content: ContentBlock[], overrides?: Partial<Omit<MessageItem, "type" | "content">>): MessageItem;
873
+ declare function reasoningItem(content: ContentBlock[], visibility?: ReasoningItem["visibility"], id?: string): ReasoningItem;
874
+ declare function toolCallItem(id: string, name: string, argumentsText: string, argumentsJson?: unknown): ToolCallItem;
875
+ declare function toolResultItem(callId: string, toolName: string, outcome: ToolResultItem["outcome"], content: ContentBlock[]): ToolResultItem;
876
+ declare function opaqueItem(source: OpaqueItem["source"], purpose: OpaqueItem["purpose"], payload: unknown, id?: string): OpaqueItem;
877
+ /**
878
+ * 从 output items 构建标准 replay items。
879
+ * 简单场景下 replay 与 output 一致。
880
+ * 复杂场景(需要 opaque continuation)由 adapter 自行扩展。
881
+ */
882
+ declare function replayFromOutput(output: readonly OutputItem[]): ReplayItem[];
883
+ /**
884
+ * 将单个 ContentBlock 转为纯文本。
885
+ * text 块直接返回文本,json 块序列化,其余返回空串。
886
+ */
887
+ declare function blockToText(b: ContentBlock): string;
888
+ /**
889
+ * 将 ContentBlock 数组拼接为纯文本,块间以换行符分隔。
890
+ */
891
+ declare function contentBlocksToText(blocks: ContentBlock[]): string;
892
+ /**
893
+ * 将 instructions(string | ContentBlock[])归一化为纯文本。
894
+ */
895
+ declare function instructionsToText(instructions: string | ContentBlock[]): string;
896
+ /**
897
+ * 从 OutputItem 数组中提取所有 message 类型 item 的文本内容。
898
+ */
899
+ declare function extractText(output: OutputItem[]): string;
900
+ //#endregion
901
+ //#region src/helpers/sse-parser.d.ts
902
+ /**
903
+ * 通用 SSE (Server-Sent Events) 解析器
904
+ *
905
+ * 解析标准 SSE 格式(event: + data: 行),适用于:
906
+ * - Anthropic Messages API (messages.ts)
907
+ * - OpenAI Responses API (responses.ts)
908
+ *
909
+ * 注意:OpenAI Chat Completions API 使用简化 SSE(仅有 data: 行),
910
+ * 由 chat-completions.ts 中的 parseChatSSE 处理。
911
+ *
912
+ * 用法:
913
+ * ```ts
914
+ * const { events, rest } = parseSSEEvents(buffer);
915
+ * for (const ev of events) {
916
+ * // ev.type — 事件类型字符串
917
+ * // ev.data — 已解析的 JSON 数据
918
+ * }
919
+ * // rest 是未处理的剩余 buffer,需要累积到下次调用
920
+ * ```
921
+ */
922
+ type SSEEvent = {
923
+ type: string;
924
+ data: unknown;
925
+ };
926
+ type SSEParseResult = {
927
+ events: SSEEvent[];
928
+ rest: string;
929
+ malformedEvents: number;
930
+ };
931
+ /**
932
+ * 将 SSE 文本块解析为事件数组。
933
+ * 累积事件行直到遇到空行,支持 [DONE] 标记。
934
+ * 返回已解析的事件和未处理的剩余 buffer(用于增量解析)。
935
+ *
936
+ * 关键行为:
937
+ * - 只解析完整的 event(以空行结尾)
938
+ * - 未完成的行保留在 rest 中,等待下次 chunk 补全
939
+ * - 支持跨 chunk 的 event 分片
940
+ */
941
+ declare function parseSSEEvents(chunk: string): SSEParseResult;
942
+ //#endregion
943
+ //#region src/helpers/synthetic-stream.d.ts
944
+ type SyntheticStreamOptions = {
945
+ model: string;
946
+ responseId: string;
947
+ backend: {
948
+ kind: "chat-completions" | "messages" | "responses";
949
+ };
950
+ output: OutputItem[];
951
+ replay?: ReplayItem[];
952
+ stopReason?: StopReason;
953
+ usage?: Usage;
954
+ billing?: BillingInfo;
955
+ providerMetadata?: Record<string, unknown>;
956
+ rawResponseId?: string;
957
+ warnings?: string[];
958
+ };
959
+ /**
960
+ * 将已解析的 output items 包装为完整规范事件流。
961
+ *
962
+ * 用法示例(在 adapter 的 runStream 中):
963
+ * ```ts
964
+ * const result = parseNonStreamingResponse(data);
965
+ * yield* syntheticStream({
966
+ * model: request.model,
967
+ * responseId: request.requestId,
968
+ * backend: { kind: "chat-completions" },
969
+ * output: result.output,
970
+ * stopReason: result.stopReason,
971
+ * usage: result.usage,
972
+ * });
973
+ * ```
974
+ */
975
+ declare function syntheticStream(options: SyntheticStreamOptions): AsyncIterable<AIStreamEvent>;
976
+ //#endregion
977
+ 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, CAPABILITY_MATRIX, ChatCompletionsAdapter, type ChatCompletionsAdapterOptions, type ContentBlock, type CreateAIClientOptions, type EventFactory, type EventFactoryBackend, type EventFactoryState, type FetchFn, type IncludeSettings, type InputItem, type LookupResult, type MessageCompletedEvent, type MessageDeltaEvent, type MessageItem, type MessageStartedEvent, MessagesAdapter, type MessagesAdapterOptions, type NormalizeOptions, type NormalizedRequest, OllamaAdapter, type OllamaAdapterOptions, type OpaqueItem, type OutputItem, 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 StreamResult, type SyntheticStreamOptions, type ToolCallCompletedEvent, type ToolCallDeltaEvent, type ToolCallItem, type ToolCallStartedEvent, type ToolChoice, type ToolDefinition, type ToolResultItem, type Usage, type UsageSource, type ValidationIssue, WarningCode, aggregateEvents, assertValidRequest, blockToText, collectStream, contentBlocksToText, createAIClient, createEventFactory, emitMalformedStreamWarning, extractText, imageBlock, instructionsToText, jsonBlock, mapReasoningVisibility, mapStopReason, messageItem, metadataSourceList, normalizeRequest, opaqueBlock, opaqueItem, parseSSEEvents, reasoningItem, replayFromOutput, syntheticStream, textBlock, toolCallItem, toolResultItem, validateRequest };
978
+ //# sourceMappingURL=index.d.mts.map