@codehz/ai 0.1.8 → 0.2.1

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.
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Provider usage → canonical Usage 映射
3
3
  *
4
- * best-effort 提取 reasoning / cache / billable 等扩展字段。
4
+ * best-effort 提取 reasoning / cache 等扩展字段。
5
5
  */
6
6
 
7
7
  import type { Usage } from "../types/index.js";
@@ -20,27 +20,6 @@ function record(obj: Record<string, number | undefined>): Partial<Usage> {
20
20
  return out;
21
21
  }
22
22
 
23
- function billableFromOpenAIStyle(
24
- inputTokens: number | undefined,
25
- outputTokens: number | undefined,
26
- cachedInputTokens: number | undefined,
27
- reasoningTokens: number | undefined,
28
- ): Pick<Usage, "billableInputTokens" | "billableOutputTokens"> {
29
- let billableInputTokens: number | undefined;
30
- if (inputTokens !== undefined) {
31
- billableInputTokens =
32
- cachedInputTokens !== undefined ? Math.max(0, inputTokens - cachedInputTokens) : inputTokens;
33
- }
34
-
35
- let billableOutputTokens: number | undefined;
36
- if (outputTokens !== undefined) {
37
- billableOutputTokens =
38
- reasoningTokens !== undefined ? Math.max(0, outputTokens - reasoningTokens) : outputTokens;
39
- }
40
-
41
- return record({ billableInputTokens, billableOutputTokens });
42
- }
43
-
44
23
  /** OpenAI Chat Completions `usage` */
45
24
  export function usageFromChatCompletions(raw: {
46
25
  prompt_tokens?: number;
@@ -63,7 +42,6 @@ export function usageFromChatCompletions(raw: {
63
42
  totalTokens,
64
43
  cachedInputTokens,
65
44
  reasoningTokens,
66
- ...billableFromOpenAIStyle(inputTokens, outputTokens, cachedInputTokens, reasoningTokens),
67
45
  });
68
46
  }
69
47
 
@@ -90,7 +68,6 @@ export function usageFromOpenAIResponses(raw: {
90
68
  totalTokens,
91
69
  cachedInputTokens,
92
70
  reasoningTokens,
93
- ...billableFromOpenAIStyle(inputTokens, outputTokens, cachedInputTokens, reasoningTokens),
94
71
  });
95
72
  }
96
73
 
