@opentiny/tiny-robot-kit 0.4.2-alpha.2 → 0.4.2-alpha.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/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var ie=Object.defineProperty;var ke=Object.getOwnPropertyDescriptor;var _e=Object.getOwnPropertyNames;var De=Object.prototype.hasOwnProperty;var Ue=(o,t)=>{for(var e in t)ie(o,e,{get:t[e],enumerable:!0})},qe=(o,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of _e(t))!De.call(o,s)&&s!==e&&ie(o,s,{get:()=>t[s],enumerable:!(n=ke(t,s))||n.enumerable});return o};var Be=o=>qe(ie({},"__esModule",{value:!0}),o);var Ve={};Ue(Ve,{AIClient:()=>Z,BaseModelProvider:()=>H,EXCLUDE_MODE_REMOVE:()=>Pe,ErrorType:()=>fe,IndexedDBStrategy:()=>V,LocalStorageStrategy:()=>G,OpenAIProvider:()=>j,StreamEventType:()=>me,extractTextFromResponse:()=>ye,fallbackRolePlugin:()=>ue,formatMessages:()=>he,handleSSEStream:()=>Y,indexedDBStorageStrategyFactory:()=>be,lengthPlugin:()=>de,localStorageStrategyFactory:()=>te,sseStreamToGenerator:()=>Ce,thinkingPlugin:()=>ge,toolPlugin:()=>je,useConversation:()=>Ge,useMessage:()=>ne});module.exports=Be(Ve);var H=class{constructor(t){this.config=t}updateConfig(t){this.config={...this.config,...t}}getConfig(){return{...this.config}}validateRequest(t){if(!t.messages||!Array.isArray(t.messages)||t.messages.length===0)throw new Error("\u8BF7\u6C42\u5FC5\u987B\u5305\u542B\u81F3\u5C11\u4E00\u6761\u6D88\u606F");for(let e of t.messages)if(!e.role||!e.content)throw new Error("\u6BCF\u6761\u6D88\u606F\u5FC5\u987B\u5305\u542B\u89D2\u8272\u548C\u5185\u5BB9")}};var fe=(c=>(c.NETWORK_ERROR="network_error",c.AUTHENTICATION_ERROR="authentication_error",c.RATE_LIMIT_ERROR="rate_limit_error",c.SERVER_ERROR="server_error",c.MODEL_ERROR="model_error",c.TIMEOUT_ERROR="timeout_error",c.UNKNOWN_ERROR="unknown_error",c))(fe||{}),me=(n=>(n.DATA="data",n.ERROR="error",n.DONE="done",n))(me||{});function K(o){return{type:o.type||"unknown_error",message:o.message||"\u672A\u77E5\u9519\u8BEF",statusCode:o.statusCode,originalError:o.originalError}}function le(o){if(!o.response)return K({type:"network_error",message:"\u7F51\u7EDC\u8FDE\u63A5\u9519\u8BEF\uFF0C\u8BF7\u68C0\u67E5\u60A8\u7684\u7F51\u7EDC\u8FDE\u63A5",originalError:o});if(o.response){let{status:t,data:e}=o.response;return t===401||t===403?K({type:"authentication_error",message:"\u8EAB\u4EFD\u9A8C\u8BC1\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u60A8\u7684API\u5BC6\u94A5",statusCode:t,originalError:o}):t===429?K({type:"rate_limit_error",message:"\u8D85\u51FAAPI\u8C03\u7528\u9650\u5236\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",statusCode:t,originalError:o}):t>=500?K({type:"server_error",message:"\u670D\u52A1\u5668\u9519\u8BEF\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",statusCode:t,originalError:o}):K({type:"unknown_error",message:e?.error?.message||`\u8BF7\u6C42\u5931\u8D25\uFF0C\u72B6\u6001\u7801: ${t}`,statusCode:t,originalError:o})}return o.code==="ECONNABORTED"?K({type:"timeout_error",message:"\u8BF7\u6C42\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",originalError:o}):K({type:"unknown_error",message:o.message||"\u53D1\u751F\u672A\u77E5\u9519\u8BEF",originalError:o})}async function Y(o,t,e){let n=o.body?.getReader();if(!n)throw new Error("Response body is null");let s=new TextDecoder,r="",a,c;e&&e.addEventListener("abort",()=>{n.cancel().catch(d=>console.error("Error cancelling reader:",d))},{once:!0});try{for(;;){if(e?.aborted){await n.cancel();break}let{done:d,value:f}=await n.read();if(d)break;let v=s.decode(f,{stream:!0});r+=v;let R=r.split(`
1
+ "use strict";var ge=Object.defineProperty;var Ne=Object.getOwnPropertyDescriptor;var je=Object.getOwnPropertyNames;var Ke=Object.prototype.hasOwnProperty;var Ve=(s,e)=>{for(var t in e)ge(s,t,{get:e[t],enumerable:!0})},We=(s,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of je(e))!Ke.call(s,n)&&n!==t&&ge(s,n,{get:()=>e[n],enumerable:!(o=Ne(e,n))||o.enumerable});return s};var He=s=>We(ge({},"__esModule",{value:!0}),s);var st={};Ve(st,{AIClient:()=>ae,BaseModelProvider:()=>z,ErrorType:()=>ve,IndexedDBStrategy:()=>J,LocalStorageStrategy:()=>$,OpenAIProvider:()=>W,StreamEventType:()=>Re,extractTextFromResponse:()=>xe,formatMessages:()=>be,handleSSEStream:()=>re,indexedDBStorageStrategyFactory:()=>Ae,lengthPlugin:()=>Ze,localStorageStrategyFactory:()=>le,sseStreamToGenerator:()=>Pe,thinkingPlugin:()=>et,toolPlugin:()=>tt,useConversation:()=>Ye,useMessage:()=>ce});module.exports=He(st);var z=class{constructor(e){this.config=e}updateConfig(e){this.config={...this.config,...e}}getConfig(){return{...this.config}}validateRequest(e){if(!e.messages||!Array.isArray(e.messages)||e.messages.length===0)throw new Error("\u8BF7\u6C42\u5FC5\u987B\u5305\u542B\u81F3\u5C11\u4E00\u6761\u6D88\u606F");for(let t of e.messages)if(!t.role||!t.content)throw new Error("\u6BCF\u6761\u6D88\u606F\u5FC5\u987B\u5305\u542B\u89D2\u8272\u548C\u5185\u5BB9")}};var ve=(u=>(u.NETWORK_ERROR="network_error",u.AUTHENTICATION_ERROR="authentication_error",u.RATE_LIMIT_ERROR="rate_limit_error",u.SERVER_ERROR="server_error",u.MODEL_ERROR="model_error",u.TIMEOUT_ERROR="timeout_error",u.UNKNOWN_ERROR="unknown_error",u))(ve||{}),Re=(o=>(o.DATA="data",o.ERROR="error",o.DONE="done",o))(Re||{});function V(s){return{type:s.type||"unknown_error",message:s.message||"\u672A\u77E5\u9519\u8BEF",statusCode:s.statusCode,originalError:s.originalError}}function pe(s){if(!s.response)return V({type:"network_error",message:"\u7F51\u7EDC\u8FDE\u63A5\u9519\u8BEF\uFF0C\u8BF7\u68C0\u67E5\u60A8\u7684\u7F51\u7EDC\u8FDE\u63A5",originalError:s});if(s.response){let{status:e,data:t}=s.response;return e===401||e===403?V({type:"authentication_error",message:"\u8EAB\u4EFD\u9A8C\u8BC1\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u60A8\u7684API\u5BC6\u94A5",statusCode:e,originalError:s}):e===429?V({type:"rate_limit_error",message:"\u8D85\u51FAAPI\u8C03\u7528\u9650\u5236\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",statusCode:e,originalError:s}):e>=500?V({type:"server_error",message:"\u670D\u52A1\u5668\u9519\u8BEF\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",statusCode:e,originalError:s}):V({type:"unknown_error",message:t?.error?.message||`\u8BF7\u6C42\u5931\u8D25\uFF0C\u72B6\u6001\u7801: ${e}`,statusCode:e,originalError:s})}return s.code==="ECONNABORTED"?V({type:"timeout_error",message:"\u8BF7\u6C42\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",originalError:s}):V({type:"unknown_error",message:s.message||"\u53D1\u751F\u672A\u77E5\u9519\u8BEF",originalError:s})}async function re(s,e,t){let o=s.body?.getReader();if(!o)throw new Error("Response body is null");let n=new TextDecoder,r="",a,u;t&&t.addEventListener("abort",()=>{o.cancel().catch(d=>console.error("Error cancelling reader:",d))},{once:!0});try{for(;;){if(t?.aborted){await o.cancel();break}let{done:d,value:i}=await o.read();if(d)break;let g=n.decode(i,{stream:!0});r+=g;let b=r.split(`
2
2
 
3
- `);r=R.pop()||"";for(let x of R)if(x.trim()!==""){if(x.trim()==="data: [DONE]"){c&&(a=c),t.onDone(a);continue}try{let A=x.match(/^data: (.+)$/m);if(!A)continue;let M=JSON.parse(A[1]);t.onData(M),c=M.choices?.[0]?.finish_reason||void 0}catch(A){console.error("Error parsing SSE message:",A)}}}(r.trim()==="data: [DONE]"||e?.aborted)&&(e?.aborted&&(a="aborted"),t.onDone(a))}catch(d){if(e?.aborted)return;throw d}}function he(o){return o.map(t=>typeof t=="object"&&"role"in t&&"content"in t?{role:t.role,content:String(t.content),...t.name?{name:t.name}:{}}:typeof t=="string"?{role:"user",content:t}:{role:"user",content:String(t)})}function ye(o){return!o.choices||!o.choices.length?"":o.choices[0].message?.content||""}function ce(o="The operation was aborted"){let t=new Error(o);return t.name="AbortError",t}async function*Ce(o,t={}){let e=o.body?.getReader();if(!e)throw new Error("ReadableStream not supported");let{signal:n}=t,s=new TextDecoder,r="",a=()=>{e.cancel()};n?.addEventListener("abort",a);try{for(;;){if(n?.aborted)throw ce();let c;try{c=await e.read()}catch(x){throw n?.aborted?ce():x}let{done:d,value:f}=c;if(d){if(n?.aborted)throw ce();return}let v=s.decode(f,{stream:!0});r+=v;let R=r.split(`
4
- `);r=R.pop()||"";for(let x of R)if(x.trim()!==""&&x.startsWith("data: ")){let A=x.slice(6);if(A==="[DONE]")return;try{yield JSON.parse(A)}catch(M){console.warn("Failed to parse SSE data:",A,M)}}}}finally{n?.removeEventListener("abort",a),e.releaseLock()}}var j=class extends H{constructor(e){super(e);this.defaultModel="gpt-3.5-turbo";this.baseURL=e.apiUrl||"https://api.openai.com/v1",this.apiKey=e.apiKey||"",e.defaultModel&&(this.defaultModel=e.defaultModel),this.apiKey||console.warn("API key is not provided. Authentication will likely fail.")}async chat(e){try{this.validateRequest(e);let n={model:e.options?.model||this.config.defaultModel||this.defaultModel,messages:e.messages,...e.options,stream:!1},s={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)};this.apiKey&&Object.assign(s.headers,{Authorization:`Bearer ${this.apiKey}`});let r=await fetch(`${this.baseURL}/chat/completions`,s);if(!r.ok){let a=await r.text();throw new Error(`HTTP error! status: ${r.status}, details: ${a}`)}return await r.json()}catch(n){throw le(n)}}async chatStream(e,n){let{signal:s,...r}=e.options||{};try{this.validateRequest(e);let a={model:e.options?.model||this.config.defaultModel||this.defaultModel,messages:e.messages,...r,stream:!0},c={method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,Accept:"text/event-stream"},body:JSON.stringify(a),signal:s};this.apiKey&&Object.assign(c.headers,{Authorization:`Bearer ${this.apiKey}`});let d=await fetch(`${this.baseURL}/chat/completions`,c);if(!d.ok){let f=await d.text();throw new Error(`HTTP error! status: ${d.status}, details: ${f}`)}await Y(d,n,s)}catch(a){if(s?.aborted)return;n.onError(le(a))}}updateConfig(e){super.updateConfig(e),e.apiUrl&&(this.baseURL=e.apiUrl),e.apiKey&&(this.apiKey=e.apiKey),e.defaultModel&&(this.defaultModel=e.defaultModel)}};var Z=class{constructor(t){this.config=t,this.provider=this.createProvider(t)}createProvider(t){if(t.provider==="custom"&&"providerImplementation"in t)return t.providerImplementation;if(t.provider==="deepseek"){let e={defaultModel:"deepseek-chat",apiUrl:"https://api.deepseek.com/v1"};return new j({...e,...t})}else return new j(t)}async chat(t){return this.provider.chat(t)}async chatStream(t,e){let n={...t,options:{...t.options,stream:!0}};return this.provider.chatStream(n,e)}getConfig(){return{...this.config}}updateConfig(t){this.config={...this.config,...t},t.provider&&t.provider!==this.config.provider?this.provider=this.createProvider(this.config):this.provider.updateConfig(this.config)}};var ve=require("vue");function X(o,t=new WeakMap){if(o==null||typeof o!="object")return o;try{let e=(0,ve.toRaw)(o);if(t.has(e))return t.get(e);if(Array.isArray(e)){let s=[];return t.set(e,s),s.push(...e.map(r=>X(r,t))),s}if(e instanceof Date||e instanceof RegExp||e instanceof ArrayBuffer||e instanceof Blob)return e;let n={};t.set(e,n);for(let s of Object.keys(e)){let r=Object.getOwnPropertyDescriptor(e,s);if(!r||r.get||r.set)continue;let a=e[s];typeof a!="function"&&typeof a!="symbol"&&(n[s]=X(a,t))}return n}catch(e){return console.warn("unwrapProxy error:",e),Array.isArray(o)?[]:{}}}var ee=o=>o.map(t=>{let{renderContent:e,...n}=t;if(!Array.isArray(e))return t;let s=e.filter(a=>a.type==="collapsible-text"),r=e.filter(a=>a.type==="markdown"||a.type==="text");return s.length>0&&(n.reasoning_content=s.map(a=>a.content).join("")),r.length>0&&(n.content=r.map(a=>a.content).join("")),n});var Q=o=>{let t=localStorage.getItem(o);return t?JSON.parse(t):[]},G=class{constructor(t="tiny-robot-ai-conversations"){this.storageKey=t}saveConversation(t){try{let e=Q(this.storageKey),n=e.findIndex(s=>s.id===t.id);n!==-1?Object.assign(e[n],t):e.unshift({...t,messages:[]}),localStorage.setItem(this.storageKey,JSON.stringify(e))}catch(e){console.error("\u4FDD\u5B58\u4F1A\u8BDD\u5931\u8D25:",e)}}loadConversations(){try{return Q(this.storageKey).map(e=>({id:e.id,title:e.title,createdAt:e.createdAt,updatedAt:e.updatedAt,metadata:e.metadata}))}catch(t){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u5931\u8D25:",t),[]}}saveMessages(t,e){try{let n=Q(this.storageKey),s=n.findIndex(r=>r.id===t);s!==-1&&(n[s].messages=e),localStorage.setItem(this.storageKey,JSON.stringify(n))}catch(n){console.error("\u4FDD\u5B58\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",n)}}loadMessages(t){try{let n=Q(this.storageKey).find(r=>r.id===t);return ee(n?.messages||[])}catch(e){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",e),[]}}deleteConversation(t){let e=Q(this.storageKey),n=e.findIndex(s=>s.id===t);n!==-1&&e.splice(n,1),localStorage.setItem(this.storageKey,JSON.stringify(e))}};var Me=require("idb");var V=class{constructor(t="tiny-robot-ai-db",e=3){this.db=null;this.dbName=t,this.dbVersion=e}async getDB(){return this.db||(this.db=await(0,Me.openDB)(this.dbName,this.dbVersion,{upgrade(t){t.objectStoreNames.contains("conversations")||t.createObjectStore("conversations",{keyPath:"id"}).createIndex("by-updated","updatedAt"),t.objectStoreNames.contains("messages")||t.createObjectStore("messages",{keyPath:"conversationId"})}})),this.db}async loadConversations(){try{return(await(await this.getDB()).getAllFromIndex("conversations","by-updated")).reverse()}catch(t){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u5931\u8D25:",t),[]}}async loadMessages(t){try{let n=await(await this.getDB()).get("messages",t);return n?ee(n.messages):[]}catch(e){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",e),[]}}async saveConversation(t){try{let e=await this.getDB(),n=X(t);await e.put("conversations",n)}catch(e){throw console.error("\u4FDD\u5B58\u4F1A\u8BDD\u5931\u8D25:",e),e}}async saveMessages(t,e){try{let n=await this.getDB(),s=X(e);await n.put("messages",{conversationId:t,messages:s})}catch(n){throw console.error("\u4FDD\u5B58\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",n),n}}async deleteConversation(t){try{let e=await this.getDB();await e.delete("conversations",t),await e.delete("messages",t)}catch(e){throw console.error("\u5220\u9664\u4F1A\u8BDD\u5931\u8D25:",e),e}}};function te(o={}){return new G(o.key||"tiny-robot-ai-conversations")}function be(o={}){return new V(o.dbName||"tiny-robot-ai-db",o.dbVersion||1)}var L=require("vue");var U=require("vue");var ue=(o={})=>{let{fallbackRole:t="assistant",...e}=o;return{name:"fallbackRole",...e,onBeforeRequest(n){let{requestBody:s}=n;return s.messages=s.messages.map(r=>({...r,role:r.role||t})),e.onBeforeRequest?.(n)}}};var de=(o={})=>{let{continueContent:t="Please continue with your previous answer.",...e}=o;return{name:"length",...e,onAfterRequest:async n=>{let{lastChoice:s,appendMessage:r,requestNext:a}=n;return s?.finish_reason==="length"&&(r({role:"user",content:t}),a()),e.onAfterRequest?.(n)}}};var ge=(o={})=>({name:"thinking",...o,onCompletionChunk(t){let{choice:e,currentMessage:n}=t,r=typeof(e?.message?.reasoning_content||e?.delta?.reasoning_content)=="string";return n.state?(n.state.thinking=r,n.state.open=r):n.state={thinking:r,open:r},o.onCompletionChunk?.(t)},onTurnEnd(t){let e=t.currentTurn.slice(-1)[0];return e?.state?.thinking&&(e.state.thinking=!1,e.state.open=!1),o.onTurnEnd?.(t)}});var Se=require("vue");var $=class extends Error{constructor(t){super(t),this.name="AbortError"}};function Ne(o){if(o.aborted)return{promise:Promise.reject(new $(String(o.reason??"Aborted"))),cleanup:()=>{}};let t=null;return{promise:new Promise((s,r)=>{t=()=>{r(new $(String(o.reason??"Aborted")))},o.addEventListener("abort",t,{once:!0})}),cleanup:()=>{t&&(o.removeEventListener("abort",t),t=null)}}}function Ae(o,t){let{promise:e,cleanup:n}=Ne(t);return Promise.race([o,e]).finally(n)}function we(o,t){let e={};for(let n in o)t.includes(n)&&(e[n]=o[n]);return e}function Te(o,t){let e={};for(let n in o)t.includes(n)||(e[n]=o[n]);return e}async function*oe(o){if(Re(o)){yield*o;return}let t=await o;if(Re(t)){yield*t;return}yield t}function Re(o){return o&&typeof o=="object"&&typeof o[Symbol.asyncIterator]=="function"}var pe=o=>typeof o=="object"&&o!==null,xe=o=>pe(o)&&typeof o.index=="number",J=(o,t)=>{for(let[e,n]of Object.entries(t)){let s=o[e];if(s)if(typeof s=="string"&&typeof n=="string")e==="type"&&s||(o[e]=s+n);else if(Array.isArray(s)&&Array.isArray(n))if(s.every(r=>xe(r))&&n.every(r=>xe(r))){let r=new Map(s.map(f=>[f.index,f])),a=new Map(n.map(f=>[f.index,f]));for(let[f,v]of a)if(r.has(f)){let R=r.get(f);r.set(f,J(R,v))}else r.set(f,v);let c=Math.max(...Array.from(r.keys()),-1)+1,d=c>s.length?Array.from({length:c}):s;for(let[f,v]of r)d[f]=v;o[e]=d}else o[e]=[...s,...n];else pe(s)&&pe(n)&&(o[e]=J(s,n));else o[e]=n}return o};function Fe(o,t){let e=[];for(let n=0;n<o.length;n++){let s=o[n];if(s.role==="assistant"&&s.tool_calls&&s.tool_calls.length>0){let r=new Set(s.tool_calls.map(d=>d.id)),a=new Set;for(let d=n+1;d<o.length;d++){let f=o[d];f.role==="tool"&&f.tool_call_id&&r.has(f.tool_call_id)&&a.add(f.tool_call_id)}let c=s.tool_calls.map(d=>d.id).filter(d=>!a.has(d));c.length>0&&e.push({insertAfterIndex:n,missingToolCallIds:c})}}for(let n=e.length-1;n>=0;n--){let{insertAfterIndex:s,missingToolCallIds:r}=e[n],a=r.map(c=>({role:"tool",tool_call_id:c,content:t}));o.splice(s+1,0,...a)}}var Pe="remove";function Ke(o,t,e,n){let s=o.filter(a=>a[e]),r=new Set(s.flatMap(a=>a.tool_calls?.map(c=>c.id)??[]));if(t===Pe)for(let a=o.length-1;a>=0;a--){let c=o[a];(c[e]||c[n]||c.tool_call_id&&r.has(c.tool_call_id))&&o.splice(a,1)}else if(t===!0)for(let a of o)(a[e]||a.tool_call_id&&r.has(a.tool_call_id))&&(a[n]=!0,delete a[e])}var je=o=>{let{getTools:t,beforeCallTools:e,callTool:n,onToolCallStart:s,onToolCallEnd:r,toolCallCancelledContent:a="Tool call cancelled.",toolCallFailedContent:c="Tool call failed.",autoFillMissingToolMessages:d=!1,excludeToolMessagesNextTurn:f=!1,...v}=o,R=Symbol("doNotSendNextTurn"),x=Symbol("doNotSend"),A=(...m)=>{let[h,{primaryMessage:T}]=m;T.state.toolCall[h.id].status="running",s?.(...m)},M=(...m)=>{let[h,{status:T,primaryMessage:O}]=m;O.state.toolCall[h.id].status=T,r?.(...m)};return{name:"tool",...v,onTurnStart:m=>{let{messages:h}=m;return d&&Fe(h,a),f&&Ke(h,f,R,x),v.onTurnStart?.(m)},onBeforeRequest:async m=>{let{messages:h,requestBody:T}=m;f===!0&&(T.messages=h.filter(E=>!E[x]));let O=await t?.();return O&&O.length>0&&(T.tools=O),v.onBeforeRequest?.(m)},onAfterRequest:async m=>{let{currentMessage:h,lastChoice:T,appendMessage:O,abortSignal:E,setRequestState:i,requestNext:l}=m;if(T?.finish_reason!=="tool_calls"||!h.tool_calls?.length)return;f&&(h[R]=!0),i("processing","calling-tools"),await e?.(h.tool_calls,{...m,currentMessage:h});let g=h.tool_calls.map(async y=>{let S=Math.floor(Date.now()/1e3),w=(0,Se.reactive)({role:"tool",tool_call_id:y.id,content:"",metadata:{createdAt:S,updatedAt:S}});O(w);let q={...m,primaryMessage:h,toolMessage:w};A(y,q);try{let k=n(y,q),N=oe(k);for await(let u of N){if(typeof u=="string")w.content+=u;else{let p={};try{p=JSON.parse(w.content||"{}")}catch(b){console.warn(b)}w.content=JSON.stringify(J(p,u))}w.metadata.updatedAt=Math.floor(Date.now()/1e3)}M(y,{...q,status:"success"})}catch(k){let N=k instanceof Error?k:new Error(String(k));if(E.aborted){M(y,{...q,status:"cancelled",error:N});return}console.error(k),w.content.length===0&&(w.content=c),M(y,{...q,status:"failed",error:N})}});return await Promise.all(g),l(),v.onAfterRequest?.(m)},onCompletionChunk:m=>{var T,O,E;let{currentMessage:h}=m;if(Array.isArray(h.tool_calls))for(let i of h.tool_calls)h.state?.toolCall?.[i.id]?.status||(h.state??(h.state={}),(T=h.state).toolCall??(T.toolCall={}),(O=h.state.toolCall)[E=i.id]??(O[E]={}));return v.onCompletionChunk?.(m)}}};var Le=o=>{let t=[];for(let e of o){if(e.name){let n=t.findIndex(s=>s.name===e.name);n!==-1&&t.splice(n,1)}t.push(e)}return t},ne=o=>{let{initialMessages:t=[],requestMessageFields:e=[],requestMessageFieldsExclude:n=["state","metadata","loading"],plugins:s=[],onCompletionChunk:r}=o,a=(0,U.ref)("idle"),c=(0,U.ref)(void 0),d=(0,U.ref)(t),f=(0,U.ref)(o.responseProvider),v=null,R=[],x={},A=[ue(),ge(),de()],M=Le(A.concat(s)),m=(0,U.computed)(()=>a.value==="processing"),h=async u=>{if(!u||!u.trim()){console.warn("Cannot send empty message");return}if(m.value){console.warn("Cannot send message while processing is in progress");return}let p=Math.floor(Date.now()/1e3);d.value.push({role:"user",content:u.trim(),metadata:{createdAt:p,updatedAt:p}}),R.push(d.value[d.value.length-1]),await w()},T=async(...u)=>{if(m.value){console.warn("Cannot send message while processing is in progress");return}d.value.push(...u),R.push(...u),await w()},O=u=>{let p=u;return e.length&&(p=p.map(b=>we(b,e))),n.length&&(p=p.map(b=>Te(b,n))),p},E=(u,p)=>{a.value=u,u==="processing"?c.value=p||"requesting":c.value=void 0},i=u=>{Object.assign(x,u)},l=u=>({messages:d.value,currentTurn:R,requestState:a.value,processingState:c.value,plugins:M,abortSignal:u,setRequestState:E,customContext:x,setCustomContext:i}),g=(u,p)=>typeof u.disabled=="function"?u.disabled(p):!!u.disabled,y=u=>!u||Object.keys(u).length===0?!1:Object.values(u).some(p=>!!p),S=async(u,p)=>{E("processing","requesting");let b=new Proxy({messages:O(d.value)},{set(D,P,F){return P==="messages"?(D.messages=O(F),!0):(D[P]=F,!0)}}),I=l(p);for(let D of M.filter(P=>!g(P,I)))await D.onBeforeRequest?.({...I,requestBody:b});let C=(0,U.reactive)({role:"",content:"",loading:!0});N(C);let _,re=u(b,p),B=oe(re);for await(let D of B){E("processing","completing"),C.loading&&(C.loading=void 0);let P=D.choices?.find(W=>W.index===0);if(P){_=P;let W=()=>{C.metadata||(C.metadata={});let{created:z,...Ie}=D;C.metadata.createdAt=z,C.metadata.updatedAt=Math.floor(Date.now()/1e3),Object.assign(C.metadata,Ie);let ae=y(P.delta)?P.delta:P.message;ae||(ae=P.delta||P.message||{}),J(C,ae)};if(r){let z=l(p);r({...z,chunk:D,choice:P,currentMessage:C},W)}else W()}let F=l(p);for(let W of M.filter(z=>!g(z,F)))W.onCompletionChunk?.({...F,abortSignal:p,chunk:D,choice:P,currentMessage:C})}await k(C,u,p,_)},w=async()=>{let u=new AbortController;v=u,x={};try{E("processing","requesting");let p=l(u.signal);for(let C of M.filter(_=>!g(_,p)))await C.onTurnStart?.(p);let b=f.value;try{await S(b,u.signal),E("completed")}catch(C){if(u.signal.aborted||C instanceof $||C instanceof Error&&C.name==="AbortError")E("aborted");else throw C}let I=l(u.signal);for(let C of M.filter(_=>!g(_,I)))await C.onTurnEnd?.(I)}catch(p){E("error");let b=!1,I=l(u.signal);for(let C of M.filter(_=>!g(_,I)))C.onError&&(b=!0,C.onError({...I,error:p}));if(!b)throw p}finally{let p=l(u.signal);for(let b of M.filter(I=>!g(I,p)))try{b.onFinally?.(p)}catch(I){console.error(`Error in onFinally hook for plugin ${b.name||"Anonymous"}:`,I)}v=null,R.slice(-1)[0]&&(R.slice(-1)[0].loading=void 0),R=[]}},q=async()=>{v?.abort(),m.value&&await new Promise(u=>{let p=(0,U.watch)(m,b=>{b||(p(),u())},{immediate:!0})})},k=async(u,p,b,I)=>{let C=!1,_=l(b),re=M.filter(B=>!g(B,_)).map(B=>{if(!B.onAfterRequest)return null;let D=F=>{N(F)},P=()=>{C=!0};return B.onAfterRequest({..._,currentMessage:u,lastChoice:I,appendMessage:D,requestNext:P})}).filter(B=>B!==null);await Ae(Promise.all(re),b),C&&await S(p,b)},N=u=>{let p=Array.isArray(u)?u:[u];d.value.push(...p),R.push(...p)};return{requestState:a,processingState:c,messages:d,responseProvider:f,isProcessing:m,sendMessage:h,send:T,abortRequest:q}};var se=require("vue");function Oe(o,t=200,e=!1,n=!0,s=!1){return We(He(t,e,n,s),o)}function We(o,t){function e(...n){return new Promise((s,r)=>{Promise.resolve(o(()=>t.apply(this,n),{fn:t,thisArg:this,args:n})).then(s).catch(r)})}return e}var Ee=()=>{};function He(...o){let t=0,e,n=!0,s=Ee,r,a,c,d,f;!(0,se.isRef)(o[0])&&typeof o[0]=="object"?{delay:a,trailing:c=!0,leading:d=!0,rejectOnCancel:f=!1}=o[0]:[a,c=!0,d=!0,f=!1]=o;let v=()=>{e&&(clearTimeout(e),e=void 0,s(),s=Ee)};return x=>{let A=(0,se.toValue)(a),M=Date.now()-t,m=()=>r=x();return v(),A<=0?(t=Date.now(),m()):(M>A?(t=Date.now(),(d||!n)&&m()):c&&(r=new Promise((h,T)=>{s=f?T:h,e=setTimeout(()=>{t=Date.now(),n=!0,h(m()),v()},Math.max(0,A-M))})),!d&&!e&&(e=setTimeout(()=>n=!0,A)),n=!1,r)}}var Ge=o=>{let t=o.storage||te(),e=(0,L.ref)([]),n=new Map,s=new Map,r=(0,L.ref)(null),a=(0,L.computed)(()=>{let i=r.value;if(!i)return null;let l=e.value.find(y=>y.id===i);if(!l)return null;let g=n.get(i);return g?{...l,engine:g}:null}),c=i=>{if(!t?.saveMessages)return;let l=i||r.value,g=e.value.find(S=>S.id===l);if(!g)return;g.updatedAt=Date.now(),t?.saveConversation?.(g);let y=n.get(g.id);y&&t.saveMessages(g.id,y.messages.value)},d=(i,l)=>{if(!o.autoSaveMessages||!t?.saveMessages)return;let g=s.get(i);g&&g();let y=o.autoSaveThrottle??1e3,S=Oe(()=>{c(i)},y,!0,!0),w=(0,L.watch)(l.messages,S,{deep:!0});s.set(i,w)},f=i=>{let l=s.get(i);l&&(l(),s.delete(i))};t?.loadConversations&&Promise.resolve(t.loadConversations()).then(i=>{if(!i?.length)return[];if(e.value.length===0)return e.value=i,e.value;let l=new Map(e.value.map(g=>[g.id,g]));return i.forEach(g=>{l.has(g.id)||l.set(g.id,g)}),e.value=Array.from(l.values()),e.value}).then(i=>{o.onLoad?.(i)}).catch(i=>{console.error("[useConversation] loadConversations failed:",i)});let v=async(i,l)=>{let g=n.get(i);if(g)return g;let y=l?.initialMessages??o.useMessageOptions.initialMessages??[];if(t?.loadMessages)try{y=await t.loadMessages(i)}catch(w){console.error("[useConversation] loadMessages failed:",w)}let S=ne({...o.useMessageOptions,...l,initialMessages:y});return n.set(i,S),d(i,S),S};function R(){return Date.now().toString(36)+Math.random().toString(36).substring(2,9)}let x=i=>{let{id:l=R(),title:g,metadata:y,useMessageOptions:S}=i||{},w=Date.now(),q={id:l,title:g,createdAt:w,updatedAt:w,metadata:y};e.value.unshift(q);let k=ne({...o.useMessageOptions,...S});return n.set(l,k),d(l,k),t?.saveConversation?.(q),t?.saveMessages?.(l,k.messages.value),r.value=l,a.value},A=i=>{let{excludeId:l}=i||{};n.forEach((g,y)=>{if(l&&y===l)return;g.isProcessing?.value||(f(y),n.delete(y))})};return{conversations:e,activeConversationId:r,activeConversation:a,createConversation:x,switchConversation:async i=>i?r.value===i?a.value:e.value.find(g=>g.id===i)?(await v(i),A({excludeId:i}),r.value=i,a.value):null:null,deleteConversation:async i=>{let l=e.value.findIndex(y=>y.id===i);if(l===-1)return;await n.get(i)?.abortRequest(),f(i),n.delete(i),e.value.splice(l,1),t?.deleteConversation?.(i),r.value===i&&(r.value=null,A())},clear:()=>{e.value.map(l=>l.id).forEach(l=>{t?.deleteConversation?.(l)}),n.forEach(l=>{l.abortRequest()}),s.forEach(l=>{l()}),e.value=[],n.clear(),s.clear(),r.value=null},updateConversationTitle:(i,l)=>{let g=e.value.find(y=>y.id===i);g&&(g.title=l,g.updatedAt=Date.now(),t?.saveConversation?.(g))},saveMessages:c,sendMessage:i=>{a.value?.engine.sendMessage(i)},abortActiveRequest:async()=>{await a.value?.engine.abortRequest()}}};0&&(module.exports={AIClient,BaseModelProvider,EXCLUDE_MODE_REMOVE,ErrorType,IndexedDBStrategy,LocalStorageStrategy,OpenAIProvider,StreamEventType,extractTextFromResponse,fallbackRolePlugin,formatMessages,handleSSEStream,indexedDBStorageStrategyFactory,lengthPlugin,localStorageStrategyFactory,sseStreamToGenerator,thinkingPlugin,toolPlugin,useConversation,useMessage});
3
+ `);r=b.pop()||"";for(let y of b)if(y.trim()!==""){if(y.trim()==="data: [DONE]"){u&&(a=u),e.onDone(a);continue}try{let c=y.match(/^data: (.+)$/m);if(!c)continue;let l=JSON.parse(c[1]);e.onData(l),u=l.choices?.[0]?.finish_reason||void 0}catch(c){console.error("Error parsing SSE message:",c)}}}(r.trim()==="data: [DONE]"||t?.aborted)&&(t?.aborted&&(a="aborted"),e.onDone(a))}catch(d){if(t?.aborted)return;throw d}}function be(s){return s.map(e=>typeof e=="object"&&"role"in e&&"content"in e?{role:e.role,content:String(e.content),...e.name?{name:e.name}:{}}:typeof e=="string"?{role:"user",content:e}:{role:"user",content:String(e)})}function xe(s){return!s.choices||!s.choices.length?"":s.choices[0].message?.content||""}function de(s="The operation was aborted"){let e=new Error(s);return e.name="AbortError",e}async function*Pe(s,e={}){let t=s.body?.getReader();if(!t)throw new Error("ReadableStream not supported");let{signal:o}=e,n=new TextDecoder,r="",a=()=>{t.cancel()};o?.addEventListener("abort",a);try{for(;;){if(o?.aborted)throw de();let u;try{u=await t.read()}catch(y){throw o?.aborted?de():y}let{done:d,value:i}=u;if(d){if(o?.aborted)throw de();return}let g=n.decode(i,{stream:!0});r+=g;let b=r.split(`
4
+ `);r=b.pop()||"";for(let y of b)if(y.trim()!==""&&y.startsWith("data: ")){let c=y.slice(6);if(c==="[DONE]")return;try{yield JSON.parse(c)}catch(l){console.warn("Failed to parse SSE data:",c,l)}}}}finally{o?.removeEventListener("abort",a),t.releaseLock()}}var W=class extends z{constructor(t){super(t);this.defaultModel="gpt-3.5-turbo";this.baseURL=t.apiUrl||"https://api.openai.com/v1",this.apiKey=t.apiKey||"",t.defaultModel&&(this.defaultModel=t.defaultModel),this.apiKey||console.warn("API key is not provided. Authentication will likely fail.")}async chat(t){try{this.validateRequest(t);let o={model:t.options?.model||this.config.defaultModel||this.defaultModel,messages:t.messages,...t.options,stream:!1},n={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)};this.apiKey&&Object.assign(n.headers,{Authorization:`Bearer ${this.apiKey}`});let r=await fetch(`${this.baseURL}/chat/completions`,n);if(!r.ok){let a=await r.text();throw new Error(`HTTP error! status: ${r.status}, details: ${a}`)}return await r.json()}catch(o){throw pe(o)}}async chatStream(t,o){let{signal:n,...r}=t.options||{};try{this.validateRequest(t);let a={model:t.options?.model||this.config.defaultModel||this.defaultModel,messages:t.messages,...r,stream:!0},u={method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,Accept:"text/event-stream"},body:JSON.stringify(a),signal:n};this.apiKey&&Object.assign(u.headers,{Authorization:`Bearer ${this.apiKey}`});let d=await fetch(`${this.baseURL}/chat/completions`,u);if(!d.ok){let i=await d.text();throw new Error(`HTTP error! status: ${d.status}, details: ${i}`)}await re(d,o,n)}catch(a){if(n?.aborted)return;o.onError(pe(a))}}updateConfig(t){super.updateConfig(t),t.apiUrl&&(this.baseURL=t.apiUrl),t.apiKey&&(this.apiKey=t.apiKey),t.defaultModel&&(this.defaultModel=t.defaultModel)}};var ae=class{constructor(e){this.config=e,this.provider=this.createProvider(e)}createProvider(e){if(e.provider==="custom"&&"providerImplementation"in e)return e.providerImplementation;if(e.provider==="deepseek"){let t={defaultModel:"deepseek-chat",apiUrl:"https://api.deepseek.com/v1"};return new W({...t,...e})}else return new W(e)}async chat(e){return this.provider.chat(e)}async chatStream(e,t){let o={...e,options:{...e.options,stream:!0}};return this.provider.chatStream(o,t)}getConfig(){return{...this.config}}updateConfig(e){this.config={...this.config,...e},e.provider&&e.provider!==this.config.provider?this.provider=this.createProvider(this.config):this.provider.updateConfig(this.config)}};var Se=require("vue");function ee(s,e=new WeakMap){if(s==null||typeof s!="object")return s;try{let t=(0,Se.toRaw)(s);if(e.has(t))return e.get(t);if(Array.isArray(t)){let n=[];return e.set(t,n),n.push(...t.map(r=>ee(r,e))),n}if(t instanceof Date||t instanceof RegExp||t instanceof ArrayBuffer||t instanceof Blob)return t;let o={};e.set(t,o);for(let n of Object.keys(t)){let r=Object.getOwnPropertyDescriptor(t,n);if(!r||r.get||r.set)continue;let a=t[n];typeof a!="function"&&typeof a!="symbol"&&(o[n]=ee(a,e))}return o}catch(t){return console.warn("unwrapProxy error:",t),Array.isArray(s)?[]:{}}}var ie=s=>s.map(e=>{let{renderContent:t,...o}=e;if(!Array.isArray(t))return e;let n=t.filter(a=>a.type==="collapsible-text"),r=t.filter(a=>a.type==="markdown"||a.type==="text");return n.length>0&&(o.reasoning_content=n.map(a=>a.content).join("")),r.length>0&&(o.content=r.map(a=>a.content).join("")),o});var te=s=>{let e=localStorage.getItem(s);return e?JSON.parse(e):[]},$=class{constructor(e="tiny-robot-ai-conversations"){this.storageKey=e}saveConversation(e){try{let t=te(this.storageKey),o=t.findIndex(n=>n.id===e.id);o!==-1?Object.assign(t[o],e):t.unshift({...e,messages:[]}),localStorage.setItem(this.storageKey,JSON.stringify(t))}catch(t){console.error("\u4FDD\u5B58\u4F1A\u8BDD\u5931\u8D25:",t)}}loadConversations(){try{return te(this.storageKey).map(t=>({id:t.id,title:t.title,createdAt:t.createdAt,updatedAt:t.updatedAt,metadata:t.metadata}))}catch(e){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u5931\u8D25:",e),[]}}saveMessages(e,t){try{let o=te(this.storageKey),n=o.findIndex(r=>r.id===e);n!==-1&&(o[n].messages=t),localStorage.setItem(this.storageKey,JSON.stringify(o))}catch(o){console.error("\u4FDD\u5B58\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",o)}}loadMessages(e){try{let o=te(this.storageKey).find(r=>r.id===e);return ie(o?.messages||[])}catch(t){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",t),[]}}deleteConversation(e){let t=te(this.storageKey),o=t.findIndex(n=>n.id===e);o!==-1&&t.splice(o,1),localStorage.setItem(this.storageKey,JSON.stringify(t))}};var Te=require("idb");var J=class{constructor(e="tiny-robot-ai-db",t=3){this.db=null;this.dbName=e,this.dbVersion=t}async getDB(){return this.db||(this.db=await(0,Te.openDB)(this.dbName,this.dbVersion,{upgrade(e){e.objectStoreNames.contains("conversations")||e.createObjectStore("conversations",{keyPath:"id"}).createIndex("by-updated","updatedAt"),e.objectStoreNames.contains("messages")||e.createObjectStore("messages",{keyPath:"conversationId"})}})),this.db}async loadConversations(){try{return(await(await this.getDB()).getAllFromIndex("conversations","by-updated")).reverse()}catch(e){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u5931\u8D25:",e),[]}}async loadMessages(e){try{let o=await(await this.getDB()).get("messages",e);return o?ie(o.messages):[]}catch(t){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",t),[]}}async saveConversation(e){try{let t=await this.getDB(),o=ee(e);await t.put("conversations",o)}catch(t){throw console.error("\u4FDD\u5B58\u4F1A\u8BDD\u5931\u8D25:",t),t}}async saveMessages(e,t){try{let o=await this.getDB(),n=ee(t);await o.put("messages",{conversationId:e,messages:n})}catch(o){throw console.error("\u4FDD\u5B58\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",o),o}}async deleteConversation(e){try{let t=await this.getDB();await t.delete("conversations",e),await t.delete("messages",e)}catch(t){throw console.error("\u5220\u9664\u4F1A\u8BDD\u5931\u8D25:",t),t}}};function le(s={}){return new $(s.key||"tiny-robot-ai-conversations")}function Ae(s={}){return new J(s.dbName||"tiny-robot-ai-db",s.dbVersion||1)}var L=require("vue");var K=require("vue");var Le=s=>typeof s=="function"?null:Array.isArray(s)?s.length>0?new Set(s):null:new Set([s]),we=s=>{let e=new Set,t=(r,a)=>{try{r.listener(a)}catch(u){console.error("Error in message state subscriber:",u)}};return{notify:r=>{let a=new Set(Array.isArray(r)?r:[r]),u=s(),d=Array.from(e);for(let i of d){if(i.kinds){let g=!1;for(let b of i.kinds)if(a.has(b)){g=!0;break}if(!g)continue}t(i,u)}},subscribe:(r,a)=>{let u=typeof r=="function"?r:a;if(!u)throw new Error("subscribe listener is required");let d={kinds:Le(r),listener:u};return e.add(d),t(d,s()),()=>{e.delete(d)}}}};var B=require("vue");var Ee=s=>(0,B.reactive)(s),fe=s=>{let e=(0,B.isProxy)(s)?(0,B.toRaw)(s):s;if(Array.isArray(e))return e.map(t=>fe(t));if(e&&typeof e=="object"){let t={};for(let[o,n]of Object.entries(e))t[o]=fe(n);return t}return e},ke=()=>{let s=!1,e=(0,B.ref)("idle"),t=(0,B.ref)(void 0),o=(0,B.ref)([]),n=(0,B.computed)(()=>e.value==="processing"),r=g=>{if(s)throw new Error("Message state adapter is already initialized");e.value=g.requestState,t.value=g.processingState,o.value=g.messages.map(Ee),s=!0},a=g=>Ee(g),u=()=>{if(!s)throw new Error("Message state adapter is not initialized");return{requestState:e.value,processingState:t.value,messages:fe(o.value),isProcessing:n.value}},d=we(u);return{requestState:e,processingState:t,messages:o,isProcessing:n,initialize:r,getState:u,createMessage:a,mutate:(g,b)=>{if(!s)throw new Error("Message state adapter is not initialized");let y={get requestState(){return e.value},set requestState(S){e.value=S},get processingState(){return t.value},set processingState(S){t.value=S},get messages(){return o.value},set messages(S){o.value=S.map(a)}},c=!1;if(b(y,()=>{c=!0}),c)return;(Array.isArray(g)?g:[g]).includes("messages")&&(o.value=[...o.value]),d.notify(g)},subscribe:d.subscribe}};var se=(s={})=>{let{continueContent:e="Please continue with your previous answer.",...t}=s;return{name:"length",...t,onAfterRequest:async o=>{let{lastChoice:n,appendMessage:r,requestNext:a}=o;return n?.finish_reason==="length"&&(r({role:"user",content:e}),a()),t.onAfterRequest?.(o)}}};var oe=(s={})=>{let e=(t,o)=>!!t.thinking!==o||!!t.open!==o;return{name:"thinking",...s,onCompletionChunk(t){let{choice:o,currentMessage:n,updateCurrentMessage:r}=t,a=o,u=a?.message?.reasoning_content||a?.delta?.reasoning_content,d=typeof u=="string"&&u.trim()!=="";return d?n.state&&typeof n.state=="object"?e(n.state,d)&&r(i=>{i.state.thinking=!0,i.state.open=!0}):r(i=>{i.state={thinking:d,open:d}}):n.state&&typeof n.state=="object"&&"thinking"in n.state&&e(n.state,d)&&r(i=>{i.state.thinking=!1,i.state.open=!1}),s.onCompletionChunk?.(t)},onTurnEnd(t){let{currentTurn:o,mutate:n}=t,r=o.at(-1);return r?.state&&typeof r.state=="object"&&"thinking"in r.state&&e(r.state,!1)&&n("messages",()=>{r.state.thinking=!1,r.state.open=!1}),s.onTurnEnd?.(t)}}};var Q=class extends Error{constructor(e){super(e),this.name="AbortError"}};function Ge(s){if(s.aborted)return{promise:Promise.reject(new Q(String(s.reason??"Aborted"))),cleanup:()=>{}};let e=null;return{promise:new Promise((n,r)=>{e=()=>{r(new Q(String(s.reason??"Aborted")))},s.addEventListener("abort",e,{once:!0})}),cleanup:()=>{e&&(s.removeEventListener("abort",e),e=null)}}}function qe(s,e){let{promise:t,cleanup:o}=Ge(e);return Promise.race([s,t]).finally(o)}function Be(s,e){let t={};for(let o in s)e.includes(o)&&(t[o]=s[o]);return t}function _e(s,e){let t={};for(let o in s)e.includes(o)||(t[o]=s[o]);return t}async function*Y(s){if(Ie(s)){yield*s;return}let e=await s;if(Ie(e)){yield*e;return}yield e}function Ie(s){return s&&typeof s=="object"&&typeof s[Symbol.asyncIterator]=="function"}var me=s=>typeof s=="object"&&s!==null,Oe=s=>me(s)&&typeof s.index=="number",X=(s,e)=>{for(let[t,o]of Object.entries(e)){let n=s[t];if(n)if(typeof n=="string"&&typeof o=="string")t==="type"&&n||(s[t]=n+o);else if(Array.isArray(n)&&Array.isArray(o))if(n.every(r=>Oe(r))&&o.every(r=>Oe(r))){let r=new Map(n.map(i=>[i.index,i])),a=new Map(o.map(i=>[i.index,i]));for(let[i,g]of a)if(r.has(i)){let b=r.get(i);r.set(i,X(b,g))}else r.set(i,g);let u=Math.max(...Array.from(r.keys()),-1)+1,d=u>n.length?Array.from({length:u}):n;for(let[i,g]of r)d[i]=g;s[t]=d}else s[t]=[...n,...o];else me(n)&&me(o)&&(s[t]=X(n,o));else s[t]=o}return s};function ze({messages:s,cancelledContent:e,createMessage:t,mutate:o}){let n=[];for(let r=0;r<s.length;r++){let a=s[r];if(a.role==="assistant"&&a.tool_calls&&a.tool_calls.length>0){let u=new Set(a.tool_calls.map(g=>g.id)),d=new Set;for(let g=r+1;g<s.length;g++){let b=s[g];b.role==="tool"&&b.tool_call_id&&u.has(b.tool_call_id)&&d.add(b.tool_call_id)}let i=a.tool_calls.map(g=>g.id).filter(g=>!d.has(g));i.length>0&&n.push({insertAfterIndex:r,missingToolCallIds:i})}}n.length!==0&&o("messages",r=>{for(let a=n.length-1;a>=0;a--){let{insertAfterIndex:u,missingToolCallIds:d}=n[a],i=d.map(g=>t({role:"tool",tool_call_id:g,content:e}));r.messages.splice(u+1,0,...i)}})}var Ce=s=>{let{getTools:e,beforeCallTools:t,callTool:o,onToolCallStart:n,onToolCallEnd:r,toolCallCancelledContent:a="Tool call cancelled.",toolCallFailedContent:u="Tool call failed.",autoFillMissingToolMessages:d=!1,...i}=s,g=(c,l)=>{var C,S;return c.state??(c.state={}),(C=c.state).toolCall??(C.toolCall={}),(S=c.state.toolCall)[l]??(S[l]={}),c},b=(...c)=>{let[l,{assistantMessage:C,mutate:S}]=c;S("messages",()=>{let w=g(C,l.id);w.state.toolCall[l.id].status="running"}),n?.(...c)},y=(...c)=>{let[l,{status:C,assistantMessage:S,mutate:w}]=c;w("messages",()=>{let U=g(S,l.id);U.state.toolCall[l.id].status=C}),r?.(...c)};return{name:"tool",...i,onTurnStart:c=>{let{getState:l,createMessage:C,mutate:S}=c,w=l().messages;return d&&ze({messages:w,cancelledContent:a,createMessage:C,mutate:S}),i.onTurnStart?.(c)},onBeforeRequest:async c=>{let{requestBody:l}=c,C=await e();return C&&C.length>0&&(l.tools=C),i.onBeforeRequest?.(c)},onAfterRequest:async c=>{let{currentMessage:l,lastChoice:C,appendMessage:S,abortSignal:w,setRequestState:U,requestNext:q,mutate:p,createMessage:f}=c;if(C?.finish_reason!=="tool_calls"||!l.tool_calls?.length)return;U("processing","calling-tools"),await t?.(l.tool_calls,{...c,assistantMessage:l});let h=l.tool_calls.map(async P=>{let E=Math.floor(Date.now()/1e3),T=!1,M=f({role:"tool",tool_call_id:P.id,content:"",metadata:{createdAt:E,updatedAt:E}});S(M);let _={...c,assistantMessage:l,toolMessage:M};b(P,_);try{let m=o(P,_),v=Y(m);for await(let x of v)p("messages",()=>{if((typeof x=="string"&&x.length>0||x&&typeof x=="object"&&Object.keys(x).length>0)&&(T=!0),typeof x=="string")M.content+=x;else{let A={};try{let k=Array.isArray(M.content)?M.content.map(R=>R.text).join(""):M.content;A=JSON.parse(k||"{}")}catch(k){console.warn(k)}M.content=JSON.stringify(X(A,x))}M.metadata.updatedAt=Math.floor(Date.now()/1e3)});y(P,{..._,status:"success"})}catch(m){let v=m instanceof Error?m:new Error(String(m));if(w.aborted){y(P,{..._,status:"cancelled",error:v});return}console.error(m),T||p("messages",()=>{M.content=u,M.metadata.updatedAt=Math.floor(Date.now()/1e3)}),y(P,{..._,status:"failed",error:v})}});return await Promise.all(h),w.aborted||q(),i.onAfterRequest?.(c)}}};var $e=async()=>{throw new Error("Response provider is not set")},Je=s=>{let e=[];for(let t of s){if(t.name){let o=e.findIndex(n=>n.name===t.name);o!==-1&&e.splice(o,1)}e.push(t)}return e},H=(s,e)=>typeof s.disabled=="function"?s.disabled(e):!!s.disabled,he=(s,e={})=>{let{initialMessages:t=[],requestMessageFields:o=[],requestMessageFieldsExclude:n=["state","metadata","loading"],responseProvider:r=$e,onCompletionChunk:a,plugins:u=[]}=e,d={requestState:"idle",processingState:void 0,messages:[...t]};s.initialize(d);let i={currentTurn:[],customContext:{},abortController:null,responseProvider:r},g=[oe(),se()],b=Je(g.concat(u)),y=()=>s.getState(),c=m=>s.createMessage(m),l=s.subscribe,C=s.mutate,S=m=>!m||Object.keys(m).length===0?!1:Object.values(m).some(v=>!!v),w=m=>{let v=m;return o.length&&(v=v.map(x=>Be(x,o))),n.length&&(v=v.map(x=>_e(x,n))),v},U=m=>{Object.assign(i.customContext,m)},q=(m,v)=>{C("requestState",(x,A)=>{if(x.requestState===m&&x.processingState===v){A();return}x.requestState=m,x.processingState=m==="processing"?v??"requesting":void 0})},p=(...m)=>{let v=m.map(x=>c(x));return C("messages",x=>{x.messages.push(...v)}),i.currentTurn.push(...v),v},f=m=>({getState:y,createMessage:c,mutate:C,abortSignal:m,currentTurn:i.currentTurn,customContext:i.customContext,setRequestState:q,setCustomContext:U});async function h(m,v,x={}){q("processing","requesting");let A={messages:y().messages},k=f(v);for(let j of b.filter(O=>!H(O,k)))await j.onBeforeRequest?.({...k,requestBody:A});A.messages=w(A.messages);let R={role:"assistant",content:"",loading:!0};[R]=p(R),x.setAssistantMessage?.(R);let I=m(A,v),F=Y(I),N;for await(let j of F){q("processing","completing"),C("messages",(D,Z)=>{R.loading?R.loading=void 0:Z()});let O=(j.choices||[]).find(D=>D.index===0)??j.choices?.[0];if(!O)continue;N=O;let G=()=>{C("messages",()=>{R.metadata||(R.metadata={});let{created:D,...Z}=j;R.metadata.createdAt=D,R.metadata.updatedAt=Math.floor(Date.now()/1e3),Object.assign(R.metadata,Z);let ne="delta"in O&&S(O.delta)&&O.delta||"message"in O&&S(O.message)&&O.message||null;if(ne?.role&&(R.role=ne.role),ne){let{role:ot,...Fe}=ne;X(R,Fe)}})},Me=D=>{C("messages",()=>{D(R)})};if(a){let D=f(v);a({...D,chunk:j,choice:O,currentMessage:R,updateCurrentMessage:Me},G)}else G();let ye=f(v);for(let D of b.filter(Z=>!H(Z,ye)))D.onCompletionChunk?.({...ye,abortSignal:v,chunk:j,choice:O,currentMessage:R,updateCurrentMessage:Me})}await P(R,m,v,N,x)}async function P(m,v,x,A,k){let R=!1,I=f(x),F=b.filter(N=>!H(N,I)).map(N=>{if(!N.onAfterRequest)return null;let j=G=>{p(...Array.isArray(G)?G:[G])},O=()=>{R=!0};return N.onAfterRequest({...I,currentMessage:m,lastChoice:A,appendMessage:j,requestNext:O})}).filter(N=>N!==null);await qe(Promise.all(F),x),R&&await h(v,x,k)}async function E(){let m=new AbortController;i.abortController=m,i.customContext={};let v=null,x=A=>{v=A};try{q("processing","requesting");let A=f(m.signal);for(let I of b.filter(F=>!H(F,A)))await I.onTurnStart?.(A);let k=i.responseProvider;try{await h(k,m.signal,{setAssistantMessage:x}),q("completed")}catch(I){if(m.signal.aborted||I instanceof Q||I instanceof Error&&I.name==="AbortError")q("aborted");else throw I}let R=f(m.signal);for(let I of b.filter(F=>!H(F,R)))await I.onTurnEnd?.(R)}catch(A){q("error");let k=!1,R=f(m.signal);for(let I of b.filter(F=>!H(F,R)))I.onError&&(k=!0,I.onError({...R,error:A}));if(!k)throw A}finally{let A=f(m.signal);for(let k of b.filter(R=>!H(R,A)))try{k.onFinally?.(A)}catch(R){console.error(`Error in onFinally hook for plugin [${k.name||"Anonymous"}]:`,R)}i.abortController=null,i.currentTurn=[],C("messages",(k,R)=>{v?.loading?v.loading=void 0:R()})}}async function T(m){if(!m||!m.trim()){console.warn("Cannot send empty message");return}if(y().requestState==="processing"){console.warn("Cannot send message while processing is in progress");return}let v=Math.floor(Date.now()/1e3);p({role:"user",content:m.trim(),metadata:{createdAt:v,updatedAt:v}}),await E()}async function M(...m){if(y().requestState==="processing"){console.warn("Cannot send message while processing is in progress");return}p(...m),await E()}async function _(){i.abortController?.abort(),y().isProcessing&&await new Promise(m=>{let v=()=>{};v=l("requestState",x=>{x.isProcessing||(v(),m())})})}return{getState:y,subscribe:l,sendMessage:T,send:M,abort:_,setResponseProvider(m){i.responseProvider=m}}};var ce=s=>{let{initialMessages:e=[],requestMessageFields:t=[],requestMessageFieldsExclude:o=["state","metadata","loading"],plugins:n=[],responseProvider:r,onCompletionChunk:a}=s,u=ke(),d=l=>u.messages.value.find(C=>C===l||(0,K.toRaw)(C)===l||(0,K.toRaw)(C)===(0,K.toRaw)(l))??l,i=l=>({messages:u.messages.value,currentTurn:l.currentTurn.map(C=>d(C)),requestState:u.requestState.value,processingState:u.processingState.value,plugins:n,setRequestState:l.setRequestState,abortSignal:l.abortSignal,customContext:l.customContext,setCustomContext:l.setCustomContext}),g=l=>{let C=l;if(typeof C.__corePluginFactory=="function")return C.__corePluginFactory({createCorePlugin:g,createVueBaseContext:i,resolveReactiveMessage:d});let{name:S,disabled:w,onTurnStart:U,onTurnEnd:q,onBeforeRequest:p,onAfterRequest:f,onCompletionChunk:h,onError:P,onFinally:E}=l,T={};return S!==void 0&&(T.name=S),w!==void 0&&(T.disabled=typeof w=="function"?M=>w(i(M)):w),U&&(T.onTurnStart=M=>U(i(M))),q&&(T.onTurnEnd=M=>q(i(M))),p&&(T.onBeforeRequest=M=>p({...i(M),requestBody:M.requestBody})),f&&(T.onAfterRequest=M=>f({...i(M),currentMessage:d(M.currentMessage),lastChoice:M.lastChoice,appendMessage:M.appendMessage,requestNext:M.requestNext})),h&&(T.onCompletionChunk=M=>h({...i(M),currentMessage:d(M.currentMessage),choice:M.choice,chunk:M.chunk})),P&&(T.onError=M=>P({...i(M),error:M.error})),E&&(T.onFinally=M=>E(i(M))),T},y=he(u,{initialMessages:e,requestMessageFields:t,requestMessageFieldsExclude:o,responseProvider:r,onCompletionChunk:a?(l,C)=>{if(a)return a({...i(l),currentMessage:d(l.currentMessage),choice:l.choice,chunk:l.chunk},C)}:void 0,plugins:n.map(l=>g(l))}),c=(0,K.ref)(r);return(0,K.watch)(c,l=>{y.setResponseProvider(l)},{flush:"sync"}),{requestState:u.requestState,processingState:u.processingState,messages:u.messages,responseProvider:c,isProcessing:u.isProcessing,sendMessage:y.sendMessage,send:y.send,abortRequest:y.abort}};var ue=require("vue");function Ue(s,e=200,t=!1,o=!0,n=!1){return Qe(Xe(e,t,o,n),s)}function Qe(s,e){function t(...o){return new Promise((n,r)=>{Promise.resolve(s(()=>e.apply(this,o),{fn:e,thisArg:this,args:o})).then(n).catch(r)})}return t}var De=()=>{};function Xe(...s){let e=0,t,o=!0,n=De,r,a,u,d,i;!(0,ue.isRef)(s[0])&&typeof s[0]=="object"?{delay:a,trailing:u=!0,leading:d=!0,rejectOnCancel:i=!1}=s[0]:[a,u=!0,d=!0,i=!1]=s;let g=()=>{t&&(clearTimeout(t),t=void 0,n(),n=De)};return y=>{let c=(0,ue.toValue)(a),l=Date.now()-e,C=()=>r=y();return g(),c<=0?(e=Date.now(),C()):(l>c?(e=Date.now(),(d||!o)&&C()):u&&(r=new Promise((S,w)=>{n=i?w:S,t=setTimeout(()=>{e=Date.now(),o=!0,S(C()),g()},Math.max(0,c-l))})),!d&&!t&&(t=setTimeout(()=>o=!0,c)),o=!1,r)}}var Ye=s=>{let e=s.storage||le(),t=(0,L.ref)([]),o=new Map,n=new Map,r=(0,L.ref)(null),a=(0,L.computed)(()=>{let p=r.value;if(!p)return null;let f=t.value.find(P=>P.id===p);if(!f)return null;let h=o.get(p);return h?{...f,engine:h}:null}),u=p=>{if(!e?.saveMessages)return;let f=p||r.value,h=t.value.find(E=>E.id===f);if(!h)return;h.updatedAt=Date.now(),e?.saveConversation?.(h);let P=o.get(h.id);P&&e.saveMessages(h.id,P.messages.value)},d=(p,f)=>{if(!s.autoSaveMessages||!e?.saveMessages)return;let h=n.get(p);h&&h();let P=s.autoSaveThrottle??1e3,E=Ue(()=>{u(p)},P,!0,!0),T=(0,L.watch)(f.messages,E,{deep:!0});n.set(p,T)},i=p=>{let f=n.get(p);f&&(f(),n.delete(p))};e?.loadConversations&&Promise.resolve(e.loadConversations()).then(p=>{if(!p?.length)return[];if(t.value.length===0)return t.value=p,t.value;let f=new Map(t.value.map(h=>[h.id,h]));return p.forEach(h=>{f.has(h.id)||f.set(h.id,h)}),t.value=Array.from(f.values()),t.value}).then(p=>{s.onLoad?.(p)}).catch(p=>{console.error("[useConversation] loadConversations failed:",p)});let g=async(p,f)=>{let h=o.get(p);if(h)return h;let P=f?.initialMessages??s.useMessageOptions.initialMessages??[];if(e?.loadMessages)try{P=await e.loadMessages(p)}catch(T){console.error("[useConversation] loadMessages failed:",T)}let E=ce({...s.useMessageOptions,...f,initialMessages:P});return o.set(p,E),d(p,E),E};function b(){return Date.now().toString(36)+Math.random().toString(36).substring(2,9)}let y=p=>{let{id:f=b(),title:h,metadata:P,useMessageOptions:E}=p||{},T=Date.now(),M={id:f,title:h,createdAt:T,updatedAt:T,metadata:P};t.value.unshift(M);let _=ce({...s.useMessageOptions,...E});return o.set(f,_),d(f,_),e?.saveConversation?.(M),e?.saveMessages?.(f,_.messages.value),r.value=f,a.value},c=p=>{let{excludeId:f}=p||{};o.forEach((h,P)=>{if(f&&P===f)return;h.isProcessing?.value||(i(P),o.delete(P))})};return{conversations:t,activeConversationId:r,activeConversation:a,createConversation:y,switchConversation:async p=>p?r.value===p?a.value:t.value.find(h=>h.id===p)?(await g(p),c({excludeId:p}),r.value=p,a.value):null:null,deleteConversation:async p=>{let f=t.value.findIndex(P=>P.id===p);if(f===-1)return;await o.get(p)?.abortRequest(),i(p),o.delete(p),t.value.splice(f,1),e?.deleteConversation?.(p),r.value===p&&(r.value=null,c())},clear:()=>{t.value.map(f=>f.id).forEach(f=>{e?.deleteConversation?.(f)}),o.forEach(f=>{f.abortRequest()}),n.forEach(f=>{f()}),t.value=[],o.clear(),n.clear(),r.value=null},updateConversationTitle:(p,f)=>{let h=t.value.find(P=>P.id===p);h&&(h.title=f,h.updatedAt=Date.now(),e?.saveConversation?.(h))},saveMessages:u,sendMessage:p=>{a.value?.engine.sendMessage(p)},abortActiveRequest:async()=>{await a.value?.engine.abortRequest()}}};var Ze=(s={})=>{let{continueContent:e="Please continue with your previous answer.",...t}=s;return{name:"length",__corePluginFactory(o){return se({...o.createCorePlugin(t),continueContent:e})}}};var et=(s={})=>({name:"thinking",__corePluginFactory(e){return oe(e.createCorePlugin(s))}});var tt=s=>{let{getTools:e,beforeCallTools:t,callTool:o,onToolCallStart:n,onToolCallEnd:r,toolCallCancelledContent:a="Tool call cancelled.",toolCallFailedContent:u="Tool call failed.",autoFillMissingToolMessages:d=!1,...i}=s;return{name:"tool",__corePluginFactory(g){let b=g.createCorePlugin(i);return Ce({...b,getTools:async()=>await e(),beforeCallTools:t?async(y,c)=>{let l=g.resolveReactiveMessage(c.assistantMessage);await t(y,{...g.createVueBaseContext(c),assistantMessage:l,currentMessage:l})}:void 0,callTool:async function*(y,c){let l=g.resolveReactiveMessage(c.assistantMessage),C=g.resolveReactiveMessage(c.toolMessage),S=o(y,{...g.createVueBaseContext(c),assistantMessage:l,currentMessage:l,toolMessage:C});for await(let w of Y(S))yield w},onToolCallStart:n?(y,c)=>{let l=g.resolveReactiveMessage(c.assistantMessage),C=g.resolveReactiveMessage(c.toolMessage);n(y,{...g.createVueBaseContext(c),assistantMessage:l,primaryMessage:l,toolMessage:C})}:void 0,onToolCallEnd:r?(y,c)=>{let l=g.resolveReactiveMessage(c.assistantMessage),C=g.resolveReactiveMessage(c.toolMessage);r(y,{...g.createVueBaseContext(c),assistantMessage:l,primaryMessage:l,toolMessage:C,status:c.status,error:c.error})}:void 0,toolCallCancelledContent:a,toolCallFailedContent:u,autoFillMissingToolMessages:d})}}};0&&(module.exports={AIClient,BaseModelProvider,ErrorType,IndexedDBStrategy,LocalStorageStrategy,OpenAIProvider,StreamEventType,extractTextFromResponse,formatMessages,handleSSEStream,indexedDBStorageStrategyFactory,lengthPlugin,localStorageStrategyFactory,sseStreamToGenerator,thinkingPlugin,toolPlugin,useConversation,useMessage});
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- var G=class{constructor(t){this.config=t}updateConfig(t){this.config={...this.config,...t}}getConfig(){return{...this.config}}validateRequest(t){if(!t.messages||!Array.isArray(t.messages)||t.messages.length===0)throw new Error("\u8BF7\u6C42\u5FC5\u987B\u5305\u542B\u81F3\u5C11\u4E00\u6761\u6D88\u606F");for(let e of t.messages)if(!e.role||!e.content)throw new Error("\u6BCF\u6761\u6D88\u606F\u5FC5\u987B\u5305\u542B\u89D2\u8272\u548C\u5185\u5BB9")}};var Me=(c=>(c.NETWORK_ERROR="network_error",c.AUTHENTICATION_ERROR="authentication_error",c.RATE_LIMIT_ERROR="rate_limit_error",c.SERVER_ERROR="server_error",c.MODEL_ERROR="model_error",c.TIMEOUT_ERROR="timeout_error",c.UNKNOWN_ERROR="unknown_error",c))(Me||{}),be=(n=>(n.DATA="data",n.ERROR="error",n.DONE="done",n))(be||{});function F(o){return{type:o.type||"unknown_error",message:o.message||"\u672A\u77E5\u9519\u8BEF",statusCode:o.statusCode,originalError:o.originalError}}function te(o){if(!o.response)return F({type:"network_error",message:"\u7F51\u7EDC\u8FDE\u63A5\u9519\u8BEF\uFF0C\u8BF7\u68C0\u67E5\u60A8\u7684\u7F51\u7EDC\u8FDE\u63A5",originalError:o});if(o.response){let{status:t,data:e}=o.response;return t===401||t===403?F({type:"authentication_error",message:"\u8EAB\u4EFD\u9A8C\u8BC1\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u60A8\u7684API\u5BC6\u94A5",statusCode:t,originalError:o}):t===429?F({type:"rate_limit_error",message:"\u8D85\u51FAAPI\u8C03\u7528\u9650\u5236\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",statusCode:t,originalError:o}):t>=500?F({type:"server_error",message:"\u670D\u52A1\u5668\u9519\u8BEF\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",statusCode:t,originalError:o}):F({type:"unknown_error",message:e?.error?.message||`\u8BF7\u6C42\u5931\u8D25\uFF0C\u72B6\u6001\u7801: ${t}`,statusCode:t,originalError:o})}return o.code==="ECONNABORTED"?F({type:"timeout_error",message:"\u8BF7\u6C42\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",originalError:o}):F({type:"unknown_error",message:o.message||"\u53D1\u751F\u672A\u77E5\u9519\u8BEF",originalError:o})}async function ne(o,t,e){let n=o.body?.getReader();if(!n)throw new Error("Response body is null");let s=new TextDecoder,r="",a,c;e&&e.addEventListener("abort",()=>{n.cancel().catch(d=>console.error("Error cancelling reader:",d))},{once:!0});try{for(;;){if(e?.aborted){await n.cancel();break}let{done:d,value:f}=await n.read();if(d)break;let v=s.decode(f,{stream:!0});r+=v;let R=r.split(`
1
+ import{b as H,c as L,d as W,e as $,g as G,h as J}from"./chunk-EES4JUCD.mjs";var A=class{constructor(t){this.config=t}updateConfig(t){this.config={...this.config,...t}}getConfig(){return{...this.config}}validateRequest(t){if(!t.messages||!Array.isArray(t.messages)||t.messages.length===0)throw new Error("\u8BF7\u6C42\u5FC5\u987B\u5305\u542B\u81F3\u5C11\u4E00\u6761\u6D88\u606F");for(let e of t.messages)if(!e.role||!e.content)throw new Error("\u6BCF\u6761\u6D88\u606F\u5FC5\u987B\u5305\u542B\u89D2\u8272\u548C\u5185\u5BB9")}};var Y=(g=>(g.NETWORK_ERROR="network_error",g.AUTHENTICATION_ERROR="authentication_error",g.RATE_LIMIT_ERROR="rate_limit_error",g.SERVER_ERROR="server_error",g.MODEL_ERROR="model_error",g.TIMEOUT_ERROR="timeout_error",g.UNKNOWN_ERROR="unknown_error",g))(Y||{}),Z=(s=>(s.DATA="data",s.ERROR="error",s.DONE="done",s))(Z||{});function T(o){return{type:o.type||"unknown_error",message:o.message||"\u672A\u77E5\u9519\u8BEF",statusCode:o.statusCode,originalError:o.originalError}}function F(o){if(!o.response)return T({type:"network_error",message:"\u7F51\u7EDC\u8FDE\u63A5\u9519\u8BEF\uFF0C\u8BF7\u68C0\u67E5\u60A8\u7684\u7F51\u7EDC\u8FDE\u63A5",originalError:o});if(o.response){let{status:t,data:e}=o.response;return t===401||t===403?T({type:"authentication_error",message:"\u8EAB\u4EFD\u9A8C\u8BC1\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u60A8\u7684API\u5BC6\u94A5",statusCode:t,originalError:o}):t===429?T({type:"rate_limit_error",message:"\u8D85\u51FAAPI\u8C03\u7528\u9650\u5236\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",statusCode:t,originalError:o}):t>=500?T({type:"server_error",message:"\u670D\u52A1\u5668\u9519\u8BEF\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",statusCode:t,originalError:o}):T({type:"unknown_error",message:e?.error?.message||`\u8BF7\u6C42\u5931\u8D25\uFF0C\u72B6\u6001\u7801: ${t}`,statusCode:t,originalError:o})}return o.code==="ECONNABORTED"?T({type:"timeout_error",message:"\u8BF7\u6C42\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",originalError:o}):T({type:"unknown_error",message:o.message||"\u53D1\u751F\u672A\u77E5\u9519\u8BEF",originalError:o})}async function q(o,t,e){let s=o.body?.getReader();if(!s)throw new Error("Response body is null");let r=new TextDecoder,a="",l,g;e&&e.addEventListener("abort",()=>{s.cancel().catch(d=>console.error("Error cancelling reader:",d))},{once:!0});try{for(;;){if(e?.aborted){await s.cancel();break}let{done:d,value:C}=await s.read();if(d)break;let h=r.decode(C,{stream:!0});a+=h;let b=a.split(`
2
2
 
3
- `);r=R.pop()||"";for(let x of R)if(x.trim()!==""){if(x.trim()==="data: [DONE]"){c&&(a=c),t.onDone(a);continue}try{let A=x.match(/^data: (.+)$/m);if(!A)continue;let M=JSON.parse(A[1]);t.onData(M),c=M.choices?.[0]?.finish_reason||void 0}catch(A){console.error("Error parsing SSE message:",A)}}}(r.trim()==="data: [DONE]"||e?.aborted)&&(e?.aborted&&(a="aborted"),t.onDone(a))}catch(d){if(e?.aborted)return;throw d}}function Re(o){return o.map(t=>typeof t=="object"&&"role"in t&&"content"in t?{role:t.role,content:String(t.content),...t.name?{name:t.name}:{}}:typeof t=="string"?{role:"user",content:t}:{role:"user",content:String(t)})}function xe(o){return!o.choices||!o.choices.length?"":o.choices[0].message?.content||""}function oe(o="The operation was aborted"){let t=new Error(o);return t.name="AbortError",t}async function*Ae(o,t={}){let e=o.body?.getReader();if(!e)throw new Error("ReadableStream not supported");let{signal:n}=t,s=new TextDecoder,r="",a=()=>{e.cancel()};n?.addEventListener("abort",a);try{for(;;){if(n?.aborted)throw oe();let c;try{c=await e.read()}catch(x){throw n?.aborted?oe():x}let{done:d,value:f}=c;if(d){if(n?.aborted)throw oe();return}let v=s.decode(f,{stream:!0});r+=v;let R=r.split(`
4
- `);r=R.pop()||"";for(let x of R)if(x.trim()!==""&&x.startsWith("data: ")){let A=x.slice(6);if(A==="[DONE]")return;try{yield JSON.parse(A)}catch(M){console.warn("Failed to parse SSE data:",A,M)}}}}finally{n?.removeEventListener("abort",a),e.releaseLock()}}var j=class extends G{constructor(e){super(e);this.defaultModel="gpt-3.5-turbo";this.baseURL=e.apiUrl||"https://api.openai.com/v1",this.apiKey=e.apiKey||"",e.defaultModel&&(this.defaultModel=e.defaultModel),this.apiKey||console.warn("API key is not provided. Authentication will likely fail.")}async chat(e){try{this.validateRequest(e);let n={model:e.options?.model||this.config.defaultModel||this.defaultModel,messages:e.messages,...e.options,stream:!1},s={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)};this.apiKey&&Object.assign(s.headers,{Authorization:`Bearer ${this.apiKey}`});let r=await fetch(`${this.baseURL}/chat/completions`,s);if(!r.ok){let a=await r.text();throw new Error(`HTTP error! status: ${r.status}, details: ${a}`)}return await r.json()}catch(n){throw te(n)}}async chatStream(e,n){let{signal:s,...r}=e.options||{};try{this.validateRequest(e);let a={model:e.options?.model||this.config.defaultModel||this.defaultModel,messages:e.messages,...r,stream:!0},c={method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,Accept:"text/event-stream"},body:JSON.stringify(a),signal:s};this.apiKey&&Object.assign(c.headers,{Authorization:`Bearer ${this.apiKey}`});let d=await fetch(`${this.baseURL}/chat/completions`,c);if(!d.ok){let f=await d.text();throw new Error(`HTTP error! status: ${d.status}, details: ${f}`)}await ne(d,n,s)}catch(a){if(s?.aborted)return;n.onError(te(a))}}updateConfig(e){super.updateConfig(e),e.apiUrl&&(this.baseURL=e.apiUrl),e.apiKey&&(this.apiKey=e.apiKey),e.defaultModel&&(this.defaultModel=e.defaultModel)}};var se=class{constructor(t){this.config=t,this.provider=this.createProvider(t)}createProvider(t){if(t.provider==="custom"&&"providerImplementation"in t)return t.providerImplementation;if(t.provider==="deepseek"){let e={defaultModel:"deepseek-chat",apiUrl:"https://api.deepseek.com/v1"};return new j({...e,...t})}else return new j(t)}async chat(t){return this.provider.chat(t)}async chatStream(t,e){let n={...t,options:{...t.options,stream:!0}};return this.provider.chatStream(n,e)}getConfig(){return{...this.config}}updateConfig(t){this.config={...this.config,...t},t.provider&&t.provider!==this.config.provider?this.provider=this.createProvider(this.config):this.provider.updateConfig(this.config)}};import{toRaw as we}from"vue";function V(o,t=new WeakMap){if(o==null||typeof o!="object")return o;try{let e=we(o);if(t.has(e))return t.get(e);if(Array.isArray(e)){let s=[];return t.set(e,s),s.push(...e.map(r=>V(r,t))),s}if(e instanceof Date||e instanceof RegExp||e instanceof ArrayBuffer||e instanceof Blob)return e;let n={};t.set(e,n);for(let s of Object.keys(e)){let r=Object.getOwnPropertyDescriptor(e,s);if(!r||r.get||r.set)continue;let a=e[s];typeof a!="function"&&typeof a!="symbol"&&(n[s]=V(a,t))}return n}catch(e){return console.warn("unwrapProxy error:",e),Array.isArray(o)?[]:{}}}var X=o=>o.map(t=>{let{renderContent:e,...n}=t;if(!Array.isArray(e))return t;let s=e.filter(a=>a.type==="collapsible-text"),r=e.filter(a=>a.type==="markdown"||a.type==="text");return s.length>0&&(n.reasoning_content=s.map(a=>a.content).join("")),r.length>0&&(n.content=r.map(a=>a.content).join("")),n});var $=o=>{let t=localStorage.getItem(o);return t?JSON.parse(t):[]},J=class{constructor(t="tiny-robot-ai-conversations"){this.storageKey=t}saveConversation(t){try{let e=$(this.storageKey),n=e.findIndex(s=>s.id===t.id);n!==-1?Object.assign(e[n],t):e.unshift({...t,messages:[]}),localStorage.setItem(this.storageKey,JSON.stringify(e))}catch(e){console.error("\u4FDD\u5B58\u4F1A\u8BDD\u5931\u8D25:",e)}}loadConversations(){try{return $(this.storageKey).map(e=>({id:e.id,title:e.title,createdAt:e.createdAt,updatedAt:e.updatedAt,metadata:e.metadata}))}catch(t){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u5931\u8D25:",t),[]}}saveMessages(t,e){try{let n=$(this.storageKey),s=n.findIndex(r=>r.id===t);s!==-1&&(n[s].messages=e),localStorage.setItem(this.storageKey,JSON.stringify(n))}catch(n){console.error("\u4FDD\u5B58\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",n)}}loadMessages(t){try{let n=$(this.storageKey).find(r=>r.id===t);return X(n?.messages||[])}catch(e){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",e),[]}}deleteConversation(t){let e=$(this.storageKey),n=e.findIndex(s=>s.id===t);n!==-1&&e.splice(n,1),localStorage.setItem(this.storageKey,JSON.stringify(e))}};import{openDB as Te}from"idb";var z=class{constructor(t="tiny-robot-ai-db",e=3){this.db=null;this.dbName=t,this.dbVersion=e}async getDB(){return this.db||(this.db=await Te(this.dbName,this.dbVersion,{upgrade(t){t.objectStoreNames.contains("conversations")||t.createObjectStore("conversations",{keyPath:"id"}).createIndex("by-updated","updatedAt"),t.objectStoreNames.contains("messages")||t.createObjectStore("messages",{keyPath:"conversationId"})}})),this.db}async loadConversations(){try{return(await(await this.getDB()).getAllFromIndex("conversations","by-updated")).reverse()}catch(t){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u5931\u8D25:",t),[]}}async loadMessages(t){try{let n=await(await this.getDB()).get("messages",t);return n?X(n.messages):[]}catch(e){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",e),[]}}async saveConversation(t){try{let e=await this.getDB(),n=V(t);await e.put("conversations",n)}catch(e){throw console.error("\u4FDD\u5B58\u4F1A\u8BDD\u5931\u8D25:",e),e}}async saveMessages(t,e){try{let n=await this.getDB(),s=V(e);await n.put("messages",{conversationId:t,messages:s})}catch(n){throw console.error("\u4FDD\u5B58\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",n),n}}async deleteConversation(t){try{let e=await this.getDB();await e.delete("conversations",t),await e.delete("messages",t)}catch(e){throw console.error("\u5220\u9664\u4F1A\u8BDD\u5931\u8D25:",e),e}}};function re(o={}){return new J(o.key||"tiny-robot-ai-conversations")}function Se(o={}){return new z(o.dbName||"tiny-robot-ai-db",o.dbVersion||1)}import{computed as je,ref as Ce,watch as Le}from"vue";import{computed as _e,reactive as De,ref as Y,watch as Ue}from"vue";var le=(o={})=>{let{fallbackRole:t="assistant",...e}=o;return{name:"fallbackRole",...e,onBeforeRequest(n){let{requestBody:s}=n;return s.messages=s.messages.map(r=>({...r,role:r.role||t})),e.onBeforeRequest?.(n)}}};var ce=(o={})=>{let{continueContent:t="Please continue with your previous answer.",...e}=o;return{name:"length",...e,onAfterRequest:async n=>{let{lastChoice:s,appendMessage:r,requestNext:a}=n;return s?.finish_reason==="length"&&(r({role:"user",content:t}),a()),e.onAfterRequest?.(n)}}};var ue=(o={})=>({name:"thinking",...o,onCompletionChunk(t){let{choice:e,currentMessage:n}=t,r=typeof(e?.message?.reasoning_content||e?.delta?.reasoning_content)=="string";return n.state?(n.state.thinking=r,n.state.open=r):n.state={thinking:r,open:r},o.onCompletionChunk?.(t)},onTurnEnd(t){let e=t.currentTurn.slice(-1)[0];return e?.state?.thinking&&(e.state.thinking=!1,e.state.open=!1),o.onTurnEnd?.(t)}});import{reactive as Ee}from"vue";var L=class extends Error{constructor(t){super(t),this.name="AbortError"}};function Pe(o){if(o.aborted)return{promise:Promise.reject(new L(String(o.reason??"Aborted"))),cleanup:()=>{}};let t=null;return{promise:new Promise((s,r)=>{t=()=>{r(new L(String(o.reason??"Aborted")))},o.addEventListener("abort",t,{once:!0})}),cleanup:()=>{t&&(o.removeEventListener("abort",t),t=null)}}}function pe(o,t){let{promise:e,cleanup:n}=Pe(t);return Promise.race([o,e]).finally(n)}function fe(o,t){let e={};for(let n in o)t.includes(n)&&(e[n]=o[n]);return e}function me(o,t){let e={};for(let n in o)t.includes(n)||(e[n]=o[n]);return e}async function*Q(o){if(de(o)){yield*o;return}let t=await o;if(de(t)){yield*t;return}yield t}function de(o){return o&&typeof o=="object"&&typeof o[Symbol.asyncIterator]=="function"}var ae=o=>typeof o=="object"&&o!==null,ge=o=>ae(o)&&typeof o.index=="number",W=(o,t)=>{for(let[e,n]of Object.entries(t)){let s=o[e];if(s)if(typeof s=="string"&&typeof n=="string")e==="type"&&s||(o[e]=s+n);else if(Array.isArray(s)&&Array.isArray(n))if(s.every(r=>ge(r))&&n.every(r=>ge(r))){let r=new Map(s.map(f=>[f.index,f])),a=new Map(n.map(f=>[f.index,f]));for(let[f,v]of a)if(r.has(f)){let R=r.get(f);r.set(f,W(R,v))}else r.set(f,v);let c=Math.max(...Array.from(r.keys()),-1)+1,d=c>s.length?Array.from({length:c}):s;for(let[f,v]of r)d[f]=v;o[e]=d}else o[e]=[...s,...n];else ae(s)&&ae(n)&&(o[e]=W(s,n));else o[e]=n}return o};function Oe(o,t){let e=[];for(let n=0;n<o.length;n++){let s=o[n];if(s.role==="assistant"&&s.tool_calls&&s.tool_calls.length>0){let r=new Set(s.tool_calls.map(d=>d.id)),a=new Set;for(let d=n+1;d<o.length;d++){let f=o[d];f.role==="tool"&&f.tool_call_id&&r.has(f.tool_call_id)&&a.add(f.tool_call_id)}let c=s.tool_calls.map(d=>d.id).filter(d=>!a.has(d));c.length>0&&e.push({insertAfterIndex:n,missingToolCallIds:c})}}for(let n=e.length-1;n>=0;n--){let{insertAfterIndex:s,missingToolCallIds:r}=e[n],a=r.map(c=>({role:"tool",tool_call_id:c,content:t}));o.splice(s+1,0,...a)}}var Ie="remove";function ke(o,t,e,n){let s=o.filter(a=>a[e]),r=new Set(s.flatMap(a=>a.tool_calls?.map(c=>c.id)??[]));if(t===Ie)for(let a=o.length-1;a>=0;a--){let c=o[a];(c[e]||c[n]||c.tool_call_id&&r.has(c.tool_call_id))&&o.splice(a,1)}else if(t===!0)for(let a of o)(a[e]||a.tool_call_id&&r.has(a.tool_call_id))&&(a[n]=!0,delete a[e])}var vt=o=>{let{getTools:t,beforeCallTools:e,callTool:n,onToolCallStart:s,onToolCallEnd:r,toolCallCancelledContent:a="Tool call cancelled.",toolCallFailedContent:c="Tool call failed.",autoFillMissingToolMessages:d=!1,excludeToolMessagesNextTurn:f=!1,...v}=o,R=Symbol("doNotSendNextTurn"),x=Symbol("doNotSend"),A=(...m)=>{let[h,{primaryMessage:T}]=m;T.state.toolCall[h.id].status="running",s?.(...m)},M=(...m)=>{let[h,{status:T,primaryMessage:O}]=m;O.state.toolCall[h.id].status=T,r?.(...m)};return{name:"tool",...v,onTurnStart:m=>{let{messages:h}=m;return d&&Oe(h,a),f&&ke(h,f,R,x),v.onTurnStart?.(m)},onBeforeRequest:async m=>{let{messages:h,requestBody:T}=m;f===!0&&(T.messages=h.filter(E=>!E[x]));let O=await t?.();return O&&O.length>0&&(T.tools=O),v.onBeforeRequest?.(m)},onAfterRequest:async m=>{let{currentMessage:h,lastChoice:T,appendMessage:O,abortSignal:E,setRequestState:i,requestNext:l}=m;if(T?.finish_reason!=="tool_calls"||!h.tool_calls?.length)return;f&&(h[R]=!0),i("processing","calling-tools"),await e?.(h.tool_calls,{...m,currentMessage:h});let g=h.tool_calls.map(async y=>{let S=Math.floor(Date.now()/1e3),w=Ee({role:"tool",tool_call_id:y.id,content:"",metadata:{createdAt:S,updatedAt:S}});O(w);let U={...m,primaryMessage:h,toolMessage:w};A(y,U);try{let k=n(y,U),B=Q(k);for await(let u of B){if(typeof u=="string")w.content+=u;else{let p={};try{p=JSON.parse(w.content||"{}")}catch(b){console.warn(b)}w.content=JSON.stringify(W(p,u))}w.metadata.updatedAt=Math.floor(Date.now()/1e3)}M(y,{...U,status:"success"})}catch(k){let B=k instanceof Error?k:new Error(String(k));if(E.aborted){M(y,{...U,status:"cancelled",error:B});return}console.error(k),w.content.length===0&&(w.content=c),M(y,{...U,status:"failed",error:B})}});return await Promise.all(g),l(),v.onAfterRequest?.(m)},onCompletionChunk:m=>{var T,O,E;let{currentMessage:h}=m;if(Array.isArray(h.tool_calls))for(let i of h.tool_calls)h.state?.toolCall?.[i.id]?.status||(h.state??(h.state={}),(T=h.state).toolCall??(T.toolCall={}),(O=h.state.toolCall)[E=i.id]??(O[E]={}));return v.onCompletionChunk?.(m)}}};var qe=o=>{let t=[];for(let e of o){if(e.name){let n=t.findIndex(s=>s.name===e.name);n!==-1&&t.splice(n,1)}t.push(e)}return t},ie=o=>{let{initialMessages:t=[],requestMessageFields:e=[],requestMessageFieldsExclude:n=["state","metadata","loading"],plugins:s=[],onCompletionChunk:r}=o,a=Y("idle"),c=Y(void 0),d=Y(t),f=Y(o.responseProvider),v=null,R=[],x={},A=[le(),ue(),ce()],M=qe(A.concat(s)),m=_e(()=>a.value==="processing"),h=async u=>{if(!u||!u.trim()){console.warn("Cannot send empty message");return}if(m.value){console.warn("Cannot send message while processing is in progress");return}let p=Math.floor(Date.now()/1e3);d.value.push({role:"user",content:u.trim(),metadata:{createdAt:p,updatedAt:p}}),R.push(d.value[d.value.length-1]),await w()},T=async(...u)=>{if(m.value){console.warn("Cannot send message while processing is in progress");return}d.value.push(...u),R.push(...u),await w()},O=u=>{let p=u;return e.length&&(p=p.map(b=>fe(b,e))),n.length&&(p=p.map(b=>me(b,n))),p},E=(u,p)=>{a.value=u,u==="processing"?c.value=p||"requesting":c.value=void 0},i=u=>{Object.assign(x,u)},l=u=>({messages:d.value,currentTurn:R,requestState:a.value,processingState:c.value,plugins:M,abortSignal:u,setRequestState:E,customContext:x,setCustomContext:i}),g=(u,p)=>typeof u.disabled=="function"?u.disabled(p):!!u.disabled,y=u=>!u||Object.keys(u).length===0?!1:Object.values(u).some(p=>!!p),S=async(u,p)=>{E("processing","requesting");let b=new Proxy({messages:O(d.value)},{set(D,P,N){return P==="messages"?(D.messages=O(N),!0):(D[P]=N,!0)}}),I=l(p);for(let D of M.filter(P=>!g(P,I)))await D.onBeforeRequest?.({...I,requestBody:b});let C=De({role:"",content:"",loading:!0});B(C);let _,Z=u(b,p),q=Q(Z);for await(let D of q){E("processing","completing"),C.loading&&(C.loading=void 0);let P=D.choices?.find(K=>K.index===0);if(P){_=P;let K=()=>{C.metadata||(C.metadata={});let{created:H,...ve}=D;C.metadata.createdAt=H,C.metadata.updatedAt=Math.floor(Date.now()/1e3),Object.assign(C.metadata,ve);let ee=y(P.delta)?P.delta:P.message;ee||(ee=P.delta||P.message||{}),W(C,ee)};if(r){let H=l(p);r({...H,chunk:D,choice:P,currentMessage:C},K)}else K()}let N=l(p);for(let K of M.filter(H=>!g(H,N)))K.onCompletionChunk?.({...N,abortSignal:p,chunk:D,choice:P,currentMessage:C})}await k(C,u,p,_)},w=async()=>{let u=new AbortController;v=u,x={};try{E("processing","requesting");let p=l(u.signal);for(let C of M.filter(_=>!g(_,p)))await C.onTurnStart?.(p);let b=f.value;try{await S(b,u.signal),E("completed")}catch(C){if(u.signal.aborted||C instanceof L||C instanceof Error&&C.name==="AbortError")E("aborted");else throw C}let I=l(u.signal);for(let C of M.filter(_=>!g(_,I)))await C.onTurnEnd?.(I)}catch(p){E("error");let b=!1,I=l(u.signal);for(let C of M.filter(_=>!g(_,I)))C.onError&&(b=!0,C.onError({...I,error:p}));if(!b)throw p}finally{let p=l(u.signal);for(let b of M.filter(I=>!g(I,p)))try{b.onFinally?.(p)}catch(I){console.error(`Error in onFinally hook for plugin ${b.name||"Anonymous"}:`,I)}v=null,R.slice(-1)[0]&&(R.slice(-1)[0].loading=void 0),R=[]}},U=async()=>{v?.abort(),m.value&&await new Promise(u=>{let p=Ue(m,b=>{b||(p(),u())},{immediate:!0})})},k=async(u,p,b,I)=>{let C=!1,_=l(b),Z=M.filter(q=>!g(q,_)).map(q=>{if(!q.onAfterRequest)return null;let D=N=>{B(N)},P=()=>{C=!0};return q.onAfterRequest({..._,currentMessage:u,lastChoice:I,appendMessage:D,requestNext:P})}).filter(q=>q!==null);await pe(Promise.all(Z),b),C&&await S(p,b)},B=u=>{let p=Array.isArray(u)?u:[u];d.value.push(...p),R.push(...p)};return{requestState:a,processingState:c,messages:d,responseProvider:f,isProcessing:m,sendMessage:h,send:T,abortRequest:U}};import{isRef as Be,toValue as Ne}from"vue";function ye(o,t=200,e=!1,n=!0,s=!1){return Fe(Ke(t,e,n,s),o)}function Fe(o,t){function e(...n){return new Promise((s,r)=>{Promise.resolve(o(()=>t.apply(this,n),{fn:t,thisArg:this,args:n})).then(s).catch(r)})}return e}var he=()=>{};function Ke(...o){let t=0,e,n=!0,s=he,r,a,c,d,f;!Be(o[0])&&typeof o[0]=="object"?{delay:a,trailing:c=!0,leading:d=!0,rejectOnCancel:f=!1}=o[0]:[a,c=!0,d=!0,f=!1]=o;let v=()=>{e&&(clearTimeout(e),e=void 0,s(),s=he)};return x=>{let A=Ne(a),M=Date.now()-t,m=()=>r=x();return v(),A<=0?(t=Date.now(),m()):(M>A?(t=Date.now(),(d||!n)&&m()):c&&(r=new Promise((h,T)=>{s=f?T:h,e=setTimeout(()=>{t=Date.now(),n=!0,h(m()),v()},Math.max(0,A-M))})),!d&&!e&&(e=setTimeout(()=>n=!0,A)),n=!1,r)}}var _t=o=>{let t=o.storage||re(),e=Ce([]),n=new Map,s=new Map,r=Ce(null),a=je(()=>{let i=r.value;if(!i)return null;let l=e.value.find(y=>y.id===i);if(!l)return null;let g=n.get(i);return g?{...l,engine:g}:null}),c=i=>{if(!t?.saveMessages)return;let l=i||r.value,g=e.value.find(S=>S.id===l);if(!g)return;g.updatedAt=Date.now(),t?.saveConversation?.(g);let y=n.get(g.id);y&&t.saveMessages(g.id,y.messages.value)},d=(i,l)=>{if(!o.autoSaveMessages||!t?.saveMessages)return;let g=s.get(i);g&&g();let y=o.autoSaveThrottle??1e3,S=ye(()=>{c(i)},y,!0,!0),w=Le(l.messages,S,{deep:!0});s.set(i,w)},f=i=>{let l=s.get(i);l&&(l(),s.delete(i))};t?.loadConversations&&Promise.resolve(t.loadConversations()).then(i=>{if(!i?.length)return[];if(e.value.length===0)return e.value=i,e.value;let l=new Map(e.value.map(g=>[g.id,g]));return i.forEach(g=>{l.has(g.id)||l.set(g.id,g)}),e.value=Array.from(l.values()),e.value}).then(i=>{o.onLoad?.(i)}).catch(i=>{console.error("[useConversation] loadConversations failed:",i)});let v=async(i,l)=>{let g=n.get(i);if(g)return g;let y=l?.initialMessages??o.useMessageOptions.initialMessages??[];if(t?.loadMessages)try{y=await t.loadMessages(i)}catch(w){console.error("[useConversation] loadMessages failed:",w)}let S=ie({...o.useMessageOptions,...l,initialMessages:y});return n.set(i,S),d(i,S),S};function R(){return Date.now().toString(36)+Math.random().toString(36).substring(2,9)}let x=i=>{let{id:l=R(),title:g,metadata:y,useMessageOptions:S}=i||{},w=Date.now(),U={id:l,title:g,createdAt:w,updatedAt:w,metadata:y};e.value.unshift(U);let k=ie({...o.useMessageOptions,...S});return n.set(l,k),d(l,k),t?.saveConversation?.(U),t?.saveMessages?.(l,k.messages.value),r.value=l,a.value},A=i=>{let{excludeId:l}=i||{};n.forEach((g,y)=>{if(l&&y===l)return;g.isProcessing?.value||(f(y),n.delete(y))})};return{conversations:e,activeConversationId:r,activeConversation:a,createConversation:x,switchConversation:async i=>i?r.value===i?a.value:e.value.find(g=>g.id===i)?(await v(i),A({excludeId:i}),r.value=i,a.value):null:null,deleteConversation:async i=>{let l=e.value.findIndex(y=>y.id===i);if(l===-1)return;await n.get(i)?.abortRequest(),f(i),n.delete(i),e.value.splice(l,1),t?.deleteConversation?.(i),r.value===i&&(r.value=null,A())},clear:()=>{e.value.map(l=>l.id).forEach(l=>{t?.deleteConversation?.(l)}),n.forEach(l=>{l.abortRequest()}),s.forEach(l=>{l()}),e.value=[],n.clear(),s.clear(),r.value=null},updateConversationTitle:(i,l)=>{let g=e.value.find(y=>y.id===i);g&&(g.title=l,g.updatedAt=Date.now(),t?.saveConversation?.(g))},saveMessages:c,sendMessage:i=>{a.value?.engine.sendMessage(i)},abortActiveRequest:async()=>{await a.value?.engine.abortRequest()}}};export{se as AIClient,G as BaseModelProvider,Ie as EXCLUDE_MODE_REMOVE,Me as ErrorType,z as IndexedDBStrategy,J as LocalStorageStrategy,j as OpenAIProvider,be as StreamEventType,xe as extractTextFromResponse,le as fallbackRolePlugin,Re as formatMessages,ne as handleSSEStream,Se as indexedDBStorageStrategyFactory,ce as lengthPlugin,re as localStorageStrategyFactory,Ae as sseStreamToGenerator,ue as thinkingPlugin,vt as toolPlugin,_t as useConversation,ie as useMessage};
3
+ `);a=b.pop()||"";for(let f of b)if(f.trim()!==""){if(f.trim()==="data: [DONE]"){g&&(l=g),t.onDone(l);continue}try{let u=f.match(/^data: (.+)$/m);if(!u)continue;let i=JSON.parse(u[1]);t.onData(i),g=i.choices?.[0]?.finish_reason||void 0}catch(u){console.error("Error parsing SSE message:",u)}}}(a.trim()==="data: [DONE]"||e?.aborted)&&(e?.aborted&&(l="aborted"),t.onDone(l))}catch(d){if(e?.aborted)return;throw d}}function ee(o){return o.map(t=>typeof t=="object"&&"role"in t&&"content"in t?{role:t.role,content:String(t.content),...t.name?{name:t.name}:{}}:typeof t=="string"?{role:"user",content:t}:{role:"user",content:String(t)})}function te(o){return!o.choices||!o.choices.length?"":o.choices[0].message?.content||""}function _(o="The operation was aborted"){let t=new Error(o);return t.name="AbortError",t}async function*se(o,t={}){let e=o.body?.getReader();if(!e)throw new Error("ReadableStream not supported");let{signal:s}=t,r=new TextDecoder,a="",l=()=>{e.cancel()};s?.addEventListener("abort",l);try{for(;;){if(s?.aborted)throw _();let g;try{g=await e.read()}catch(f){throw s?.aborted?_():f}let{done:d,value:C}=g;if(d){if(s?.aborted)throw _();return}let h=r.decode(C,{stream:!0});a+=h;let b=a.split(`
4
+ `);a=b.pop()||"";for(let f of b)if(f.trim()!==""&&f.startsWith("data: ")){let u=f.slice(6);if(u==="[DONE]")return;try{yield JSON.parse(u)}catch(i){console.warn("Failed to parse SSE data:",u,i)}}}}finally{s?.removeEventListener("abort",l),e.releaseLock()}}var S=class extends A{constructor(e){super(e);this.defaultModel="gpt-3.5-turbo";this.baseURL=e.apiUrl||"https://api.openai.com/v1",this.apiKey=e.apiKey||"",e.defaultModel&&(this.defaultModel=e.defaultModel),this.apiKey||console.warn("API key is not provided. Authentication will likely fail.")}async chat(e){try{this.validateRequest(e);let s={model:e.options?.model||this.config.defaultModel||this.defaultModel,messages:e.messages,...e.options,stream:!1},r={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)};this.apiKey&&Object.assign(r.headers,{Authorization:`Bearer ${this.apiKey}`});let a=await fetch(`${this.baseURL}/chat/completions`,r);if(!a.ok){let l=await a.text();throw new Error(`HTTP error! status: ${a.status}, details: ${l}`)}return await a.json()}catch(s){throw F(s)}}async chatStream(e,s){let{signal:r,...a}=e.options||{};try{this.validateRequest(e);let l={model:e.options?.model||this.config.defaultModel||this.defaultModel,messages:e.messages,...a,stream:!0},g={method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,Accept:"text/event-stream"},body:JSON.stringify(l),signal:r};this.apiKey&&Object.assign(g.headers,{Authorization:`Bearer ${this.apiKey}`});let d=await fetch(`${this.baseURL}/chat/completions`,g);if(!d.ok){let C=await d.text();throw new Error(`HTTP error! status: ${d.status}, details: ${C}`)}await q(d,s,r)}catch(l){if(r?.aborted)return;s.onError(F(l))}}updateConfig(e){super.updateConfig(e),e.apiUrl&&(this.baseURL=e.apiUrl),e.apiKey&&(this.apiKey=e.apiKey),e.defaultModel&&(this.defaultModel=e.defaultModel)}};var N=class{constructor(t){this.config=t,this.provider=this.createProvider(t)}createProvider(t){if(t.provider==="custom"&&"providerImplementation"in t)return t.providerImplementation;if(t.provider==="deepseek"){let e={defaultModel:"deepseek-chat",apiUrl:"https://api.deepseek.com/v1"};return new S({...e,...t})}else return new S(t)}async chat(t){return this.provider.chat(t)}async chatStream(t,e){let s={...t,options:{...t.options,stream:!0}};return this.provider.chatStream(s,e)}getConfig(){return{...this.config}}updateConfig(t){this.config={...this.config,...t},t.provider&&t.provider!==this.config.provider?this.provider=this.createProvider(this.config):this.provider.updateConfig(this.config)}};import{toRaw as oe}from"vue";function w(o,t=new WeakMap){if(o==null||typeof o!="object")return o;try{let e=oe(o);if(t.has(e))return t.get(e);if(Array.isArray(e)){let r=[];return t.set(e,r),r.push(...e.map(a=>w(a,t))),r}if(e instanceof Date||e instanceof RegExp||e instanceof ArrayBuffer||e instanceof Blob)return e;let s={};t.set(e,s);for(let r of Object.keys(e)){let a=Object.getOwnPropertyDescriptor(e,r);if(!a||a.get||a.set)continue;let l=e[r];typeof l!="function"&&typeof l!="symbol"&&(s[r]=w(l,t))}return s}catch(e){return console.warn("unwrapProxy error:",e),Array.isArray(o)?[]:{}}}var k=o=>o.map(t=>{let{renderContent:e,...s}=t;if(!Array.isArray(e))return t;let r=e.filter(l=>l.type==="collapsible-text"),a=e.filter(l=>l.type==="markdown"||l.type==="text");return r.length>0&&(s.reasoning_content=r.map(l=>l.content).join("")),a.length>0&&(s.content=a.map(l=>l.content).join("")),s});var E=o=>{let t=localStorage.getItem(o);return t?JSON.parse(t):[]},O=class{constructor(t="tiny-robot-ai-conversations"){this.storageKey=t}saveConversation(t){try{let e=E(this.storageKey),s=e.findIndex(r=>r.id===t.id);s!==-1?Object.assign(e[s],t):e.unshift({...t,messages:[]}),localStorage.setItem(this.storageKey,JSON.stringify(e))}catch(e){console.error("\u4FDD\u5B58\u4F1A\u8BDD\u5931\u8D25:",e)}}loadConversations(){try{return E(this.storageKey).map(e=>({id:e.id,title:e.title,createdAt:e.createdAt,updatedAt:e.updatedAt,metadata:e.metadata}))}catch(t){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u5931\u8D25:",t),[]}}saveMessages(t,e){try{let s=E(this.storageKey),r=s.findIndex(a=>a.id===t);r!==-1&&(s[r].messages=e),localStorage.setItem(this.storageKey,JSON.stringify(s))}catch(s){console.error("\u4FDD\u5B58\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",s)}}loadMessages(t){try{let s=E(this.storageKey).find(a=>a.id===t);return k(s?.messages||[])}catch(e){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",e),[]}}deleteConversation(t){let e=E(this.storageKey),s=e.findIndex(r=>r.id===t);s!==-1&&e.splice(s,1),localStorage.setItem(this.storageKey,JSON.stringify(e))}};import{openDB as re}from"idb";var I=class{constructor(t="tiny-robot-ai-db",e=3){this.db=null;this.dbName=t,this.dbVersion=e}async getDB(){return this.db||(this.db=await re(this.dbName,this.dbVersion,{upgrade(t){t.objectStoreNames.contains("conversations")||t.createObjectStore("conversations",{keyPath:"id"}).createIndex("by-updated","updatedAt"),t.objectStoreNames.contains("messages")||t.createObjectStore("messages",{keyPath:"conversationId"})}})),this.db}async loadConversations(){try{return(await(await this.getDB()).getAllFromIndex("conversations","by-updated")).reverse()}catch(t){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u5931\u8D25:",t),[]}}async loadMessages(t){try{let s=await(await this.getDB()).get("messages",t);return s?k(s.messages):[]}catch(e){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",e),[]}}async saveConversation(t){try{let e=await this.getDB(),s=w(t);await e.put("conversations",s)}catch(e){throw console.error("\u4FDD\u5B58\u4F1A\u8BDD\u5931\u8D25:",e),e}}async saveMessages(t,e){try{let s=await this.getDB(),r=w(e);await s.put("messages",{conversationId:t,messages:r})}catch(s){throw console.error("\u4FDD\u5B58\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",s),s}}async deleteConversation(t){try{let e=await this.getDB();await e.delete("conversations",t),await e.delete("messages",t)}catch(e){throw console.error("\u5220\u9664\u4F1A\u8BDD\u5931\u8D25:",e),e}}};function K(o={}){return new O(o.key||"tiny-robot-ai-conversations")}function ne(o={}){return new I(o.dbName||"tiny-robot-ai-db",o.dbVersion||1)}import{computed as pe,ref as X,watch as de}from"vue";import{ref as ae,toRaw as j,watch as ie}from"vue";var V=o=>{let{initialMessages:t=[],requestMessageFields:e=[],requestMessageFieldsExclude:s=["state","metadata","loading"],plugins:r=[],responseProvider:a,onCompletionChunk:l}=o,g=H(),d=i=>g.messages.value.find(M=>M===i||j(M)===i||j(M)===j(i))??i,C=i=>({messages:g.messages.value,currentTurn:i.currentTurn.map(M=>d(M)),requestState:g.requestState.value,processingState:g.processingState.value,plugins:r,setRequestState:i.setRequestState,abortSignal:i.abortSignal,customContext:i.customContext,setCustomContext:i.setCustomContext}),h=i=>{let M=i;if(typeof M.__corePluginFactory=="function")return M.__corePluginFactory({createCorePlugin:h,createVueBaseContext:C,resolveReactiveMessage:d});let{name:P,disabled:x,onTurnStart:U,onTurnEnd:B,onBeforeRequest:n,onAfterRequest:c,onCompletionChunk:p,onError:y,onFinally:R}=i,v={};return P!==void 0&&(v.name=P),x!==void 0&&(v.disabled=typeof x=="function"?m=>x(C(m)):x),U&&(v.onTurnStart=m=>U(C(m))),B&&(v.onTurnEnd=m=>B(C(m))),n&&(v.onBeforeRequest=m=>n({...C(m),requestBody:m.requestBody})),c&&(v.onAfterRequest=m=>c({...C(m),currentMessage:d(m.currentMessage),lastChoice:m.lastChoice,appendMessage:m.appendMessage,requestNext:m.requestNext})),p&&(v.onCompletionChunk=m=>p({...C(m),currentMessage:d(m.currentMessage),choice:m.choice,chunk:m.chunk})),y&&(v.onError=m=>y({...C(m),error:m.error})),R&&(v.onFinally=m=>R(C(m))),v},f=J(g,{initialMessages:t,requestMessageFields:e,requestMessageFieldsExclude:s,responseProvider:a,onCompletionChunk:l?(i,M)=>{if(l)return l({...C(i),currentMessage:d(i.currentMessage),choice:i.choice,chunk:i.chunk},M)}:void 0,plugins:r.map(i=>h(i))}),u=ae(a);return ie(u,i=>{f.setResponseProvider(i)},{flush:"sync"}),{requestState:g.requestState,processingState:g.processingState,messages:g.messages,responseProvider:u,isProcessing:g.isProcessing,sendMessage:f.sendMessage,send:f.send,abortRequest:f.abort}};import{isRef as le,toValue as ce}from"vue";function Q(o,t=200,e=!1,s=!0,r=!1){return ge(ue(t,e,s,r),o)}function ge(o,t){function e(...s){return new Promise((r,a)=>{Promise.resolve(o(()=>t.apply(this,s),{fn:t,thisArg:this,args:s})).then(r).catch(a)})}return e}var z=()=>{};function ue(...o){let t=0,e,s=!0,r=z,a,l,g,d,C;!le(o[0])&&typeof o[0]=="object"?{delay:l,trailing:g=!0,leading:d=!0,rejectOnCancel:C=!1}=o[0]:[l,g=!0,d=!0,C=!1]=o;let h=()=>{e&&(clearTimeout(e),e=void 0,r(),r=z)};return f=>{let u=ce(l),i=Date.now()-t,M=()=>a=f();return h(),u<=0?(t=Date.now(),M()):(i>u?(t=Date.now(),(d||!s)&&M()):g&&(a=new Promise((P,x)=>{r=C?x:P,e=setTimeout(()=>{t=Date.now(),s=!0,P(M()),h()},Math.max(0,u-i))})),!d&&!e&&(e=setTimeout(()=>s=!0,u)),s=!1,a)}}var Qe=o=>{let t=o.storage||K(),e=X([]),s=new Map,r=new Map,a=X(null),l=pe(()=>{let n=a.value;if(!n)return null;let c=e.value.find(y=>y.id===n);if(!c)return null;let p=s.get(n);return p?{...c,engine:p}:null}),g=n=>{if(!t?.saveMessages)return;let c=n||a.value,p=e.value.find(R=>R.id===c);if(!p)return;p.updatedAt=Date.now(),t?.saveConversation?.(p);let y=s.get(p.id);y&&t.saveMessages(p.id,y.messages.value)},d=(n,c)=>{if(!o.autoSaveMessages||!t?.saveMessages)return;let p=r.get(n);p&&p();let y=o.autoSaveThrottle??1e3,R=Q(()=>{g(n)},y,!0,!0),v=de(c.messages,R,{deep:!0});r.set(n,v)},C=n=>{let c=r.get(n);c&&(c(),r.delete(n))};t?.loadConversations&&Promise.resolve(t.loadConversations()).then(n=>{if(!n?.length)return[];if(e.value.length===0)return e.value=n,e.value;let c=new Map(e.value.map(p=>[p.id,p]));return n.forEach(p=>{c.has(p.id)||c.set(p.id,p)}),e.value=Array.from(c.values()),e.value}).then(n=>{o.onLoad?.(n)}).catch(n=>{console.error("[useConversation] loadConversations failed:",n)});let h=async(n,c)=>{let p=s.get(n);if(p)return p;let y=c?.initialMessages??o.useMessageOptions.initialMessages??[];if(t?.loadMessages)try{y=await t.loadMessages(n)}catch(v){console.error("[useConversation] loadMessages failed:",v)}let R=V({...o.useMessageOptions,...c,initialMessages:y});return s.set(n,R),d(n,R),R};function b(){return Date.now().toString(36)+Math.random().toString(36).substring(2,9)}let f=n=>{let{id:c=b(),title:p,metadata:y,useMessageOptions:R}=n||{},v=Date.now(),m={id:c,title:p,createdAt:v,updatedAt:v,metadata:y};e.value.unshift(m);let D=V({...o.useMessageOptions,...R});return s.set(c,D),d(c,D),t?.saveConversation?.(m),t?.saveMessages?.(c,D.messages.value),a.value=c,l.value},u=n=>{let{excludeId:c}=n||{};s.forEach((p,y)=>{if(c&&y===c)return;p.isProcessing?.value||(C(y),s.delete(y))})};return{conversations:e,activeConversationId:a,activeConversation:l,createConversation:f,switchConversation:async n=>n?a.value===n?l.value:e.value.find(p=>p.id===n)?(await h(n),u({excludeId:n}),a.value=n,l.value):null:null,deleteConversation:async n=>{let c=e.value.findIndex(y=>y.id===n);if(c===-1)return;await s.get(n)?.abortRequest(),C(n),s.delete(n),e.value.splice(c,1),t?.deleteConversation?.(n),a.value===n&&(a.value=null,u())},clear:()=>{e.value.map(c=>c.id).forEach(c=>{t?.deleteConversation?.(c)}),s.forEach(c=>{c.abortRequest()}),r.forEach(c=>{c()}),e.value=[],s.clear(),r.clear(),a.value=null},updateConversationTitle:(n,c)=>{let p=e.value.find(y=>y.id===n);p&&(p.title=c,p.updatedAt=Date.now(),t?.saveConversation?.(p))},saveMessages:g,sendMessage:n=>{l.value?.engine.sendMessage(n)},abortActiveRequest:async()=>{await l.value?.engine.abortRequest()}}};var Ze=(o={})=>{let{continueContent:t="Please continue with your previous answer.",...e}=o;return{name:"length",__corePluginFactory(s){return L({...s.createCorePlugin(e),continueContent:t})}}};var st=(o={})=>({name:"thinking",__corePluginFactory(t){return W(t.createCorePlugin(o))}});var at=o=>{let{getTools:t,beforeCallTools:e,callTool:s,onToolCallStart:r,onToolCallEnd:a,toolCallCancelledContent:l="Tool call cancelled.",toolCallFailedContent:g="Tool call failed.",autoFillMissingToolMessages:d=!1,...C}=o;return{name:"tool",__corePluginFactory(h){let b=h.createCorePlugin(C);return G({...b,getTools:async()=>await t(),beforeCallTools:e?async(f,u)=>{let i=h.resolveReactiveMessage(u.assistantMessage);await e(f,{...h.createVueBaseContext(u),assistantMessage:i,currentMessage:i})}:void 0,callTool:async function*(f,u){let i=h.resolveReactiveMessage(u.assistantMessage),M=h.resolveReactiveMessage(u.toolMessage),P=s(f,{...h.createVueBaseContext(u),assistantMessage:i,currentMessage:i,toolMessage:M});for await(let x of $(P))yield x},onToolCallStart:r?(f,u)=>{let i=h.resolveReactiveMessage(u.assistantMessage),M=h.resolveReactiveMessage(u.toolMessage);r(f,{...h.createVueBaseContext(u),assistantMessage:i,primaryMessage:i,toolMessage:M})}:void 0,onToolCallEnd:a?(f,u)=>{let i=h.resolveReactiveMessage(u.assistantMessage),M=h.resolveReactiveMessage(u.toolMessage);a(f,{...h.createVueBaseContext(u),assistantMessage:i,primaryMessage:i,toolMessage:M,status:u.status,error:u.error})}:void 0,toolCallCancelledContent:l,toolCallFailedContent:g,autoFillMissingToolMessages:d})}}};export{N as AIClient,A as BaseModelProvider,Y as ErrorType,I as IndexedDBStrategy,O as LocalStorageStrategy,S as OpenAIProvider,Z as StreamEventType,te as extractTextFromResponse,ee as formatMessages,q as handleSSEStream,ne as indexedDBStorageStrategyFactory,Ze as lengthPlugin,K as localStorageStrategyFactory,se as sseStreamToGenerator,st as thinkingPlugin,at as toolPlugin,Qe as useConversation,V as useMessage};
@@ -0,0 +1,212 @@
1
+ /**
2
+ * 模型Provider基类
3
+ */
4
+ declare abstract class BaseModelProvider {
5
+ protected config: AIModelConfig;
6
+ /**
7
+ * @param config AI模型配置
8
+ */
9
+ constructor(config: AIModelConfig);
10
+ /**
11
+ * 发送聊天请求并获取响应
12
+ * @param request 聊天请求参数
13
+ * @returns 聊天响应
14
+ */
15
+ abstract chat(request: ChatCompletionRequest): Promise<ChatCompletionResponse>;
16
+ /**
17
+ * 发送流式聊天请求并通过处理器处理响应
18
+ * @param request 聊天请求参数
19
+ * @param handler 流式响应处理器
20
+ */
21
+ abstract chatStream(request: ChatCompletionRequest, handler: StreamHandler): Promise<void>;
22
+ /**
23
+ * 更新配置
24
+ * @param config 新的AI模型配置
25
+ */
26
+ updateConfig(config: AIModelConfig): void;
27
+ /**
28
+ * 获取当前配置
29
+ * @returns AI模型配置
30
+ */
31
+ getConfig(): AIModelConfig;
32
+ /**
33
+ * 验证请求参数
34
+ * @param request 聊天请求参数
35
+ */
36
+ protected validateRequest(request: ChatCompletionRequest): void;
37
+ }
38
+
39
+ type MaybePromise<T> = T | Promise<T>;
40
+ /**
41
+ * 消息角色类型
42
+ */
43
+ type MessageRole = 'system' | 'user' | 'assistant';
44
+ interface ToolCall {
45
+ index: number;
46
+ id: string;
47
+ type: 'function';
48
+ function: {
49
+ name: string;
50
+ arguments: string;
51
+ result?: string;
52
+ };
53
+ }
54
+ interface MessageMetadata {
55
+ createdAt?: number;
56
+ updatedAt?: number;
57
+ id?: string;
58
+ model?: string;
59
+ [key: string]: any;
60
+ }
61
+ /**
62
+ * 聊天消息接口
63
+ */
64
+ interface ChatMessage {
65
+ role: string;
66
+ content: string;
67
+ reasoning_content?: string;
68
+ metadata?: MessageMetadata;
69
+ tool_calls?: ToolCall[];
70
+ tool_call_id?: string;
71
+ [key: string]: any;
72
+ [key: symbol]: any;
73
+ }
74
+ /**
75
+ * 聊天历史记录
76
+ */
77
+ type ChatHistory = ChatMessage[];
78
+ /**
79
+ * 聊天完成请求选项
80
+ */
81
+ interface ChatCompletionOptions {
82
+ model?: string;
83
+ temperature?: number;
84
+ top_p?: number;
85
+ n?: number;
86
+ stream?: boolean;
87
+ max_tokens?: number;
88
+ signal?: AbortSignal;
89
+ }
90
+ /**
91
+ * 聊天完成请求参数
92
+ */
93
+ interface ChatCompletionRequest {
94
+ messages: ChatMessage[];
95
+ options?: ChatCompletionOptions;
96
+ }
97
+ /**
98
+ * 聊天完成响应消息
99
+ */
100
+ interface ChatCompletionResponseMessage {
101
+ role: MessageRole;
102
+ content: string;
103
+ [x: string]: unknown;
104
+ }
105
+ /**
106
+ * 聊天完成响应选择
107
+ */
108
+ interface ChatCompletionResponseChoice {
109
+ index: number;
110
+ message: ChatCompletionResponseMessage;
111
+ finish_reason: string;
112
+ }
113
+ /**
114
+ * 聊天完成响应使用情况
115
+ */
116
+ interface ChatCompletionResponseUsage {
117
+ prompt_tokens: number;
118
+ completion_tokens: number;
119
+ total_tokens: number;
120
+ }
121
+ /**
122
+ * 聊天完成响应
123
+ */
124
+ interface ChatCompletionResponse {
125
+ id: string;
126
+ object: string;
127
+ created: number;
128
+ model: string;
129
+ choices: ChatCompletionResponseChoice[];
130
+ usage: ChatCompletionResponseUsage;
131
+ }
132
+ /**
133
+ * 流式聊天完成响应增量
134
+ */
135
+ interface ChatCompletionStreamResponseDelta {
136
+ content?: string;
137
+ role?: MessageRole;
138
+ [x: string]: unknown;
139
+ }
140
+ /**
141
+ * 流式聊天完成响应选择
142
+ */
143
+ interface ChatCompletionStreamResponseChoice {
144
+ index: number;
145
+ delta: ChatCompletionStreamResponseDelta;
146
+ finish_reason: string | null;
147
+ }
148
+ /**
149
+ * 流式聊天完成响应
150
+ */
151
+ interface ChatCompletionStreamResponse {
152
+ id: string;
153
+ object: string;
154
+ created: number;
155
+ model: string;
156
+ choices: ChatCompletionStreamResponseChoice[];
157
+ }
158
+ /**
159
+ * AI模型提供商类型
160
+ */
161
+ type AIProvider = 'openai' | 'deepseek' | 'custom';
162
+ /**
163
+ * AI模型配置接口
164
+ */
165
+ interface AIModelConfig {
166
+ provider: AIProvider;
167
+ providerImplementation?: BaseModelProvider;
168
+ apiKey?: string;
169
+ apiUrl?: string;
170
+ apiVersion?: string;
171
+ defaultModel?: string;
172
+ defaultOptions?: ChatCompletionOptions;
173
+ }
174
+ /**
175
+ * 错误类型
176
+ */
177
+ declare enum ErrorType {
178
+ NETWORK_ERROR = "network_error",
179
+ AUTHENTICATION_ERROR = "authentication_error",
180
+ RATE_LIMIT_ERROR = "rate_limit_error",
181
+ SERVER_ERROR = "server_error",
182
+ MODEL_ERROR = "model_error",
183
+ TIMEOUT_ERROR = "timeout_error",
184
+ UNKNOWN_ERROR = "unknown_error"
185
+ }
186
+ /**
187
+ * AI适配器错误
188
+ */
189
+ interface AIAdapterError {
190
+ type: ErrorType;
191
+ message: string;
192
+ statusCode?: number;
193
+ originalError?: object;
194
+ }
195
+ /**
196
+ * 流式响应事件类型
197
+ */
198
+ declare enum StreamEventType {
199
+ DATA = "data",
200
+ ERROR = "error",
201
+ DONE = "done"
202
+ }
203
+ /**
204
+ * 流式响应处理器
205
+ */
206
+ interface StreamHandler {
207
+ onData: (data: ChatCompletionStreamResponse) => void;
208
+ onError: (error: AIAdapterError) => void;
209
+ onDone: (finishReason?: string) => void;
210
+ }
211
+
212
+ export { type AIModelConfig as A, BaseModelProvider as B, type ChatCompletionRequest as C, ErrorType as E, type MaybePromise as M, type StreamHandler as S, type ToolCall as T, type ChatCompletionResponse as a, type ChatMessage as b, type AIAdapterError as c, type AIProvider as d, type ChatCompletionOptions as e, type ChatCompletionResponseChoice as f, type ChatCompletionResponseMessage as g, type ChatCompletionResponseUsage as h, type ChatCompletionStreamResponse as i, type ChatCompletionStreamResponseChoice as j, type ChatCompletionStreamResponseDelta as k, type ChatHistory as l, type MessageMetadata as m, type MessageRole as n, StreamEventType as o };