{"id":13455774,"url":"https://github.com/easychen/api2d-js","last_synced_at":"2025-04-04T23:06:53.921Z","repository":{"id":142910972,"uuid":"614280178","full_name":"easychen/api2d-js","owner":"easychen","description":"OpenAI/Api2d pure js sdk 无需node后端直接在浏览器中运行，支持SSE流式输出","archived":false,"fork":false,"pushed_at":"2025-02-21T07:32:22.000Z","size":338,"stargazers_count":96,"open_issues_count":0,"forks_count":17,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-28T22:14:14.349Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/easychen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-03-15T09:14:26.000Z","updated_at":"2025-02-21T07:32:25.000Z","dependencies_parsed_at":"2024-01-13T17:47:24.189Z","dependency_job_id":"2302d73c-95d0-499f-818e-5bad34778af6","html_url":"https://github.com/easychen/api2d-js","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easychen%2Fapi2d-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easychen%2Fapi2d-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easychen%2Fapi2d-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easychen%2Fapi2d-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/easychen","download_url":"https://codeload.github.com/easychen/api2d-js/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247261600,"owners_count":20910108,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T08:01:10.890Z","updated_at":"2025-04-04T23:06:53.899Z","avatar_url":"https://github.com/easychen.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"中文说明见后边，以下英文由 GPT3.5 友情翻译。感谢 [cdswyda](https://github.com/cdswyda) 的 PR，已经可以在 Node 环境运行。\n\n# A Simple Pure Browser SDK for Api2d and OpenAI\n\nFor some reason, I couldn't find a pure browser OpenAI SDK, they were all implemented in Node. So I wrote one myself, which is compatible with both OpenAI and [API2d](https://api2d.com/) keys.\n\n## Change Log\n\n- 0.1.41 添加 onReasoning 方法，用于输出推理过程中的内容\n- 0.1.39 添加 imageGenerate 方法，用于调用 DALL 生成图片\n\n- 0.1.37：Azure默认模型名称采用去掉小数点的版本\n\n```\n{\n  'gpt-3.5-turbo':'gpt-35-turbo',\n  'gpt-3.5-turbo-0301':'gpt-35-turbo-0301',\n  'gpt-3.5-turbo-0613':'gpt-35-turbo-0613',\n  'gpt-3.5-16k':'gpt-35-16k',\n  'gpt-3.5-16k-0613':'gpt-35-16k-0613',\n  'gpt-4':'gpt-4',\n  'text-embedding-ada-002':'text-embedding-ada-002',\n}\n```\n\n- 0.1.36：修正chunk同时包含content和stop时，无法显示内容的问题，支持event action（清屏）\n- 0.1.33：强制关闭 `@microsoft/fetch-event-source` 默认配置导致的请求重发\n- 0.1.31：从api层删除发送给OpenAI的moderation的header以避免400错误\n\n- 0.1.28：兼容Azure OpenAI 接口\n\n使用方式：\n\n1. apiBaseUrl 填入部署模型的域名部分如 `https://ai2co.openai.azure.com`\n2. 按 deployments 参数中 `模型→部署名` 的对应关系在 Azure 上部署模型。如果你已经部署过模型，也可以修改 deployments 对象的值，并作为参数传递\n\n```\n(key = null, apiBaseUrl = null, timeout = 60000, version = '2023-07-01-preview', deployments = {\n        'gpt-3.5-turbo':'GPT35',\n        'gpt-3.5-turbo-0301':'GPT35',\n        'gpt-3.5-turbo-0613':'GPT35',\n        'gpt-3.5-16k':'GPT35-16K',\n        'gpt-3.5-16k-0613':'GPT35-16K',\n        'gpt-4':'GPT4',\n        'text-embedding-ada-002':'EBD002',\n    }) \n```\n- 0.1.25：添加带重试的请求方法 completionWithRetry，添加 request 方法以支持自定义接口\n\n- 0.1.22：tts支持speed参数\n\n## Usage\n\n```js\nimport Api2d from 'api2d';\n\nconst timeout = 1000 * 60; // 60 seconds timeout\nconst api = new Api2d(key, apiBaseUrl, timeout);\n\n// chat completion\nconst ret = await api.completion({\n  model: 'gpt-3.5-turbo',\n  messages: [\n    {\n      role: 'user',\n      content: 'Hello',\n    },\n  ],\n  stream: true, // supports stream, note that when stream is true, the return value is undefined\n  onMessage: (string) =\u003e {\n    console.log('SSE returns, here is the complete string received', string);\n  },\n  onEnd: (string) =\u003e {\n    console.log('end', string);\n  },\n});\n\n// embeddings\nconst ret = await api.embeddings({\n  input: 'hello world',\n});\nconsole.log(ret);\n\napi.setKey('newkey'); // set key\napi.setApiBaseUrl('https://...your openai proxy address');\napi.setTimeout(1000 * 60 * 5);\napi.abort(); // cancel the request actively\n```\n\n### Example of using in Node environment\n\n```js\nconst api2d = require('api2d-js/cjs/index.js');\nconst forward_key = 'FK...';\nasync function doit() {\n  const api2d_instance = new api2d(forward_key);\n  const response = await api2d_instance.completion({\n    messages: [\n      {\n        role: 'user',\n        content: '来首唐诗',\n      },\n    ],\n    stream: true,\n    onMessage: (message) =\u003e {\n      console.log(message);\n    },\n  });\n  console.log(response);\n}\n\ndoit();\n```\n\n[More examples](https://github.com/easychen/api2d-js/pull/3#issuecomment-1498753640)\n\n# 一个简单的纯浏览器 SDK for Api2d 和 OpenAI\n\n不知道为啥，找了半天没有找到纯 Browser 的 OpenAI SDK，都是 Node 实现的。于是自己写了一个，同时兼容 OpenAI 和 [API2d](https://api2d.com/) 的 key。\n\n## 使用方法\n\n```js\nimport Api2d from 'api2d';\n\nconst timeout = 1000 * 60; // 60秒超时\nconst api = new Api2d(key, apiBaseUrl, timeout);\n\n// chat 补全\nconst ret = await api.completion({\n  model: 'gpt-3.5-turbo',\n  messages: [\n    {\n      role: 'user',\n      content: 'Hello',\n    },\n  ],\n  stream: true, // 支持 stream，注意stream为 true 的时候，返回值为undefined\n  onMessage: (string) =\u003e {\n    console.log('SSE返回，这里返回的是已经接收到的完整字符串', string);\n  },\n  onEnd: (string) =\u003e {\n    console.log('end', string);\n  },\n});\n\n// embeddings\nconst ret = await api.embeddings({\n  input: 'hello world',\n});\nconsole.log(ret);\n\napi.setKey('newkey'); // set key\napi.setApiBaseUrl('https://...your openai proxy address');\napi.setTimeout(1000 * 60 * 5);\napi.abort(); // 主动取消请求\n```\n\n### Node 环境使用示例\n\n```js\nconst api2d = require('api2d-js/cjs/index.js');\nconst forward_key = 'FK...';\nasync function doit() {\n  const api2d_instance = new api2d(forward_key);\n  const response = await api2d_instance.completion({\n    messages: [\n      {\n        role: 'user',\n        content: '来首唐诗',\n      },\n    ],\n    stream: true,\n    onMessage: (message) =\u003e {\n      console.log(message);\n    },\n  });\n  console.log(response);\n}\n\ndoit();\n```\n\n## Azure 语音 \u003c=\u003e 文字\n\nAzure 这两个 API 涉及到文件操作，稍微有点复杂，所以单独拿出来说明。\n\n注意，Azure API 只能使用 API2D 地址。\n\n### 浏览器环境\n\n#### 语音 =\u003e 文字\n\n```js\nimport Api2d from 'api2d';\n\nconst timeout = 1000 * 60; // 60秒超时\nconst api = new Api2d(key, apiBaseUrl, timeout);\n\n// stt\nconst ret = await api.speechToText({\n  file: document.querySelector('input').files[0], // 这里可以使用用户本地选择的文件，也可以通过各种形式构建 File 对象传入\n  language: 'zh-CN', // 文字对应的语言，Azure 支持的语言列表：https://learn.microsoft.com/en-us/azure/cognitive-services/speech-service/language-support?tabs=stt\n  moderation: false, // 如果设置为 true，会使用腾讯云的文本审核\n  moderation_stop: false, // 如果设置为 true，当内容违规会自动清除\n});\nconsole.log(ret); // {text: '这里是转换好的文字内容'}\n\napi.setKey('newkey'); // set key\napi.setApiBaseUrl('https://openai.api2d.net'); // 只能使用 api2d\napi.setTimeout(1000 * 60 * 5);\napi.abort(); // 主动取消请求\n```\n\n注意输入的文件只能是 `.wav` 格式。\n\n#### 文字 =\u003e 语音\n\n首先，文字转语音支持三种返回类型：\n\n- `file`：指定文件名，会直接调用浏览器把生成好的文件下载到本地\n- `blob`：返回文件的 blob，可以做进一步处理\n- `blob-url`：返回一个 blob-url，可以直接调用浏览器的 `Audio` 接口播放声音\n\n下面分别举例。\n\n##### file\n\n```js\nimport Api2d from 'api2d';\n\nconst timeout = 1000 * 60; // 60秒超时\nconst api = new Api2d(key, apiBaseUrl, timeout);\n\n// tts\napi.textToSpeech({\n  text: '你好',\n  voiceName: 'zh-CN-XiaochenNeural', // Azure 支持的声音列表：https://learn.microsoft.com/en-us/azure/cognitive-services/speech-service/language-support?tabs=tts#supported-languages\n  responseType: 'file',\n  speed: 1.5, // 语速，默认为 1，范围是 0.5~2，超出范围会自动改为最近的合法值\n  moderation: false, // 如果设置为 true，会使用腾讯云的文本审核，在【转换音频之前】对文字进行审核\n  moderation_stop: false, // 如果设置为 true，当内容违规会直接返回，不生成音频文件\n});\n\napi.setKey('newkey'); // set key\napi.setApiBaseUrl('https://openai.api2d.net'); // 只能使用 api2d\napi.setTimeout(1000 * 60 * 5);\napi.abort(); // 主动取消请求\n```\n\n这里我们不需要 `await`，因为生成好之后会直接通过浏览器下载，我们不需要什么返回值。当然如果你想要等待这个过程完成，也可以 `await`，只是返回值为空，单纯用来判断是否生成完毕。\n\n##### blob\n\n```js\nimport Api2d from 'api2d';\n\nconst timeout = 1000 * 60; // 60秒超时\nconst api = new Api2d(key, apiBaseUrl, timeout);\n\n// tts\nconst blob = await api.textToSpeech({\n  text: '你好',\n  voiceName: 'zh-CN-XiaochenNeural', // Azure 支持的声音列表：https://learn.microsoft.com/en-us/azure/cognitive-services/speech-service/language-support?tabs=tts#supported-languages\n  responseType: 'blob',\n  speed: 1.5, // 语速，默认为 1，范围是 0.5~2，超出范围会自动改为最近的合法值\n  moderation: false, // 如果设置为 true，会使用腾讯云的文本审核，在【转换音频之前】对文字进行审核\n  moderation_stop: false, // 如果设置为 true，当内容违规会直接返回，不生成音频文件\n});\n\napi.setKey('newkey'); // set key\napi.setApiBaseUrl('https://openai.api2d.net'); // 只能使用 api2d\napi.setTimeout(1000 * 60 * 5);\napi.abort(); // 主动取消请求\n```\n\n拿到 blob 之后可以进行各种处理。如果你只是想播放声音，可以使用 `blob-url`。\n\n##### blob-url\n\n```js\nimport Api2d from 'api2d';\n\nconst timeout = 1000 * 60; // 60秒超时\nconst api = new Api2d(key, apiBaseUrl, timeout);\n\n// tts\nconst blob_url = await api.textToSpeech({\n  text: '你好',\n  voiceName: 'zh-CN-XiaochenNeural', // Azure 支持的声音列表：https://learn.microsoft.com/en-us/azure/cognitive-services/speech-service/language-support?tabs=tts#supported-languages\n  responseType: 'blob-url',\n  speed: 1.5, // 语速，默认为 1，范围是 0.5~2，超出范围会自动改为最近的合法值\n  moderation: false, // 如果设置为 true，会使用腾讯云的文本审核，在【转换音频之前】对文字进行审核\n  moderation_stop: false, // 如果设置为 true，当内容违规会直接返回，不生成音频文件\n});\n\nvar audio0 = new Audio(blob_url);\naudio0.play(); // 这里会直接播放声音\n\napi.setKey('newkey'); // set key\napi.setApiBaseUrl('https://openai.api2d.net'); // 只能使用 api2d\napi.setTimeout(1000 * 60 * 5);\napi.abort(); // 主动取消请求\n```\n\n### NodeJS 环境\n\nNodeJS 环境因为可以操作本地文件，也可以对流做更多处理，所以接口和返回类型稍有不同。\n\n#### 语音 =\u003e 文字\n\n```js\nimport Api2d from 'api2d';\n\nconst timeout = 1000 * 60; // 60秒超时\nconst api = new Api2d(key, apiBaseUrl, timeout);\n\n// stt\nconst ret = await api.speechToText({\n  file: 'demo.wav', // 可以是一个完整路径\n  language: 'zh-CN', // 文字对应的语言，Azure 支持的语言列表：https://learn.microsoft.com/en-us/azure/cognitive-services/speech-service/language-support?tabs=stt\n  moderation: false, // 如果设置为 true，会使用腾讯云的文本审核\n  moderation_stop: false, // 如果设置为 true，当内容违规会自动清除\n});\nconsole.log(ret); // {text: '这里是转换好的文字内容'}\n\napi.setKey('newkey'); // set key\napi.setApiBaseUrl('https://openai.api2d.net'); // 只能使用 api2d\napi.setTimeout(1000 * 60 * 5);\napi.abort(); // 主动取消请求\n```\n\n#### 文字 =\u003e 语音\n\nNodeJS 环境下支持两种返回值：\n\n- file\n- stream\n\n##### file\n\n```js\nimport Api2d from 'api2d';\n\nconst timeout = 1000 * 60; // 60秒超时\nconst api = new Api2d(key, apiBaseUrl, timeout);\n\n// tts\nawait api.textToSpeech({\n  text: '你好',\n  voiceName: 'zh-CN-XiaochenNeural', // Azure 支持的声音列表：https://learn.microsoft.com/en-us/azure/cognitive-services/speech-service/language-support?tabs=tts#supported-languages\n  responseType: 'file',\n  speed: 1.5, // 语速，默认为 1，范围是 0.5~2，超出范围会自动改为最近的合法值\n  output: 'output.mp3', // 可以是一个完整路径\n  moderation: false, // 如果设置为 true，会使用腾讯云的文本审核，在【转换音频之前】对文字进行审核\n  moderation_stop: false, // 如果设置为 true，当内容违规会直接返回，不生成音频文件\n});\n\napi.setKey('newkey'); // set key\napi.setApiBaseUrl('https://openai.api2d.net'); // 只能使用 api2d\napi.setTimeout(1000 * 60 * 5);\napi.abort(); // 主动取消请求\n```\n\n执行完毕后会直接把音频存入本地文件中。\n\n##### stream\n\n```js\nimport Api2d from 'api2d';\n\nconst timeout = 1000 * 60; // 60秒超时\nconst api = new Api2d(key, apiBaseUrl, timeout);\n\n// tts\nawait api.textToSpeech({\n  text: '你好',\n  voiceName: 'zh-CN-XiaochenNeural', // Azure 支持的声音列表：https://learn.microsoft.com/en-us/azure/cognitive-services/speech-service/language-support?tabs=tts#supported-languages\n  responseType: 'stream',\n  speed: 1.5, // 语速，默认为 1，范围是 0.5~2，超出范围会自动改为最近的合法值\n  output: fs.createWriteStream('outputStream.mp3'),\n  moderation: false, // 如果设置为 true，会使用腾讯云的文本审核，在【转换音频之前】对文字进行审核\n  moderation_stop: false, // 如果设置为 true，当内容违规会直接返回，不生成音频文件\n});\n\napi.setKey('newkey'); // set key\napi.setApiBaseUrl('https://openai.api2d.net'); // 只能使用 api2d\napi.setTimeout(1000 * 60 * 5);\napi.abort(); // 主动取消请求\n```\n\n输出是一个 stream，这里我们只是把它写入本地文件，你也可以自行处理实现更多功能，比如一边生成一边播放。\n\n[更多例子](https://github.com/easychen/api2d-js/pull/3#issuecomment-1498753640)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feasychen%2Fapi2d-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feasychen%2Fapi2d-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feasychen%2Fapi2d-js/lists"}