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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,215 +1,8 @@
1
+ import { a as AIModelConfig, f as ChatCompletionRequest, g as ChatCompletionResponse, W as StreamHandler, B as BaseModelProvider, p as ChatMessage, M as MaybePromise, X as ToolCall, N as SkillCommandRequest, O as SkillCommandResult, T as SkillPluginState, $ as ToolSource, _ as ToolProviderItem } from './skillPlugin-D6X-p9fQ.js';
2
+ export { A as AIAdapterError, b as AIProvider, C as ChatCompletionOptions, h as ChatCompletionResponseChoice, i as ChatCompletionResponseMessage, j as ChatCompletionResponseUsage, k as ChatCompletionStreamResponse, l as ChatCompletionStreamResponseChoice, m as ChatCompletionStreamResponseDelta, n as ChatHistory, E as ErrorType, u as MessageMetadata, x as MessageRole, V as StreamEventType } from './skillPlugin-D6X-p9fQ.js';
1
3
  import { Ref, ComputedRef } from 'vue';
2
-
3
- /**
4
- * 模型Provider基类
5
- */
6
- declare abstract class BaseModelProvider {
7
- protected config: AIModelConfig;
8
- /**
9
- * @param config AI模型配置
10
- */
11
- constructor(config: AIModelConfig);
12
- /**
13
- * 发送聊天请求并获取响应
14
- * @param request 聊天请求参数
15
- * @returns 聊天响应
16
- */
17
- abstract chat(request: ChatCompletionRequest): Promise<ChatCompletionResponse>;
18
- /**
19
- * 发送流式聊天请求并通过处理器处理响应
20
- * @param request 聊天请求参数
21
- * @param handler 流式响应处理器
22
- */
23
- abstract chatStream(request: ChatCompletionRequest, handler: StreamHandler): Promise<void>;
24
- /**
25
- * 更新配置
26
- * @param config 新的AI模型配置
27
- */
28
- updateConfig(config: AIModelConfig): void;
29
- /**
30
- * 获取当前配置
31
- * @returns AI模型配置
32
- */
33
- getConfig(): AIModelConfig;
34
- /**
35
- * 验证请求参数
36
- * @param request 聊天请求参数
37
- */
38
- protected validateRequest(request: ChatCompletionRequest): void;
39
- }
40
-
41
- type MaybePromise<T> = T | Promise<T>;
42
- /**
43
- * 消息角色类型
44
- */
45
- type MessageRole = 'system' | 'user' | 'assistant';
46
- interface ToolCall {
47
- index: number;
48
- id: string;
49
- type: 'function';
50
- function: {
51
- name: string;
52
- arguments: string;
53
- result?: string;
54
- };
55
- }
56
- interface MessageMetadata {
57
- createdAt?: number;
58
- updatedAt?: number;
59
- id?: string;
60
- model?: string;
61
- [key: string]: any;
62
- }
63
- /**
64
- * 聊天消息接口
65
- */
66
- interface ChatMessage {
67
- role: string;
68
- content: string;
69
- reasoning_content?: string;
70
- metadata?: MessageMetadata;
71
- tool_calls?: ToolCall[];
72
- tool_call_id?: string;
73
- [key: string]: any;
74
- [key: symbol]: any;
75
- }
76
- /**
77
- * 聊天历史记录
78
- */
79
- type ChatHistory = ChatMessage[];
80
- /**
81
- * 聊天完成请求选项
82
- */
83
- interface ChatCompletionOptions {
84
- model?: string;
85
- temperature?: number;
86
- top_p?: number;
87
- n?: number;
88
- stream?: boolean;
89
- max_tokens?: number;
90
- signal?: AbortSignal;
91
- }
92
- /**
93
- * 聊天完成请求参数
94
- */
95
- interface ChatCompletionRequest {
96
- messages: ChatMessage[];
97
- options?: ChatCompletionOptions;
98
- }
99
- /**
100
- * 聊天完成响应消息
101
- */
102
- interface ChatCompletionResponseMessage {
103
- role: MessageRole;
104
- content: string;
105
- [x: string]: unknown;
106
- }
107
- /**
108
- * 聊天完成响应选择
109
- */
110
- interface ChatCompletionResponseChoice {
111
- index: number;
112
- message: ChatCompletionResponseMessage;
113
- finish_reason: string;
114
- }
115
- /**
116
- * 聊天完成响应使用情况
117
- */
118
- interface ChatCompletionResponseUsage {
119
- prompt_tokens: number;
120
- completion_tokens: number;
121
- total_tokens: number;
122
- }
123
- /**
124
- * 聊天完成响应
125
- */
126
- interface ChatCompletionResponse {
127
- id: string;
128
- object: string;
129
- created: number;
130
- model: string;
131
- choices: ChatCompletionResponseChoice[];
132
- usage: ChatCompletionResponseUsage;
133
- }
134
- /**
135
- * 流式聊天完成响应增量
136
- */
137
- interface ChatCompletionStreamResponseDelta {
138
- content?: string;
139
- role?: MessageRole;
140
- [x: string]: unknown;
141
- }
142
- /**
143
- * 流式聊天完成响应选择
144
- */
145
- interface ChatCompletionStreamResponseChoice {
146
- index: number;
147
- delta: ChatCompletionStreamResponseDelta;
148
- finish_reason: string | null;
149
- }
150
- /**
151
- * 流式聊天完成响应
152
- */
153
- interface ChatCompletionStreamResponse {
154
- id: string;
155
- object: string;
156
- created: number;
157
- model: string;
158
- choices: ChatCompletionStreamResponseChoice[];
159
- }
160
- /**
161
- * AI模型提供商类型
162
- */
163
- type AIProvider = 'openai' | 'deepseek' | 'custom';
164
- /**
165
- * AI模型配置接口
166
- */
167
- interface AIModelConfig {
168
- provider: AIProvider;
169
- providerImplementation?: BaseModelProvider;
170
- apiKey?: string;
171
- apiUrl?: string;
172
- apiVersion?: string;
173
- defaultModel?: string;
174
- defaultOptions?: ChatCompletionOptions;
175
- }
176
- /**
177
- * 错误类型
178
- */
179
- declare enum ErrorType {
180
- NETWORK_ERROR = "network_error",
181
- AUTHENTICATION_ERROR = "authentication_error",
182
- RATE_LIMIT_ERROR = "rate_limit_error",
183
- SERVER_ERROR = "server_error",
184
- MODEL_ERROR = "model_error",
185
- TIMEOUT_ERROR = "timeout_error",
186
- UNKNOWN_ERROR = "unknown_error"
187
- }
188
- /**
189
- * AI适配器错误
190
- */
191
- interface AIAdapterError {
192
- type: ErrorType;
193
- message: string;
194
- statusCode?: number;
195
- originalError?: object;
196
- }
197
- /**
198
- * 流式响应事件类型
199
- */
200
- declare enum StreamEventType {
201
- DATA = "data",
202
- ERROR = "error",
203
- DONE = "done"
204
- }
205
- /**
206
- * 流式响应处理器
207
- */
208
- interface StreamHandler {
209
- onData: (data: ChatCompletionStreamResponse) => void;
210
- onError: (error: AIAdapterError) => void;
211
- onDone: (finishReason?: string) => void;
212
- }
4
+ import { S as SkillDefinition } from './types-ChCZ8jKB.js';
5
+ import 'openai/resources';
213
6
 
214
7
  /**
215
8
  * AI客户端类
@@ -353,6 +146,7 @@ interface ChatCompletion {
353
146
  choices: CompletionChoice[];
354
147
  usage?: Usage;
355
148
  }
149
+ type ResponseProvider<T = ChatCompletion> = (requestBody: MessageRequestBody, abortSignal: AbortSignal) => Promise<T> | AsyncGenerator<T> | Promise<AsyncGenerator<T>>;
356
150
  interface UseMessageOptions {
357
151
  initialMessages?: ChatMessage[];
358
152
  /**
@@ -366,7 +160,7 @@ interface UseMessageOptions {
366
160
  */
367
161
  requestMessageFieldsExclude?: string[];
368
162
  plugins?: UseMessagePlugin[];
369
- responseProvider: <T = ChatCompletion>(requestBody: MessageRequestBody, abortSignal: AbortSignal) => Promise<T> | AsyncGenerator<T> | Promise<AsyncGenerator<T>>;
163
+ responseProvider: ResponseProvider;
370
164
  /**
371
165
  * 全局的数据块处理钩子,在接收到每个响应数据块时触发。
372
166
  * 注意:此钩子与插件中的 onCompletionChunk 有区别。
@@ -664,48 +458,82 @@ declare function sseStreamToGenerator<T = any>(response: Response, options?: {
664
458
 
665
459
  declare const useConversation: (options: UseConversationOptions) => UseConversationReturn;
666
460
 
667
- declare const fallbackRolePlugin: (options?: UseMessagePlugin & {
668
- fallbackRole?: string;
669
- }) => UseMessagePlugin;
670
-
671
461
  declare const lengthPlugin: (options?: UseMessagePlugin & {
672
462
  continueContent?: string;
673
463
  }) => UseMessagePlugin;
674
464
 
465
+ type VueSkillSource = SkillDefinition[] | undefined;
466
+ type VueSkillSourceRef = VueSkillSource | Ref<VueSkillSource> | ComputedRef<VueSkillSource>;
467
+ type UseMessageSkillPluginOptions = UseMessagePlugin & {
468
+ /**
469
+ * 当前请求要使用的 skills。支持普通数组、ref 或 computed。
470
+ */
471
+ skills?: VueSkillSourceRef;
472
+ /**
473
+ * 动态返回当前请求要使用的 skills。
474
+ */
475
+ getSkills?: (context: BasePluginContext) => MaybePromise<VueSkillSourceRef>;
476
+ /**
477
+ * 执行模型为某个 skill 规划的后端命令。
478
+ *
479
+ * @experimental 该 API 仍在设计和验证中,命令协议、返回结构和安全边界后续可能调整。
480
+ */
481
+ executeSkillCommand?: (request: SkillCommandRequest, context: BasePluginContext) => MaybePromise<SkillCommandResult>;
482
+ /**
483
+ * skills 解析并转换为插件状态后触发。
484
+ */
485
+ onSkillsResolved?: (state: SkillPluginState, context: BasePluginContext) => MaybePromise<void>;
486
+ };
487
+ declare const skillPlugin: (options: UseMessageSkillPluginOptions) => UseMessagePlugin;
488
+
675
489
  declare const thinkingPlugin: (options?: UseMessagePlugin) => UseMessagePlugin;
676
490
 
