{"_id":"s-aiproviders-core","_rev":"2-1e6d9c812581ae2a6ad4b7016328216a","name":"s-aiproviders-core","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"s-aiproviders-core","version":"0.1.0","keywords":["ai","llm","openai","anthropic","claude","gemini","deepseek","kimi","qwen","doubao","zhipu","tokenplan","image-generation","streaming","sse"],"author":{"name":"lisiyuan0828"},"license":"MIT","_id":"s-aiproviders-core@0.1.0","maintainers":[{"name":"lisiyuan0828","email":"lisiyuan0828@gmail.com"}],"homepage":"https://github.com/lisiyuan0828/S-AIProviders/tree/main/packages/core#readme","bugs":{"url":"https://github.com/lisiyuan0828/S-AIProviders/issues"},"dist":{"shasum":"1dda5c3a099e38a657f30f4a5c74b8eae3cc9417","tarball":"https://registry.npmjs.org/s-aiproviders-core/-/s-aiproviders-core-0.1.0.tgz","fileCount":54,"integrity":"sha512-HjlssxLEIFxmcR96AFhVicQ3QdqLlzipR9fsYy5a3QoWurzdVWYxM/EQvBJimEtkrbtyap9A6akF0aSp1GfWcw==","signatures":[{"sig":"MEUCIDemTtDVnAFYzo9Qwf/vzCh0RXsDIH3bCm1o6jHloZIkAiEA5zN6eSUjSPLT+V0k49rv8M2g6ZGBpXZHks8J8CHcpzM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":120547},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.17"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./image-gen":{"types":"./dist/image-gen/index.d.ts","import":"./dist/image-gen/index.js"}},"gitHead":"22be523c093d0ab356eccc0d3d7bbcabd4ccf5bb","scripts":{"build":"tsc -p tsconfig.json","clean":"rm -rf dist","typecheck":"tsc -p tsconfig.json --noEmit","prepublishOnly":"pnpm clean && pnpm build"},"_npmUser":{"name":"lisiyuan0828","email":"lisiyuan0828@gmail.com"},"repository":{"url":"git+https://github.com/lisiyuan0828/S-AIProviders.git","type":"git","directory":"packages/core"},"_npmVersion":"10.8.2","description":"Unified AI provider protocol layer: OpenAI-compatible / Anthropic / Gemini chat streaming + image generation (OpenAI-compatible & Tencent Cloud TC3).","directories":{},"_nodeVersion":"20.18.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.7.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/s-aiproviders-core_0.1.0_1779175991279_0.0019378154847256024","host":"s3://npm-registry-packages-npm-production"},"deprecated":"This package has been merged into 's-aiproviders'. Please use 'npm install s-aiproviders' instead."}},"time":{"created":"2026-05-19T07:33:11.189Z","modified":"2026-05-19T07:38:06.717Z","0.1.0":"2026-05-19T07:33:11.452Z"},"bugs":{"url":"https://github.com/lisiyuan0828/S-AIProviders/issues"},"author":{"name":"lisiyuan0828"},"license":"MIT","homepage":"https://github.com/lisiyuan0828/S-AIProviders/tree/main/packages/core#readme","keywords":["ai","llm","openai","anthropic","claude","gemini","deepseek","kimi","qwen","doubao","zhipu","tokenplan","image-generation","streaming","sse"],"repository":{"url":"git+https://github.com/lisiyuan0828/S-AIProviders.git","type":"git","directory":"packages/core"},"description":"Unified AI provider protocol layer: OpenAI-compatible / Anthropic / Gemini chat streaming + image generation (OpenAI-compatible & Tencent Cloud TC3).","maintainers":[{"name":"lisiyuan0828","email":"lisiyuan0828@gmail.com"}],"readme":"# s-aiproviders-core\n\n> 统一的 AI Provider 抽象。一套 API 同时对接 OpenAI、Anthropic、Gemini、DeepSeek、Kimi、Qwen、豆包、智谱、腾讯 Token Plan，并通过 DALL·E / CogView / 混元提供图像生成。**零运行时依赖**。\n\n[English](./README.md) · [简体中文](./README.zh.md)\n\n[![npm](https://img.shields.io/npm/v/%40s-aiproviders%2Fcore.svg)](https://www.npmjs.com/package/s-aiproviders-core)\n[![install size](https://img.shields.io/badge/install%20size-%3C30KB-brightgreen.svg)](#)\n[![runtime deps](https://img.shields.io/badge/runtime%20deps-0-success.svg)](#)\n[![types](https://img.shields.io/badge/types-bundled-blue.svg)](#)\n[![Node](https://img.shields.io/badge/node-%E2%89%A518.17-brightgreen.svg)](#环境要求)\n[![license](https://img.shields.io/badge/license-MIT-green.svg)](#许可证)\n\n---\n\n## 亮点\n\n- **流式对话** — `openai-compatible`、`anthropic`、`gemini` 三种方言归一到同一个 `IProvider.chat()`，返回 `AsyncIterable<ChatChunk>`。\n- **图像生成** — 兼容 OpenAI Images（DALL·E 3 / gpt-image-1 / CogView / lkeap 网关下的混元）和**腾讯云 TC3**（`SubmitTextToImageJob` 异步任务，自带 TC3-HMAC-SHA256 签名 + 状态轮询）。模块挂在仅 Node 子路径下，绝不污染浏览器构建。\n- **13 个内置 Preset** — Token Plan ★ · OpenAI · Anthropic · Gemini · DeepSeek · Kimi · 通义 · 豆包 · 智谱 · OpenAI Image · 混元 ×2 · CogView。每个 Preset 都带 `displayName`、`defaultBaseURL`、`builtinModels`（含 `capabilities`）。\n- **跨厂商模型选择器** — `pickModel({ prefer: ['image-gen', 'vision', 'text'] })` 在已启用的 provider 中按能力优先级降级匹配，可指定 `providerId` 作为同级 tiebreaker。\n- **零运行时依赖**。基于平台原生 `fetch` + `ReadableStream` + `AbortSignal` 的纯 ESM 实现。\n- **构造上即浏览器安全**。主入口绝不 import `node:*`，仅 Node 模块挂在 `s-aiproviders-core/image-gen`。\n- **诚实的流式语义**。`chat()` **不抛错** —— 网络/解析失败会以 `{ type: 'error' }` 事件下发。`AbortSignal` 端到端贯穿。\n- **不读全局，不读环境变量**。配置全部由调用方注入。SaaS、多租户 Electron、边缘运行时全部安全可用。\n\n## 安装\n\n```bash\npnpm add s-aiproviders-core\n# 或\nnpm install s-aiproviders-core\n# 或\nyarn add s-aiproviders-core\n```\n\n## 环境要求\n\n- Node.js **≥ 18.17**（依赖原生 `fetch` + `ReadableStream`）\n- 或任意暴露 WHATWG `fetch`、`ReadableStream`、`AbortSignal`、`TextDecoder` 的浏览器/运行时（Cloudflare Workers、Vercel Edge、Deno、Bun…）\n- image-gen 子路径额外需要 Node 兼容的 `node:crypto` 和 `node:fs/promises`\n\n## 流式对话\n\n```ts\nimport { createProvider } from 's-aiproviders-core';\n\nconst provider = createProvider('openai-compatible', {\n  apiKey: process.env.OPENAI_API_KEY!,\n  baseURL: 'https://api.openai.com/v1',\n});\n\nconst ac = new AbortController();\nfor await (const ev of provider.chat(\n  {\n    model: 'gpt-4o-mini',\n    messages: [\n      { role: 'system', content: '请保持简洁。' },\n      { role: 'user',   content: '一句话解释 SSE。' },\n    ],\n    temperature: 0.2,\n  },\n  ac.signal,\n)) {\n  switch (ev.type) {\n    case 'delta': process.stdout.write(ev.text); break;\n    case 'usage': console.error('usage:', ev.usage); break;\n    case 'error': throw new Error(`${ev.code}: ${ev.message}`);\n    case 'done':  break;\n  }\n}\n```\n\n`chat()` 在 Anthropic 和 Gemini 上的形态完全一致，只需切换 `protocol`：\n\n```ts\nconst claude = createProvider('anthropic', {\n  apiKey: process.env.ANTHROPIC_API_KEY!,\n  baseURL: 'https://api.anthropic.com/v1',\n});\n\nconst gemini = createProvider('gemini', {\n  apiKey: process.env.GEMINI_API_KEY!,\n  baseURL: 'https://generativelanguage.googleapis.com/v1beta',\n});\n```\n\n库内部会自动：为 Anthropic 抽出 `system` 消息、把 Gemini 的 `assistant` 映射为 `model`、把 `maxTokens` 翻译成各家正确的字段（`max_tokens` / `max_tokens` / `maxOutputTokens`）。\n\n## 图像生成（仅 Node）\n\n走子路径 —— 主入口刻意没有 re-export 它。\n\n```ts\nimport { generateImage } from 's-aiproviders-core/image-gen';\n\nconst result = await generateImage({\n  // 默认根据 baseURL 自动判定；也可显式指定：\n  // protocol: 'openai-compatible' | 'tencent-cloud',\n  baseURL: 'https://api.openai.com/v1',\n  apiKey:  process.env.OPENAI_API_KEY!,\n  model:   'dall-e-3',\n  prompt:  '极简风格的猫图标，flat，SaaS 风',\n  size:    '1024x1024',\n  outputDir: './generated',\n});\n\nconsole.log(result.filePath, `（${result.latencyMs}ms）`);\n```\n\n接 **腾讯云 TC3**（混元生图 3.0）时，把 baseURL 指向原生端点，apiKey 用 `\"SecretId:SecretKey\"` 形式即可。协议自动识别，TC3-HMAC-SHA256 签名 + 异步任务轮询（默认超时 180s）由库内部完成：\n\n```ts\nconst r = await generateImage({\n  baseURL: 'https://aiart.tencentcloudapi.com',\n  apiKey:  `${process.env.TENCENTCLOUD_SECRET_ID}:${process.env.TENCENTCLOUD_SECRET_KEY}`,\n  model:   'SubmitTextToImageJob',\n  prompt:  '极简风格的猫图标',\n  size:    '1024x1024',\n  outputDir: './generated',\n});\n```\n\n## 跨厂商模型选择器\n\n```ts\nimport { pickModel, type ProviderLike } from 's-aiproviders-core';\n\nconst inventory: ProviderLike[] = [\n  { id: 'openai',    models: [{ id: 'gpt-4o-mini',  label: 'GPT-4o mini', capabilities: ['text', 'vision'] }] },\n  { id: 'tokenplan', models: [{ id: 'tc-code-latest', label: 'Auto',      capabilities: ['text'] }] },\n];\n\nconst picked = pickModel(inventory, { prefer: ['vision', 'text'] });\n// → { providerId: 'openai', modelId: 'gpt-4o-mini', matched: 'vision' }\n```\n\n`pickModel` 按 `prefer` 顺序遍历你已启用的 provider（`enabled === false` 的会被跳过），返回首个匹配的模型。可传 `providerId` 在同等优先级下偏向某个 provider。\n\n## 内置 Preset\n\n```ts\nimport {\n  BUILTIN_PRESETS,    // 13 个全部\n  CHAT_PRESETS,       // 9 个对话\n  IMAGE_PRESETS,      // 4 个生图\n  findPreset,         // 按 id 查\n  TOKENPLAN_PRESET,\n  OPENAI_PRESET,\n  ANTHROPIC_PRESET,\n  GEMINI_PRESET,\n  DEEPSEEK_PRESET,\n  KIMI_PRESET,\n  QWEN_PRESET,\n  DOUBAO_PRESET,\n  ZHIPU_PRESET,\n  OPENAI_IMAGE_PRESET,\n  HUNYUAN_IMAGE_PRESET,\n  HUNYUAN_IMAGE_TC3_PRESET,\n  ZHIPU_IMAGE_PRESET,\n} from 's-aiproviders-core';\n\n// 比如做\"快速添加 provider\"的下拉\nCHAT_PRESETS.forEach((p) => {\n  console.log(`${p.id} — ${p.displayName} (${p.protocol}) → ${p.defaultBaseURL}`);\n});\n```\n\nPreset 结构：\n\n```ts\ninterface ProviderPreset {\n  id: string;\n  displayName: string;\n  protocol: 'openai-compatible' | 'anthropic' | 'gemini';\n  defaultBaseURL: string;\n  builtinModels: ModelInfo[];\n  recommended?: boolean;\n  description?: string;\n  docsUrl?: string;\n  extraFields?: Array<{ name: string; label: string; required: boolean }>;\n  kind?: 'chat' | 'image';\n}\n```\n\n## 公共 API\n\n| 名称 | 来源 | 浏览器安全 |\n|---|---|---|\n| `createProvider`、`OpenAICompatibleProvider`、`AnthropicProvider`、`GeminiProvider` | 主入口 | ✅ |\n| `IProvider`、`ProviderInitConfig`、`ProviderProtocol`、`ChatRequest`、`ChatChunk`、`ChatMessageInput`、`ChatRole`、`ChatUsage` | 主入口 | ✅ |\n| `ModelInfo`、`ModelCapability`、`ProviderKind`、`ProviderPreset` | 主入口 | ✅ |\n| `BUILTIN_PRESETS`、`CHAT_PRESETS`、`IMAGE_PRESETS`、`findPreset`，以及 13 个 `*_PRESET` 常量 | 主入口 | ✅ |\n| `modelHasCapability`、`isMultimodal`、`pickModel`、`ProviderLike`、`PickModelOptions`、`PickedModel` | 主入口 | ✅ |\n| `parseSse`、`SseEvent` | 主入口 | ✅ |\n| `KIT_VERSION` | 主入口 | ✅ |\n| `generateImage`、`generateImageStandalone`、`ImageGenInput`、`ImageGenResult` | `/image-gen` | ❌ 仅 Node |\n\n## 流式语义\n\n`IProvider.chat(req, signal)` 返回 `AsyncIterable<ChatChunk>`：\n\n```ts\ntype ChatChunk =\n  | { type: 'delta'; text: string }\n  | { type: 'usage'; usage: { promptTokens: number; completionTokens: number; totalTokens?: number } }\n  | { type: 'done' }\n  | { type: 'error'; code: string; message: string };\n```\n\n特性：\n\n- 迭代器对协议级失败**不抛错**：网络异常、非 2xx 响应、JSON 解析失败一律以 `{ type: 'error' }` 事件下发并自然结束。`for await` 外面**不需要** `try/catch`。\n- `AbortSignal` 同时作用于 `fetch()` 和 SSE 读取器。Abort 会同时切 socket 和迭代器，干净退出。\n- `usage` 事件做了三方言归一化（OpenAI 的 `usage`、Anthropic 的 `message_delta.usage`、Gemini 的 `usageMetadata`）。\n- 迭代器**总会终止** —— 每个实现都会在退出前 yield `{ type: 'done' }`（或 `error`）。\n\n## 接入未列入的 OpenAI 兼容厂商\n\n只要厂商讲 OpenAI 的 `/chat/completions` 协议 + Bearer 鉴权，**无需改一行代码**：\n\n```ts\nconst provider = createProvider('openai-compatible', {\n  apiKey: 'your-key',\n  baseURL: 'https://your-gateway.example.com/v1',\n});\n```\n\n完全不同的协议，可以自己实现 `IProvider`：\n\n```ts\nimport type { IProvider, ChatChunk, ChatRequest } from 's-aiproviders-core';\n\nclass MyProvider implements IProvider {\n  readonly protocol = 'openai-compatible' as const; // 选最接近的方言挂载即可\n  async *chat(req: ChatRequest, signal: AbortSignal): AsyncIterable<ChatChunk> {\n    // 你的实现；记得 honour signal；不要 throw —— 用 yield {type:'error'}\n  }\n}\n```\n\n## 在 Electron 中使用\n\n直接放进主进程：\n\n```ts\n// main/services/ai.service.ts\nimport { createProvider } from 's-aiproviders-core';\nimport { ipcMain, BrowserWindow } from 'electron';\n\nipcMain.handle('chat:start', async (event, args: { model: string; prompt: string; apiKey: string }) => {\n  const provider = createProvider('openai-compatible', {\n    apiKey: args.apiKey,\n    baseURL: 'https://api.openai.com/v1',\n  });\n  const ac = new AbortController();\n  const win = BrowserWindow.fromWebContents(event.sender);\n  for await (const ev of provider.chat(\n    { model: args.model, messages: [{ role: 'user', content: args.prompt }] },\n    ac.signal,\n  )) {\n    win?.webContents.send('chat:chunk', ev);\n  }\n  return { ok: true };\n});\n```\n\n主进程可以安全地直接 import 这个库；渲染端不要直接 import 核心，**通过 IPC 桥接**以保持 bundle 体积。\n\n## 在边缘运行时使用\n\nCloudflare Workers、Vercel Edge、Deno、Bun —— 对话主面全部支持。Image-gen **不支持**边缘运行时（依赖 `node:crypto` + `node:fs`）。\n\n## 常见问题\n\n**为什么不直接用 OpenAI SDK？** 官方 SDK 自带 HTTP 客户端和重试中间件。三家叠在一起，安装体积翻三倍，错误形状还各不相同。本包用 ~25KB 的代码把三家归一化到一个流式契约。\n\n**支持 tool / function calling 吗？** 暂未支持，路线图上会在 `ChatRequest` 增加 `tools` 字段。如果你急需，欢迎提 Issue。\n\n**支持视觉输入（图片消息）吗？** 当前 transport 接受任意 string content；做视觉时把上游期望的 payload 编进 message content 即可。归一化的\"图片消息\"API 在路线图上。\n\n**API Key 放哪里？** 想放哪都行 —— 库本身**不读环境变量、不读文件**。如果你需要现成的多源加载策略，可以用配套 CLI [`@s-aiproviders/cli`](https://www.npmjs.com/package/@s-aiproviders/cli)，它内置 5 级优先级（CLI flag > 项目 EXTEND.md > 用户 EXTEND.md > 环境变量 > Preset 默认）。\n\n## 配套包\n\n- [`@s-aiproviders/cli`](https://www.npmjs.com/package/@s-aiproviders/cli) — 基于此核心的 Skill / CLI。`npx @s-aiproviders/cli chat ...`。打包了一份 `SKILL.md`，可被 AI agent（Claude Code / Cursor / Codebuddy …）读取自动调用。\n\n## 许可证\n\n[MIT](./LICENSE)\n","readmeFilename":"README.zh.md"}