{"_id":"@autolabz/llmapi-sdk","_rev":"9-f25fadf6791cf53301481b86a767e36f","name":"@autolabz/llmapi-sdk","dist-tags":{"latest":"0.1.9"},"versions":{"0.1.1":{"name":"@autolabz/llmapi-sdk","version":"0.1.1","_id":"@autolabz/llmapi-sdk@0.1.1","maintainers":[{"name":"autolabz","email":"mzhh@mzhh.xyz"}],"dist":{"shasum":"71b8128d497f880794e2566b24fe53218057505c","tarball":"https://registry.npmjs.org/@autolabz/llmapi-sdk/-/llmapi-sdk-0.1.1.tgz","fileCount":11,"integrity":"sha512-zE/AHTpkka/E2AhVAzwfHZAKhVJwgnQGg0VuTHn7JQ4TvOwod/cxnmrihiX1iD/tZIlQq0CPG46vL7l6s1Algg==","signatures":[{"sig":"MEUCIQCFHPnFxFK65mgkrRj/JVWIZN+f4BBNtFLE0CTx2U0QRAIgfpIT2iaEmuwSiOnGON5atSaJq4Hy6TmvozHrsAHJK2s=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":14432},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"}},"gitHead":"5bce87ba3e45534289b0bdf8c2165f9c84f58b25","private":false,"scripts":{"build":"tsc -p tsconfig.json","prepare":"npm run build"},"_npmUser":{"name":"autolabz","email":"mzhh@mzhh.xyz"},"_npmVersion":"10.8.2","description":"AutoLab LLM API SDK - typed client for llmapi-service","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","dependencies":{"axios":"^1.7.7"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.3"},"_npmOperationalInternal":{"tmp":"tmp/llmapi-sdk_0.1.1_1760883640407_0.5153129921999284","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@autolabz/llmapi-sdk","version":"0.1.2","_id":"@autolabz/llmapi-sdk@0.1.2","maintainers":[{"name":"autolabz","email":"mzhh@mzhh.xyz"}],"dist":{"shasum":"b83c667460125c98cc01ecfcdadae7636e99e62c","tarball":"https://registry.npmjs.org/@autolabz/llmapi-sdk/-/llmapi-sdk-0.1.2.tgz","fileCount":11,"integrity":"sha512-p5IJxm3N+KQqwzUZm3wnt4+IrHtdaF06U9iHhCAlad8vcwRLDUowCZzH9fRcOC4X+hznNj+nyVwQV/Lpn+yH0A==","signatures":[{"sig":"MEQCIDv/Vcrr+6blYXXwqUAMNarWnYFApazUtTq3lVVzXJNdAiBL4W1o0CNMsLtALGM0VKxzkri+nSzd7v6s/Sv9tlkbbg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":14432},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"}},"gitHead":"5bce87ba3e45534289b0bdf8c2165f9c84f58b25","private":false,"scripts":{"build":"tsc -p tsconfig.json","prepare":"npm run build"},"_npmUser":{"name":"autolabz","email":"mzhh@mzhh.xyz"},"_npmVersion":"10.8.2","description":"AutoLab LLM API SDK - typed client for llmapi-service","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","dependencies":{"axios":"^1.7.7"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.3"},"_npmOperationalInternal":{"tmp":"tmp/llmapi-sdk_0.1.2_1761188453203_0.44055616319157864","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@autolabz/llmapi-sdk","version":"0.1.3","_id":"@autolabz/llmapi-sdk@0.1.3","maintainers":[{"name":"autolabz","email":"mzhh@mzhh.xyz"}],"dist":{"shasum":"a5ceee10beb3ef885f245c85dc775a9c7fb71447","tarball":"https://registry.npmjs.org/@autolabz/llmapi-sdk/-/llmapi-sdk-0.1.3.tgz","fileCount":11,"integrity":"sha512-hVji7RiqN2CAZ4ig9ljWKTih5Y74+mAs6h35cyZThFFNGW5tqEaN9Cq9ra/KXFsLEzSEk0a+PyzUlYTNpwpqmg==","signatures":[{"sig":"MEUCIQCypI2/uzOlT9kbSpPGwXHBltAz3dMXxty4A2bZVjC6NAIgdCM5zpDwQ+gsdT7BhKZi1ep94EnJfeGFalL4TXBOIyg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":14432},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"}},"gitHead":"93935a6d544bf8cc249d07c95a7f15c6c9c8ed88","private":false,"scripts":{"build":"tsc -p tsconfig.json","prepare":"npm run build"},"_npmUser":{"name":"autolabz","email":"mzhh@mzhh.xyz"},"_npmVersion":"10.8.2","description":"AutoLab LLM API SDK - typed client for llmapi-service","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","dependencies":{"axios":"^1.7.7"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.3"},"_npmOperationalInternal":{"tmp":"tmp/llmapi-sdk_0.1.3_1761300019546_0.15122818206289979","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@autolabz/llmapi-sdk","version":"0.1.4","_id":"@autolabz/llmapi-sdk@0.1.4","maintainers":[{"name":"autolabz","email":"mzhh@mzhh.xyz"}],"dist":{"shasum":"2e76a04ba9ec60d6d98e28bd538b9eae85bd1a3f","tarball":"https://registry.npmjs.org/@autolabz/llmapi-sdk/-/llmapi-sdk-0.1.4.tgz","fileCount":12,"integrity":"sha512-t621u+m9GMmC4L50ISi97MrdakCSEyYhZ/Qx7uMMtqXCblAt5UDL+QeCsuuLZn1LFSLmaSfjJCP4urWQjkG+8A==","signatures":[{"sig":"MEUCIQDYljJ1mrHkPGPJEP6GqKLT6D5JcYq+m1e5kjbZzE5zngIgIzTmFMO5m/TN8I4TZ+qaJv60HoR7NNEuuwQUZc0fw9Q=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":27964},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"}},"gitHead":"d66ca4e4f5ed9c7cc6fa54b9e5269a83f1da733b","private":false,"scripts":{"build":"tsc -p tsconfig.json","prepare":"npm run build"},"_npmUser":{"name":"autolabz","email":"mzhh@mzhh.xyz"},"_npmVersion":"10.8.2","description":"AutoLab LLM API SDK - typed client for llmapi-service","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","dependencies":{"axios":"^1.7.7"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.3"},"_npmOperationalInternal":{"tmp":"tmp/llmapi-sdk_0.1.4_1761965356647_0.684543805907758","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"@autolabz/llmapi-sdk","version":"0.1.5","_id":"@autolabz/llmapi-sdk@0.1.5","maintainers":[{"name":"autolabz","email":"mzhh@mzhh.xyz"}],"dist":{"shasum":"79d1e940f0d5bb5b93dfc4b707661138ba62178a","tarball":"https://registry.npmjs.org/@autolabz/llmapi-sdk/-/llmapi-sdk-0.1.5.tgz","fileCount":12,"integrity":"sha512-ECZcR+efrRVgPJqNadYxesTT+sv5ZWoB9c0fKQsC6O6iGPhQweU30DurfqzFwilbRuSstiE4H7LeTQbCpBogew==","signatures":[{"sig":"MEUCIQD/7y+jIyAk1o1qTlm0iVjiZROoeK4DMnTUbbE6TiX02QIgd/ZZnTsDTswFsNSpd+Kan5pbhzyky06D4s56gxlM3gQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":27991},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"}},"gitHead":"d66ca4e4f5ed9c7cc6fa54b9e5269a83f1da733b","private":false,"scripts":{"build":"tsc -p tsconfig.json","prepare":"npm run build"},"_npmUser":{"name":"autolabz","email":"mzhh@mzhh.xyz"},"_npmVersion":"10.8.2","description":"AutoLab LLM API SDK - typed client for llmapi-service","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","dependencies":{"axios":"^1.7.7"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.3"},"_npmOperationalInternal":{"tmp":"tmp/llmapi-sdk_0.1.5_1761968400647_0.9987077347005053","host":"s3://npm-registry-packages-npm-production"}},"0.1.6":{"name":"@autolabz/llmapi-sdk","version":"0.1.6","_id":"@autolabz/llmapi-sdk@0.1.6","maintainers":[{"name":"autolabz","email":"mzhh@mzhh.xyz"}],"dist":{"shasum":"dcb156fc292c36e2aec2f93f7f381edb6c923e40","tarball":"https://registry.npmjs.org/@autolabz/llmapi-sdk/-/llmapi-sdk-0.1.6.tgz","fileCount":12,"integrity":"sha512-sqT1rQNJT35Uo/p/ouFg7OY2qYbgxYUDVXp3puNsGljHxv98cbjm6ZbiMFlvkCjPxRQ1JSrltfyNXiOW7XPDfw==","signatures":[{"sig":"MEUCIQD2PpXBSKkl1qgbex/UjdexxlcxNg98mzpQpzpK4msJZgIgGeJVIzBTcbsYKOQ93xQHOX0OlaBqqpxfu01IykHSKH8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":29503},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"}},"gitHead":"77eba31449e2d94064dd6c9c6d84e79864a3a8c1","private":false,"scripts":{"build":"tsc -p tsconfig.json","prepare":"npm run build"},"_npmUser":{"name":"autolabz","email":"mzhh@mzhh.xyz"},"_npmVersion":"10.8.2","description":"AutoLab LLM API SDK - typed client for llmapi-service","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","dependencies":{"axios":"^1.7.7"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.3"},"_npmOperationalInternal":{"tmp":"tmp/llmapi-sdk_0.1.6_1762678264039_0.673634150318565","host":"s3://npm-registry-packages-npm-production"}},"0.1.7":{"name":"@autolabz/llmapi-sdk","version":"0.1.7","_id":"@autolabz/llmapi-sdk@0.1.7","maintainers":[{"name":"autolabz","email":"mzhh@mzhh.xyz"}],"dist":{"shasum":"0081d83c50789545c07e5d07ed95a7cfa55f5f2e","tarball":"https://registry.npmjs.org/@autolabz/llmapi-sdk/-/llmapi-sdk-0.1.7.tgz","fileCount":12,"integrity":"sha512-veJigTGOjqF3xu8Bx4NIEuEm+pNkmE7XER6ozBwGV6r4CaVfwoL1BflQbsaCO4GekyBPZUS9xFuloan5adj5hQ==","signatures":[{"sig":"MEUCIQC5x0FNvqmjqa1XJNznYRpu0FIUPQVAc8kb7VAZ4SR0DgIgV427V5OfNuVWj8lo2b46Sd7K0hbgEtgTwL16jn/UGRA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":29503},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"}},"gitHead":"77eba31449e2d94064dd6c9c6d84e79864a3a8c1","private":false,"scripts":{"build":"tsc -p tsconfig.json","prepare":"npm run build"},"_npmUser":{"name":"autolabz","email":"mzhh@mzhh.xyz"},"_npmVersion":"10.8.2","description":"AutoLab LLM API SDK - typed client for llmapi-service","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","dependencies":{"axios":"^1.7.7"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.3"},"_npmOperationalInternal":{"tmp":"tmp/llmapi-sdk_0.1.7_1762678311270_0.32997783104579437","host":"s3://npm-registry-packages-npm-production"}},"0.1.8":{"name":"@autolabz/llmapi-sdk","version":"0.1.8","_id":"@autolabz/llmapi-sdk@0.1.8","maintainers":[{"name":"autolabz","email":"mzhh@mzhh.xyz"}],"dist":{"shasum":"e8c8604825117f8168bff82290c6a02603661444","tarball":"https://registry.npmjs.org/@autolabz/llmapi-sdk/-/llmapi-sdk-0.1.8.tgz","fileCount":12,"integrity":"sha512-eTyVTJm1PkFInGEQ2N0jEgB7f8claToZ/ueXgfr2tdTWwJofUj5/ohLFfMPrPPhze1CoUGJyLr7zwpvtxLbASA==","signatures":[{"sig":"MEYCIQDHAp/vWhqFlyyMwT7QioKD18AdRFK/giZ8oEYAieAIyQIhAPS42Q4HOzHjlKGihcm+hdAeaM7XVsksAN4fhAsAZZMz","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":29636},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.js"}},"gitHead":"7b1ade33c4a017d49213b47af937459f8f8ce935","private":false,"scripts":{"build":"tsc -p tsconfig.json","prepare":"npm run build"},"_npmUser":{"name":"autolabz","email":"mzhh@mzhh.xyz"},"_npmVersion":"10.8.2","description":"AutoLab LLM API SDK - typed client for llmapi-service","directories":{},"sideEffects":false,"_nodeVersion":"20.19.5","dependencies":{"axios":"^1.7.7"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.3"},"_npmOperationalInternal":{"tmp":"tmp/llmapi-sdk_0.1.8_1765270350128_0.9568355349654478","host":"s3://npm-registry-packages-npm-production"}},"0.1.9":{"name":"@autolabz/llmapi-sdk","version":"0.1.9","private":false,"description":"AutoLab LLM API SDK - typed client for llmapi-service","type":"module","main":"dist/index.js","module":"dist/index.js","types":"dist/index.d.ts","publishConfig":{"access":"public"},"sideEffects":false,"exports":{".":{"import":"./dist/index.js","require":"./dist/index.js","types":"./dist/index.d.ts"}},"scripts":{"build":"tsc -p tsconfig.json","prepare":"npm run build"},"dependencies":{"axios":"^1.7.7"},"devDependencies":{"typescript":"^5.6.3"},"_id":"@autolabz/llmapi-sdk@0.1.9","gitHead":"7b1ade33c4a017d49213b47af937459f8f8ce935","_nodeVersion":"20.19.5","_npmVersion":"10.8.2","dist":{"integrity":"sha512-27Wc0ipSrLrCF0SmhNVUrAV7gPx9RYD4ZoJ/qRwgH/gNSZin+zgPLCre9P8qMsCTyvxQlxu290hzOaxiyCYkRA==","shasum":"78d48a63fdd6c6e22e517ea93c4ac64c3ae9626c","tarball":"https://registry.npmjs.org/@autolabz/llmapi-sdk/-/llmapi-sdk-0.1.9.tgz","fileCount":12,"unpackedSize":29772,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIEchzXUeyzCcHOWuiU0PHo38jkxQ9hSzE5te1RJx5t8QAiBwzqGQqzap1AxOJ9vkEw2kyzdSOU18g3OyKrNZOOGXKA=="}]},"_npmUser":{"name":"autolabz","email":"mzhh@mzhh.xyz"},"directories":{},"maintainers":[{"name":"autolabz","email":"mzhh@mzhh.xyz"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/llmapi-sdk_0.1.9_1765271127349_0.17381513737382637"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-19T14:20:40.257Z","modified":"2025-12-09T09:05:27.694Z","0.1.1":"2025-10-19T14:20:40.600Z","0.1.2":"2025-10-23T03:00:53.387Z","0.1.3":"2025-10-24T10:00:19.751Z","0.1.4":"2025-11-01T02:49:16.837Z","0.1.5":"2025-11-01T03:40:00.852Z","0.1.6":"2025-11-09T08:51:04.234Z","0.1.7":"2025-11-09T08:51:51.466Z","0.1.8":"2025-12-09T08:52:30.262Z","0.1.9":"2025-12-09T09:05:27.512Z"},"description":"AutoLab LLM API SDK - typed client for llmapi-service","maintainers":[{"name":"autolabz","email":"mzhh@mzhh.xyz"}],"readme":"# @autolabz/llmapi-sdk\n\nAutoLab LLM API SDK - 用于 llmapi-service 的类型化客户端\n\n## 安装\n\n```bash\nnpm install @autolabz/llmapi-sdk\n```\n\n## 兼容性\n\n✅ **完全支持 Node.js ESM 模式**\n\n本包已针对 Node.js ESM 规范进行优化，可以在 `\"type\": \"module\"` 的项目中无缝使用，无需任何额外配置或运行时工具（如 tsx）。\n\n```json\n// package.json\n{\n  \"type\": \"module\"\n}\n```\n\n```javascript\n// 可以直接使用 ESM 导入\nimport { createLLMClient } from '@autolabz/llmapi-sdk';\n```\n\n## 快速开始\n\n```typescript\nimport { createLLMClient } from '@autolabz/llmapi-sdk';\n\nconst client = createLLMClient({\n  baseURL: 'https://api.autolab.example.com/llmapi',\n  auth: {\n    getAccessToken: () => localStorage.getItem('access_token'),\n    getClientId: () => 'your-client-id',\n    refreshAccessToken: async () => {\n      // 实现 token 刷新逻辑\n      return newToken;\n    },\n    onUnauthorized: () => {\n      // 处理未授权情况\n    }\n  }\n});\n\n// 非流式调用 - 获取完整响应对象\nconst response = await client.chat({\n  model: 'gpt-4o-mini-2024-07-18',\n  messages: [{ role: 'user', content: 'Hello!' }]\n});\n\n// 非流式调用 - 直接获取内容字符串\nconst content = await client.getChatContent({\n  model: 'gpt-4o-mini-2024-07-18',\n  messages: [{ role: 'user', content: 'Hello!' }]\n});\nconsole.log(content); // \"Hello from AutoLab! How can I assist you today?\"\n\n// 流式调用\nawait client.chatStream(\n  {\n    model: 'gpt-4o-mini-2024-07-18',\n    messages: [{ role: 'user', content: 'Hello!' }],\n    stream: true\n  },\n  {\n    onMessage: (data) => console.log(data),\n    onDone: () => console.log('Done'),\n    onError: (err) => console.error(err)\n  }\n);\n```\n\n## API 方法\n\n### `client.health()`\n\n健康检查接口。\n\n**返回值：**\n```typescript\n{\n  status: 'ok' | 'degraded' | 'down';\n  version?: string;\n  time?: string;\n  db?: 'ok' | 'error';\n  latencyMs?: number;\n}\n```\n\n### `client.chat(request)`\n\n非流式聊天接口。\n\n**请求参数：**\n```typescript\n{\n  model: string;\n  messages: Array<{ role: string; content: any }>;\n  temperature?: number;\n  max_tokens?: number;\n}\n```\n\n**返回形式：**\n\n返回一个 Promise，resolve 为完整的聊天响应对象：\n\n```json\n{\n  \"id\": \"chatcmpl-CWlq5L6lqXNG3OFmDOcY0pNg4PfjV\",\n  \"object\": \"chat.completion\",\n  \"created\": 1761926425,\n  \"model\": \"gpt-4o-mini-2024-07-18\",\n  \"choices\": [\n    {\n      \"index\": 0,\n      \"message\": {\n        \"role\": \"assistant\",\n        \"content\": \"Hello from AutoLab! How can I assist you today?\",\n        \"refusal\": null,\n        \"annotations\": []\n      },\n      \"logprobs\": null,\n      \"finish_reason\": \"stop\"\n    }\n  ],\n  \"usage\": {\n    \"prompt_tokens\": 13,\n    \"completion_tokens\": 13,\n    \"total_tokens\": 26,\n    \"prompt_tokens_details\": {\n      \"cached_tokens\": 0,\n      \"audio_tokens\": 0\n    },\n    \"completion_tokens_details\": {\n      \"reasoning_tokens\": 0,\n      \"audio_tokens\": 0,\n      \"accepted_prediction_tokens\": 0,\n      \"rejected_prediction_tokens\": 0\n    }\n  },\n  \"system_fingerprint\": \"fp_efad92c60b\"\n}\n```\n\n**响应字段说明：**\n\n- `id`: 聊天完成的唯一标识符\n- `object`: 对象类型，固定为 `\"chat.completion\"`\n- `created`: Unix 时间戳，表示创建时间\n- `model`: 使用的模型名称\n- `choices`: 生成的回复列表\n  - `index`: 回复的索引\n  - `message`: 消息对象\n    - `role`: 角色，通常为 `\"assistant\"`\n    - `content`: 生成的内容\n    - `refusal`: 拒绝信息（如果有）\n    - `annotations`: 注释列表\n  - `logprobs`: 对数概率信息\n  - `finish_reason`: 完成原因（`\"stop\"` 表示正常结束）\n- `usage`: Token 使用统计\n  - `prompt_tokens`: 提示词使用的 token 数\n  - `completion_tokens`: 生成内容使用的 token 数\n  - `total_tokens`: 总 token 数\n  - `prompt_tokens_details`: 提示词 token 详情\n  - `completion_tokens_details`: 生成 token 详情\n- `system_fingerprint`: 系统指纹\n\n### `client.getChatContent(request)`\n\n便捷方法：直接获取聊天内容字符串，而不是完整的响应对象。\n\n**请求参数：**\n```typescript\n{\n  model: string;\n  messages: Array<{ role: string; content: any }>;\n  temperature?: number;\n  max_tokens?: number;\n}\n```\n\n**返回形式：**\n\n返回一个 Promise，resolve 为聊天内容字符串：\n\n```typescript\nconst content = await client.getChatContent({\n  model: 'gpt-4o-mini-2024-07-18',\n  messages: [{ role: 'user', content: 'Hello!' }]\n});\n// content = \"Hello from AutoLab! How can I assist you today?\"\n```\n\n**说明：**\n\n- 这是对 `client.chat()` 的封装，内部调用 `chat()` 方法\n- 自动提取 `response.choices[0].message.content` 字段\n- 如果内容不存在，返回空字符串 `\"\"`\n- 适用于只需要内容字符串而不关心其他元数据的场景\n\n### `client.chatStream(request, handlers)`\n\n流式聊天接口。\n\n**请求参数：**\n```typescript\n{\n  model: string;\n  messages: Array<{ role: string; content: any }>;\n  stream: true;  // 必须为 true\n  temperature?: number;\n  max_tokens?: number;\n}\n```\n\n**处理器参数：**\n```typescript\n{\n  onEvent?: (line: string) => void;    // 原始 SSE 事件行\n  onMessage?: (data: any) => void;      // 解析后的 JSON 数据\n  onDone?: () => void;                  // 流结束时调用\n  onError?: (err: Error) => void;       // 错误处理\n}\n```\n\n**返回形式：**\n\n流式返回通过 Server-Sent Events (SSE) 格式推送，每条消息以 `data:` 开头，后跟 JSON 数据。通过 `onMessage` 回调接收解析后的数据。\n\n**数据流示例：**\n\n```\ndata: {\"id\":\"\",\"object\":\"\",\"created\":0,\"model\":\"gpt-4o-mini-2024-07-18\",\"choices\":[]}\n\ndata: {\"id\":\"chatcmpl-CWvlnHBwh3VlWjxyX2QHVu9N1JvIO\",\"object\":\"chat.completion.chunk\",\"created\":1761964599,\"model\":\"gpt-4o-mini-2024-07-18\",\"system_fingerprint\":\"fp_efad92c60b\",\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\",\"refusal\":null},\"logprobs\":null,\"finish_reason\":null}],\"usage\":{},\"obfuscation\":\"lL\"}\n\ndata: {\"id\":\"chatcmpl-CWvlnHBwh3VlWjxyX2QHVu9N1JvIO\",\"object\":\"chat.completion.chunk\",\"created\":1761964599,\"model\":\"gpt-4o-mini-2024-07-18\",\"system_fingerprint\":\"fp_efad92c60b\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Hello\"},\"logprobs\":null,\"finish_reason\":null}],\"usage\":{},\"obfuscation\":\"sCV1ilTpoj6SqxS\"}\n\ndata: {\"id\":\"chatcmpl-CWvlnHBwh3VlWjxyX2QHVu9N1JvIO\",\"object\":\"chat.completion.chunk\",\"created\":1761964599,\"model\":\"gpt-4o-mini-2024-07-18\",\"system_fingerprint\":\"fp_efad92c60b\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" from\"},\"logprobs\":null,\"finish_reason\":null}],\"usage\":{},\"obfuscation\":\"EJAbKIM9yxRvoaX\"}\n\ndata: {\"id\":\"chatcmpl-CWvlnHBwh3VlWjxyX2QHVu9N1JvIO\",\"object\":\"chat.completion.chunk\",\"created\":1761964599,\"model\":\"gpt-4o-mini-2024-07-18\",\"system_fingerprint\":\"fp_efad92c60b\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" Auto\"},\"logprobs\":null,\"finish_reason\":null}],\"usage\":{},\"obfuscation\":\"CtikDiQd1fp4ub7\"}\n\ndata: {\"id\":\"chatcmpl-CWvlnHBwh3VlWjxyX2QHVu9N1JvIO\",\"object\":\"chat.completion.chunk\",\"created\":1761964599,\"model\":\"gpt-4o-mini-2024-07-18\",\"system_fingerprint\":\"fp_efad92c60b\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"Lab\"},\"logprobs\":null,\"finish_reason\":null}],\"usage\":{},\"obfuscation\":\"L\"}\n\ndata: {\"id\":\"chatcmpl-CWvlnHBwh3VlWjxyX2QHVu9N1JvIO\",\"object\":\"chat.completion.chunk\",\"created\":1761964599,\"model\":\"gpt-4o-mini-2024-07-18\",\"system_fingerprint\":\"fp_efad92c60b\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"!\"},\"logprobs\":null,\"finish_reason\":null}],\"usage\":{},\"obfuscation\":\"35c\"}\n\ndata: {\"id\":\"chatcmpl-CWvlnHBwh3VlWjxyX2QHVu9N1JvIO\",\"object\":\"chat.completion.chunk\",\"created\":1761964599,\"model\":\"gpt-4o-mini-2024-07-18\",\"system_fingerprint\":\"fp_efad92c60b\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" How\"},\"logprobs\":null,\"finish_reason\":null}],\"usage\":{},\"obfuscation\":\"\"}\n\ndata: {\"id\":\"chatcmpl-CWvlnHBwh3VlWjxyX2QHVu9N1JvIO\",\"object\":\"chat.completion.chunk\",\"created\":1761964599,\"model\":\"gpt-4o-mini-2024-07-18\",\"system_fingerprint\":\"fp_efad92c60b\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" can\"},\"logprobs\":null,\"finish_reason\":null}],\"usage\":{},\"obfuscation\":\"\"}\n\ndata: {\"id\":\"chatcmpl-CWvlnHBwh3VlWjxyX2QHVu9N1JvIO\",\"object\":\"chat.completion.chunk\",\"created\":1761964599,\"model\":\"gpt-4o-mini-2024-07-18\",\"system_fingerprint\":\"fp_efad92c60b\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" I\"},\"logprobs\":null,\"finish_reason\":null}],\"usage\":{},\"obfuscation\":\"Om\"}\n\ndata: {\"id\":\"chatcmpl-CWvlnHBwh3VlWjxyX2QHVu9N1JvIO\",\"object\":\"chat.completion.chunk\",\"created\":1761964599,\"model\":\"gpt-4o-mini-2024-07-18\",\"system_fingerprint\":\"fp_efad92c60b\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" assist\"},\"logprobs\":null,\"finish_reason\":null}],\"usage\":{},\"obfuscation\":\"0dugxG8TLaxA7\"}\n\ndata: {\"id\":\"chatcmpl-CWvlnHBwh3VlWjxyX2QHVu9N1JvIO\",\"object\":\"chat.completion.chunk\",\"created\":1761964599,\"model\":\"gpt-4o-mini-2024-07-18\",\"system_fingerprint\":\"fp_efad92c60b\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" you\"},\"logprobs\":null,\"finish_reason\":null}],\"usage\":{},\"obfuscation\":\"\"}\n\ndata: {\"id\":\"chatcmpl-CWvlnHBwh3VlWjxyX2QHVu9N1JvIO\",\"object\":\"chat.completion.chunk\",\"created\":1761964599,\"model\":\"gpt-4o-mini-2024-07-18\",\"system_fingerprint\":\"fp_efad92c60b\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" today\"},\"logprobs\":null,\"finish_reason\":null}],\"usage\":{},\"obfuscation\":\"dCoTwLg7cyoFUI\"}\n\ndata: {\"id\":\"chatcmpl-CWvlnHBwh3VlWjxyX2QHVu9N1JvIO\",\"object\":\"chat.completion.chunk\",\"created\":1761964599,\"model\":\"gpt-4o-mini-2024-07-18\",\"system_fingerprint\":\"fp_efad92c60b\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"?\"},\"logprobs\":null,\"finish_reason\":null}],\"usage\":{},\"obfuscation\":\"vxb\"}\n\ndata: {\"id\":\"chatcmpl-CWvlnHBwh3VlWjxyX2QHVu9N1JvIO\",\"object\":\"chat.completion.chunk\",\"created\":1761964599,\"model\":\"gpt-4o-mini-2024-07-18\",\"system_fingerprint\":\"fp_efad92c60b\",\"choices\":[{\"index\":0,\"delta\":{},\"logprobs\":null,\"finish_reason\":\"stop\"}],\"usage\":{},\"obfuscation\":\"R4p7CUTPYt7cDZ\"}\n\ndata: {\"id\":\"chatcmpl-CWvlnHBwh3VlWjxyX2QHVu9N1JvIO\",\"object\":\"chat.completion.chunk\",\"created\":1761964599,\"model\":\"gpt-4o-mini-2024-07-18\",\"system_fingerprint\":\"fp_efad92c60b\",\"choices\":[],\"usage\":{\"prompt_tokens\":13,\"completion_tokens\":13,\"total_tokens\":26,\"prompt_tokens_details\":{\"cached_tokens\":0,\"audio_tokens\":0},\"completion_tokens_details\":{\"reasoning_tokens\":0,\"audio_tokens\":0,\"accepted_prediction_tokens\":0,\"rejected_prediction_tokens\":0}},\"obfuscation\":\"OKV\"}\n\ndata: [DONE]\n```\n\n**流式响应字段说明：**\n\n每个流式数据块（chunk）包含：\n\n- `id`: 聊天完成的唯一标识符\n- `object`: 对象类型，固定为 `\"chat.completion.chunk\"`\n- `created`: Unix 时间戳\n- `model`: 使用的模型名称\n- `system_fingerprint`: 系统指纹\n- `choices`: 生成的回复列表\n  - `index`: 回复的索引\n  - `delta`: 增量内容对象\n    - `role`: 角色（仅在第一个 chunk 中）\n    - `content`: 当前 chunk 的内容片段\n  - `logprobs`: 对数概率信息\n  - `finish_reason`: 完成原因（最后一个 chunk 中为 `\"stop\"`）\n- `usage`: Token 使用统计（仅在最后一个数据块中）\n- `obfuscation`: 混淆字段（可忽略）\n\n**流式数据特点：**\n\n1. **第一个数据块**：通常为空或包含初始化信息\n2. **中间数据块**：每个块的 `delta.content` 包含一个文本片段\n3. **倒数第二个数据块**：包含 `finish_reason: \"stop\"` 表示生成结束\n4. **倒数第一个数据块**：包含 `usage` 字段，提供完整的 token 使用统计\n5. **最后一行**：`data: [DONE]` 标记流结束\n\n**使用示例：**\n\n```typescript\nlet fullContent = '';\n\nawait client.chatStream(\n  {\n    model: 'gpt-4o-mini-2024-07-18',\n    messages: [{ role: 'user', content: 'Hello!' }],\n    stream: true\n  },\n  {\n    onMessage: (data) => {\n      // 提取并累积内容\n      if (data.choices?.[0]?.delta?.content) {\n        fullContent += data.choices[0].delta.content;\n        console.log('收到内容:', data.choices[0].delta.content);\n      }\n      \n      // 检查是否完成\n      if (data.choices?.[0]?.finish_reason === 'stop') {\n        console.log('生成完成');\n      }\n      \n      // 获取使用统计\n      if (data.usage) {\n        console.log('Token 使用:', data.usage);\n      }\n    },\n    onDone: () => {\n      console.log('完整内容:', fullContent);\n    },\n    onError: (err) => {\n      console.error('错误:', err);\n    }\n  }\n);\n```\n\n## 配置选项\n\n### `LLMClientConfig`\n\n```typescript\n{\n  baseURL: string;              // API 基础 URL\n  auth: AuthBridge;             // 认证桥接器\n  retry?: RetryPolicy;          // 重试策略\n  defaultHeaders?: Record<string, string>;  // 默认请求头\n}\n```\n\n### `AuthBridge`\n\n```typescript\n{\n  getAccessToken(): string | null | Promise<string | null>;\n  getClientId(): string | null | Promise<string | null>;\n  refreshAccessToken(): Promise<string>;\n  onUnauthorized?: () => void | Promise<void>;\n}\n```\n\n### `RetryPolicy`\n\n```typescript\n{\n  maxAttempts?: number;    // 最大重试次数，默认 3\n  baseDelayMs?: number;    // 基础延迟毫秒数，默认 250\n}\n```\n\n## 错误处理\n\nSDK 会自动处理以下情况：\n\n1. **401 未授权**：自动调用 `refreshAccessToken()` 刷新 token 并重试\n2. **网络错误**：根据 `RetryPolicy` 进行重试\n3. **请求失败**：抛出 `LLMServiceError` 异常\n\n## 许可证\n\n根据项目根目录的许可证文件确定。\n\n## 相关链接\n\n- [NPM Package](https://www.npmjs.com/package/@autolabz/llmapi-sdk)\n- [GitHub Repository](https://github.com/autolabz/autolab_auth)\n\n","readmeFilename":"README.md"}