ctod 0.8.1 → 0.8.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 +6 -15
- package/dist/index.js +15 -37
- package/dist/index.js.map +4 -4
- package/examples/anthropic.ts +101 -0
- package/examples/plugin.ts +2 -2
- package/lib/index.ts +2 -0
- package/lib/service/anthropic/chat.ts +146 -0
- package/lib/service/anthropic/index.ts +29 -0
- package/lib/service/google/chat.ts +5 -0
- package/lib/service/google/index.ts +5 -2
- package/lib/service/llama3.cpp/completion.ts +35 -32
- package/lib/service/openai/chat.ts +2 -2
- package/package.json +6 -4
- package/types/examples/anthropic.d.ts +1 -0
- package/types/lib/index.d.ts +2 -0
- package/types/lib/service/anthropic/chat.d.ts +52 -0
- package/types/lib/service/anthropic/index.d.ts +11 -0
- package/types/lib/service/google/chat.d.ts +4 -0
- package/types/lib/service/llama3.cpp/completion.d.ts +1 -0
- package/types/lib/service/openai/chat.d.ts +2 -2
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
|
|
22
22
|
在對話過程中,CtoD 採用 [yup](https://github.com/jquense/yup) 來驗證請求與回復資料是否符合預期,以確保一致性,只要保持這個互動模式,就可以利用在 API 串接或是自動化系統上。
|
|
23
23
|
|
|
24
|
-
我們還附帶支援 `OpenAI`
|
|
24
|
+
我們還附帶支援 `OpenAI`, `Google`, `Llama3` 等相關 LLM 服務。
|
|
25
25
|
|
|
26
26
|
## 安裝
|
|
27
27
|
|
|
@@ -42,10 +42,10 @@ yarn add ctod
|
|
|
42
42
|
這個例子示範如何將藥物索引與客戶需求傳遞給聊天機器人,並返回最適合的結果,開發人員可以利用索引結果去資料庫搜尋最適合的藥物給消費者:
|
|
43
43
|
|
|
44
44
|
```ts
|
|
45
|
-
import { CtoD,
|
|
45
|
+
import { CtoD, OpenAICtodService } from 'ctod'
|
|
46
46
|
|
|
47
47
|
const ctod = new CtoD({
|
|
48
|
-
request:
|
|
48
|
+
request: OpenAICtodService.createChatRequestWithJsonSchema({
|
|
49
49
|
apiKey: 'YOUR_API_KEY',
|
|
50
50
|
config: {
|
|
51
51
|
model: 'gpt-4o'
|
|
@@ -131,14 +131,14 @@ broker.request({
|
|
|
131
131
|
|
|
132
132
|
雖然 Broker 本身已經能夠處理大部分的事務,但透過 Plugin 可以協助改善複雜的流程,幫助專案工程化。
|
|
133
133
|
|
|
134
|
-
每次發送請求時,Broker 會觸發一系列的生命週期,你可以從[原始碼](./lib/broker/
|
|
134
|
+
每次發送請求時,Broker 會觸發一系列的生命週期,你可以從[原始碼](./lib/broker/openai.ts)中了解每個生命週期的參數與行為,並對其行為進行加工。
|
|
135
135
|
|
|
136
136
|
現在,假設我們想要設計一個插件,它會在每次對話結束時將訊息備份到伺服器上:
|
|
137
137
|
|
|
138
138
|
```ts
|
|
139
139
|
import axios from 'axios'
|
|
140
|
-
import {
|
|
141
|
-
const backupPlugin = new
|
|
140
|
+
import { CtoDPlugin } from 'ctod'
|
|
141
|
+
const backupPlugin = new CtoDPlugin({
|
|
142
142
|
name: 'backup-plugin',
|
|
143
143
|
// 定義參數為 sendUrl
|
|
144
144
|
params: yup => {
|
|
@@ -178,15 +178,6 @@ const backupPlugin = new ChatBrokerPlugin({
|
|
|
178
178
|
}
|
|
179
179
|
})
|
|
180
180
|
|
|
181
|
-
const broker = new ChatBroker({
|
|
182
|
-
// ...
|
|
183
|
-
plugins: {
|
|
184
|
-
backup: backupPlugin.use({
|
|
185
|
-
sendUrl: 'https://api/backup'
|
|
186
|
-
})
|
|
187
|
-
}
|
|
188
|
-
})
|
|
189
|
-
|
|
190
181
|
const ctod = new CtoD({
|
|
191
182
|
// ...
|
|
192
183
|
plugins: () => {
|
package/dist/index.js
CHANGED
|
@@ -1,40 +1,18 @@
|
|
|
1
|
-
var
|
|
2
|
-
`+JSON.stringify(
|
|
3
|
-
`+
|
|
4
|
-
`+
|
|
5
|
-
`+JSON.stringify(
|
|
6
|
-
`+
|
|
1
|
+
var Z=Object.defineProperty;var ce=(s,e,t)=>e in s?Z(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t;var ee=(s,e)=>{for(var t in e)Z(s,t,{get:e[t],enumerable:!0})};var o=(s,e,t)=>ce(s,typeof e!="symbol"?e+"":e,t);var se={};ee(se,{LimiterPlugin:()=>fe,LimiterPluginGlobState:()=>ye,PrintLogPlugin:()=>de,RetryPlugin:()=>he,RolePlugin:()=>Ce});import{Event as pe}from"power-helper";var h=class{constructor(e){o(this,"_event",new pe);o(this,"_params");this._params=e}use(e){return{instance:this,params:e,send:t=>{this._event.emit("receive",t)},receive:t=>{this._event.on("receive",t)},__receiveData:null}}};var te=new h({name:"retry",params:s=>({retry:s.number().required().default(1),printWarn:s.boolean().required().default(!0)}),receiveData:()=>({}),onInstall({log:s,attach:e,params:t}){e("parseFailed",async({count:n,retry:r,messages:a,changeMessages:i})=>{n<=t.retry&&(t.printWarn&&s.print(`Is Failed, Retry ${n} times.`),i(a),r())})}});var ne=new h({name:"print-log",params:s=>({detail:s.boolean().default(!1)}),receiveData:()=>({}),onInstall({params:s,log:e,attach:t}){t("talkBefore",async({lastUserMessage:n,messages:r})=>{e.print("Send:",{color:"green"}),s.detail?e.print(`
|
|
2
|
+
`+JSON.stringify(r,null,4)):e.print(`
|
|
3
|
+
`+n)}),t("talkAfter",async({parseText:n})=>{e.print("Receive:",{color:"cyan"}),e.print(`
|
|
4
|
+
`+n)}),t("succeeded",async({output:n})=>{e.print("Output:",{color:"yellow"});try{e.print(`
|
|
5
|
+
`+JSON.stringify(n,null,4))}catch{e.print(`
|
|
6
|
+
`+n)}})}});import{Event as ge,flow as me,Schedule as ue}from"power-helper";var F={limit:3,interval:6e4},m={event:new ge,schedule:null,waitTimes:[],waitQueue:[]},H={event:m.event,config:F,closeSchedule:()=>{m.schedule&&(m.schedule.close(),m.schedule=null)},plugin:new h({name:"limiter",params:()=>({}),receiveData:()=>({}),onInstall({attach:s}){m.schedule==null&&(m.schedule=new ue,m.schedule.add("calc queue",1e3,async()=>{let e=Date.now();if(m.waitTimes=m.waitTimes.filter(t=>e-t<F.interval),m.waitTimes.length!==F.limit){let t=m.waitQueue.shift();t&&(m.waitTimes.push(Date.now()),m.event.emit("run",{id:t}))}else m.waitTimes[0]&&m.event.emit("waitTimeChange",{waitTime:Math.floor(60-(e-m.waitTimes[0])/1e3)})}),m.schedule.play()),s("talkBefore",async()=>{let e=me.createUuid();return m.waitQueue.push(e),new Promise(t=>{m.event.on("run",({id:n},{off:r})=>{n===e&&(r(),t())})})})}})};var re=new h({name:"role",params:s=>({role:s.string().required()}),receiveData:()=>({}),onInstall({attach:s,params:e}){s("start",async({messages:t,changeMessages:n})=>{n([{role:"user",content:`\u4F60\u73FE\u5728\u662F${e.role}\u3002`},{role:"assistant",content:`\u6C92\u554F\u984C\uFF0C\u6211\u73FE\u5728\u662F${e.role}\uFF0C\u6709\u4EC0\u9EBC\u53EF\u4EE5\u5E6B\u4F60\u7684\u55CE\uFF1F`},...t])})}});var de=ne,he=te,fe=H.plugin,ye=H,Ce=re;var oe={};ee(oe,{requireJsonResponse:()=>ae,requireJsonResponseWithHandlebars:()=>ve,requireJsonResponseWithJsonSchema:()=>Te});import xe from"handlebars";import{record as ke}from"power-helper";var ae=(s,e)=>[...Array.isArray(s)?s:[s],"Please respond using the following JSON format and minify the JSON without including any explanation: ","{",Object.entries(e).map(([t,n])=>[`/* ${n.desc} */`,`"${t}": ${JSON.stringify(n.example)}`].join(`
|
|
7
7
|
`)).join(`,
|
|
8
8
|
`),"}"].join(`
|
|
9
|
-
`),
|
|
10
|
-
`);import
|
|
11
|
-
`):
|
|
12
|
-
`):C.content}))},changeMessages:
|
|
13
|
-
`):
|
|
14
|
-
`);for(let
|
|
15
|
-
`):e}]);return{result:
|
|
16
|
-
|
|
17
|
-
`);g
|
|
18
|
-
|
|
19
|
-
${i}
|
|
20
|
-
|
|
21
|
-
`),s==="user"&&t.push(`<|start_header_id|>user<|end_header_id|>
|
|
22
|
-
|
|
23
|
-
${i?.replaceAll(`
|
|
24
|
-
`,"\\n")??""}`),s==="assistant"&&t.push(`<|start_header_id|>assistant<|end_header_id|>
|
|
25
|
-
|
|
26
|
-
`+i);let r=e.messages.at(-1)||"",n=new w(this);return{...n.export(),run:async()=>{let s=await n.fetch({path:"completion",data:{...e.options||{},prompt:this.config.autoConvertTraditionalChinese?G(t.join(`
|
|
27
|
-
`)):t.join(`
|
|
28
|
-
`)}}),i=this.config.autoConvertTraditionalChinese?E(s.data.content):s.data.content;return{message:i,fullMessage:`${r}${i}`}}}}completionStream(e){let t=[];for(let{role:n,content:s}of e.messages)n==="system"&&t.push(`<|start_header_id|>system<|end_header_id|>
|
|
29
|
-
|
|
30
|
-
${s}
|
|
31
|
-
|
|
32
|
-
`),n==="user"&&t.push(`<|start_header_id|>user<|end_header_id|>
|
|
33
|
-
|
|
34
|
-
${s?.replaceAll(`
|
|
35
|
-
`,"\\n")??""}`),n==="assistant"&&t.push(`<|start_header_id|>assistant<|end_header_id|>
|
|
36
|
-
|
|
37
|
-
`+s);let r=new w(this);return r.stream({path:"completion",onEnd:e.onEnd||(()=>null),onMessage:n=>{e.onMessage({message:this.config.autoConvertTraditionalChinese?E(n.content):n.content})},onWarn:e.onWarn||(()=>null),onError:e.onError||(()=>null),data:{...e.options||{},prompt:this.config.autoConvertTraditionalChinese?G(t.join(`
|
|
38
|
-
`)):t.join(`
|
|
39
|
-
`),stream:!0}}),r.export()}talk(e){let t=new w(this);return{...t.export(),run:async()=>{let n=(await t.fetch({path:"v1/chat/completions",data:{...e.options||{},response_format:e.response_format,messages:e.messages.map(s=>({role:s.role,content:this.config.autoConvertTraditionalChinese?G(s.content):s.content}))}})).data.choices[0].message.content||"";return{message:this.config.autoConvertTraditionalChinese?E(n):n}}}}talkStream(e){let t=new w(this);return t.stream({path:"v1/chat/completions",onEnd:e.onEnd||(()=>null),onMessage:r=>{let n=r.choices[0].delta.content;n&&e.onMessage({message:this.config.autoConvertTraditionalChinese?E(n):n})},onWarn:e.onWarn||(()=>null),onError:e.onError||(()=>null),data:{...e.options||{},stream:!0,messages:e.messages.map(r=>({role:r.role,content:this.config.autoConvertTraditionalChinese?G(r.content):r.content}))}}),t.export()}};var L=class a{constructor(){o(this,"_axios",Me.create())}static createChatRequestWithJsonSchema(e){return async(t,{schema:r,onCancel:n})=>{let i=new a().createCompletion(),c=typeof e.config=="function"?await e.config():e.config;i.setConfig(c);let l=v(r.output);i.config.autoConvertTraditionalChinese&&(l=JSON.parse(Re(JSON.stringify(l))));let{run:g,cancel:f}=i.talk({options:e.talkOptions,messages:t,response_format:{type:"json_object",schema:l}});n(f);let{message:P}=await g();return P}}setAxios(e){this._axios=e}createCompletion(){return new B(this)}};import{json as Ie}from"power-helper";var q=class{constructor(e){o(this,"google");o(this,"config",{model:"gemini-1.5-flash"});this.google=e}setConfig(e){Object.assign(this.config,e)}async talk(e=[]){let t=Ie.jpjs(e),s=(await this.google.generativeAI.getGenerativeModel({model:this.config.model}).generateContent({contents:t})).response.text();return{text:s,newMessages:[...t,{role:"model",parts:[{text:s}]}]}}talkStream(e){let t=this.google.generativeAI.getGenerativeModel({model:this.config.model}),r={contents:e.messages};t.generateContentStream(r).then(async({stream:n})=>{for await(let s of n){let i=s.text();e.onMessage(i)}e.onEnd()}).catch(n=>{e.onError(n)})}};var U=class a{constructor(e){o(this,"generativeAI");this.generativeAI=e}static chatGPTMessageToGoogleChatMessage(e){let t=r=>typeof r=="string"?[{text:r}]:Array.isArray(r)?r.map(({type:n,image_url:s,text:i})=>n==="image_url"?{inlineData:{data:s?.url||"",mimeType:"image/jpeg"}}:{text:i||""}):[];return e.map(r=>r.role==="user"||r.role==="system"?{role:"user",parts:t(r.content)}:{role:"model",parts:t(r.content)})}static createChatRequestWithJsonSchema(e){let t=r=>(r.type==="object"?(delete r.additionalProperties,Object.keys(r.properties).forEach(n=>{t(r.properties[n])})):r.type==="array"&&t(r.items),r);return async(r,{schema:n})=>{let s=t(v(n.output));return(await e.googleGenerativeAI.getGenerativeModel({model:e.model,generationConfig:{responseMimeType:"application/json",responseSchema:s}}).generateContent({contents:a.chatGPTMessageToGoogleChatMessage(r)})).response.text()}}createChat(){return new q(this)}};export{M as ChatBroker,h as ChatBrokerPlugin,W as CtoD,U as GoogleCtodService,L as Llama3CppCtodService,D as OpenAICtodService,O as TextParser,A as Translator,Te as defineYupSchema,re as plugins,ae as templates,v as validateToJsonSchema};
|
|
9
|
+
`),ve=(s,e,t)=>{let n=xe.create();return n.registerHelper("DATA",function(r){return JSON.stringify(r)}),n.registerHelper("ENV",function(r){return this.__envs&&r?this.__envs[r]:""}),n.registerHelper("INPUT",function(){return JSON.stringify(ke.omit(this,["__envs"]))}),n.registerHelper("JOIN",function(r){return Array.isArray(r)?r.join():JSON.stringify(r)}),n.compile(ae(e,t))(s)},Te=(s,e)=>[...Array.isArray(s)?s:[s],"Please provide JSON data according to the following JSON Schema format:",JSON.stringify(e)].join(`
|
|
10
|
+
`);import Pe from"json5";var _=class s{constructor(e){o(this,"params");this.params=e}static JsonMessage(){return new s({name:"JsonMessage",handler:async e=>{try{return JSON.parse(e)}catch{let n=/{(?:[^{}]|(?:{[^{}]*}))*}/,r=e.match(n)?.[0]||"";return Pe.parse(r)}}})}get name(){return this.params.name}async read(e){return await this.params.handler(e)}};import{Event as we,flow as ie,Hook as Oe,Log as _e}from"power-helper";import*as S from"yup";import{convertSchema as be}from"@sodaru/yup-to-json-schema";function D(s,e){return S.object(e(S)).required().validateSync(s||{})}var Se=s=>s(S),k=s=>{let e=r=>{if(r.default&&delete r.default,r.properties)for(let a in r.properties)r.properties[a].default&&delete r.properties[a].default,e(r.properties[a]);r.items&&e(r.items)},t=r=>{if(r.type==="object"){r.additionalProperties=!1;for(let a in r.properties)t(r.properties[a])}else r.type==="array"&&t(r.items)},n=be(S.object(s(S)));return e(n),t(n),n};var P=class{constructor(e,t){o(this,"isParserError",!0);o(this,"parserFails",[]);o(this,"error");this.error=e,this.parserFails=t}};var A=class{constructor(e){o(this,"params");this.params=e}get __schemeType(){return null}get __outputType(){return null}async compile(e,t){let n=this.params.input?D(e,this.params.input):e,r=this.params.question?await this.params.question(n,t):"";return{scheme:n,prompt:Array.isArray(r)?r.join(`
|
|
11
|
+
`):r}}getValidate(){return{input:this.params.input,output:this.params.output}}changeOutputSchema(e){this.params.output=e}async parse(e){let t,n="",r=[];for(let a of this.params.parsers)try{t=await a.read(e),n=a.name}catch(i){t=void 0,r.push({name:a.name,error:i})}try{return{output:D(t,this.params.output),parserName:n,parserFails:r}}catch(a){throw new P(a,r)}}};var M=class{constructor(e){o(this,"__hookType");o(this,"log");o(this,"hook",new Oe);o(this,"params");o(this,"plugins",{});o(this,"installed",!1);o(this,"translator");o(this,"event",new we);this.log=new _e(e.name??"no name"),this.params=e,this.translator=new A({...e,parsers:[_.JsonMessage()]})}_install(){if(this.installed===!1){this.installed=!0;let e={log:this.log,attach:this.hook.attach.bind(this.hook),attachAfter:this.hook.attachAfter.bind(this.hook),translator:this.translator};if(this.params.plugins){this.plugins=typeof this.params.plugins=="function"?this.params.plugins():this.params.plugins;for(let t in this.plugins)this.plugins[t].instance._params.onInstall({...e,params:this.plugins[t].params,receive:this.plugins[t].receive})}this.params.install?.(e)}}async cancel(e){e?this.event.emit("cancel",{requestId:e}):this.event.emit("cancelAll",{})}requestWithId(e){this._install();let t=ie.createUuid(),n=null,r=!1,a=!1,i=[this.event.on("cancel",({requestId:g})=>{g===t&&c()}),this.event.on("cancelAll",()=>{c()})],l=()=>i.forEach(g=>g.off()),c=()=>{r===!1&&(a&&n&&n(),r=!0,l())},p=g=>{n=g},u=async()=>{let g=this.translator.getValidate(),T=null,b={},y=new Map,Q=await this.translator.compile(e,{schema:g}),X=[],f=[];Q.prompt&&f.push({role:"user",content:Q.prompt});for(let d in this.plugins)b[d]={send:C=>this.plugins[d].send({id:t,data:C})};return await this.hook.notify("start",{id:t,data:e,schema:g,plugins:b,messages:f,metadata:y,setPreMessages:d=>{X=d.map(C=>({...C,content:Array.isArray(C.content)?C.content.join(`
|
|
12
|
+
`):C.content}))},changeMessages:d=>{f=d},changeOutputSchema:d=>{this.translator.changeOutputSchema(d),g=this.translator.getValidate()}}),f=[...X,...f],await ie.asyncWhile(async({count:d,doBreak:C})=>{if(d>=99)return C();let R="",I="",K=!1,W=f.filter(x=>x.role==="user").slice(-1)[0]?.content||"";try{await this.hook.notify("talkBefore",{id:t,data:e,messages:f,metadata:y,lastUserMessage:W});let x=this.params.request(f,{id:t,count:d,schema:g,onCancel:p,metadata:y,isRetry:K});if(r)n&&n();else try{a=!0,R=await x,I=R}finally{a=!1}r===!1&&(await this.hook.notify("talkAfter",{id:t,data:e,response:R,messages:f,parseText:I,metadata:y,lastUserMessage:W,parseFail:O=>{throw new P(O,[])},changeParseText:O=>{I=O}}),T=(await this.translator.parse(I)).output,await this.hook.notify("succeeded",{id:t,output:T,metadata:y})),await this.hook.notify("done",{id:t,metadata:y}),C()}catch(x){if(x instanceof P){if(await this.hook.notify("parseFailed",{id:t,error:x.error,count:d,response:R,messages:f,metadata:y,lastUserMessage:W,parserFails:x.parserFails,retry:()=>{K=!0},changeMessages:O=>{f=O}}),K===!1)throw await this.hook.notify("done",{id:t,metadata:y}),x}else throw await this.hook.notify("done",{id:t,metadata:y}),x}}),T};return{id:t,request:(async()=>{try{return await u()}finally{l()}})()}}async request(e){let{request:t}=this.requestWithId(e);return await t}};import*as Ae from"yup";var $=class{constructor(e){o(this,"params");this.params=e}createBrokerBuilder(e){return{create:t=>new M({output:()=>({}),install:n=>{e?.install?.(n),n.attach("start",async({id:r,plugins:a,data:i,metadata:l,changeMessages:c,changeOutputSchema:p})=>{let u=await t({id:r,data:i,plugins:a,yup:Ae,setMessages:v=>{c(v.map(g=>({role:g.role,content:Array.isArray(g.content)?g.content.join(`
|
|
13
|
+
`):g.content})))},metadata:l});p(()=>u)})},plugins:this.params.plugins?()=>this.params.plugins():void 0,request:this.params.request})}}};import Re from"axios";var V=class{constructor(e){o(this,"openai");o(this,"config",{model:"gpt-4-vision-preview",maxTokens:void 0,temperature:1});this.openai=e}setConfig(e){Object.assign(this.config,e)}async view(e){let t=await this.openai._axios.post("https://api.openai.com/v1/chat/completions",{model:this.config.model,n:1,messages:e,max_tokens:this.config.maxTokens,temperature:this.config.temperature},{headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.openai._apiKey}`}}),r=(t.data.choices||[])[0]?.message||{role:"assistant",content:""};return{id:t?.data.id,text:r.content,apiResponse:t.data}}};import{json as Me}from"power-helper";var j=class{constructor(e){o(this,"openai");o(this,"config",{n:1,model:"gpt-4o",temperature:1,maxTokens:void 0,forceJsonFormat:!0});this.openai=e}setConfig(e){Object.assign(this.config,e)}async moderations(e){let t=await this.openai._axios.post("https://api.openai.com/v1/moderations",{input:e},{headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.openai._apiKey}`}});return{isSafe:t.data.results?.[0]?.flagged===!1,result:t.data}}async talk(e=[],t){let n=Me.jpjs(e),r=["gpt-4-turbo-preview","gpt-4-turbo","gpt-4o","gpt-4o-mini","gpt-3.5-turbo-1106"].includes(this.config.model),a;r&&this.config.forceJsonFormat&&(a={type:"json_object"}),r&&this.config.forceJsonFormat&&t?.jsonSchema&&(a={type:"json_schema",json_schema:t.jsonSchema});let i=await this.openai._axios.post("https://api.openai.com/v1/chat/completions",{model:this.config.model,n:this.config.n,messages:n,response_format:a,temperature:this.config.temperature},{signal:t?.abortController?.signal,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.openai._apiKey}`}}),l=i.data.choices||[],c=l[0]?.message||{role:"assistant",content:""};return n.push(c),{id:i?.data.id,text:c.content,newMessages:n,isDone:l[0]?.finish_reason==="stop",apiResponse:i.data}}talkStream(e){let t=new AbortController;return fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.openai._apiKey}`},body:JSON.stringify({model:this.config.model,stream:!0,messages:e.messages}),signal:t.signal}).then(async n=>{let r=n.body?.pipeThrough(new TextDecoderStream).getReader();if(!r)throw new Error("Can not get reader");for(;;){let{value:a,done:i}=await r.read();if(i)break;let l=a.split(`
|
|
14
|
+
`);for(let c of l)if(c.length!==0&&!c.startsWith(":")){if(c==="data: [DONE]"){e.onEnd();break}try{let u=JSON.parse(c.substring(6)).choices[0].delta.content;e.onMessage(u)}catch(p){e.onWarn(p)}}}}).catch(n=>{n.name==="AbortError"?e.onEnd():e.onError(n)}),{cancel:()=>t.abort()}}async keepTalk(e,t=[]){let n=await this.talk([...t,{role:"user",content:Array.isArray(e)?e.join(`
|
|
15
|
+
`):e}]);return{result:n,nextTalk:r=>this.keepTalk(r,n.newMessages)}}};var E=class{constructor(e){o(this,"openai");o(this,"config",{model:"dall-e-2",size:"1024x1024"});this.openai=e}setConfig(e){Object.assign(this.config,e)}async create(e){return(await this.openai._axios.post("https://api.openai.com/v1/images/generations",{prompt:e,n:1,size:this.config.size,model:this.config.model,response_format:"b64_json"},{timeout:3e5,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.openai._apiKey}`}})).data}};var L=class s{constructor(e=""){o(this,"_axios",Re.create());o(this,"_apiKey","");this._apiKey=e}static createChatRequest(e,t={},n){return async(r,{onCancel:a})=>{let i=new s(typeof e=="string"?e:await e()),l=i.createChat(),c=new AbortController;n&&n.axios&&i.setAxios(n.axios),l.setConfig(typeof t=="function"?await t():t),a(()=>c.abort());let{text:p}=await l.talk(r,{abortController:c});return p}}static createChatRequestWithJsonSchema(e){return async(t,{schema:n,onCancel:r})=>{let a=new s(typeof e.apiKey=="string"?e.apiKey:await e.apiKey()),i=a.createChat(),l=new AbortController;e.config&&i.setConfig(typeof e.config=="function"?await e.config():e.config),e.axios&&a.setAxios(e.axios),r(()=>l.abort());let c=k(n.output),{text:p}=await i.talk(t,{abortController:l,jsonSchema:{name:"data",strict:!0,schema:c}});return p}}setAxios(e){this._axios=e}setConfiguration(e){this._apiKey=e}createChat(){return new j(this)}createVision(){return new V(this)}createImagesGeneration(){return new E(this)}};import je from"axios";import{sify as Ee}from"chinese-conv/dist";import{flow as Ie,Once as Ve}from"power-helper";import{tify as J,sify as G}from"chinese-conv/dist";import{Template as le}from"@huggingface/jinja";var w=class{constructor(e){o(this,"core");o(this,"streamAbortControllers",[]);this.core=e}createAbortController(){let e=new AbortController,t=Ie.createUuid();return this.streamAbortControllers.push({id:t,controller:e}),{signal:e.signal,controllerId:t}}removeAbortController(e){this.streamAbortControllers=this.streamAbortControllers.filter(t=>t.id!==e)}async stream(e){let{signal:t,controllerId:n}=this.createAbortController(),r=()=>{this.removeAbortController(n),e.onEnd()},a=async i=>{if(i.body){let l=i.body.getReader(),c=!1,p="";for(;!c;){let{value:u,done:v}=await l.read();if(u){p+=new TextDecoder("utf-8").decode(u);let g=p.split(`
|
|
16
|
+
|
|
17
|
+
`);p=g.pop()||"",g.forEach(T=>{if(T.includes("[DONE]")&&(c=!0),T.startsWith("data:"))try{let b=JSON.parse(T.replace("data: ",""));e.onMessage(b)}catch(b){e.onWarn(b)}})}v&&(c=!0)}r()}else e.onError(new Error("Body not found."))};fetch(`${this.core.config.baseUrl}/${e.path}`,{method:"POST",body:JSON.stringify(typeof e.data=="function"?await e.data():e.data),signal:t,headers:{"Content-Type":"application/json",...this.core.config.headers}}).then(a).catch(i=>{i instanceof Error&&i.message.includes("The user aborted a request")?r():e.onError(i)})}async fetch(e){let{signal:t,controllerId:n}=this.createAbortController();try{return{data:(await this.core.core._axios.post(`${this.core.config.baseUrl}/${e.path}`,e.data,{signal:t,headers:{"Content-Type":"application/json",...this.core.config.headers}})).data}}finally{this.removeAbortController(n)}}cancel(){this.streamAbortControllers.forEach(e=>e.controller.abort()),this.streamAbortControllers=[]}export(){return{cancel:this.cancel.bind(this)}}},B=class{constructor(e){o(this,"getProp",new Ve({handler:async()=>{let e=`${this.config.baseUrl}/props`,{data:t}=await this.core._axios.get(e,{});return t}}));o(this,"core");o(this,"config",{baseUrl:"",headers:{},autoConvertTraditionalChinese:!0});this.core=e}setConfig(e){this.config={...this.config,...e}}completion(e){let t=e.messages.at(-1)||"",n=new w(this);return{...n.export(),run:async()=>{let r=await this.getProp.run(),i=new le(r.chat_template).render({bos_token:r.bos_token,messages:e.messages}).slice(0,r.eos_token.length*-1-1),l=await n.fetch({path:"completion",data:{...e.options||{},prompt:this.config.autoConvertTraditionalChinese?G(i):i}}),c=this.config.autoConvertTraditionalChinese?J(l.data.content):l.data.content;return{message:c,fullMessage:`${t}${c}`}}}}completionStream(e){let t=new w(this);return t.stream({path:"completion",onEnd:e.onEnd||(()=>null),onMessage:n=>{e.onMessage({message:this.config.autoConvertTraditionalChinese?J(n.content):n.content})},onWarn:e.onWarn||(()=>null),onError:e.onError||(()=>null),data:async()=>{let n=await this.getProp.run(),a=new le(n.chat_template).render({bos_token:n.bos_token,messages:e.messages}).slice(0,n.eos_token.length*-1-1);return{...e.options||{},prompt:this.config.autoConvertTraditionalChinese?G(a):a,stream:!0}}}),t.export()}talk(e){let t=new w(this);return{...t.export(),run:async()=>{let r=(await t.fetch({path:"v1/chat/completions",data:{...e.options||{},response_format:e.response_format,messages:e.messages.map(a=>({role:a.role,content:this.config.autoConvertTraditionalChinese?G(a.content):a.content}))}})).data.choices[0].message.content||"";return{message:this.config.autoConvertTraditionalChinese?J(r):r}}}}talkStream(e){let t=new w(this);return t.stream({path:"v1/chat/completions",onEnd:e.onEnd||(()=>null),onMessage:n=>{let r=n.choices[0].delta.content;r&&e.onMessage({message:this.config.autoConvertTraditionalChinese?J(r):r})},onWarn:e.onWarn||(()=>null),onError:e.onError||(()=>null),data:{...e.options||{},stream:!0,messages:e.messages.map(n=>({role:n.role,content:this.config.autoConvertTraditionalChinese?G(n.content):n.content}))}}),t.export()}};var U=class s{constructor(){o(this,"_axios",je.create())}static createChatRequestWithJsonSchema(e){return async(t,{schema:n,onCancel:r})=>{let i=new s().createCompletion(),l=typeof e.config=="function"?await e.config():e.config;i.setConfig(l);let c=k(n.output);i.config.autoConvertTraditionalChinese&&(c=JSON.parse(Ee(JSON.stringify(c))));let{run:p,cancel:u}=i.talk({options:e.talkOptions,messages:t,response_format:{type:"json_object",schema:c}});r(u);let{message:v}=await p();return v}}setAxios(e){this._axios=e}createCompletion(){return new B(this)}};import{json as Je}from"power-helper";var q=class{constructor(e){o(this,"google");o(this,"config",{model:"gemini-1.5-flash"});this.google=e}setConfig(e){Object.assign(this.config,e)}async talk(e=[]){let t=Je.jpjs(e),a=(await this.google.generativeAI.getGenerativeModel({model:this.config.model}).generateContent({contents:t})).response.text();return{text:a,newMessages:[...t,{role:"model",parts:[{text:a}]}]}}talkStream(e){let t=this.google.generativeAI.getGenerativeModel({model:this.config.model}),n={contents:e.messages};t.generateContentStream(n).then(async({stream:r})=>{for await(let a of r){let i=a.text();e.onMessage(i)}e.onEnd()}).catch(r=>{e.onError(r)})}};var z=class s{constructor(e){o(this,"generativeAI");this.generativeAI=e}static chatGPTMessageToGoogleChatMessage(e){let t=n=>typeof n=="string"?[{text:n}]:Array.isArray(n)?n.map(({type:r,image_url:a,text:i})=>{if(r==="image_url"){let l=a?.url||"",c=l.includes("data:image/png")?"image/png":"image/jpeg";return{inlineData:{data:l.split("base64,")[1]||"",mimeType:c}}}else return{text:i||""}}):[];return e.map(n=>n.role==="user"||n.role==="system"?{role:"user",parts:t(n.content)}:{role:"model",parts:t(n.content)})}static createChatRequestWithJsonSchema(e){let t=n=>(n.type==="object"?(delete n.additionalProperties,Object.keys(n.properties).forEach(r=>{t(n.properties[r])})):n.type==="array"&&t(n.items),n);return async(n,{schema:r})=>{let a=t(k(r.output));return(await e.googleGenerativeAI.getGenerativeModel({model:e.model,generationConfig:{responseMimeType:"application/json",responseSchema:a}}).generateContent({contents:s.chatGPTMessageToGoogleChatMessage(n)})).response.text()}}createChat(){return new q(this)}};var N=class{constructor(e){o(this,"anthropic");o(this,"config",{model:"claude-3-5-haiku-latest",maxTokens:8192});this.anthropic=e}setConfig(e){Object.assign(this.config,e)}translateMessages(e){return{system:e.find(t=>t.role==="system")?.content[0].text,messages:e.filter(t=>t.role!=="system")}}async chatAndStructure(e,t){let n=this.anthropic.anthropicSdk,r=this.translateMessages(e),l=(await n.messages.create({model:this.config.model,max_tokens:this.config.maxTokens,system:r.system,messages:r.messages,tools:[{name:"data",description:"Response Data",input_schema:t}],tool_choice:{type:"tool",name:"data"}})).content.find(c=>c.type==="tool_use")?.input||null;return l==null?"null":JSON.stringify(l)}async talk(e=[]){let t=this.anthropic.anthropicSdk,n=this.translateMessages(e),r=await t.messages.create({model:this.config.model,max_tokens:this.config.maxTokens,system:n.system,messages:n.messages}),a="",i=r.content.find(l=>l.type==="text");return i&&(a=i.text),a}talkStream(e){let t=this.anthropic.anthropicSdk,{onMessage:n,onEnd:r,onError:a}=e,{messages:i,system:l}=this.translateMessages(e.messages);return(async()=>{try{let p=await t.messages.create({model:this.config.model,max_tokens:this.config.maxTokens,system:l,stream:!0,messages:i});for await(let u of p)if(u.type==="content_block_delta"){let v="text"in u.delta?u.delta.text:"";n(v)}r()}catch(p){a(p)}})(),{cancel:()=>null}}};var Y=class s{constructor(e){o(this,"anthropicSdk");this.anthropicSdk=e}static createChatRequestWithJsonSchema(e){let n=new s(e.anthropicSdk).createChat();return n.setConfig(e.config||{}),async(r,{schema:a})=>{let i=k(a.output);return await n.chatAndStructure(r,i)}}createChat(){return new N(this)}};export{Y as AnthropicCtodService,M as ChatBroker,h as ChatBrokerPlugin,$ as CtoD,h as CtoDPlugin,z as GoogleCtodService,U as Llama3CppCtodService,L as OpenAICtodService,_ as TextParser,A as Translator,Se as defineYupSchema,se as plugins,oe as templates,k as validateToJsonSchema};
|
|
40
18
|
//# sourceMappingURL=index.js.map
|