page-agent 0.0.0 → 0.0.2
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/README.md +41 -16
- package/dist/lib/PageAgent.d.ts +191 -53
- package/dist/lib/page-agent.js +555 -292
- package/dist/lib/page-agent.js.map +1 -1
- package/package.json +47 -34
- package/NOTICE +0 -23
package/dist/lib/page-agent.js
CHANGED
|
@@ -22,19 +22,18 @@ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read fr
|
|
|
22
22
|
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
23
23
|
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
24
24
|
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
25
|
-
var
|
|
26
|
-
import { generateText, stepCountIs, tool } from "ai";
|
|
25
|
+
var _bus, _wrapper, _indicator, _statusText, _historySection, _expandButton, _pauseButton, _stopButton, _inputSection, _taskInput, _bus2, _state, _isExpanded, _pageAgent, _userAnswerResolver, _isWaitingForUserAnswer, _headerUpdateTimer, _pendingHeaderText, _isAnimating, _Panel_instances, update_fn, show_fn, hide_fn, reset_fn, togglePause_fn, updatePauseButton_fn, stopAgent_fn, submitTask_fn, handleUserAnswer_fn, showInputArea_fn, hideInputArea_fn, shouldShowInputArea_fn, createWrapper_fn, setupEventListeners_fn, toggle_fn, expand_fn, collapse_fn, startHeaderUpdateLoop_fn, stopHeaderUpdateLoop_fn, checkAndUpdateHeader_fn, animateTextChange_fn, updateStatusIndicator_fn, updateHistory_fn, scrollToBottom_fn, createHistoryItem_fn, _cursor, _currentCursorX, _currentCursorY, _targetCursorX, _targetCursorY, _SimulatorMask_instances, createCursor_fn, moveCursorToTarget_fn, _llm, _totalWaitTime, _abortController, _PageAgent_instances, packMacroTool_fn, getSystemPrompt_fn, assembleUserPrompt_fn, onDone_fn, getBrowserState_fn, updateTree_fn;
|
|
27
26
|
import chalk from "chalk";
|
|
28
|
-
import zod from "zod";
|
|
29
|
-
import { createOpenAI } from "@ai-sdk/openai";
|
|
27
|
+
import zod, { z } from "zod";
|
|
30
28
|
import { Motion } from "ai-motion";
|
|
31
29
|
const VIEWPORT_EXPANSION = -1;
|
|
32
30
|
const DEFAULT_MODEL_NAME = "gpt-41-mini-0414-global";
|
|
33
31
|
const DEFAULT_API_KEY = "not-needed";
|
|
34
32
|
const DEFAULT_BASE_URL = "http://localhost:3000/api/agent";
|
|
35
|
-
const MACRO_TOOL_NAME = "AgentOutput";
|
|
36
33
|
const LLM_MAX_RETRIES = 2;
|
|
37
34
|
const MAX_STEPS = 20;
|
|
35
|
+
const DEFAULT_TEMPERATURE = 0.7;
|
|
36
|
+
const DEFAULT_MAX_TOKENS = 4096;
|
|
38
37
|
const domTree = /* @__PURE__ */ __name((args = {
|
|
39
38
|
doHighlightElements: true,
|
|
40
39
|
focusHighlightIndex: -1,
|
|
@@ -1396,49 +1395,6 @@ function getPageInfo() {
|
|
|
1396
1395
|
};
|
|
1397
1396
|
}
|
|
1398
1397
|
__name(getPageInfo, "getPageInfo");
|
|
1399
|
-
const zhCN = {
|
|
1400
|
-
ui: {
|
|
1401
|
-
panel: {
|
|
1402
|
-
ready: "准备就绪",
|
|
1403
|
-
thinking: "正在思考...",
|
|
1404
|
-
paused: "暂停中,稍后",
|
|
1405
|
-
taskInput: "输入新任务,详细描述步骤,回车提交",
|
|
1406
|
-
userAnswerPrompt: "请回答上面问题,回车提交",
|
|
1407
|
-
taskTerminated: "任务已终止",
|
|
1408
|
-
taskCompleted: "任务结束",
|
|
1409
|
-
continueExecution: "继续执行",
|
|
1410
|
-
userAnswer: "用户回答: {{input}}",
|
|
1411
|
-
pause: "暂停",
|
|
1412
|
-
continue: "继续",
|
|
1413
|
-
stop: "终止",
|
|
1414
|
-
expand: "展开历史",
|
|
1415
|
-
collapse: "收起历史",
|
|
1416
|
-
step: "步骤 {{number}} · {{time}}{{duration}}"
|
|
1417
|
-
},
|
|
1418
|
-
tools: {
|
|
1419
|
-
clicking: "正在点击元素 [{{index}}]...",
|
|
1420
|
-
inputting: "正在输入文本到元素 [{{index}}]...",
|
|
1421
|
-
selecting: '正在选择选项 "{{text}}"...',
|
|
1422
|
-
scrolling: "正在滚动页面...",
|
|
1423
|
-
waiting: "等待 {{seconds}} 秒...",
|
|
1424
|
-
done: "结束任务",
|
|
1425
|
-
clicked: "🖱️ 已点击元素 [{{index}}]",
|
|
1426
|
-
inputted: '⌨️ 已输入文本 "{{text}}"',
|
|
1427
|
-
selected: '☑️ 已选择选项 "{{text}}"',
|
|
1428
|
-
scrolled: "🛞 页面滚动完成",
|
|
1429
|
-
waited: "⌛️ 等待完成",
|
|
1430
|
-
executing: "正在执行 {{toolName}}..."
|
|
1431
|
-
},
|
|
1432
|
-
errors: {
|
|
1433
|
-
elementNotFound: "未找到索引为 {{index}} 的交互元素",
|
|
1434
|
-
taskRequired: "任务描述不能为空",
|
|
1435
|
-
executionFailed: "任务执行失败",
|
|
1436
|
-
notInputElement: "元素不是输入框或文本域",
|
|
1437
|
-
notSelectElement: "元素不是选择框",
|
|
1438
|
-
optionNotFound: '未找到选项 "{{text}}"'
|
|
1439
|
-
}
|
|
1440
|
-
}
|
|
1441
|
-
};
|
|
1442
1398
|
const enUS = {
|
|
1443
1399
|
ui: {
|
|
1444
1400
|
panel: {
|
|
@@ -1451,6 +1407,8 @@ const enUS = {
|
|
|
1451
1407
|
taskCompleted: "Task completed",
|
|
1452
1408
|
continueExecution: "Continue execution",
|
|
1453
1409
|
userAnswer: "User answer: {{input}}",
|
|
1410
|
+
question: "Question: {{question}}",
|
|
1411
|
+
waitingPlaceholder: "Waiting for task to start...",
|
|
1454
1412
|
pause: "Pause",
|
|
1455
1413
|
continue: "Continue",
|
|
1456
1414
|
stop: "Stop",
|
|
@@ -1470,7 +1428,10 @@ const enUS = {
|
|
|
1470
1428
|
selected: '☑️ Selected option "{{text}}"',
|
|
1471
1429
|
scrolled: "🛞 Page scrolled",
|
|
1472
1430
|
waited: "⌛️ Wait completed",
|
|
1473
|
-
executing: "
|
|
1431
|
+
executing: "Executing {{toolName}}...",
|
|
1432
|
+
resultSuccess: "success",
|
|
1433
|
+
resultFailure: "failed",
|
|
1434
|
+
resultError: "error"
|
|
1474
1435
|
},
|
|
1475
1436
|
errors: {
|
|
1476
1437
|
elementNotFound: "No interactive element found at index {{index}}",
|
|
@@ -1482,9 +1443,57 @@ const enUS = {
|
|
|
1482
1443
|
}
|
|
1483
1444
|
}
|
|
1484
1445
|
};
|
|
1446
|
+
const zhCN = {
|
|
1447
|
+
ui: {
|
|
1448
|
+
panel: {
|
|
1449
|
+
ready: "准备就绪",
|
|
1450
|
+
thinking: "正在思考...",
|
|
1451
|
+
paused: "暂停中,稍后",
|
|
1452
|
+
taskInput: "输入新任务,详细描述步骤,回车提交",
|
|
1453
|
+
userAnswerPrompt: "请回答上面问题,回车提交",
|
|
1454
|
+
taskTerminated: "任务已终止",
|
|
1455
|
+
taskCompleted: "任务结束",
|
|
1456
|
+
continueExecution: "继续执行",
|
|
1457
|
+
userAnswer: "用户回答: {{input}}",
|
|
1458
|
+
question: "询问: {{question}}",
|
|
1459
|
+
waitingPlaceholder: "等待任务开始...",
|
|
1460
|
+
pause: "暂停",
|
|
1461
|
+
continue: "继续",
|
|
1462
|
+
stop: "终止",
|
|
1463
|
+
expand: "展开历史",
|
|
1464
|
+
collapse: "收起历史",
|
|
1465
|
+
step: "步骤 {{number}} · {{time}}{{duration}}"
|
|
1466
|
+
},
|
|
1467
|
+
tools: {
|
|
1468
|
+
clicking: "正在点击元素 [{{index}}]...",
|
|
1469
|
+
inputting: "正在输入文本到元素 [{{index}}]...",
|
|
1470
|
+
selecting: '正在选择选项 "{{text}}"...',
|
|
1471
|
+
scrolling: "正在滚动页面...",
|
|
1472
|
+
waiting: "等待 {{seconds}} 秒...",
|
|
1473
|
+
done: "结束任务",
|
|
1474
|
+
clicked: "🖱️ 已点击元素 [{{index}}]",
|
|
1475
|
+
inputted: '⌨️ 已输入文本 "{{text}}"',
|
|
1476
|
+
selected: '☑️ 已选择选项 "{{text}}"',
|
|
1477
|
+
scrolled: "🛞 页面滚动完成",
|
|
1478
|
+
waited: "⌛️ 等待完成",
|
|
1479
|
+
executing: "正在执行 {{toolName}}...",
|
|
1480
|
+
resultSuccess: "成功",
|
|
1481
|
+
resultFailure: "失败",
|
|
1482
|
+
resultError: "错误"
|
|
1483
|
+
},
|
|
1484
|
+
errors: {
|
|
1485
|
+
elementNotFound: "未找到索引为 {{index}} 的交互元素",
|
|
1486
|
+
taskRequired: "任务描述不能为空",
|
|
1487
|
+
executionFailed: "任务执行失败",
|
|
1488
|
+
notInputElement: "元素不是输入框或文本域",
|
|
1489
|
+
notSelectElement: "元素不是选择框",
|
|
1490
|
+
optionNotFound: '未找到选项 "{{text}}"'
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
};
|
|
1485
1494
|
const locales = {
|
|
1486
|
-
"
|
|
1487
|
-
"
|
|
1495
|
+
"en-US": enUS,
|
|
1496
|
+
"zh-CN": zhCN
|
|
1488
1497
|
};
|
|
1489
1498
|
const _I18n = class _I18n {
|
|
1490
1499
|
language;
|
|
@@ -1510,7 +1519,7 @@ const _I18n = class _I18n {
|
|
|
1510
1519
|
}
|
|
1511
1520
|
interpolate(template, params) {
|
|
1512
1521
|
return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
|
|
1513
|
-
return params[key]
|
|
1522
|
+
return params[key] != null ? params[key].toString() : match;
|
|
1514
1523
|
});
|
|
1515
1524
|
}
|
|
1516
1525
|
getLanguage() {
|
|
@@ -1519,14 +1528,17 @@ const _I18n = class _I18n {
|
|
|
1519
1528
|
};
|
|
1520
1529
|
__name(_I18n, "I18n");
|
|
1521
1530
|
let I18n = _I18n;
|
|
1522
|
-
function
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1531
|
+
function parseLLMConfig(config) {
|
|
1532
|
+
return {
|
|
1533
|
+
baseURL: config.baseURL ?? DEFAULT_BASE_URL,
|
|
1534
|
+
apiKey: config.apiKey ?? DEFAULT_API_KEY,
|
|
1535
|
+
model: config.model ?? DEFAULT_MODEL_NAME,
|
|
1536
|
+
temperature: config.temperature ?? DEFAULT_TEMPERATURE,
|
|
1537
|
+
maxTokens: config.maxTokens ?? DEFAULT_MAX_TOKENS,
|
|
1538
|
+
maxRetries: config.maxRetries ?? LLM_MAX_RETRIES
|
|
1539
|
+
};
|
|
1528
1540
|
}
|
|
1529
|
-
__name(
|
|
1541
|
+
__name(parseLLMConfig, "parseLLMConfig");
|
|
1530
1542
|
const _EventBus = class _EventBus extends EventTarget {
|
|
1531
1543
|
/**
|
|
1532
1544
|
* Listen to built-in events
|
|
@@ -1571,24 +1583,316 @@ function getEventBus(channel) {
|
|
|
1571
1583
|
return bus;
|
|
1572
1584
|
}
|
|
1573
1585
|
__name(getEventBus, "getEventBus");
|
|
1586
|
+
const InvokeErrorType = {
|
|
1587
|
+
// Retryable
|
|
1588
|
+
NETWORK_ERROR: "network_error",
|
|
1589
|
+
// Network error, retry
|
|
1590
|
+
RATE_LIMIT: "rate_limit",
|
|
1591
|
+
// Rate limit, retry
|
|
1592
|
+
SERVER_ERROR: "server_error",
|
|
1593
|
+
// 5xx, retry
|
|
1594
|
+
NO_TOOL_CALL: "no_tool_call",
|
|
1595
|
+
// Model did not call tool
|
|
1596
|
+
INVALID_TOOL_ARGS: "invalid_tool_args",
|
|
1597
|
+
// Tool args don't match schema
|
|
1598
|
+
TOOL_EXECUTION_ERROR: "tool_execution_error",
|
|
1599
|
+
// Tool execution error
|
|
1600
|
+
UNKNOWN: "unknown",
|
|
1601
|
+
// Non-retryable
|
|
1602
|
+
AUTH_ERROR: "auth_error",
|
|
1603
|
+
// Authentication failed
|
|
1604
|
+
CONTEXT_LENGTH: "context_length",
|
|
1605
|
+
// Prompt too long
|
|
1606
|
+
CONTENT_FILTER: "content_filter"
|
|
1607
|
+
// Content filtered
|
|
1608
|
+
};
|
|
1609
|
+
const _InvokeError = class _InvokeError extends Error {
|
|
1610
|
+
type;
|
|
1611
|
+
retryable;
|
|
1612
|
+
statusCode;
|
|
1613
|
+
rawError;
|
|
1614
|
+
constructor(type, message, rawError) {
|
|
1615
|
+
super(message);
|
|
1616
|
+
this.name = "InvokeError";
|
|
1617
|
+
this.type = type;
|
|
1618
|
+
this.retryable = this.isRetryable(type);
|
|
1619
|
+
this.rawError = rawError;
|
|
1620
|
+
}
|
|
1621
|
+
isRetryable(type) {
|
|
1622
|
+
const retryableTypes = [
|
|
1623
|
+
InvokeErrorType.NETWORK_ERROR,
|
|
1624
|
+
InvokeErrorType.RATE_LIMIT,
|
|
1625
|
+
InvokeErrorType.SERVER_ERROR,
|
|
1626
|
+
InvokeErrorType.NO_TOOL_CALL,
|
|
1627
|
+
InvokeErrorType.INVALID_TOOL_ARGS,
|
|
1628
|
+
InvokeErrorType.TOOL_EXECUTION_ERROR,
|
|
1629
|
+
InvokeErrorType.UNKNOWN
|
|
1630
|
+
];
|
|
1631
|
+
return retryableTypes.includes(type);
|
|
1632
|
+
}
|
|
1633
|
+
};
|
|
1634
|
+
__name(_InvokeError, "InvokeError");
|
|
1635
|
+
let InvokeError = _InvokeError;
|
|
1636
|
+
function zodToOpenAITool(name, tool2) {
|
|
1637
|
+
return {
|
|
1638
|
+
type: "function",
|
|
1639
|
+
function: {
|
|
1640
|
+
name,
|
|
1641
|
+
description: tool2.description,
|
|
1642
|
+
parameters: z.toJSONSchema(tool2.inputSchema, { target: "openapi-3.0" })
|
|
1643
|
+
}
|
|
1644
|
+
};
|
|
1645
|
+
}
|
|
1646
|
+
__name(zodToOpenAITool, "zodToOpenAITool");
|
|
1647
|
+
function lenientParseMacroToolCall(responseData, inputSchema) {
|
|
1648
|
+
const choice = responseData.choices?.[0];
|
|
1649
|
+
if (!choice) {
|
|
1650
|
+
throw new InvokeError(InvokeErrorType.UNKNOWN, "No choices in response", responseData);
|
|
1651
|
+
}
|
|
1652
|
+
switch (choice.finish_reason) {
|
|
1653
|
+
case "tool_calls":
|
|
1654
|
+
case "stop":
|
|
1655
|
+
break;
|
|
1656
|
+
case "length":
|
|
1657
|
+
throw new InvokeError(
|
|
1658
|
+
InvokeErrorType.CONTEXT_LENGTH,
|
|
1659
|
+
"Response truncated: max tokens reached"
|
|
1660
|
+
);
|
|
1661
|
+
case "content_filter":
|
|
1662
|
+
throw new InvokeError(InvokeErrorType.CONTENT_FILTER, "Content filtered by safety system");
|
|
1663
|
+
default:
|
|
1664
|
+
throw new InvokeError(
|
|
1665
|
+
InvokeErrorType.UNKNOWN,
|
|
1666
|
+
`Unexpected finish_reason: ${choice.finish_reason}`
|
|
1667
|
+
);
|
|
1668
|
+
}
|
|
1669
|
+
const actionSchema = inputSchema.shape.action;
|
|
1670
|
+
if (!actionSchema) {
|
|
1671
|
+
throw new Error('inputSchema must have an "action" field');
|
|
1672
|
+
}
|
|
1673
|
+
let arg = null;
|
|
1674
|
+
const toolCall = choice.message?.tool_calls?.[0]?.function;
|
|
1675
|
+
arg = toolCall?.arguments ?? null;
|
|
1676
|
+
if (arg && toolCall.name !== "AgentOutput") {
|
|
1677
|
+
console.log(chalk.yellow("lenientParseMacroToolCall: #1 fixing incorrect tool call"));
|
|
1678
|
+
let tmpArg;
|
|
1679
|
+
try {
|
|
1680
|
+
tmpArg = JSON.parse(arg);
|
|
1681
|
+
} catch (error2) {
|
|
1682
|
+
throw new InvokeError(
|
|
1683
|
+
InvokeErrorType.INVALID_TOOL_ARGS,
|
|
1684
|
+
"Failed to parse tool arguments as JSON",
|
|
1685
|
+
error2
|
|
1686
|
+
);
|
|
1687
|
+
}
|
|
1688
|
+
arg = JSON.stringify({ action: { [toolCall.name]: tmpArg } });
|
|
1689
|
+
}
|
|
1690
|
+
if (!arg) {
|
|
1691
|
+
arg = choice.message?.content.trim() || null;
|
|
1692
|
+
}
|
|
1693
|
+
if (!arg) {
|
|
1694
|
+
throw new InvokeError(
|
|
1695
|
+
InvokeErrorType.NO_TOOL_CALL,
|
|
1696
|
+
"No tool call or content found in response",
|
|
1697
|
+
responseData
|
|
1698
|
+
);
|
|
1699
|
+
}
|
|
1700
|
+
let parsedArgs;
|
|
1701
|
+
try {
|
|
1702
|
+
parsedArgs = JSON.parse(arg);
|
|
1703
|
+
} catch (error2) {
|
|
1704
|
+
throw new InvokeError(
|
|
1705
|
+
InvokeErrorType.INVALID_TOOL_ARGS,
|
|
1706
|
+
"Failed to parse tool arguments as JSON",
|
|
1707
|
+
error2
|
|
1708
|
+
);
|
|
1709
|
+
}
|
|
1710
|
+
if (parsedArgs.action || parsedArgs.evaluation_previous_goal || parsedArgs.next_goal) {
|
|
1711
|
+
if (!parsedArgs.action) {
|
|
1712
|
+
console.log(chalk.yellow("lenientParseMacroToolCall: #2 fixing incorrect tool call"));
|
|
1713
|
+
parsedArgs.action = {
|
|
1714
|
+
wait: { seconds: 1 }
|
|
1715
|
+
};
|
|
1716
|
+
}
|
|
1717
|
+
} else if (parsedArgs.type && parsedArgs.function) {
|
|
1718
|
+
if (parsedArgs.function.name !== "AgentOutput")
|
|
1719
|
+
throw new InvokeError(
|
|
1720
|
+
InvokeErrorType.INVALID_TOOL_ARGS,
|
|
1721
|
+
`Expected function name "AgentOutput", got "${parsedArgs.function.name}"`,
|
|
1722
|
+
null
|
|
1723
|
+
);
|
|
1724
|
+
console.log(chalk.yellow("lenientParseMacroToolCall: #3 fixing incorrect tool call"));
|
|
1725
|
+
parsedArgs = parsedArgs.function.arguments;
|
|
1726
|
+
} else if (parsedArgs.name && parsedArgs.arguments) {
|
|
1727
|
+
if (parsedArgs.name !== "AgentOutput")
|
|
1728
|
+
throw new InvokeError(
|
|
1729
|
+
InvokeErrorType.INVALID_TOOL_ARGS,
|
|
1730
|
+
`Expected function name "AgentOutput", got "${parsedArgs.name}"`,
|
|
1731
|
+
null
|
|
1732
|
+
);
|
|
1733
|
+
console.log(chalk.yellow("lenientParseMacroToolCall: #4 fixing incorrect tool call"));
|
|
1734
|
+
parsedArgs = parsedArgs.arguments;
|
|
1735
|
+
} else {
|
|
1736
|
+
console.log(chalk.yellow("lenientParseMacroToolCall: #5 fixing incorrect tool call"));
|
|
1737
|
+
parsedArgs = { action: parsedArgs };
|
|
1738
|
+
}
|
|
1739
|
+
if (typeof parsedArgs === "string") {
|
|
1740
|
+
console.log(chalk.yellow("lenientParseMacroToolCall: #6 fixing incorrect tool call"));
|
|
1741
|
+
try {
|
|
1742
|
+
parsedArgs = JSON.parse(parsedArgs);
|
|
1743
|
+
} catch (error2) {
|
|
1744
|
+
throw new InvokeError(
|
|
1745
|
+
InvokeErrorType.INVALID_TOOL_ARGS,
|
|
1746
|
+
"Failed to parse nested tool arguments as JSON",
|
|
1747
|
+
error2
|
|
1748
|
+
);
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
const validation = inputSchema.safeParse(parsedArgs);
|
|
1752
|
+
if (validation.success) {
|
|
1753
|
+
return validation.data;
|
|
1754
|
+
} else {
|
|
1755
|
+
const action = parsedArgs.action ?? {};
|
|
1756
|
+
const actionName = Object.keys(action)[0] || "unknown";
|
|
1757
|
+
const actionArgs = JSON.stringify(action[actionName] || "unknown");
|
|
1758
|
+
throw new InvokeError(
|
|
1759
|
+
InvokeErrorType.INVALID_TOOL_ARGS,
|
|
1760
|
+
`Tool arguments validation failed: action "${actionName}" with args ${actionArgs}`,
|
|
1761
|
+
validation.error
|
|
1762
|
+
);
|
|
1763
|
+
}
|
|
1764
|
+
}
|
|
1765
|
+
__name(lenientParseMacroToolCall, "lenientParseMacroToolCall");
|
|
1766
|
+
function modelPatch(body) {
|
|
1767
|
+
const model = body.model || "";
|
|
1768
|
+
if (model.toLowerCase().startsWith("claude")) {
|
|
1769
|
+
body.tool_choice = { type: "tool", name: "AgentOutput" };
|
|
1770
|
+
body.thinking = { type: "disabled" };
|
|
1771
|
+
}
|
|
1772
|
+
if (model.toLowerCase().includes("grok")) {
|
|
1773
|
+
console.log("Applying Grok patch: removing tool_choice");
|
|
1774
|
+
delete body.tool_choice;
|
|
1775
|
+
console.log("Applying Grok patch: disable reasoning and thinking");
|
|
1776
|
+
body.thinking = { type: "disabled", effort: "minimal" };
|
|
1777
|
+
body.reasoning = { enabled: false, effort: "low" };
|
|
1778
|
+
}
|
|
1779
|
+
return body;
|
|
1780
|
+
}
|
|
1781
|
+
__name(modelPatch, "modelPatch");
|
|
1782
|
+
const _OpenAIClient = class _OpenAIClient {
|
|
1783
|
+
config;
|
|
1784
|
+
constructor(config) {
|
|
1785
|
+
this.config = config;
|
|
1786
|
+
}
|
|
1787
|
+
async invoke(messages, tools2, abortSignal) {
|
|
1788
|
+
const openaiTools = Object.entries(tools2).map(([name, tool22]) => zodToOpenAITool(name, tool22));
|
|
1789
|
+
let response;
|
|
1790
|
+
try {
|
|
1791
|
+
response = await fetch(`${this.config.baseURL}/chat/completions`, {
|
|
1792
|
+
method: "POST",
|
|
1793
|
+
headers: {
|
|
1794
|
+
"Content-Type": "application/json",
|
|
1795
|
+
Authorization: `Bearer ${this.config.apiKey}`
|
|
1796
|
+
},
|
|
1797
|
+
body: JSON.stringify(
|
|
1798
|
+
modelPatch({
|
|
1799
|
+
model: this.config.model,
|
|
1800
|
+
temperature: this.config.temperature,
|
|
1801
|
+
max_tokens: this.config.maxTokens,
|
|
1802
|
+
messages,
|
|
1803
|
+
tools: openaiTools,
|
|
1804
|
+
// tool_choice: 'required',
|
|
1805
|
+
tool_choice: { type: "function", function: { name: "AgentOutput" } },
|
|
1806
|
+
// model specific params
|
|
1807
|
+
// reasoning_effort: 'minimal',
|
|
1808
|
+
// verbosity: 'low',
|
|
1809
|
+
parallel_tool_calls: false
|
|
1810
|
+
})
|
|
1811
|
+
),
|
|
1812
|
+
signal: abortSignal
|
|
1813
|
+
});
|
|
1814
|
+
} catch (error2) {
|
|
1815
|
+
throw new InvokeError(InvokeErrorType.NETWORK_ERROR, "Network request failed", error2);
|
|
1816
|
+
}
|
|
1817
|
+
if (!response.ok) {
|
|
1818
|
+
const errorData = await response.json().catch();
|
|
1819
|
+
const errorMessage = errorData.error?.message || response.statusText;
|
|
1820
|
+
if (response.status === 401 || response.status === 403) {
|
|
1821
|
+
throw new InvokeError(
|
|
1822
|
+
InvokeErrorType.AUTH_ERROR,
|
|
1823
|
+
`Authentication failed: ${errorMessage}`,
|
|
1824
|
+
errorData
|
|
1825
|
+
);
|
|
1826
|
+
}
|
|
1827
|
+
if (response.status === 429) {
|
|
1828
|
+
throw new InvokeError(
|
|
1829
|
+
InvokeErrorType.RATE_LIMIT,
|
|
1830
|
+
`Rate limit exceeded: ${errorMessage}`,
|
|
1831
|
+
errorData
|
|
1832
|
+
);
|
|
1833
|
+
}
|
|
1834
|
+
if (response.status >= 500) {
|
|
1835
|
+
throw new InvokeError(
|
|
1836
|
+
InvokeErrorType.SERVER_ERROR,
|
|
1837
|
+
`Server error: ${errorMessage}`,
|
|
1838
|
+
errorData
|
|
1839
|
+
);
|
|
1840
|
+
}
|
|
1841
|
+
throw new InvokeError(
|
|
1842
|
+
InvokeErrorType.UNKNOWN,
|
|
1843
|
+
`HTTP ${response.status}: ${errorMessage}`,
|
|
1844
|
+
errorData
|
|
1845
|
+
);
|
|
1846
|
+
}
|
|
1847
|
+
const data = await response.json();
|
|
1848
|
+
const tool2 = tools2.AgentOutput;
|
|
1849
|
+
const macroToolInput = lenientParseMacroToolCall(data, tool2.inputSchema);
|
|
1850
|
+
let toolResult;
|
|
1851
|
+
try {
|
|
1852
|
+
toolResult = await tool2.execute(macroToolInput);
|
|
1853
|
+
} catch (e) {
|
|
1854
|
+
throw new InvokeError(
|
|
1855
|
+
InvokeErrorType.TOOL_EXECUTION_ERROR,
|
|
1856
|
+
`Tool execution failed: ${e.message}`,
|
|
1857
|
+
e
|
|
1858
|
+
);
|
|
1859
|
+
}
|
|
1860
|
+
return {
|
|
1861
|
+
toolCall: {
|
|
1862
|
+
// id: toolCall.id,
|
|
1863
|
+
name: "AgentOutput",
|
|
1864
|
+
args: macroToolInput
|
|
1865
|
+
},
|
|
1866
|
+
toolResult,
|
|
1867
|
+
usage: {
|
|
1868
|
+
promptTokens: data.usage?.prompt_tokens ?? 0,
|
|
1869
|
+
completionTokens: data.usage?.completion_tokens ?? 0,
|
|
1870
|
+
totalTokens: data.usage?.total_tokens ?? 0,
|
|
1871
|
+
cachedTokens: data.usage?.prompt_tokens_details?.cached_tokens,
|
|
1872
|
+
reasoningTokens: data.usage?.completion_tokens_details?.reasoning_tokens
|
|
1873
|
+
},
|
|
1874
|
+
rawResponse: data
|
|
1875
|
+
};
|
|
1876
|
+
}
|
|
1877
|
+
};
|
|
1878
|
+
__name(_OpenAIClient, "OpenAIClient");
|
|
1879
|
+
let OpenAIClient = _OpenAIClient;
|
|
1574
1880
|
const _LLM = class _LLM {
|
|
1575
1881
|
constructor(config, id) {
|
|
1576
1882
|
__publicField(this, "config");
|
|
1577
1883
|
__publicField(this, "id");
|
|
1578
|
-
|
|
1579
|
-
__privateAdd(this, _model);
|
|
1884
|
+
__publicField(this, "client");
|
|
1580
1885
|
__privateAdd(this, _bus);
|
|
1581
|
-
this.config =
|
|
1582
|
-
baseURL: DEFAULT_BASE_URL,
|
|
1583
|
-
apiKey: DEFAULT_API_KEY,
|
|
1584
|
-
modelName: DEFAULT_MODEL_NAME,
|
|
1585
|
-
maxRetries: LLM_MAX_RETRIES,
|
|
1586
|
-
...config
|
|
1587
|
-
};
|
|
1886
|
+
this.config = parseLLMConfig(config);
|
|
1588
1887
|
this.id = id;
|
|
1589
1888
|
__privateSet(this, _bus, getEventBus(id));
|
|
1590
|
-
|
|
1591
|
-
|
|
1889
|
+
this.client = new OpenAIClient({
|
|
1890
|
+
model: this.config.model,
|
|
1891
|
+
apiKey: this.config.apiKey,
|
|
1892
|
+
baseURL: this.config.baseURL,
|
|
1893
|
+
temperature: this.config.temperature,
|
|
1894
|
+
maxTokens: this.config.maxTokens
|
|
1895
|
+
});
|
|
1592
1896
|
}
|
|
1593
1897
|
/**
|
|
1594
1898
|
* - call llm api *once*
|
|
@@ -1596,81 +1900,10 @@ const _LLM = class _LLM {
|
|
|
1596
1900
|
* - return the result of the tool
|
|
1597
1901
|
*/
|
|
1598
1902
|
async invoke(messages, tools2, abortSignal) {
|
|
1599
|
-
const isClaude = this.config.modelName.slice(0, 8).includes("claude");
|
|
1600
|
-
this.config.modelName.slice(0, 6).includes("qwen");
|
|
1601
|
-
this.config.modelName.slice(0, 5).includes("gpt");
|
|
1602
1903
|
return await withRetry(
|
|
1603
1904
|
async () => {
|
|
1604
|
-
const result = await
|
|
1605
|
-
|
|
1606
|
-
messages,
|
|
1607
|
-
tools: tools2,
|
|
1608
|
-
abortSignal,
|
|
1609
|
-
/**
|
|
1610
|
-
* 文档中没有说明,从源码看,@facts
|
|
1611
|
-
* - 只会重试被识别为 retryable 的 API_CALL_ERROR
|
|
1612
|
-
* - 返回无法解析的 json 应该不会重试
|
|
1613
|
-
* - experimental_repairToolCall 只会执行一次,不算作重试
|
|
1614
|
-
* @facts
|
|
1615
|
-
* - 许多 proxy 过的 openAI 兼容接口返回的错误格式并不规范,通常不会被识别为 retryable
|
|
1616
|
-
* @conclusion
|
|
1617
|
-
* - 看起来并不实用,不如完全手工控制粗粒度重试
|
|
1618
|
-
*/
|
|
1619
|
-
// maxRetries: this.config.maxRetries,
|
|
1620
|
-
maxRetries: 0,
|
|
1621
|
-
// toolChoice: 'required',
|
|
1622
|
-
// @note incompatible to Claude
|
|
1623
|
-
toolChoice: isClaude ? void 0 : { type: "tool", toolName: MACRO_TOOL_NAME },
|
|
1624
|
-
/**
|
|
1625
|
-
* controlled by main loop. our method only call api once
|
|
1626
|
-
*/
|
|
1627
|
-
// stopWhen: [hasToolCall('done'), stepCountIs(100)],
|
|
1628
|
-
stopWhen: [stepCountIs(1)],
|
|
1629
|
-
// stopWhen: [hasToolCall('AgentOutput')],
|
|
1630
|
-
providerOptions: {
|
|
1631
|
-
openai: {
|
|
1632
|
-
// @note this one needs all fields in tool schema must be `required`
|
|
1633
|
-
// strictJsonSchema: true,
|
|
1634
|
-
// This way only at most one tool can be called at a time
|
|
1635
|
-
parallelToolCalls: false,
|
|
1636
|
-
reasoningEffort: "minimal",
|
|
1637
|
-
// @note not working
|
|
1638
|
-
// serviceTier: 'priority',
|
|
1639
|
-
textVerbosity: "low",
|
|
1640
|
-
// @note Optimize OpenAI model caching, should be unique per user, currently has no effect
|
|
1641
|
-
promptCacheKey: "page-agent:" + this.id
|
|
1642
|
-
}
|
|
1643
|
-
}
|
|
1644
|
-
/**
|
|
1645
|
-
* schema 出错时执行一次,不确定是否计入重试
|
|
1646
|
-
* 目前看起来像是会直接抛错,被 withRetry 处理
|
|
1647
|
-
* @note
|
|
1648
|
-
* 如果不提供,则 ai-sdk 会把 tool-error 加入 message 中重新调用一次,
|
|
1649
|
-
* 配合 stepCountIs 或者 hasToolCall 都会导致错误被 silent,toolResults 永远为 0
|
|
1650
|
-
* 遗憾的是,这里没有办法抛错(抛错后回到默认逻辑),只要这里 repair 不好,就会导致 silent error
|
|
1651
|
-
* 更糟糕的是,只要传入了 tools,无论 stopWhen 如何设置,都会被当作 multi-step,
|
|
1652
|
-
* 本质上就和我们 single step 的逻辑冲突
|
|
1653
|
-
* 长远来看必须删掉 ai-sdk,直接用 openAI API 实现
|
|
1654
|
-
*/
|
|
1655
|
-
// experimental_repairToolCall: (options): Promise<LanguageModelV2ToolCall | null> => {
|
|
1656
|
-
// console.error('hahhah', options)
|
|
1657
|
-
// throw options.error
|
|
1658
|
-
// },
|
|
1659
|
-
});
|
|
1660
|
-
console.log(chalk.blue.bold("LLM:invoke finished"), result);
|
|
1661
|
-
const toolError = result.content.find((part) => part.type === "tool-error");
|
|
1662
|
-
if (toolError) throw toolError.error;
|
|
1663
|
-
assert(!result.text, "Model returned text without calling done tool", true);
|
|
1664
|
-
assert(result.toolCalls.length === 1, "Model must call exactly one tool", true);
|
|
1665
|
-
assert(result.toolResults.length === 1, "Step must have exactly one tool result", true);
|
|
1666
|
-
const toolCall = result.toolCalls[0];
|
|
1667
|
-
const toolResult = result.toolResults[0];
|
|
1668
|
-
const usage = result.totalUsage;
|
|
1669
|
-
return {
|
|
1670
|
-
toolCall,
|
|
1671
|
-
toolResult,
|
|
1672
|
-
usage
|
|
1673
|
-
};
|
|
1905
|
+
const result = await this.client.invoke(messages, tools2, abortSignal);
|
|
1906
|
+
return result;
|
|
1674
1907
|
},
|
|
1675
1908
|
// retry settings
|
|
1676
1909
|
{
|
|
@@ -1691,8 +1924,6 @@ const _LLM = class _LLM {
|
|
|
1691
1924
|
);
|
|
1692
1925
|
}
|
|
1693
1926
|
};
|
|
1694
|
-
_openai = new WeakMap();
|
|
1695
|
-
_model = new WeakMap();
|
|
1696
1927
|
_bus = new WeakMap();
|
|
1697
1928
|
__name(_LLM, "LLM");
|
|
1698
1929
|
let LLM = _LLM;
|
|
@@ -1710,6 +1941,7 @@ async function withRetry(fn, settings) {
|
|
|
1710
1941
|
console.error(error2);
|
|
1711
1942
|
settings.onError(error2, retries < settings.maxRetries);
|
|
1712
1943
|
if (error2?.name === "AbortError") throw error2;
|
|
1944
|
+
if (error2 instanceof InvokeError && !error2.retryable) throw error2;
|
|
1713
1945
|
lastError = error2;
|
|
1714
1946
|
retries++;
|
|
1715
1947
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
@@ -2049,6 +2281,10 @@ const utils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
|
|
|
2049
2281
|
waitFor
|
|
2050
2282
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2051
2283
|
window.utils = utils;
|
|
2284
|
+
function tool(options) {
|
|
2285
|
+
return options;
|
|
2286
|
+
}
|
|
2287
|
+
__name(tool, "tool");
|
|
2052
2288
|
const tools = /* @__PURE__ */ new Map();
|
|
2053
2289
|
tools.set(
|
|
2054
2290
|
"done",
|
|
@@ -2058,7 +2294,8 @@ tools.set(
|
|
|
2058
2294
|
text: zod.string(),
|
|
2059
2295
|
success: zod.boolean().default(true)
|
|
2060
2296
|
}),
|
|
2061
|
-
execute: /* @__PURE__ */ __name(function(input2) {
|
|
2297
|
+
execute: /* @__PURE__ */ __name(async function(input2) {
|
|
2298
|
+
return Promise.resolve("Task completed");
|
|
2062
2299
|
}, "execute")
|
|
2063
2300
|
})
|
|
2064
2301
|
);
|
|
@@ -2389,6 +2626,9 @@ const _Panel = class _Panel {
|
|
|
2389
2626
|
__privateAdd(this, _pageAgent);
|
|
2390
2627
|
__privateAdd(this, _userAnswerResolver, null);
|
|
2391
2628
|
__privateAdd(this, _isWaitingForUserAnswer, false);
|
|
2629
|
+
__privateAdd(this, _headerUpdateTimer, null);
|
|
2630
|
+
__privateAdd(this, _pendingHeaderText, null);
|
|
2631
|
+
__privateAdd(this, _isAnimating, false);
|
|
2392
2632
|
__privateSet(this, _pageAgent, pageAgent);
|
|
2393
2633
|
__privateSet(this, _bus2, pageAgent.bus);
|
|
2394
2634
|
__privateSet(this, _wrapper, __privateMethod(this, _Panel_instances, createWrapper_fn).call(this));
|
|
@@ -2401,6 +2641,7 @@ const _Panel = class _Panel {
|
|
|
2401
2641
|
__privateSet(this, _inputSection, __privateGet(this, _wrapper).querySelector(`.${styles$1.inputSectionWrapper}`));
|
|
2402
2642
|
__privateSet(this, _taskInput, __privateGet(this, _wrapper).querySelector(`.${styles$1.taskInput}`));
|
|
2403
2643
|
__privateMethod(this, _Panel_instances, setupEventListeners_fn).call(this);
|
|
2644
|
+
__privateMethod(this, _Panel_instances, startHeaderUpdateLoop_fn).call(this);
|
|
2404
2645
|
__privateMethod(this, _Panel_instances, showInputArea_fn).call(this);
|
|
2405
2646
|
__privateGet(this, _bus2).on("panel:show", () => __privateMethod(this, _Panel_instances, show_fn).call(this));
|
|
2406
2647
|
__privateGet(this, _bus2).on("panel:hide", () => __privateMethod(this, _Panel_instances, hide_fn).call(this));
|
|
@@ -2421,7 +2662,7 @@ const _Panel = class _Panel {
|
|
|
2421
2662
|
__privateSet(this, _userAnswerResolver, resolve);
|
|
2422
2663
|
__privateMethod(this, _Panel_instances, update_fn).call(this, {
|
|
2423
2664
|
type: "output",
|
|
2424
|
-
displayText:
|
|
2665
|
+
displayText: __privateGet(this, _pageAgent).i18n.t("ui.panel.question", { question })
|
|
2425
2666
|
});
|
|
2426
2667
|
if (!__privateGet(this, _isExpanded)) {
|
|
2427
2668
|
__privateMethod(this, _Panel_instances, expand_fn).call(this);
|
|
@@ -2434,6 +2675,7 @@ const _Panel = class _Panel {
|
|
|
2434
2675
|
*/
|
|
2435
2676
|
dispose() {
|
|
2436
2677
|
__privateSet(this, _isWaitingForUserAnswer, false);
|
|
2678
|
+
__privateMethod(this, _Panel_instances, stopHeaderUpdateLoop_fn).call(this);
|
|
2437
2679
|
this.wrapper.remove();
|
|
2438
2680
|
}
|
|
2439
2681
|
};
|
|
@@ -2452,13 +2694,17 @@ _isExpanded = new WeakMap();
|
|
|
2452
2694
|
_pageAgent = new WeakMap();
|
|
2453
2695
|
_userAnswerResolver = new WeakMap();
|
|
2454
2696
|
_isWaitingForUserAnswer = new WeakMap();
|
|
2697
|
+
_headerUpdateTimer = new WeakMap();
|
|
2698
|
+
_pendingHeaderText = new WeakMap();
|
|
2699
|
+
_isAnimating = new WeakMap();
|
|
2455
2700
|
_Panel_instances = new WeakSet();
|
|
2456
|
-
|
|
2701
|
+
/**
|
|
2702
|
+
* Update status
|
|
2703
|
+
*/
|
|
2704
|
+
update_fn = /* @__PURE__ */ __name(function(stepData) {
|
|
2457
2705
|
const step = __privateGet(this, _state).addStep(stepData);
|
|
2458
2706
|
const headerText = truncate(step.displayText, 20);
|
|
2459
|
-
|
|
2460
|
-
await __privateMethod(this, _Panel_instances, animateTextChange_fn).call(this, headerText);
|
|
2461
|
-
}
|
|
2707
|
+
__privateSet(this, _pendingHeaderText, headerText);
|
|
2462
2708
|
__privateMethod(this, _Panel_instances, updateStatusIndicator_fn).call(this, step.type);
|
|
2463
2709
|
__privateMethod(this, _Panel_instances, updateHistory_fn).call(this);
|
|
2464
2710
|
if (step.type === "completed" || step.type === "error") {
|
|
@@ -2482,7 +2728,7 @@ show_fn = /* @__PURE__ */ __name(function() {
|
|
|
2482
2728
|
this.wrapper.style.transform = "translateX(-50%) translateY(0)";
|
|
2483
2729
|
}, "#show");
|
|
2484
2730
|
/**
|
|
2485
|
-
*
|
|
2731
|
+
* Hide panel
|
|
2486
2732
|
*/
|
|
2487
2733
|
hide_fn = /* @__PURE__ */ __name(function() {
|
|
2488
2734
|
this.wrapper.style.opacity = "0";
|
|
@@ -2490,7 +2736,7 @@ hide_fn = /* @__PURE__ */ __name(function() {
|
|
|
2490
2736
|
this.wrapper.style.display = "none";
|
|
2491
2737
|
}, "#hide");
|
|
2492
2738
|
/**
|
|
2493
|
-
*
|
|
2739
|
+
* Reset state
|
|
2494
2740
|
*/
|
|
2495
2741
|
reset_fn = /* @__PURE__ */ __name(function() {
|
|
2496
2742
|
__privateGet(this, _state).reset();
|
|
@@ -2511,39 +2757,39 @@ togglePause_fn = /* @__PURE__ */ __name(function() {
|
|
|
2511
2757
|
__privateGet(this, _pageAgent).paused = !__privateGet(this, _pageAgent).paused;
|
|
2512
2758
|
__privateMethod(this, _Panel_instances, updatePauseButton_fn).call(this);
|
|
2513
2759
|
if (__privateGet(this, _pageAgent).paused) {
|
|
2514
|
-
__privateGet(this, _statusText).textContent = "
|
|
2760
|
+
__privateGet(this, _statusText).textContent = __privateGet(this, _pageAgent).i18n.t("ui.panel.paused");
|
|
2515
2761
|
__privateMethod(this, _Panel_instances, updateStatusIndicator_fn).call(this, "thinking");
|
|
2516
2762
|
} else {
|
|
2517
|
-
__privateGet(this, _statusText).textContent = "
|
|
2763
|
+
__privateGet(this, _statusText).textContent = __privateGet(this, _pageAgent).i18n.t("ui.panel.continueExecution");
|
|
2518
2764
|
__privateMethod(this, _Panel_instances, updateStatusIndicator_fn).call(this, "tool_executing");
|
|
2519
2765
|
}
|
|
2520
2766
|
}, "#togglePause");
|
|
2521
2767
|
/**
|
|
2522
|
-
*
|
|
2768
|
+
* Update pause button state
|
|
2523
2769
|
*/
|
|
2524
2770
|
updatePauseButton_fn = /* @__PURE__ */ __name(function() {
|
|
2525
2771
|
if (__privateGet(this, _pageAgent).paused) {
|
|
2526
2772
|
__privateGet(this, _pauseButton).textContent = "▶";
|
|
2527
|
-
__privateGet(this, _pauseButton).title = "
|
|
2773
|
+
__privateGet(this, _pauseButton).title = __privateGet(this, _pageAgent).i18n.t("ui.panel.continue");
|
|
2528
2774
|
__privateGet(this, _pauseButton).classList.add(styles$1.paused);
|
|
2529
2775
|
} else {
|
|
2530
2776
|
__privateGet(this, _pauseButton).textContent = "⏸︎";
|
|
2531
|
-
__privateGet(this, _pauseButton).title = "
|
|
2777
|
+
__privateGet(this, _pauseButton).title = __privateGet(this, _pageAgent).i18n.t("ui.panel.pause");
|
|
2532
2778
|
__privateGet(this, _pauseButton).classList.remove(styles$1.paused);
|
|
2533
2779
|
}
|
|
2534
2780
|
}, "#updatePauseButton");
|
|
2535
2781
|
/**
|
|
2536
|
-
*
|
|
2782
|
+
* Stop Agent
|
|
2537
2783
|
*/
|
|
2538
2784
|
stopAgent_fn = /* @__PURE__ */ __name(function() {
|
|
2539
2785
|
__privateMethod(this, _Panel_instances, update_fn).call(this, {
|
|
2540
2786
|
type: "error",
|
|
2541
|
-
displayText: "
|
|
2787
|
+
displayText: __privateGet(this, _pageAgent).i18n.t("ui.panel.taskTerminated")
|
|
2542
2788
|
});
|
|
2543
2789
|
__privateGet(this, _pageAgent).dispose();
|
|
2544
2790
|
}, "#stopAgent");
|
|
2545
2791
|
/**
|
|
2546
|
-
*
|
|
2792
|
+
* Submit task
|
|
2547
2793
|
*/
|
|
2548
2794
|
submitTask_fn = /* @__PURE__ */ __name(function() {
|
|
2549
2795
|
const input2 = __privateGet(this, _taskInput).value.trim();
|
|
@@ -2556,12 +2802,12 @@ submitTask_fn = /* @__PURE__ */ __name(function() {
|
|
|
2556
2802
|
}
|
|
2557
2803
|
}, "#submitTask");
|
|
2558
2804
|
/**
|
|
2559
|
-
*
|
|
2805
|
+
* Handle user answer
|
|
2560
2806
|
*/
|
|
2561
2807
|
handleUserAnswer_fn = /* @__PURE__ */ __name(function(input2) {
|
|
2562
2808
|
__privateMethod(this, _Panel_instances, update_fn).call(this, {
|
|
2563
2809
|
type: "input",
|
|
2564
|
-
displayText:
|
|
2810
|
+
displayText: __privateGet(this, _pageAgent).i18n.t("ui.panel.userAnswer", { input: input2 })
|
|
2565
2811
|
});
|
|
2566
2812
|
__privateSet(this, _isWaitingForUserAnswer, false);
|
|
2567
2813
|
if (__privateGet(this, _userAnswerResolver)) {
|
|
@@ -2570,24 +2816,24 @@ handleUserAnswer_fn = /* @__PURE__ */ __name(function(input2) {
|
|
|
2570
2816
|
}
|
|
2571
2817
|
}, "#handleUserAnswer");
|
|
2572
2818
|
/**
|
|
2573
|
-
*
|
|
2819
|
+
* Show input area
|
|
2574
2820
|
*/
|
|
2575
2821
|
showInputArea_fn = /* @__PURE__ */ __name(function(placeholder) {
|
|
2576
2822
|
__privateGet(this, _taskInput).value = "";
|
|
2577
|
-
__privateGet(this, _taskInput).placeholder = placeholder || "
|
|
2823
|
+
__privateGet(this, _taskInput).placeholder = placeholder || __privateGet(this, _pageAgent).i18n.t("ui.panel.taskInput");
|
|
2578
2824
|
__privateGet(this, _inputSection).classList.remove(styles$1.hidden);
|
|
2579
2825
|
setTimeout(() => {
|
|
2580
2826
|
__privateGet(this, _taskInput).focus();
|
|
2581
2827
|
}, 100);
|
|
2582
2828
|
}, "#showInputArea");
|
|
2583
2829
|
/**
|
|
2584
|
-
*
|
|
2830
|
+
* Hide input area
|
|
2585
2831
|
*/
|
|
2586
2832
|
hideInputArea_fn = /* @__PURE__ */ __name(function() {
|
|
2587
2833
|
__privateGet(this, _inputSection).classList.add(styles$1.hidden);
|
|
2588
2834
|
}, "#hideInputArea");
|
|
2589
2835
|
/**
|
|
2590
|
-
*
|
|
2836
|
+
* Check if input area should be shown
|
|
2591
2837
|
*/
|
|
2592
2838
|
shouldShowInputArea_fn = /* @__PURE__ */ __name(function() {
|
|
2593
2839
|
if (__privateGet(this, _isWaitingForUserAnswer)) return true;
|
|
@@ -2612,23 +2858,23 @@ createWrapper_fn = /* @__PURE__ */ __name(function() {
|
|
|
2612
2858
|
stepNumber: 0,
|
|
2613
2859
|
timestamp: /* @__PURE__ */ new Date(),
|
|
2614
2860
|
type: "thinking",
|
|
2615
|
-
displayText: "
|
|
2861
|
+
displayText: __privateGet(this, _pageAgent).i18n.t("ui.panel.waitingPlaceholder")
|
|
2616
2862
|
})}
|
|
2617
2863
|
</div>
|
|
2618
2864
|
</div>
|
|
2619
2865
|
<div class="${styles$1.header}">
|
|
2620
2866
|
<div class="${styles$1.statusSection}">
|
|
2621
2867
|
<div class="${styles$1.indicator} ${styles$1.thinking}"></div>
|
|
2622
|
-
<div class="${styles$1.statusText}"
|
|
2868
|
+
<div class="${styles$1.statusText}">${__privateGet(this, _pageAgent).i18n.t("ui.panel.ready")}</div>
|
|
2623
2869
|
</div>
|
|
2624
2870
|
<div class="${styles$1.controls}">
|
|
2625
|
-
<button class="${styles$1.controlButton} ${styles$1.expandButton}" title="
|
|
2871
|
+
<button class="${styles$1.controlButton} ${styles$1.expandButton}" title="${__privateGet(this, _pageAgent).i18n.t("ui.panel.expand")}">
|
|
2626
2872
|
▼
|
|
2627
2873
|
</button>
|
|
2628
|
-
<button class="${styles$1.controlButton} ${styles$1.pauseButton}" title="
|
|
2874
|
+
<button class="${styles$1.controlButton} ${styles$1.pauseButton}" title="${__privateGet(this, _pageAgent).i18n.t("ui.panel.pause")}">
|
|
2629
2875
|
⏸︎
|
|
2630
2876
|
</button>
|
|
2631
|
-
<button class="${styles$1.controlButton} ${styles$1.stopButton}" title="
|
|
2877
|
+
<button class="${styles$1.controlButton} ${styles$1.stopButton}" title="${__privateGet(this, _pageAgent).i18n.t("ui.panel.stop")}">
|
|
2632
2878
|
X
|
|
2633
2879
|
</button>
|
|
2634
2880
|
</div>
|
|
@@ -2696,19 +2942,53 @@ collapse_fn = /* @__PURE__ */ __name(function() {
|
|
|
2696
2942
|
this.wrapper.classList.add(styles$1.collapsed);
|
|
2697
2943
|
__privateGet(this, _expandButton).textContent = "▼";
|
|
2698
2944
|
}, "#collapse");
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2945
|
+
/**
|
|
2946
|
+
* Start periodic header update loop
|
|
2947
|
+
*/
|
|
2948
|
+
startHeaderUpdateLoop_fn = /* @__PURE__ */ __name(function() {
|
|
2949
|
+
__privateSet(this, _headerUpdateTimer, setInterval(() => {
|
|
2950
|
+
__privateMethod(this, _Panel_instances, checkAndUpdateHeader_fn).call(this);
|
|
2951
|
+
}, 450));
|
|
2952
|
+
}, "#startHeaderUpdateLoop");
|
|
2953
|
+
/**
|
|
2954
|
+
* Stop periodic header update loop
|
|
2955
|
+
*/
|
|
2956
|
+
stopHeaderUpdateLoop_fn = /* @__PURE__ */ __name(function() {
|
|
2957
|
+
if (__privateGet(this, _headerUpdateTimer)) {
|
|
2958
|
+
clearInterval(__privateGet(this, _headerUpdateTimer));
|
|
2959
|
+
__privateSet(this, _headerUpdateTimer, null);
|
|
2960
|
+
}
|
|
2961
|
+
}, "#stopHeaderUpdateLoop");
|
|
2962
|
+
/**
|
|
2963
|
+
* Check if header needs update and trigger animation if not currently animating
|
|
2964
|
+
*/
|
|
2965
|
+
checkAndUpdateHeader_fn = /* @__PURE__ */ __name(function() {
|
|
2966
|
+
if (!__privateGet(this, _pendingHeaderText) || __privateGet(this, _isAnimating)) {
|
|
2967
|
+
return;
|
|
2968
|
+
}
|
|
2969
|
+
if (__privateGet(this, _statusText).textContent === __privateGet(this, _pendingHeaderText)) {
|
|
2970
|
+
__privateSet(this, _pendingHeaderText, null);
|
|
2971
|
+
return;
|
|
2972
|
+
}
|
|
2973
|
+
const textToShow = __privateGet(this, _pendingHeaderText);
|
|
2974
|
+
__privateSet(this, _pendingHeaderText, null);
|
|
2975
|
+
__privateMethod(this, _Panel_instances, animateTextChange_fn).call(this, textToShow);
|
|
2976
|
+
}, "#checkAndUpdateHeader");
|
|
2977
|
+
/**
|
|
2978
|
+
* Animate text change with fade out/in effect
|
|
2979
|
+
*/
|
|
2980
|
+
animateTextChange_fn = /* @__PURE__ */ __name(function(newText) {
|
|
2981
|
+
__privateSet(this, _isAnimating, true);
|
|
2982
|
+
__privateGet(this, _statusText).classList.add(styles$1.fadeOut);
|
|
2983
|
+
setTimeout(() => {
|
|
2984
|
+
__privateGet(this, _statusText).textContent = newText;
|
|
2985
|
+
__privateGet(this, _statusText).classList.remove(styles$1.fadeOut);
|
|
2986
|
+
__privateGet(this, _statusText).classList.add(styles$1.fadeIn);
|
|
2702
2987
|
setTimeout(() => {
|
|
2703
|
-
__privateGet(this, _statusText).
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
__privateGet(this, _statusText).classList.remove(styles$1.fadeIn);
|
|
2708
|
-
resolve();
|
|
2709
|
-
}, 300);
|
|
2710
|
-
}, 150);
|
|
2711
|
-
});
|
|
2988
|
+
__privateGet(this, _statusText).classList.remove(styles$1.fadeIn);
|
|
2989
|
+
__privateSet(this, _isAnimating, false);
|
|
2990
|
+
}, 300);
|
|
2991
|
+
}, 150);
|
|
2712
2992
|
}, "#animateTextChange");
|
|
2713
2993
|
updateStatusIndicator_fn = /* @__PURE__ */ __name(function(type) {
|
|
2714
2994
|
__privateGet(this, _indicator).className = styles$1.indicator;
|
|
@@ -2716,7 +2996,7 @@ updateStatusIndicator_fn = /* @__PURE__ */ __name(function(type) {
|
|
|
2716
2996
|
}, "#updateStatusIndicator");
|
|
2717
2997
|
updateHistory_fn = /* @__PURE__ */ __name(function() {
|
|
2718
2998
|
const steps = __privateGet(this, _state).getAllSteps();
|
|
2719
|
-
__privateGet(this, _historySection).innerHTML = steps.
|
|
2999
|
+
__privateGet(this, _historySection).innerHTML = steps.map((step) => __privateMethod(this, _Panel_instances, createHistoryItem_fn).call(this, step)).join("");
|
|
2720
3000
|
__privateMethod(this, _Panel_instances, scrollToBottom_fn).call(this);
|
|
2721
3001
|
}, "#updateHistory");
|
|
2722
3002
|
scrollToBottom_fn = /* @__PURE__ */ __name(function() {
|
|
@@ -2735,7 +3015,9 @@ createHistoryItem_fn = /* @__PURE__ */ __name(function(step) {
|
|
|
2735
3015
|
let statusIcon2 = "";
|
|
2736
3016
|
if (step.type === "completed") {
|
|
2737
3017
|
if (step.toolName === "done") {
|
|
2738
|
-
const
|
|
3018
|
+
const failureKeyword = __privateGet(this, _pageAgent).i18n.t("ui.tools.resultFailure");
|
|
3019
|
+
const errorKeyword = __privateGet(this, _pageAgent).i18n.t("ui.tools.resultError");
|
|
3020
|
+
const isSuccess = !step.toolResult || !step.toolResult.includes(failureKeyword) && !step.toolResult.includes(errorKeyword);
|
|
2739
3021
|
typeClass = isSuccess ? styles$1.doneSuccess : styles$1.doneError;
|
|
2740
3022
|
statusIcon2 = isSuccess ? "🎉" : "❌";
|
|
2741
3023
|
} else {
|
|
@@ -2759,6 +3041,13 @@ createHistoryItem_fn = /* @__PURE__ */ __name(function(step) {
|
|
|
2759
3041
|
} else {
|
|
2760
3042
|
statusIcon2 = "🧠";
|
|
2761
3043
|
}
|
|
3044
|
+
const durationText = step.duration ? ` · ${step.duration}ms` : "";
|
|
3045
|
+
const stepLabel = __privateGet(this, _pageAgent).i18n.t("ui.panel.step", {
|
|
3046
|
+
number: step.stepNumber.toString(),
|
|
3047
|
+
time,
|
|
3048
|
+
duration: durationText || ""
|
|
3049
|
+
// Explicitly pass empty string to replace template
|
|
3050
|
+
});
|
|
2762
3051
|
return `
|
|
2763
3052
|
<div class="${styles$1.historyItem} ${typeClass}">
|
|
2764
3053
|
<div class="${styles$1.historyContent}">
|
|
@@ -2766,8 +3055,7 @@ createHistoryItem_fn = /* @__PURE__ */ __name(function(step) {
|
|
|
2766
3055
|
<span>${step.displayText}</span>
|
|
2767
3056
|
</div>
|
|
2768
3057
|
<div class="${styles$1.historyMeta}">
|
|
2769
|
-
|
|
2770
|
-
${step.duration ? ` · ${step.duration}ms` : ""}
|
|
3058
|
+
${stepLabel}
|
|
2771
3059
|
</div>
|
|
2772
3060
|
</div>
|
|
2773
3061
|
`;
|
|
@@ -3028,6 +3316,14 @@ moveCursorToTarget_fn = /* @__PURE__ */ __name(function() {
|
|
|
3028
3316
|
}, "#moveCursorToTarget");
|
|
3029
3317
|
__name(_SimulatorMask, "SimulatorMask");
|
|
3030
3318
|
let SimulatorMask = _SimulatorMask;
|
|
3319
|
+
function assert(condition, message, silent) {
|
|
3320
|
+
if (!condition) {
|
|
3321
|
+
const errorMessage = message ?? "Assertion failed";
|
|
3322
|
+
console.error(chalk.red(`❌ assert: ${errorMessage}`));
|
|
3323
|
+
throw new Error(errorMessage);
|
|
3324
|
+
}
|
|
3325
|
+
}
|
|
3326
|
+
__name(assert, "assert");
|
|
3031
3327
|
const _PageAgent = class _PageAgent extends EventTarget {
|
|
3032
3328
|
constructor(config = {}) {
|
|
3033
3329
|
super();
|
|
@@ -3036,6 +3332,7 @@ const _PageAgent = class _PageAgent extends EventTarget {
|
|
|
3036
3332
|
__publicField(this, "id", uid());
|
|
3037
3333
|
__publicField(this, "bus", getEventBus(this.id));
|
|
3038
3334
|
__publicField(this, "i18n");
|
|
3335
|
+
__publicField(this, "panel");
|
|
3039
3336
|
__publicField(this, "paused", false);
|
|
3040
3337
|
__publicField(this, "disposed", false);
|
|
3041
3338
|
__publicField(this, "task", "");
|
|
@@ -3059,13 +3356,12 @@ const _PageAgent = class _PageAgent extends EventTarget {
|
|
|
3059
3356
|
__publicField(this, "tools", new Map(tools));
|
|
3060
3357
|
/** Fullscreen mask */
|
|
3061
3358
|
__publicField(this, "mask", new SimulatorMask());
|
|
3062
|
-
/** Interactive panel */
|
|
3063
|
-
__publicField(this, "panel", new Panel(this));
|
|
3064
3359
|
/** History records */
|
|
3065
3360
|
__publicField(this, "history", []);
|
|
3066
3361
|
this.config = config;
|
|
3067
3362
|
__privateSet(this, _llm, new LLM(this.config, this.id));
|
|
3068
3363
|
this.i18n = new I18n(this.config.language);
|
|
3364
|
+
this.panel = new Panel(this);
|
|
3069
3365
|
patchReact();
|
|
3070
3366
|
}
|
|
3071
3367
|
/**
|
|
@@ -3108,18 +3404,16 @@ const _PageAgent = class _PageAgent extends EventTarget {
|
|
|
3108
3404
|
content: __privateMethod(this, _PageAgent_instances, assembleUserPrompt_fn).call(this)
|
|
3109
3405
|
}
|
|
3110
3406
|
],
|
|
3111
|
-
|
|
3112
|
-
__privateMethod(this, _PageAgent_instances, packMacroTool_fn).call(this),
|
|
3407
|
+
{ AgentOutput: __privateMethod(this, _PageAgent_instances, packMacroTool_fn).call(this) },
|
|
3113
3408
|
__privateGet(this, _abortController).signal
|
|
3114
3409
|
);
|
|
3115
|
-
const
|
|
3116
|
-
const input2 =
|
|
3117
|
-
const output2 =
|
|
3410
|
+
const macroResult = result.toolResult;
|
|
3411
|
+
const input2 = macroResult.input;
|
|
3412
|
+
const output2 = macroResult.output;
|
|
3118
3413
|
const brain = {
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
next_goal: input2.next_goal
|
|
3414
|
+
evaluation_previous_goal: input2.evaluation_previous_goal || "",
|
|
3415
|
+
memory: input2.memory || "",
|
|
3416
|
+
next_goal: input2.next_goal || ""
|
|
3123
3417
|
};
|
|
3124
3418
|
const actionName = Object.keys(input2.action)[0];
|
|
3125
3419
|
const action = {
|
|
@@ -3144,8 +3438,8 @@ const _PageAgent = class _PageAgent extends EventTarget {
|
|
|
3144
3438
|
};
|
|
3145
3439
|
}
|
|
3146
3440
|
if (actionName === "done") {
|
|
3147
|
-
const success = action.input
|
|
3148
|
-
const text = action.input
|
|
3441
|
+
const success = action.input?.success ?? false;
|
|
3442
|
+
const text = action.input?.text || "no text provided";
|
|
3149
3443
|
console.log(chalk.green.bold("Task completed"), success, text);
|
|
3150
3444
|
__privateMethod(this, _PageAgent_instances, onDone_fn).call(this, text, success);
|
|
3151
3445
|
return {
|
|
@@ -3190,42 +3484,6 @@ _PageAgent_instances = new WeakSet();
|
|
|
3190
3484
|
* - next_goal: string
|
|
3191
3485
|
* - action: { toolName: toolInput }
|
|
3192
3486
|
* where action must be selected from tools defined in this.tools
|
|
3193
|
-
*
|
|
3194
|
-
* @topic 要不要合并成一个 tool?
|
|
3195
|
-
* @facts
|
|
3196
|
-
* - 我们需要模型每步返回 evaluation/memory/goal 等思考过程
|
|
3197
|
-
* - browser use 合并成一个巨大的 tool
|
|
3198
|
-
* ```json
|
|
3199
|
-
* {
|
|
3200
|
-
* "memory": "...",
|
|
3201
|
-
* "goal": "...",
|
|
3202
|
-
* "actions": [
|
|
3203
|
-
* {
|
|
3204
|
-
* "name": "...",
|
|
3205
|
-
* "args": "..."
|
|
3206
|
-
* }
|
|
3207
|
-
* // ...
|
|
3208
|
-
* ]
|
|
3209
|
-
* }
|
|
3210
|
-
* ```
|
|
3211
|
-
* - qwen 目前必须指定 function name 来确保 tool call
|
|
3212
|
-
* @reasoning
|
|
3213
|
-
* - 不能为了 qwen 的缺陷而设计系统
|
|
3214
|
-
* - 更复杂的 tool 更容易出错
|
|
3215
|
-
* - 分散的 tool 更容易利用 ai-sdk 的重试机制,也更容易处理错误
|
|
3216
|
-
* - 不能用额外的步骤生成这些数据,不仅性能过差,而且 goal 之类的必须和 call 一起生成
|
|
3217
|
-
* @options
|
|
3218
|
-
* - Plan @A
|
|
3219
|
-
* - 和 browser use 使用完全一致的做法,合并成一个大 tool,要求每次调用
|
|
3220
|
-
* - 会把 tool 定义变得非常复杂,增加出错率
|
|
3221
|
-
* - Plan @B
|
|
3222
|
-
* - 每次调用两个 tool,其中一个用来输出思考
|
|
3223
|
-
* - 很难用提示词 enforce 这么复杂的规则
|
|
3224
|
-
* - Plan @C
|
|
3225
|
-
* - 自动为每个 tool 增加固定的 reasoning/memory/goal 等输入,并自动拦截提取这些数据
|
|
3226
|
-
* - 会让 tool 定义变得很长
|
|
3227
|
-
* @conclusion
|
|
3228
|
-
* - 使用 @A
|
|
3229
3487
|
*/
|
|
3230
3488
|
packMacroTool_fn = /* @__PURE__ */ __name(function() {
|
|
3231
3489
|
const tools2 = this.tools;
|
|
@@ -3234,70 +3492,75 @@ packMacroTool_fn = /* @__PURE__ */ __name(function() {
|
|
|
3234
3492
|
[toolName]: tool2.inputSchema
|
|
3235
3493
|
});
|
|
3236
3494
|
});
|
|
3237
|
-
const actionSchema = zod.union(
|
|
3495
|
+
const actionSchema = zod.union(
|
|
3496
|
+
actionSchemas
|
|
3497
|
+
);
|
|
3498
|
+
const macroToolSchema = zod.object({
|
|
3499
|
+
// thinking: zod.string().optional(),
|
|
3500
|
+
evaluation_previous_goal: zod.string().optional(),
|
|
3501
|
+
memory: zod.string().optional(),
|
|
3502
|
+
next_goal: zod.string().optional(),
|
|
3503
|
+
action: actionSchema
|
|
3504
|
+
});
|
|
3238
3505
|
return {
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
await waitUntil(() => !this.paused);
|
|
3251
|
-
console.log(chalk.blue.bold("MacroTool execute"), input2);
|
|
3252
|
-
const action = input2.action;
|
|
3253
|
-
const toolName = Object.keys(action)[0];
|
|
3254
|
-
const toolInput = action[toolName];
|
|
3255
|
-
const brain = trimLines(`✅: ${input2.evaluation_previous_goal}
|
|
3506
|
+
// name: MACRO_TOOL_NAME,
|
|
3507
|
+
// description: 'Execute agent action', // @todo remote
|
|
3508
|
+
inputSchema: macroToolSchema,
|
|
3509
|
+
execute: /* @__PURE__ */ __name(async (input2) => {
|
|
3510
|
+
if (__privateGet(this, _abortController).signal.aborted) throw new Error("AbortError");
|
|
3511
|
+
await waitUntil(() => !this.paused);
|
|
3512
|
+
console.log(chalk.blue.bold("MacroTool execute"), input2);
|
|
3513
|
+
const action = input2.action;
|
|
3514
|
+
const toolName = Object.keys(action)[0];
|
|
3515
|
+
const toolInput = action[toolName];
|
|
3516
|
+
const brain = trimLines(`✅: ${input2.evaluation_previous_goal}
|
|
3256
3517
|
💾: ${input2.memory}
|
|
3257
3518
|
🎯: ${input2.next_goal}
|
|
3258
3519
|
`);
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3520
|
+
console.log(brain);
|
|
3521
|
+
this.bus.emit("panel:update", {
|
|
3522
|
+
type: "thinking",
|
|
3523
|
+
displayText: brain
|
|
3524
|
+
});
|
|
3525
|
+
const tool2 = tools2.get(toolName);
|
|
3526
|
+
assert(tool2, `Tool ${toolName} not found. (@note should have been caught before this!!!)`);
|
|
3527
|
+
console.log(chalk.blue.bold(`Executing tool: ${toolName}`), toolInput);
|
|
3528
|
+
this.bus.emit("panel:update", {
|
|
3529
|
+
type: "tool_executing",
|
|
3530
|
+
toolName,
|
|
3531
|
+
toolArgs: toolInput,
|
|
3532
|
+
displayText: getToolExecutingText(toolName, toolInput, this.i18n)
|
|
3533
|
+
});
|
|
3534
|
+
const startTime = Date.now();
|
|
3535
|
+
let result = await tool2.execute.bind(this)(toolInput);
|
|
3536
|
+
const duration = Date.now() - startTime;
|
|
3537
|
+
console.log(chalk.green.bold(`Tool (${toolName}) executed for ${duration}ms`), result);
|
|
3538
|
+
if (toolName === "wait") {
|
|
3539
|
+
__privateSet(this, _totalWaitTime, __privateGet(this, _totalWaitTime) + Math.round(toolInput.seconds + duration / 1e3));
|
|
3540
|
+
result += `
|
|
3541
|
+
<sys> You have waited ${__privateGet(this, _totalWaitTime)} seconds accumulatively.`;
|
|
3542
|
+
if (__privateGet(this, _totalWaitTime) >= 3)
|
|
3543
|
+
result += "\nDo NOT wait any longer unless you have a good reason.\n";
|
|
3544
|
+
result += "</sys>";
|
|
3545
|
+
} else {
|
|
3546
|
+
__privateSet(this, _totalWaitTime, 0);
|
|
3547
|
+
}
|
|
3548
|
+
const displayResult = getToolCompletedText(toolName, toolInput, this.i18n);
|
|
3549
|
+
if (displayResult)
|
|
3267
3550
|
this.bus.emit("panel:update", {
|
|
3268
3551
|
type: "tool_executing",
|
|
3269
3552
|
toolName,
|
|
3270
3553
|
toolArgs: toolInput,
|
|
3271
|
-
|
|
3554
|
+
toolResult: result,
|
|
3555
|
+
displayText: displayResult,
|
|
3556
|
+
duration
|
|
3272
3557
|
});
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
result += `
|
|
3280
|
-
<sys> You have waited ${__privateGet(this, _totalWaitTime)} seconds accumulatively.`;
|
|
3281
|
-
if (__privateGet(this, _totalWaitTime) >= 3)
|
|
3282
|
-
result += "\nDo NOT wait any longer unless you have a good reason.\n";
|
|
3283
|
-
result += "</sys>";
|
|
3284
|
-
} else {
|
|
3285
|
-
__privateSet(this, _totalWaitTime, 0);
|
|
3286
|
-
}
|
|
3287
|
-
const displayResult = getToolCompletedText(toolName, toolInput, this.i18n);
|
|
3288
|
-
if (displayResult)
|
|
3289
|
-
this.bus.emit("panel:update", {
|
|
3290
|
-
type: "tool_executing",
|
|
3291
|
-
toolName,
|
|
3292
|
-
toolArgs: toolInput,
|
|
3293
|
-
toolResult: result,
|
|
3294
|
-
displayText: displayResult,
|
|
3295
|
-
duration
|
|
3296
|
-
});
|
|
3297
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
3298
|
-
return result;
|
|
3299
|
-
}, "execute")
|
|
3300
|
-
})
|
|
3558
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
3559
|
+
return {
|
|
3560
|
+
input: input2,
|
|
3561
|
+
output: result
|
|
3562
|
+
};
|
|
3563
|
+
}, "execute")
|
|
3301
3564
|
};
|
|
3302
3565
|
}, "#packMacroTool");
|
|
3303
3566
|
/**
|