@hao-gd/page-agent-ui 1.10.1
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/LICENSE +22 -0
- package/dist/lib/index.d.ts +801 -0
- package/dist/lib/page-agent-ui.js +6689 -0
- package/dist/lib/page-agent-ui.js.map +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,801 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derived active LLM configuration from the currently selected provider + model.
|
|
3
|
+
*/
|
|
4
|
+
export declare interface ActiveLLMConfig {
|
|
5
|
+
baseURL: string;
|
|
6
|
+
model: string;
|
|
7
|
+
apiKey?: string;
|
|
8
|
+
apiFormat: ApiFormat;
|
|
9
|
+
temperature: number;
|
|
10
|
+
maxSteps: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Supported API protocol formats.
|
|
15
|
+
* - `openai`: OpenAI Chat Completions API (/chat/completions)
|
|
16
|
+
* - `anthropic`: Anthropic Messages API (/messages)
|
|
17
|
+
*/
|
|
18
|
+
export declare type ApiFormat = 'openai' | 'anthropic';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A single conversation representing one agent task session.
|
|
22
|
+
*/
|
|
23
|
+
export declare interface Conversation {
|
|
24
|
+
/** Unique identifier */
|
|
25
|
+
id: string;
|
|
26
|
+
/** Display title — derived from the first task or auto-generated */
|
|
27
|
+
title: string;
|
|
28
|
+
/** Unix timestamp of creation */
|
|
29
|
+
createdAt: number;
|
|
30
|
+
/** Unix timestamp of last modification */
|
|
31
|
+
updatedAt: number;
|
|
32
|
+
/** The original task description */
|
|
33
|
+
task: string;
|
|
34
|
+
/** Full history of agent events */
|
|
35
|
+
history: ConversationHistoryEvent[];
|
|
36
|
+
/** Result of the most recent run, or null if never completed */
|
|
37
|
+
lastResult: {
|
|
38
|
+
success: boolean;
|
|
39
|
+
data: string;
|
|
40
|
+
history?: ConversationHistoryEvent[];
|
|
41
|
+
} | null;
|
|
42
|
+
/** Agent status at save time */
|
|
43
|
+
status: 'idle' | 'running' | 'completed' | 'error' | 'stopped';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export declare interface ConversationErrorEvent {
|
|
47
|
+
type: 'error';
|
|
48
|
+
message: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Serializable history event stored in a conversation.
|
|
53
|
+
* Mirrors the agent's HistoricalEvent shape but is self-contained
|
|
54
|
+
* so the UI package stays independent of @hao-gd/page-agent-core.
|
|
55
|
+
*/
|
|
56
|
+
export declare type ConversationHistoryEvent = ConversationStepEvent | ConversationObservationEvent | ConversationUserTakeoverEvent | ConversationRetryEvent | ConversationErrorEvent;
|
|
57
|
+
|
|
58
|
+
export declare interface ConversationObservationEvent {
|
|
59
|
+
type: 'observation';
|
|
60
|
+
content: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export declare interface ConversationRetryEvent {
|
|
64
|
+
type: 'retry';
|
|
65
|
+
message: string;
|
|
66
|
+
attempt: number;
|
|
67
|
+
maxAttempts: number;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export declare interface ConversationStepEvent {
|
|
71
|
+
type: 'step';
|
|
72
|
+
stepIndex: number;
|
|
73
|
+
reflection: {
|
|
74
|
+
evaluation_previous_goal?: string;
|
|
75
|
+
memory?: string;
|
|
76
|
+
next_goal?: string;
|
|
77
|
+
};
|
|
78
|
+
action: {
|
|
79
|
+
name: string;
|
|
80
|
+
input: unknown;
|
|
81
|
+
output: string;
|
|
82
|
+
};
|
|
83
|
+
usage?: {
|
|
84
|
+
promptTokens: number;
|
|
85
|
+
completionTokens: number;
|
|
86
|
+
totalTokens: number;
|
|
87
|
+
cachedTokens?: number;
|
|
88
|
+
reasoningTokens?: number;
|
|
89
|
+
};
|
|
90
|
+
rawResponse?: unknown;
|
|
91
|
+
rawRequest?: unknown;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Static helper for persisting and retrieving conversations via IndexedDB.
|
|
96
|
+
*
|
|
97
|
+
* Usage:
|
|
98
|
+
* await ConversationStorage.save(conv)
|
|
99
|
+
* const all = await ConversationStorage.list()
|
|
100
|
+
* const active = await ConversationStorage.getActiveId()
|
|
101
|
+
*/
|
|
102
|
+
export declare const ConversationStorage: {
|
|
103
|
+
/** List all conversations ordered by updatedAt descending (newest first). */
|
|
104
|
+
list(): Promise<Conversation[]>;
|
|
105
|
+
/** Get a single conversation by id. */
|
|
106
|
+
get(id: string): Promise<Conversation | undefined>;
|
|
107
|
+
/** Insert or update a conversation. */
|
|
108
|
+
save(conv: Conversation): Promise<void>;
|
|
109
|
+
/** Delete a conversation by id. */
|
|
110
|
+
delete(id: string): Promise<void>;
|
|
111
|
+
/** Get the currently active conversation id from localStorage. */
|
|
112
|
+
getActiveId(): string | null;
|
|
113
|
+
/** Set the currently active conversation id in localStorage. */
|
|
114
|
+
setActiveId(id: string): void;
|
|
115
|
+
/** Clear the active conversation marker. */
|
|
116
|
+
clearActiveId(): void;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export declare interface ConversationUserTakeoverEvent {
|
|
120
|
+
type: 'user_takeover';
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
declare type DeepStringify<T> = {
|
|
124
|
+
[K in keyof T]: T[K] extends string ? string : T[K] extends object ? DeepStringify<T[K]> : T[K];
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Derive a title from a task string: first line, truncated.
|
|
129
|
+
*/
|
|
130
|
+
export declare function deriveTitle(task: string): string;
|
|
131
|
+
|
|
132
|
+
declare const enUS: {
|
|
133
|
+
readonly ui: {
|
|
134
|
+
readonly panel: {
|
|
135
|
+
readonly ready: "Ready";
|
|
136
|
+
readonly thinking: "Thinking...";
|
|
137
|
+
readonly taskInput: "Enter new task, describe steps in detail, press Ctrl/Cmd+Enter to submit";
|
|
138
|
+
readonly taskInputWindows: "Enter new task, describe steps in detail, press Enter to submit, Shift+Enter for new line";
|
|
139
|
+
readonly userAnswerPrompt: "Please answer the question above, press Ctrl/Cmd+Enter to submit";
|
|
140
|
+
readonly userAnswerPromptWindows: "Please answer the question above, press Enter to submit, Shift+Enter for new line";
|
|
141
|
+
readonly waitingPlaceholder: "Waiting for task to start...";
|
|
142
|
+
readonly stop: "Stop";
|
|
143
|
+
readonly close: "Close";
|
|
144
|
+
readonly expand: "Expand history";
|
|
145
|
+
readonly history: "History";
|
|
146
|
+
readonly step: "Step {{number}}";
|
|
147
|
+
readonly newConversation: "New Conversation";
|
|
148
|
+
readonly conversations: "Conversations";
|
|
149
|
+
readonly noConversations: "No conversations";
|
|
150
|
+
readonly conversationDefaultTitle: "New Conversation";
|
|
151
|
+
readonly deleteConversation: "Delete conversation";
|
|
152
|
+
readonly timeJustNow: "Just now";
|
|
153
|
+
readonly timeMinutesAgo: "{{n}}m ago";
|
|
154
|
+
readonly timeHoursAgo: "{{n}}h ago";
|
|
155
|
+
readonly timeDaysAgo: "{{n}}d ago";
|
|
156
|
+
};
|
|
157
|
+
readonly settings: {
|
|
158
|
+
readonly title: "Settings";
|
|
159
|
+
readonly modelTab: "Model Config";
|
|
160
|
+
readonly providersTab: "Providers";
|
|
161
|
+
readonly generalTab: "General";
|
|
162
|
+
readonly baseURL: "Base URL";
|
|
163
|
+
readonly baseURLHint: "API endpoint (without /chat/completions or /messages)";
|
|
164
|
+
readonly apiFormat: "API Format";
|
|
165
|
+
readonly apiFormatHint: "Select the API protocol format for this provider";
|
|
166
|
+
readonly apiFormatOpenAI: "OpenAI Chat Completions";
|
|
167
|
+
readonly apiFormatAnthropic: "Anthropic Messages";
|
|
168
|
+
readonly model: "Model";
|
|
169
|
+
readonly modelHint: "Model name (e.g. gpt-4o, claude-opus-4-8)";
|
|
170
|
+
readonly apiKey: "API Key";
|
|
171
|
+
readonly apiKeyHint: "Your API key (stored locally in browser)";
|
|
172
|
+
readonly temperature: "Temperature";
|
|
173
|
+
readonly maxSteps: "Max Steps";
|
|
174
|
+
readonly maxStepsHint: "Maximum agent loop iterations (5-200)";
|
|
175
|
+
readonly save: "Save";
|
|
176
|
+
readonly cancel: "Cancel";
|
|
177
|
+
readonly saved: "Settings saved. Restart agent for changes to take effect.";
|
|
178
|
+
readonly activeProvider: "Active Provider";
|
|
179
|
+
readonly enableProvider: "Enable";
|
|
180
|
+
readonly selectedProvider: "Enabled";
|
|
181
|
+
readonly providerName: "Provider Name";
|
|
182
|
+
readonly providerNameHint: "Display name (e.g. OpenAI, Anthropic)";
|
|
183
|
+
readonly models: "Models";
|
|
184
|
+
readonly addModel: "+ Add Model";
|
|
185
|
+
readonly addProvider: "+ Add Provider";
|
|
186
|
+
readonly currentModel: "Current";
|
|
187
|
+
readonly modelNameHint: "Model ID (e.g. gpt-4o)";
|
|
188
|
+
readonly useThisModel: "Use This";
|
|
189
|
+
readonly enabled: "Enabled";
|
|
190
|
+
readonly noProviders: "No providers configured. Add one to get started.";
|
|
191
|
+
readonly deleteProvider: "Delete Provider";
|
|
192
|
+
readonly enabledProviderLocked: "Enabled provider cannot be deleted";
|
|
193
|
+
readonly deleteModel: "Delete";
|
|
194
|
+
readonly confirmDeleteProvider: "Delete this provider and all its models?";
|
|
195
|
+
};
|
|
196
|
+
readonly modelSwitcher: {
|
|
197
|
+
readonly configureProviders: "Configure Providers...";
|
|
198
|
+
readonly noModels: "No models configured";
|
|
199
|
+
readonly searchPlaceholder: "Search models...";
|
|
200
|
+
};
|
|
201
|
+
readonly tools: {
|
|
202
|
+
readonly clicking: "Clicking element [{{index}}]...";
|
|
203
|
+
readonly inputting: "Inputting text to element [{{index}}]...";
|
|
204
|
+
readonly selecting: "Selecting option \"{{text}}\"...";
|
|
205
|
+
readonly scrolling: "Scrolling page...";
|
|
206
|
+
readonly waiting: "Waiting {{seconds}} seconds...";
|
|
207
|
+
readonly askingUser: "Asking user...";
|
|
208
|
+
readonly done: "Task done";
|
|
209
|
+
readonly executing: "Executing {{toolName}}...";
|
|
210
|
+
};
|
|
211
|
+
readonly skills: {
|
|
212
|
+
readonly tab: "Skills";
|
|
213
|
+
readonly create: "Create Skill";
|
|
214
|
+
readonly edit: "Edit Skill";
|
|
215
|
+
readonly importJSON: "Import Skill";
|
|
216
|
+
readonly exportJSON: "Export JSON";
|
|
217
|
+
readonly delete: "Delete";
|
|
218
|
+
readonly confirmDelete: "Are you sure you want to delete this skill?";
|
|
219
|
+
readonly empty: "No skills configured. Create one or import from JSON.";
|
|
220
|
+
readonly builtIn: "Built-in Skills";
|
|
221
|
+
readonly pasteJSON: "Paste skill JSON here:";
|
|
222
|
+
readonly loadError: "Failed to load skills.";
|
|
223
|
+
readonly fieldId: "Skill ID";
|
|
224
|
+
readonly fieldName: "Name";
|
|
225
|
+
readonly fieldVersion: "Version";
|
|
226
|
+
readonly fieldDescription: "Description";
|
|
227
|
+
readonly fieldPromptFragment: "System Prompt Fragment";
|
|
228
|
+
readonly fieldPromptPlaceholder: "Tell the LLM when and how to use this skill's tools...";
|
|
229
|
+
readonly fieldTools: "Tools (JSON array)";
|
|
230
|
+
readonly fieldToolsHint: "Define tools as JSON. executeCode should be the source code of an async function.";
|
|
231
|
+
readonly fieldRequired: "ID and Name are required";
|
|
232
|
+
readonly saveFailed: "Failed to save skill: ";
|
|
233
|
+
readonly importFailed: "Failed to import skill: ";
|
|
234
|
+
readonly importAsText: "Create skill from pasted text";
|
|
235
|
+
readonly importHint: "Paste JSON for a full skill definition, or paste markdown/text to auto-create a knowledge skill.";
|
|
236
|
+
};
|
|
237
|
+
};
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
/** Generate a short unique id for a conversation. */
|
|
241
|
+
export declare function generateConversationId(): string;
|
|
242
|
+
|
|
243
|
+
/** Generate a short unique id for a custom skill. */
|
|
244
|
+
export declare function generateSkillId(): string;
|
|
245
|
+
|
|
246
|
+
export declare class I18n {
|
|
247
|
+
private language;
|
|
248
|
+
private translations;
|
|
249
|
+
constructor(language?: SupportedLanguage);
|
|
250
|
+
t(key: TranslationKey, params?: TranslationParams): string;
|
|
251
|
+
private getNestedValue;
|
|
252
|
+
private interpolate;
|
|
253
|
+
getLanguage(): SupportedLanguage;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
declare const locales: {
|
|
257
|
+
readonly 'en-US': {
|
|
258
|
+
readonly ui: {
|
|
259
|
+
readonly panel: {
|
|
260
|
+
readonly ready: "Ready";
|
|
261
|
+
readonly thinking: "Thinking...";
|
|
262
|
+
readonly taskInput: "Enter new task, describe steps in detail, press Ctrl/Cmd+Enter to submit";
|
|
263
|
+
readonly taskInputWindows: "Enter new task, describe steps in detail, press Enter to submit, Shift+Enter for new line";
|
|
264
|
+
readonly userAnswerPrompt: "Please answer the question above, press Ctrl/Cmd+Enter to submit";
|
|
265
|
+
readonly userAnswerPromptWindows: "Please answer the question above, press Enter to submit, Shift+Enter for new line";
|
|
266
|
+
readonly waitingPlaceholder: "Waiting for task to start...";
|
|
267
|
+
readonly stop: "Stop";
|
|
268
|
+
readonly close: "Close";
|
|
269
|
+
readonly expand: "Expand history";
|
|
270
|
+
readonly history: "History";
|
|
271
|
+
readonly step: "Step {{number}}";
|
|
272
|
+
readonly newConversation: "New Conversation";
|
|
273
|
+
readonly conversations: "Conversations";
|
|
274
|
+
readonly noConversations: "No conversations";
|
|
275
|
+
readonly conversationDefaultTitle: "New Conversation";
|
|
276
|
+
readonly deleteConversation: "Delete conversation";
|
|
277
|
+
readonly timeJustNow: "Just now";
|
|
278
|
+
readonly timeMinutesAgo: "{{n}}m ago";
|
|
279
|
+
readonly timeHoursAgo: "{{n}}h ago";
|
|
280
|
+
readonly timeDaysAgo: "{{n}}d ago";
|
|
281
|
+
};
|
|
282
|
+
readonly settings: {
|
|
283
|
+
readonly title: "Settings";
|
|
284
|
+
readonly modelTab: "Model Config";
|
|
285
|
+
readonly providersTab: "Providers";
|
|
286
|
+
readonly generalTab: "General";
|
|
287
|
+
readonly baseURL: "Base URL";
|
|
288
|
+
readonly baseURLHint: "API endpoint (without /chat/completions or /messages)";
|
|
289
|
+
readonly apiFormat: "API Format";
|
|
290
|
+
readonly apiFormatHint: "Select the API protocol format for this provider";
|
|
291
|
+
readonly apiFormatOpenAI: "OpenAI Chat Completions";
|
|
292
|
+
readonly apiFormatAnthropic: "Anthropic Messages";
|
|
293
|
+
readonly model: "Model";
|
|
294
|
+
readonly modelHint: "Model name (e.g. gpt-4o, claude-opus-4-8)";
|
|
295
|
+
readonly apiKey: "API Key";
|
|
296
|
+
readonly apiKeyHint: "Your API key (stored locally in browser)";
|
|
297
|
+
readonly temperature: "Temperature";
|
|
298
|
+
readonly maxSteps: "Max Steps";
|
|
299
|
+
readonly maxStepsHint: "Maximum agent loop iterations (5-200)";
|
|
300
|
+
readonly save: "Save";
|
|
301
|
+
readonly cancel: "Cancel";
|
|
302
|
+
readonly saved: "Settings saved. Restart agent for changes to take effect.";
|
|
303
|
+
readonly activeProvider: "Active Provider";
|
|
304
|
+
readonly enableProvider: "Enable";
|
|
305
|
+
readonly selectedProvider: "Enabled";
|
|
306
|
+
readonly providerName: "Provider Name";
|
|
307
|
+
readonly providerNameHint: "Display name (e.g. OpenAI, Anthropic)";
|
|
308
|
+
readonly models: "Models";
|
|
309
|
+
readonly addModel: "+ Add Model";
|
|
310
|
+
readonly addProvider: "+ Add Provider";
|
|
311
|
+
readonly currentModel: "Current";
|
|
312
|
+
readonly modelNameHint: "Model ID (e.g. gpt-4o)";
|
|
313
|
+
readonly useThisModel: "Use This";
|
|
314
|
+
readonly enabled: "Enabled";
|
|
315
|
+
readonly noProviders: "No providers configured. Add one to get started.";
|
|
316
|
+
readonly deleteProvider: "Delete Provider";
|
|
317
|
+
readonly enabledProviderLocked: "Enabled provider cannot be deleted";
|
|
318
|
+
readonly deleteModel: "Delete";
|
|
319
|
+
readonly confirmDeleteProvider: "Delete this provider and all its models?";
|
|
320
|
+
};
|
|
321
|
+
readonly modelSwitcher: {
|
|
322
|
+
readonly configureProviders: "Configure Providers...";
|
|
323
|
+
readonly noModels: "No models configured";
|
|
324
|
+
readonly searchPlaceholder: "Search models...";
|
|
325
|
+
};
|
|
326
|
+
readonly tools: {
|
|
327
|
+
readonly clicking: "Clicking element [{{index}}]...";
|
|
328
|
+
readonly inputting: "Inputting text to element [{{index}}]...";
|
|
329
|
+
readonly selecting: "Selecting option \"{{text}}\"...";
|
|
330
|
+
readonly scrolling: "Scrolling page...";
|
|
331
|
+
readonly waiting: "Waiting {{seconds}} seconds...";
|
|
332
|
+
readonly askingUser: "Asking user...";
|
|
333
|
+
readonly done: "Task done";
|
|
334
|
+
readonly executing: "Executing {{toolName}}...";
|
|
335
|
+
};
|
|
336
|
+
readonly skills: {
|
|
337
|
+
readonly tab: "Skills";
|
|
338
|
+
readonly create: "Create Skill";
|
|
339
|
+
readonly edit: "Edit Skill";
|
|
340
|
+
readonly importJSON: "Import Skill";
|
|
341
|
+
readonly exportJSON: "Export JSON";
|
|
342
|
+
readonly delete: "Delete";
|
|
343
|
+
readonly confirmDelete: "Are you sure you want to delete this skill?";
|
|
344
|
+
readonly empty: "No skills configured. Create one or import from JSON.";
|
|
345
|
+
readonly builtIn: "Built-in Skills";
|
|
346
|
+
readonly pasteJSON: "Paste skill JSON here:";
|
|
347
|
+
readonly loadError: "Failed to load skills.";
|
|
348
|
+
readonly fieldId: "Skill ID";
|
|
349
|
+
readonly fieldName: "Name";
|
|
350
|
+
readonly fieldVersion: "Version";
|
|
351
|
+
readonly fieldDescription: "Description";
|
|
352
|
+
readonly fieldPromptFragment: "System Prompt Fragment";
|
|
353
|
+
readonly fieldPromptPlaceholder: "Tell the LLM when and how to use this skill's tools...";
|
|
354
|
+
readonly fieldTools: "Tools (JSON array)";
|
|
355
|
+
readonly fieldToolsHint: "Define tools as JSON. executeCode should be the source code of an async function.";
|
|
356
|
+
readonly fieldRequired: "ID and Name are required";
|
|
357
|
+
readonly saveFailed: "Failed to save skill: ";
|
|
358
|
+
readonly importFailed: "Failed to import skill: ";
|
|
359
|
+
readonly importAsText: "Create skill from pasted text";
|
|
360
|
+
readonly importHint: "Paste JSON for a full skill definition, or paste markdown/text to auto-create a knowledge skill.";
|
|
361
|
+
};
|
|
362
|
+
};
|
|
363
|
+
};
|
|
364
|
+
readonly 'zh-CN': {
|
|
365
|
+
readonly ui: {
|
|
366
|
+
readonly panel: {
|
|
367
|
+
readonly ready: "准备就绪";
|
|
368
|
+
readonly thinking: "正在思考...";
|
|
369
|
+
readonly taskInput: "输入新任务,详细描述步骤,按 Ctrl/Cmd+Enter 提交";
|
|
370
|
+
readonly taskInputWindows: "输入新任务,详细描述步骤,按 Enter 提交,Shift+Enter 换行";
|
|
371
|
+
readonly userAnswerPrompt: "请回答上面问题,按 Ctrl/Cmd+Enter 提交";
|
|
372
|
+
readonly userAnswerPromptWindows: "请回答上面问题,按 Enter 提交,Shift+Enter 换行";
|
|
373
|
+
readonly waitingPlaceholder: "等待任务开始...";
|
|
374
|
+
readonly stop: "终止";
|
|
375
|
+
readonly close: "关闭";
|
|
376
|
+
readonly expand: "展开历史";
|
|
377
|
+
readonly history: "历史记录";
|
|
378
|
+
readonly step: "步骤 {{number}}";
|
|
379
|
+
readonly newConversation: "新建会话";
|
|
380
|
+
readonly conversations: "会话列表";
|
|
381
|
+
readonly noConversations: "暂无会话";
|
|
382
|
+
readonly conversationDefaultTitle: "新的会话";
|
|
383
|
+
readonly deleteConversation: "删除会话";
|
|
384
|
+
readonly timeJustNow: "刚刚";
|
|
385
|
+
readonly timeMinutesAgo: "{{n}}分钟前";
|
|
386
|
+
readonly timeHoursAgo: "{{n}}小时前";
|
|
387
|
+
readonly timeDaysAgo: "{{n}}天前";
|
|
388
|
+
};
|
|
389
|
+
readonly settings: {
|
|
390
|
+
readonly title: "设置";
|
|
391
|
+
readonly modelTab: "模型配置";
|
|
392
|
+
readonly providersTab: "供应商";
|
|
393
|
+
readonly generalTab: "通用";
|
|
394
|
+
readonly baseURL: "API 地址";
|
|
395
|
+
readonly baseURLHint: "API 端点 (不包含 /chat/completions 或 /messages)";
|
|
396
|
+
readonly apiFormat: "API 格式";
|
|
397
|
+
readonly apiFormatHint: "选择此供应商使用的 API 协议格式";
|
|
398
|
+
readonly apiFormatOpenAI: "OpenAI Chat Completions";
|
|
399
|
+
readonly apiFormatAnthropic: "Anthropic Messages";
|
|
400
|
+
readonly model: "模型";
|
|
401
|
+
readonly modelHint: "模型名称 (例如 gpt-4o, claude-opus-4-8)";
|
|
402
|
+
readonly apiKey: "API 密钥";
|
|
403
|
+
readonly apiKeyHint: "密钥仅存储在浏览器本地";
|
|
404
|
+
readonly temperature: "温度参数";
|
|
405
|
+
readonly maxSteps: "最大步数";
|
|
406
|
+
readonly maxStepsHint: "Agent 循环最大迭代次数 (5-200)";
|
|
407
|
+
readonly save: "保存";
|
|
408
|
+
readonly cancel: "取消";
|
|
409
|
+
readonly saved: "设置已保存。重新启动 Agent 后生效。";
|
|
410
|
+
readonly activeProvider: "当前供应商";
|
|
411
|
+
readonly enableProvider: "启用";
|
|
412
|
+
readonly selectedProvider: "已启用";
|
|
413
|
+
readonly providerName: "供应商名称";
|
|
414
|
+
readonly providerNameHint: "显示名称 (例如 OpenAI, Anthropic)";
|
|
415
|
+
readonly models: "模型列表";
|
|
416
|
+
readonly addModel: "+ 添加模型";
|
|
417
|
+
readonly addProvider: "+ 添加供应商";
|
|
418
|
+
readonly currentModel: "当前使用";
|
|
419
|
+
readonly modelNameHint: "模型标识 (例如 gpt-4o)";
|
|
420
|
+
readonly useThisModel: "设为当前";
|
|
421
|
+
readonly enabled: "已启用";
|
|
422
|
+
readonly noProviders: "尚未配置供应商,请添加一个开始使用。";
|
|
423
|
+
readonly deleteProvider: "删除供应商";
|
|
424
|
+
readonly enabledProviderLocked: "已启用的供应商无法删除";
|
|
425
|
+
readonly deleteModel: "删除";
|
|
426
|
+
readonly confirmDeleteProvider: "确认删除此供应商及其所有模型?";
|
|
427
|
+
};
|
|
428
|
+
readonly modelSwitcher: {
|
|
429
|
+
readonly configureProviders: "配置供应商...";
|
|
430
|
+
readonly noModels: "未配置模型";
|
|
431
|
+
readonly searchPlaceholder: "搜索模型...";
|
|
432
|
+
};
|
|
433
|
+
readonly tools: {
|
|
434
|
+
readonly clicking: "正在点击元素 [{{index}}]...";
|
|
435
|
+
readonly inputting: "正在输入文本到元素 [{{index}}]...";
|
|
436
|
+
readonly selecting: "正在选择选项 \"{{text}}\"...";
|
|
437
|
+
readonly scrolling: "正在滚动页面...";
|
|
438
|
+
readonly waiting: "等待 {{seconds}} 秒...";
|
|
439
|
+
readonly askingUser: "正在询问用户...";
|
|
440
|
+
readonly done: "结束任务";
|
|
441
|
+
readonly executing: "正在执行 {{toolName}}...";
|
|
442
|
+
};
|
|
443
|
+
readonly skills: {
|
|
444
|
+
readonly tab: "技能";
|
|
445
|
+
readonly create: "创建技能";
|
|
446
|
+
readonly edit: "编辑技能";
|
|
447
|
+
readonly importJSON: "导入技能";
|
|
448
|
+
readonly exportJSON: "导出 JSON";
|
|
449
|
+
readonly delete: "删除";
|
|
450
|
+
readonly confirmDelete: "确认删除此技能?";
|
|
451
|
+
readonly empty: "尚未配置技能。请创建或从 JSON 导入。";
|
|
452
|
+
readonly builtIn: "内置技能";
|
|
453
|
+
readonly pasteJSON: "请粘贴 Skill JSON:";
|
|
454
|
+
readonly loadError: "技能加载失败。";
|
|
455
|
+
readonly fieldId: "技能 ID";
|
|
456
|
+
readonly fieldName: "名称";
|
|
457
|
+
readonly fieldVersion: "版本";
|
|
458
|
+
readonly fieldDescription: "描述";
|
|
459
|
+
readonly fieldPromptFragment: "System Prompt 片段";
|
|
460
|
+
readonly fieldPromptPlaceholder: "告诉 LLM 何时以及如何使用此技能的工具...";
|
|
461
|
+
readonly fieldTools: "工具(JSON 数组)";
|
|
462
|
+
readonly fieldToolsHint: "以 JSON 定义工具。executeCode 应为 async 函数的源代码。";
|
|
463
|
+
readonly fieldRequired: "ID 和名称为必填项";
|
|
464
|
+
readonly saveFailed: "保存技能失败:";
|
|
465
|
+
readonly importFailed: "导入技能失败:";
|
|
466
|
+
readonly importAsText: "将粘贴的文本创建为技能";
|
|
467
|
+
readonly importHint: "粘贴 JSON 可导入完整技能定义,粘贴 Markdown/文本可自动创建知识型技能。";
|
|
468
|
+
};
|
|
469
|
+
};
|
|
470
|
+
};
|
|
471
|
+
};
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Per-model configuration within a provider.
|
|
475
|
+
*/
|
|
476
|
+
export declare interface ModelConfig {
|
|
477
|
+
/** Model identifier (e.g. "gpt-4o", "claude-opus-4-8") */
|
|
478
|
+
name: string;
|
|
479
|
+
/** Per-model temperature override. Falls back to global default if unset. */
|
|
480
|
+
temperature?: number;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
declare type NestedKeyOf<ObjectType extends object> = {
|
|
484
|
+
[Key in keyof ObjectType & (string | number)]: ObjectType[Key] extends object ? `${Key}` | `${Key}.${NestedKeyOf<ObjectType[Key]>}` : `${Key}`;
|
|
485
|
+
}[keyof ObjectType & (string | number)];
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Complete settings stored in localStorage.
|
|
489
|
+
*/
|
|
490
|
+
export declare interface PageAgentSettings {
|
|
491
|
+
/** All configured providers */
|
|
492
|
+
providers: ProviderConfig[];
|
|
493
|
+
/** ID of the currently active provider */
|
|
494
|
+
activeProviderId: string;
|
|
495
|
+
/** Name of the currently active model (within the active provider) */
|
|
496
|
+
activeModelName: string;
|
|
497
|
+
/** Global maximum agent loop iterations */
|
|
498
|
+
maxSteps: number;
|
|
499
|
+
/** Global default temperature (overridable per-model) */
|
|
500
|
+
temperature: number;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Agent control panel
|
|
505
|
+
*
|
|
506
|
+
* Architecture:
|
|
507
|
+
* - History list: renders directly from agent.history (historical events)
|
|
508
|
+
* - Header bar: shows activity events (transient state) and agent status
|
|
509
|
+
* - Draggable: header acts as drag handle, position saved to localStorage
|
|
510
|
+
* - Resizable: top-edge resize handle
|
|
511
|
+
*
|
|
512
|
+
* This separation ensures data consistency - history is the single source of truth
|
|
513
|
+
* for what has been done, while activity shows what is happening now.
|
|
514
|
+
*/
|
|
515
|
+
export declare class Panel {
|
|
516
|
+
#private;
|
|
517
|
+
get wrapper(): HTMLElement;
|
|
518
|
+
/**
|
|
519
|
+
* Create a Panel bound to an agent
|
|
520
|
+
* @param agent - Agent instance that implements PanelAgentAdapter
|
|
521
|
+
* @param config - Optional panel configuration
|
|
522
|
+
*/
|
|
523
|
+
constructor(agent: PanelAgentAdapter, config?: PanelConfig);
|
|
524
|
+
show(): void;
|
|
525
|
+
hide(): void;
|
|
526
|
+
reset(): void;
|
|
527
|
+
expand(): void;
|
|
528
|
+
collapse(): void;
|
|
529
|
+
/**
|
|
530
|
+
* Dispose panel and clean up event listeners
|
|
531
|
+
*/
|
|
532
|
+
dispose(): void;
|
|
533
|
+
/**
|
|
534
|
+
* Get the active LLM config derived from the currently selected provider + model.
|
|
535
|
+
* Returns null if no active provider/model is configured.
|
|
536
|
+
*/
|
|
537
|
+
getActiveLLMConfig(): ActiveLLMConfig | null;
|
|
538
|
+
/**
|
|
539
|
+
* Get current settings from storage (public, for use by PageAgent during initialization).
|
|
540
|
+
*/
|
|
541
|
+
getSettings(): Record<string, string>;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Minimal interface that Panel expects from an agent.
|
|
546
|
+
* Panel does not depend on PageAgent directly - it only requires this interface.
|
|
547
|
+
* This enables decoupling and allows any agent implementation to work with Panel.
|
|
548
|
+
*
|
|
549
|
+
* Events:
|
|
550
|
+
* - 'statuschange': Agent status changed
|
|
551
|
+
* - 'historychange': Historical events updated (persisted)
|
|
552
|
+
* - 'activity': Transient activity for immediate UI feedback (thinking/executing/etc)
|
|
553
|
+
* - 'dispose': Agent is being disposed
|
|
554
|
+
*/
|
|
555
|
+
declare interface PanelAgentAdapter extends EventTarget {
|
|
556
|
+
/** Current agent status */
|
|
557
|
+
readonly status: 'idle' | 'running' | 'completed' | 'error' | 'stopped';
|
|
558
|
+
/** Result of the most recent run, or `null` before the first run completes */
|
|
559
|
+
readonly lastResult: {
|
|
560
|
+
success: boolean;
|
|
561
|
+
} | null;
|
|
562
|
+
/** History of agent events */
|
|
563
|
+
readonly history: readonly {
|
|
564
|
+
type: 'step' | 'observation' | 'user_takeover' | 'retry' | 'error';
|
|
565
|
+
stepIndex?: number;
|
|
566
|
+
/** For 'step' type */
|
|
567
|
+
reflection?: {
|
|
568
|
+
evaluation_previous_goal?: string;
|
|
569
|
+
memory?: string;
|
|
570
|
+
next_goal?: string;
|
|
571
|
+
};
|
|
572
|
+
/** For 'step' type */
|
|
573
|
+
action?: {
|
|
574
|
+
name: string;
|
|
575
|
+
input: unknown;
|
|
576
|
+
output: string;
|
|
577
|
+
};
|
|
578
|
+
/** For 'observation' type */
|
|
579
|
+
content?: string;
|
|
580
|
+
/** For 'retry' type */
|
|
581
|
+
attempt?: number;
|
|
582
|
+
maxAttempts?: number;
|
|
583
|
+
/** For 'retry' and 'error' types */
|
|
584
|
+
message?: string;
|
|
585
|
+
}[];
|
|
586
|
+
/** Current task being executed */
|
|
587
|
+
readonly task: string;
|
|
588
|
+
/**
|
|
589
|
+
* Called when the agent needs to ask the user questions.
|
|
590
|
+
* If unset, the `ask_user` tool will be disabled.
|
|
591
|
+
* Panel will set this to handle user questions via its UI.
|
|
592
|
+
* The optional `signal` aborts when the task is stopped or disposed.
|
|
593
|
+
*/
|
|
594
|
+
onAskUser?: (question: string, options?: {
|
|
595
|
+
signal: AbortSignal;
|
|
596
|
+
}) => Promise<string>;
|
|
597
|
+
/** Execute a task */
|
|
598
|
+
execute(task: string): Promise<unknown>;
|
|
599
|
+
/** Stop the current task (agent remains reusable) */
|
|
600
|
+
stop(): Promise<void>;
|
|
601
|
+
/** Dispose the agent (terminal, cannot be reused) */
|
|
602
|
+
dispose(): void;
|
|
603
|
+
/**
|
|
604
|
+
* Get the current page's simplified HTML content for DOM preview.
|
|
605
|
+
* Returns null/undefined when DOM preview is not supported.
|
|
606
|
+
* Called on-demand when the user opens the DOM preview panel.
|
|
607
|
+
*/
|
|
608
|
+
getSimplifiedHTML?(): string | null | undefined;
|
|
609
|
+
/**
|
|
610
|
+
* Snapshot the current agent state for conversation persistence.
|
|
611
|
+
* Returns a serializable state object, or null if no meaningful state exists.
|
|
612
|
+
*/
|
|
613
|
+
getConversationState?(): {
|
|
614
|
+
task: string;
|
|
615
|
+
history: readonly unknown[];
|
|
616
|
+
lastResult: {
|
|
617
|
+
success: boolean;
|
|
618
|
+
data: string;
|
|
619
|
+
} | null;
|
|
620
|
+
status: 'idle' | 'running' | 'completed' | 'error' | 'stopped';
|
|
621
|
+
} | null;
|
|
622
|
+
/**
|
|
623
|
+
* Restore agent state from a previously saved conversation snapshot.
|
|
624
|
+
* Emits historychange and statuschange so the UI re-renders.
|
|
625
|
+
*/
|
|
626
|
+
restoreConversationState?(state: {
|
|
627
|
+
task: string;
|
|
628
|
+
history: readonly unknown[];
|
|
629
|
+
lastResult: {
|
|
630
|
+
success: boolean;
|
|
631
|
+
data: string;
|
|
632
|
+
} | null;
|
|
633
|
+
status: 'idle' | 'running' | 'completed' | 'error' | 'stopped';
|
|
634
|
+
}): void;
|
|
635
|
+
/**
|
|
636
|
+
* Reset the agent to a fresh state for a new conversation.
|
|
637
|
+
* Emits events so the UI clears history and shows the input area.
|
|
638
|
+
*/
|
|
639
|
+
newConversation?(): void;
|
|
640
|
+
/** Get metadata for all registered skills */
|
|
641
|
+
getAvailableSkills?(): {
|
|
642
|
+
id: string;
|
|
643
|
+
name: string;
|
|
644
|
+
description: string;
|
|
645
|
+
version: string;
|
|
646
|
+
author?: string;
|
|
647
|
+
icon?: string;
|
|
648
|
+
active: boolean;
|
|
649
|
+
hasConfig: boolean;
|
|
650
|
+
configSchema?: object;
|
|
651
|
+
source: string;
|
|
652
|
+
}[];
|
|
653
|
+
/** Get IDs of currently active skills */
|
|
654
|
+
getActiveSkillIds?(): string[];
|
|
655
|
+
/** Load (activate) a skill by id or full skill object */
|
|
656
|
+
loadSkill?(skillOrId: unknown): Promise<void>;
|
|
657
|
+
/** Unload (deactivate) a skill by id */
|
|
658
|
+
unloadSkill?(skillId: string): Promise<void>;
|
|
659
|
+
/** Get current config for a skill */
|
|
660
|
+
getSkillConfig?(skillId: string): Record<string, unknown>;
|
|
661
|
+
/** Update config for a skill */
|
|
662
|
+
updateSkillConfig?(skillId: string, config: Record<string, unknown>): Promise<void>;
|
|
663
|
+
/** Subscribe to skill change events */
|
|
664
|
+
onSkillChange?(callback: () => void): void;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* Panel configuration
|
|
669
|
+
*/
|
|
670
|
+
export declare interface PanelConfig {
|
|
671
|
+
language?: SupportedLanguage;
|
|
672
|
+
/**
|
|
673
|
+
* Whether to prompt for next task after task completion
|
|
674
|
+
* @default true
|
|
675
|
+
*/
|
|
676
|
+
promptForNextTask?: boolean;
|
|
677
|
+
/** Default model config values from agent initialization (used as form defaults) */
|
|
678
|
+
defaults?: {
|
|
679
|
+
baseURL?: string;
|
|
680
|
+
model?: string;
|
|
681
|
+
apiKey?: string;
|
|
682
|
+
temperature?: number;
|
|
683
|
+
maxSteps?: number;
|
|
684
|
+
};
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/**
|
|
688
|
+
* A configured LLM provider with its models.
|
|
689
|
+
*/
|
|
690
|
+
export declare interface ProviderConfig {
|
|
691
|
+
/** Unique identifier */
|
|
692
|
+
id: string;
|
|
693
|
+
/** Display name (e.g. "OpenAI", "Anthropic") */
|
|
694
|
+
name: string;
|
|
695
|
+
/** API endpoint (base URL, without the endpoint path) */
|
|
696
|
+
baseURL: string;
|
|
697
|
+
/** API protocol format */
|
|
698
|
+
apiFormat: ApiFormat;
|
|
699
|
+
/** API key (stored locally in browser) */
|
|
700
|
+
apiKey?: string;
|
|
701
|
+
/** Models configured under this provider */
|
|
702
|
+
models: ModelConfig[];
|
|
703
|
+
/** Whether this provider is active and visible in the quick-switch dropdown */
|
|
704
|
+
enabled: boolean;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
/**
|
|
708
|
+
* Resolve the currently active provider and model from settings.
|
|
709
|
+
*
|
|
710
|
+
* Resolution order:
|
|
711
|
+
* 1. Find provider by activeProviderId (must be enabled)
|
|
712
|
+
* 2. Fall back to first enabled provider
|
|
713
|
+
* 3. Find model by activeModelName within the resolved provider
|
|
714
|
+
* 4. Fall back to first model in that provider
|
|
715
|
+
*
|
|
716
|
+
* Returns null if no enabled provider with models is configured.
|
|
717
|
+
*/
|
|
718
|
+
export declare function resolveActiveModel(settings: PageAgentSettings): ResolvedActiveModel | null;
|
|
719
|
+
|
|
720
|
+
/**
|
|
721
|
+
* Result of resolving the active provider + model from settings.
|
|
722
|
+
*/
|
|
723
|
+
export declare interface ResolvedActiveModel {
|
|
724
|
+
provider: ProviderConfig;
|
|
725
|
+
model: ModelConfig;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
/**
|
|
729
|
+
* Static helper for persisting and retrieving Skills via IndexedDB.
|
|
730
|
+
* Mirrors ConversationStorage from conversations.ts.
|
|
731
|
+
*
|
|
732
|
+
* Usage:
|
|
733
|
+
* await SkillStorage.save(skill)
|
|
734
|
+
* const all = await SkillStorage.list()
|
|
735
|
+
* const enabled = await SkillStorage.listEnabled()
|
|
736
|
+
*/
|
|
737
|
+
export declare const SkillStorage: {
|
|
738
|
+
/** List all skills ordered by updatedAt descending (newest first). */
|
|
739
|
+
list(): Promise<StoredSkill[]>;
|
|
740
|
+
/** List all enabled skills. */
|
|
741
|
+
listEnabled(): Promise<StoredSkill[]>;
|
|
742
|
+
/** Get a single skill by id. */
|
|
743
|
+
get(id: string): Promise<StoredSkill | undefined>;
|
|
744
|
+
/** Insert or update a skill. */
|
|
745
|
+
save(skill: StoredSkill): Promise<void>;
|
|
746
|
+
/** Batch save multiple skills. */
|
|
747
|
+
saveAll(skills: StoredSkill[]): Promise<void>;
|
|
748
|
+
/** Delete a skill by id. */
|
|
749
|
+
delete(id: string): Promise<void>;
|
|
750
|
+
/** Toggle the enabled state of a skill. */
|
|
751
|
+
toggleEnabled(id: string, enabled: boolean): Promise<void>;
|
|
752
|
+
/** Update config for a skill. */
|
|
753
|
+
updateConfig(id: string, config: Record<string, unknown>): Promise<void>;
|
|
754
|
+
/** Clear all skills. */
|
|
755
|
+
clear(): Promise<void>;
|
|
756
|
+
/** Export a skill as JSON string. */
|
|
757
|
+
exportJSON(id: string): Promise<string | null>;
|
|
758
|
+
/** Import a skill from JSON string. */
|
|
759
|
+
importJSON(json: string): Promise<StoredSkill>;
|
|
760
|
+
/** Get the total count of stored skills. */
|
|
761
|
+
count(): Promise<number>;
|
|
762
|
+
};
|
|
763
|
+
|
|
764
|
+
/**
|
|
765
|
+
* Serializable skill definition stored in IndexedDB.
|
|
766
|
+
*/
|
|
767
|
+
export declare interface StoredSkill {
|
|
768
|
+
id: string;
|
|
769
|
+
name: string;
|
|
770
|
+
description: string;
|
|
771
|
+
version: string;
|
|
772
|
+
icon?: string;
|
|
773
|
+
author?: string;
|
|
774
|
+
systemPromptFragment?: string;
|
|
775
|
+
tools?: StoredTool[];
|
|
776
|
+
config?: Record<string, unknown>;
|
|
777
|
+
enabled: boolean;
|
|
778
|
+
createdAt: number;
|
|
779
|
+
updatedAt: number;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
/**
|
|
783
|
+
* Serializable tool definition stored in IndexedDB.
|
|
784
|
+
* Mirrors PageAgentTool but with serializable fields only.
|
|
785
|
+
*/
|
|
786
|
+
export declare interface StoredTool {
|
|
787
|
+
name: string;
|
|
788
|
+
description: string;
|
|
789
|
+
inputSchema: Record<string, unknown>;
|
|
790
|
+
executeCode: string;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
export declare type SupportedLanguage = keyof typeof locales;
|
|
794
|
+
|
|
795
|
+
export declare type TranslationKey = NestedKeyOf<TranslationSchema>;
|
|
796
|
+
|
|
797
|
+
declare type TranslationParams = Record<string, string | number>;
|
|
798
|
+
|
|
799
|
+
declare type TranslationSchema = DeepStringify<typeof enUS>;
|
|
800
|
+
|
|
801
|
+
export { }
|