@@ -111,13 +88,7 @@ export function usageFromAnthropicMessages(raw: {
111
88
  (n): n is number => n !== undefined,
112
89
  );
113
90
  const inputTokens = inputParts.length > 0 ? inputParts.reduce((sum, n) => sum + n, 0) : undefined;
114
- const totalTokens =
115
- inputTokens !== undefined && outputTokens !== undefined ? inputTokens + outputTokens : undefined;
116
-
117
- let billableInputTokens: number | undefined;
118
- if (uncachedInputTokens !== undefined || cacheWriteInputTokens !== undefined) {
119
- billableInputTokens = (uncachedInputTokens ?? 0) + (cacheWriteInputTokens ?? 0);
120
- }
91
+ const totalTokens = inputTokens !== undefined && outputTokens !== undefined ? inputTokens + outputTokens : undefined;
121
92
 
122
93
  return record({
123
94
  inputTokens,
@@ -125,26 +96,18 @@ export function usageFromAnthropicMessages(raw: {
125
96
  totalTokens,
126
97
  cachedInputTokens,
127
98
  cacheWriteInputTokens,
128
- billableInputTokens,
129
- billableOutputTokens: outputTokens,
130
99
  });
131
100
  }
132
101
 
133
- /** Ollama 流式 chunk(无 cache / reasoning 细分时仅填基础与 billable 镜像) */
134
- export function usageFromOllama(raw: {
135
- prompt_eval_count?: number;
136
- eval_count?: number;
137
- }): Partial<Usage> {
102
+ /** Ollama 流式 chunk */
103
+ export function usageFromOllama(raw: { prompt_eval_count?: number; eval_count?: number }): Partial<Usage> {
138
104
  const inputTokens = num(raw.prompt_eval_count);
139
105
  const outputTokens = num(raw.eval_count);
140
- const totalTokens =
141
- inputTokens !== undefined && outputTokens !== undefined ? inputTokens + outputTokens : undefined;
106
+ const totalTokens = inputTokens !== undefined && outputTokens !== undefined ? inputTokens + outputTokens : undefined;
142
107
 
143
108
  return record({
144
109
  inputTokens,
145
110
  outputTokens,
146
111
  totalTokens,
147
- billableInputTokens: inputTokens,
148
- billableOutputTokens: outputTokens,
149
112
  });
150
- }
113
+ }
@@ -21,9 +21,20 @@ export type NormalizedRequest = AIRequest & {
21
21
 
22
22
  // ── Adapter 接口 ──────────────────────────────────────────────
23
23
 
24
+ export type StreamingCapability = "native" | "synthetic" | "none";
25
+
26
+ export type AdapterCapabilities = {
27
+ readonly textStreaming: StreamingCapability;
28
+ readonly reasoningStreaming: StreamingCapability;
29
+ readonly toolCallStreaming: StreamingCapability;
30
+ readonly replay: "canonical" | "opaque" | "none";
31
+ readonly usage: "stream" | "final" | "none";
32
+ readonly toolResultOutcomes: ReadonlyArray<"success" | "error" | "rejected">;
33
+ };
34
+
24
35
  export interface BackendAdapter {
25
36
  readonly kind: "chat-completions" | "messages" | "responses" | "ollama" | "mock";
26
- readonly nativeStreaming: boolean;
37
+ readonly capabilities: AdapterCapabilities;
27
38
  stream(request: NormalizedRequest): AsyncIterable<AIStreamEvent>;
28
39
  }
29
40
 
@@ -7,8 +7,8 @@
7
7
  */
8
8
 
9
9
  import type { ContentBlock } from "./content.js";
10
- import type { MessageItem, ReasoningItem, ToolCallItem } from "./items.js";
11
- import type { AIResponse, Usage, BillingInfo, AuxiliaryInfo } from "./response.js";
10
+ import type { Usage, BillingInfo, AuxiliaryInfo, BackendTrace, StopReason } from "./response.js";
11
+ import type { OpaqueItem, ReplayItem } from "./items.js";
12
12
 
13
13
  // ── 事件基类 ──────────────────────────────────────────────────
14
14
 
@@ -45,7 +45,14 @@ export type ResponseAuxiliaryEvent = StreamEventBase & {
45
45
 
46
46
  export type ResponseCompletedEvent = StreamEventBase & {
47
47
  type: "response.completed";
48
- response: AIResponse;
48
+ replay: ReplayItem[];
49
+ stopReason?: StopReason;
50
+ usage?: Usage;
51
+ billing?: BillingInfo;
52
+ auxiliary?: AuxiliaryInfo;
53
+ warnings?: string[];
54
+ opaqueOutput?: OpaqueItem[];
55
+ trace?: Partial<BackendTrace>;
49
56
  };
50
57
 
51
58
  // ── 消息流事件 ────────────────────────────────────────────────
@@ -61,15 +68,12 @@ export type MessageStartedEvent = StreamEventBase & {
61
68
  export type MessageDeltaEvent = StreamEventBase & {
62
69
  type: "message.delta";
63
70
  itemId: string;
64
- delta: {
65
- type: "text";
66
- text: string;
67
- };
71
+ delta: ContentBlock;
68
72
  };
69
73
 
70
74
  export type MessageCompletedEvent = StreamEventBase & {
71
75
  type: "message.completed";
72
- item: MessageItem;
76
+ itemId: string;
73
77
  };
74
78
 
75
79
  // ── 思维链流事件 ──────────────────────────────────────────────
@@ -90,7 +94,7 @@ export type ReasoningDeltaEvent = StreamEventBase & {
90
94
 
91
95
  export type ReasoningCompletedEvent = StreamEventBase & {
92
96
  type: "reasoning.completed";
93
- item: ReasoningItem;
97
+ itemId: string;
94
98
  };
95
99
 
96
100
  // ── 工具调用流事件 ────────────────────────────────────────────
@@ -113,7 +117,7 @@ export type ToolCallDeltaEvent = StreamEventBase & {
113
117
 
114
118
  export type ToolCallCompletedEvent = StreamEventBase & {
115
119
  type: "tool_call.completed";
116
- item: ToolCallItem;
120
+ itemId: string;
117
121
  };
118
122
 
119
123
  // ── 统一事件联合 ──────────────────────────────────────────────
@@ -46,4 +46,12 @@ export type {
46
46
  } from "./events.js";
47
47
 
48
48
  // Adapter 协议和 client 类型
49
- export type { BackendAdapter, FetchFn, NormalizedRequest, CreateAIClientOptions, AIClient } from "./adapter.js";
49
+ export type {
50
+ AdapterCapabilities,
51
+ StreamingCapability,
52
+ BackendAdapter,
53
+ FetchFn,
54
+ NormalizedRequest,
55
+ CreateAIClientOptions,
56
+ AIClient,
57
+ } from "./adapter.js";
@@ -24,10 +24,6 @@ export type Usage = {
24
24
  cachedInputTokens?: number;
25
25
  /** Tokens written to prompt cache (Anthropic cache_creation_input_tokens) */
26
26
  cacheWriteInputTokens?: number;
27
- /** Best-effort billable input (full-rate input; excludes discounted cache reads where known) */
28
- billableInputTokens?: number;
29
- /** Best-effort billable output (non-reasoning slice when provider gives reasoning breakdown) */
30
- billableOutputTokens?: number;
31
27
  };
32
28
 
33
29
  export type BillingInfo = {