@opentiny/tiny-robot-kit 0.4.2-alpha.3 → 0.4.2-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-6JEZBNBO.mjs +5 -0
- package/dist/chunk-ZO2ZONVX.mjs +1 -0
- package/dist/core.d.mts +109 -248
- package/dist/core.d.ts +109 -248
- package/dist/core.js +6 -1
- package/dist/core.mjs +2 -1
- package/dist/index.d.mts +38 -4
- package/dist/index.d.ts +38 -4
- package/dist/index.js +7 -3
- package/dist/index.mjs +3 -3
- package/dist/node.d.mts +14 -0
- package/dist/node.d.ts +14 -0
- package/dist/node.js +1 -0
- package/dist/node.mjs +1 -0
- package/dist/skillPlugin-4pC5SvPk.d.mts +548 -0
- package/dist/skillPlugin-D6X-p9fQ.d.ts +548 -0
- package/dist/types-ChCZ8jKB.d.mts +70 -0
- package/dist/types-ChCZ8jKB.d.ts +70 -0
- package/package.json +13 -5
- package/dist/chunk-EES4JUCD.mjs +0 -1
- package/dist/types-D0E0rOVi.d.mts +0 -212
- package/dist/types-D0E0rOVi.d.ts +0 -212
package/dist/core.d.ts
CHANGED
|
@@ -1,196 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { z as MessageStateAdapter, J as RequestState, R as RequestProcessingState, o as ChatMessage, r as CreateMessageEngineOptions, s as MessageEngine, t as MessageEnginePlugin } from './skillPlugin-D6X-p9fQ.js';
|
|
2
|
+
export { c as AfterRequestContext, d as BasePluginContext, e as BeforeRequestContext, q as CompletionChunkContext, D as DeepReadonly, I as InternalMessageState, v as MessageMutationRecipe, w as MessageRequestBody, y as MessageRuntime, F as MessageUpdateKind, G as MessageUpdateKinds, H as MutateMessageStateFn, P as PublicMessageState, K as ResponseProvider, L as RuntimeTool, S as SkillCommandExecutor, N as SkillCommandRequest, O as SkillCommandResult, Q as SkillPluginOptions, T as SkillPluginState, U as SkillRuntimeToolsOptions, Y as ToolCallContext, Z as ToolProvider, _ as ToolProviderItem, $ as ToolSource, a0 as compileSkillInstructions, a1 as createSkillRuntimeTools, a2 as skillPlugin, a3 as toolPlugin } from './skillPlugin-D6X-p9fQ.js';
|
|
3
3
|
import { Ref, ComputedRef } from 'vue';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} : T;
|
|
8
|
-
type RequestState = 'idle' | 'processing' | 'completed' | 'aborted' | 'error';
|
|
9
|
-
type RequestProcessingState = 'requesting' | 'completing' | string;
|
|
10
|
-
type ChatMessage<Metadata extends object = Record<string, unknown>, State extends object = Record<string, unknown>> = ChatCompletionMessageParam & {
|
|
11
|
-
tool_calls?: Array<ChatCompletionMessageToolCall>;
|
|
12
|
-
loading?: boolean;
|
|
13
|
-
metadata?: Metadata;
|
|
14
|
-
state?: State;
|
|
15
|
-
[key: string]: any;
|
|
16
|
-
};
|
|
17
|
-
interface MessageRequestBody {
|
|
18
|
-
messages: Array<ChatMessage>;
|
|
19
|
-
[key: string]: any;
|
|
20
|
-
}
|
|
21
|
-
type ResponseProvider<T extends ChatCompletion | ChatCompletionChunk = ChatCompletion | ChatCompletionChunk> = (requestBody: MessageRequestBody, abortSignal: AbortSignal) => Promise<T> | AsyncGenerator<T> | Promise<AsyncGenerator<T>>;
|
|
22
|
-
interface PublicMessageState {
|
|
23
|
-
requestState: RequestState;
|
|
24
|
-
processingState?: RequestProcessingState;
|
|
25
|
-
messages: ChatMessage[];
|
|
26
|
-
isProcessing: boolean;
|
|
27
|
-
}
|
|
28
|
-
interface InternalMessageState {
|
|
29
|
-
requestState: RequestState;
|
|
30
|
-
processingState?: RequestProcessingState;
|
|
31
|
-
messages: ChatMessage[];
|
|
32
|
-
}
|
|
33
|
-
interface MessageRuntime {
|
|
34
|
-
currentTurn: ChatMessage[];
|
|
35
|
-
customContext: Record<string, unknown>;
|
|
36
|
-
abortController: AbortController | null;
|
|
37
|
-
responseProvider: ResponseProvider;
|
|
38
|
-
}
|
|
39
|
-
interface MessageEngine {
|
|
40
|
-
getState(): PublicMessageState;
|
|
41
|
-
subscribe(listener: (state: PublicMessageState) => void): () => void;
|
|
42
|
-
subscribe(kinds: MessageUpdateKinds, listener: (state: PublicMessageState) => void): () => void;
|
|
43
|
-
sendMessage(content: string): Promise<void>;
|
|
44
|
-
send(...msgs: ChatMessage[]): Promise<void>;
|
|
45
|
-
abort(): Promise<void>;
|
|
46
|
-
setResponseProvider(provider: ResponseProvider): void;
|
|
47
|
-
}
|
|
48
|
-
type MessageUpdateKind = 'messages' | 'requestState';
|
|
49
|
-
type MessageUpdateKinds = MessageUpdateKind | MessageUpdateKind[];
|
|
50
|
-
type MessageMutationRecipe = (draft: InternalMessageState, skipNotify: () => void) => void;
|
|
51
|
-
interface MutateMessageStateFn {
|
|
52
|
-
/**
|
|
53
|
-
* 在受控上下文中修改消息状态,并按声明的更新类型分发状态变更通知。
|
|
54
|
-
*
|
|
55
|
-
* 这里的“通知”语义对应 `subscribe` 订阅链路,用于驱动依赖 engine 状态快照的观察者;
|
|
56
|
-
* 它并不等同于具体框架的响应式更新机制。对于 Vue 等运行时,界面更新可能同时依赖
|
|
57
|
-
* 框架自身的响应式追踪与 `subscribe` 侧的状态通知,两者职责不同,不应混用。
|
|
58
|
-
*/
|
|
59
|
-
(kinds: MessageUpdateKinds, recipe: MessageMutationRecipe): void;
|
|
60
|
-
}
|
|
61
|
-
interface MessageStateAdapter {
|
|
62
|
-
initialize(initialState: InternalMessageState): void;
|
|
63
|
-
getState(): PublicMessageState;
|
|
64
|
-
/**
|
|
65
|
-
* 创建一条适配当前运行时的消息对象。
|
|
66
|
-
*
|
|
67
|
-
* engine 和 core 插件里凡是“新建消息”的入口,都应统一走这个方法,
|
|
68
|
-
* 以便不同平台注入各自的运行时能力。
|
|
69
|
-
*
|
|
70
|
-
* 例如:
|
|
71
|
-
* - native/纯 TS 场景:直接返回原对象即可
|
|
72
|
-
* `createMessage(message) { return message }`
|
|
73
|
-
* - Vue 场景:返回 reactive proxy,使后续对 message.content / message.state 的原地修改能够被追踪
|
|
74
|
-
* `createMessage(message) { return reactive(message) }`
|
|
75
|
-
*/
|
|
76
|
-
createMessage<T extends ChatMessage>(message: T): T;
|
|
77
|
-
mutate: MutateMessageStateFn;
|
|
78
|
-
subscribe(listener: (state: PublicMessageState) => void): () => void;
|
|
79
|
-
subscribe(kinds: MessageUpdateKinds, listener: (state: PublicMessageState) => void): () => void;
|
|
80
|
-
}
|
|
81
|
-
interface BasePluginContext {
|
|
82
|
-
getState(): PublicMessageState;
|
|
83
|
-
/**
|
|
84
|
-
* 创建一条适配当前运行时的消息对象。
|
|
85
|
-
*
|
|
86
|
-
* 插件在运行过程中如果需要主动创建并追加消息,应统一通过此接口构造消息实例,
|
|
87
|
-
* 而不是直接持有普通对象字面量。这样可以确保消息对象具备当前平台所要求的运行时能力。
|
|
88
|
-
*
|
|
89
|
-
* 对于采用响应式机制的平台(例如 Vue),该接口通常会返回带有响应式包装的消息实例。
|
|
90
|
-
* 如果插件绕过此接口直接创建普通对象,再参与后续的状态更新或原地字段修改,
|
|
91
|
-
* 可能导致消息内容、状态字段等变更无法被正确追踪。
|
|
92
|
-
*/
|
|
93
|
-
createMessage<T extends ChatMessage>(message: T): T;
|
|
94
|
-
/**
|
|
95
|
-
* 在受控上下文中修改状态,并触发与 `subscribe` 对应的状态更新通知。
|
|
96
|
-
*
|
|
97
|
-
* 该通知机制面向 engine 的订阅接口,而不是具体框架的响应式系统本身。
|
|
98
|
-
* 因此,在需要让 `subscribe` 观察者感知到变更时,应通过此接口完成状态写入。
|
|
99
|
-
*/
|
|
100
|
-
mutate: MutateMessageStateFn;
|
|
101
|
-
abortSignal: AbortSignal;
|
|
102
|
-
currentTurn: ChatMessage[];
|
|
103
|
-
customContext: Record<string, unknown>;
|
|
104
|
-
setRequestState: (state: RequestState, processingState?: RequestProcessingState) => void;
|
|
105
|
-
setCustomContext: (data: Record<string, unknown>) => void;
|
|
106
|
-
}
|
|
107
|
-
interface BeforeRequestContext extends BasePluginContext {
|
|
108
|
-
requestBody: MessageRequestBody;
|
|
109
|
-
}
|
|
110
|
-
interface AfterRequestContext extends BasePluginContext {
|
|
111
|
-
currentMessage: DeepReadonly<ChatMessage>;
|
|
112
|
-
lastChoice?: ChatCompletion.Choice | ChatCompletionChunk.Choice;
|
|
113
|
-
/**
|
|
114
|
-
* 使用 appendMessage 函数追加消息,可触发消息更新通知。
|
|
115
|
-
*/
|
|
116
|
-
appendMessage: (message: ChatMessage | ChatMessage[]) => void;
|
|
117
|
-
requestNext: () => void;
|
|
118
|
-
}
|
|
119
|
-
interface CompletionChunkContext extends BasePluginContext {
|
|
120
|
-
/**
|
|
121
|
-
* 当前消息,只读。需要使用 updateCurrentMessage 函数修改当前消息,才能正常触发消息更新通知。
|
|
122
|
-
*/
|
|
123
|
-
currentMessage: DeepReadonly<ChatMessage>;
|
|
124
|
-
/**
|
|
125
|
-
* 使用 updateCurrentMessage 函数修改当前消息,才能正常触发消息更新通知。
|
|
126
|
-
*/
|
|
127
|
-
updateCurrentMessage: (recipe: (message: ChatMessage) => void) => void;
|
|
128
|
-
choice: ChatCompletion.Choice | ChatCompletionChunk.Choice;
|
|
129
|
-
chunk: ChatCompletion | ChatCompletionChunk;
|
|
130
|
-
}
|
|
131
|
-
interface MessageEnginePlugin {
|
|
132
|
-
/**
|
|
133
|
-
* 插件名称。
|
|
134
|
-
*/
|
|
135
|
-
name?: string;
|
|
136
|
-
/**
|
|
137
|
-
* 是否禁用插件。
|
|
138
|
-
*/
|
|
139
|
-
disabled?: boolean | ((context: BasePluginContext) => boolean);
|
|
140
|
-
/**
|
|
141
|
-
* 一次对话回合(turn)开始钩子:用户消息入队后、正式发起请求之前触发。
|
|
142
|
-
* 按插件注册顺序串行执行,便于做有序初始化/校验;出错则中断流程。
|
|
143
|
-
*/
|
|
144
|
-
onTurnStart?: (context: BasePluginContext) => MaybePromise<void>;
|
|
145
|
-
/**
|
|
146
|
-
* 一次对话回合(turn)结束的生命周期钩子。
|
|
147
|
-
* 触发时机:本轮对话完成(成功、被中止)后。
|
|
148
|
-
* 执行策略:按插件注册顺序串行执行,有错误则中断流程。
|
|
149
|
-
*/
|
|
150
|
-
onTurnEnd?: (context: BasePluginContext) => MaybePromise<void>;
|
|
151
|
-
/**
|
|
152
|
-
* 请求开始前的生命周期钩子。
|
|
153
|
-
* 触发时机:已组装 requestBody,正式发起请求之前。
|
|
154
|
-
* 执行策略:按插件注册顺序串行执行,避免并发修改 requestBody 产生冲突。
|
|
155
|
-
*/
|
|
156
|
-
onBeforeRequest?: (context: BeforeRequestContext) => MaybePromise<void>;
|
|
157
|
-
/**
|
|
158
|
-
* 请求完成后的生命周期钩子。
|
|
159
|
-
* 触发时机:本次请求(含流式)结束后。
|
|
160
|
-
* 执行策略:并行执行(Promise.all)。
|
|
161
|
-
*/
|
|
162
|
-
onAfterRequest?: (context: AfterRequestContext) => MaybePromise<void>;
|
|
163
|
-
/**
|
|
164
|
-
* 数据块处理钩子,在接收到每个响应数据块时触发。
|
|
165
|
-
* 无论是流式响应(多个增量数据块)还是非流式响应(单个完整数据块),都会触发此钩子。
|
|
166
|
-
*/
|
|
167
|
-
onCompletionChunk?: (context: CompletionChunkContext) => void;
|
|
168
|
-
onError?: (context: BasePluginContext & {
|
|
169
|
-
error: unknown;
|
|
170
|
-
}) => void;
|
|
171
|
-
onFinally?: (context: BasePluginContext) => void;
|
|
172
|
-
}
|
|
173
|
-
interface CreateMessageEngineOptions {
|
|
174
|
-
initialMessages?: ChatMessage[];
|
|
175
|
-
/**
|
|
176
|
-
* 请求消息时,要包含的字段(白名单)。默认包含所有字段。
|
|
177
|
-
* 如果 `requestMessageFieldsExclude` 存在,会先取 `requestMessageFields` 中的字段,再排除 `requestMessageFieldsExclude` 中的字段
|
|
178
|
-
*/
|
|
179
|
-
requestMessageFields?: string[];
|
|
180
|
-
/**
|
|
181
|
-
* 请求消息时,要排除的字段(黑名单)。默认会排除 `state`、`metadata`、`loading` 字段(这几个字段是给UI展示用的)。
|
|
182
|
-
* 如果 `requestMessageFields` 存在,会先取 `requestMessageFields` 中的字段,再排除 `requestMessageFieldsExclude` 中的字段
|
|
183
|
-
*/
|
|
184
|
-
requestMessageFieldsExclude?: string[];
|
|
185
|
-
responseProvider?: ResponseProvider;
|
|
186
|
-
/**
|
|
187
|
-
* 全局的数据块处理钩子,在接收到每个响应数据块时触发。
|
|
188
|
-
* 注意:此钩子与插件中的 onCompletionChunk 有区别。
|
|
189
|
-
* 如果传入了此参数,默认的 chunk 处理逻辑不会自动执行,需要手动调用 runDefault 来执行默认处理逻辑。
|
|
190
|
-
*/
|
|
191
|
-
onCompletionChunk?: (context: CompletionChunkContext, runDefault: () => void) => void;
|
|
192
|
-
plugins?: MessageEnginePlugin[];
|
|
193
|
-
}
|
|
4
|
+
import { b as SkillFile, S as SkillDefinition } from './types-ChCZ8jKB.js';
|
|
5
|
+
export { B as BaseSkillFile, a as BinarySkillFile, c as SkillFileKind, d as SkillFileResource, T as TextSkillFile } from './types-ChCZ8jKB.js';
|
|
6
|
+
import 'openai/resources';
|
|
194
7
|
|
|
195
8
|
declare const createNativeMessageAdapter: () => MessageStateAdapter;
|
|
196
9
|
|
|
@@ -210,72 +23,120 @@ declare const lengthPlugin: (options?: MessageEnginePlugin & {
|
|
|
210
23
|
|
|
211
24
|
declare const thinkingPlugin: (options?: MessageEnginePlugin) => MessageEnginePlugin;
|
|
212
25
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
26
|
+
declare function normalizeToAsyncGenerator<T>(result: T | Promise<T> | AsyncGenerator<T> | Promise<AsyncGenerator<T>>): AsyncGenerator<T>;
|
|
27
|
+
/**
|
|
28
|
+
* Merge delta data from completion responses
|
|
29
|
+
* Handles string concatenation, object merging, and array merging by index
|
|
30
|
+
*
|
|
31
|
+
* @param target - Target object to merge into
|
|
32
|
+
* @param source - Source object to merge from
|
|
33
|
+
* @returns Merged target object
|
|
34
|
+
*/
|
|
35
|
+
declare const combineDeltaData: (target: Record<string, any>, source: Record<string, any>) => Record<string, any>;
|
|
36
|
+
|
|
37
|
+
type BrowserFile = Pick<File, 'arrayBuffer' | 'lastModified' | 'name' | 'size' | 'text' | 'type'> & {
|
|
38
|
+
webkitRelativePath?: string;
|
|
219
39
|
};
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
40
|
+
type BrowserFileHandle = {
|
|
41
|
+
kind: 'file';
|
|
42
|
+
name: string;
|
|
43
|
+
getFile: () => Promise<BrowserFile>;
|
|
44
|
+
};
|
|
45
|
+
type BrowserDirectoryHandle = {
|
|
46
|
+
kind: 'directory';
|
|
47
|
+
name: string;
|
|
48
|
+
entries: () => AsyncIterable<[string, BrowserFileHandle | BrowserDirectoryHandle]>;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Browser FileList 适配器,用于读取文件选择器选中的 skill 目录。
|
|
52
|
+
*/
|
|
53
|
+
declare const loadSkillFilesFromFileList: (fileList: ArrayLike<BrowserFile>) => Promise<SkillFile[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Browser FileSystemDirectoryHandle 适配器,用于读取 window.showDirectoryPicker() 选中的目录。
|
|
56
|
+
*/
|
|
57
|
+
declare const loadSkillFilesFromDirectoryHandle: (directoryHandle: BrowserDirectoryHandle) => Promise<SkillFile[]>;
|
|
58
|
+
|
|
59
|
+
interface SkillLoaderResult {
|
|
60
|
+
/**
|
|
61
|
+
* 从源文件解析出的 skill 定义。
|
|
62
|
+
*/
|
|
63
|
+
skill: SkillDefinition;
|
|
64
|
+
/**
|
|
65
|
+
* 非致命的加载警告。
|
|
66
|
+
*/
|
|
67
|
+
warnings: Array<{
|
|
68
|
+
/**
|
|
69
|
+
* 用于 UI 和日志分类的警告编码。
|
|
70
|
+
*/
|
|
71
|
+
code: string;
|
|
72
|
+
/**
|
|
73
|
+
* 人类可读的警告信息。
|
|
74
|
+
*/
|
|
75
|
+
message: string;
|
|
76
|
+
/**
|
|
77
|
+
* 关联的 skill 文件路径。
|
|
78
|
+
*/
|
|
79
|
+
path?: string;
|
|
80
|
+
}>;
|
|
81
|
+
}
|
|
82
|
+
interface SkillLoaderOptions {
|
|
242
83
|
/**
|
|
243
|
-
*
|
|
244
|
-
* 触发时机:工具调用完成(成功、失败或取消)时触发。
|
|
245
|
-
* @param toolCall - 工具调用对象
|
|
246
|
-
* @param context - 插件上下文,包含当前工具消息、状态和错误信息
|
|
247
|
-
* @param context.status - 工具调用状态:'success' | 'failed' | 'cancelled'
|
|
248
|
-
* @param context.error - 当状态为 'failed' 或 'cancelled' 时,可能包含错误信息
|
|
84
|
+
* skill 入口文件名。
|
|
249
85
|
*/
|
|
250
|
-
|
|
251
|
-
status: "success" | "failed" | "cancelled";
|
|
252
|
-
error?: Error;
|
|
253
|
-
}) => void;
|
|
86
|
+
entryFile?: string;
|
|
254
87
|
/**
|
|
255
|
-
*
|
|
88
|
+
* 启用后,警告会直接抛出为错误。
|
|
256
89
|
*/
|
|
257
|
-
|
|
90
|
+
strict?: boolean;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* 将标准化后的 skill 文件转换为 SkillDefinition。
|
|
94
|
+
*
|
|
95
|
+
* 文件来源适配器负责提供 SkillFile[];该 loader 负责解析入口文件和资源文件。
|
|
96
|
+
*/
|
|
97
|
+
declare class SkillLoader {
|
|
98
|
+
private entryFile;
|
|
99
|
+
private strict;
|
|
100
|
+
constructor(options?: SkillLoaderOptions);
|
|
101
|
+
load(files: SkillFile[]): SkillLoaderResult;
|
|
102
|
+
private normalizeFiles;
|
|
103
|
+
private handleWarning;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
type SkillManagerOptions = {
|
|
258
107
|
/**
|
|
259
|
-
*
|
|
108
|
+
* 初始化时写入 manager 的 skill 列表。
|
|
260
109
|
*/
|
|
261
|
-
|
|
110
|
+
skills?: SkillDefinition[];
|
|
262
111
|
/**
|
|
263
|
-
*
|
|
264
|
-
* 当 assistant 响应了 tool_calls 但未追加对应的 tool 消息时,
|
|
265
|
-
* 插件将自动补充"工具调用已取消"的 tool 消息。默认:false。
|
|
112
|
+
* 初始化时选中的 skill 名称。
|
|
266
113
|
*/
|
|
267
|
-
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
declare function normalizeToAsyncGenerator<T>(result: Promise<T> | AsyncGenerator<T> | Promise<AsyncGenerator<T>>): AsyncGenerator<T>;
|
|
114
|
+
selectedSkillNames?: string[];
|
|
115
|
+
};
|
|
271
116
|
/**
|
|
272
|
-
*
|
|
273
|
-
* Handles string concatenation, object merging, and array merging by index
|
|
117
|
+
* 管理 skill 集合和选择状态。
|
|
274
118
|
*
|
|
275
|
-
*
|
|
276
|
-
* @param source - Source object to merge from
|
|
277
|
-
* @returns Merged target object
|
|
119
|
+
* manager 不编译 prompt 或 tools,也不接入 message 生命周期。
|
|
278
120
|
*/
|
|
279
|
-
declare
|
|
121
|
+
declare class SkillManager {
|
|
122
|
+
private skills;
|
|
123
|
+
private selectedSkillNames;
|
|
124
|
+
constructor(options?: SkillManagerOptions);
|
|
125
|
+
set(skill: SkillDefinition): SkillDefinition;
|
|
126
|
+
remove(name: string): SkillDefinition | undefined;
|
|
127
|
+
clear(): void;
|
|
128
|
+
get(name: string): SkillDefinition | undefined;
|
|
129
|
+
has(name: string): boolean;
|
|
130
|
+
list(): SkillDefinition[];
|
|
131
|
+
select(names: string | string[]): void;
|
|
132
|
+
unselect(names: string | string[]): void;
|
|
133
|
+
getSelectedSkillNames(): string[];
|
|
134
|
+
getSelectedSkills(): SkillDefinition[];
|
|
135
|
+
import(files: SkillFile[], options?: SkillLoaderOptions): SkillLoaderResult;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
declare const normalizeSkillPath: (path: string) => string | null;
|
|
139
|
+
declare const isTextSkillFilePath: (path: string) => boolean;
|
|
140
|
+
declare const getExtension: (path: string) => string;
|
|
280
141
|
|
|
281
|
-
export { type
|
|
142
|
+
export { type BrowserDirectoryHandle, type BrowserFile, type BrowserFileHandle, ChatMessage, CreateMessageEngineOptions, MessageEngine, MessageEnginePlugin, MessageStateAdapter, RequestProcessingState, RequestState, SkillDefinition, SkillFile, SkillLoader, type SkillLoaderOptions, type SkillLoaderResult, SkillManager, type SkillManagerOptions, type VueMessageStateAdapter, combineDeltaData, createMessageEngine, createNativeMessageAdapter, createVueMessageAdapter, getExtension, isTextSkillFilePath, lengthPlugin, loadSkillFilesFromDirectoryHandle, loadSkillFilesFromFileList, normalizeSkillPath, normalizeToAsyncGenerator, thinkingPlugin };
|
package/dist/core.js
CHANGED
|
@@ -1 +1,6 @@
|
|
|
1
|
-
"use strict";var X=Object.defineProperty;var ge=Object.getOwnPropertyDescriptor;var fe=Object.getOwnPropertyNames;var de=Object.prototype.hasOwnProperty;var pe=(e,t)=>{for(var s in t)X(e,s,{get:t[s],enumerable:!0})},me=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of fe(t))!de.call(e,o)&&o!==s&&X(e,o,{get:()=>t[o],enumerable:!(n=ge(t,o))||n.enumerable});return e};var Me=e=>me(X({},"__esModule",{value:!0}),e);var Te={};pe(Te,{combineDeltaData:()=>B,createMessageEngine:()=>ce,createNativeMessageAdapter:()=>he,createVueMessageAdapter:()=>ye,lengthPlugin:()=>H,normalizeToAsyncGenerator:()=>O,thinkingPlugin:()=>Q,toolPlugin:()=>le});module.exports=Me(Te);var Ce=e=>typeof e=="function"?null:Array.isArray(e)?e.length>0?new Set(e):null:new Set([e]),$=e=>{let t=new Set,s=(a,l)=>{try{a.listener(l)}catch(m){console.error("Error in message state subscriber:",m)}};return{notify:a=>{let l=new Set(Array.isArray(a)?a:[a]),m=e(),d=Array.from(t);for(let r of d){if(r.kinds){let u=!1;for(let y of r.kinds)if(l.has(y)){u=!0;break}if(!u)continue}s(r,m)}},subscribe:(a,l)=>{let m=typeof a=="function"?a:l;if(!m)throw new Error("subscribe listener is required");let d={kinds:Ce(a),listener:m};return t.add(d),s(d,e()),()=>{t.delete(d)}}}};var he=()=>{let e=!1,t,s=l=>{if(e)throw new Error("Message state adapter is already initialized");t={requestState:l.requestState,processingState:l.processingState,messages:[...l.messages]},e=!0},n=()=>{if(!e)throw new Error("Message state adapter is not initialized");return{requestState:t.requestState,processingState:t.processingState,messages:[...t.messages],isProcessing:t.requestState==="processing"}},o=$(n);return{initialize:s,getState:n,createMessage(l){return l},mutate:(l,m)=>{if(!e)throw new Error("Message state adapter is not initialized");let d=!1;m(t,()=>{d=!0}),d||o.notify(l)},subscribe:o.subscribe}};var w=require("vue");var se=e=>(0,w.reactive)(e),Y=e=>{let t=(0,w.isProxy)(e)?(0,w.toRaw)(e):e;if(Array.isArray(t))return t.map(s=>Y(s));if(t&&typeof t=="object"){let s={};for(let[n,o]of Object.entries(t))s[n]=Y(o);return s}return t},ye=()=>{let e=!1,t=(0,w.ref)("idle"),s=(0,w.ref)(void 0),n=(0,w.ref)([]),o=(0,w.computed)(()=>t.value==="processing"),a=u=>{if(e)throw new Error("Message state adapter is already initialized");t.value=u.requestState,s.value=u.processingState,n.value=u.messages.map(se),e=!0},l=u=>se(u),m=()=>{if(!e)throw new Error("Message state adapter is not initialized");return{requestState:t.value,processingState:s.value,messages:Y(n.value),isProcessing:o.value}},d=$(m);return{requestState:t,processingState:s,messages:n,isProcessing:o,initialize:a,getState:m,createMessage:l,mutate:(u,y)=>{if(!e)throw new Error("Message state adapter is not initialized");let T={get requestState(){return t.value},set requestState(S){t.value=S},get processingState(){return s.value},set processingState(S){s.value=S},get messages(){return n.value},set messages(S){n.value=S.map(l)}},p=!1;if(y(T,()=>{p=!0}),p)return;(Array.isArray(u)?u:[u]).includes("messages")&&(n.value=[...n.value]),d.notify(u)},subscribe:d.subscribe}};var H=(e={})=>{let{continueContent:t="Please continue with your previous answer.",...s}=e;return{name:"length",...s,onAfterRequest:async n=>{let{lastChoice:o,appendMessage:a,requestNext:l}=n;return o?.finish_reason==="length"&&(a({role:"user",content:t}),l()),s.onAfterRequest?.(n)}}};var Q=(e={})=>{let t=(s,n)=>!!s.thinking!==n||!!s.open!==n;return{name:"thinking",...e,onCompletionChunk(s){let{choice:n,currentMessage:o,updateCurrentMessage:a}=s,l=n,m=l?.message?.reasoning_content||l?.delta?.reasoning_content,d=typeof m=="string"&&m.trim()!=="";return d?o.state&&typeof o.state=="object"?t(o.state,d)&&a(r=>{r.state.thinking=!0,r.state.open=!0}):a(r=>{r.state={thinking:d,open:d}}):o.state&&typeof o.state=="object"&&"thinking"in o.state&&t(o.state,d)&&a(r=>{r.state.thinking=!1,r.state.open=!1}),e.onCompletionChunk?.(s)},onTurnEnd(s){let{currentTurn:n,mutate:o}=s,a=n.at(-1);return a?.state&&typeof a.state=="object"&&"thinking"in a.state&&t(a.state,!1)&&o("messages",()=>{a.state.thinking=!1,a.state.open=!1}),e.onTurnEnd?.(s)}}};var N=class extends Error{constructor(t){super(t),this.name="AbortError"}};function Se(e){if(e.aborted)return{promise:Promise.reject(new N(String(e.reason??"Aborted"))),cleanup:()=>{}};let t=null;return{promise:new Promise((o,a)=>{t=()=>{a(new N(String(e.reason??"Aborted")))},e.addEventListener("abort",t,{once:!0})}),cleanup:()=>{t&&(e.removeEventListener("abort",t),t=null)}}}function ae(e,t){let{promise:s,cleanup:n}=Se(t);return Promise.race([e,s]).finally(n)}function re(e,t){let s={};for(let n in e)t.includes(n)&&(s[n]=e[n]);return s}function ie(e,t){let s={};for(let n in e)t.includes(n)||(s[n]=e[n]);return s}async function*O(e){if(ne(e)){yield*e;return}let t=await e;if(ne(t)){yield*t;return}yield t}function ne(e){return e&&typeof e=="object"&&typeof e[Symbol.asyncIterator]=="function"}var Z=e=>typeof e=="object"&&e!==null,oe=e=>Z(e)&&typeof e.index=="number",B=(e,t)=>{for(let[s,n]of Object.entries(t)){let o=e[s];if(o)if(typeof o=="string"&&typeof n=="string")s==="type"&&o||(e[s]=o+n);else if(Array.isArray(o)&&Array.isArray(n))if(o.every(a=>oe(a))&&n.every(a=>oe(a))){let a=new Map(o.map(r=>[r.index,r])),l=new Map(n.map(r=>[r.index,r]));for(let[r,u]of l)if(a.has(r)){let y=a.get(r);a.set(r,B(y,u))}else a.set(r,u);let m=Math.max(...Array.from(a.keys()),-1)+1,d=m>o.length?Array.from({length:m}):o;for(let[r,u]of a)d[r]=u;e[s]=d}else e[s]=[...o,...n];else Z(o)&&Z(n)&&(e[s]=B(o,n));else e[s]=n}return e};function be({messages:e,cancelledContent:t,createMessage:s,mutate:n}){let o=[];for(let a=0;a<e.length;a++){let l=e[a];if(l.role==="assistant"&&l.tool_calls&&l.tool_calls.length>0){let m=new Set(l.tool_calls.map(u=>u.id)),d=new Set;for(let u=a+1;u<e.length;u++){let y=e[u];y.role==="tool"&&y.tool_call_id&&m.has(y.tool_call_id)&&d.add(y.tool_call_id)}let r=l.tool_calls.map(u=>u.id).filter(u=>!d.has(u));r.length>0&&o.push({insertAfterIndex:a,missingToolCallIds:r})}}o.length!==0&&n("messages",a=>{for(let l=o.length-1;l>=0;l--){let{insertAfterIndex:m,missingToolCallIds:d}=o[l],r=d.map(u=>s({role:"tool",tool_call_id:u,content:t}));a.messages.splice(m+1,0,...r)}})}var le=e=>{let{getTools:t,beforeCallTools:s,callTool:n,onToolCallStart:o,onToolCallEnd:a,toolCallCancelledContent:l="Tool call cancelled.",toolCallFailedContent:m="Tool call failed.",autoFillMissingToolMessages:d=!1,...r}=e,u=(p,M)=>{var C,S;return p.state??(p.state={}),(C=p.state).toolCall??(C.toolCall={}),(S=p.state.toolCall)[M]??(S[M]={}),p},y=(...p)=>{let[M,{assistantMessage:C,mutate:S}]=p;S("messages",()=>{let R=u(C,M.id);R.state.toolCall[M.id].status="running"}),o?.(...p)},T=(...p)=>{let[M,{status:C,assistantMessage:S,mutate:R}]=p;R("messages",()=>{let W=u(S,M.id);W.state.toolCall[M.id].status=C}),a?.(...p)};return{name:"tool",...r,onTurnStart:p=>{let{getState:M,createMessage:C,mutate:S}=p,R=M().messages;return d&&be({messages:R,cancelledContent:l,createMessage:C,mutate:S}),r.onTurnStart?.(p)},onBeforeRequest:async p=>{let{requestBody:M}=p,C=await t();return C&&C.length>0&&(M.tools=C),r.onBeforeRequest?.(p)},onAfterRequest:async p=>{let{currentMessage:M,lastChoice:C,appendMessage:S,abortSignal:R,setRequestState:W,requestNext:v,mutate:F,createMessage:E}=p;if(C?.finish_reason!=="tool_calls"||!M.tool_calls?.length)return;W("processing","calling-tools"),await s?.(M.tool_calls,{...p,assistantMessage:M});let U=M.tool_calls.map(async j=>{let G=Math.floor(Date.now()/1e3),J=!1,x=E({role:"tool",tool_call_id:j.id,content:"",metadata:{createdAt:G,updatedAt:G}});S(x);let K={...p,assistantMessage:M,toolMessage:x};y(j,K);try{let i=n(j,K),c=O(i);for await(let f of c)F("messages",()=>{if((typeof f=="string"&&f.length>0||f&&typeof f=="object"&&Object.keys(f).length>0)&&(J=!0),typeof f=="string")x.content+=f;else{let h={};try{let b=Array.isArray(x.content)?x.content.map(g=>g.text).join(""):x.content;h=JSON.parse(b||"{}")}catch(b){console.warn(b)}x.content=JSON.stringify(B(h,f))}x.metadata.updatedAt=Math.floor(Date.now()/1e3)});T(j,{...K,status:"success"})}catch(i){let c=i instanceof Error?i:new Error(String(i));if(R.aborted){T(j,{...K,status:"cancelled",error:c});return}console.error(i),J||F("messages",()=>{x.content=m,x.metadata.updatedAt=Math.floor(Date.now()/1e3)}),T(j,{...K,status:"failed",error:c})}});return await Promise.all(U),R.aborted||v(),r.onAfterRequest?.(p)}}};var Pe=async()=>{throw new Error("Response provider is not set")},Ae=e=>{let t=[];for(let s of e){if(s.name){let n=t.findIndex(o=>o.name===s.name);n!==-1&&t.splice(n,1)}t.push(s)}return t},z=(e,t)=>typeof e.disabled=="function"?e.disabled(t):!!e.disabled,ce=(e,t={})=>{let{initialMessages:s=[],requestMessageFields:n=[],requestMessageFieldsExclude:o=["state","metadata","loading"],responseProvider:a=Pe,onCompletionChunk:l,plugins:m=[]}=t,d={requestState:"idle",processingState:void 0,messages:[...s]};e.initialize(d);let r={currentTurn:[],customContext:{},abortController:null,responseProvider:a},u=[Q(),H()],y=Ae(u.concat(m)),T=()=>e.getState(),p=i=>e.createMessage(i),M=e.subscribe,C=e.mutate,S=i=>!i||Object.keys(i).length===0?!1:Object.values(i).some(c=>!!c),R=i=>{let c=i;return n.length&&(c=c.map(f=>re(f,n))),o.length&&(c=c.map(f=>ie(f,o))),c},W=i=>{Object.assign(r.customContext,i)},v=(i,c)=>{C("requestState",(f,h)=>{if(f.requestState===i&&f.processingState===c){h();return}f.requestState=i,f.processingState=i==="processing"?c??"requesting":void 0})},F=(...i)=>{let c=i.map(f=>p(f));return C("messages",f=>{f.messages.push(...c)}),r.currentTurn.push(...c),c},E=i=>({getState:T,createMessage:p,mutate:C,abortSignal:i,currentTurn:r.currentTurn,customContext:r.customContext,setRequestState:v,setCustomContext:W});async function U(i,c,f={}){v("processing","requesting");let h={messages:T().messages},b=E(c);for(let _ of y.filter(A=>!z(A,b)))await _.onBeforeRequest?.({...b,requestBody:h});h.messages=R(h.messages);let g={role:"assistant",content:"",loading:!0};[g]=F(g),f.setAssistantMessage?.(g);let P=i(h,c),k=O(P),I;for await(let _ of k){v("processing","completing"),C("messages",(q,V)=>{g.loading?g.loading=void 0:V()});let A=(_.choices||[]).find(q=>q.index===0)??_.choices?.[0];if(!A)continue;I=A;let D=()=>{C("messages",()=>{g.metadata||(g.metadata={});let{created:q,...V}=_;g.metadata.createdAt=q,g.metadata.updatedAt=Math.floor(Date.now()/1e3),Object.assign(g.metadata,V);let L="delta"in A&&S(A.delta)&&A.delta||"message"in A&&S(A.message)&&A.message||null;if(L?.role&&(g.role=L.role),L){let{role:xe,...ue}=L;B(g,ue)}})},ee=q=>{C("messages",()=>{q(g)})};if(l){let q=E(c);l({...q,chunk:_,choice:A,currentMessage:g,updateCurrentMessage:ee},D)}else D();let te=E(c);for(let q of y.filter(V=>!z(V,te)))q.onCompletionChunk?.({...te,abortSignal:c,chunk:_,choice:A,currentMessage:g,updateCurrentMessage:ee})}await j(g,i,c,I,f)}async function j(i,c,f,h,b){let g=!1,P=E(f),k=y.filter(I=>!z(I,P)).map(I=>{if(!I.onAfterRequest)return null;let _=D=>{F(...Array.isArray(D)?D:[D])},A=()=>{g=!0};return I.onAfterRequest({...P,currentMessage:i,lastChoice:h,appendMessage:_,requestNext:A})}).filter(I=>I!==null);await ae(Promise.all(k),f),g&&await U(c,f,b)}async function G(){let i=new AbortController;r.abortController=i,r.customContext={};let c=null,f=h=>{c=h};try{v("processing","requesting");let h=E(i.signal);for(let P of y.filter(k=>!z(k,h)))await P.onTurnStart?.(h);let b=r.responseProvider;try{await U(b,i.signal,{setAssistantMessage:f}),v("completed")}catch(P){if(i.signal.aborted||P instanceof N||P instanceof Error&&P.name==="AbortError")v("aborted");else throw P}let g=E(i.signal);for(let P of y.filter(k=>!z(k,g)))await P.onTurnEnd?.(g)}catch(h){v("error");let b=!1,g=E(i.signal);for(let P of y.filter(k=>!z(k,g)))P.onError&&(b=!0,P.onError({...g,error:h}));if(!b)throw h}finally{let h=E(i.signal);for(let b of y.filter(g=>!z(g,h)))try{b.onFinally?.(h)}catch(g){console.error(`Error in onFinally hook for plugin [${b.name||"Anonymous"}]:`,g)}r.abortController=null,r.currentTurn=[],C("messages",(b,g)=>{c?.loading?c.loading=void 0:g()})}}async function J(i){if(!i||!i.trim()){console.warn("Cannot send empty message");return}if(T().requestState==="processing"){console.warn("Cannot send message while processing is in progress");return}let c=Math.floor(Date.now()/1e3);F({role:"user",content:i.trim(),metadata:{createdAt:c,updatedAt:c}}),await G()}async function x(...i){if(T().requestState==="processing"){console.warn("Cannot send message while processing is in progress");return}F(...i),await G()}async function K(){r.abortController?.abort(),T().isProcessing&&await new Promise(i=>{let c=()=>{};c=M("requestState",f=>{f.isProcessing||(c(),i())})})}return{getState:T,subscribe:M,sendMessage:J,send:x,abort:K,setResponseProvider(i){r.responseProvider=i}}};0&&(module.exports={combineDeltaData,createMessageEngine,createNativeMessageAdapter,createVueMessageAdapter,lengthPlugin,normalizeToAsyncGenerator,thinkingPlugin,toolPlugin});
|
|
1
|
+
"use strict";var re=Object.defineProperty;var ve=Object.getOwnPropertyDescriptor;var Ee=Object.getOwnPropertyNames;var qe=Object.prototype.hasOwnProperty;var Be=(e,t)=>{for(var s in t)re(e,s,{get:t[s],enumerable:!0})},_e=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Ee(t))!qe.call(e,i)&&i!==s&&re(e,i,{get:()=>t[i],enumerable:!(n=ve(t,i))||n.enumerable});return e};var Ie=e=>_e(re({},"__esModule",{value:!0}),e);var Ze={};Be(Ze,{SkillLoader:()=>J,SkillManager:()=>ie,combineDeltaData:()=>D,compileSkillInstructions:()=>ne,createMessageEngine:()=>Pe,createNativeMessageAdapter:()=>De,createSkillRuntimeTools:()=>se,createVueMessageAdapter:()=>ze,getExtension:()=>Q,isTextSkillFilePath:()=>U,lengthPlugin:()=>te,loadSkillFilesFromDirectoryHandle:()=>we,loadSkillFilesFromFileList:()=>xe,normalizeSkillPath:()=>V,normalizeToAsyncGenerator:()=>H,skillPlugin:()=>ye,thinkingPlugin:()=>oe,toolPlugin:()=>Te});module.exports=Ie(Ze);var Ne=e=>typeof e=="function"?null:Array.isArray(e)?e.length>0?new Set(e):null:new Set([e]),ee=e=>{let t=new Set,s=(o,r)=>{try{o.listener(r)}catch(c){console.error("Error in message state subscriber:",c)}};return{notify:o=>{let r=new Set(Array.isArray(o)?o:[o]),c=e(),p=Array.from(t);for(let a of p){if(a.kinds){let u=!1;for(let M of a.kinds)if(r.has(M)){u=!0;break}if(!u)continue}s(a,c)}},subscribe:(o,r)=>{let c=typeof o=="function"?o:r;if(!c)throw new Error("subscribe listener is required");let p={kinds:Ne(o),listener:c};return t.add(p),s(p,e()),()=>{t.delete(p)}}}};var De=()=>{let e=!1,t,s=r=>{if(e)throw new Error("Message state adapter is already initialized");t={requestState:r.requestState,processingState:r.processingState,messages:[...r.messages]},e=!0},n=()=>{if(!e)throw new Error("Message state adapter is not initialized");return{requestState:t.requestState,processingState:t.processingState,messages:[...t.messages],isProcessing:t.requestState==="processing"}},i=ee(n);return{initialize:s,getState:n,createMessage(r){return r},mutate:(r,c)=>{if(!e)throw new Error("Message state adapter is not initialized");let p=!1;c(t,()=>{p=!0}),p||i.notify(r)},subscribe:i.subscribe}};var v=require("vue");var de=e=>(0,v.reactive)(e),ae=e=>{let t=(0,v.isProxy)(e)?(0,v.toRaw)(e):e;if(Array.isArray(t))return t.map(s=>ae(s));if(t&&typeof t=="object"){let s={};for(let[n,i]of Object.entries(t))s[n]=ae(i);return s}return t},ze=()=>{let e=!1,t=(0,v.ref)("idle"),s=(0,v.ref)(void 0),n=(0,v.ref)([]),i=(0,v.computed)(()=>t.value==="processing"),o=u=>{if(e)throw new Error("Message state adapter is already initialized");t.value=u.requestState,s.value=u.processingState,n.value=u.messages.map(de),e=!0},r=u=>de(u),c=()=>{if(!e)throw new Error("Message state adapter is not initialized");return{requestState:t.value,processingState:s.value,messages:ae(n.value),isProcessing:i.value}},p=ee(c);return{requestState:t,processingState:s,messages:n,isProcessing:i,initialize:o,getState:c,createMessage:r,mutate:(u,M)=>{if(!e)throw new Error("Message state adapter is not initialized");let F={get requestState(){return t.value},set requestState(_){t.value=_},get processingState(){return s.value},set processingState(_){s.value=_},get messages(){return n.value},set messages(_){n.value=_.map(r)}},z=!1;if(M(F,()=>{z=!0}),z)return;(Array.isArray(u)?u:[u]).includes("messages")&&(n.value=[...n.value]),p.notify(u)},subscribe:p.subscribe}};var te=(e={})=>{let{continueContent:t="Please continue with your previous answer.",...s}=e;return{name:"length",...s,onAfterRequest:async n=>{let{lastChoice:i,appendMessage:o,requestNext:r}=n;return i?.finish_reason==="length"&&(o({role:"user",content:t}),r()),s.onAfterRequest?.(n)}}};var pe={listSkillFiles:"list_skill_files",readSkillFile:"read_skill_file"},Oe="execute_skill_command",fe=[{type:"function",function:{name:pe.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:pe.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}}}],je={type:"function",function:{name:Oe,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}}},le=(e,t)=>({skillName:e,id:t.id,path:t.path,kind:t.kind,mimeType:t.mimeType,size:t.size,lastModified:t.lastModified}),ce=e=>{let t=e.function.arguments;if(!t)return{};try{let s=JSON.parse(t);return s&&typeof s=="object"&&!Array.isArray(s)?s:{}}catch{return{}}},Le=e=>Array.isArray(e)&&e.every(t=>typeof t=="string")?e:void 0,Ke=e=>{if(!e.some(n=>!!n.files?.length))return[];let s=n=>{if(!(typeof n!="string"||!n))return e.find(i=>i.name===n)};return[{tool:fe[0],handler:n=>{let i=ce(n),o=s(i.skillName);return{files:(o?[o]:e).flatMap(c=>(c.files??[]).map(p=>le(c.name,p)))}}},{tool:fe[1],handler:n=>{let i=ce(n),o=s(i.skillName),r=typeof i.path=="string"?i.path:void 0;if(!o)return{error:"skill_not_found"};if(!r)return{error:"file_path_required",skillName:o.name};let c=o.files?.find(p=>p.path===r);return c?c.kind==="binary"?{error:"binary_file_not_readable",file:le(o.name,c)}:{file:le(o.name,c),content:c.content}:{error:"file_not_found",skillName:o.name,path:r}}}]},We=(e,t)=>{if(!t||e.length===0)return[];let s=n=>{if(!(typeof n!="string"||!n))return e.find(i=>i.name===n)};return[{tool:je,handler:async n=>{let i=ce(n),o=s(i.skillName),r=typeof i.command=="string"?i.command:void 0,c=Le(i.args);return o?r?c?t({skill:o,skillName:o.name,command:r,args:c}):{error:"args_required",skillName:o.name,command:r}:{error:"command_required",skillName:o.name}:{error:"skill_not_found"}}}]},se=(e,t={})=>[...Ke(e),...We(e,t.executeSkillCommand)],ne=async e=>{let t=[];for(let s of e){let n=s.instructions?.trim();n&&t.push(`## ${s.name}
|
|
2
|
+
|
|
3
|
+
${n}`)}if(t.length!==0)return{role:"system",content:["Apply these skill instructions when generating the response.",...t].join(`
|
|
4
|
+
|
|
5
|
+
`)}};var ue="__tiny_robot_skill",ye=e=>{let{getSkills:t,executeSkillCommand:s,onSkillsResolved:n,...i}=e;return{name:"skill",...i,provideTools:async o=>o.customContext[ue]?.runtimeTools??[],onTurnStart:async o=>{let r=await t?.(o)??[],c={skills:r,skillNames:r.map(p=>p.name),runtimeTools:se(r,{executeSkillCommand:s&&(p=>s(p,o))})};return o.setCustomContext({[ue]:c}),await n?.(c,o),i.onTurnStart?.(o)},onBeforeRequest:async o=>{let r=o.customContext[ue];if(r){let c=await ne(r.skills);c&&(o.requestBody.messages=[c,...o.requestBody.messages])}return i.onBeforeRequest?.(o)}}};var oe=(e={})=>{let t=(s,n)=>!!s.thinking!==n||!!s.open!==n;return{name:"thinking",...e,onCompletionChunk(s){let{choice:n,currentMessage:i,updateCurrentMessage:o}=s,r=n,c=r?.message?.reasoning_content||r?.delta?.reasoning_content,p=typeof c=="string"&&c.trim()!=="";return p?i.state&&typeof i.state=="object"?t(i.state,p)&&o(a=>{a.state.thinking=!0,a.state.open=!0}):o(a=>{a.state={thinking:p,open:p}}):i.state&&typeof i.state=="object"&&"thinking"in i.state&&t(i.state,p)&&o(a=>{a.state.thinking=!1,a.state.open=!1}),e.onCompletionChunk?.(s)},onTurnEnd(s){let{currentTurn:n,mutate:i}=s,o=n.at(-1);return o?.state&&typeof o.state=="object"&&"thinking"in o.state&&t(o.state,!1)&&i("messages",()=>{o.state.thinking=!1,o.state.open=!1}),e.onTurnEnd?.(s)}}};var G=class extends Error{constructor(t){super(t),this.name="AbortError"}};function $e(e){if(e.aborted)return{promise:Promise.reject(new G(String(e.reason??"Aborted"))),cleanup:()=>{}};let t=null;return{promise:new Promise((i,o)=>{t=()=>{o(new G(String(e.reason??"Aborted")))},e.addEventListener("abort",t,{once:!0})}),cleanup:()=>{t&&(e.removeEventListener("abort",t),t=null)}}}function Se(e,t){let{promise:s,cleanup:n}=$e(t);return Promise.race([e,s]).finally(n)}function Ce(e,t){let s={};for(let n in e)t.includes(n)&&(s[n]=e[n]);return s}function Me(e,t){let s={};for(let n in e)t.includes(n)||(s[n]=e[n]);return s}async function*H(e){if(he(e)){yield*e;return}let t=await e;if(he(t)){yield*t;return}yield t}function he(e){return e&&typeof e=="object"&&typeof e[Symbol.asyncIterator]=="function"}var me=e=>typeof e=="object"&&e!==null,ke=e=>me(e)&&typeof e.index=="number",D=(e,t)=>{for(let[s,n]of Object.entries(t)){let i=e[s];if(i)if(typeof i=="string"&&typeof n=="string")s==="type"&&i||(e[s]=i+n);else if(Array.isArray(i)&&Array.isArray(n))if(i.every(o=>ke(o))&&n.every(o=>ke(o))){let o=new Map(i.map(a=>[a.index,a])),r=new Map(n.map(a=>[a.index,a]));for(let[a,u]of r)if(o.has(a)){let M=o.get(a);o.set(a,D(M,u))}else o.set(a,u);let c=Math.max(...Array.from(o.keys()),-1)+1,p=c>i.length?Array.from({length:c}):i;for(let[a,u]of o)p[a]=u;e[s]=p}else e[s]=[...i,...n];else me(i)&&me(n)&&(e[s]=D(i,n));else e[s]=n}return e};function Ge({messages:e,cancelledContent:t,createMessage:s,mutate:n}){let i=[];for(let o=0;o<e.length;o++){let r=e[o];if(r.role==="assistant"&&r.tool_calls&&r.tool_calls.length>0){let c=new Set(r.tool_calls.map(u=>u.id)),p=new Set;for(let u=o+1;u<e.length;u++){let M=e[u];M.role==="tool"&&M.tool_call_id&&c.has(M.tool_call_id)&&p.add(M.tool_call_id)}let a=r.tool_calls.map(u=>u.id).filter(u=>!p.has(u));a.length>0&&i.push({insertAfterIndex:o,missingToolCallIds:a})}}i.length!==0&&n("messages",o=>{for(let r=i.length-1;r>=0;r--){let{insertAfterIndex:c,missingToolCallIds:p}=i[r],a=p.map(u=>s({role:"tool",tool_call_id:u,content:t}));o.messages.splice(c+1,0,...a)}})}var Te=e=>{let{getTools:t,beforeCallTools:s,callTool:n,onToolCallStart:i,onToolCallEnd:o,toolCallCancelledContent:r="Tool call cancelled.",toolCallFailedContent:c="Tool call failed.",autoFillMissingToolMessages:p=!1,...a}=e,u=(m,f)=>{var S,h;return m.state??(m.state={}),(S=m.state).toolCall??(S.toolCall={}),(h=m.state.toolCall)[f]??(h[f]={}),m},M=(...m)=>{let[f,{assistantMessage:S,mutate:h}]=m;h("messages",()=>{let R=u(S,f.id);R.state.toolCall[f.id].status="running"}),i?.(...m)},F=(...m)=>{let[f,{status:S,assistantMessage:h,mutate:R}]=m;R("messages",()=>{let I=u(h,f.id);I.state.toolCall[f.id].status=S}),o?.(...m)},z=m=>m.type==="function"&&"function"in m,W=m=>!!(m&&typeof m=="object"&&"tool"in m&&"handler"in m),B=m=>{let f=m;return typeof f.provideTools=="function"?f:void 0},_=(m,f)=>typeof m.disabled=="function"?m.disabled(f):!!m.disabled,X=async(m,f=[])=>{let S=[];for(let T of m.plugins){let l=B(T);!_(T,m)&&l&&S.push(...(await l.provideTools(m)).map(d=>({item:d,source:{type:"toolProvider",pluginName:T.name}})))}let h=[...S,...(await t(m)).map(T=>({item:T,source:{type:"toolPlugin"}}))],R=[],I=new Map,O=new Map,j=new Set,$=T=>{let l=T.function.name;if(j.has(l))throw new Error(`Duplicate tool name "${l}" detected. Tool names must be unique because tool calls are routed by function.name.`);j.add(l)};f.forEach($);for(let{item:T,source:l}of h){let d=W(T)?T.tool:T;$(d),O.set(d.function.name,l),W(T)?(R.push(T.tool),I.set(T.tool.function.name,T)):R.push(T)}return{tools:R,runtimeToolMap:I,toolSourceMap:O}};return{name:"tool",...a,onTurnStart:m=>{let{getState:f,createMessage:S,mutate:h}=m,R=f().messages;return p&&Ge({messages:R,cancelledContent:r,createMessage:S,mutate:h}),a.onTurnStart?.(m)},onBeforeRequest:async m=>{let{requestBody:f}=m,S=Array.isArray(f.tools)?f.tools:[],{tools:h}=await X(m,S);return h&&h.length>0&&(f.tools=S.length?[...S,...h]:h),a.onBeforeRequest?.(m)},onAfterRequest:async m=>{let{currentMessage:f,lastChoice:S,appendMessage:h,abortSignal:R,setRequestState:I,requestNext:O,mutate:j,createMessage:$}=m;if(S?.finish_reason!=="tool_calls"||!f.tool_calls?.length)return;I("processing","calling-tools"),await s?.(f.tool_calls,{...m,assistantMessage:f});let{runtimeToolMap:T,toolSourceMap:l}=await X(m),d=f.tool_calls.map(async y=>{let C=Math.floor(Date.now()/1e3),w=!1,g=$({role:"tool",tool_call_id:y.id,content:"",metadata:{createdAt:C,updatedAt:C}});h(g);let k=z(y)?y:void 0,E=k?l.get(k.function.name)??{type:"unknown"}:{type:"unknown"},b={...m,assistantMessage:f,toolMessage:g,toolSource:E};M(y,b);try{let x=k?T.get(k.function.name):void 0,P=x&&k?x.handler(k,b):n(y,b),N=H(P);for await(let q of N)j("messages",()=>{if((typeof q=="string"&&q.length>0||q&&typeof q=="object"&&Object.keys(q).length>0)&&(w=!0),typeof q=="string")g.content+=q;else{let Y={};try{let A=Array.isArray(g.content)?g.content.map(L=>L.text).join(""):g.content;Y=JSON.parse(A||"{}")}catch(A){console.warn(A)}g.content=JSON.stringify(D(Y,q))}g.metadata.updatedAt=Math.floor(Date.now()/1e3)});F(y,{...b,status:"success"})}catch(x){let P=x instanceof Error?x:new Error(String(x));if(R.aborted){F(y,{...b,status:"cancelled",error:P});return}console.error(x),w||j("messages",()=>{g.content=c,g.metadata.updatedAt=Math.floor(Date.now()/1e3)}),F(y,{...b,status:"failed",error:P})}});return await Promise.all(d),R.aborted||O(),a.onAfterRequest?.(m)}}};var He=async()=>{throw new Error("Response provider is not set")},Ve=e=>{let t=[];for(let s of e){if(s.name){let n=t.findIndex(i=>i.name===s.name);n!==-1&&t.splice(n,1)}t.push(s)}return t},K=(e,t)=>typeof e.disabled=="function"?e.disabled(t):!!e.disabled,Pe=(e,t={})=>{let{initialMessages:s=[],requestMessageFields:n=[],requestMessageFieldsExclude:i=["state","metadata","loading"],responseProvider:o=He,onCompletionChunk:r,plugins:c=[]}=t,p={requestState:"idle",processingState:void 0,messages:[...s]};e.initialize(p);let a={currentTurn:[],customContext:{},abortController:null,responseProvider:o},u=[oe(),te()],M=Ve(u.concat(c)),F=()=>e.getState(),z=l=>e.createMessage(l),W=e.subscribe,B=e.mutate,_=l=>!l||Object.keys(l).length===0?!1:Object.values(l).some(d=>!!d),X=l=>{let d=l;return n.length&&(d=d.map(y=>Ce(y,n))),i.length&&(d=d.map(y=>Me(y,i))),d},m=l=>{Object.assign(a.customContext,l)},f=(l,d)=>{B("requestState",(y,C)=>{if(y.requestState===l&&y.processingState===d){C();return}y.requestState=l,y.processingState=l==="processing"?d??"requesting":void 0})},S=(...l)=>{let d=l.map(y=>z(y));return B("messages",y=>{y.messages.push(...d)}),a.currentTurn.push(...d),d},h=l=>({getState:F,createMessage:z,mutate:B,abortSignal:l,currentTurn:a.currentTurn,plugins:M,customContext:a.customContext,setRequestState:f,setCustomContext:m});async function R(l,d,y={}){f("processing","requesting");let C={messages:F().messages},w=h(d);for(let x of M.filter(P=>!K(P,w)))await x.onBeforeRequest?.({...w,requestBody:C});C.messages=X(C.messages);let g={role:"assistant",content:"",loading:!0};[g]=S(g),y.setAssistantMessage?.(g);let k=l(C,d),E=H(k),b;for await(let x of E){f("processing","completing"),B("messages",(A,L)=>{g.loading?g.loading=void 0:L()});let P=(x.choices||[]).find(A=>A.index===0)??x.choices?.[0];if(!P)continue;b=P;let N=()=>{B("messages",()=>{g.metadata||(g.metadata={});let{created:A,...L}=x;g.metadata.createdAt=A,g.metadata.updatedAt=Math.floor(Date.now()/1e3),Object.assign(g.metadata,L);let Z="delta"in P&&_(P.delta)&&P.delta||"message"in P&&_(P.message)&&P.message||null;if(Z?.role&&(g.role=Z.role),Z){let{role:et,...Fe}=Z;D(g,Fe)}})},q=A=>{B("messages",()=>{A(g)})};if(r){let A=h(d);r({...A,chunk:x,choice:P,currentMessage:g,updateCurrentMessage:q},N)}else N();let Y=h(d);for(let A of M.filter(L=>!K(L,Y)))A.onCompletionChunk?.({...Y,abortSignal:d,chunk:x,choice:P,currentMessage:g,updateCurrentMessage:q})}await I(g,l,d,b,y)}async function I(l,d,y,C,w){let g=!1,k=h(y),E=M.filter(b=>!K(b,k)).map(b=>{if(!b.onAfterRequest)return null;let x=N=>{S(...Array.isArray(N)?N:[N])},P=()=>{g=!0};return b.onAfterRequest({...k,currentMessage:l,lastChoice:C,appendMessage:x,requestNext:P})}).filter(b=>b!==null);await Se(Promise.all(E),y),g&&await R(d,y,w)}async function O(){let l=new AbortController;a.abortController=l,a.customContext={};let d=null,y=C=>{d=C};try{f("processing","requesting");let C=h(l.signal);for(let k of M.filter(E=>!K(E,C)))await k.onTurnStart?.(C);let w=a.responseProvider;try{await R(w,l.signal,{setAssistantMessage:y}),f("completed")}catch(k){if(l.signal.aborted||k instanceof G||k instanceof Error&&k.name==="AbortError")f("aborted");else throw k}let g=h(l.signal);for(let k of M.filter(E=>!K(E,g)))await k.onTurnEnd?.(g)}catch(C){f("error");let w=!1,g=h(l.signal);for(let k of M.filter(E=>!K(E,g)))k.onError&&(w=!0,k.onError({...g,error:C}));if(!w)throw C}finally{let C=h(l.signal);for(let w of M.filter(g=>!K(g,C)))try{w.onFinally?.(C)}catch(g){console.error(`Error in onFinally hook for plugin [${w.name||"Anonymous"}]:`,g)}a.abortController=null,a.currentTurn=[],B("messages",(w,g)=>{d?.loading?d.loading=void 0:g()})}}async function j(l){if(!l||!l.trim()){console.warn("Cannot send empty message");return}if(F().requestState==="processing"){console.warn("Cannot send message while processing is in progress");return}let d=Math.floor(Date.now()/1e3);S({role:"user",content:l.trim(),metadata:{createdAt:d,updatedAt:d}}),await O()}async function $(...l){if(F().requestState==="processing"){console.warn("Cannot send message while processing is in progress");return}S(...l),await O()}async function T(){a.abortController?.abort(),F().isProcessing&&await new Promise(l=>{let d=()=>{};d=W("requestState",y=>{y.isProcessing||(d(),l())})})}return{getState:F,subscribe:W,sendMessage:j,send:$,abort:T,setResponseProvider(l){a.responseProvider=l}}};var V=e=>{let t=e.split("\\").join("/").replace(/^\.\/+/,"");return!t||t.startsWith("/")||t.includes("\0")||t.split("/").some(s=>s===".."||s==="")?null:t},U=e=>[".md",".txt",".json"].includes(Q(e)),Q=e=>{let t=e.split("/").at(-1)||e,s=t.lastIndexOf(".");return s===-1?"":t.slice(s).toLowerCase()};var xe=async e=>{let t=Array.from({length:e.length},(s,n)=>e[n]).filter(s=>!!s);return Promise.all(t.map(s=>{let n=s.webkitRelativePath||s.name;return be(s,Ue(n))}))},we=async e=>{let t=[],s=async(n,i="")=>{for await(let[o,r]of n.entries()){let c=i?`${i}/${o}`:o;if(r.kind==="directory"){await s(r,c);continue}t.push(await be(await r.getFile(),c))}};return await s(e),t.sort((n,i)=>n.path.localeCompare(i.path))},be=async(e,t)=>{let s=V(t);if(!s)throw new Error(`Invalid skill file path: ${t}`);return U(s)?{path:s,kind:"text",content:await e.text(),mimeType:e.type,size:e.size,lastModified:e.lastModified}:{path:s,kind:"binary",content:await e.arrayBuffer(),mimeType:e.type,size:e.size,lastModified:e.lastModified}},Ue=e=>{let t=e.split("\\").join("/"),s=t.split("/").filter(Boolean);return s.length<=1?t:s.slice(1).join("/")};var Re=require("yaml");var J=class{constructor(t={}){this.entryFile=t.entryFile??"SKILL.md",this.strict=t.strict??!1}load(t){let s=[],n=this.normalizeFiles(t,s),i=n.find(u=>u.path===this.entryFile);if(!i)throw new Error(`Skill entry file "${this.entryFile}" is missing.`);if(i.kind!=="text")throw new Error(`Skill entry file "${this.entryFile}" must be a text file.`);let{frontmatter:o,body:r}=Je(i.content),c=r.trim();if(!c)throw new Error(`Skill entry file "${this.entryFile}" must contain instructions.`);let p=Ae(o.metadata),a=[];for(let u of n)if(u.path!==this.entryFile){if(u.kind==="binary"){a.push({...u,id:u.path});continue}if(!U(u.path)){s.push({code:"unsupported-text-file-ignored",message:"Only markdown, text, and json files are converted to text skill files.",path:u.path});continue}a.push({...u,id:u.path})}return{skill:{name:ge(o.name)||Xe(this.entryFile),description:ge(o.description)||"",instructions:c,files:a.length?a:void 0,metadata:{...p,homepage:ge(o.homepage),frontmatter:o}},warnings:s}}normalizeFiles(t,s){let n=[],i=new Set;for(let o of t){let r=V(o.path);if(!r){this.handleWarning(s,{code:"invalid-path",message:`Invalid skill file path: ${o.path}`,path:o.path});continue}if(i.has(r)){this.handleWarning(s,{code:"duplicate-path",message:`Duplicate skill file path: ${r}`,path:r});continue}i.add(r),n.push({...o,path:r})}return n.sort((o,r)=>o.path.localeCompare(r.path))}handleWarning(t,s){if(this.strict)throw new Error(s.path?`${s.path}: ${s.message}`:s.message);t.push(s)}},Je=e=>{if(!e.startsWith("---"))return{frontmatter:{},body:e};let t=e.indexOf(`
|
|
6
|
+
---`,3);if(t===-1)return{frontmatter:{},body:e};let s=e.slice(3,t).trim(),n=e.slice(t+4);return{frontmatter:Ye(s),body:n}},Ye=e=>{let t=(0,Re.parse)(e);return Ae(t)??{}},ge=e=>typeof e=="string"?e:void 0,Ae=e=>e&&typeof e=="object"&&!Array.isArray(e)?e:void 0,Qe=e=>{let t=e.split("/").at(-1)||e,s=Q(t);return s?t.slice(0,-s.length):t},Xe=e=>Qe(e);var ie=class{constructor(t={}){this.skills=new Map;this.selectedSkillNames=new Set;for(let s of t.skills??[])this.set(s);this.select(t.selectedSkillNames??[])}set(t){return this.skills.set(t.name,t),t}remove(t){let s=this.get(t);return this.skills.delete(t),this.selectedSkillNames.delete(t),s}clear(){this.skills.clear(),this.selectedSkillNames.clear()}get(t){return this.skills.get(t)}has(t){return this.skills.has(t)}list(){return Array.from(this.skills.values())}select(t){for(let s of Array.isArray(t)?t:[t]){if(!this.skills.has(s))throw new Error(`Skill "${s}" does not exist.`);this.selectedSkillNames.add(s)}}unselect(t){for(let s of Array.isArray(t)?t:[t])this.selectedSkillNames.delete(s)}getSelectedSkillNames(){return Array.from(this.selectedSkillNames)}getSelectedSkills(){return this.getSelectedSkillNames().flatMap(t=>{let s=this.skills.get(t);return s?[s]:[]})}import(t,s={}){let n=new J(s).load(t);return this.set(n.skill),n}};0&&(module.exports={SkillLoader,SkillManager,combineDeltaData,compileSkillInstructions,createMessageEngine,createNativeMessageAdapter,createSkillRuntimeTools,createVueMessageAdapter,getExtension,isTextSkillFilePath,lengthPlugin,loadSkillFilesFromDirectoryHandle,loadSkillFilesFromFileList,normalizeSkillPath,normalizeToAsyncGenerator,skillPlugin,thinkingPlugin,toolPlugin});
|
package/dist/core.mjs
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import{a as
|
|
1
|
+
import{a as g,b as N,c as E,d as F,e as w,f as v,g as O,h as x,i as M,j as T,k as $}from"./chunk-6JEZBNBO.mjs";import{a as p,b as d,c as f}from"./chunk-ZO2ZONVX.mjs";var I=()=>{let i=!1,e,t=r=>{if(i)throw new Error("Message state adapter is already initialized");e={requestState:r.requestState,processingState:r.processingState,messages:[...r.messages]},i=!0},s=()=>{if(!i)throw new Error("Message state adapter is not initialized");return{requestState:e.requestState,processingState:e.processingState,messages:[...e.messages],isProcessing:e.requestState==="processing"}},o=g(s);return{initialize:t,getState:s,createMessage(r){return r},mutate:(r,a)=>{if(!i)throw new Error("Message state adapter is not initialized");let k=!1;a(e,()=>{k=!0}),k||o.notify(r)},subscribe:o.subscribe}};var b=async i=>{let e=Array.from({length:i.length},(t,s)=>i[s]).filter(t=>!!t);return Promise.all(e.map(t=>{let s=t.webkitRelativePath||t.name;return h(t,L(s))}))},R=async i=>{let e=[],t=async(s,o="")=>{for await(let[l,r]of s.entries()){let a=o?`${o}/${l}`:l;if(r.kind==="directory"){await t(r,a);continue}e.push(await h(await r.getFile(),a))}};return await t(i),e.sort((s,o)=>s.path.localeCompare(o.path))},h=async(i,e)=>{let t=p(e);if(!t)throw new Error(`Invalid skill file path: ${e}`);return d(t)?{path:t,kind:"text",content:await i.text(),mimeType:i.type,size:i.size,lastModified:i.lastModified}:{path:t,kind:"binary",content:await i.arrayBuffer(),mimeType:i.type,size:i.size,lastModified:i.lastModified}},L=i=>{let e=i.split("\\").join("/"),t=e.split("/").filter(Boolean);return t.length<=1?e:t.slice(1).join("/")};import{parse as B}from"yaml";var m=class{constructor(e={}){this.entryFile=e.entryFile??"SKILL.md",this.strict=e.strict??!1}load(e){let t=[],s=this.normalizeFiles(e,t),o=s.find(n=>n.path===this.entryFile);if(!o)throw new Error(`Skill entry file "${this.entryFile}" is missing.`);if(o.kind!=="text")throw new Error(`Skill entry file "${this.entryFile}" must be a text file.`);let{frontmatter:l,body:r}=z(o.content),a=r.trim();if(!a)throw new Error(`Skill entry file "${this.entryFile}" must contain instructions.`);let k=y(l.metadata),c=[];for(let n of s)if(n.path!==this.entryFile){if(n.kind==="binary"){c.push({...n,id:n.path});continue}if(!d(n.path)){t.push({code:"unsupported-text-file-ignored",message:"Only markdown, text, and json files are converted to text skill files.",path:n.path});continue}c.push({...n,id:n.path})}return{skill:{name:S(l.name)||P(this.entryFile),description:S(l.description)||"",instructions:a,files:c.length?c:void 0,metadata:{...k,homepage:S(l.homepage),frontmatter:l}},warnings:t}}normalizeFiles(e,t){let s=[],o=new Set;for(let l of e){let r=p(l.path);if(!r){this.handleWarning(t,{code:"invalid-path",message:`Invalid skill file path: ${l.path}`,path:l.path});continue}if(o.has(r)){this.handleWarning(t,{code:"duplicate-path",message:`Duplicate skill file path: ${r}`,path:r});continue}o.add(r),s.push({...l,path:r})}return s.sort((l,r)=>l.path.localeCompare(r.path))}handleWarning(e,t){if(this.strict)throw new Error(t.path?`${t.path}: ${t.message}`:t.message);e.push(t)}},z=i=>{if(!i.startsWith("---"))return{frontmatter:{},body:i};let e=i.indexOf(`
|
|
2
|
+
---`,3);if(e===-1)return{frontmatter:{},body:i};let t=i.slice(3,e).trim(),s=i.slice(e+4);return{frontmatter:D(t),body:s}},D=i=>{let e=B(i);return y(e)??{}},S=i=>typeof i=="string"?i:void 0,y=i=>i&&typeof i=="object"&&!Array.isArray(i)?i:void 0,A=i=>{let e=i.split("/").at(-1)||i,t=f(e);return t?e.slice(0,-t.length):e},P=i=>A(i);var u=class{constructor(e={}){this.skills=new Map;this.selectedSkillNames=new Set;for(let t of e.skills??[])this.set(t);this.select(e.selectedSkillNames??[])}set(e){return this.skills.set(e.name,e),e}remove(e){let t=this.get(e);return this.skills.delete(e),this.selectedSkillNames.delete(e),t}clear(){this.skills.clear(),this.selectedSkillNames.clear()}get(e){return this.skills.get(e)}has(e){return this.skills.has(e)}list(){return Array.from(this.skills.values())}select(e){for(let t of Array.isArray(e)?e:[e]){if(!this.skills.has(t))throw new Error(`Skill "${t}" does not exist.`);this.selectedSkillNames.add(t)}}unselect(e){for(let t of Array.isArray(e)?e:[e])this.selectedSkillNames.delete(t)}getSelectedSkillNames(){return Array.from(this.selectedSkillNames)}getSelectedSkills(){return this.getSelectedSkillNames().flatMap(e=>{let t=this.skills.get(e);return t?[t]:[]})}import(e,t={}){let s=new m(t).load(e);return this.set(s.skill),s}};export{m as SkillLoader,u as SkillManager,M as combineDeltaData,w as compileSkillInstructions,$ as createMessageEngine,I as createNativeMessageAdapter,F as createSkillRuntimeTools,N as createVueMessageAdapter,f as getExtension,d as isTextSkillFilePath,E as lengthPlugin,R as loadSkillFilesFromDirectoryHandle,b as loadSkillFilesFromFileList,p as normalizeSkillPath,x as normalizeToAsyncGenerator,v as skillPlugin,O as thinkingPlugin,T as toolPlugin};
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
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-4pC5SvPk.mjs';
|
|
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-4pC5SvPk.mjs';
|
|
3
3
|
import { Ref, ComputedRef } from 'vue';
|
|
4
|
+
import { S as SkillDefinition } from './types-ChCZ8jKB.mjs';
|
|
5
|
+
import 'openai/resources';
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* AI客户端类
|
|
@@ -460,10 +462,38 @@ declare const lengthPlugin: (options?: UseMessagePlugin & {
|
|
|
460
462
|
continueContent?: string;
|
|
461
463
|
}) => UseMessagePlugin;
|
|
462
464
|
|
|
465
|
+
type VueSkillSource = SkillDefinition[] | undefined;
|
|
466
|
+
type VueSkillSourceRef = VueSkillSource | Ref<VueSkillSource> | ComputedRef<VueSkillSource>;
|
|
467
|
+
type UseMessageSkillPluginOptions = UseMessagePlugin & {
|
|
468
|
+
/**
|
|
469
|
+
* 当前请求要使用的 skills。支持普通数组、ref 或 computed。
|
|
470
|
+
*/
|
|
471
|
+
skills?: VueSkillSourceRef;
|
|
472
|
+
/**
|
|
473
|
+
* 动态返回当前请求要使用的 skills。
|
|
474
|
+
*/
|
|
475
|
+
getSkills?: (context: BasePluginContext) => MaybePromise<VueSkillSourceRef>;
|
|
476
|
+
/**
|
|
477
|
+
* 执行模型为某个 skill 规划的后端命令。
|
|
478
|
+
*
|
|
479
|
+
* @experimental 该 API 仍在设计和验证中,命令协议、返回结构和安全边界后续可能调整。
|
|
480
|
+
*/
|
|
481
|
+
executeSkillCommand?: (request: SkillCommandRequest, context: BasePluginContext) => MaybePromise<SkillCommandResult>;
|
|
482
|
+
/**
|
|
483
|
+
* skills 解析并转换为插件状态后触发。
|
|
484
|
+
*/
|
|
485
|
+
onSkillsResolved?: (state: SkillPluginState, context: BasePluginContext) => MaybePromise<void>;
|
|
486
|
+
};
|
|
487
|
+
declare const skillPlugin: (options: UseMessageSkillPluginOptions) => UseMessagePlugin;
|
|
488
|
+
|
|
463
489
|
declare const thinkingPlugin: (options?: UseMessagePlugin) => UseMessagePlugin;
|
|
464
490
|
|
|
465
491
|
interface UseMessageToolActionContext extends BasePluginContext {
|
|
466
492
|
assistantMessage: ChatMessage;
|
|
493
|
+
/**
|
|
494
|
+
* 当前工具的来源。
|
|
495
|
+
*/
|
|
496
|
+
toolSource?: ToolSource;
|
|
467
497
|
/**
|
|
468
498
|
* @deprecated use `assistantMessage` instead
|
|
469
499
|
*/
|
|
@@ -474,6 +504,10 @@ interface UseMessageCallToolContext extends UseMessageToolActionContext {
|
|
|
474
504
|
}
|
|
475
505
|
interface UseMessageToolCallContext extends BasePluginContext {
|
|
476
506
|
assistantMessage: ChatMessage;
|
|
507
|
+
/**
|
|
508
|
+
* 当前工具的来源。
|
|
509
|
+
*/
|
|
510
|
+
toolSource: ToolSource;
|
|
477
511
|
/**
|
|
478
512
|
* @deprecated use `assistantMessage` instead
|
|
479
513
|
*/
|
|
@@ -484,7 +518,7 @@ declare const toolPlugin: (options: UseMessagePlugin & {
|
|
|
484
518
|
/**
|
|
485
519
|
* 获取工具列表的函数。
|
|
486
520
|
*/
|
|
487
|
-
getTools: () => Promise<
|
|
521
|
+
getTools: (context: BasePluginContext) => Promise<ToolProviderItem[]>;
|
|
488
522
|
/**
|
|
489
523
|
* 在处理包含 tool_calls 的响应前调用。
|
|
490
524
|
*/
|
|
@@ -530,4 +564,4 @@ declare const toolPlugin: (options: UseMessagePlugin & {
|
|
|
530
564
|
|
|
531
565
|
declare const useMessage: (options: UseMessageOptions) => UseMessageReturn;
|
|
532
566
|
|
|
533
|
-
export { AIClient, AIModelConfig, BaseModelProvider, type BasePluginContext, type ChatCompletion, ChatCompletionRequest, ChatCompletionResponse, ChatMessage, type Choice, type CompletionChoice, type Conversation, type ConversationInfo, type ConversationStorageStrategy, type DeltaChoice, type IndexedDBConfig, IndexedDBStrategy, type LocalStorageConfig, LocalStorageStrategy, MaybePromise, type MessageRequestBody, OpenAIProvider, type RequestProcessingState, type RequestState, type ResponseProvider, StreamHandler, type Tool, ToolCall, type Usage, type UseConversationOptions, type UseConversationReturn, type UseMessageCallToolContext, type UseMessageOptions, type UseMessagePlugin, type UseMessageReturn, type UseMessageToolActionContext, type UseMessageToolCallContext, extractTextFromResponse, formatMessages, handleSSEStream, indexedDBStorageStrategyFactory, lengthPlugin, localStorageStrategyFactory, sseStreamToGenerator, thinkingPlugin, toolPlugin, useConversation, useMessage };
|
|
567
|
+
export { AIClient, AIModelConfig, BaseModelProvider, type BasePluginContext, type ChatCompletion, ChatCompletionRequest, ChatCompletionResponse, ChatMessage, type Choice, type CompletionChoice, type Conversation, type ConversationInfo, type ConversationStorageStrategy, type DeltaChoice, type IndexedDBConfig, IndexedDBStrategy, type LocalStorageConfig, LocalStorageStrategy, MaybePromise, type MessageRequestBody, OpenAIProvider, type RequestProcessingState, type RequestState, type ResponseProvider, StreamHandler, type Tool, ToolCall, type Usage, type UseConversationOptions, type UseConversationReturn, type UseMessageCallToolContext, type UseMessageOptions, type UseMessagePlugin, type UseMessageReturn, type UseMessageSkillPluginOptions, type UseMessageToolActionContext, type UseMessageToolCallContext, type VueSkillSource, type VueSkillSourceRef, extractTextFromResponse, formatMessages, handleSSEStream, indexedDBStorageStrategyFactory, lengthPlugin, localStorageStrategyFactory, skillPlugin, sseStreamToGenerator, thinkingPlugin, toolPlugin, useConversation, useMessage };
|