@opentiny/tiny-robot-kit 0.4.2-alpha.3 → 0.4.2-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
- import { A as AIModelConfig, C as ChatCompletionRequest, a as ChatCompletionResponse, S as StreamHandler, B as BaseModelProvider, b as ChatMessage, M as MaybePromise, T as ToolCall } from './types-D0E0rOVi.js';
2
- export { c as AIAdapterError, d as AIProvider, e as ChatCompletionOptions, f as ChatCompletionResponseChoice, g as ChatCompletionResponseMessage, h as ChatCompletionResponseUsage, i as ChatCompletionStreamResponse, j as ChatCompletionStreamResponseChoice, k as ChatCompletionStreamResponseDelta, l as ChatHistory, E as ErrorType, m as MessageMetadata, n as MessageRole, o as StreamEventType } from './types-D0E0rOVi.js';
1
+ import { a as AIModelConfig, f as ChatCompletionRequest, g as ChatCompletionResponse, W as StreamHandler, B as BaseModelProvider, p as ChatMessage, M as MaybePromise, X as ToolCall, N as SkillCommandRequest, O as SkillCommandResult, T as SkillPluginState, $ as ToolSource, _ as ToolProviderItem } from './skillPlugin-D6X-p9fQ.js';
2
+ export { A as AIAdapterError, b as AIProvider, C as ChatCompletionOptions, h as ChatCompletionResponseChoice, i as ChatCompletionResponseMessage, j as ChatCompletionResponseUsage, k as ChatCompletionStreamResponse, l as ChatCompletionStreamResponseChoice, m as ChatCompletionStreamResponseDelta, n as ChatHistory, E as ErrorType, u as MessageMetadata, x as MessageRole, V as StreamEventType } from './skillPlugin-D6X-p9fQ.js';
3
3
  import { Ref, ComputedRef } from 'vue';
4
+ import { S as SkillDefinition } from './types-ChCZ8jKB.js';
5
+ import 'openai/resources';
4
6
 
5
7
  /**
6
8
  * AI客户端类
@@ -460,10 +462,38 @@ declare const lengthPlugin: (options?: UseMessagePlugin & {
460
462
  continueContent?: string;
461
463
  }) => UseMessagePlugin;
462
464
 
465
+ type VueSkillSource = SkillDefinition[] | undefined;
466
+ type VueSkillSourceRef = VueSkillSource | Ref<VueSkillSource> | ComputedRef<VueSkillSource>;
467
+ type UseMessageSkillPluginOptions = UseMessagePlugin & {
468
+ /**
469
+ * 当前请求要使用的 skills。支持普通数组、ref 或 computed。
470
+ */
471
+ skills?: VueSkillSourceRef;
472
+ /**
473
+ * 动态返回当前请求要使用的 skills。
474
+ */
475
+ getSkills?: (context: BasePluginContext) => MaybePromise<VueSkillSourceRef>;
476
+ /**
477
+ * 执行模型为某个 skill 规划的后端命令。
478
+ *
479
+ * @experimental 该 API 仍在设计和验证中,命令协议、返回结构和安全边界后续可能调整。
480
+ */
481
+ executeSkillCommand?: (request: SkillCommandRequest, context: BasePluginContext) => MaybePromise<SkillCommandResult>;
482
+ /**
483
+ * skills 解析并转换为插件状态后触发。
484
+ */
485
+ onSkillsResolved?: (state: SkillPluginState, context: BasePluginContext) => MaybePromise<void>;
486
+ };
487
+ declare const skillPlugin: (options: UseMessageSkillPluginOptions) => UseMessagePlugin;
488
+
463
489
  declare const thinkingPlugin: (options?: UseMessagePlugin) => UseMessagePlugin;
464
490
 
