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