@weisiren000/oiiai 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,112 +1,165 @@
1
- # @weisiren000/oiiai
2
-
3
- 统一的 AI Provider 接口封装,支持 OpenRouter、OpenAI、Anthropic 等多种 AI 服务。
4
-
5
- ## 安装
6
-
7
- ```bash
8
- npm install @weisiren000/oiiai
9
- ```
10
-
11
- ## 快速开始
12
-
13
- ```typescript
14
- import { OpenRouterProvider } from '@weisiren000/oiiai';
15
-
16
- const ai = new OpenRouterProvider('your-api-key');
17
-
18
- // 简单问答
19
- const answer = await ai.ask('deepseek/deepseek-chat', '你好');
20
-
21
- // 带系统提示
22
- const response = await ai.askWithSystem(
23
- 'deepseek/deepseek-chat',
24
- '你是一个有帮助的助手',
25
- '介绍一下自己'
26
- );
27
-
28
- // 完整对话
29
- const result = await ai.chat({
30
- model: 'deepseek/deepseek-chat',
31
- messages: [
32
- { role: 'system', content: '你是一个简洁的助手' },
33
- { role: 'user', content: '1+1=?' }
34
- ],
35
- temperature: 0.7,
36
- maxTokens: 100
37
- });
38
-
39
- console.log(result.content);
40
- console.log(result.usage);
41
- ```
42
-
43
- ## 流式输出
44
-
45
- ```typescript
46
- for await (const chunk of ai.chatStream({
47
- model: 'deepseek/deepseek-chat',
48
- messages: [{ role: 'user', content: '写一首诗' }]
49
- })) {
50
- if (chunk.type === 'content') {
51
- process.stdout.write(chunk.text);
52
- }
53
- }
54
- ```
55
-
56
- ## 思考模型 (Reasoning)
57
-
58
- 支持 OpenAI o1/o3、DeepSeek R1、Claude 等思考模型:
59
-
60
- ```typescript
61
- const result = await ai.chat({
62
- model: 'deepseek/deepseek-r1',
63
- messages: [{ role: 'user', content: '9.11 和 9.9 哪个大?' }],
64
- reasoning: {
65
- effort: 'high', // OpenAI/Grok 风格
66
- // maxTokens: 2000, // Anthropic/Gemini 风格
67
- // exclude: true, // 不返回思考内容
68
- }
69
- });
70
-
71
- console.log('思考过程:', result.reasoning);
72
- console.log('最终答案:', result.content);
73
- ```
74
-
75
- ## 统一接口
76
-
77
- 所有 Provider 实现统一的 `AIProvider` 接口:
78
-
79
- ```typescript
80
- interface AIProvider {
81
- readonly name: string;
82
- chat(options: ChatOptions): Promise<ChatResult>;
83
- chatStream(options: ChatOptions): AsyncGenerator<StreamChunk>;
84
- ask(model: string, question: string, options?): Promise<string>;
85
- askWithSystem(model: string, systemPrompt: string, userMessage: string, options?): Promise<string>;
86
- listModels?(): Promise<ModelInfo[]>;
87
- }
88
- ```
89
-
90
- ## 自定义 Provider
91
-
92
- 继承 `BaseAIProvider` 实现自定义 Provider:
93
-
94
- ```typescript
95
- import { BaseAIProvider, ChatOptions, ChatResult, StreamChunk } from '@weisiren000/oiiai';
96
-
97
- class MyProvider extends BaseAIProvider {
98
- readonly name = 'my-provider';
99
-
100
- async chat(options: ChatOptions): Promise<ChatResult> {
101
- // 实现非流式请求
102
- }
103
-
104
- async *chatStream(options: ChatOptions): AsyncGenerator<StreamChunk> {
105
- // 实现流式请求
106
- }
107
- }
108
- ```
109
-
110
- ## License
111
-
112
- MIT
1
+ <div align="center">
2
+
3
+ # 🤖 @weisiren000/oiiai
4
+
5
+ **统一的 AI Provider 接口封装库**
6
+
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-3178C6?style=flat-square&logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
8
+ [![Node.js](https://img.shields.io/badge/Node.js-18+-339933?style=flat-square&logo=node.js&logoColor=white)](https://nodejs.org/)
9
+ [![License](https://img.shields.io/badge/License-MIT-yellow?style=flat-square)](LICENSE)
10
+ [![npm](https://img.shields.io/npm/v/@weisiren000/oiiai?style=flat-square&color=CB3837&logo=npm)](https://www.npmjs.com/package/@weisiren000/oiiai)
11
+
12
+ 支持 **OpenRouter** · **Gemini** · **Groq** · **HuggingFace** · **ModelScope**
13
+
14
+ [📖 详细文档](./docs/providers.md) · [🚀 快速开始](#快速开始) · [💡 示例](#使用示例)
15
+
16
+ </div>
17
+
18
+ ---
19
+
20
+ ## ✨ 特性
21
+
22
+ - 🔌 **统一接口** - 所有 Provider 使用相同 API,学会一个就会全部
23
+ - 🧠 **Reasoning 支持** - 统一的思考模式配置,自动转换各 Provider 格式
24
+ - 🌊 **流式输出** - 支持实时流式响应,区分思考/回答内容
25
+ - 📦 **TypeScript** - 完整类型定义,开发体验友好
26
+ - 🔧 **可扩展** - 轻松实现自定义 Provider
27
+
28
+ ## 📦 安装
29
+
30
+ ```bash
31
+ npm install @weisiren000/oiiai
32
+ ```
33
+
34
+ ## 🚀 快速开始
35
+
36
+ ```typescript
37
+ import { ai } from '@weisiren000/oiiai';
38
+
39
+ // 创建 Provider(所有 Provider 使用方式完全一致)
40
+ const openrouter = ai.openrouter('your-api-key');
41
+ const gemini = ai.gemini('your-api-key');
42
+ const groq = ai.groq('your-api-key');
43
+
44
+ // 简单问答
45
+ const answer = await openrouter.ask('openai/gpt-4o', '你好');
46
+ ```
47
+
48
+ ## 💡 使用示例
49
+
50
+ ### 简单问答
51
+
52
+ ```typescript
53
+ const answer = await provider.ask('model-id', '什么是 TypeScript?');
54
+ ```
55
+
56
+ ### 带系统提示
57
+
58
+ ```typescript
59
+ const answer = await provider.askWithSystem(
60
+ 'model-id',
61
+ '你是一个专业的代码助手',
62
+ '如何定义 TypeScript 接口?'
63
+ );
64
+ ```
65
+
66
+ ### 完整对话
67
+
68
+ ```typescript
69
+ const result = await provider.chat({
70
+ model: 'model-id',
71
+ messages: [
72
+ { role: 'system', content: '你是一个友好的助手' },
73
+ { role: 'user', content: '你好!' },
74
+ ],
75
+ temperature: 0.7,
76
+ maxTokens: 1000,
77
+ });
78
+
79
+ console.log(result.content); // 回答内容
80
+ console.log(result.usage); // Token 使用情况
81
+ ```
82
+
83
+ ### 流式输出
84
+
85
+ ```typescript
86
+ for await (const chunk of provider.chatStream({
87
+ model: 'model-id',
88
+ messages: [{ role: 'user', content: '写一首诗' }],
89
+ })) {
90
+ if (chunk.type === 'reasoning') {
91
+ process.stdout.write(`[思考] ${chunk.text}`);
92
+ } else {
93
+ process.stdout.write(chunk.text);
94
+ }
95
+ }
96
+ ```
97
+
98
+ ### 思考模式 (Reasoning)
99
+
100
+ ```typescript
101
+ const result = await provider.chat({
102
+ model: 'deepseek/deepseek-r1',
103
+ messages: [{ role: 'user', content: '9.11 和 9.9 哪个大?' }],
104
+ reasoning: {
105
+ effort: 'high', // 'off' | 'low' | 'medium' | 'high'
106
+ },
107
+ });
108
+
109
+ console.log('思考过程:', result.reasoning);
110
+ console.log('最终答案:', result.content);
111
+ ```
112
+
113
+ ## 🔧 支持的 Provider
114
+
115
+ | Provider | 服务商 | Reasoning 参数 | 参考文档 |
116
+ | ------------- | ------------- | ---------------------------- | ---------------------------------------------------------------------- |
117
+ | `openrouter` | OpenRouter | `reasoning.effort` | [Docs](https://openrouter.ai/docs/requests) |
118
+ | `gemini` | Google Gemini | `reasoning_effort` | [Docs](https://ai.google.dev/gemini-api/docs/text-generation) |
119
+ | `groq` | Groq | `reasoning_format: 'parsed'` | [Docs](https://console.groq.com/docs/reasoning) |
120
+ | `huggingface` | HuggingFace | 不支持 | - |
121
+ | `modelscope` | 魔搭社区 | `enable_thinking` | [Docs](https://www.alibabacloud.com/help/en/model-studio/deepseek-api) |
122
+
123
+ ## 📝 常用模型
124
+
125
+ ```typescript
126
+ // OpenRouter
127
+ 'openai/gpt-4o';
128
+ 'anthropic/claude-sonnet-4';
129
+ 'deepseek/deepseek-r1';
130
+
131
+ // Gemini
132
+ 'gemini-2.5-flash';
133
+ 'gemini-2.5-pro';
134
+
135
+ // Groq
136
+ 'llama-3.3-70b-versatile';
137
+ 'qwen/qwen3-32b';
138
+
139
+ // ModelScope
140
+ 'deepseek-ai/DeepSeek-R1';
141
+ 'Qwen/Qwen2.5-72B-Instruct';
142
+ ```
143
+
144
+ ## 🛠️ 自定义 Provider
145
+
146
+ ```typescript
147
+ import { BaseProvider } from '@weisiren000/oiiai';
148
+ import type { ChatOptions, ChatResult, StreamChunk } from '@weisiren000/oiiai';
149
+
150
+ class MyProvider extends BaseProvider {
151
+ readonly name = 'my-provider';
152
+
153
+ async chat(options: ChatOptions): Promise<ChatResult> {
154
+ // 实现非流式请求
155
+ }
156
+
157
+ async *chatStream(options: ChatOptions): AsyncGenerator<StreamChunk> {
158
+ // 实现流式请求
159
+ }
160
+ }
161
+ ```
162
+
163
+ ## 📄 License
164
+
165
+ MIT
package/dist/index.d.mts CHANGED
@@ -6,20 +6,56 @@ interface ChatMessage {
6
6
  content: string;
7
7
  }
8
8
  /**
9
- * 思考/推理配置
10
- * - effort: OpenAI o1/o3, Grok 使用
11
- * - maxTokens: Anthropic Claude, Gemini, Qwen 使用
9
+ * 统一的思考努力程度
10
+ * - off: 关闭思考
11
+ * - low: 快速思考,适合简单问题
12
+ * - medium: 平衡模式(默认)
13
+ * - high: 深度思考,适合复杂问题
14
+ */
15
+ type ReasoningEffort = 'off' | 'low' | 'medium' | 'high';
16
+ /**
17
+ * 统一的思考/推理配置
18
+ *
19
+ * 只需设置 effort,库会自动转换为各 Provider 需要的格式:
20
+ * - OpenRouter: effort 参数
21
+ * - Gemini: reasoning_effort 参数
22
+ * - Groq: reasoning_effort 参数
23
+ * - ModelScope: enable_thinking 参数
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * // 简单用法 - 只设置 effort
28
+ * { effort: 'high' }
29
+ *
30
+ * // 高级用法 - 精细控制
31
+ * { effort: 'high', budgetTokens: 8000 }
32
+ * ```
12
33
  */
13
34
  interface ReasoningConfig {
14
- /** 思考努力程度 */
15
- effort?: 'high' | 'medium' | 'low';
16
- /** 思考最大 token 数 */
17
- maxTokens?: number;
18
- /** 是否在响应中排除思考内容 */
35
+ /**
36
+ * 思考努力程度(推荐使用)
37
+ * - 'off': 关闭思考
38
+ * - 'low': 快速思考
39
+ * - 'medium': 平衡模式
40
+ * - 'high': 深度思考
41
+ */
42
+ effort?: ReasoningEffort;
43
+ /**
44
+ * 思考 token 预算(可选,精细控制)
45
+ * 设置后会覆盖 effort 对应的默认值
46
+ * 仅部分 Provider 支持(OpenRouter)
47
+ */
48
+ budgetTokens?: number;
49
+ /**
50
+ * 是否在响应中排除思考内容
51
+ * 仅部分 Provider 支持(OpenRouter)
52
+ */
19
53
  exclude?: boolean;
20
- /** 是否启用思考 */
21
- enabled?: boolean;
22
54
  }
55
+ /**
56
+ * effort 到 token 预算的默认映射
57
+ */
58
+ declare const EFFORT_TOKEN_MAP: Record<ReasoningEffort, number>;
23
59
  interface ChatOptions {
24
60
  /** 模型 ID */
25
61
  model: string;
@@ -114,20 +150,70 @@ interface AIProvider {
114
150
  * AI Provider 基础抽象类
115
151
  * 提供一些通用实现,子类只需实现核心方法
116
152
  */
117
- declare abstract class ProviderBase implements AIProvider {
153
+ declare abstract class BaseProvider implements AIProvider {
118
154
  abstract readonly name: string;
119
155
  abstract chat(options: ChatOptions): Promise<ChatResult>;
120
156
  abstract chatStream(options: ChatOptions): AsyncGenerator<StreamChunk, void, unknown>;
121
157
  /**
122
158
  * 简单对话:单轮问答(默认实现)
159
+ * 对于思考模型,如果 content 为空则返回 reasoning
123
160
  */
124
161
  ask(model: string, question: string, options?: Omit<ChatOptions, 'model' | 'messages'>): Promise<string>;
125
162
  /**
126
163
  * 带系统提示的对话(默认实现)
164
+ * 对于思考模型,如果 content 为空则返回 reasoning
127
165
  */
128
166
  askWithSystem(model: string, systemPrompt: string, userMessage: string, options?: Omit<ChatOptions, 'model' | 'messages'>): Promise<string>;
129
167
  }
130
168
 
169
+ /**
170
+ * 统一的 Provider 工厂
171
+ * 让所有 Provider 使用方式一致
172
+ */
173
+
174
+ /**
175
+ * 支持的 Provider 类型
176
+ */
177
+ type ProviderType = 'openrouter' | 'gemini' | 'groq' | 'huggingface' | 'modelscope' | 'deepseek';
178
+ /**
179
+ * 统一的 Provider 配置
180
+ */
181
+ interface ProviderConfig {
182
+ /** Provider 类型 */
183
+ provider: ProviderType;
184
+ /** API Key */
185
+ apiKey: string;
186
+ /** 自定义 API 地址(可选) */
187
+ baseUrl?: string;
188
+ }
189
+ /**
190
+ * 创建 AI Provider 实例
191
+ *
192
+ * @example
193
+ * ```ts
194
+ * // 所有 Provider 使用相同方式创建
195
+ * const openrouter = createProvider({ provider: 'openrouter', apiKey: 'xxx' });
196
+ * const gemini = createProvider({ provider: 'gemini', apiKey: 'xxx' });
197
+ * const groq = createProvider({ provider: 'groq', apiKey: 'xxx' });
198
+ *
199
+ * // 之后使用方式完全一致
200
+ * const answer = await openrouter.ask('gpt-4o', '你好');
201
+ * const answer = await gemini.ask('gemini-2.5-flash', '你好');
202
+ * ```
203
+ */
204
+ declare function createProvider(config: ProviderConfig): AIProvider;
205
+ /**
206
+ * 快捷创建函数
207
+ */
208
+ declare const ai: {
209
+ openrouter: (apiKey: string, baseUrl?: string) => AIProvider;
210
+ gemini: (apiKey: string, baseUrl?: string) => AIProvider;
211
+ groq: (apiKey: string, baseUrl?: string) => AIProvider;
212
+ huggingface: (apiKey: string, baseUrl?: string) => AIProvider;
213
+ modelscope: (apiKey: string, baseUrl?: string) => AIProvider;
214
+ deepseek: (apiKey: string, baseUrl?: string) => AIProvider;
215
+ };
216
+
131
217
  /**
132
218
  * OpenRouter Provider 实现
133
219
  */
@@ -152,7 +238,7 @@ interface OpenRouterModelInfo extends ModelInfo {
152
238
  /**
153
239
  * OpenRouter Provider
154
240
  */
155
- declare class OpenRouterProvider extends ProviderBase {
241
+ declare class OpenRouterProvider extends BaseProvider {
156
242
  readonly name = "openrouter";
157
243
  private client;
158
244
  constructor(apiKey: string);
@@ -170,4 +256,129 @@ declare class OpenRouterProvider extends ProviderBase {
170
256
  listModels(): Promise<OpenRouterModelInfo[]>;
171
257
  }
172
258
 
173
- export { type AIProvider, type ChatMessage, type ChatOptions, type ChatResult, type ModelInfo, type ModelPricing, type OpenRouterModelInfo, OpenRouterProvider, ProviderBase, type ReasoningConfig, type StreamChunk, type TokenUsage };
259
+ /**
260
+ * ModelScope Provider 实现
261
+ * 使用 OpenAI 兼容 API
262
+ */
263
+
264
+ /**
265
+ * ModelScope Provider 配置
266
+ */
267
+ interface ModelScopeConfig {
268
+ apiKey: string;
269
+ baseUrl?: string;
270
+ }
271
+ /**
272
+ * ModelScope Provider
273
+ * 兼容 OpenAI API 格式,支持 DeepSeek 等模型
274
+ */
275
+ declare class ModelScopeProvider extends BaseProvider {
276
+ readonly name = "modelscope";
277
+ private apiKey;
278
+ private baseUrl;
279
+ constructor(config: ModelScopeConfig | string);
280
+ /**
281
+ * 发送聊天请求(非流式)
282
+ */
283
+ chat(options: ChatOptions): Promise<ChatResult>;
284
+ /**
285
+ * 发送流式聊天请求
286
+ */
287
+ chatStream(options: ChatOptions): AsyncGenerator<StreamChunk, void, unknown>;
288
+ }
289
+
290
+ /**
291
+ * HuggingFace Provider 实现
292
+ * 使用 HuggingFace Router API (OpenAI 兼容)
293
+ */
294
+
295
+ /**
296
+ * HuggingFace Provider 配置
297
+ */
298
+ interface HuggingFaceConfig {
299
+ apiKey: string;
300
+ baseUrl?: string;
301
+ }
302
+ /**
303
+ * HuggingFace Provider
304
+ * 使用 HuggingFace Router,兼容 OpenAI API 格式
305
+ */
306
+ declare class HuggingFaceProvider extends BaseProvider {
307
+ readonly name = "huggingface";
308
+ private apiKey;
309
+ private baseUrl;
310
+ constructor(config: HuggingFaceConfig | string);
311
+ /**
312
+ * 发送聊天请求(非流式)
313
+ */
314
+ chat(options: ChatOptions): Promise<ChatResult>;
315
+ /**
316
+ * 发送流式聊天请求
317
+ */
318
+ chatStream(options: ChatOptions): AsyncGenerator<StreamChunk, void, unknown>;
319
+ }
320
+
321
+ /**
322
+ * Groq Provider 实现
323
+ * 使用 Groq API (OpenAI 兼容)
324
+ */
325
+
326
+ /**
327
+ * Groq Provider 配置
328
+ */
329
+ interface GroqConfig {
330
+ apiKey: string;
331
+ baseUrl?: string;
332
+ }
333
+ /**
334
+ * Groq Provider
335
+ * 兼容 OpenAI API 格式,支持 reasoning_effort 参数
336
+ */
337
+ declare class GroqProvider extends BaseProvider {
338
+ readonly name = "groq";
339
+ private apiKey;
340
+ private baseUrl;
341
+ constructor(config: GroqConfig | string);
342
+ /**
343
+ * 发送聊天请求(非流式)
344
+ */
345
+ chat(options: ChatOptions): Promise<ChatResult>;
346
+ /**
347
+ * 发送流式聊天请求
348
+ */
349
+ chatStream(options: ChatOptions): AsyncGenerator<StreamChunk, void, unknown>;
350
+ }
351
+
352
+ /**
353
+ * Gemini Provider 实现
354
+ * 使用 Google Gemini API (OpenAI 兼容格式)
355
+ * https://ai.google.dev/gemini-api/docs/openai
356
+ */
357
+
358
+ /**
359
+ * Gemini Provider 配置
360
+ */
361
+ interface GeminiConfig {
362
+ apiKey: string;
363
+ baseUrl?: string;
364
+ }
365
+ /**
366
+ * Gemini Provider
367
+ * 使用 Google Gemini API,兼容 OpenAI 格式
368
+ */
369
+ declare class GeminiProvider extends BaseProvider {
370
+ readonly name = "gemini";
371
+ private apiKey;
372
+ private baseUrl;
373
+ constructor(config: GeminiConfig | string);
374
+ /**
375
+ * 发送聊天请求(非流式)
376
+ */
377
+ chat(options: ChatOptions): Promise<ChatResult>;
378
+ /**
379
+ * 发送流式聊天请求
380
+ */
381
+ chatStream(options: ChatOptions): AsyncGenerator<StreamChunk, void, unknown>;
382
+ }
383
+
384
+ export { type AIProvider, BaseProvider, type ChatMessage, type ChatOptions, type ChatResult, EFFORT_TOKEN_MAP, GeminiProvider, GroqProvider, HuggingFaceProvider, type ModelInfo, type ModelPricing, ModelScopeProvider, type OpenRouterModelInfo, OpenRouterProvider, type ProviderConfig, type ProviderType, type ReasoningConfig, type ReasoningEffort, type StreamChunk, type TokenUsage, ai, createProvider };