677
- /**
678
- * 消息排除模式:从 messages 数组中直接移除消息。
679
- * 使用此模式时,消息会被完全从数组中移除,不会保留在 messages 中。
680
- */
681
- declare const EXCLUDE_MODE_REMOVE: "remove";
491
+ interface UseMessageToolActionContext extends BasePluginContext {
492
+ assistantMessage: ChatMessage;
493
+ /**
494
+ * 当前工具的来源。
495
+ */
496
+ toolSource?: ToolSource;
497
+ /**
498
+ * @deprecated use `assistantMessage` instead
499
+ */
500
+ currentMessage: ChatMessage;
501
+ }
502
+ interface UseMessageCallToolContext extends UseMessageToolActionContext {
503
+ toolMessage: ChatMessage;
504
+ }
505
+ interface UseMessageToolCallContext extends BasePluginContext {
506
+ assistantMessage: ChatMessage;
507
+ /**
508
+ * 当前工具的来源。
509
+ */
510
+ toolSource: ToolSource;
511
+ /**
512
+ * @deprecated use `assistantMessage` instead
513
+ */
514
+ primaryMessage: ChatMessage;
515
+ toolMessage: ChatMessage;
516
+ }
682
517
  declare const toolPlugin: (options: UseMessagePlugin & {
683
518
  /**
684
519
  * 获取工具列表的函数。
685
520
  */
686
- getTools: () => Promise<Tool[]>;
521
+ getTools: (context: BasePluginContext) => Promise<ToolProviderItem[]>;
687
522
  /**
688
523
  * 在处理包含 tool_calls 的响应前调用。
689
524
  */
690
- beforeCallTools?: (toolCalls: ToolCall[], context: BasePluginContext & {
691
- currentMessage: ChatMessage;
692
- }) => Promise<void>;
525
+ beforeCallTools?: (toolCalls: ToolCall[], context: UseMessageToolActionContext) => Promise<void>;
693
526
  /**
694
527
  * 执行单个工具调用并返回其文本结果的函数。
695
528
  */
696
- callTool: (toolCall: ToolCall, context: BasePluginContext & {
697
- currentMessage: ChatMessage;
698
- }) => Promise<string | Record<string, any>> | AsyncGenerator<string | Record<string, any>>;
529
+ callTool: (toolCall: ToolCall, context: UseMessageCallToolContext) => Promise<string | Record<string, any>> | AsyncGenerator<string | Record<string, any>>;
699
530
  /**
700
531
  * 工具调用开始时的回调函数。
701
532
  * 触发时机:工具消息已创建并追加后,调用 callTool 之前触发。
702
533
  * @param toolCall - 工具调用对象
703
534
  * @param context - 插件上下文,包含当前工具消息
704
535
  */
705
- onToolCallStart?: (toolCall: ToolCall, context: BasePluginContext & {
706
- primaryMessage: ChatMessage;
707
- toolMessage: ChatMessage;
708
- }) => void;
536
+ onToolCallStart?: (toolCall: ToolCall, context: UseMessageToolCallContext) => void;
709
537
  /**
710
538
  * 工具调用结束时的回调函数。
711
539
  * 触发时机:工具调用完成(成功、失败或取消)时触发。
@@ -714,9 +542,7 @@ declare const toolPlugin: (options: UseMessagePlugin & {
714
542
  * @param context.status - 工具调用状态:'success' | 'failed' | 'cancelled'
715
543
  * @param context.error - 当状态为 'failed' 或 'cancelled' 时,可能包含错误信息
716
544
  */
717
- onToolCallEnd?: (toolCall: ToolCall, context: BasePluginContext & {
718
- primaryMessage: ChatMessage;
719
- toolMessage: ChatMessage;
545
+ onToolCallEnd?: (toolCall: ToolCall, context: UseMessageToolCallContext & {
720
546
  status: "success" | "failed" | "cancelled";
721
547
  error?: Error;
722
548
  }) => void;
@@ -729,20 +555,13 @@ declare const toolPlugin: (options: UseMessagePlugin & {
729
555
  */
730
556
  toolCallFailedContent?: string;
731
557
  /**
732
- * 是否在请求被中止时自动补充缺失的 tool 消息。
558
+ * 是否在请求前自动补充缺失的 tool 消息。
733
559
  * 当 assistant 响应了 tool_calls 但未追加对应的 tool 消息时,
734
560
  * 插件将自动补充"工具调用已取消"的 tool 消息。默认:false。
735
561
  */
736
562
  autoFillMissingToolMessages?: boolean;
737
- /**
738
- * 是否在下一轮对话中,排除包含 tool_calls 的 assistant 消息和对应的 tool 消息,只保留结果。
739
- * - 当为 `true` 时,这些消息会被标记为不发送,不会包含在下一次请求的 messages 中。
740
- * - 当为 `'remove'` 时,这些消息会直接从 messages 数组中移除。
741
- * 默认:false。
742
- */
743
- excludeToolMessagesNextTurn?: boolean | typeof EXCLUDE_MODE_REMOVE;
744
563
  }) => UseMessagePlugin;
745
564
 
746
565
  declare const useMessage: (options: UseMessageOptions) => UseMessageReturn;
747
566
 
748
- export { type AIAdapterError, AIClient, type AIModelConfig, type AIProvider, BaseModelProvider, type BasePluginContext, type ChatCompletion, type ChatCompletionOptions, type ChatCompletionRequest, type ChatCompletionResponse, type ChatCompletionResponseChoice, type ChatCompletionResponseMessage, type ChatCompletionResponseUsage, type ChatCompletionStreamResponse, type ChatCompletionStreamResponseChoice, type ChatCompletionStreamResponseDelta, type ChatHistory, type ChatMessage, type Choice, type CompletionChoice, type Conversation, type ConversationInfo, type ConversationStorageStrategy, type DeltaChoice, EXCLUDE_MODE_REMOVE, ErrorType, type IndexedDBConfig, IndexedDBStrategy, type LocalStorageConfig, LocalStorageStrategy, type MaybePromise, type MessageMetadata, type MessageRequestBody, type MessageRole, OpenAIProvider, type RequestProcessingState, type RequestState, StreamEventType, type StreamHandler, type Tool, type ToolCall, type Usage, type UseConversationOptions, type UseConversationReturn, type UseMessageOptions, type UseMessagePlugin, type UseMessageReturn, extractTextFromResponse, fallbackRolePlugin, formatMessages, handleSSEStream, indexedDBStorageStrategyFactory, lengthPlugin, localStorageStrategyFactory, sseStreamToGenerator, thinkingPlugin, toolPlugin, useConversation, useMessage };
567
+ export { AIClient, AIModelConfig, BaseModelProvider, type BasePluginContext, type ChatCompletion, ChatCompletionRequest, ChatCompletionResponse, ChatMessage, type Choice, type CompletionChoice, type Conversation, type ConversationInfo, type ConversationStorageStrategy, type DeltaChoice, type IndexedDBConfig, IndexedDBStrategy, type LocalStorageConfig, LocalStorageStrategy, MaybePromise, type MessageRequestBody, OpenAIProvider, type RequestProcessingState, type RequestState, type ResponseProvider, StreamHandler, type Tool, ToolCall, type Usage, type UseConversationOptions, type UseConversationReturn, type UseMessageCallToolContext, type UseMessageOptions, type UseMessagePlugin, type UseMessageReturn, type UseMessageSkillPluginOptions, type UseMessageToolActionContext, type UseMessageToolCallContext, type VueSkillSource, type VueSkillSourceRef, extractTextFromResponse, formatMessages, handleSSEStream, indexedDBStorageStrategyFactory, lengthPlugin, localStorageStrategyFactory, skillPlugin, sseStreamToGenerator, thinkingPlugin, toolPlugin, useConversation, useMessage };
package/dist/index.js CHANGED
@@ -1,4 +1,8 @@
1
- "use strict";var ie=Object.defineProperty;var ke=Object.getOwnPropertyDescriptor;var _e=Object.getOwnPropertyNames;var De=Object.prototype.hasOwnProperty;var Ue=(o,t)=>{for(var e in t)ie(o,e,{get:t[e],enumerable:!0})},qe=(o,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of _e(t))!De.call(o,s)&&s!==e&&ie(o,s,{get:()=>t[s],enumerable:!(n=ke(t,s))||n.enumerable});return o};var Be=o=>qe(ie({},"__esModule",{value:!0}),o);var Ve={};Ue(Ve,{AIClient:()=>Z,BaseModelProvider:()=>H,EXCLUDE_MODE_REMOVE:()=>Pe,ErrorType:()=>fe,IndexedDBStrategy:()=>V,LocalStorageStrategy:()=>G,OpenAIProvider:()=>j,StreamEventType:()=>me,extractTextFromResponse:()=>ye,fallbackRolePlugin:()=>ue,formatMessages:()=>he,handleSSEStream:()=>Y,indexedDBStorageStrategyFactory:()=>be,lengthPlugin:()=>de,localStorageStrategyFactory:()=>te,sseStreamToGenerator:()=>Ce,thinkingPlugin:()=>ge,toolPlugin:()=>je,useConversation:()=>Ge,useMessage:()=>ne});module.exports=Be(Ve);var H=class{constructor(t){this.config=t}updateConfig(t){this.config={...this.config,...t}}getConfig(){return{...this.config}}validateRequest(t){if(!t.messages||!Array.isArray(t.messages)||t.messages.length===0)throw new Error("\u8BF7\u6C42\u5FC5\u987B\u5305\u542B\u81F3\u5C11\u4E00\u6761\u6D88\u606F");for(let e of t.messages)if(!e.role||!e.content)throw new Error("\u6BCF\u6761\u6D88\u606F\u5FC5\u987B\u5305\u542B\u89D2\u8272\u548C\u5185\u5BB9")}};var fe=(c=>(c.NETWORK_ERROR="network_error",c.AUTHENTICATION_ERROR="authentication_error",c.RATE_LIMIT_ERROR="rate_limit_error",c.SERVER_ERROR="server_error",c.MODEL_ERROR="model_error",c.TIMEOUT_ERROR="timeout_error",c.UNKNOWN_ERROR="unknown_error",c))(fe||{}),me=(n=>(n.DATA="data",n.ERROR="error",n.DONE="done",n))(me||{});function K(o){return{type:o.type||"unknown_error",message:o.message||"\u672A\u77E5\u9519\u8BEF",statusCode:o.statusCode,originalError:o.originalError}}function le(o){if(!o.response)return K({type:"network_error",message:"\u7F51\u7EDC\u8FDE\u63A5\u9519\u8BEF\uFF0C\u8BF7\u68C0\u67E5\u60A8\u7684\u7F51\u7EDC\u8FDE\u63A5",originalError:o});if(o.response){let{status:t,data:e}=o.response;return t===401||t===403?K({type:"authentication_error",message:"\u8EAB\u4EFD\u9A8C\u8BC1\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u60A8\u7684API\u5BC6\u94A5",statusCode:t,originalError:o}):t===429?K({type:"rate_limit_error",message:"\u8D85\u51FAAPI\u8C03\u7528\u9650\u5236\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",statusCode:t,originalError:o}):t>=500?K({type:"server_error",message:"\u670D\u52A1\u5668\u9519\u8BEF\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",statusCode:t,originalError:o}):K({type:"unknown_error",message:e?.error?.message||`\u8BF7\u6C42\u5931\u8D25\uFF0C\u72B6\u6001\u7801: ${t}`,statusCode:t,originalError:o})}return o.code==="ECONNABORTED"?K({type:"timeout_error",message:"\u8BF7\u6C42\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",originalError:o}):K({type:"unknown_error",message:o.message||"\u53D1\u751F\u672A\u77E5\u9519\u8BEF",originalError:o})}async function Y(o,t,e){let n=o.body?.getReader();if(!n)throw new Error("Response body is null");let s=new TextDecoder,r="",a,c;e&&e.addEventListener("abort",()=>{n.cancel().catch(d=>console.error("Error cancelling reader:",d))},{once:!0});try{for(;;){if(e?.aborted){await n.cancel();break}let{done:d,value:f}=await n.read();if(d)break;let v=s.decode(f,{stream:!0});r+=v;let R=r.split(`
1
+ "use strict";var me=Object.defineProperty;var $e=Object.getOwnPropertyDescriptor;var Je=Object.getOwnPropertyNames;var Qe=Object.prototype.hasOwnProperty;var Xe=(s,e)=>{for(var t in e)me(s,t,{get:e[t],enumerable:!0})},Ye=(s,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Je(e))!Qe.call(s,r)&&r!==t&&me(s,r,{get:()=>e[r],enumerable:!(o=$e(e,r))||o.enumerable});return s};var Ze=s=>Ye(me({},"__esModule",{value:!0}),s);var yt={};Xe(yt,{AIClient:()=>le,BaseModelProvider:()=>J,ErrorType:()=>xe,IndexedDBStrategy:()=>X,LocalStorageStrategy:()=>Q,OpenAIProvider:()=>z,StreamEventType:()=>be,extractTextFromResponse:()=>Ae,formatMessages:()=>ke,handleSSEStream:()=>ie,indexedDBStorageStrategyFactory:()=>Oe,lengthPlugin:()=>dt,localStorageStrategyFactory:()=>ue,skillPlugin:()=>ft,sseStreamToGenerator:()=>we,thinkingPlugin:()=>Ct,toolPlugin:()=>ht,useConversation:()=>pt,useMessage:()=>ge});module.exports=Ze(yt);var J=class{constructor(e){this.config=e}updateConfig(e){this.config={...this.config,...e}}getConfig(){return{...this.config}}validateRequest(e){if(!e.messages||!Array.isArray(e.messages)||e.messages.length===0)throw new Error("\u8BF7\u6C42\u5FC5\u987B\u5305\u542B\u81F3\u5C11\u4E00\u6761\u6D88\u606F");for(let t of e.messages)if(!t.role||!t.content)throw new Error("\u6BCF\u6761\u6D88\u606F\u5FC5\u987B\u5305\u542B\u89D2\u8272\u548C\u5185\u5BB9")}};var xe=(i=>(i.NETWORK_ERROR="network_error",i.AUTHENTICATION_ERROR="authentication_error",i.RATE_LIMIT_ERROR="rate_limit_error",i.SERVER_ERROR="server_error",i.MODEL_ERROR="model_error",i.TIMEOUT_ERROR="timeout_error",i.UNKNOWN_ERROR="unknown_error",i))(xe||{}),be=(o=>(o.DATA="data",o.ERROR="error",o.DONE="done",o))(be||{});function H(s){return{type:s.type||"unknown_error",message:s.message||"\u672A\u77E5\u9519\u8BEF",statusCode:s.statusCode,originalError:s.originalError}}function fe(s){if(!s.response)return H({type:"network_error",message:"\u7F51\u7EDC\u8FDE\u63A5\u9519\u8BEF\uFF0C\u8BF7\u68C0\u67E5\u60A8\u7684\u7F51\u7EDC\u8FDE\u63A5",originalError:s});if(s.response){let{status:e,data:t}=s.response;return e===401||e===403?H({type:"authentication_error",message:"\u8EAB\u4EFD\u9A8C\u8BC1\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u60A8\u7684API\u5BC6\u94A5",statusCode:e,originalError:s}):e===429?H({type:"rate_limit_error",message:"\u8D85\u51FAAPI\u8C03\u7528\u9650\u5236\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",statusCode:e,originalError:s}):e>=500?H({type:"server_error",message:"\u670D\u52A1\u5668\u9519\u8BEF\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",statusCode:e,originalError:s}):H({type:"unknown_error",message:t?.error?.message||`\u8BF7\u6C42\u5931\u8D25\uFF0C\u72B6\u6001\u7801: ${e}`,statusCode:e,originalError:s})}return s.code==="ECONNABORTED"?H({type:"timeout_error",message:"\u8BF7\u6C42\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5",originalError:s}):H({type:"unknown_error",message:s.message||"\u53D1\u751F\u672A\u77E5\u9519\u8BEF",originalError:s})}async function ie(s,e,t){let o=s.body?.getReader();if(!o)throw new Error("Response body is null");let r=new TextDecoder,n="",a,i;t&&t.addEventListener("abort",()=>{o.cancel().catch(u=>console.error("Error cancelling reader:",u))},{once:!0});try{for(;;){if(t?.aborted){await o.cancel();break}let{done:u,value:l}=await o.read();if(u)break;let p=r.decode(l,{stream:!0});n+=p;let R=n.split(`
2
2
 
3
- `);r=R.pop()||"";for(let x of R)if(x.trim()!==""){if(x.trim()==="data: [DONE]"){c&&(a=c),t.onDone(a);continue}try{let A=x.match(/^data: (.+)$/m);if(!A)continue;let M=JSON.parse(A[1]);t.onData(M),c=M.choices?.[0]?.finish_reason||void 0}catch(A){console.error("Error parsing SSE message:",A)}}}(r.trim()==="data: [DONE]"||e?.aborted)&&(e?.aborted&&(a="aborted"),t.onDone(a))}catch(d){if(e?.aborted)return;throw d}}function he(o){return o.map(t=>typeof t=="object"&&"role"in t&&"content"in t?{role:t.role,content:String(t.content),...t.name?{name:t.name}:{}}:typeof t=="string"?{role:"user",content:t}:{role:"user",content:String(t)})}function ye(o){return!o.choices||!o.choices.length?"":o.choices[0].message?.content||""}function ce(o="The operation was aborted"){let t=new Error(o);return t.name="AbortError",t}async function*Ce(o,t={}){let e=o.body?.getReader();if(!e)throw new Error("ReadableStream not supported");let{signal:n}=t,s=new TextDecoder,r="",a=()=>{e.cancel()};n?.addEventListener("abort",a);try{for(;;){if(n?.aborted)throw ce();let c;try{c=await e.read()}catch(x){throw n?.aborted?ce():x}let{done:d,value:f}=c;if(d){if(n?.aborted)throw ce();return}let v=s.decode(f,{stream:!0});r+=v;let R=r.split(`
4
- `);r=R.pop()||"";for(let x of R)if(x.trim()!==""&&x.startsWith("data: ")){let A=x.slice(6);if(A==="[DONE]")return;try{yield JSON.parse(A)}catch(M){console.warn("Failed to parse SSE data:",A,M)}}}}finally{n?.removeEventListener("abort",a),e.releaseLock()}}var j=class extends H{constructor(e){super(e);this.defaultModel="gpt-3.5-turbo";this.baseURL=e.apiUrl||"https://api.openai.com/v1",this.apiKey=e.apiKey||"",e.defaultModel&&(this.defaultModel=e.defaultModel),this.apiKey||console.warn("API key is not provided. Authentication will likely fail.")}async chat(e){try{this.validateRequest(e);let n={model:e.options?.model||this.config.defaultModel||this.defaultModel,messages:e.messages,...e.options,stream:!1},s={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)};this.apiKey&&Object.assign(s.headers,{Authorization:`Bearer ${this.apiKey}`});let r=await fetch(`${this.baseURL}/chat/completions`,s);if(!r.ok){let a=await r.text();throw new Error(`HTTP error! status: ${r.status}, details: ${a}`)}return await r.json()}catch(n){throw le(n)}}async chatStream(e,n){let{signal:s,...r}=e.options||{};try{this.validateRequest(e);let a={model:e.options?.model||this.config.defaultModel||this.defaultModel,messages:e.messages,...r,stream:!0},c={method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,Accept:"text/event-stream"},body:JSON.stringify(a),signal:s};this.apiKey&&Object.assign(c.headers,{Authorization:`Bearer ${this.apiKey}`});let d=await fetch(`${this.baseURL}/chat/completions`,c);if(!d.ok){let f=await d.text();throw new Error(`HTTP error! status: ${d.status}, details: ${f}`)}await Y(d,n,s)}catch(a){if(s?.aborted)return;n.onError(le(a))}}updateConfig(e){super.updateConfig(e),e.apiUrl&&(this.baseURL=e.apiUrl),e.apiKey&&(this.apiKey=e.apiKey),e.defaultModel&&(this.defaultModel=e.defaultModel)}};var Z=class{constructor(t){this.config=t,this.provider=this.createProvider(t)}createProvider(t){if(t.provider==="custom"&&"providerImplementation"in t)return t.providerImplementation;if(t.provider==="deepseek"){let e={defaultModel:"deepseek-chat",apiUrl:"https://api.deepseek.com/v1"};return new j({...e,...t})}else return new j(t)}async chat(t){return this.provider.chat(t)}async chatStream(t,e){let n={...t,options:{...t.options,stream:!0}};return this.provider.chatStream(n,e)}getConfig(){return{...this.config}}updateConfig(t){this.config={...this.config,...t},t.provider&&t.provider!==this.config.provider?this.provider=this.createProvider(this.config):this.provider.updateConfig(this.config)}};var ve=require("vue");function X(o,t=new WeakMap){if(o==null||typeof o!="object")return o;try{let e=(0,ve.toRaw)(o);if(t.has(e))return t.get(e);if(Array.isArray(e)){let s=[];return t.set(e,s),s.push(...e.map(r=>X(r,t))),s}if(e instanceof Date||e instanceof RegExp||e instanceof ArrayBuffer||e instanceof Blob)return e;let n={};t.set(e,n);for(let s of Object.keys(e)){let r=Object.getOwnPropertyDescriptor(e,s);if(!r||r.get||r.set)continue;let a=e[s];typeof a!="function"&&typeof a!="symbol"&&(n[s]=X(a,t))}return n}catch(e){return console.warn("unwrapProxy error:",e),Array.isArray(o)?[]:{}}}var ee=o=>o.map(t=>{let{renderContent:e,...n}=t;if(!Array.isArray(e))return t;let s=e.filter(a=>a.type==="collapsible-text"),r=e.filter(a=>a.type==="markdown"||a.type==="text");return s.length>0&&(n.reasoning_content=s.map(a=>a.content).join("")),r.length>0&&(n.content=r.map(a=>a.content).join("")),n});var Q=o=>{let t=localStorage.getItem(o);return t?JSON.parse(t):[]},G=class{constructor(t="tiny-robot-ai-conversations"){this.storageKey=t}saveConversation(t){try{let e=Q(this.storageKey),n=e.findIndex(s=>s.id===t.id);n!==-1?Object.assign(e[n],t):e.unshift({...t,messages:[]}),localStorage.setItem(this.storageKey,JSON.stringify(e))}catch(e){console.error("\u4FDD\u5B58\u4F1A\u8BDD\u5931\u8D25:",e)}}loadConversations(){try{return Q(this.storageKey).map(e=>({id:e.id,title:e.title,createdAt:e.createdAt,updatedAt:e.updatedAt,metadata:e.metadata}))}catch(t){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u5931\u8D25:",t),[]}}saveMessages(t,e){try{let n=Q(this.storageKey),s=n.findIndex(r=>r.id===t);s!==-1&&(n[s].messages=e),localStorage.setItem(this.storageKey,JSON.stringify(n))}catch(n){console.error("\u4FDD\u5B58\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",n)}}loadMessages(t){try{let n=Q(this.storageKey).find(r=>r.id===t);return ee(n?.messages||[])}catch(e){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",e),[]}}deleteConversation(t){let e=Q(this.storageKey),n=e.findIndex(s=>s.id===t);n!==-1&&e.splice(n,1),localStorage.setItem(this.storageKey,JSON.stringify(e))}};var Me=require("idb");var V=class{constructor(t="tiny-robot-ai-db",e=3){this.db=null;this.dbName=t,this.dbVersion=e}async getDB(){return this.db||(this.db=await(0,Me.openDB)(this.dbName,this.dbVersion,{upgrade(t){t.objectStoreNames.contains("conversations")||t.createObjectStore("conversations",{keyPath:"id"}).createIndex("by-updated","updatedAt"),t.objectStoreNames.contains("messages")||t.createObjectStore("messages",{keyPath:"conversationId"})}})),this.db}async loadConversations(){try{return(await(await this.getDB()).getAllFromIndex("conversations","by-updated")).reverse()}catch(t){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u5931\u8D25:",t),[]}}async loadMessages(t){try{let n=await(await this.getDB()).get("messages",t);return n?ee(n.messages):[]}catch(e){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",e),[]}}async saveConversation(t){try{let e=await this.getDB(),n=X(t);await e.put("conversations",n)}catch(e){throw console.error("\u4FDD\u5B58\u4F1A\u8BDD\u5931\u8D25:",e),e}}async saveMessages(t,e){try{let n=await this.getDB(),s=X(e);await n.put("messages",{conversationId:t,messages:s})}catch(n){throw console.error("\u4FDD\u5B58\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",n),n}}async deleteConversation(t){try{let e=await this.getDB();await e.delete("conversations",t),await e.delete("messages",t)}catch(e){throw console.error("\u5220\u9664\u4F1A\u8BDD\u5931\u8D25:",e),e}}};function te(o={}){return new G(o.key||"tiny-robot-ai-conversations")}function be(o={}){return new V(o.dbName||"tiny-robot-ai-db",o.dbVersion||1)}var L=require("vue");var U=require("vue");var ue=(o={})=>{let{fallbackRole:t="assistant",...e}=o;return{name:"fallbackRole",...e,onBeforeRequest(n){let{requestBody:s}=n;return s.messages=s.messages.map(r=>({...r,role:r.role||t})),e.onBeforeRequest?.(n)}}};var de=(o={})=>{let{continueContent:t="Please continue with your previous answer.",...e}=o;return{name:"length",...e,onAfterRequest:async n=>{let{lastChoice:s,appendMessage:r,requestNext:a}=n;return s?.finish_reason==="length"&&(r({role:"user",content:t}),a()),e.onAfterRequest?.(n)}}};var ge=(o={})=>({name:"thinking",...o,onCompletionChunk(t){let{choice:e,currentMessage:n}=t,r=typeof(e?.message?.reasoning_content||e?.delta?.reasoning_content)=="string";return n.state?(n.state.thinking=r,n.state.open=r):n.state={thinking:r,open:r},o.onCompletionChunk?.(t)},onTurnEnd(t){let e=t.currentTurn.slice(-1)[0];return e?.state?.thinking&&(e.state.thinking=!1,e.state.open=!1),o.onTurnEnd?.(t)}});var Se=require("vue");var $=class extends Error{constructor(t){super(t),this.name="AbortError"}};function Ne(o){if(o.aborted)return{promise:Promise.reject(new $(String(o.reason??"Aborted"))),cleanup:()=>{}};let t=null;return{promise:new Promise((s,r)=>{t=()=>{r(new $(String(o.reason??"Aborted")))},o.addEventListener("abort",t,{once:!0})}),cleanup:()=>{t&&(o.removeEventListener("abort",t),t=null)}}}function Ae(o,t){let{promise:e,cleanup:n}=Ne(t);return Promise.race([o,e]).finally(n)}function we(o,t){let e={};for(let n in o)t.includes(n)&&(e[n]=o[n]);return e}function Te(o,t){let e={};for(let n in o)t.includes(n)||(e[n]=o[n]);return e}async function*oe(o){if(Re(o)){yield*o;return}let t=await o;if(Re(t)){yield*t;return}yield t}function Re(o){return o&&typeof o=="object"&&typeof o[Symbol.asyncIterator]=="function"}var pe=o=>typeof o=="object"&&o!==null,xe=o=>pe(o)&&typeof o.index=="number",J=(o,t)=>{for(let[e,n]of Object.entries(t)){let s=o[e];if(s)if(typeof s=="string"&&typeof n=="string")e==="type"&&s||(o[e]=s+n);else if(Array.isArray(s)&&Array.isArray(n))if(s.every(r=>xe(r))&&n.every(r=>xe(r))){let r=new Map(s.map(f=>[f.index,f])),a=new Map(n.map(f=>[f.index,f]));for(let[f,v]of a)if(r.has(f)){let R=r.get(f);r.set(f,J(R,v))}else r.set(f,v);let c=Math.max(...Array.from(r.keys()),-1)+1,d=c>s.length?Array.from({length:c}):s;for(let[f,v]of r)d[f]=v;o[e]=d}else o[e]=[...s,...n];else pe(s)&&pe(n)&&(o[e]=J(s,n));else o[e]=n}return o};function Fe(o,t){let e=[];for(let n=0;n<o.length;n++){let s=o[n];if(s.role==="assistant"&&s.tool_calls&&s.tool_calls.length>0){let r=new Set(s.tool_calls.map(d=>d.id)),a=new Set;for(let d=n+1;d<o.length;d++){let f=o[d];f.role==="tool"&&f.tool_call_id&&r.has(f.tool_call_id)&&a.add(f.tool_call_id)}let c=s.tool_calls.map(d=>d.id).filter(d=>!a.has(d));c.length>0&&e.push({insertAfterIndex:n,missingToolCallIds:c})}}for(let n=e.length-1;n>=0;n--){let{insertAfterIndex:s,missingToolCallIds:r}=e[n],a=r.map(c=>({role:"tool",tool_call_id:c,content:t}));o.splice(s+1,0,...a)}}var Pe="remove";function Ke(o,t,e,n){let s=o.filter(a=>a[e]),r=new Set(s.flatMap(a=>a.tool_calls?.map(c=>c.id)??[]));if(t===Pe)for(let a=o.length-1;a>=0;a--){let c=o[a];(c[e]||c[n]||c.tool_call_id&&r.has(c.tool_call_id))&&o.splice(a,1)}else if(t===!0)for(let a of o)(a[e]||a.tool_call_id&&r.has(a.tool_call_id))&&(a[n]=!0,delete a[e])}var je=o=>{let{getTools:t,beforeCallTools:e,callTool:n,onToolCallStart:s,onToolCallEnd:r,toolCallCancelledContent:a="Tool call cancelled.",toolCallFailedContent:c="Tool call failed.",autoFillMissingToolMessages:d=!1,excludeToolMessagesNextTurn:f=!1,...v}=o,R=Symbol("doNotSendNextTurn"),x=Symbol("doNotSend"),A=(...m)=>{let[h,{primaryMessage:T}]=m;T.state.toolCall[h.id].status="running",s?.(...m)},M=(...m)=>{let[h,{status:T,primaryMessage:O}]=m;O.state.toolCall[h.id].status=T,r?.(...m)};return{name:"tool",...v,onTurnStart:m=>{let{messages:h}=m;return d&&Fe(h,a),f&&Ke(h,f,R,x),v.onTurnStart?.(m)},onBeforeRequest:async m=>{let{messages:h,requestBody:T}=m;f===!0&&(T.messages=h.filter(E=>!E[x]));let O=await t?.();return O&&O.length>0&&(T.tools=O),v.onBeforeRequest?.(m)},onAfterRequest:async m=>{let{currentMessage:h,lastChoice:T,appendMessage:O,abortSignal:E,setRequestState:i,requestNext:l}=m;if(T?.finish_reason!=="tool_calls"||!h.tool_calls?.length)return;f&&(h[R]=!0),i("processing","calling-tools"),await e?.(h.tool_calls,{...m,currentMessage:h});let g=h.tool_calls.map(async y=>{let S=Math.floor(Date.now()/1e3),w=(0,Se.reactive)({role:"tool",tool_call_id:y.id,content:"",metadata:{createdAt:S,updatedAt:S}});O(w);let q={...m,primaryMessage:h,toolMessage:w};A(y,q);try{let k=n(y,q),N=oe(k);for await(let u of N){if(typeof u=="string")w.content+=u;else{let p={};try{p=JSON.parse(w.content||"{}")}catch(b){console.warn(b)}w.content=JSON.stringify(J(p,u))}w.metadata.updatedAt=Math.floor(Date.now()/1e3)}M(y,{...q,status:"success"})}catch(k){let N=k instanceof Error?k:new Error(String(k));if(E.aborted){M(y,{...q,status:"cancelled",error:N});return}console.error(k),w.content.length===0&&(w.content=c),M(y,{...q,status:"failed",error:N})}});return await Promise.all(g),l(),v.onAfterRequest?.(m)},onCompletionChunk:m=>{var T,O,E;let{currentMessage:h}=m;if(Array.isArray(h.tool_calls))for(let i of h.tool_calls)h.state?.toolCall?.[i.id]?.status||(h.state??(h.state={}),(T=h.state).toolCall??(T.toolCall={}),(O=h.state.toolCall)[E=i.id]??(O[E]={}));return v.onCompletionChunk?.(m)}}};var Le=o=>{let t=[];for(let e of o){if(e.name){let n=t.findIndex(s=>s.name===e.name);n!==-1&&t.splice(n,1)}t.push(e)}return t},ne=o=>{let{initialMessages:t=[],requestMessageFields:e=[],requestMessageFieldsExclude:n=["state","metadata","loading"],plugins:s=[],onCompletionChunk:r}=o,a=(0,U.ref)("idle"),c=(0,U.ref)(void 0),d=(0,U.ref)(t),f=(0,U.ref)(o.responseProvider),v=null,R=[],x={},A=[ue(),ge(),de()],M=Le(A.concat(s)),m=(0,U.computed)(()=>a.value==="processing"),h=async u=>{if(!u||!u.trim()){console.warn("Cannot send empty message");return}if(m.value){console.warn("Cannot send message while processing is in progress");return}let p=Math.floor(Date.now()/1e3);d.value.push({role:"user",content:u.trim(),metadata:{createdAt:p,updatedAt:p}}),R.push(d.value[d.value.length-1]),await w()},T=async(...u)=>{if(m.value){console.warn("Cannot send message while processing is in progress");return}d.value.push(...u),R.push(...u),await w()},O=u=>{let p=u;return e.length&&(p=p.map(b=>we(b,e))),n.length&&(p=p.map(b=>Te(b,n))),p},E=(u,p)=>{a.value=u,u==="processing"?c.value=p||"requesting":c.value=void 0},i=u=>{Object.assign(x,u)},l=u=>({messages:d.value,currentTurn:R,requestState:a.value,processingState:c.value,plugins:M,abortSignal:u,setRequestState:E,customContext:x,setCustomContext:i}),g=(u,p)=>typeof u.disabled=="function"?u.disabled(p):!!u.disabled,y=u=>!u||Object.keys(u).length===0?!1:Object.values(u).some(p=>!!p),S=async(u,p)=>{E("processing","requesting");let b=new Proxy({messages:O(d.value)},{set(D,P,F){return P==="messages"?(D.messages=O(F),!0):(D[P]=F,!0)}}),I=l(p);for(let D of M.filter(P=>!g(P,I)))await D.onBeforeRequest?.({...I,requestBody:b});let C=(0,U.reactive)({role:"",content:"",loading:!0});N(C);let _,re=u(b,p),B=oe(re);for await(let D of B){E("processing","completing"),C.loading&&(C.loading=void 0);let P=D.choices?.find(W=>W.index===0);if(P){_=P;let W=()=>{C.metadata||(C.metadata={});let{created:z,...Ie}=D;C.metadata.createdAt=z,C.metadata.updatedAt=Math.floor(Date.now()/1e3),Object.assign(C.metadata,Ie);let ae=y(P.delta)?P.delta:P.message;ae||(ae=P.delta||P.message||{}),J(C,ae)};if(r){let z=l(p);r({...z,chunk:D,choice:P,currentMessage:C},W)}else W()}let F=l(p);for(let W of M.filter(z=>!g(z,F)))W.onCompletionChunk?.({...F,abortSignal:p,chunk:D,choice:P,currentMessage:C})}await k(C,u,p,_)},w=async()=>{let u=new AbortController;v=u,x={};try{E("processing","requesting");let p=l(u.signal);for(let C of M.filter(_=>!g(_,p)))await C.onTurnStart?.(p);let b=f.value;try{await S(b,u.signal),E("completed")}catch(C){if(u.signal.aborted||C instanceof $||C instanceof Error&&C.name==="AbortError")E("aborted");else throw C}let I=l(u.signal);for(let C of M.filter(_=>!g(_,I)))await C.onTurnEnd?.(I)}catch(p){E("error");let b=!1,I=l(u.signal);for(let C of M.filter(_=>!g(_,I)))C.onError&&(b=!0,C.onError({...I,error:p}));if(!b)throw p}finally{let p=l(u.signal);for(let b of M.filter(I=>!g(I,p)))try{b.onFinally?.(p)}catch(I){console.error(`Error in onFinally hook for plugin ${b.name||"Anonymous"}:`,I)}v=null,R.slice(-1)[0]&&(R.slice(-1)[0].loading=void 0),R=[]}},q=async()=>{v?.abort(),m.value&&await new Promise(u=>{let p=(0,U.watch)(m,b=>{b||(p(),u())},{immediate:!0})})},k=async(u,p,b,I)=>{let C=!1,_=l(b),re=M.filter(B=>!g(B,_)).map(B=>{if(!B.onAfterRequest)return null;let D=F=>{N(F)},P=()=>{C=!0};return B.onAfterRequest({..._,currentMessage:u,lastChoice:I,appendMessage:D,requestNext:P})}).filter(B=>B!==null);await Ae(Promise.all(re),b),C&&await S(p,b)},N=u=>{let p=Array.isArray(u)?u:[u];d.value.push(...p),R.push(...p)};return{requestState:a,processingState:c,messages:d,responseProvider:f,isProcessing:m,sendMessage:h,send:T,abortRequest:q}};var se=require("vue");function Oe(o,t=200,e=!1,n=!0,s=!1){return We(He(t,e,n,s),o)}function We(o,t){function e(...n){return new Promise((s,r)=>{Promise.resolve(o(()=>t.apply(this,n),{fn:t,thisArg:this,args:n})).then(s).catch(r)})}return e}var Ee=()=>{};function He(...o){let t=0,e,n=!0,s=Ee,r,a,c,d,f;!(0,se.isRef)(o[0])&&typeof o[0]=="object"?{delay:a,trailing:c=!0,leading:d=!0,rejectOnCancel:f=!1}=o[0]:[a,c=!0,d=!0,f=!1]=o;let v=()=>{e&&(clearTimeout(e),e=void 0,s(),s=Ee)};return x=>{let A=(0,se.toValue)(a),M=Date.now()-t,m=()=>r=x();return v(),A<=0?(t=Date.now(),m()):(M>A?(t=Date.now(),(d||!n)&&m()):c&&(r=new Promise((h,T)=>{s=f?T:h,e=setTimeout(()=>{t=Date.now(),n=!0,h(m()),v()},Math.max(0,A-M))})),!d&&!e&&(e=setTimeout(()=>n=!0,A)),n=!1,r)}}var Ge=o=>{let t=o.storage||te(),e=(0,L.ref)([]),n=new Map,s=new Map,r=(0,L.ref)(null),a=(0,L.computed)(()=>{let i=r.value;if(!i)return null;let l=e.value.find(y=>y.id===i);if(!l)return null;let g=n.get(i);return g?{...l,engine:g}:null}),c=i=>{if(!t?.saveMessages)return;let l=i||r.value,g=e.value.find(S=>S.id===l);if(!g)return;g.updatedAt=Date.now(),t?.saveConversation?.(g);let y=n.get(g.id);y&&t.saveMessages(g.id,y.messages.value)},d=(i,l)=>{if(!o.autoSaveMessages||!t?.saveMessages)return;let g=s.get(i);g&&g();let y=o.autoSaveThrottle??1e3,S=Oe(()=>{c(i)},y,!0,!0),w=(0,L.watch)(l.messages,S,{deep:!0});s.set(i,w)},f=i=>{let l=s.get(i);l&&(l(),s.delete(i))};t?.loadConversations&&Promise.resolve(t.loadConversations()).then(i=>{if(!i?.length)return[];if(e.value.length===0)return e.value=i,e.value;let l=new Map(e.value.map(g=>[g.id,g]));return i.forEach(g=>{l.has(g.id)||l.set(g.id,g)}),e.value=Array.from(l.values()),e.value}).then(i=>{o.onLoad?.(i)}).catch(i=>{console.error("[useConversation] loadConversations failed:",i)});let v=async(i,l)=>{let g=n.get(i);if(g)return g;let y=l?.initialMessages??o.useMessageOptions.initialMessages??[];if(t?.loadMessages)try{y=await t.loadMessages(i)}catch(w){console.error("[useConversation] loadMessages failed:",w)}let S=ne({...o.useMessageOptions,...l,initialMessages:y});return n.set(i,S),d(i,S),S};function R(){return Date.now().toString(36)+Math.random().toString(36).substring(2,9)}let x=i=>{let{id:l=R(),title:g,metadata:y,useMessageOptions:S}=i||{},w=Date.now(),q={id:l,title:g,createdAt:w,updatedAt:w,metadata:y};e.value.unshift(q);let k=ne({...o.useMessageOptions,...S});return n.set(l,k),d(l,k),t?.saveConversation?.(q),t?.saveMessages?.(l,k.messages.value),r.value=l,a.value},A=i=>{let{excludeId:l}=i||{};n.forEach((g,y)=>{if(l&&y===l)return;g.isProcessing?.value||(f(y),n.delete(y))})};return{conversations:e,activeConversationId:r,activeConversation:a,createConversation:x,switchConversation:async i=>i?r.value===i?a.value:e.value.find(g=>g.id===i)?(await v(i),A({excludeId:i}),r.value=i,a.value):null:null,deleteConversation:async i=>{let l=e.value.findIndex(y=>y.id===i);if(l===-1)return;await n.get(i)?.abortRequest(),f(i),n.delete(i),e.value.splice(l,1),t?.deleteConversation?.(i),r.value===i&&(r.value=null,A())},clear:()=>{e.value.map(l=>l.id).forEach(l=>{t?.deleteConversation?.(l)}),n.forEach(l=>{l.abortRequest()}),s.forEach(l=>{l()}),e.value=[],n.clear(),s.clear(),r.value=null},updateConversationTitle:(i,l)=>{let g=e.value.find(y=>y.id===i);g&&(g.title=l,g.updatedAt=Date.now(),t?.saveConversation?.(g))},saveMessages:c,sendMessage:i=>{a.value?.engine.sendMessage(i)},abortActiveRequest:async()=>{await a.value?.engine.abortRequest()}}};0&&(module.exports={AIClient,BaseModelProvider,EXCLUDE_MODE_REMOVE,ErrorType,IndexedDBStrategy,LocalStorageStrategy,OpenAIProvider,StreamEventType,extractTextFromResponse,fallbackRolePlugin,formatMessages,handleSSEStream,indexedDBStorageStrategyFactory,lengthPlugin,localStorageStrategyFactory,sseStreamToGenerator,thinkingPlugin,toolPlugin,useConversation,useMessage});
3
+ `);n=R.pop()||"";for(let M of R)if(M.trim()!==""){if(M.trim()==="data: [DONE]"){i&&(a=i),e.onDone(a);continue}try{let h=M.match(/^data: (.+)$/m);if(!h)continue;let m=JSON.parse(h[1]);e.onData(m),i=m.choices?.[0]?.finish_reason||void 0}catch(h){console.error("Error parsing SSE message:",h)}}}(n.trim()==="data: [DONE]"||t?.aborted)&&(t?.aborted&&(a="aborted"),e.onDone(a))}catch(u){if(t?.aborted)return;throw u}}function ke(s){return s.map(e=>typeof e=="object"&&"role"in e&&"content"in e?{role:e.role,content:String(e.content),...e.name?{name:e.name}:{}}:typeof e=="string"?{role:"user",content:e}:{role:"user",content:String(e)})}function Ae(s){return!s.choices||!s.choices.length?"":s.choices[0].message?.content||""}function Ce(s="The operation was aborted"){let e=new Error(s);return e.name="AbortError",e}async function*we(s,e={}){let t=s.body?.getReader();if(!t)throw new Error("ReadableStream not supported");let{signal:o}=e,r=new TextDecoder,n="",a=()=>{t.cancel()};o?.addEventListener("abort",a);try{for(;;){if(o?.aborted)throw Ce();let i;try{i=await t.read()}catch(M){throw o?.aborted?Ce():M}let{done:u,value:l}=i;if(u){if(o?.aborted)throw Ce();return}let p=r.decode(l,{stream:!0});n+=p;let R=n.split(`
4
+ `);n=R.pop()||"";for(let M of R)if(M.trim()!==""&&M.startsWith("data: ")){let h=M.slice(6);if(h==="[DONE]")return;try{yield JSON.parse(h)}catch(m){console.warn("Failed to parse SSE data:",h,m)}}}}finally{o?.removeEventListener("abort",a),t.releaseLock()}}var z=class extends J{constructor(t){super(t);this.defaultModel="gpt-3.5-turbo";this.baseURL=t.apiUrl||"https://api.openai.com/v1",this.apiKey=t.apiKey||"",t.defaultModel&&(this.defaultModel=t.defaultModel),this.apiKey||console.warn("API key is not provided. Authentication will likely fail.")}async chat(t){try{this.validateRequest(t);let o={model:t.options?.model||this.config.defaultModel||this.defaultModel,messages:t.messages,...t.options,stream:!1},r={method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)};this.apiKey&&Object.assign(r.headers,{Authorization:`Bearer ${this.apiKey}`});let n=await fetch(`${this.baseURL}/chat/completions`,r);if(!n.ok){let a=await n.text();throw new Error(`HTTP error! status: ${n.status}, details: ${a}`)}return await n.json()}catch(o){throw fe(o)}}async chatStream(t,o){let{signal:r,...n}=t.options||{};try{this.validateRequest(t);let a={model:t.options?.model||this.config.defaultModel||this.defaultModel,messages:t.messages,...n,stream:!0},i={method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,Accept:"text/event-stream"},body:JSON.stringify(a),signal:r};this.apiKey&&Object.assign(i.headers,{Authorization:`Bearer ${this.apiKey}`});let u=await fetch(`${this.baseURL}/chat/completions`,i);if(!u.ok){let l=await u.text();throw new Error(`HTTP error! status: ${u.status}, details: ${l}`)}await ie(u,o,r)}catch(a){if(r?.aborted)return;o.onError(fe(a))}}updateConfig(t){super.updateConfig(t),t.apiUrl&&(this.baseURL=t.apiUrl),t.apiKey&&(this.apiKey=t.apiKey),t.defaultModel&&(this.defaultModel=t.defaultModel)}};var le=class{constructor(e){this.config=e,this.provider=this.createProvider(e)}createProvider(e){if(e.provider==="custom"&&"providerImplementation"in e)return e.providerImplementation;if(e.provider==="deepseek"){let t={defaultModel:"deepseek-chat",apiUrl:"https://api.deepseek.com/v1"};return new z({...t,...e})}else return new z(e)}async chat(e){return this.provider.chat(e)}async chatStream(e,t){let o={...e,options:{...e.options,stream:!0}};return this.provider.chatStream(o,t)}getConfig(){return{...this.config}}updateConfig(e){this.config={...this.config,...e},e.provider&&e.provider!==this.config.provider?this.provider=this.createProvider(this.config):this.provider.updateConfig(this.config)}};var Ee=require("vue");function se(s,e=new WeakMap){if(s==null||typeof s!="object")return s;try{let t=(0,Ee.toRaw)(s);if(e.has(t))return e.get(t);if(Array.isArray(t)){let r=[];return e.set(t,r),r.push(...t.map(n=>se(n,e))),r}if(t instanceof Date||t instanceof RegExp||t instanceof ArrayBuffer||t instanceof Blob)return t;let o={};e.set(t,o);for(let r of Object.keys(t)){let n=Object.getOwnPropertyDescriptor(t,r);if(!n||n.get||n.set)continue;let a=t[r];typeof a!="function"&&typeof a!="symbol"&&(o[r]=se(a,e))}return o}catch(t){return console.warn("unwrapProxy error:",t),Array.isArray(s)?[]:{}}}var ce=s=>s.map(e=>{let{renderContent:t,...o}=e;if(!Array.isArray(t))return e;let r=t.filter(a=>a.type==="collapsible-text"),n=t.filter(a=>a.type==="markdown"||a.type==="text");return r.length>0&&(o.reasoning_content=r.map(a=>a.content).join("")),n.length>0&&(o.content=n.map(a=>a.content).join("")),o});var oe=s=>{let e=localStorage.getItem(s);return e?JSON.parse(e):[]},Q=class{constructor(e="tiny-robot-ai-conversations"){this.storageKey=e}saveConversation(e){try{let t=oe(this.storageKey),o=t.findIndex(r=>r.id===e.id);o!==-1?Object.assign(t[o],e):t.unshift({...e,messages:[]}),localStorage.setItem(this.storageKey,JSON.stringify(t))}catch(t){console.error("\u4FDD\u5B58\u4F1A\u8BDD\u5931\u8D25:",t)}}loadConversations(){try{return oe(this.storageKey).map(t=>({id:t.id,title:t.title,createdAt:t.createdAt,updatedAt:t.updatedAt,metadata:t.metadata}))}catch(e){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u5931\u8D25:",e),[]}}saveMessages(e,t){try{let o=oe(this.storageKey),r=o.findIndex(n=>n.id===e);r!==-1&&(o[r].messages=t),localStorage.setItem(this.storageKey,JSON.stringify(o))}catch(o){console.error("\u4FDD\u5B58\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",o)}}loadMessages(e){try{let o=oe(this.storageKey).find(n=>n.id===e);return ce(o?.messages||[])}catch(t){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",t),[]}}deleteConversation(e){let t=oe(this.storageKey),o=t.findIndex(r=>r.id===e);o!==-1&&t.splice(o,1),localStorage.setItem(this.storageKey,JSON.stringify(t))}};var Ie=require("idb");var X=class{constructor(e="tiny-robot-ai-db",t=3){this.db=null;this.dbName=e,this.dbVersion=t}async getDB(){return this.db||(this.db=await(0,Ie.openDB)(this.dbName,this.dbVersion,{upgrade(e){e.objectStoreNames.contains("conversations")||e.createObjectStore("conversations",{keyPath:"id"}).createIndex("by-updated","updatedAt"),e.objectStoreNames.contains("messages")||e.createObjectStore("messages",{keyPath:"conversationId"})}})),this.db}async loadConversations(){try{return(await(await this.getDB()).getAllFromIndex("conversations","by-updated")).reverse()}catch(e){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u5931\u8D25:",e),[]}}async loadMessages(e){try{let o=await(await this.getDB()).get("messages",e);return o?ce(o.messages):[]}catch(t){return console.error("\u52A0\u8F7D\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",t),[]}}async saveConversation(e){try{let t=await this.getDB(),o=se(e);await t.put("conversations",o)}catch(t){throw console.error("\u4FDD\u5B58\u4F1A\u8BDD\u5931\u8D25:",t),t}}async saveMessages(e,t){try{let o=await this.getDB(),r=se(t);await o.put("messages",{conversationId:e,messages:r})}catch(o){throw console.error("\u4FDD\u5B58\u4F1A\u8BDD\u6D88\u606F\u5931\u8D25:",o),o}}async deleteConversation(e){try{let t=await this.getDB();await t.delete("conversations",e),await t.delete("messages",e)}catch(t){throw console.error("\u5220\u9664\u4F1A\u8BDD\u5931\u8D25:",t),t}}};function ue(s={}){return new Q(s.key||"tiny-robot-ai-conversations")}function Oe(s={}){return new X(s.dbName||"tiny-robot-ai-db",s.dbVersion||1)}var $=require("vue");var W=require("vue");var et=s=>typeof s=="function"?null:Array.isArray(s)?s.length>0?new Set(s):null:new Set([s]),qe=s=>{let e=new Set,t=(n,a)=>{try{n.listener(a)}catch(i){console.error("Error in message state subscriber:",i)}};return{notify:n=>{let a=new Set(Array.isArray(n)?n:[n]),i=s(),u=Array.from(e);for(let l of u){if(l.kinds){let p=!1;for(let R of l.kinds)if(a.has(R)){p=!0;break}if(!p)continue}t(l,i)}},subscribe:(n,a)=>{let i=typeof n=="function"?n:a;if(!i)throw new Error("subscribe listener is required");let u={kinds:et(n),listener:i};return e.add(u),t(u,s()),()=>{e.delete(u)}}}};var N=require("vue");var Be=s=>(0,N.reactive)(s),he=s=>{let e=(0,N.isProxy)(s)?(0,N.toRaw)(s):s;if(Array.isArray(e))return e.map(t=>he(t));if(e&&typeof e=="object"){let t={};for(let[o,r]of Object.entries(e))t[o]=he(r);return t}return e},_e=()=>{let s=!1,e=(0,N.ref)("idle"),t=(0,N.ref)(void 0),o=(0,N.ref)([]),r=(0,N.computed)(()=>e.value==="processing"),n=p=>{if(s)throw new Error("Message state adapter is already initialized");e.value=p.requestState,t.value=p.processingState,o.value=p.messages.map(Be),s=!0},a=p=>Be(p),i=()=>{if(!s)throw new Error("Message state adapter is not initialized");return{requestState:e.value,processingState:t.value,messages:he(o.value),isProcessing:r.value}},u=qe(i);return{requestState:e,processingState:t,messages:o,isProcessing:r,initialize:n,getState:i,createMessage:a,mutate:(p,R)=>{if(!s)throw new Error("Message state adapter is not initialized");let M={get requestState(){return e.value},set requestState(O){e.value=O},get processingState(){return t.value},set processingState(O){t.value=O},get messages(){return o.value},set messages(O){o.value=O.map(a)}},h=!1;if(R(M,()=>{h=!0}),h)return;(Array.isArray(p)?p:[p]).includes("messages")&&(o.value=[...o.value]),u.notify(p)},subscribe:u.subscribe}};var ne=(s={})=>{let{continueContent:e="Please continue with your previous answer.",...t}=s;return{name:"length",...t,onAfterRequest:async o=>{let{lastChoice:r,appendMessage:n,requestNext:a}=o;return r?.finish_reason==="length"&&(n({role:"user",content:e}),a()),t.onAfterRequest?.(o)}}};var Fe={listSkillFiles:"list_skill_files",readSkillFile:"read_skill_file"},tt="execute_skill_command",De=[{type:"function",function:{name:Fe.listSkillFiles,description:"List files available from the current skills.",parameters:{type:"object",properties:{skillName:{type:"string",description:"Optional skill name. When omitted, files from all current skills are listed."}},additionalProperties:!1}}},{type:"function",function:{name:Fe.readSkillFile,description:"Read a file from a current skill by skill name and relative path.",parameters:{type:"object",properties:{skillName:{type:"string",description:"Skill name that owns the file."},path:{type:"string",description:"File path relative to the skill root."}},required:["skillName","path"],additionalProperties:!1}}}],st={type:"function",function:{name:tt,description:"Execute a command in the backend runtime environment for a selected skill.",parameters:{type:"object",properties:{skillName:{type:"string",description:"Name of the current skill that provides the command instructions."},command:{type:"string",description:"Command name to execute in the skill backend runtime."},args:{type:"array",description:"Command arguments passed as argv items.",items:{type:"string"}}},required:["skillName","command","args"],additionalProperties:!1}}},ye=(s,e)=>({skillName:s,id:e.id,path:e.path,kind:e.kind,mimeType:e.mimeType,size:e.size,lastModified:e.lastModified}),Me=s=>{let e=s.function.arguments;if(!e)return{};try{let t=JSON.parse(e);return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}catch{return{}}},ot=s=>Array.isArray(s)&&s.every(e=>typeof e=="string")?s:void 0,nt=s=>{if(!s.some(o=>!!o.files?.length))return[];let t=o=>{if(!(typeof o!="string"||!o))return s.find(r=>r.name===o)};return[{tool:De[0],handler:o=>{let r=Me(o),n=t(r.skillName);return{files:(n?[n]:s).flatMap(i=>(i.files??[]).map(u=>ye(i.name,u)))}}},{tool:De[1],handler:o=>{let r=Me(o),n=t(r.skillName),a=typeof r.path=="string"?r.path:void 0;if(!n)return{error:"skill_not_found"};if(!a)return{error:"file_path_required",skillName:n.name};let i=n.files?.find(u=>u.path===a);return i?i.kind==="binary"?{error:"binary_file_not_readable",file:ye(n.name,i)}:{file:ye(n.name,i),content:i.content}:{error:"file_not_found",skillName:n.name,path:a}}}]},rt=(s,e)=>{if(!e||s.length===0)return[];let t=o=>{if(!(typeof o!="string"||!o))return s.find(r=>r.name===o)};return[{tool:st,handler:async o=>{let r=Me(o),n=t(r.skillName),a=typeof r.command=="string"?r.command:void 0,i=ot(r.args);return n?a?i?e({skill:n,skillName:n.name,command:a,args:i}):{error:"args_required",skillName:n.name,command:a}:{error:"command_required",skillName:n.name}:{error:"skill_not_found"}}}]},Ue=(s,e={})=>[...nt(s),...rt(s,e.executeSkillCommand)],Ne=async s=>{let e=[];for(let t of s){let o=t.instructions?.trim();o&&e.push(`## ${t.name}
5
+
6
+ ${o}`)}if(e.length!==0)return{role:"system",content:["Apply these skill instructions when generating the response.",...e].join(`
7
+
8
+ `)}};var Se="__tiny_robot_skill",ve=s=>{let{getSkills:e,executeSkillCommand:t,onSkillsResolved:o,...r}=s;return{name:"skill",...r,provideTools:async n=>n.customContext[Se]?.runtimeTools??[],onTurnStart:async n=>{let a=await e?.(n)??[],i={skills:a,skillNames:a.map(u=>u.name),runtimeTools:Ue(a,{executeSkillCommand:t&&(u=>t(u,n))})};return n.setCustomContext({[Se]:i}),await o?.(i,n),r.onTurnStart?.(n)},onBeforeRequest:async n=>{let a=n.customContext[Se];if(a){let i=await Ne(a.skills);i&&(n.requestBody.messages=[i,...n.requestBody.messages])}return r.onBeforeRequest?.(n)}}};var re=(s={})=>{let e=(t,o)=>!!t.thinking!==o||!!t.open!==o;return{name:"thinking",...s,onCompletionChunk(t){let{choice:o,currentMessage:r,updateCurrentMessage:n}=t,a=o,i=a?.message?.reasoning_content||a?.delta?.reasoning_content,u=typeof i=="string"&&i.trim()!=="";return u?r.state&&typeof r.state=="object"?e(r.state,u)&&n(l=>{l.state.thinking=!0,l.state.open=!0}):n(l=>{l.state={thinking:u,open:u}}):r.state&&typeof r.state=="object"&&"thinking"in r.state&&e(r.state,u)&&n(l=>{l.state.thinking=!1,l.state.open=!1}),s.onCompletionChunk?.(t)},onTurnEnd(t){let{currentTurn:o,mutate:r}=t,n=o.at(-1);return n?.state&&typeof n.state=="object"&&"thinking"in n.state&&e(n.state,!1)&&r("messages",()=>{n.state.thinking=!1,n.state.open=!1}),s.onTurnEnd?.(t)}}};var Y=class extends Error{constructor(e){super(e),this.name="AbortError"}};function at(s){if(s.aborted)return{promise:Promise.reject(new Y(String(s.reason??"Aborted"))),cleanup:()=>{}};let e=null;return{promise:new Promise((r,n)=>{e=()=>{n(new Y(String(s.reason??"Aborted")))},s.addEventListener("abort",e,{once:!0})}),cleanup:()=>{e&&(s.removeEventListener("abort",e),e=null)}}}function Ke(s,e){let{promise:t,cleanup:o}=at(e);return Promise.race([s,t]).finally(o)}function We(s,e){let t={};for(let o in s)e.includes(o)&&(t[o]=s[o]);return t}function Le(s,e){let t={};for(let o in s)e.includes(o)||(t[o]=s[o]);return t}async function*ee(s){if(je(s)){yield*s;return}let e=await s;if(je(e)){yield*e;return}yield e}function je(s){return s&&typeof s=="object"&&typeof s[Symbol.asyncIterator]=="function"}var Pe=s=>typeof s=="object"&&s!==null,Ve=s=>Pe(s)&&typeof s.index=="number",Z=(s,e)=>{for(let[t,o]of Object.entries(e)){let r=s[t];if(r)if(typeof r=="string"&&typeof o=="string")t==="type"&&r||(s[t]=r+o);else if(Array.isArray(r)&&Array.isArray(o))if(r.every(n=>Ve(n))&&o.every(n=>Ve(n))){let n=new Map(r.map(l=>[l.index,l])),a=new Map(o.map(l=>[l.index,l]));for(let[l,p]of a)if(n.has(l)){let R=n.get(l);n.set(l,Z(R,p))}else n.set(l,p);let i=Math.max(...Array.from(n.keys()),-1)+1,u=i>r.length?Array.from({length:i}):r;for(let[l,p]of n)u[l]=p;s[t]=u}else s[t]=[...r,...o];else Pe(r)&&Pe(o)&&(s[t]=Z(r,o));else s[t]=o}return s};function it({messages:s,cancelledContent:e,createMessage:t,mutate:o}){let r=[];for(let n=0;n<s.length;n++){let a=s[n];if(a.role==="assistant"&&a.tool_calls&&a.tool_calls.length>0){let i=new Set(a.tool_calls.map(p=>p.id)),u=new Set;for(let p=n+1;p<s.length;p++){let R=s[p];R.role==="tool"&&R.tool_call_id&&i.has(R.tool_call_id)&&u.add(R.tool_call_id)}let l=a.tool_calls.map(p=>p.id).filter(p=>!u.has(p));l.length>0&&r.push({insertAfterIndex:n,missingToolCallIds:l})}}r.length!==0&&o("messages",n=>{for(let a=r.length-1;a>=0;a--){let{insertAfterIndex:i,missingToolCallIds:u}=r[a],l=u.map(p=>t({role:"tool",tool_call_id:p,content:e}));n.messages.splice(i+1,0,...l)}})}var Re=s=>{let{getTools:e,beforeCallTools:t,callTool:o,onToolCallStart:r,onToolCallEnd:n,toolCallCancelledContent:a="Tool call cancelled.",toolCallFailedContent:i="Tool call failed.",autoFillMissingToolMessages:u=!1,...l}=s,p=(C,S)=>{var c,g;return C.state??(C.state={}),(c=C.state).toolCall??(c.toolCall={}),(g=C.state.toolCall)[S]??(g[S]={}),C},R=(...C)=>{let[S,{assistantMessage:c,mutate:g}]=C;g("messages",()=>{let d=p(c,S.id);d.state.toolCall[S.id].status="running"}),r?.(...C)},M=(...C)=>{let[S,{status:c,assistantMessage:g,mutate:d}]=C;d("messages",()=>{let b=p(g,S.id);b.state.toolCall[S.id].status=c}),n?.(...C)},h=C=>C.type==="function"&&"function"in C,m=C=>!!(C&&typeof C=="object"&&"tool"in C&&"handler"in C),T=C=>{let S=C;return typeof S.provideTools=="function"?S:void 0},O=(C,S)=>typeof C.disabled=="function"?C.disabled(S):!!C.disabled,D=async(C,S=[])=>{let c=[];for(let A of C.plugins){let f=T(A);!O(A,C)&&f&&c.push(...(await f.provideTools(C)).map(v=>({item:v,source:{type:"toolProvider",pluginName:A.name}})))}let g=[...c,...(await e(C)).map(A=>({item:A,source:{type:"toolPlugin"}}))],d=[],b=new Map,I=new Map,k=new Set,P=A=>{let f=A.function.name;if(k.has(f))throw new Error(`Duplicate tool name "${f}" detected. Tool names must be unique because tool calls are routed by function.name.`);k.add(f)};S.forEach(P);for(let{item:A,source:f}of g){let v=m(A)?A.tool:A;P(v),I.set(v.function.name,f),m(A)?(d.push(A.tool),b.set(A.tool.function.name,A)):d.push(A)}return{tools:d,runtimeToolMap:b,toolSourceMap:I}};return{name:"tool",...l,onTurnStart:C=>{let{getState:S,createMessage:c,mutate:g}=C,d=S().messages;return u&&it({messages:d,cancelledContent:a,createMessage:c,mutate:g}),l.onTurnStart?.(C)},onBeforeRequest:async C=>{let{requestBody:S}=C,c=Array.isArray(S.tools)?S.tools:[],{tools:g}=await D(C,c);return g&&g.length>0&&(S.tools=c.length?[...c,...g]:g),l.onBeforeRequest?.(C)},onAfterRequest:async C=>{let{currentMessage:S,lastChoice:c,appendMessage:g,abortSignal:d,setRequestState:b,requestNext:I,mutate:k,createMessage:P}=C;if(c?.finish_reason!=="tool_calls"||!S.tool_calls?.length)return;b("processing","calling-tools"),await t?.(S.tool_calls,{...C,assistantMessage:S});let{runtimeToolMap:A,toolSourceMap:f}=await D(C),v=S.tool_calls.map(async x=>{let E=Math.floor(Date.now()/1e3),_=!1,y=P({role:"tool",tool_call_id:x.id,content:"",metadata:{createdAt:E,updatedAt:E}});g(y);let w=h(x)?x:void 0,j=w?f.get(w.function.name)??{type:"unknown"}:{type:"unknown"},F={...C,assistantMessage:S,toolMessage:y,toolSource:j};R(x,F);try{let B=w?A.get(w.function.name):void 0,q=B&&w?B.handler(w,F):o(x,F),K=ee(q);for await(let V of K)k("messages",()=>{if((typeof V=="string"&&V.length>0||V&&typeof V=="object"&&Object.keys(V).length>0)&&(_=!0),typeof V=="string")y.content+=V;else{let te={};try{let U=Array.isArray(y.content)?y.content.map(L=>L.text).join(""):y.content;te=JSON.parse(U||"{}")}catch(U){console.warn(U)}y.content=JSON.stringify(Z(te,V))}y.metadata.updatedAt=Math.floor(Date.now()/1e3)});M(x,{...F,status:"success"})}catch(B){let q=B instanceof Error?B:new Error(String(B));if(d.aborted){M(x,{...F,status:"cancelled",error:q});return}console.error(B),_||k("messages",()=>{y.content=i,y.metadata.updatedAt=Math.floor(Date.now()/1e3)}),M(x,{...F,status:"failed",error:q})}});return await Promise.all(v),d.aborted||I(),l.onAfterRequest?.(C)}}};var lt=async()=>{throw new Error("Response provider is not set")},ct=s=>{let e=[];for(let t of s){if(t.name){let o=e.findIndex(r=>r.name===t.name);o!==-1&&e.splice(o,1)}e.push(t)}return e},G=(s,e)=>typeof s.disabled=="function"?s.disabled(e):!!s.disabled,Te=(s,e={})=>{let{initialMessages:t=[],requestMessageFields:o=[],requestMessageFieldsExclude:r=["state","metadata","loading"],responseProvider:n=lt,onCompletionChunk:a,plugins:i=[]}=e,u={requestState:"idle",processingState:void 0,messages:[...t]};s.initialize(u);let l={currentTurn:[],customContext:{},abortController:null,responseProvider:n},p=[re(),ne()],R=ct(p.concat(i)),M=()=>s.getState(),h=f=>s.createMessage(f),m=s.subscribe,T=s.mutate,O=f=>!f||Object.keys(f).length===0?!1:Object.values(f).some(v=>!!v),D=f=>{let v=f;return o.length&&(v=v.map(x=>We(x,o))),r.length&&(v=v.map(x=>Le(x,r))),v},C=f=>{Object.assign(l.customContext,f)},S=(f,v)=>{T("requestState",(x,E)=>{if(x.requestState===f&&x.processingState===v){E();return}x.requestState=f,x.processingState=f==="processing"?v??"requesting":void 0})},c=(...f)=>{let v=f.map(x=>h(x));return T("messages",x=>{x.messages.push(...v)}),l.currentTurn.push(...v),v},g=f=>({getState:M,createMessage:h,mutate:T,abortSignal:f,currentTurn:l.currentTurn,plugins:R,customContext:l.customContext,setRequestState:S,setCustomContext:C});async function d(f,v,x={}){S("processing","requesting");let E={messages:M().messages},_=g(v);for(let B of R.filter(q=>!G(q,_)))await B.onBeforeRequest?.({..._,requestBody:E});E.messages=D(E.messages);let y={role:"assistant",content:"",loading:!0};[y]=c(y),x.setAssistantMessage?.(y);let w=f(E,v),j=ee(w),F;for await(let B of j){S("processing","completing"),T("messages",(U,L)=>{y.loading?y.loading=void 0:L()});let q=(B.choices||[]).find(U=>U.index===0)??B.choices?.[0];if(!q)continue;F=q;let K=()=>{T("messages",()=>{y.metadata||(y.metadata={});let{created:U,...L}=B;y.metadata.createdAt=U,y.metadata.updatedAt=Math.floor(Date.now()/1e3),Object.assign(y.metadata,L);let ae="delta"in q&&O(q.delta)&&q.delta||"message"in q&&O(q.message)&&q.message||null;if(ae?.role&&(y.role=ae.role),ae){let{role:Mt,...Ge}=ae;Z(y,Ge)}})},V=U=>{T("messages",()=>{U(y)})};if(a){let U=g(v);a({...U,chunk:B,choice:q,currentMessage:y,updateCurrentMessage:V},K)}else K();let te=g(v);for(let U of R.filter(L=>!G(L,te)))U.onCompletionChunk?.({...te,abortSignal:v,chunk:B,choice:q,currentMessage:y,updateCurrentMessage:V})}await b(y,f,v,F,x)}async function b(f,v,x,E,_){let y=!1,w=g(x),j=R.filter(F=>!G(F,w)).map(F=>{if(!F.onAfterRequest)return null;let B=K=>{c(...Array.isArray(K)?K:[K])},q=()=>{y=!0};return F.onAfterRequest({...w,currentMessage:f,lastChoice:E,appendMessage:B,requestNext:q})}).filter(F=>F!==null);await Ke(Promise.all(j),x),y&&await d(v,x,_)}async function I(){let f=new AbortController;l.abortController=f,l.customContext={};let v=null,x=E=>{v=E};try{S("processing","requesting");let E=g(f.signal);for(let w of R.filter(j=>!G(j,E)))await w.onTurnStart?.(E);let _=l.responseProvider;try{await d(_,f.signal,{setAssistantMessage:x}),S("completed")}catch(w){if(f.signal.aborted||w instanceof Y||w instanceof Error&&w.name==="AbortError")S("aborted");else throw w}let y=g(f.signal);for(let w of R.filter(j=>!G(j,y)))await w.onTurnEnd?.(y)}catch(E){S("error");let _=!1,y=g(f.signal);for(let w of R.filter(j=>!G(j,y)))w.onError&&(_=!0,w.onError({...y,error:E}));if(!_)throw E}finally{let E=g(f.signal);for(let _ of R.filter(y=>!G(y,E)))try{_.onFinally?.(E)}catch(y){console.error(`Error in onFinally hook for plugin [${_.name||"Anonymous"}]:`,y)}l.abortController=null,l.currentTurn=[],T("messages",(_,y)=>{v?.loading?v.loading=void 0:y()})}}async function k(f){if(!f||!f.trim()){console.warn("Cannot send empty message");return}if(M().requestState==="processing"){console.warn("Cannot send message while processing is in progress");return}let v=Math.floor(Date.now()/1e3);c({role:"user",content:f.trim(),metadata:{createdAt:v,updatedAt:v}}),await I()}async function P(...f){if(M().requestState==="processing"){console.warn("Cannot send message while processing is in progress");return}c(...f),await I()}async function A(){l.abortController?.abort(),M().isProcessing&&await new Promise(f=>{let v=()=>{};v=m("requestState",x=>{x.isProcessing||(v(),f())})})}return{getState:M,subscribe:m,sendMessage:k,send:P,abort:A,setResponseProvider(f){l.responseProvider=f}}};var ge=s=>{let{initialMessages:e=[],requestMessageFields:t=[],requestMessageFieldsExclude:o=["state","metadata","loading"],plugins:r=[],responseProvider:n,onCompletionChunk:a}=s,i=_e(),u=m=>i.messages.value.find(T=>T===m||(0,W.toRaw)(T)===m||(0,W.toRaw)(T)===(0,W.toRaw)(m))??m,l=m=>({messages:i.messages.value,currentTurn:m.currentTurn.map(T=>u(T)),requestState:i.requestState.value,processingState:i.processingState.value,plugins:r,setRequestState:m.setRequestState,abortSignal:m.abortSignal,customContext:m.customContext,setCustomContext:m.setCustomContext}),p=m=>{let T=m;if(typeof T.__corePluginFactory=="function")return T.__corePluginFactory({createCorePlugin:p,createVueBaseContext:l,resolveReactiveMessage:u});let{name:O,disabled:D,onTurnStart:C,onTurnEnd:S,onBeforeRequest:c,onAfterRequest:g,onCompletionChunk:d,onError:b,onFinally:I}=m,k={};return O!==void 0&&(k.name=O),D!==void 0&&(k.disabled=typeof D=="function"?P=>D(l(P)):D),C&&(k.onTurnStart=P=>C(l(P))),S&&(k.onTurnEnd=P=>S(l(P))),c&&(k.onBeforeRequest=P=>c({...l(P),requestBody:P.requestBody})),g&&(k.onAfterRequest=P=>g({...l(P),currentMessage:u(P.currentMessage),lastChoice:P.lastChoice,appendMessage:P.appendMessage,requestNext:P.requestNext})),d&&(k.onCompletionChunk=P=>d({...l(P),currentMessage:u(P.currentMessage),choice:P.choice,chunk:P.chunk})),b&&(k.onError=P=>b({...l(P),error:P.error})),I&&(k.onFinally=P=>I(l(P))),k},M=Te(i,{initialMessages:e,requestMessageFields:t,requestMessageFieldsExclude:o,responseProvider:n,onCompletionChunk:a?(m,T)=>{if(a)return a({...l(m),currentMessage:u(m.currentMessage),choice:m.choice,chunk:m.chunk},T)}:void 0,plugins:r.map(m=>p(m))}),h=(0,W.ref)(n);return(0,W.watch)(h,m=>{M.setResponseProvider(m)},{flush:"sync"}),{requestState:i.requestState,processingState:i.processingState,messages:i.messages,responseProvider:h,isProcessing:i.isProcessing,sendMessage:M.sendMessage,send:M.send,abortRequest:M.abort}};var pe=require("vue");function ze(s,e=200,t=!1,o=!0,r=!1){return ut(gt(e,t,o,r),s)}function ut(s,e){function t(...o){return new Promise((r,n)=>{Promise.resolve(s(()=>e.apply(this,o),{fn:e,thisArg:this,args:o})).then(r).catch(n)})}return t}var He=()=>{};function gt(...s){let e=0,t,o=!0,r=He,n,a,i,u,l;!(0,pe.isRef)(s[0])&&typeof s[0]=="object"?{delay:a,trailing:i=!0,leading:u=!0,rejectOnCancel:l=!1}=s[0]:[a,i=!0,u=!0,l=!1]=s;let p=()=>{t&&(clearTimeout(t),t=void 0,r(),r=He)};return M=>{let h=(0,pe.toValue)(a),m=Date.now()-e,T=()=>n=M();return p(),h<=0?(e=Date.now(),T()):(m>h?(e=Date.now(),(u||!o)&&T()):i&&(n=new Promise((O,D)=>{r=l?D:O,t=setTimeout(()=>{e=Date.now(),o=!0,O(T()),p()},Math.max(0,h-m))})),!u&&!t&&(t=setTimeout(()=>o=!0,h)),o=!1,n)}}var pt=s=>{let e=s.storage||ue(),t=(0,$.ref)([]),o=new Map,r=new Map,n=(0,$.ref)(null),a=(0,$.computed)(()=>{let c=n.value;if(!c)return null;let g=t.value.find(b=>b.id===c);if(!g)return null;let d=o.get(c);return d?{...g,engine:d}:null}),i=c=>{if(!e?.saveMessages)return;let g=c||n.value,d=t.value.find(I=>I.id===g);if(!d)return;d.updatedAt=Date.now(),e?.saveConversation?.(d);let b=o.get(d.id);b&&e.saveMessages(d.id,b.messages.value)},u=(c,g)=>{if(!s.autoSaveMessages||!e?.saveMessages)return;let d=r.get(c);d&&d();let b=s.autoSaveThrottle??1e3,I=ze(()=>{i(c)},b,!0,!0),k=(0,$.watch)(g.messages,I,{deep:!0});r.set(c,k)},l=c=>{let g=r.get(c);g&&(g(),r.delete(c))};e?.loadConversations&&Promise.resolve(e.loadConversations()).then(c=>{if(!c?.length)return[];if(t.value.length===0)return t.value=c,t.value;let g=new Map(t.value.map(d=>[d.id,d]));return c.forEach(d=>{g.has(d.id)||g.set(d.id,d)}),t.value=Array.from(g.values()),t.value}).then(c=>{s.onLoad?.(c)}).catch(c=>{console.error("[useConversation] loadConversations failed:",c)});let p=async(c,g)=>{let d=o.get(c);if(d)return d;let b=g?.initialMessages??s.useMessageOptions.initialMessages??[];if(e?.loadMessages)try{b=await e.loadMessages(c)}catch(k){console.error("[useConversation] loadMessages failed:",k)}let I=ge({...s.useMessageOptions,...g,initialMessages:b});return o.set(c,I),u(c,I),I};function R(){return Date.now().toString(36)+Math.random().toString(36).substring(2,9)}let M=c=>{let{id:g=R(),title:d,metadata:b,useMessageOptions:I}=c||{},k=Date.now(),P={id:g,title:d,createdAt:k,updatedAt:k,metadata:b};t.value.unshift(P);let A=ge({...s.useMessageOptions,...I});return o.set(g,A),u(g,A),e?.saveConversation?.(P),e?.saveMessages?.(g,A.messages.value),n.value=g,a.value},h=c=>{let{excludeId:g}=c||{};o.forEach((d,b)=>{if(g&&b===g)return;d.isProcessing?.value||(l(b),o.delete(b))})};return{conversations:t,activeConversationId:n,activeConversation:a,createConversation:M,switchConversation:async c=>c?n.value===c?a.value:t.value.find(d=>d.id===c)?(await p(c),h({excludeId:c}),n.value=c,a.value):null:null,deleteConversation:async c=>{let g=t.value.findIndex(b=>b.id===c);if(g===-1)return;await o.get(c)?.abortRequest(),l(c),o.delete(c),t.value.splice(g,1),e?.deleteConversation?.(c),n.value===c&&(n.value=null,h())},clear:()=>{t.value.map(g=>g.id).forEach(g=>{e?.deleteConversation?.(g)}),o.forEach(g=>{g.abortRequest()}),r.forEach(g=>{g()}),t.value=[],o.clear(),r.clear(),n.value=null},updateConversationTitle:(c,g)=>{let d=t.value.find(b=>b.id===c);d&&(d.title=g,d.updatedAt=Date.now(),e?.saveConversation?.(d))},saveMessages:i,sendMessage:c=>{a.value?.engine.sendMessage(c)},abortActiveRequest:async()=>{await a.value?.engine.abortRequest()}}};var dt=(s={})=>{let{continueContent:e="Please continue with your previous answer.",...t}=s;return{name:"length",__corePluginFactory(o){return ne({...o.createCorePlugin(t),continueContent:e})}}};var de=require("vue");var mt=s=>(0,de.isRef)(s)?(0,de.unref)(s):s,ft=s=>{let{skills:e,getSkills:t,executeSkillCommand:o,onSkillsResolved:r,...n}=s;return{name:"skill",__corePluginFactory(a){return ve({...a.createCorePlugin(n),getSkills:async i=>{let u=a.createVueBaseContext(i),l=t?await t(u):e;return mt(l)},executeSkillCommand:o?(i,u)=>o(i,a.createVueBaseContext(u)):void 0,onSkillsResolved:r?(i,u)=>r(i,a.createVueBaseContext(u)):void 0})}}};var Ct=(s={})=>({name:"thinking",__corePluginFactory(e){return re(e.createCorePlugin(s))}});var ht=s=>{let{getTools:e,beforeCallTools:t,callTool:o,onToolCallStart:r,onToolCallEnd:n,toolCallCancelledContent:a="Tool call cancelled.",toolCallFailedContent:i="Tool call failed.",autoFillMissingToolMessages:u=!1,...l}=s;return{name:"tool",__corePluginFactory(p){let R=p.createCorePlugin(l);return Re({...R,getTools:async M=>e(p.createVueBaseContext(M)),beforeCallTools:t?async(M,h)=>{let m=p.resolveReactiveMessage(h.assistantMessage);await t(M,{...p.createVueBaseContext(h),assistantMessage:m,currentMessage:m})}:void 0,callTool:async function*(M,h){let m=p.resolveReactiveMessage(h.assistantMessage),T=p.resolveReactiveMessage(h.toolMessage),O=o(M,{...p.createVueBaseContext(h),assistantMessage:m,currentMessage:m,toolMessage:T,toolSource:h.toolSource});for await(let D of ee(O))yield D},onToolCallStart:r?(M,h)=>{let m=p.resolveReactiveMessage(h.assistantMessage),T=p.resolveReactiveMessage(h.toolMessage);r(M,{...p.createVueBaseContext(h),assistantMessage:m,primaryMessage:m,toolMessage:T,toolSource:h.toolSource})}:void 0,onToolCallEnd:n?(M,h)=>{let m=p.resolveReactiveMessage(h.assistantMessage),T=p.resolveReactiveMessage(h.toolMessage);n(M,{...p.createVueBaseContext(h),assistantMessage:m,primaryMessage:m,toolMessage:T,toolSource:h.toolSource,status:h.status,error:h.error})}:void 0,toolCallCancelledContent:a,toolCallFailedContent:i,autoFillMissingToolMessages:u})}}};0&&(module.exports={AIClient,BaseModelProvider,ErrorType,IndexedDBStrategy,LocalStorageStrategy,OpenAIProvider,StreamEventType,extractTextFromResponse,formatMessages,handleSSEStream,indexedDBStorageStrategyFactory,lengthPlugin,localStorageStrategyFactory,skillPlugin,sseStreamToGenerator,thinkingPlugin,toolPlugin,useConversation,useMessage});