465
491
  interface UseMessageToolActionContext extends BasePluginContext {
466
492
  assistantMessage: ChatMessage;
493
+ /**
494
+ * 当前工具的来源。
495
+ */
496
+ toolSource?: ToolSource;
467
497
  /**
468
498
  * @deprecated use `assistantMessage` instead
469
499
  */
@@ -474,6 +504,10 @@ interface UseMessageCallToolContext extends UseMessageToolActionContext {
474
504
  }
475
505
  interface UseMessageToolCallContext extends BasePluginContext {
476
506
  assistantMessage: ChatMessage;
507
+ /**
508
+ * 当前工具的来源。
509
+ */
510
+ toolSource: ToolSource;
477
511
  /**
478
512
  * @deprecated use `assistantMessage` instead
479
513
  */
@@ -484,7 +518,7 @@ declare const toolPlugin: (options: UseMessagePlugin & {
484
518
  /**
485
519
  * 获取工具列表的函数。
486
520
  */
487
- getTools: () => Promise<Tool[]>;
521
+ getTools: (context: BasePluginContext) => Promise<ToolProviderItem[]>;
488
522
  /**
489
523
  * 在处理包含 tool_calls 的响应前调用。
490
524
  */
@@ -530,4 +564,4 @@ declare const toolPlugin: (options: UseMessagePlugin & {
530
564
 
531
565
  declare const useMessage: (options: UseMessageOptions) => UseMessageReturn;
532
566
 
533
- export { AIClient, AIModelConfig, BaseModelProvider, type BasePluginContext, type ChatCompletion, ChatCompletionRequest, ChatCompletionResponse, ChatMessage, type Choice, type CompletionChoice, type Conversation, type ConversationInfo, type ConversationStorageStrategy, type DeltaChoice, type IndexedDBConfig, IndexedDBStrategy, type LocalStorageConfig, LocalStorageStrategy, MaybePromise, type MessageRequestBody, OpenAIProvider, type RequestProcessingState, type RequestState, type ResponseProvider, StreamHandler, type Tool, ToolCall, type Usage, type UseConversationOptions, type UseConversationReturn, type UseMessageCallToolContext, type UseMessageOptions, type UseMessagePlugin, type UseMessageReturn, type UseMessageToolActionContext, type UseMessageToolCallContext, extractTextFromResponse, formatMessages, handleSSEStream, indexedDBStorageStrategyFactory, lengthPlugin, localStorageStrategyFactory, sseStreamToGenerator, thinkingPlugin, toolPlugin, useConversation, useMessage };
567
+ export { AIClient, AIModelConfig, BaseModelProvider, type BasePluginContext, type ChatCompletion, ChatCompletionRequest, ChatCompletionResponse, ChatMessage, type Choice, type CompletionChoice, type Conversation, type ConversationInfo, type ConversationStorageStrategy, type DeltaChoice, type IndexedDBConfig, IndexedDBStrategy, type LocalStorageConfig, LocalStorageStrategy, MaybePromise, type MessageRequestBody, OpenAIProvider, type RequestProcessingState, type RequestState, type ResponseProvider, StreamHandler, type Tool, ToolCall, type Usage, type UseConversationOptions, type UseConversationReturn, type UseMessageCallToolContext, type UseMessageOptions, type UseMessagePlugin, type UseMessageReturn, type UseMessageSkillPluginOptions, type UseMessageToolActionContext, type UseMessageToolCallContext, type VueSkillSource, type VueSkillSourceRef, extractTextFromResponse, formatMessages, handleSSEStream, indexedDBStorageStrategyFactory, lengthPlugin, localStorageStrategyFactory, skillPlugin, sseStreamToGenerator, thinkingPlugin, toolPlugin, useConversation, useMessage };
package/dist/index.js CHANGED
@@ -1,4 +1,8 @@
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(`
1
+ "use strict";var me=Object.defineProperty;var $e=Object.getOwnPropertyDescriptor;var Je=Object.getOwnPropertyNames;var Qe=Object.prototype.hasOwnProperty;var Xe=(s,e)=>{for(var t in e)me(s,t,{get:e[t],enumerable:!0})},Ye=(s,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Je(e))!Qe.call(s,r)&&r!==t&&me(s,r,{get:()=>e[r],enumerable:!(o=$e(e,r))||o.enumerable});return s};var Ze=s=>Ye(me({},"__esModule",{value:!0}),s);var yt={};Xe(yt,{AIClient:()=>le,BaseModelProvider:()=>J,ErrorType:()=>xe,IndexedDBStrategy:()=>X,LocalStorageStrategy:()=>Q,OpenAIProvider:()=>z,StreamEventType:()=>be,extractTextFromResponse:()=>Ae,formatMessages:()=>ke,handleSSEStream:()=>ie,indexedDBStorageStrategyFactory:()=>Oe,lengthPlugin:()=>dt,localStorageStrategyFactory:()=>ue,skillPlugin:()=>ft,sseStreamToGenerator:()=>we,thinkingPlugin:()=>Ct,toolPlugin:()=>ht,useConversation:()=>pt,useMessage:()=>ge});module.exports=Ze(yt);var J=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 xe=(i=>(i.NETWORK_ERROR="network_error",i.AUTHENTICATION_ERROR="authentication_error",i.RATE_LIMIT_ERROR="rate_limit_error",i.SERVER_ERROR="server_error",i.MODEL_ERROR="model_error",i.TIMEOUT_ERROR="timeout_error",i.UNKNOWN_ERROR="unknown_error",i))(xe||{}),be=(o=>(o.DATA="data",o.ERROR="error",o.DONE="done",o))(be||{});function H(s){return{type:s.type||"unknown_error",message:s.message||"\u672A\u77E5\u9519\u8BEF",statusCode:s.statusCode,originalError:s.originalError}}function fe(s){if(!s.response)return H({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?H({type:"authentication_error",message:"\u8EAB\u4EFD\u9A8C\u8BC1\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u60A8\u7684API\u5BC6\u94A5",statusCode:e,originalError:s}):e===429?H({type:"rate_limit_error",message:"\u8D85\u51FAAPI\u8C03\u7528\u9650\u5236\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",statusCode:e,originalError:s}):e>=500?H({type:"server_error",message:"\u670D\u52A1\u5668\u9519\u8BEF\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",statusCode:e,originalError:s}):H({type:"unknown_error",message:t?.error?.message||`\u8BF7\u6C42\u5931\u8D25\uFF0C\u72B6\u6001\u7801: ${e}`,statusCode:e,originalError:s})}return s.code==="ECONNABORTED"?H({type:"timeout_error",message:"\u8BF7\u6C42\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",originalError:s}):H({type:"unknown_error",message:s.message||"\u53D1\u751F\u672A\u77E5\u9519\u8BEF",originalError:s})}async function ie(s,e,t){let o=s.body?.getReader();if(!o)throw new Error("Response body is null");let r=new TextDecoder,n="",a,i;t&&t.addEventListener("abort",()=>{o.cancel().catch(u=>console.error("Error cancelling reader:",u))},{once:!0});try{for(;;){if(t?.aborted){await o.cancel();break}let{done:u,value:l}=await o.read();if(u)break;let p=r.decode(l,{stream:!0});n+=p;let R=n.split(`
2
2
 
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});
3
+ `);n=R.pop()||"";for(let M of R)if(M.trim()!==""){if(M.trim()==="data: [DONE]"){i&&(a=i),e.onDone(a);continue}try{let h=M.match(/^data: (.+)$/m);if(!h)continue;let m=JSON.parse(h[1]);e.onData(m),i=m.choices?.[0]?.finish_reason||void 0}catch(h){console.error("Error parsing SSE message:",h)}}}(n.trim()==="data: [DONE]"||t?.aborted)&&(t?.aborted&&(a="aborted"),e.onDone(a))}catch(u){if(t?.aborted)return;throw u}}function ke(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 Ae(s){return!s.choices||!s.choices.length?"":s.choices[0].message?.content||""}function Ce(s="The operation was aborted"){let e=new Error(s);return e.name="AbortError",e}async function*we(s,e={}){let t=s.body?.getReader();if(!t)throw new Error("ReadableStream not supported");let{signal:o}=e,r=new TextDecoder,n="",a=()=>{t.cancel()};o?.addEventListener("abort",a);try{for(;;){if(o?.aborted)throw Ce();let i;try{i=await t.read()}catch(M){throw o?.aborted?Ce():M}let{done:u,value:l}=i;if(u){if(o?.aborted)throw Ce();return}let p=r.decode(l,{stream:!0});n+=p;let R=n.split(`
4
+ `);n=R.pop()||"";for(let M of R)if(M.trim()!==""&&M.startsWith("data: ")){let h=M.slice(6);if(h==="[DONE]")return;try{yield JSON.parse(h)}catch(m){console.warn("Failed to parse SSE data:",h,m)}}}}finally{o?.removeEventListener("abort",a),t.releaseLock()}}var z=class extends J{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},r={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)};this.apiKey&&Object.assign(r.headers,{Authorization:`Bearer ${this.apiKey}`});let n=await fetch(`${this.baseURL}/chat/completions`,r);if(!n.ok){let a=await n.text();throw new Error(`HTTP error! status: ${n.status}, details: ${a}`)}return await n.json()}catch(o){throw fe(o)}}async chatStream(t,o){let{signal:r,...n}=t.options||{};try{this.validateRequest(t);let a={model:t.options?.model||this.config.defaultModel||this.defaultModel,messages:t.messages,...n,stream:!0},i={method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,Accept:"text/event-stream"},body:JSON.stringify(a),signal:r};this.apiKey&&Object.assign(i.headers,{Authorization:`Bearer ${this.apiKey}`});let u=await fetch(`${this.baseURL}/chat/completions`,i);if(!u.ok){let l=await u.text();throw new Error(`HTTP error! status: ${u.status}, details: ${l}`)}await ie(u,o,r)}catch(a){if(r?.aborted)return;o.onError(fe(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 le=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 z({...t,...e})}else return new z(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 Ee=require("vue");function se(s,e=new WeakMap){if(s==null||typeof s!="object")return s;try{let t=(0,Ee.toRaw)(s);if(e.has(t))return e.get(t);if(Array.isArray(t)){let r=[];return e.set(t,r),r.push(...t.map(n=>se(n,e))),r}if(t instanceof Date||t instanceof RegExp||t instanceof ArrayBuffer||t instanceof Blob)return t;let o={};e.set(t,o);for(let r of Object.keys(t)){let n=Object.getOwnPropertyDescriptor(t,r);if(!n||n.get||n.set)continue;let a=t[r];typeof a!="function"&&typeof a!="symbol"&&(o[r]=se(a,e))}return o}catch(t){return console.warn("unwrapProxy error:",t),Array.isArray(s)?[]:{}}}var ce=s=>s.map(e=>{let{renderContent:t,...o}=e;if(!Array.isArray(t))return e;let r=t.filter(a=>a.type==="collapsible-text"),n=t.filter(a=>a.type==="markdown"||a.type==="text");return r.length>0&&(o.reasoning_content=r.map(a=>a.content).join("")),n.length>0&&(o.content=n.map(a=>a.content).join("")),o});var oe=s=>{let e=localStorage.getItem(s);return e?JSON.parse(e):[]},Q=class{constructor(e="tiny-robot-ai-conversations"){this.storageKey=e}saveConversation(e){try{let t=oe(this.storageKey),o=t.findIndex(r=>r.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 oe(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=oe(this.storageKey),r=o.findIndex(n=>n.id===e);r!==-1&&(o[r].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=oe(this.storageKey).find(n=>n.id===e);return ce(o?.messages||[])}catch(t){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",t),[]}}deleteConversation(e){let t=oe(this.storageKey),o=t.findIndex(r=>r.id===e);o!==-1&&t.splice(o,1),localStorage.setItem(this.storageKey,JSON.stringify(t))}};var Ie=require("idb");var X=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,Ie.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?ce(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=se(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(),r=se(t);await o.put("messages",{conversationId:e,messages:r})}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 ue(s={}){return new Q(s.key||"tiny-robot-ai-conversations")}function Oe(s={}){return new X(s.dbName||"tiny-robot-ai-db",s.dbVersion||1)}var $=require("vue");var W=require("vue");var et=s=>typeof s=="function"?null:Array.isArray(s)?s.length>0?new Set(s):null:new Set([s]),qe=s=>{let e=new Set,t=(n,a)=>{try{n.listener(a)}catch(i){console.error("Error in message state subscriber:",i)}};return{notify:n=>{let a=new Set(Array.isArray(n)?n:[n]),i=s(),u=Array.from(e);for(let l of u){if(l.kinds){let p=!1;for(let R of l.kinds)if(a.has(R)){p=!0;break}if(!p)continue}t(l,i)}},subscribe:(n,a)=>{let i=typeof n=="function"?n:a;if(!i)throw new Error("subscribe listener is required");let u={kinds:et(n),listener:i};return e.add(u),t(u,s()),()=>{e.delete(u)}}}};var N=require("vue");var Be=s=>(0,N.reactive)(s),he=s=>{let e=(0,N.isProxy)(s)?(0,N.toRaw)(s):s;if(Array.isArray(e))return e.map(t=>he(t));if(e&&typeof e=="object"){let t={};for(let[o,r]of Object.entries(e))t[o]=he(r);return t}return e},_e=()=>{let s=!1,e=(0,N.ref)("idle"),t=(0,N.ref)(void 0),o=(0,N.ref)([]),r=(0,N.computed)(()=>e.value==="processing"),n=p=>{if(s)throw new Error("Message state adapter is already initialized");e.value=p.requestState,t.value=p.processingState,o.value=p.messages.map(Be),s=!0},a=p=>Be(p),i=()=>{if(!s)throw new Error("Message state adapter is not initialized");return{requestState:e.value,processingState:t.value,messages:he(o.value),isProcessing:r.value}},u=qe(i);return{requestState:e,processingState:t,messages:o,isProcessing:r,initialize:n,getState:i,createMessage:a,mutate:(p,R)=>{if(!s)throw new Error("Message state adapter is not initialized");let M={get requestState(){return e.value},set requestState(O){e.value=O},get processingState(){return t.value},set processingState(O){t.value=O},get messages(){return o.value},set messages(O){o.value=O.map(a)}},h=!1;if(R(M,()=>{h=!0}),h)return;(Array.isArray(p)?p:[p]).includes("messages")&&(o.value=[...o.value]),u.notify(p)},subscribe:u.subscribe}};var ne=(s={})=>{let{continueContent:e="Please continue with your previous answer.",...t}=s;return{name:"length",...t,onAfterRequest:async o=>{let{lastChoice:r,appendMessage:n,requestNext:a}=o;return r?.finish_reason==="length"&&(n({role:"user",content:e}),a()),t.onAfterRequest?.(o)}}};var Fe={listSkillFiles:"list_skill_files",readSkillFile:"read_skill_file"},tt="execute_skill_command",De=[{type:"function",function:{name:Fe.listSkillFiles,description:"List files available from the current skills.",parameters:{type:"object",properties:{skillName:{type:"string",description:"Optional skill name. When omitted, files from all current skills are listed."}},additionalProperties:!1}}},{type:"function",function:{name:Fe.readSkillFile,description:"Read a file from a current skill by skill name and relative path.",parameters:{type:"object",properties:{skillName:{type:"string",description:"Skill name that owns the file."},path:{type:"string",description:"File path relative to the skill root."}},required:["skillName","path"],additionalProperties:!1}}}],st={type:"function",function:{name:tt,description:"Execute a command in the backend runtime environment for a selected skill.",parameters:{type:"object",properties:{skillName:{type:"string",description:"Name of the current skill that provides the command instructions."},command:{type:"string",description:"Command name to execute in the skill backend runtime."},args:{type:"array",description:"Command arguments passed as argv items.",items:{type:"string"}}},required:["skillName","command","args"],additionalProperties:!1}}},ye=(s,e)=>({skillName:s,id:e.id,path:e.path,kind:e.kind,mimeType:e.mimeType,size:e.size,lastModified:e.lastModified}),Me=s=>{let e=s.function.arguments;if(!e)return{};try{let t=JSON.parse(e);return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}catch{return{}}},ot=s=>Array.isArray(s)&&s.every(e=>typeof e=="string")?s:void 0,nt=s=>{if(!s.some(o=>!!o.files?.length))return[];let t=o=>{if(!(typeof o!="string"||!o))return s.find(r=>r.name===o)};return[{tool:De[0],handler:o=>{let r=Me(o),n=t(r.skillName);return{files:(n?[n]:s).flatMap(i=>(i.files??[]).map(u=>ye(i.name,u)))}}},{tool:De[1],handler:o=>{let r=Me(o),n=t(r.skillName),a=typeof r.path=="string"?r.path:void 0;if(!n)return{error:"skill_not_found"};if(!a)return{error:"file_path_required",skillName:n.name};let i=n.files?.find(u=>u.path===a);return i?i.kind==="binary"?{error:"binary_file_not_readable",file:ye(n.name,i)}:{file:ye(n.name,i),content:i.content}:{error:"file_not_found",skillName:n.name,path:a}}}]},rt=(s,e)=>{if(!e||s.length===0)return[];let t=o=>{if(!(typeof o!="string"||!o))return s.find(r=>r.name===o)};return[{tool:st,handler:async o=>{let r=Me(o),n=t(r.skillName),a=typeof r.command=="string"?r.command:void 0,i=ot(r.args);return n?a?i?e({skill:n,skillName:n.name,command:a,args:i}):{error:"args_required",skillName:n.name,command:a}:{error:"command_required",skillName:n.name}:{error:"skill_not_found"}}}]},Ue=(s,e={})=>[...nt(s),...rt(s,e.executeSkillCommand)],Ne=async s=>{let e=[];for(let t of s){let o=t.instructions?.trim();o&&e.push(`## ${t.name}
5
+
6
+ ${o}`)}if(e.length!==0)return{role:"system",content:["Apply these skill instructions when generating the response.",...e].join(`
7
+
8
+ `)}};var Se="__tiny_robot_skill",ve=s=>{let{getSkills:e,executeSkillCommand:t,onSkillsResolved:o,...r}=s;return{name:"skill",...r,provideTools:async n=>n.customContext[Se]?.runtimeTools??[],onTurnStart:async n=>{let a=await e?.(n)??[],i={skills:a,skillNames:a.map(u=>u.name),runtimeTools:Ue(a,{executeSkillCommand:t&&(u=>t(u,n))})};return n.setCustomContext({[Se]:i}),await o?.(i,n),r.onTurnStart?.(n)},onBeforeRequest:async n=>{let a=n.customContext[Se];if(a){let i=await Ne(a.skills);i&&(n.requestBody.messages=[i,...n.requestBody.messages])}return r.onBeforeRequest?.(n)}}};var re=(s={})=>{let e=(t,o)=>!!t.thinking!==o||!!t.open!==o;return{name:"thinking",...s,onCompletionChunk(t){let{choice:o,currentMessage:r,updateCurrentMessage:n}=t,a=o,i=a?.message?.reasoning_content||a?.delta?.reasoning_content,u=typeof i=="string"&&i.trim()!=="";return u?r.state&&typeof r.state=="object"?e(r.state,u)&&n(l=>{l.state.thinking=!0,l.state.open=!0}):n(l=>{l.state={thinking:u,open:u}}):r.state&&typeof r.state=="object"&&"thinking"in r.state&&e(r.state,u)&&n(l=>{l.state.thinking=!1,l.state.open=!1}),s.onCompletionChunk?.(t)},onTurnEnd(t){let{currentTurn:o,mutate:r}=t,n=o.at(-1);return n?.state&&typeof n.state=="object"&&"thinking"in n.state&&e(n.state,!1)&&r("messages",()=>{n.state.thinking=!1,n.state.open=!1}),s.onTurnEnd?.(t)}}};var Y=class extends Error{constructor(e){super(e),this.name="AbortError"}};function at(s){if(s.aborted)return{promise:Promise.reject(new Y(String(s.reason??"Aborted"))),cleanup:()=>{}};let e=null;return{promise:new Promise((r,n)=>{e=()=>{n(new Y(String(s.reason??"Aborted")))},s.addEventListener("abort",e,{once:!0})}),cleanup:()=>{e&&(s.removeEventListener("abort",e),e=null)}}}function Ke(s,e){let{promise:t,cleanup:o}=at(e);return Promise.race([s,t]).finally(o)}function We(s,e){let t={};for(let o in s)e.includes(o)&&(t[o]=s[o]);return t}function Le(s,e){let t={};for(let o in s)e.includes(o)||(t[o]=s[o]);return t}async function*ee(s){if(je(s)){yield*s;return}let e=await s;if(je(e)){yield*e;return}yield e}function je(s){return s&&typeof s=="object"&&typeof s[Symbol.asyncIterator]=="function"}var Pe=s=>typeof s=="object"&&s!==null,Ve=s=>Pe(s)&&typeof s.index=="number",Z=(s,e)=>{for(let[t,o]of Object.entries(e)){let r=s[t];if(r)if(typeof r=="string"&&typeof o=="string")t==="type"&&r||(s[t]=r+o);else if(Array.isArray(r)&&Array.isArray(o))if(r.every(n=>Ve(n))&&o.every(n=>Ve(n))){let n=new Map(r.map(l=>[l.index,l])),a=new Map(o.map(l=>[l.index,l]));for(let[l,p]of a)if(n.has(l)){let R=n.get(l);n.set(l,Z(R,p))}else n.set(l,p);let i=Math.max(...Array.from(n.keys()),-1)+1,u=i>r.length?Array.from({length:i}):r;for(let[l,p]of n)u[l]=p;s[t]=u}else s[t]=[...r,...o];else Pe(r)&&Pe(o)&&(s[t]=Z(r,o));else s[t]=o}return s};function it({messages:s,cancelledContent:e,createMessage:t,mutate:o}){let r=[];for(let n=0;n<s.length;n++){let a=s[n];if(a.role==="assistant"&&a.tool_calls&&a.tool_calls.length>0){let i=new Set(a.tool_calls.map(p=>p.id)),u=new Set;for(let p=n+1;p<s.length;p++){let R=s[p];R.role==="tool"&&R.tool_call_id&&i.has(R.tool_call_id)&&u.add(R.tool_call_id)}let l=a.tool_calls.map(p=>p.id).filter(p=>!u.has(p));l.length>0&&r.push({insertAfterIndex:n,missingToolCallIds:l})}}r.length!==0&&o("messages",n=>{for(let a=r.length-1;a>=0;a--){let{insertAfterIndex:i,missingToolCallIds:u}=r[a],l=u.map(p=>t({role:"tool",tool_call_id:p,content:e}));n.messages.splice(i+1,0,...l)}})}var Re=s=>{let{getTools:e,beforeCallTools:t,callTool:o,onToolCallStart:r,onToolCallEnd:n,toolCallCancelledContent:a="Tool call cancelled.",toolCallFailedContent:i="Tool call failed.",autoFillMissingToolMessages:u=!1,...l}=s,p=(C,S)=>{var c,g;return C.state??(C.state={}),(c=C.state).toolCall??(c.toolCall={}),(g=C.state.toolCall)[S]??(g[S]={}),C},R=(...C)=>{let[S,{assistantMessage:c,mutate:g}]=C;g("messages",()=>{let d=p(c,S.id);d.state.toolCall[S.id].status="running"}),r?.(...C)},M=(...C)=>{let[S,{status:c,assistantMessage:g,mutate:d}]=C;d("messages",()=>{let b=p(g,S.id);b.state.toolCall[S.id].status=c}),n?.(...C)},h=C=>C.type==="function"&&"function"in C,m=C=>!!(C&&typeof C=="object"&&"tool"in C&&"handler"in C),T=C=>{let S=C;return typeof S.provideTools=="function"?S:void 0},O=(C,S)=>typeof C.disabled=="function"?C.disabled(S):!!C.disabled,D=async(C,S=[])=>{let c=[];for(let A of C.plugins){let f=T(A);!O(A,C)&&f&&c.push(...(await f.provideTools(C)).map(v=>({item:v,source:{type:"toolProvider",pluginName:A.name}})))}let g=[...c,...(await e(C)).map(A=>({item:A,source:{type:"toolPlugin"}}))],d=[],b=new Map,I=new Map,k=new Set,P=A=>{let f=A.function.name;if(k.has(f))throw new Error(`Duplicate tool name "${f}" detected. Tool names must be unique because tool calls are routed by function.name.`);k.add(f)};S.forEach(P);for(let{item:A,source:f}of g){let v=m(A)?A.tool:A;P(v),I.set(v.function.name,f),m(A)?(d.push(A.tool),b.set(A.tool.function.name,A)):d.push(A)}return{tools:d,runtimeToolMap:b,toolSourceMap:I}};return{name:"tool",...l,onTurnStart:C=>{let{getState:S,createMessage:c,mutate:g}=C,d=S().messages;return u&&it({messages:d,cancelledContent:a,createMessage:c,mutate:g}),l.onTurnStart?.(C)},onBeforeRequest:async C=>{let{requestBody:S}=C,c=Array.isArray(S.tools)?S.tools:[],{tools:g}=await D(C,c);return g&&g.length>0&&(S.tools=c.length?[...c,...g]:g),l.onBeforeRequest?.(C)},onAfterRequest:async C=>{let{currentMessage:S,lastChoice:c,appendMessage:g,abortSignal:d,setRequestState:b,requestNext:I,mutate:k,createMessage:P}=C;if(c?.finish_reason!=="tool_calls"||!S.tool_calls?.length)return;b("processing","calling-tools"),await t?.(S.tool_calls,{...C,assistantMessage:S});let{runtimeToolMap:A,toolSourceMap:f}=await D(C),v=S.tool_calls.map(async x=>{let E=Math.floor(Date.now()/1e3),_=!1,y=P({role:"tool",tool_call_id:x.id,content:"",metadata:{createdAt:E,updatedAt:E}});g(y);let w=h(x)?x:void 0,j=w?f.get(w.function.name)??{type:"unknown"}:{type:"unknown"},F={...C,assistantMessage:S,toolMessage:y,toolSource:j};R(x,F);try{let B=w?A.get(w.function.name):void 0,q=B&&w?B.handler(w,F):o(x,F),K=ee(q);for await(let V of K)k("messages",()=>{if((typeof V=="string"&&V.length>0||V&&typeof V=="object"&&Object.keys(V).length>0)&&(_=!0),typeof V=="string")y.content+=V;else{let te={};try{let U=Array.isArray(y.content)?y.content.map(L=>L.text).join(""):y.content;te=JSON.parse(U||"{}")}catch(U){console.warn(U)}y.content=JSON.stringify(Z(te,V))}y.metadata.updatedAt=Math.floor(Date.now()/1e3)});M(x,{...F,status:"success"})}catch(B){let q=B instanceof Error?B:new Error(String(B));if(d.aborted){M(x,{...F,status:"cancelled",error:q});return}console.error(B),_||k("messages",()=>{y.content=i,y.metadata.updatedAt=Math.floor(Date.now()/1e3)}),M(x,{...F,status:"failed",error:q})}});return await Promise.all(v),d.aborted||I(),l.onAfterRequest?.(C)}}};var lt=async()=>{throw new Error("Response provider is not set")},ct=s=>{let e=[];for(let t of s){if(t.name){let o=e.findIndex(r=>r.name===t.name);o!==-1&&e.splice(o,1)}e.push(t)}return e},G=(s,e)=>typeof s.disabled=="function"?s.disabled(e):!!s.disabled,Te=(s,e={})=>{let{initialMessages:t=[],requestMessageFields:o=[],requestMessageFieldsExclude:r=["state","metadata","loading"],responseProvider:n=lt,onCompletionChunk:a,plugins:i=[]}=e,u={requestState:"idle",processingState:void 0,messages:[...t]};s.initialize(u);let l={currentTurn:[],customContext:{},abortController:null,responseProvider:n},p=[re(),ne()],R=ct(p.concat(i)),M=()=>s.getState(),h=f=>s.createMessage(f),m=s.subscribe,T=s.mutate,O=f=>!f||Object.keys(f).length===0?!1:Object.values(f).some(v=>!!v),D=f=>{let v=f;return o.length&&(v=v.map(x=>We(x,o))),r.length&&(v=v.map(x=>Le(x,r))),v},C=f=>{Object.assign(l.customContext,f)},S=(f,v)=>{T("requestState",(x,E)=>{if(x.requestState===f&&x.processingState===v){E();return}x.requestState=f,x.processingState=f==="processing"?v??"requesting":void 0})},c=(...f)=>{let v=f.map(x=>h(x));return T("messages",x=>{x.messages.push(...v)}),l.currentTurn.push(...v),v},g=f=>({getState:M,createMessage:h,mutate:T,abortSignal:f,currentTurn:l.currentTurn,plugins:R,customContext:l.customContext,setRequestState:S,setCustomContext:C});async function d(f,v,x={}){S("processing","requesting");let E={messages:M().messages},_=g(v);for(let B of R.filter(q=>!G(q,_)))await B.onBeforeRequest?.({..._,requestBody:E});E.messages=D(E.messages);let y={role:"assistant",content:"",loading:!0};[y]=c(y),x.setAssistantMessage?.(y);let w=f(E,v),j=ee(w),F;for await(let B of j){S("processing","completing"),T("messages",(U,L)=>{y.loading?y.loading=void 0:L()});let q=(B.choices||[]).find(U=>U.index===0)??B.choices?.[0];if(!q)continue;F=q;let K=()=>{T("messages",()=>{y.metadata||(y.metadata={});let{created:U,...L}=B;y.metadata.createdAt=U,y.metadata.updatedAt=Math.floor(Date.now()/1e3),Object.assign(y.metadata,L);let ae="delta"in q&&O(q.delta)&&q.delta||"message"in q&&O(q.message)&&q.message||null;if(ae?.role&&(y.role=ae.role),ae){let{role:Mt,...Ge}=ae;Z(y,Ge)}})},V=U=>{T("messages",()=>{U(y)})};if(a){let U=g(v);a({...U,chunk:B,choice:q,currentMessage:y,updateCurrentMessage:V},K)}else K();let te=g(v);for(let U of R.filter(L=>!G(L,te)))U.onCompletionChunk?.({...te,abortSignal:v,chunk:B,choice:q,currentMessage:y,updateCurrentMessage:V})}await b(y,f,v,F,x)}async function b(f,v,x,E,_){let y=!1,w=g(x),j=R.filter(F=>!G(F,w)).map(F=>{if(!F.onAfterRequest)return null;let B=K=>{c(...Array.isArray(K)?K:[K])},q=()=>{y=!0};return F.onAfterRequest({...w,currentMessage:f,lastChoice:E,appendMessage:B,requestNext:q})}).filter(F=>F!==null);await Ke(Promise.all(j),x),y&&await d(v,x,_)}async function I(){let f=new AbortController;l.abortController=f,l.customContext={};let v=null,x=E=>{v=E};try{S("processing","requesting");let E=g(f.signal);for(let w of R.filter(j=>!G(j,E)))await w.onTurnStart?.(E);let _=l.responseProvider;try{await d(_,f.signal,{setAssistantMessage:x}),S("completed")}catch(w){if(f.signal.aborted||w instanceof Y||w instanceof Error&&w.name==="AbortError")S("aborted");else throw w}let y=g(f.signal);for(let w of R.filter(j=>!G(j,y)))await w.onTurnEnd?.(y)}catch(E){S("error");let _=!1,y=g(f.signal);for(let w of R.filter(j=>!G(j,y)))w.onError&&(_=!0,w.onError({...y,error:E}));if(!_)throw E}finally{let E=g(f.signal);for(let _ of R.filter(y=>!G(y,E)))try{_.onFinally?.(E)}catch(y){console.error(`Error in onFinally hook for plugin [${_.name||"Anonymous"}]:`,y)}l.abortController=null,l.currentTurn=[],T("messages",(_,y)=>{v?.loading?v.loading=void 0:y()})}}async function k(f){if(!f||!f.trim()){console.warn("Cannot send empty message");return}if(M().requestState==="processing"){console.warn("Cannot send message while processing is in progress");return}let v=Math.floor(Date.now()/1e3);c({role:"user",content:f.trim(),metadata:{createdAt:v,updatedAt:v}}),await I()}async function P(...f){if(M().requestState==="processing"){console.warn("Cannot send message while processing is in progress");return}c(...f),await I()}async function A(){l.abortController?.abort(),M().isProcessing&&await new Promise(f=>{let v=()=>{};v=m("requestState",x=>{x.isProcessing||(v(),f())})})}return{getState:M,subscribe:m,sendMessage:k,send:P,abort:A,setResponseProvider(f){l.responseProvider=f}}};var ge=s=>{let{initialMessages:e=[],requestMessageFields:t=[],requestMessageFieldsExclude:o=["state","metadata","loading"],plugins:r=[],responseProvider:n,onCompletionChunk:a}=s,i=_e(),u=m=>i.messages.value.find(T=>T===m||(0,W.toRaw)(T)===m||(0,W.toRaw)(T)===(0,W.toRaw)(m))??m,l=m=>({messages:i.messages.value,currentTurn:m.currentTurn.map(T=>u(T)),requestState:i.requestState.value,processingState:i.processingState.value,plugins:r,setRequestState:m.setRequestState,abortSignal:m.abortSignal,customContext:m.customContext,setCustomContext:m.setCustomContext}),p=m=>{let T=m;if(typeof T.__corePluginFactory=="function")return T.__corePluginFactory({createCorePlugin:p,createVueBaseContext:l,resolveReactiveMessage:u});let{name:O,disabled:D,onTurnStart:C,onTurnEnd:S,onBeforeRequest:c,onAfterRequest:g,onCompletionChunk:d,onError:b,onFinally:I}=m,k={};return O!==void 0&&(k.name=O),D!==void 0&&(k.disabled=typeof D=="function"?P=>D(l(P)):D),C&&(k.onTurnStart=P=>C(l(P))),S&&(k.onTurnEnd=P=>S(l(P))),c&&(k.onBeforeRequest=P=>c({...l(P),requestBody:P.requestBody})),g&&(k.onAfterRequest=P=>g({...l(P),currentMessage:u(P.currentMessage),lastChoice:P.lastChoice,appendMessage:P.appendMessage,requestNext:P.requestNext})),d&&(k.onCompletionChunk=P=>d({...l(P),currentMessage:u(P.currentMessage),choice:P.choice,chunk:P.chunk})),b&&(k.onError=P=>b({...l(P),error:P.error})),I&&(k.onFinally=P=>I(l(P))),k},M=Te(i,{initialMessages:e,requestMessageFields:t,requestMessageFieldsExclude:o,responseProvider:n,onCompletionChunk:a?(m,T)=>{if(a)return a({...l(m),currentMessage:u(m.currentMessage),choice:m.choice,chunk:m.chunk},T)}:void 0,plugins:r.map(m=>p(m))}),h=(0,W.ref)(n);return(0,W.watch)(h,m=>{M.setResponseProvider(m)},{flush:"sync"}),{requestState:i.requestState,processingState:i.processingState,messages:i.messages,responseProvider:h,isProcessing:i.isProcessing,sendMessage:M.sendMessage,send:M.send,abortRequest:M.abort}};var pe=require("vue");function ze(s,e=200,t=!1,o=!0,r=!1){return ut(gt(e,t,o,r),s)}function ut(s,e){function t(...o){return new Promise((r,n)=>{Promise.resolve(s(()=>e.apply(this,o),{fn:e,thisArg:this,args:o})).then(r).catch(n)})}return t}var He=()=>{};function gt(...s){let e=0,t,o=!0,r=He,n,a,i,u,l;!(0,pe.isRef)(s[0])&&typeof s[0]=="object"?{delay:a,trailing:i=!0,leading:u=!0,rejectOnCancel:l=!1}=s[0]:[a,i=!0,u=!0,l=!1]=s;let p=()=>{t&&(clearTimeout(t),t=void 0,r(),r=He)};return M=>{let h=(0,pe.toValue)(a),m=Date.now()-e,T=()=>n=M();return p(),h<=0?(e=Date.now(),T()):(m>h?(e=Date.now(),(u||!o)&&T()):i&&(n=new Promise((O,D)=>{r=l?D:O,t=setTimeout(()=>{e=Date.now(),o=!0,O(T()),p()},Math.max(0,h-m))})),!u&&!t&&(t=setTimeout(()=>o=!0,h)),o=!1,n)}}var pt=s=>{let e=s.storage||ue(),t=(0,$.ref)([]),o=new Map,r=new Map,n=(0,$.ref)(null),a=(0,$.computed)(()=>{let c=n.value;if(!c)return null;let g=t.value.find(b=>b.id===c);if(!g)return null;let d=o.get(c);return d?{...g,engine:d}:null}),i=c=>{if(!e?.saveMessages)return;let g=c||n.value,d=t.value.find(I=>I.id===g);if(!d)return;d.updatedAt=Date.now(),e?.saveConversation?.(d);let b=o.get(d.id);b&&e.saveMessages(d.id,b.messages.value)},u=(c,g)=>{if(!s.autoSaveMessages||!e?.saveMessages)return;let d=r.get(c);d&&d();let b=s.autoSaveThrottle??1e3,I=ze(()=>{i(c)},b,!0,!0),k=(0,$.watch)(g.messages,I,{deep:!0});r.set(c,k)},l=c=>{let g=r.get(c);g&&(g(),r.delete(c))};e?.loadConversations&&Promise.resolve(e.loadConversations()).then(c=>{if(!c?.length)return[];if(t.value.length===0)return t.value=c,t.value;let g=new Map(t.value.map(d=>[d.id,d]));return c.forEach(d=>{g.has(d.id)||g.set(d.id,d)}),t.value=Array.from(g.values()),t.value}).then(c=>{s.onLoad?.(c)}).catch(c=>{console.error("[useConversation] loadConversations failed:",c)});let p=async(c,g)=>{let d=o.get(c);if(d)return d;let b=g?.initialMessages??s.useMessageOptions.initialMessages??[];if(e?.loadMessages)try{b=await e.loadMessages(c)}catch(k){console.error("[useConversation] loadMessages failed:",k)}let I=ge({...s.useMessageOptions,...g,initialMessages:b});return o.set(c,I),u(c,I),I};function R(){return Date.now().toString(36)+Math.random().toString(36).substring(2,9)}let M=c=>{let{id:g=R(),title:d,metadata:b,useMessageOptions:I}=c||{},k=Date.now(),P={id:g,title:d,createdAt:k,updatedAt:k,metadata:b};t.value.unshift(P);let A=ge({...s.useMessageOptions,...I});return o.set(g,A),u(g,A),e?.saveConversation?.(P),e?.saveMessages?.(g,A.messages.value),n.value=g,a.value},h=c=>{let{excludeId:g}=c||{};o.forEach((d,b)=>{if(g&&b===g)return;d.isProcessing?.value||(l(b),o.delete(b))})};return{conversations:t,activeConversationId:n,activeConversation:a,createConversation:M,switchConversation:async c=>c?n.value===c?a.value:t.value.find(d=>d.id===c)?(await p(c),h({excludeId:c}),n.value=c,a.value):null:null,deleteConversation:async c=>{let g=t.value.findIndex(b=>b.id===c);if(g===-1)return;await o.get(c)?.abortRequest(),l(c),o.delete(c),t.value.splice(g,1),e?.deleteConversation?.(c),n.value===c&&(n.value=null,h())},clear:()=>{t.value.map(g=>g.id).forEach(g=>{e?.deleteConversation?.(g)}),o.forEach(g=>{g.abortRequest()}),r.forEach(g=>{g()}),t.value=[],o.clear(),r.clear(),n.value=null},updateConversationTitle:(c,g)=>{let d=t.value.find(b=>b.id===c);d&&(d.title=g,d.updatedAt=Date.now(),e?.saveConversation?.(d))},saveMessages:i,sendMessage:c=>{a.value?.engine.sendMessage(c)},abortActiveRequest:async()=>{await a.value?.engine.abortRequest()}}};var dt=(s={})=>{let{continueContent:e="Please continue with your previous answer.",...t}=s;return{name:"length",__corePluginFactory(o){return ne({...o.createCorePlugin(t),continueContent:e})}}};var de=require("vue");var mt=s=>(0,de.isRef)(s)?(0,de.unref)(s):s,ft=s=>{let{skills:e,getSkills:t,executeSkillCommand:o,onSkillsResolved:r,...n}=s;return{name:"skill",__corePluginFactory(a){return ve({...a.createCorePlugin(n),getSkills:async i=>{let u=a.createVueBaseContext(i),l=t?await t(u):e;return mt(l)},executeSkillCommand:o?(i,u)=>o(i,a.createVueBaseContext(u)):void 0,onSkillsResolved:r?(i,u)=>r(i,a.createVueBaseContext(u)):void 0})}}};var Ct=(s={})=>({name:"thinking",__corePluginFactory(e){return re(e.createCorePlugin(s))}});var ht=s=>{let{getTools:e,beforeCallTools:t,callTool:o,onToolCallStart:r,onToolCallEnd:n,toolCallCancelledContent:a="Tool call cancelled.",toolCallFailedContent:i="Tool call failed.",autoFillMissingToolMessages:u=!1,...l}=s;return{name:"tool",__corePluginFactory(p){let R=p.createCorePlugin(l);return Re({...R,getTools:async M=>e(p.createVueBaseContext(M)),beforeCallTools:t?async(M,h)=>{let m=p.resolveReactiveMessage(h.assistantMessage);await t(M,{...p.createVueBaseContext(h),assistantMessage:m,currentMessage:m})}:void 0,callTool:async function*(M,h){let m=p.resolveReactiveMessage(h.assistantMessage),T=p.resolveReactiveMessage(h.toolMessage),O=o(M,{...p.createVueBaseContext(h),assistantMessage:m,currentMessage:m,toolMessage:T,toolSource:h.toolSource});for await(let D of ee(O))yield D},onToolCallStart:r?(M,h)=>{let m=p.resolveReactiveMessage(h.assistantMessage),T=p.resolveReactiveMessage(h.toolMessage);r(M,{...p.createVueBaseContext(h),assistantMessage:m,primaryMessage:m,toolMessage:T,toolSource:h.toolSource})}:void 0,onToolCallEnd:n?(M,h)=>{let m=p.resolveReactiveMessage(h.assistantMessage),T=p.resolveReactiveMessage(h.toolMessage);n(M,{...p.createVueBaseContext(h),assistantMessage:m,primaryMessage:m,toolMessage:T,toolSource:h.toolSource,status:h.status,error:h.error})}:void 0,toolCallCancelledContent:a,toolCallFailedContent:i,autoFillMissingToolMessages:u})}}};0&&(module.exports={AIClient,BaseModelProvider,ErrorType,IndexedDBStrategy,LocalStorageStrategy,OpenAIProvider,StreamEventType,extractTextFromResponse,formatMessages,handleSSEStream,indexedDBStorageStrategyFactory,lengthPlugin,localStorageStrategyFactory,skillPlugin,sseStreamToGenerator,thinkingPlugin,toolPlugin,useConversation,useMessage});
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
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(`
1
+ import{b as H,c as L,f as W,g as $,h as G,j as J,k as z}from"./chunk-6JEZBNBO.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 Z=(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))(Z||{}),ee=(o=>(o.DATA="data",o.ERROR="error",o.DONE="done",o))(ee||{});function b(s){return{type:s.type||"unknown_error",message:s.message||"\u672A\u77E5\u9519\u8BEF",statusCode:s.statusCode,originalError:s.originalError}}function _(s){if(!s.response)return b({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:t,data:e}=s.response;return t===401||t===403?b({type:"authentication_error",message:"\u8EAB\u4EFD\u9A8C\u8BC1\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u60A8\u7684API\u5BC6\u94A5",statusCode:t,originalError:s}):t===429?b({type:"rate_limit_error",message:"\u8D85\u51FAAPI\u8C03\u7528\u9650\u5236\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",statusCode:t,originalError:s}):t>=500?b({type:"server_error",message:"\u670D\u52A1\u5668\u9519\u8BEF\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",statusCode:t,originalError:s}):b({type:"unknown_error",message:e?.error?.message||`\u8BF7\u6C42\u5931\u8D25\uFF0C\u72B6\u6001\u7801: ${t}`,statusCode:t,originalError:s})}return s.code==="ECONNABORTED"?b({type:"timeout_error",message:"\u8BF7\u6C42\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",originalError:s}):b({type:"unknown_error",message:s.message||"\u53D1\u751F\u672A\u77E5\u9519\u8BEF",originalError:s})}async function q(s,t,e){let o=s.body?.getReader();if(!o)throw new Error("Response body is null");let r=new TextDecoder,n="",i,c;e&&e.addEventListener("abort",()=>{o.cancel().catch(d=>console.error("Error cancelling reader:",d))},{once:!0});try{for(;;){if(e?.aborted){await o.cancel();break}let{done:d,value:f}=await o.read();if(d)break;let h=r.decode(f,{stream:!0});n+=h;let S=n.split(`
2
2
 
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};
3
+ `);n=S.pop()||"";for(let m of S)if(m.trim()!==""){if(m.trim()==="data: [DONE]"){c&&(i=c),t.onDone(i);continue}try{let g=m.match(/^data: (.+)$/m);if(!g)continue;let l=JSON.parse(g[1]);t.onData(l),c=l.choices?.[0]?.finish_reason||void 0}catch(g){console.error("Error parsing SSE message:",g)}}}(n.trim()==="data: [DONE]"||e?.aborted)&&(e?.aborted&&(i="aborted"),t.onDone(i))}catch(d){if(e?.aborted)return;throw d}}function te(s){return s.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 oe(s){return!s.choices||!s.choices.length?"":s.choices[0].message?.content||""}function F(s="The operation was aborted"){let t=new Error(s);return t.name="AbortError",t}async function*se(s,t={}){let e=s.body?.getReader();if(!e)throw new Error("ReadableStream not supported");let{signal:o}=t,r=new TextDecoder,n="",i=()=>{e.cancel()};o?.addEventListener("abort",i);try{for(;;){if(o?.aborted)throw F();let c;try{c=await e.read()}catch(m){throw o?.aborted?F():m}let{done:d,value:f}=c;if(d){if(o?.aborted)throw F();return}let h=r.decode(f,{stream:!0});n+=h;let S=n.split(`
4
+ `);n=S.pop()||"";for(let m of S)if(m.trim()!==""&&m.startsWith("data: ")){let g=m.slice(6);if(g==="[DONE]")return;try{yield JSON.parse(g)}catch(l){console.warn("Failed to parse SSE data:",g,l)}}}}finally{o?.removeEventListener("abort",i),e.releaseLock()}}var T=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 o={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(o)};this.apiKey&&Object.assign(r.headers,{Authorization:`Bearer ${this.apiKey}`});let n=await fetch(`${this.baseURL}/chat/completions`,r);if(!n.ok){let i=await n.text();throw new Error(`HTTP error! status: ${n.status}, details: ${i}`)}return await n.json()}catch(o){throw _(o)}}async chatStream(e,o){let{signal:r,...n}=e.options||{};try{this.validateRequest(e);let i={model:e.options?.model||this.config.defaultModel||this.defaultModel,messages:e.messages,...n,stream:!0},c={method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,Accept:"text/event-stream"},body:JSON.stringify(i),signal:r};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 q(d,o,r)}catch(i){if(r?.aborted)return;o.onError(_(i))}}updateConfig(e){super.updateConfig(e),e.apiUrl&&(this.baseURL=e.apiUrl),e.apiKey&&(this.apiKey=e.apiKey),e.defaultModel&&(this.defaultModel=e.defaultModel)}};var V=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 T({...e,...t})}else return new T(t)}async chat(t){return this.provider.chat(t)}async chatStream(t,e){let o={...t,options:{...t.options,stream:!0}};return this.provider.chatStream(o,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 re}from"vue";function w(s,t=new WeakMap){if(s==null||typeof s!="object")return s;try{let e=re(s);if(t.has(e))return t.get(e);if(Array.isArray(e)){let r=[];return t.set(e,r),r.push(...e.map(n=>w(n,t))),r}if(e instanceof Date||e instanceof RegExp||e instanceof ArrayBuffer||e instanceof Blob)return e;let o={};t.set(e,o);for(let r of Object.keys(e)){let n=Object.getOwnPropertyDescriptor(e,r);if(!n||n.get||n.set)continue;let i=e[r];typeof i!="function"&&typeof i!="symbol"&&(o[r]=w(i,t))}return o}catch(e){return console.warn("unwrapProxy error:",e),Array.isArray(s)?[]:{}}}var I=s=>s.map(t=>{let{renderContent:e,...o}=t;if(!Array.isArray(e))return t;let r=e.filter(i=>i.type==="collapsible-text"),n=e.filter(i=>i.type==="markdown"||i.type==="text");return r.length>0&&(o.reasoning_content=r.map(i=>i.content).join("")),n.length>0&&(o.content=n.map(i=>i.content).join("")),o});var k=s=>{let t=localStorage.getItem(s);return t?JSON.parse(t):[]},E=class{constructor(t="tiny-robot-ai-conversations"){this.storageKey=t}saveConversation(t){try{let e=k(this.storageKey),o=e.findIndex(r=>r.id===t.id);o!==-1?Object.assign(e[o],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 k(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 o=k(this.storageKey),r=o.findIndex(n=>n.id===t);r!==-1&&(o[r].messages=e),localStorage.setItem(this.storageKey,JSON.stringify(o))}catch(o){console.error("\u4FDD\u5B58\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",o)}}loadMessages(t){try{let o=k(this.storageKey).find(n=>n.id===t);return I(o?.messages||[])}catch(e){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",e),[]}}deleteConversation(t){let e=k(this.storageKey),o=e.findIndex(r=>r.id===t);o!==-1&&e.splice(o,1),localStorage.setItem(this.storageKey,JSON.stringify(e))}};import{openDB as ne}from"idb";var O=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 ne(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 o=await(await this.getDB()).get("messages",t);return o?I(o.messages):[]}catch(e){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",e),[]}}async saveConversation(t){try{let e=await this.getDB(),o=w(t);await e.put("conversations",o)}catch(e){throw console.error("\u4FDD\u5B58\u4F1A\u8BDD\u5931\u8D25:",e),e}}async saveMessages(t,e){try{let o=await this.getDB(),r=w(e);await o.put("messages",{conversationId:t,messages:r})}catch(o){throw console.error("\u4FDD\u5B58\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",o),o}}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 N(s={}){return new E(s.key||"tiny-robot-ai-conversations")}function ae(s={}){return new O(s.dbName||"tiny-robot-ai-db",s.dbVersion||1)}import{computed as de,ref as Y,watch as me}from"vue";import{ref as ie,toRaw as K,watch as le}from"vue";var j=s=>{let{initialMessages:t=[],requestMessageFields:e=[],requestMessageFieldsExclude:o=["state","metadata","loading"],plugins:r=[],responseProvider:n,onCompletionChunk:i}=s,c=H(),d=l=>c.messages.value.find(M=>M===l||K(M)===l||K(M)===K(l))??l,f=l=>({messages:c.messages.value,currentTurn:l.currentTurn.map(M=>d(M)),requestState:c.requestState.value,processingState:c.processingState.value,plugins:r,setRequestState:l.setRequestState,abortSignal:l.abortSignal,customContext:l.customContext,setCustomContext:l.setCustomContext}),h=l=>{let M=l;if(typeof M.__corePluginFactory=="function")return M.__corePluginFactory({createCorePlugin:h,createVueBaseContext:f,resolveReactiveMessage:d});let{name:P,disabled:x,onTurnStart:U,onTurnEnd:B,onBeforeRequest:a,onAfterRequest:u,onCompletionChunk:p,onError:y,onFinally:R}=l,v={};return P!==void 0&&(v.name=P),x!==void 0&&(v.disabled=typeof x=="function"?C=>x(f(C)):x),U&&(v.onTurnStart=C=>U(f(C))),B&&(v.onTurnEnd=C=>B(f(C))),a&&(v.onBeforeRequest=C=>a({...f(C),requestBody:C.requestBody})),u&&(v.onAfterRequest=C=>u({...f(C),currentMessage:d(C.currentMessage),lastChoice:C.lastChoice,appendMessage:C.appendMessage,requestNext:C.requestNext})),p&&(v.onCompletionChunk=C=>p({...f(C),currentMessage:d(C.currentMessage),choice:C.choice,chunk:C.chunk})),y&&(v.onError=C=>y({...f(C),error:C.error})),R&&(v.onFinally=C=>R(f(C))),v},m=z(c,{initialMessages:t,requestMessageFields:e,requestMessageFieldsExclude:o,responseProvider:n,onCompletionChunk:i?(l,M)=>{if(i)return i({...f(l),currentMessage:d(l.currentMessage),choice:l.choice,chunk:l.chunk},M)}:void 0,plugins:r.map(l=>h(l))}),g=ie(n);return le(g,l=>{m.setResponseProvider(l)},{flush:"sync"}),{requestState:c.requestState,processingState:c.processingState,messages:c.messages,responseProvider:g,isProcessing:c.isProcessing,sendMessage:m.sendMessage,send:m.send,abortRequest:m.abort}};import{isRef as ce,toValue as ue}from"vue";function X(s,t=200,e=!1,o=!0,r=!1){return ge(pe(t,e,o,r),s)}function ge(s,t){function e(...o){return new Promise((r,n)=>{Promise.resolve(s(()=>t.apply(this,o),{fn:t,thisArg:this,args:o})).then(r).catch(n)})}return e}var Q=()=>{};function pe(...s){let t=0,e,o=!0,r=Q,n,i,c,d,f;!ce(s[0])&&typeof s[0]=="object"?{delay:i,trailing:c=!0,leading:d=!0,rejectOnCancel:f=!1}=s[0]:[i,c=!0,d=!0,f=!1]=s;let h=()=>{e&&(clearTimeout(e),e=void 0,r(),r=Q)};return m=>{let g=ue(i),l=Date.now()-t,M=()=>n=m();return h(),g<=0?(t=Date.now(),M()):(l>g?(t=Date.now(),(d||!o)&&M()):c&&(n=new Promise((P,x)=>{r=f?x:P,e=setTimeout(()=>{t=Date.now(),o=!0,P(M()),h()},Math.max(0,g-l))})),!d&&!e&&(e=setTimeout(()=>o=!0,g)),o=!1,n)}}var et=s=>{let t=s.storage||N(),e=Y([]),o=new Map,r=new Map,n=Y(null),i=de(()=>{let a=n.value;if(!a)return null;let u=e.value.find(y=>y.id===a);if(!u)return null;let p=o.get(a);return p?{...u,engine:p}:null}),c=a=>{if(!t?.saveMessages)return;let u=a||n.value,p=e.value.find(R=>R.id===u);if(!p)return;p.updatedAt=Date.now(),t?.saveConversation?.(p);let y=o.get(p.id);y&&t.saveMessages(p.id,y.messages.value)},d=(a,u)=>{if(!s.autoSaveMessages||!t?.saveMessages)return;let p=r.get(a);p&&p();let y=s.autoSaveThrottle??1e3,R=X(()=>{c(a)},y,!0,!0),v=me(u.messages,R,{deep:!0});r.set(a,v)},f=a=>{let u=r.get(a);u&&(u(),r.delete(a))};t?.loadConversations&&Promise.resolve(t.loadConversations()).then(a=>{if(!a?.length)return[];if(e.value.length===0)return e.value=a,e.value;let u=new Map(e.value.map(p=>[p.id,p]));return a.forEach(p=>{u.has(p.id)||u.set(p.id,p)}),e.value=Array.from(u.values()),e.value}).then(a=>{s.onLoad?.(a)}).catch(a=>{console.error("[useConversation] loadConversations failed:",a)});let h=async(a,u)=>{let p=o.get(a);if(p)return p;let y=u?.initialMessages??s.useMessageOptions.initialMessages??[];if(t?.loadMessages)try{y=await t.loadMessages(a)}catch(v){console.error("[useConversation] loadMessages failed:",v)}let R=j({...s.useMessageOptions,...u,initialMessages:y});return o.set(a,R),d(a,R),R};function S(){return Date.now().toString(36)+Math.random().toString(36).substring(2,9)}let m=a=>{let{id:u=S(),title:p,metadata:y,useMessageOptions:R}=a||{},v=Date.now(),C={id:u,title:p,createdAt:v,updatedAt:v,metadata:y};e.value.unshift(C);let D=j({...s.useMessageOptions,...R});return o.set(u,D),d(u,D),t?.saveConversation?.(C),t?.saveMessages?.(u,D.messages.value),n.value=u,i.value},g=a=>{let{excludeId:u}=a||{};o.forEach((p,y)=>{if(u&&y===u)return;p.isProcessing?.value||(f(y),o.delete(y))})};return{conversations:e,activeConversationId:n,activeConversation:i,createConversation:m,switchConversation:async a=>a?n.value===a?i.value:e.value.find(p=>p.id===a)?(await h(a),g({excludeId:a}),n.value=a,i.value):null:null,deleteConversation:async a=>{let u=e.value.findIndex(y=>y.id===a);if(u===-1)return;await o.get(a)?.abortRequest(),f(a),o.delete(a),e.value.splice(u,1),t?.deleteConversation?.(a),n.value===a&&(n.value=null,g())},clear:()=>{e.value.map(u=>u.id).forEach(u=>{t?.deleteConversation?.(u)}),o.forEach(u=>{u.abortRequest()}),r.forEach(u=>{u()}),e.value=[],o.clear(),r.clear(),n.value=null},updateConversationTitle:(a,u)=>{let p=e.value.find(y=>y.id===a);p&&(p.title=u,p.updatedAt=Date.now(),t?.saveConversation?.(p))},saveMessages:c,sendMessage:a=>{i.value?.engine.sendMessage(a)},abortActiveRequest:async()=>{await i.value?.engine.abortRequest()}}};var st=(s={})=>{let{continueContent:t="Please continue with your previous answer.",...e}=s;return{name:"length",__corePluginFactory(o){return L({...o.createCorePlugin(e),continueContent:t})}}};import{isRef as fe,unref as Ce}from"vue";var he=s=>fe(s)?Ce(s):s,it=s=>{let{skills:t,getSkills:e,executeSkillCommand:o,onSkillsResolved:r,...n}=s;return{name:"skill",__corePluginFactory(i){return W({...i.createCorePlugin(n),getSkills:async c=>{let d=i.createVueBaseContext(c),f=e?await e(d):t;return he(f)},executeSkillCommand:o?(c,d)=>o(c,i.createVueBaseContext(d)):void 0,onSkillsResolved:r?(c,d)=>r(c,i.createVueBaseContext(d)):void 0})}}};var ut=(s={})=>({name:"thinking",__corePluginFactory(t){return $(t.createCorePlugin(s))}});var mt=s=>{let{getTools:t,beforeCallTools:e,callTool:o,onToolCallStart:r,onToolCallEnd:n,toolCallCancelledContent:i="Tool call cancelled.",toolCallFailedContent:c="Tool call failed.",autoFillMissingToolMessages:d=!1,...f}=s;return{name:"tool",__corePluginFactory(h){let S=h.createCorePlugin(f);return J({...S,getTools:async m=>t(h.createVueBaseContext(m)),beforeCallTools:e?async(m,g)=>{let l=h.resolveReactiveMessage(g.assistantMessage);await e(m,{...h.createVueBaseContext(g),assistantMessage:l,currentMessage:l})}:void 0,callTool:async function*(m,g){let l=h.resolveReactiveMessage(g.assistantMessage),M=h.resolveReactiveMessage(g.toolMessage),P=o(m,{...h.createVueBaseContext(g),assistantMessage:l,currentMessage:l,toolMessage:M,toolSource:g.toolSource});for await(let x of G(P))yield x},onToolCallStart:r?(m,g)=>{let l=h.resolveReactiveMessage(g.assistantMessage),M=h.resolveReactiveMessage(g.toolMessage);r(m,{...h.createVueBaseContext(g),assistantMessage:l,primaryMessage:l,toolMessage:M,toolSource:g.toolSource})}:void 0,onToolCallEnd:n?(m,g)=>{let l=h.resolveReactiveMessage(g.assistantMessage),M=h.resolveReactiveMessage(g.toolMessage);n(m,{...h.createVueBaseContext(g),assistantMessage:l,primaryMessage:l,toolMessage:M,toolSource:g.toolSource,status:g.status,error:g.error})}:void 0,toolCallCancelledContent:i,toolCallFailedContent:c,autoFillMissingToolMessages:d})}}};export{V as AIClient,A as BaseModelProvider,Z as ErrorType,O as IndexedDBStrategy,E as LocalStorageStrategy,T as OpenAIProvider,ee as StreamEventType,oe as extractTextFromResponse,te as formatMessages,q as handleSSEStream,ae as indexedDBStorageStrategyFactory,st as lengthPlugin,N as localStorageStrategyFactory,it as skillPlugin,se as sseStreamToGenerator,ut as thinkingPlugin,mt as toolPlugin,et as useConversation,j as useMessage};
@@ -0,0 +1,14 @@
1
+ import { b as SkillFile } from './types-ChCZ8jKB.mjs';
2
+
3
+ interface FsSkillFilesOptions {
4
+ /**
5
+ * 遍历时排除的目录名。
6
+ */
7
+ ignoredDirectories?: string[];
8
+ }
9
+ /**
10
+ * Node.js 目录适配器,将本地 skill 目录读取为 SkillFile 记录。
11
+ */
12
+ declare const loadSkillFilesFromFs: (root: string, options?: FsSkillFilesOptions) => Promise<SkillFile[]>;
13
+
14
+ export { type FsSkillFilesOptions, loadSkillFilesFromFs };
package/dist/node.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ import { b as SkillFile } from './types-ChCZ8jKB.js';
2
+
3
+ interface FsSkillFilesOptions {
4
+ /**
5
+ * 遍历时排除的目录名。
6
+ */
7
+ ignoredDirectories?: string[];
8
+ }
9
+ /**
10
+ * Node.js 目录适配器,将本地 skill 目录读取为 SkillFile 记录。
11
+ */
12
+ declare const loadSkillFilesFromFs: (root: string, options?: FsSkillFilesOptions) => Promise<SkillFile[]>;
13
+
14
+ export { type FsSkillFilesOptions, loadSkillFilesFromFs };
package/dist/node.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";var F=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var h=Object.prototype.hasOwnProperty;var g=(t,i)=>{for(var e in i)F(t,e,{get:i[e],enumerable:!0})},w=(t,i,e,n)=>{if(i&&typeof i=="object"||typeof i=="function")for(let s of x(i))!h.call(t,s)&&s!==e&&F(t,s,{get:()=>i[s],enumerable:!(n=S(i,s))||n.enumerable});return t};var y=t=>w(F({},"__esModule",{value:!0}),t);var P={};g(P,{loadSkillFilesFromFs:()=>k});module.exports=y(P);var l=require("fs/promises"),p=require("path");var d=t=>{let i=t.split("\\").join("/").replace(/^\.\/+/,"");return!i||i.startsWith("/")||i.includes("\0")||i.split("/").some(e=>e===".."||e==="")?null:i},u=t=>[".md",".txt",".json"].includes(z(t)),z=t=>{let i=t.split("/").at(-1)||t,e=i.lastIndexOf(".");return e===-1?"":i.slice(e).toLowerCase()};var k=async(t,i={})=>{let e=new Set(i.ignoredDirectories??[".git","node_modules"]),n=[],s=async a=>{let f=await(0,l.readdir)(a,{withFileTypes:!0});for(let c of f){let o=(0,p.join)(a,c.name);if(c.isDirectory()){e.has(c.name)||await s(o);continue}if(!c.isFile())continue;let r=await(0,l.stat)(o);if(!r.isFile())continue;let m=d((0,p.relative)(t,o));m&&(u(m)?n.push({path:m,kind:"text",content:await(0,l.readFile)(o,"utf-8"),size:r.size,lastModified:r.mtimeMs}):n.push({path:m,kind:"binary",content:await(0,l.readFile)(o),size:r.size,lastModified:r.mtimeMs}))}};return await s(t),n.sort((a,f)=>a.path.localeCompare(f.path))};0&&(module.exports={loadSkillFilesFromFs});
package/dist/node.mjs ADDED
@@ -0,0 +1 @@
1
+ import{a as c,b as m}from"./chunk-ZO2ZONVX.mjs";import{readdir as d,readFile as f,stat as k}from"fs/promises";import{join as S,relative as u}from"path";var h=async(r,p={})=>{let F=new Set(p.ignoredDirectories??[".git","node_modules"]),o=[],a=async t=>{let n=await d(t,{withFileTypes:!0});for(let s of n){let i=S(t,s.name);if(s.isDirectory()){F.has(s.name)||await a(i);continue}if(!s.isFile())continue;let e=await k(i);if(!e.isFile())continue;let l=c(u(r,i));l&&(m(l)?o.push({path:l,kind:"text",content:await f(i,"utf-8"),size:e.size,lastModified:e.mtimeMs}):o.push({path:l,kind:"binary",content:await f(i),size:e.size,lastModified:e.mtimeMs}))}};return await a(r),o.sort((t,n)=>t.path.localeCompare(n.path))};export{h as loadSkillFilesFromFs};