@opentiny/tiny-robot-kit 0.4.0-alpha.2 → 0.4.0-alpha.4
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/dist/index.d.mts +14 -3
- package/dist/index.d.ts +14 -3
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/package.json +5 -2
package/dist/index.d.mts
CHANGED
|
@@ -33,6 +33,7 @@ interface MessageMetadata {
|
|
|
33
33
|
interface ChatMessage {
|
|
34
34
|
role: string;
|
|
35
35
|
content: string;
|
|
36
|
+
reasoning_content?: string;
|
|
36
37
|
metadata?: MessageMetadata;
|
|
37
38
|
tool_calls?: ToolCall[];
|
|
38
39
|
tool_call_id?: string;
|
|
@@ -101,7 +102,16 @@ interface ChatCompletion {
|
|
|
101
102
|
}
|
|
102
103
|
interface UseMessageOptions {
|
|
103
104
|
initialMessages?: ChatMessage[];
|
|
104
|
-
|
|
105
|
+
/**
|
|
106
|
+
* 请求消息时,要包含的字段(白名单)。默认包含所有字段。
|
|
107
|
+
* 如果 `requestMessageFieldsExclude` 存在,会先取 `requestMessageFields` 中的字段,再排除 `requestMessageFieldsExclude` 中的字段
|
|
108
|
+
*/
|
|
109
|
+
requestMessageFields?: string[];
|
|
110
|
+
/**
|
|
111
|
+
* 请求消息时,要排除的字段(黑名单)。默认会排除 `state`、`metadata`、`loading` 字段(这几个字段是给UI展示用的)。
|
|
112
|
+
* 如果 `requestMessageFields` 存在,会先取 `requestMessageFields` 中的字段,再排除 `requestMessageFieldsExclude` 中的字段
|
|
113
|
+
*/
|
|
114
|
+
requestMessageFieldsExclude?: string[];
|
|
105
115
|
plugins?: UseMessagePlugin[];
|
|
106
116
|
responseProvider: <T = ChatCompletion>(requestBody: MessageRequestBody, abortSignal: AbortSignal) => Promise<T> | AsyncGenerator<T> | Promise<AsyncGenerator<T>>;
|
|
107
117
|
/**
|
|
@@ -111,6 +121,7 @@ interface UseMessageOptions {
|
|
|
111
121
|
*/
|
|
112
122
|
onCompletionChunk?: (context: BasePluginContext & {
|
|
113
123
|
currentMessage: ChatMessage;
|
|
124
|
+
choice: CompletionChoice;
|
|
114
125
|
chunk: ChatCompletion;
|
|
115
126
|
}, runDefault: () => void) => void;
|
|
116
127
|
}
|
|
@@ -129,7 +140,6 @@ interface BasePluginContext {
|
|
|
129
140
|
currentTurn: ChatMessage[];
|
|
130
141
|
requestState: RequestState;
|
|
131
142
|
processingState?: RequestProcessingState;
|
|
132
|
-
requestMessageFields: (keyof ChatMessage)[];
|
|
133
143
|
plugins: UseMessagePlugin[];
|
|
134
144
|
setRequestState: (state: RequestState, processingState?: RequestProcessingState) => void;
|
|
135
145
|
abortSignal: AbortSignal;
|
|
@@ -150,7 +160,7 @@ interface UseMessagePlugin {
|
|
|
150
160
|
/**
|
|
151
161
|
* 是否禁用插件。useMessage 可能会内置一些默认插件,如果需要禁用,可以设置为 true。
|
|
152
162
|
*/
|
|
153
|
-
disabled?: boolean;
|
|
163
|
+
disabled?: boolean | ((context: BasePluginContext) => boolean);
|
|
154
164
|
/**
|
|
155
165
|
* 一次对话回合(turn)开始钩子:用户消息入队后、正式发起请求之前触发。
|
|
156
166
|
* 按插件注册顺序串行执行,便于做有序初始化/校验;出错则中断流程。
|
|
@@ -195,6 +205,7 @@ interface UseMessagePlugin {
|
|
|
195
205
|
onError?: (context: BasePluginContext & {
|
|
196
206
|
error: unknown;
|
|
197
207
|
}) => void;
|
|
208
|
+
onFinally?: (context: BasePluginContext) => void;
|
|
198
209
|
}
|
|
199
210
|
|
|
200
211
|
interface ConversationInfo {
|
package/dist/index.d.ts
CHANGED
|
@@ -33,6 +33,7 @@ interface MessageMetadata {
|
|
|
33
33
|
interface ChatMessage {
|
|
34
34
|
role: string;
|
|
35
35
|
content: string;
|
|
36
|
+
reasoning_content?: string;
|
|
36
37
|
metadata?: MessageMetadata;
|
|
37
38
|
tool_calls?: ToolCall[];
|
|
38
39
|
tool_call_id?: string;
|
|
@@ -101,7 +102,16 @@ interface ChatCompletion {
|
|
|
101
102
|
}
|
|
102
103
|
interface UseMessageOptions {
|
|
103
104
|
initialMessages?: ChatMessage[];
|
|
104
|
-
|
|
105
|
+
/**
|
|
106
|
+
* 请求消息时,要包含的字段(白名单)。默认包含所有字段。
|
|
107
|
+
* 如果 `requestMessageFieldsExclude` 存在,会先取 `requestMessageFields` 中的字段,再排除 `requestMessageFieldsExclude` 中的字段
|
|
108
|
+
*/
|
|
109
|
+
requestMessageFields?: string[];
|
|
110
|
+
/**
|
|
111
|
+
* 请求消息时,要排除的字段(黑名单)。默认会排除 `state`、`metadata`、`loading` 字段(这几个字段是给UI展示用的)。
|
|
112
|
+
* 如果 `requestMessageFields` 存在,会先取 `requestMessageFields` 中的字段,再排除 `requestMessageFieldsExclude` 中的字段
|
|
113
|
+
*/
|
|
114
|
+
requestMessageFieldsExclude?: string[];
|
|
105
115
|
plugins?: UseMessagePlugin[];
|
|
106
116
|
responseProvider: <T = ChatCompletion>(requestBody: MessageRequestBody, abortSignal: AbortSignal) => Promise<T> | AsyncGenerator<T> | Promise<AsyncGenerator<T>>;
|
|
107
117
|
/**
|
|
@@ -111,6 +121,7 @@ interface UseMessageOptions {
|
|
|
111
121
|
*/
|
|
112
122
|
onCompletionChunk?: (context: BasePluginContext & {
|
|
113
123
|
currentMessage: ChatMessage;
|
|
124
|
+
choice: CompletionChoice;
|
|
114
125
|
chunk: ChatCompletion;
|
|
115
126
|
}, runDefault: () => void) => void;
|
|
116
127
|
}
|
|
@@ -129,7 +140,6 @@ interface BasePluginContext {
|
|
|
129
140
|
currentTurn: ChatMessage[];
|
|
130
141
|
requestState: RequestState;
|
|
131
142
|
processingState?: RequestProcessingState;
|
|
132
|
-
requestMessageFields: (keyof ChatMessage)[];
|
|
133
143
|
plugins: UseMessagePlugin[];
|
|
134
144
|
setRequestState: (state: RequestState, processingState?: RequestProcessingState) => void;
|
|
135
145
|
abortSignal: AbortSignal;
|
|
@@ -150,7 +160,7 @@ interface UseMessagePlugin {
|
|
|
150
160
|
/**
|
|
151
161
|
* 是否禁用插件。useMessage 可能会内置一些默认插件,如果需要禁用,可以设置为 true。
|
|
152
162
|
*/
|
|
153
|
-
disabled?: boolean;
|
|
163
|
+
disabled?: boolean | ((context: BasePluginContext) => boolean);
|
|
154
164
|
/**
|
|
155
165
|
* 一次对话回合(turn)开始钩子:用户消息入队后、正式发起请求之前触发。
|
|
156
166
|
* 按插件注册顺序串行执行,便于做有序初始化/校验;出错则中断流程。
|
|
@@ -195,6 +205,7 @@ interface UseMessagePlugin {
|
|
|
195
205
|
onError?: (context: BasePluginContext & {
|
|
196
206
|
error: unknown;
|
|
197
207
|
}) => void;
|
|
208
|
+
onFinally?: (context: BasePluginContext) => void;
|
|
198
209
|
}
|
|
199
210
|
|
|
200
211
|
interface ConversationInfo {
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`);a=A.pop()||"";for(let w of A)if(w.trim()!==""&&w.startsWith("data: ")){let v=w.slice(6);if(v==="[DONE]")return;try{yield JSON.parse(v)}catch(T){console.warn("Failed to parse SSE data:",v,T)}}}}finally{s?.removeEventListener("abort",i),n.releaseLock()}}var F=require("vue");var q=require("vue");var J=(e={})=>{let{fallbackRole:t="assistant",...n}=e;return{name:"fallbackRole",...n,onBeforeRequest(s){let{requestBody:o,messages:a}=s;return o.messages=a.map(i=>({...i,role:i.role||t})),n.onBeforeRequest?.(s)}}};var X=(e={})=>{let{continueContent:t="Please continue with your previous answer.",...n}=e;return{name:"length",...n,onAfterRequest:async s=>{let{lastChoice:o,appendMessage:a,requestNext:i}=s;return o?.finish_reason==="length"&&(a({role:"user",content:t}),i()),n.onAfterRequest?.(s)}}};var $=(e={})=>({name:"thinking",...e,onCompletionChunk(t){let{choice:n,currentMessage:s}=t,a=typeof(n?.message?.reasoning_content||n?.delta?.reasoning_content)=="string";return s.state?s.state.thinking=a:s.state={thinking:a},e.onCompletionChunk?.(t)},onTurnEnd(t){let n=t.currentTurn.slice(-1)[0];return n?.state&&(n.state.thinking=void 0),e.onTurnEnd?.(t)}});var se=require("vue");var B=class extends Error{constructor(t){super(t),this.name="AbortError"}};function pe(e){if(e.aborted)return{promise:Promise.reject(new B(String(e.reason??"Aborted"))),cleanup:()=>{}};let t=null;return{promise:new Promise((o,a)=>{t=()=>{a(new B(String(e.reason??"Aborted")))},e.addEventListener("abort",t,{once:!0})}),cleanup:()=>{t&&(e.removeEventListener("abort",t),t=null)}}}function te(e,t){let{promise:n,cleanup:s}=pe(t);return Promise.race([e,n]).finally(s)}function ne(e,t){let n={};for(let s of t)s in e&&(n[s]=e[s]);return n}async function*W(e){if(Z(e)){yield*e;return}let t=await e;if(Z(t)){yield*t;return}yield t}function Z(e){return e&&typeof e=="object"&&typeof e[Symbol.asyncIterator]=="function"}var Q=e=>typeof e=="object"&&e!==null,ee=e=>Q(e)&&typeof e.index=="number",G=(e,t)=>{for(let[n,s]of Object.entries(t)){let o=e[n];if(o)if(typeof o=="string"&&typeof s=="string")n==="type"&&o||(e[n]=o+s);else if(Array.isArray(o)&&Array.isArray(s))if(o.every(a=>ee(a))&&s.every(a=>ee(a))){let a=new Map(o.map(d=>[d.index,d])),i=new Map(s.map(d=>[d.index,d]));for(let[d,M]of i)if(a.has(d)){let A=a.get(d);a.set(d,G(A,M))}else a.set(d,M);let u=Math.max(...Array.from(a.keys()),-1)+1,y=u>o.length?Array.from({length:u}):o;for(let[d,M]of a)y[d]=M;e[n]=y}else e[n]=[...o,...s];else Q(o)&&Q(s)&&(e[n]=G(o,s));else e[n]=s}return e};function me(e,t){let n=[];for(let s=0;s<e.length;s++){let o=e[s];if(o.role==="assistant"&&o.tool_calls&&o.tool_calls.length>0){let a=new Set(o.tool_calls.map(y=>y.id)),i=new Set;for(let y=s+1;y<e.length;y++){let d=e[y];d.role==="tool"&&d.tool_call_id&&a.has(d.tool_call_id)&&i.add(d.tool_call_id)}let u=o.tool_calls.map(y=>y.id).filter(y=>!i.has(y));u.length>0&&n.push({insertAfterIndex:s,missingToolCallIds:u})}}for(let s=n.length-1;s>=0;s--){let{insertAfterIndex:o,missingToolCallIds:a}=n[s],i=a.map(u=>({role:"tool",tool_call_id:u,content:t}));e.splice(o+1,0,...i)}}var oe="remove";function he(e,t,n,s){let o=e.filter(i=>i[n]),a=new Set(o.flatMap(i=>i.tool_calls?.map(u=>u.id)??[]));if(t===oe)for(let i=e.length-1;i>=0;i--){let u=e[i];(u[n]||u[s]||u.tool_call_id&&a.has(u.tool_call_id))&&e.splice(i,1)}else if(t===!0)for(let i of e)(i[n]||i.tool_call_id&&a.has(i.tool_call_id))&&(i[s]=!0,delete i[n])}var ye=e=>{let{getTools:t,beforeCallTools:n,callTool:s,onToolCallStart:o,onToolCallEnd:a,toolCallCancelledContent:i="Tool call cancelled.",toolCallFailedContent:u="Tool call failed.",autoFillMissingToolMessages:y=!1,excludeToolMessagesNextTurn:d=!1,...M}=e,A=Symbol("doNotSendNextTurn"),w=Symbol("doNotSend"),v=(...C)=>{let[p,{primaryMessage:r}]=C;r.state.toolCall[p.id].status="running",o?.(...C)},T=(...C)=>{let[p,{status:r,primaryMessage:l}]=C;l.state.toolCall[p.id].status=r,a?.(...C)};return{name:"tool",...M,onTurnStart:C=>{let{messages:p}=C;return y&&me(p,i),d&&he(p,d,A,w),M.onTurnStart?.(C)},onBeforeRequest:async C=>{let{messages:p,requestBody:r}=C;d===!0&&(r.messages=p.filter(g=>!g[w]));let l=await t?.();return l&&l.length>0&&(r.tools=l),M.onBeforeRequest?.(C)},onAfterRequest:async C=>{let{currentMessage:p,lastChoice:r,appendMessage:l,abortSignal:g,setRequestState:f,requestNext:x}=C;if(r?.finish_reason!=="tool_calls"||!p.tool_calls?.length)return;d&&(p[A]=!0),f("processing","calling-tools"),await n?.(p.tool_calls,{...C,currentMessage:p});let E=p.tool_calls.map(async S=>{let D=Math.floor(Date.now()/1e3),O=(0,se.reactive)({role:"tool",tool_call_id:S.id,content:"",metadata:{createdAt:D,updatedAt:D}});l(O);let c={...C,primaryMessage:p,toolMessage:O};v(S,c);try{let h=s(S,c),b=W(h);for await(let _ of b){if(typeof _=="string")O.content+=_;else{let m={};try{m=JSON.parse(O.content||"{}")}catch(R){console.warn(R)}O.content=JSON.stringify(G(m,_))}O.metadata.updatedAt=Math.floor(Date.now()/1e3)}T(S,{...c,status:"success"})}catch(h){let b=h instanceof Error?h:new Error(String(h));if(g.aborted){T(S,{...c,status:"cancelled",error:b});return}console.error(h),O.content.length===0&&(O.content=u),T(S,{...c,status:"failed",error:b})}});return await Promise.all(E),x(),M.onAfterRequest?.(C)},onCompletionChunk:C=>{var r,l,g;let{currentMessage:p}=C;if(Array.isArray(p.tool_calls))for(let f of p.tool_calls)p.state?.toolCall?.[f.id]?.status||(p.state??(p.state={}),(r=p.state).toolCall??(r.toolCall={}),(l=p.state.toolCall)[g=f.id]??(l[g]={}));return M.onCompletionChunk?.(C)}}};var Ce=e=>{let t=[];for(let n of e){if(n.name){let s=t.findIndex(o=>o.name===n.name);s!==-1&&t.splice(s,1)}t.push(n)}return t},L=e=>{let{initialMessages:t=[],requestMessageFields:n=["role","content","tool_calls","tool_call_id"],plugins:s=[],onCompletionChunk:o}=e,a=(0,q.ref)("idle"),i=(0,q.ref)(void 0),u=(0,q.ref)(t),y=(0,q.ref)(e.responseProvider),d=null,M=[],A={},w=[J(),$(),X()],v=Ce(w.concat(s)),T=(0,q.computed)(()=>a.value==="processing"),C=async c=>{if(!c||!c.trim()){console.warn("Cannot send empty message");return}if(T.value){console.warn("Cannot send message while processing is in progress");return}let h=Math.floor(Date.now()/1e3);u.value.push({role:"user",content:c.trim(),metadata:{createdAt:h,updatedAt:h}}),M.push(u.value[u.value.length-1]),await E()},p=async(...c)=>{if(T.value){console.warn("Cannot send message while processing is in progress");return}u.value.push(...c),M.push(...c),await E()},r=c=>c.map(h=>ne(h,n)),l=(c,h)=>{a.value=c,c==="processing"?i.value=h||"requesting":i.value=void 0},g=c=>{Object.assign(A,c)},f=()=>({messages:u.value,currentTurn:M,requestState:a.value,processingState:i.value,requestMessageFields:n,plugins:v,setRequestState:l,customContext:A,setCustomContext:g}),x=async(c,h)=>{l("processing","requesting");let b=new Proxy({messages:r(u.value)},{set(k,P,I){return P==="messages"?(k.messages=r(I),!0):(k[P]=I,!0)}}),_=f();for(let k of v.filter(P=>!P.disabled))await k.onBeforeRequest?.({..._,abortSignal:h,requestBody:b});let m=(0,q.reactive)({role:"",content:"",loading:!0});O(m);let R,V=c(b,h),U=W(V);for await(let k of U){l("processing","completing"),m.loading&&(m.loading=void 0);let P=k.choices?.find(N=>N.index===0);if(P){R=P;let N=()=>{m.metadata||(m.metadata={});let{created:j,...ie}=k;m.metadata.createdAt=j,m.metadata.updatedAt=Math.floor(Date.now()/1e3),Object.assign(m.metadata,ie),G(m,P.message||P.delta)};if(o){let j=f();o({...j,abortSignal:h,chunk:k,currentMessage:m},N)}else N()}let I=f();for(let N of v.filter(j=>!j.disabled))N.onCompletionChunk?.({...I,abortSignal:h,chunk:k,choice:P,currentMessage:m})}await D(m,c,h,R)},E=async()=>{let c=new AbortController;d=c;let h=y.value;A={};try{l("processing","requesting");let b=f();for(let m of v.filter(R=>!R.disabled))await m.onTurnStart?.({...b,abortSignal:c.signal});try{await x(h,c.signal),l("completed")}catch(m){if(c.signal.aborted||m instanceof B||m instanceof Error&&m.name==="AbortError")l("aborted");else throw m}let _=f();for(let m of v.filter(R=>!R.disabled))await m.onTurnEnd?.({..._,abortSignal:c.signal})}catch(b){l("error");let _=f();for(let m of v.filter(R=>!R.disabled))m.onError?.({..._,abortSignal:c.signal,error:b});throw b}finally{d=null,M.slice(-1)[0]&&(M.slice(-1)[0].loading=void 0),M=[]}},S=async()=>{d?.abort(),T.value&&await new Promise(c=>{let h=(0,q.watch)(T,b=>{b||(h(),c())},{immediate:!0})})},D=async(c,h,b,_)=>{let m=!1,R=f(),V=v.filter(U=>!U.disabled).map(U=>{if(!U.onAfterRequest)return null;let k=I=>{O(I)},P=()=>{m=!0};return U.onAfterRequest({...R,abortSignal:b,currentMessage:c,lastChoice:_,appendMessage:k,requestNext:P})}).filter(U=>U!==null);await te(Promise.all(V),b),m&&await x(h,b)},O=c=>{let h=Array.isArray(c)?c:[c];u.value.push(...h),M.push(...h)};return{requestState:a,processingState:i,messages:u,responseProvider:y,isProcessing:T,sendMessage:C,send:p,abortRequest:S}};var H=require("vue");function ae(e,t=200,n=!1,s=!0,o=!1){return Me(ve(t,n,s,o),e)}function Me(e,t){function n(...s){return new Promise((o,a)=>{Promise.resolve(e(()=>t.apply(this,s),{fn:t,thisArg:this,args:s})).then(o).catch(a)})}return n}var re=()=>{};function ve(...e){let t=0,n,s=!0,o=re,a,i,u,y,d;!(0,H.isRef)(e[0])&&typeof e[0]=="object"?{delay:i,trailing:u=!0,leading:y=!0,rejectOnCancel:d=!1}=e[0]:[i,u=!0,y=!0,d=!1]=e;let M=()=>{n&&(clearTimeout(n),n=void 0,o(),o=re)};return w=>{let v=(0,H.toValue)(i),T=Date.now()-t,C=()=>a=w();return M(),v<=0?(t=Date.now(),C()):(T>v?(t=Date.now(),(y||!s)&&C()):u&&(a=new Promise((p,r)=>{o=d?r:p,n=setTimeout(()=>{t=Date.now(),s=!0,p(C()),M()},Math.max(0,v-T))})),!y&&!n&&(n=setTimeout(()=>s=!0,v)),s=!1,a)}}var be=e=>{let t=(0,F.ref)([]),n=new Map,s=new Map,o=(0,F.ref)(null),a=(0,F.computed)(()=>{let r=o.value;if(!r)return null;let l=t.value.find(f=>f.id===r);if(!l)return null;let g=n.get(r);return g?{...l,engine:g}:null}),i=r=>{if(!e.storage?.saveMessages)return;let l=r||o.value,g=t.value.find(x=>x.id===l);if(!g)return;g.updatedAt=Date.now(),e.storage?.saveConversation?.(g);let f=n.get(g.id);f&&e.storage.saveMessages(g.id,f.messages.value)},u=(r,l)=>{if(!e.autoSaveMessages||!e.storage?.saveMessages)return;let g=s.get(r);g&&g();let f=e.autoSaveThrottle??1e3,x=ae(()=>{i(r)},f,!0,!0),E=(0,F.watch)(l.messages,x,{deep:!0});s.set(r,E)},y=r=>{let l=s.get(r);l&&(l(),s.delete(r))};e.storage?.loadConversations&&Promise.resolve(e.storage.loadConversations()).then(r=>{t.value=r}).catch(r=>{console.error("[useConversation] loadConversations failed:",r)});let d=async(r,l)=>{let g=n.get(r);if(g)return g;let f=l?.initialMessages??e.useMessageOptions.initialMessages??[];if(e.storage?.loadMessages)try{f=await e.storage.loadMessages(r)}catch(E){console.error("[useConversation] loadMessages failed:",E)}let x=L({...e.useMessageOptions,...l,initialMessages:f});return n.set(r,x),u(r,x),x};function M(){return Date.now().toString(36)+Math.random().toString(36).substring(2,9)}let A=r=>{let{id:l=M(),title:g,metadata:f,useMessageOptions:x}=r||{},E=Date.now(),S={id:l,title:g,createdAt:E,updatedAt:E,metadata:f};t.value.unshift(S);let D=L({...e.useMessageOptions,...x});return n.set(l,D),u(l,D),e.storage?.saveConversation?.(S),e.storage?.saveMessages?.(l,D.messages.value),o.value=l,a.value},w=async r=>r?o.value===r?a.value:t.value.find(g=>g.id===r)?(await d(r),n.forEach((g,f)=>{if(f===r)return;g.isProcessing?.value||(y(f),n.delete(f))}),o.value=r,a.value):null:null;return{conversations:t,activeConversationId:o,activeConversation:a,createConversation:A,switchConversation:w,deleteConversation:async r=>{let l=t.value.findIndex(f=>f.id===r);if(l===-1)return;if(await n.get(r)?.abortRequest(),y(r),n.delete(r),t.value.splice(l,1),e.storage?.deleteConversation?.(r),o.value===r){let f=t.value[0];f?await w(f.id):o.value=null}},updateConversationTitle:(r,l)=>{let g=t.value.find(f=>f.id===r);g&&(g.title=l,g.updatedAt=Date.now(),e.storage?.saveConversation?.(g))},saveMessages:i,sendMessage:r=>{a.value?.engine.sendMessage(r)},abortActiveRequest:async()=>{await a.value?.engine.abortRequest()}}};0&&(module.exports={EXCLUDE_MODE_REMOVE,createSSEStreamGenerator,fallbackRolePlugin,lengthPlugin,thinkingPlugin,toolPlugin,useConversation,useMessage});
|
|
1
|
+
"use strict";var J=Object.defineProperty;var ge=Object.getOwnPropertyDescriptor;var fe=Object.getOwnPropertyNames;var de=Object.prototype.hasOwnProperty;var pe=(e,t)=>{for(var n in t)J(e,n,{get:t[n],enumerable:!0})},me=(e,t,n,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of fe(t))!de.call(e,o)&&o!==n&&J(e,o,{get:()=>t[o],enumerable:!(s=ge(t,o))||s.enumerable});return e};var he=e=>me(J({},"__esModule",{value:!0}),e);var Ae={};pe(Ae,{EXCLUDE_MODE_REMOVE:()=>ie,createSSEStreamGenerator:()=>ee,fallbackRolePlugin:()=>$,lengthPlugin:()=>Q,thinkingPlugin:()=>Y,toolPlugin:()=>ve,useConversation:()=>xe,useMessage:()=>H});module.exports=he(Ae);function X(e="The operation was aborted"){let t=new Error(e);return t.name="AbortError",t}async function*ee(e,t={}){let n=e.body?.getReader();if(!n)throw new Error("ReadableStream not supported");let{signal:s}=t,o=new TextDecoder,a="",i=()=>{n.cancel()};s?.addEventListener("abort",i);try{for(;;){if(s?.aborted)throw X();let p;try{p=await n.read()}catch(x){throw s?.aborted?X():x}let{done:g,value:f}=p;if(g){if(s?.aborted)throw X();return}let v=o.decode(f,{stream:!0});a+=v;let w=a.split(`
|
|
2
|
+
`);a=w.pop()||"";for(let x of w)if(x.trim()!==""&&x.startsWith("data: ")){let S=x.slice(6);if(S==="[DONE]")return;try{yield JSON.parse(S)}catch(b){console.warn("Failed to parse SSE data:",S,b)}}}}finally{s?.removeEventListener("abort",i),n.releaseLock()}}var N=require("vue");var q=require("vue");var $=(e={})=>{let{fallbackRole:t="assistant",...n}=e;return{name:"fallbackRole",...n,onBeforeRequest(s){let{requestBody:o,messages:a}=s;return o.messages=a.map(i=>({...i,role:i.role||t})),n.onBeforeRequest?.(s)}}};var Q=(e={})=>{let{continueContent:t="Please continue with your previous answer.",...n}=e;return{name:"length",...n,onAfterRequest:async s=>{let{lastChoice:o,appendMessage:a,requestNext:i}=s;return o?.finish_reason==="length"&&(a({role:"user",content:t}),i()),n.onAfterRequest?.(s)}}};var Y=(e={})=>({name:"thinking",...e,onCompletionChunk(t){let{choice:n,currentMessage:s}=t,a=typeof(n?.message?.reasoning_content||n?.delta?.reasoning_content)=="string";return s.state?s.state.thinking=a:s.state={thinking:a},e.onCompletionChunk?.(t)},onTurnEnd(t){let n=t.currentTurn.slice(-1)[0];return n?.state&&(n.state.thinking=void 0),e.onTurnEnd?.(t)}});var ae=require("vue");var j=class extends Error{constructor(t){super(t),this.name="AbortError"}};function ye(e){if(e.aborted)return{promise:Promise.reject(new j(String(e.reason??"Aborted"))),cleanup:()=>{}};let t=null;return{promise:new Promise((o,a)=>{t=()=>{a(new j(String(e.reason??"Aborted")))},e.addEventListener("abort",t,{once:!0})}),cleanup:()=>{t&&(e.removeEventListener("abort",t),t=null)}}}function se(e,t){let{promise:n,cleanup:s}=ye(t);return Promise.race([e,n]).finally(s)}function oe(e,t){let n={};for(let s in e)t.includes(s)&&(n[s]=e[s]);return n}function re(e,t){let n={};for(let s in e)t.includes(s)||(n[s]=e[s]);return n}async function*L(e){if(te(e)){yield*e;return}let t=await e;if(te(t)){yield*t;return}yield t}function te(e){return e&&typeof e=="object"&&typeof e[Symbol.asyncIterator]=="function"}var Z=e=>typeof e=="object"&&e!==null,ne=e=>Z(e)&&typeof e.index=="number",W=(e,t)=>{for(let[n,s]of Object.entries(t)){let o=e[n];if(o)if(typeof o=="string"&&typeof s=="string")n==="type"&&o||(e[n]=o+s);else if(Array.isArray(o)&&Array.isArray(s))if(o.every(a=>ne(a))&&s.every(a=>ne(a))){let a=new Map(o.map(f=>[f.index,f])),i=new Map(s.map(f=>[f.index,f]));for(let[f,v]of i)if(a.has(f)){let w=a.get(f);a.set(f,W(w,v))}else a.set(f,v);let p=Math.max(...Array.from(a.keys()),-1)+1,g=p>o.length?Array.from({length:p}):o;for(let[f,v]of a)g[f]=v;e[n]=g}else e[n]=[...o,...s];else Z(o)&&Z(s)&&(e[n]=W(o,s));else e[n]=s}return e};function Ce(e,t){let n=[];for(let s=0;s<e.length;s++){let o=e[s];if(o.role==="assistant"&&o.tool_calls&&o.tool_calls.length>0){let a=new Set(o.tool_calls.map(g=>g.id)),i=new Set;for(let g=s+1;g<e.length;g++){let f=e[g];f.role==="tool"&&f.tool_call_id&&a.has(f.tool_call_id)&&i.add(f.tool_call_id)}let p=o.tool_calls.map(g=>g.id).filter(g=>!i.has(g));p.length>0&&n.push({insertAfterIndex:s,missingToolCallIds:p})}}for(let s=n.length-1;s>=0;s--){let{insertAfterIndex:o,missingToolCallIds:a}=n[s],i=a.map(p=>({role:"tool",tool_call_id:p,content:t}));e.splice(o+1,0,...i)}}var ie="remove";function Me(e,t,n,s){let o=e.filter(i=>i[n]),a=new Set(o.flatMap(i=>i.tool_calls?.map(p=>p.id)??[]));if(t===ie)for(let i=e.length-1;i>=0;i--){let p=e[i];(p[n]||p[s]||p.tool_call_id&&a.has(p.tool_call_id))&&e.splice(i,1)}else if(t===!0)for(let i of e)(i[n]||i.tool_call_id&&a.has(i.tool_call_id))&&(i[s]=!0,delete i[n])}var ve=e=>{let{getTools:t,beforeCallTools:n,callTool:s,onToolCallStart:o,onToolCallEnd:a,toolCallCancelledContent:i="Tool call cancelled.",toolCallFailedContent:p="Tool call failed.",autoFillMissingToolMessages:g=!1,excludeToolMessagesNextTurn:f=!1,...v}=e,w=Symbol("doNotSendNextTurn"),x=Symbol("doNotSend"),S=(...m)=>{let[h,{primaryMessage:A}]=m;A.state.toolCall[h.id].status="running",o?.(...m)},b=(...m)=>{let[h,{status:A,primaryMessage:r}]=m;r.state.toolCall[h.id].status=A,a?.(...m)};return{name:"tool",...v,onTurnStart:m=>{let{messages:h}=m;return g&&Ce(h,i),f&&Me(h,f,w,x),v.onTurnStart?.(m)},onBeforeRequest:async m=>{let{messages:h,requestBody:A}=m;f===!0&&(A.messages=h.filter(c=>!c[x]));let r=await t?.();return r&&r.length>0&&(A.tools=r),v.onBeforeRequest?.(m)},onAfterRequest:async m=>{let{currentMessage:h,lastChoice:A,appendMessage:r,abortSignal:c,setRequestState:d,requestNext:y}=m;if(A?.finish_reason!=="tool_calls"||!h.tool_calls?.length)return;f&&(h[w]=!0),d("processing","calling-tools"),await n?.(h.tool_calls,{...m,currentMessage:h});let T=h.tool_calls.map(async R=>{let D=Math.floor(Date.now()/1e3),E=(0,ae.reactive)({role:"tool",tool_call_id:R.id,content:"",metadata:{createdAt:D,updatedAt:D}});r(E);let I={...m,primaryMessage:h,toolMessage:E};S(R,I);try{let F=s(R,I),l=L(F);for await(let u of l){if(typeof u=="string")E.content+=u;else{let M={};try{M=JSON.parse(E.content||"{}")}catch(P){console.warn(P)}E.content=JSON.stringify(W(M,u))}E.metadata.updatedAt=Math.floor(Date.now()/1e3)}b(R,{...I,status:"success"})}catch(F){let l=F instanceof Error?F:new Error(String(F));if(c.aborted){b(R,{...I,status:"cancelled",error:l});return}console.error(F),E.content.length===0&&(E.content=p),b(R,{...I,status:"failed",error:l})}});return await Promise.all(T),y(),v.onAfterRequest?.(m)},onCompletionChunk:m=>{var A,r,c;let{currentMessage:h}=m;if(Array.isArray(h.tool_calls))for(let d of h.tool_calls)h.state?.toolCall?.[d.id]?.status||(h.state??(h.state={}),(A=h.state).toolCall??(A.toolCall={}),(r=h.state.toolCall)[c=d.id]??(r[c]={}));return v.onCompletionChunk?.(m)}}};var Te=e=>{let t=[];for(let n of e){if(n.name){let s=t.findIndex(o=>o.name===n.name);s!==-1&&t.splice(s,1)}t.push(n)}return t},H=e=>{let{initialMessages:t=[],requestMessageFields:n=[],requestMessageFieldsExclude:s=["state","metadata","loading"],plugins:o=[],onCompletionChunk:a}=e,i=(0,q.ref)("idle"),p=(0,q.ref)(void 0),g=(0,q.ref)(t),f=(0,q.ref)(e.responseProvider),v=null,w=[],x={},S=[$(),Y(),Q()],b=Te(S.concat(o)),m=(0,q.computed)(()=>i.value==="processing"),h=async l=>{if(!l||!l.trim()){console.warn("Cannot send empty message");return}if(m.value){console.warn("Cannot send message while processing is in progress");return}let u=Math.floor(Date.now()/1e3);g.value.push({role:"user",content:l.trim(),metadata:{createdAt:u,updatedAt:u}}),w.push(g.value[g.value.length-1]),await D()},A=async(...l)=>{if(m.value){console.warn("Cannot send message while processing is in progress");return}g.value.push(...l),w.push(...l),await D()},r=l=>{let u=l;return n.length&&(u=u.map(M=>oe(M,n))),s.length&&(u=u.map(M=>re(M,s))),u},c=(l,u)=>{i.value=l,l==="processing"?p.value=u||"requesting":p.value=void 0},d=l=>{Object.assign(x,l)},y=l=>({messages:g.value,currentTurn:w,requestState:i.value,processingState:p.value,plugins:b,abortSignal:l,setRequestState:c,customContext:x,setCustomContext:d}),T=(l,u)=>typeof l.disabled=="function"?l.disabled(u):!!l.disabled,R=async(l,u)=>{c("processing","requesting");let M=new Proxy({messages:r(g.value)},{set(_,O,B){return O==="messages"?(_.messages=r(B),!0):(_[O]=B,!0)}}),P=y(u);for(let _ of b.filter(O=>!T(O,P)))await _.onBeforeRequest?.({...P,requestBody:M});let C=(0,q.reactive)({role:"",content:"",loading:!0});F(C);let k,z=l(M,u),U=L(z);for await(let _ of U){c("processing","completing"),C.loading&&(C.loading=void 0);let O=_.choices?.find(G=>G.index===0);if(O){k=O;let G=()=>{C.metadata||(C.metadata={});let{created:K,...ue}=_;C.metadata.createdAt=K,C.metadata.updatedAt=Math.floor(Date.now()/1e3),Object.assign(C.metadata,ue),W(C,O.message||O.delta)};if(a){let K=y(u);a({...K,chunk:_,choice:O,currentMessage:C},G)}else G()}let B=y(u);for(let G of b.filter(K=>!T(K,B)))G.onCompletionChunk?.({...B,abortSignal:u,chunk:_,choice:O,currentMessage:C})}await I(C,l,u,k)},D=async()=>{let l=new AbortController;v=l,x={};try{c("processing","requesting");let u=y(l.signal);for(let C of b.filter(k=>!T(k,u)))await C.onTurnStart?.(u);let M=f.value;try{await R(M,l.signal),c("completed")}catch(C){if(l.signal.aborted||C instanceof j||C instanceof Error&&C.name==="AbortError")c("aborted");else throw C}let P=y(l.signal);for(let C of b.filter(k=>!T(k,P)))await C.onTurnEnd?.(P)}catch(u){c("error");let M=!1,P=y(l.signal);for(let C of b.filter(k=>!T(k,P)))M=!0,C.onError?.({...P,error:u});if(!M)throw u}finally{let u=y(l.signal);for(let M of b.filter(P=>!T(P,u)))try{M.onFinally?.(u)}catch(P){console.error(`Error in onFinally hook for plugin ${M.name||"Anonymous"}:`,P)}v=null,w.slice(-1)[0]&&(w.slice(-1)[0].loading=void 0),w=[]}},E=async()=>{v?.abort(),m.value&&await new Promise(l=>{let u=(0,q.watch)(m,M=>{M||(u(),l())},{immediate:!0})})},I=async(l,u,M,P)=>{let C=!1,k=y(M),z=b.filter(U=>!T(U,k)).map(U=>{if(!U.onAfterRequest)return null;let _=B=>{F(B)},O=()=>{C=!0};return U.onAfterRequest({...k,currentMessage:l,lastChoice:P,appendMessage:_,requestNext:O})}).filter(U=>U!==null);await se(Promise.all(z),M),C&&await R(u,M)},F=l=>{let u=Array.isArray(l)?l:[l];g.value.push(...u),w.push(...u)};return{requestState:i,processingState:p,messages:g,responseProvider:f,isProcessing:m,sendMessage:h,send:A,abortRequest:E}};var V=require("vue");function ce(e,t=200,n=!1,s=!0,o=!1){return be(we(t,n,s,o),e)}function be(e,t){function n(...s){return new Promise((o,a)=>{Promise.resolve(e(()=>t.apply(this,s),{fn:t,thisArg:this,args:s})).then(o).catch(a)})}return n}var le=()=>{};function we(...e){let t=0,n,s=!0,o=le,a,i,p,g,f;!(0,V.isRef)(e[0])&&typeof e[0]=="object"?{delay:i,trailing:p=!0,leading:g=!0,rejectOnCancel:f=!1}=e[0]:[i,p=!0,g=!0,f=!1]=e;let v=()=>{n&&(clearTimeout(n),n=void 0,o(),o=le)};return x=>{let S=(0,V.toValue)(i),b=Date.now()-t,m=()=>a=x();return v(),S<=0?(t=Date.now(),m()):(b>S?(t=Date.now(),(g||!s)&&m()):p&&(a=new Promise((h,A)=>{o=f?A:h,n=setTimeout(()=>{t=Date.now(),s=!0,h(m()),v()},Math.max(0,S-b))})),!g&&!n&&(n=setTimeout(()=>s=!0,S)),s=!1,a)}}var xe=e=>{let t=(0,N.ref)([]),n=new Map,s=new Map,o=(0,N.ref)(null),a=(0,N.computed)(()=>{let r=o.value;if(!r)return null;let c=t.value.find(y=>y.id===r);if(!c)return null;let d=n.get(r);return d?{...c,engine:d}:null}),i=r=>{if(!e.storage?.saveMessages)return;let c=r||o.value,d=t.value.find(T=>T.id===c);if(!d)return;d.updatedAt=Date.now(),e.storage?.saveConversation?.(d);let y=n.get(d.id);y&&e.storage.saveMessages(d.id,y.messages.value)},p=(r,c)=>{if(!e.autoSaveMessages||!e.storage?.saveMessages)return;let d=s.get(r);d&&d();let y=e.autoSaveThrottle??1e3,T=ce(()=>{i(r)},y,!0,!0),R=(0,N.watch)(c.messages,T,{deep:!0});s.set(r,R)},g=r=>{let c=s.get(r);c&&(c(),s.delete(r))};e.storage?.loadConversations&&Promise.resolve(e.storage.loadConversations()).then(r=>{t.value=r}).catch(r=>{console.error("[useConversation] loadConversations failed:",r)});let f=async(r,c)=>{let d=n.get(r);if(d)return d;let y=c?.initialMessages??e.useMessageOptions.initialMessages??[];if(e.storage?.loadMessages)try{y=await e.storage.loadMessages(r)}catch(R){console.error("[useConversation] loadMessages failed:",R)}let T=H({...e.useMessageOptions,...c,initialMessages:y});return n.set(r,T),p(r,T),T};function v(){return Date.now().toString(36)+Math.random().toString(36).substring(2,9)}let w=r=>{let{id:c=v(),title:d,metadata:y,useMessageOptions:T}=r||{},R=Date.now(),D={id:c,title:d,createdAt:R,updatedAt:R,metadata:y};t.value.unshift(D);let E=H({...e.useMessageOptions,...T});return n.set(c,E),p(c,E),e.storage?.saveConversation?.(D),e.storage?.saveMessages?.(c,E.messages.value),o.value=c,a.value},x=r=>{let{excludeId:c}=r||{};n.forEach((d,y)=>{if(c&&y===c)return;d.isProcessing?.value||(g(y),n.delete(y))})};return{conversations:t,activeConversationId:o,activeConversation:a,createConversation:w,switchConversation:async r=>r?o.value===r?a.value:t.value.find(d=>d.id===r)?(await f(r),x({excludeId:r}),o.value=r,a.value):null:null,deleteConversation:async r=>{let c=t.value.findIndex(y=>y.id===r);if(c===-1)return;await n.get(r)?.abortRequest(),g(r),n.delete(r),t.value.splice(c,1),e.storage?.deleteConversation?.(r),o.value===r&&(o.value=null,x())},updateConversationTitle:(r,c)=>{let d=t.value.find(y=>y.id===r);d&&(d.title=c,d.updatedAt=Date.now(),e.storage?.saveConversation?.(d))},saveMessages:i,sendMessage:r=>{a.value?.engine.sendMessage(r)},abortActiveRequest:async()=>{await a.value?.engine.abortRequest()}}};0&&(module.exports={EXCLUDE_MODE_REMOVE,createSSEStreamGenerator,fallbackRolePlugin,lengthPlugin,thinkingPlugin,toolPlugin,useConversation,useMessage});
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function
|
|
2
|
-
`);a=A.pop()||"";for(let w of A)if(w.trim()!==""&&w.startsWith("data: ")){let v=w.slice(6);if(v==="[DONE]")return;try{yield JSON.parse(v)}catch(T){console.warn("Failed to parse SSE data:",v,T)}}}}finally{s?.removeEventListener("abort",i),t.releaseLock()}}import{computed as ye,ref as te,watch as Ce}from"vue";import{computed as ce,reactive as ue,ref as j,watch as ge}from"vue";var K=(e={})=>{let{fallbackRole:n="assistant",...t}=e;return{name:"fallbackRole",...t,onBeforeRequest(s){let{requestBody:r,messages:a}=s;return r.messages=a.map(i=>({...i,role:i.role||n})),t.onBeforeRequest?.(s)}}};var z=(e={})=>{let{continueContent:n="Please continue with your previous answer.",...t}=e;return{name:"length",...t,onAfterRequest:async s=>{let{lastChoice:r,appendMessage:a,requestNext:i}=s;return r?.finish_reason==="length"&&(a({role:"user",content:n}),i()),t.onAfterRequest?.(s)}}};var J=(e={})=>({name:"thinking",...e,onCompletionChunk(n){let{choice:t,currentMessage:s}=n,a=typeof(t?.message?.reasoning_content||t?.delta?.reasoning_content)=="string";return s.state?s.state.thinking=a:s.state={thinking:a},e.onCompletionChunk?.(n)},onTurnEnd(n){let t=n.currentTurn.slice(-1)[0];return t?.state&&(t.state.thinking=void 0),e.onTurnEnd?.(n)}});import{reactive as re}from"vue";var I=class extends Error{constructor(n){super(n),this.name="AbortError"}};function oe(e){if(e.aborted)return{promise:Promise.reject(new I(String(e.reason??"Aborted"))),cleanup:()=>{}};let n=null;return{promise:new Promise((r,a)=>{n=()=>{a(new I(String(e.reason??"Aborted")))},e.addEventListener("abort",n,{once:!0})}),cleanup:()=>{n&&(e.removeEventListener("abort",n),n=null)}}}function Q(e,n){let{promise:t,cleanup:s}=oe(n);return Promise.race([e,t]).finally(s)}function Y(e,n){let t={};for(let s of n)s in e&&(t[s]=e[s]);return t}async function*G(e){if(X(e)){yield*e;return}let n=await e;if(X(n)){yield*n;return}yield n}function X(e){return e&&typeof e=="object"&&typeof e[Symbol.asyncIterator]=="function"}var H=e=>typeof e=="object"&&e!==null,$=e=>H(e)&&typeof e.index=="number",N=(e,n)=>{for(let[t,s]of Object.entries(n)){let r=e[t];if(r)if(typeof r=="string"&&typeof s=="string")t==="type"&&r||(e[t]=r+s);else if(Array.isArray(r)&&Array.isArray(s))if(r.every(a=>$(a))&&s.every(a=>$(a))){let a=new Map(r.map(d=>[d.index,d])),i=new Map(s.map(d=>[d.index,d]));for(let[d,M]of i)if(a.has(d)){let A=a.get(d);a.set(d,N(A,M))}else a.set(d,M);let u=Math.max(...Array.from(a.keys()),-1)+1,y=u>r.length?Array.from({length:u}):r;for(let[d,M]of a)y[d]=M;e[t]=y}else e[t]=[...r,...s];else H(r)&&H(s)&&(e[t]=N(r,s));else e[t]=s}return e};function ae(e,n){let t=[];for(let s=0;s<e.length;s++){let r=e[s];if(r.role==="assistant"&&r.tool_calls&&r.tool_calls.length>0){let a=new Set(r.tool_calls.map(y=>y.id)),i=new Set;for(let y=s+1;y<e.length;y++){let d=e[y];d.role==="tool"&&d.tool_call_id&&a.has(d.tool_call_id)&&i.add(d.tool_call_id)}let u=r.tool_calls.map(y=>y.id).filter(y=>!i.has(y));u.length>0&&t.push({insertAfterIndex:s,missingToolCallIds:u})}}for(let s=t.length-1;s>=0;s--){let{insertAfterIndex:r,missingToolCallIds:a}=t[s],i=a.map(u=>({role:"tool",tool_call_id:u,content:n}));e.splice(r+1,0,...i)}}var ie="remove";function le(e,n,t,s){let r=e.filter(i=>i[t]),a=new Set(r.flatMap(i=>i.tool_calls?.map(u=>u.id)??[]));if(n===ie)for(let i=e.length-1;i>=0;i--){let u=e[i];(u[t]||u[s]||u.tool_call_id&&a.has(u.tool_call_id))&&e.splice(i,1)}else if(n===!0)for(let i of e)(i[t]||i.tool_call_id&&a.has(i.tool_call_id))&&(i[s]=!0,delete i[t])}var Re=e=>{let{getTools:n,beforeCallTools:t,callTool:s,onToolCallStart:r,onToolCallEnd:a,toolCallCancelledContent:i="Tool call cancelled.",toolCallFailedContent:u="Tool call failed.",autoFillMissingToolMessages:y=!1,excludeToolMessagesNextTurn:d=!1,...M}=e,A=Symbol("doNotSendNextTurn"),w=Symbol("doNotSend"),v=(...C)=>{let[p,{primaryMessage:o}]=C;o.state.toolCall[p.id].status="running",r?.(...C)},T=(...C)=>{let[p,{status:o,primaryMessage:l}]=C;l.state.toolCall[p.id].status=o,a?.(...C)};return{name:"tool",...M,onTurnStart:C=>{let{messages:p}=C;return y&&ae(p,i),d&&le(p,d,A,w),M.onTurnStart?.(C)},onBeforeRequest:async C=>{let{messages:p,requestBody:o}=C;d===!0&&(o.messages=p.filter(g=>!g[w]));let l=await n?.();return l&&l.length>0&&(o.tools=l),M.onBeforeRequest?.(C)},onAfterRequest:async C=>{let{currentMessage:p,lastChoice:o,appendMessage:l,abortSignal:g,setRequestState:f,requestNext:x}=C;if(o?.finish_reason!=="tool_calls"||!p.tool_calls?.length)return;d&&(p[A]=!0),f("processing","calling-tools"),await t?.(p.tool_calls,{...C,currentMessage:p});let E=p.tool_calls.map(async S=>{let q=Math.floor(Date.now()/1e3),O=re({role:"tool",tool_call_id:S.id,content:"",metadata:{createdAt:q,updatedAt:q}});l(O);let c={...C,primaryMessage:p,toolMessage:O};v(S,c);try{let h=s(S,c),b=G(h);for await(let _ of b){if(typeof _=="string")O.content+=_;else{let m={};try{m=JSON.parse(O.content||"{}")}catch(R){console.warn(R)}O.content=JSON.stringify(N(m,_))}O.metadata.updatedAt=Math.floor(Date.now()/1e3)}T(S,{...c,status:"success"})}catch(h){let b=h instanceof Error?h:new Error(String(h));if(g.aborted){T(S,{...c,status:"cancelled",error:b});return}console.error(h),O.content.length===0&&(O.content=u),T(S,{...c,status:"failed",error:b})}});return await Promise.all(E),x(),M.onAfterRequest?.(C)},onCompletionChunk:C=>{var o,l,g;let{currentMessage:p}=C;if(Array.isArray(p.tool_calls))for(let f of p.tool_calls)p.state?.toolCall?.[f.id]?.status||(p.state??(p.state={}),(o=p.state).toolCall??(o.toolCall={}),(l=p.state.toolCall)[g=f.id]??(l[g]={}));return M.onCompletionChunk?.(C)}}};var fe=e=>{let n=[];for(let t of e){if(t.name){let s=n.findIndex(r=>r.name===t.name);s!==-1&&n.splice(s,1)}n.push(t)}return n},V=e=>{let{initialMessages:n=[],requestMessageFields:t=["role","content","tool_calls","tool_call_id"],plugins:s=[],onCompletionChunk:r}=e,a=j("idle"),i=j(void 0),u=j(n),y=j(e.responseProvider),d=null,M=[],A={},w=[K(),J(),z()],v=fe(w.concat(s)),T=ce(()=>a.value==="processing"),C=async c=>{if(!c||!c.trim()){console.warn("Cannot send empty message");return}if(T.value){console.warn("Cannot send message while processing is in progress");return}let h=Math.floor(Date.now()/1e3);u.value.push({role:"user",content:c.trim(),metadata:{createdAt:h,updatedAt:h}}),M.push(u.value[u.value.length-1]),await E()},p=async(...c)=>{if(T.value){console.warn("Cannot send message while processing is in progress");return}u.value.push(...c),M.push(...c),await E()},o=c=>c.map(h=>Y(h,t)),l=(c,h)=>{a.value=c,c==="processing"?i.value=h||"requesting":i.value=void 0},g=c=>{Object.assign(A,c)},f=()=>({messages:u.value,currentTurn:M,requestState:a.value,processingState:i.value,requestMessageFields:t,plugins:v,setRequestState:l,customContext:A,setCustomContext:g}),x=async(c,h)=>{l("processing","requesting");let b=new Proxy({messages:o(u.value)},{set(k,P,U){return P==="messages"?(k.messages=o(U),!0):(k[P]=U,!0)}}),_=f();for(let k of v.filter(P=>!P.disabled))await k.onBeforeRequest?.({..._,abortSignal:h,requestBody:b});let m=ue({role:"",content:"",loading:!0});O(m);let R,W=c(b,h),D=G(W);for await(let k of D){l("processing","completing"),m.loading&&(m.loading=void 0);let P=k.choices?.find(F=>F.index===0);if(P){R=P;let F=()=>{m.metadata||(m.metadata={});let{created:B,...ne}=k;m.metadata.createdAt=B,m.metadata.updatedAt=Math.floor(Date.now()/1e3),Object.assign(m.metadata,ne),N(m,P.message||P.delta)};if(r){let B=f();r({...B,abortSignal:h,chunk:k,currentMessage:m},F)}else F()}let U=f();for(let F of v.filter(B=>!B.disabled))F.onCompletionChunk?.({...U,abortSignal:h,chunk:k,choice:P,currentMessage:m})}await q(m,c,h,R)},E=async()=>{let c=new AbortController;d=c;let h=y.value;A={};try{l("processing","requesting");let b=f();for(let m of v.filter(R=>!R.disabled))await m.onTurnStart?.({...b,abortSignal:c.signal});try{await x(h,c.signal),l("completed")}catch(m){if(c.signal.aborted||m instanceof I||m instanceof Error&&m.name==="AbortError")l("aborted");else throw m}let _=f();for(let m of v.filter(R=>!R.disabled))await m.onTurnEnd?.({..._,abortSignal:c.signal})}catch(b){l("error");let _=f();for(let m of v.filter(R=>!R.disabled))m.onError?.({..._,abortSignal:c.signal,error:b});throw b}finally{d=null,M.slice(-1)[0]&&(M.slice(-1)[0].loading=void 0),M=[]}},S=async()=>{d?.abort(),T.value&&await new Promise(c=>{let h=ge(T,b=>{b||(h(),c())},{immediate:!0})})},q=async(c,h,b,_)=>{let m=!1,R=f(),W=v.filter(D=>!D.disabled).map(D=>{if(!D.onAfterRequest)return null;let k=U=>{O(U)},P=()=>{m=!0};return D.onAfterRequest({...R,abortSignal:b,currentMessage:c,lastChoice:_,appendMessage:k,requestNext:P})}).filter(D=>D!==null);await Q(Promise.all(W),b),m&&await x(h,b)},O=c=>{let h=Array.isArray(c)?c:[c];u.value.push(...h),M.push(...h)};return{requestState:a,processingState:i,messages:u,responseProvider:y,isProcessing:T,sendMessage:C,send:p,abortRequest:S}};import{isRef as de,toValue as pe}from"vue";function ee(e,n=200,t=!1,s=!0,r=!1){return me(he(n,t,s,r),e)}function me(e,n){function t(...s){return new Promise((r,a)=>{Promise.resolve(e(()=>n.apply(this,s),{fn:n,thisArg:this,args:s})).then(r).catch(a)})}return t}var Z=()=>{};function he(...e){let n=0,t,s=!0,r=Z,a,i,u,y,d;!de(e[0])&&typeof e[0]=="object"?{delay:i,trailing:u=!0,leading:y=!0,rejectOnCancel:d=!1}=e[0]:[i,u=!0,y=!0,d=!1]=e;let M=()=>{t&&(clearTimeout(t),t=void 0,r(),r=Z)};return w=>{let v=pe(i),T=Date.now()-n,C=()=>a=w();return M(),v<=0?(n=Date.now(),C()):(T>v?(n=Date.now(),(y||!s)&&C()):u&&(a=new Promise((p,o)=>{r=d?o:p,t=setTimeout(()=>{n=Date.now(),s=!0,p(C()),M()},Math.max(0,v-T))})),!y&&!t&&(t=setTimeout(()=>s=!0,v)),s=!1,a)}}var Be=e=>{let n=te([]),t=new Map,s=new Map,r=te(null),a=ye(()=>{let o=r.value;if(!o)return null;let l=n.value.find(f=>f.id===o);if(!l)return null;let g=t.get(o);return g?{...l,engine:g}:null}),i=o=>{if(!e.storage?.saveMessages)return;let l=o||r.value,g=n.value.find(x=>x.id===l);if(!g)return;g.updatedAt=Date.now(),e.storage?.saveConversation?.(g);let f=t.get(g.id);f&&e.storage.saveMessages(g.id,f.messages.value)},u=(o,l)=>{if(!e.autoSaveMessages||!e.storage?.saveMessages)return;let g=s.get(o);g&&g();let f=e.autoSaveThrottle??1e3,x=ee(()=>{i(o)},f,!0,!0),E=Ce(l.messages,x,{deep:!0});s.set(o,E)},y=o=>{let l=s.get(o);l&&(l(),s.delete(o))};e.storage?.loadConversations&&Promise.resolve(e.storage.loadConversations()).then(o=>{n.value=o}).catch(o=>{console.error("[useConversation] loadConversations failed:",o)});let d=async(o,l)=>{let g=t.get(o);if(g)return g;let f=l?.initialMessages??e.useMessageOptions.initialMessages??[];if(e.storage?.loadMessages)try{f=await e.storage.loadMessages(o)}catch(E){console.error("[useConversation] loadMessages failed:",E)}let x=V({...e.useMessageOptions,...l,initialMessages:f});return t.set(o,x),u(o,x),x};function M(){return Date.now().toString(36)+Math.random().toString(36).substring(2,9)}let A=o=>{let{id:l=M(),title:g,metadata:f,useMessageOptions:x}=o||{},E=Date.now(),S={id:l,title:g,createdAt:E,updatedAt:E,metadata:f};n.value.unshift(S);let q=V({...e.useMessageOptions,...x});return t.set(l,q),u(l,q),e.storage?.saveConversation?.(S),e.storage?.saveMessages?.(l,q.messages.value),r.value=l,a.value},w=async o=>o?r.value===o?a.value:n.value.find(g=>g.id===o)?(await d(o),t.forEach((g,f)=>{if(f===o)return;g.isProcessing?.value||(y(f),t.delete(f))}),r.value=o,a.value):null:null;return{conversations:n,activeConversationId:r,activeConversation:a,createConversation:A,switchConversation:w,deleteConversation:async o=>{let l=n.value.findIndex(f=>f.id===o);if(l===-1)return;if(await t.get(o)?.abortRequest(),y(o),t.delete(o),n.value.splice(l,1),e.storage?.deleteConversation?.(o),r.value===o){let f=n.value[0];f?await w(f.id):r.value=null}},updateConversationTitle:(o,l)=>{let g=n.value.find(f=>f.id===o);g&&(g.title=l,g.updatedAt=Date.now(),e.storage?.saveConversation?.(g))},saveMessages:i,sendMessage:o=>{a.value?.engine.sendMessage(o)},abortActiveRequest:async()=>{await a.value?.engine.abortRequest()}}};export{ie as EXCLUDE_MODE_REMOVE,se as createSSEStreamGenerator,K as fallbackRolePlugin,z as lengthPlugin,J as thinkingPlugin,Re as toolPlugin,Be as useConversation,V as useMessage};
|
|
1
|
+
function H(e="The operation was aborted"){let s=new Error(e);return s.name="AbortError",s}async function*ae(e,s={}){let t=e.body?.getReader();if(!t)throw new Error("ReadableStream not supported");let{signal:n}=s,r=new TextDecoder,a="",i=()=>{t.cancel()};n?.addEventListener("abort",i);try{for(;;){if(n?.aborted)throw H();let p;try{p=await t.read()}catch(x){throw n?.aborted?H():x}let{done:g,value:f}=p;if(g){if(n?.aborted)throw H();return}let v=r.decode(f,{stream:!0});a+=v;let w=a.split(`
|
|
2
|
+
`);a=w.pop()||"";for(let x of w)if(x.trim()!==""&&x.startsWith("data: ")){let S=x.slice(6);if(S==="[DONE]")return;try{yield JSON.parse(S)}catch(b){console.warn("Failed to parse SSE data:",S,b)}}}}finally{n?.removeEventListener("abort",i),t.releaseLock()}}import{computed as ve,ref as oe,watch as Te}from"vue";import{computed as fe,reactive as de,ref as K,watch as pe}from"vue";var J=(e={})=>{let{fallbackRole:s="assistant",...t}=e;return{name:"fallbackRole",...t,onBeforeRequest(n){let{requestBody:r,messages:a}=n;return r.messages=a.map(i=>({...i,role:i.role||s})),t.onBeforeRequest?.(n)}}};var X=(e={})=>{let{continueContent:s="Please continue with your previous answer.",...t}=e;return{name:"length",...t,onAfterRequest:async n=>{let{lastChoice:r,appendMessage:a,requestNext:i}=n;return r?.finish_reason==="length"&&(a({role:"user",content:s}),i()),t.onAfterRequest?.(n)}}};var $=(e={})=>({name:"thinking",...e,onCompletionChunk(s){let{choice:t,currentMessage:n}=s,a=typeof(t?.message?.reasoning_content||t?.delta?.reasoning_content)=="string";return n.state?n.state.thinking=a:n.state={thinking:a},e.onCompletionChunk?.(s)},onTurnEnd(s){let t=s.currentTurn.slice(-1)[0];return t?.state&&(t.state.thinking=void 0),e.onTurnEnd?.(s)}});import{reactive as le}from"vue";var N=class extends Error{constructor(s){super(s),this.name="AbortError"}};function ie(e){if(e.aborted)return{promise:Promise.reject(new N(String(e.reason??"Aborted"))),cleanup:()=>{}};let s=null;return{promise:new Promise((r,a)=>{s=()=>{a(new N(String(e.reason??"Aborted")))},e.addEventListener("abort",s,{once:!0})}),cleanup:()=>{s&&(e.removeEventListener("abort",s),s=null)}}}function Z(e,s){let{promise:t,cleanup:n}=ie(s);return Promise.race([e,t]).finally(n)}function ee(e,s){let t={};for(let n in e)s.includes(n)&&(t[n]=e[n]);return t}function te(e,s){let t={};for(let n in e)s.includes(n)||(t[n]=e[n]);return t}async function*W(e){if(Q(e)){yield*e;return}let s=await e;if(Q(s)){yield*s;return}yield s}function Q(e){return e&&typeof e=="object"&&typeof e[Symbol.asyncIterator]=="function"}var V=e=>typeof e=="object"&&e!==null,Y=e=>V(e)&&typeof e.index=="number",G=(e,s)=>{for(let[t,n]of Object.entries(s)){let r=e[t];if(r)if(typeof r=="string"&&typeof n=="string")t==="type"&&r||(e[t]=r+n);else if(Array.isArray(r)&&Array.isArray(n))if(r.every(a=>Y(a))&&n.every(a=>Y(a))){let a=new Map(r.map(f=>[f.index,f])),i=new Map(n.map(f=>[f.index,f]));for(let[f,v]of i)if(a.has(f)){let w=a.get(f);a.set(f,G(w,v))}else a.set(f,v);let p=Math.max(...Array.from(a.keys()),-1)+1,g=p>r.length?Array.from({length:p}):r;for(let[f,v]of a)g[f]=v;e[t]=g}else e[t]=[...r,...n];else V(r)&&V(n)&&(e[t]=G(r,n));else e[t]=n}return e};function ce(e,s){let t=[];for(let n=0;n<e.length;n++){let r=e[n];if(r.role==="assistant"&&r.tool_calls&&r.tool_calls.length>0){let a=new Set(r.tool_calls.map(g=>g.id)),i=new Set;for(let g=n+1;g<e.length;g++){let f=e[g];f.role==="tool"&&f.tool_call_id&&a.has(f.tool_call_id)&&i.add(f.tool_call_id)}let p=r.tool_calls.map(g=>g.id).filter(g=>!i.has(g));p.length>0&&t.push({insertAfterIndex:n,missingToolCallIds:p})}}for(let n=t.length-1;n>=0;n--){let{insertAfterIndex:r,missingToolCallIds:a}=t[n],i=a.map(p=>({role:"tool",tool_call_id:p,content:s}));e.splice(r+1,0,...i)}}var ue="remove";function ge(e,s,t,n){let r=e.filter(i=>i[t]),a=new Set(r.flatMap(i=>i.tool_calls?.map(p=>p.id)??[]));if(s===ue)for(let i=e.length-1;i>=0;i--){let p=e[i];(p[t]||p[n]||p.tool_call_id&&a.has(p.tool_call_id))&&e.splice(i,1)}else if(s===!0)for(let i of e)(i[t]||i.tool_call_id&&a.has(i.tool_call_id))&&(i[n]=!0,delete i[t])}var Se=e=>{let{getTools:s,beforeCallTools:t,callTool:n,onToolCallStart:r,onToolCallEnd:a,toolCallCancelledContent:i="Tool call cancelled.",toolCallFailedContent:p="Tool call failed.",autoFillMissingToolMessages:g=!1,excludeToolMessagesNextTurn:f=!1,...v}=e,w=Symbol("doNotSendNextTurn"),x=Symbol("doNotSend"),S=(...m)=>{let[h,{primaryMessage:A}]=m;A.state.toolCall[h.id].status="running",r?.(...m)},b=(...m)=>{let[h,{status:A,primaryMessage:o}]=m;o.state.toolCall[h.id].status=A,a?.(...m)};return{name:"tool",...v,onTurnStart:m=>{let{messages:h}=m;return g&&ce(h,i),f&&ge(h,f,w,x),v.onTurnStart?.(m)},onBeforeRequest:async m=>{let{messages:h,requestBody:A}=m;f===!0&&(A.messages=h.filter(c=>!c[x]));let o=await s?.();return o&&o.length>0&&(A.tools=o),v.onBeforeRequest?.(m)},onAfterRequest:async m=>{let{currentMessage:h,lastChoice:A,appendMessage:o,abortSignal:c,setRequestState:d,requestNext:y}=m;if(A?.finish_reason!=="tool_calls"||!h.tool_calls?.length)return;f&&(h[w]=!0),d("processing","calling-tools"),await t?.(h.tool_calls,{...m,currentMessage:h});let T=h.tool_calls.map(async R=>{let F=Math.floor(Date.now()/1e3),E=le({role:"tool",tool_call_id:R.id,content:"",metadata:{createdAt:F,updatedAt:F}});o(E);let U={...m,primaryMessage:h,toolMessage:E};S(R,U);try{let q=n(R,U),l=W(q);for await(let u of l){if(typeof u=="string")E.content+=u;else{let M={};try{M=JSON.parse(E.content||"{}")}catch(P){console.warn(P)}E.content=JSON.stringify(G(M,u))}E.metadata.updatedAt=Math.floor(Date.now()/1e3)}b(R,{...U,status:"success"})}catch(q){let l=q instanceof Error?q:new Error(String(q));if(c.aborted){b(R,{...U,status:"cancelled",error:l});return}console.error(q),E.content.length===0&&(E.content=p),b(R,{...U,status:"failed",error:l})}});return await Promise.all(T),y(),v.onAfterRequest?.(m)},onCompletionChunk:m=>{var A,o,c;let{currentMessage:h}=m;if(Array.isArray(h.tool_calls))for(let d of h.tool_calls)h.state?.toolCall?.[d.id]?.status||(h.state??(h.state={}),(A=h.state).toolCall??(A.toolCall={}),(o=h.state.toolCall)[c=d.id]??(o[c]={}));return v.onCompletionChunk?.(m)}}};var me=e=>{let s=[];for(let t of e){if(t.name){let n=s.findIndex(r=>r.name===t.name);n!==-1&&s.splice(n,1)}s.push(t)}return s},z=e=>{let{initialMessages:s=[],requestMessageFields:t=[],requestMessageFieldsExclude:n=["state","metadata","loading"],plugins:r=[],onCompletionChunk:a}=e,i=K("idle"),p=K(void 0),g=K(s),f=K(e.responseProvider),v=null,w=[],x={},S=[J(),$(),X()],b=me(S.concat(r)),m=fe(()=>i.value==="processing"),h=async l=>{if(!l||!l.trim()){console.warn("Cannot send empty message");return}if(m.value){console.warn("Cannot send message while processing is in progress");return}let u=Math.floor(Date.now()/1e3);g.value.push({role:"user",content:l.trim(),metadata:{createdAt:u,updatedAt:u}}),w.push(g.value[g.value.length-1]),await F()},A=async(...l)=>{if(m.value){console.warn("Cannot send message while processing is in progress");return}g.value.push(...l),w.push(...l),await F()},o=l=>{let u=l;return t.length&&(u=u.map(M=>ee(M,t))),n.length&&(u=u.map(M=>te(M,n))),u},c=(l,u)=>{i.value=l,l==="processing"?p.value=u||"requesting":p.value=void 0},d=l=>{Object.assign(x,l)},y=l=>({messages:g.value,currentTurn:w,requestState:i.value,processingState:p.value,plugins:b,abortSignal:l,setRequestState:c,customContext:x,setCustomContext:d}),T=(l,u)=>typeof l.disabled=="function"?l.disabled(u):!!l.disabled,R=async(l,u)=>{c("processing","requesting");let M=new Proxy({messages:o(g.value)},{set(_,O,I){return O==="messages"?(_.messages=o(I),!0):(_[O]=I,!0)}}),P=y(u);for(let _ of b.filter(O=>!T(O,P)))await _.onBeforeRequest?.({...P,requestBody:M});let C=de({role:"",content:"",loading:!0});q(C);let k,L=l(M,u),D=W(L);for await(let _ of D){c("processing","completing"),C.loading&&(C.loading=void 0);let O=_.choices?.find(B=>B.index===0);if(O){k=O;let B=()=>{C.metadata||(C.metadata={});let{created:j,...re}=_;C.metadata.createdAt=j,C.metadata.updatedAt=Math.floor(Date.now()/1e3),Object.assign(C.metadata,re),G(C,O.message||O.delta)};if(a){let j=y(u);a({...j,chunk:_,choice:O,currentMessage:C},B)}else B()}let I=y(u);for(let B of b.filter(j=>!T(j,I)))B.onCompletionChunk?.({...I,abortSignal:u,chunk:_,choice:O,currentMessage:C})}await U(C,l,u,k)},F=async()=>{let l=new AbortController;v=l,x={};try{c("processing","requesting");let u=y(l.signal);for(let C of b.filter(k=>!T(k,u)))await C.onTurnStart?.(u);let M=f.value;try{await R(M,l.signal),c("completed")}catch(C){if(l.signal.aborted||C instanceof N||C instanceof Error&&C.name==="AbortError")c("aborted");else throw C}let P=y(l.signal);for(let C of b.filter(k=>!T(k,P)))await C.onTurnEnd?.(P)}catch(u){c("error");let M=!1,P=y(l.signal);for(let C of b.filter(k=>!T(k,P)))M=!0,C.onError?.({...P,error:u});if(!M)throw u}finally{let u=y(l.signal);for(let M of b.filter(P=>!T(P,u)))try{M.onFinally?.(u)}catch(P){console.error(`Error in onFinally hook for plugin ${M.name||"Anonymous"}:`,P)}v=null,w.slice(-1)[0]&&(w.slice(-1)[0].loading=void 0),w=[]}},E=async()=>{v?.abort(),m.value&&await new Promise(l=>{let u=pe(m,M=>{M||(u(),l())},{immediate:!0})})},U=async(l,u,M,P)=>{let C=!1,k=y(M),L=b.filter(D=>!T(D,k)).map(D=>{if(!D.onAfterRequest)return null;let _=I=>{q(I)},O=()=>{C=!0};return D.onAfterRequest({...k,currentMessage:l,lastChoice:P,appendMessage:_,requestNext:O})}).filter(D=>D!==null);await Z(Promise.all(L),M),C&&await R(u,M)},q=l=>{let u=Array.isArray(l)?l:[l];g.value.push(...u),w.push(...u)};return{requestState:i,processingState:p,messages:g,responseProvider:f,isProcessing:m,sendMessage:h,send:A,abortRequest:E}};import{isRef as he,toValue as ye}from"vue";function se(e,s=200,t=!1,n=!0,r=!1){return Ce(Me(s,t,n,r),e)}function Ce(e,s){function t(...n){return new Promise((r,a)=>{Promise.resolve(e(()=>s.apply(this,n),{fn:s,thisArg:this,args:n})).then(r).catch(a)})}return t}var ne=()=>{};function Me(...e){let s=0,t,n=!0,r=ne,a,i,p,g,f;!he(e[0])&&typeof e[0]=="object"?{delay:i,trailing:p=!0,leading:g=!0,rejectOnCancel:f=!1}=e[0]:[i,p=!0,g=!0,f=!1]=e;let v=()=>{t&&(clearTimeout(t),t=void 0,r(),r=ne)};return x=>{let S=ye(i),b=Date.now()-s,m=()=>a=x();return v(),S<=0?(s=Date.now(),m()):(b>S?(s=Date.now(),(g||!n)&&m()):p&&(a=new Promise((h,A)=>{r=f?A:h,t=setTimeout(()=>{s=Date.now(),n=!0,h(m()),v()},Math.max(0,S-b))})),!g&&!t&&(t=setTimeout(()=>n=!0,S)),n=!1,a)}}var We=e=>{let s=oe([]),t=new Map,n=new Map,r=oe(null),a=ve(()=>{let o=r.value;if(!o)return null;let c=s.value.find(y=>y.id===o);if(!c)return null;let d=t.get(o);return d?{...c,engine:d}:null}),i=o=>{if(!e.storage?.saveMessages)return;let c=o||r.value,d=s.value.find(T=>T.id===c);if(!d)return;d.updatedAt=Date.now(),e.storage?.saveConversation?.(d);let y=t.get(d.id);y&&e.storage.saveMessages(d.id,y.messages.value)},p=(o,c)=>{if(!e.autoSaveMessages||!e.storage?.saveMessages)return;let d=n.get(o);d&&d();let y=e.autoSaveThrottle??1e3,T=se(()=>{i(o)},y,!0,!0),R=Te(c.messages,T,{deep:!0});n.set(o,R)},g=o=>{let c=n.get(o);c&&(c(),n.delete(o))};e.storage?.loadConversations&&Promise.resolve(e.storage.loadConversations()).then(o=>{s.value=o}).catch(o=>{console.error("[useConversation] loadConversations failed:",o)});let f=async(o,c)=>{let d=t.get(o);if(d)return d;let y=c?.initialMessages??e.useMessageOptions.initialMessages??[];if(e.storage?.loadMessages)try{y=await e.storage.loadMessages(o)}catch(R){console.error("[useConversation] loadMessages failed:",R)}let T=z({...e.useMessageOptions,...c,initialMessages:y});return t.set(o,T),p(o,T),T};function v(){return Date.now().toString(36)+Math.random().toString(36).substring(2,9)}let w=o=>{let{id:c=v(),title:d,metadata:y,useMessageOptions:T}=o||{},R=Date.now(),F={id:c,title:d,createdAt:R,updatedAt:R,metadata:y};s.value.unshift(F);let E=z({...e.useMessageOptions,...T});return t.set(c,E),p(c,E),e.storage?.saveConversation?.(F),e.storage?.saveMessages?.(c,E.messages.value),r.value=c,a.value},x=o=>{let{excludeId:c}=o||{};t.forEach((d,y)=>{if(c&&y===c)return;d.isProcessing?.value||(g(y),t.delete(y))})};return{conversations:s,activeConversationId:r,activeConversation:a,createConversation:w,switchConversation:async o=>o?r.value===o?a.value:s.value.find(d=>d.id===o)?(await f(o),x({excludeId:o}),r.value=o,a.value):null:null,deleteConversation:async o=>{let c=s.value.findIndex(y=>y.id===o);if(c===-1)return;await t.get(o)?.abortRequest(),g(o),t.delete(o),s.value.splice(c,1),e.storage?.deleteConversation?.(o),r.value===o&&(r.value=null,x())},updateConversationTitle:(o,c)=>{let d=s.value.find(y=>y.id===o);d&&(d.title=c,d.updatedAt=Date.now(),e.storage?.saveConversation?.(d))},saveMessages:i,sendMessage:o=>{a.value?.engine.sendMessage(o)},abortActiveRequest:async()=>{await a.value?.engine.abortRequest()}}};export{ue as EXCLUDE_MODE_REMOVE,ae as createSSEStreamGenerator,J as fallbackRolePlugin,X as lengthPlugin,$ as thinkingPlugin,Se as toolPlugin,We as useConversation,z as useMessage};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opentiny/tiny-robot-kit",
|
|
3
|
-
"version": "0.4.0-alpha.
|
|
3
|
+
"version": "0.4.0-alpha.4",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -26,5 +26,8 @@
|
|
|
26
26
|
"peerDependencies": {
|
|
27
27
|
"vue": ">=3.0.0"
|
|
28
28
|
},
|
|
29
|
-
"
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"idb": "^8.0.3"
|
|
31
|
+
},
|
|
32
|
+
"gitHead": "a25e92bf59065712e7814abb5d31c19ccfd342e0"
|
|
30
33
|
}
|