@page-agent/ui 0.0.20 → 0.0.22
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/lib/index.d.ts +0 -14
- package/dist/lib/page-agent-ui.js +54 -279
- package/dist/lib/page-agent-ui.js.map +1 -1
- package/package.json +2 -5
package/dist/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { Motion } from 'ai-motion';
|
|
2
|
-
|
|
3
1
|
export declare type AgentStatus = 'idle' | 'running' | 'paused' | 'completed' | 'error';
|
|
4
2
|
|
|
5
3
|
declare type DeepStringify<T> = {
|
|
@@ -244,18 +242,6 @@ export declare type PanelUpdate = {
|
|
|
244
242
|
duration?: number;
|
|
245
243
|
};
|
|
246
244
|
|
|
247
|
-
export declare class SimulatorMask {
|
|
248
|
-
#private;
|
|
249
|
-
wrapper: HTMLDivElement;
|
|
250
|
-
motion: Motion;
|
|
251
|
-
constructor();
|
|
252
|
-
setCursorPosition(x: number, y: number): void;
|
|
253
|
-
triggerClickAnimation(): void;
|
|
254
|
-
show(): void;
|
|
255
|
-
hide(): void;
|
|
256
|
-
dispose(): void;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
245
|
/**
|
|
260
246
|
* Agent execution state management
|
|
261
247
|
*/
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
try {
|
|
4
4
|
if (typeof document != "undefined") {
|
|
5
5
|
var elementStyle = document.createElement("style");
|
|
6
|
-
elementStyle.appendChild(document.createTextNode("._wrapper_1j0ct_1 {\n position: fixed;\n bottom: 100px;\n left: 50%;\n transform: translateX(-50%) translateY(20px);\n opacity: 0;\n z-index: 2147483642; /* 比 SimulatorMask 高一层 */\n box-sizing: border-box;\n\n overflow: visible;\n\n * {\n box-sizing: border-box;\n }\n\n --width: 360px;\n --height: 40px;\n --border-radius: 12px;\n\n --side-space: 12px; /* 控制栏两侧的间距 */\n --history-width: calc(var(--width) - var(--side-space) * 2);\n\n --color-1: rgb(57, 182, 255);\n --color-2: rgb(189, 69, 251);\n --color-3: rgb(255, 87, 51);\n --color-4: rgb(255, 214, 0);\n\n width: var(--width);\n height: var(--height);\n\n transition: all 0.3s ease-in-out;\n\n /* 响应式设计 */\n @media (max-width: 480px) {\n width: calc(100vw - 40px);\n --width: calc(100vw - 40px);\n }\n\n ._background_1j0ct_39 {\n position: absolute;\n inset: -2px -8px;\n border-radius: calc(var(--border-radius) + 4px);\n filter: blur(16px);\n overflow: hidden;\n /* mix-blend-mode: lighten; */\n /* display: none; */\n\n &::before {\n content: '';\n z-index: -1;\n pointer-events: none;\n position: absolute;\n width: 100%;\n height: 100%;\n /* left: -100%; */\n left: 0;\n top: 0;\n\n background-image: linear-gradient(\n to bottom left,\n var(--color-1),\n var(--color-2),\n var(--color-1)\n );\n animation: _mask-running_1j0ct_1 2s linear infinite;\n }\n &::after {\n content: '';\n z-index: -1;\n pointer-events: none;\n position: absolute;\n width: 100%;\n height: 100%;\n left: 0;\n top: 0;\n\n background-image: linear-gradient(\n to bottom left,\n var(--color-2),\n var(--color-1),\n var(--color-2)\n );\n animation: _mask-running_1j0ct_1 2s linear infinite;\n animation-delay: 1s;\n }\n }\n}\n\n@keyframes _mask-running_1j0ct_1 {\n from {\n transform: translateX(-100%);\n }\n to {\n transform: translateX(100%);\n }\n}\n\n/* 控制栏 */\n._header_1j0ct_99 {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 12px;\n user-select: none;\n\n position: absolute;\n inset: 0;\n\n cursor: pointer;\n flex-shrink: 0; /* 防止 header 被压缩 */\n\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(10px);\n border-radius: var(--border-radius);\n background-clip: padding-box;\n\n box-shadow:\n 0 0 0px 2px rgba(255, 255, 255, 0.4),\n 0 0 5px 1px rgba(255, 255, 255, 0.3);\n\n ._statusSection_1j0ct_121 {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-height: 24px; /* 确保垂直居中 */\n\n ._indicator_1j0ct_128 {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: rgba(255, 255, 255, 0.5);\n flex-shrink: 0;\n animation: none; /* 默认无动画 */\n\n /* 运行状态 - 有动画 */\n &._thinking_1j0ct_137 {\n background: rgb(57, 182, 255);\n animation: _pulse_1j0ct_1 0.8s ease-in-out infinite;\n }\n\n &._tool_executing_1j0ct_142 {\n background: rgb(189, 69, 251);\n animation: _pulse_1j0ct_1 0.6s ease-in-out infinite;\n }\n\n &._retry_1j0ct_147 {\n background: rgb(255, 214, 0);\n animation: _retryPulse_1j0ct_1 1s ease-in-out infinite;\n }\n\n /* 静止状态 - 无动画 */\n &._completed_1j0ct_153,\n &._input_1j0ct_154,\n &._output_1j0ct_155 {\n background: rgb(34, 197, 94);\n animation: none;\n }\n\n &._error_1j0ct_160 {\n background: rgb(239, 68, 68);\n animation: none;\n }\n }\n\n ._statusText_1j0ct_166 {\n color: white;\n font-size: 12px;\n line-height: 1;\n font-weight: 500;\n transition: all 0.3s ease-in-out;\n position: relative;\n overflow: hidden;\n display: flex;\n align-items: center;\n min-height: 24px; /* 确保垂直居中 */\n\n &._fadeOut_1j0ct_178 {\n animation: _statusTextFadeOut_1j0ct_1 0.3s ease forwards;\n }\n\n &._fadeIn_1j0ct_182 {\n animation: _statusTextFadeIn_1j0ct_1 0.3s ease forwards;\n }\n }\n }\n\n ._controls_1j0ct_188 {\n display: flex;\n align-items: center;\n gap: 4px;\n\n ._controlButton_1j0ct_193 {\n width: 24px;\n height: 24px;\n border: none;\n border-radius: 4px;\n background: rgba(255, 255, 255, 0.1);\n color: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n line-height: 1;\n\n &:hover {\n background: rgba(255, 255, 255, 0.2);\n }\n }\n\n ._pauseButton_1j0ct_212 {\n font-weight: 600;\n &._paused_1j0ct_214 {\n background: rgba(34, 197, 94, 0.2); /* 绿色背景表示可以继续 */\n color: rgb(34, 197, 94);\n\n &:hover {\n background: rgba(34, 197, 94, 0.3);\n }\n }\n }\n\n ._stopButton_1j0ct_224 {\n background: rgba(239, 68, 68, 0.2);\n color: rgb(255, 41, 41);\n font-weight: 600;\n\n &:hover {\n background: rgba(239, 68, 68, 0.3);\n }\n }\n }\n}\n\n@keyframes _statusTextFadeIn_1j0ct_1 {\n 0% {\n opacity: 0;\n transform: translateY(5px);\n }\n 100% {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes _statusTextFadeOut_1j0ct_1 {\n 0% {\n opacity: 1;\n transform: translateY(0);\n }\n 100% {\n opacity: 0;\n transform: translateY(-5px);\n }\n}\n\n._historySectionWrapper_1j0ct_258 {\n position: absolute;\n width: var(--history-width);\n bottom: var(--height);\n left: var(--side-space);\n z-index: -2;\n\n padding-top: 0px;\n visibility: collapse;\n overflow: hidden;\n\n transition: all 0.2s;\n\n background: rgba(2, 0, 20, 0.5);\n /* background: rgba(186, 186, 186, 0.2); */\n backdrop-filter: blur(10px);\n\n text-shadow: 0 0 1px rgba(0, 0, 0, 0.2);\n\n border-top-left-radius: calc(var(--border-radius) + 4px);\n border-top-right-radius: calc(var(--border-radius) + 4px);\n\n /* border: 2px solid rgba(255, 255, 255, 0.8); */\n border: 2px solid rgba(255, 255, 255, 0.4);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.6);\n\n /* @media (prefers-color-scheme: dark) {\n box-shadow:\n 0 8px 32px 0 rgba(0, 0, 0, 0.85),\n 0 2px 12px 0 rgba(57, 182, 255, 0.1);\n } */\n\n ._expanded_1j0ct_290 & {\n padding-top: 8px;\n visibility: visible;\n }\n\n ._historySection_1j0ct_258 {\n position: relative;\n overflow-y: auto;\n overscroll-behavior: contain;\n scrollbar-width: none;\n max-height: 0;\n padding-inline: 8px;\n\n transition: max-height 0.2s;\n\n ._expanded_1j0ct_290 & {\n max-height: 400px;\n }\n\n ._historyItem_1j0ct_309 {\n /* backdrop-filter: blur(10px); */\n padding: 8px 10px;\n margin-bottom: 6px;\n background: linear-gradient(135deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.03));\n border-radius: 8px;\n border-left: 2px solid rgba(57, 182, 255, 0.5);\n font-size: 12px;\n color: white;\n /* color: black; */\n line-height: 1.3;\n position: relative;\n overflow: hidden;\n\n /* 微妙的内阴影 */\n box-shadow:\n inset 0 1px 0 rgba(255, 255, 255, 0.1),\n 0 1px 3px rgba(0, 0, 0, 0.1);\n\n &::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 1px;\n background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);\n }\n\n &:hover {\n background: linear-gradient(135deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.06));\n /* transform: translateY(-1px); */\n box-shadow:\n inset 0 1px 0 rgba(255, 255, 255, 0.15),\n 0 2px 4px rgba(0, 0, 0, 0.15);\n }\n\n &:last-child {\n margin-bottom: 10px;\n }\n\n &._completed_1j0ct_153,\n &._input_1j0ct_154,\n &._output_1j0ct_155 {\n border-left-color: rgb(34, 197, 94);\n background: linear-gradient(135deg, rgba(34, 197, 94, 0.1), rgba(34, 197, 94, 0.05));\n }\n\n &._error_1j0ct_160 {\n border-left-color: rgb(239, 68, 68);\n background: linear-gradient(135deg, rgba(239, 68, 68, 0.1), rgba(239, 68, 68, 0.05));\n }\n\n &._retry_1j0ct_147 {\n border-left-color: rgb(255, 214, 0);\n background: linear-gradient(135deg, rgba(255, 214, 0, 0.1), rgba(255, 214, 0, 0.05));\n }\n\n /* 突出显示 done 成功结果 */\n &._doneSuccess_1j0ct_368 {\n background: linear-gradient(\n 135deg,\n rgba(34, 197, 94, 0.25),\n rgba(34, 197, 94, 0.15),\n rgba(34, 197, 94, 0.08)\n );\n border: none;\n border-left: 4px solid rgb(34, 197, 94);\n box-shadow:\n 0 4px 12px rgba(34, 197, 94, 0.3),\n inset 0 1px 0 rgba(255, 255, 255, 0.2),\n 0 0 20px rgba(34, 197, 94, 0.1);\n font-weight: 600;\n color: rgb(220, 252, 231);\n padding: 10px 12px;\n margin-bottom: 8px;\n border-radius: 8px;\n position: relative;\n overflow: hidden;\n\n &::before {\n background: linear-gradient(90deg, transparent, rgba(34, 197, 94, 0.4), transparent);\n }\n\n &::after {\n content: '';\n position: absolute;\n top: 0;\n left: -100%;\n width: 100%;\n height: 100%;\n background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);\n animation: _shimmer_1j0ct_1 2s ease-in-out infinite;\n }\n\n ._historyContent_1j0ct_404 {\n ._statusIcon_1j0ct_405 {\n font-size: 16px;\n animation: _celebrate_1j0ct_1 0.8s ease-in-out;\n filter: drop-shadow(0 2px 4px rgba(34, 197, 94, 0.5));\n }\n }\n }\n\n /* 突出显示 done 失败结果 */\n &._doneError_1j0ct_414 {\n background: linear-gradient(\n 135deg,\n rgba(239, 68, 68, 0.25),\n rgba(239, 68, 68, 0.15),\n rgba(239, 68, 68, 0.08)\n );\n border: none;\n border-left: 4px solid rgb(239, 68, 68);\n box-shadow:\n 0 4px 12px rgba(239, 68, 68, 0.3),\n inset 0 1px 0 rgba(255, 255, 255, 0.2),\n 0 0 20px rgba(239, 68, 68, 0.1);\n font-weight: 600;\n color: rgb(254, 226, 226);\n padding: 10px 12px;\n margin-bottom: 8px;\n border-radius: 8px;\n position: relative;\n overflow: hidden;\n\n &::before {\n background: linear-gradient(90deg, transparent, rgba(239, 68, 68, 0.4), transparent);\n }\n\n ._historyContent_1j0ct_404 {\n ._statusIcon_1j0ct_405 {\n font-size: 16px;\n filter: drop-shadow(0 2px 4px rgba(239, 68, 68, 0.5));\n }\n }\n }\n\n ._historyContent_1j0ct_404 {\n display: flex;\n align-items: center;\n gap: 8px;\n\n word-break: break-all;\n white-space: pre-wrap;\n\n /* overflow-x: auto; */\n\n ._statusIcon_1j0ct_405 {\n font-size: 12px;\n flex-shrink: 0;\n line-height: 1;\n transition: all 0.3s ease;\n }\n }\n\n ._historyMeta_1j0ct_465 {\n font-size: 10px;\n color: rgba(255, 255, 255, 0.6);\n /* color: rgb(61, 61, 61); */\n margin-top: 8px;\n line-height: 1;\n }\n }\n }\n}\n\n/* 动画关键帧 - 更快的闪烁 */\n@keyframes _pulse_1j0ct_1 {\n 0%,\n 100% {\n opacity: 1;\n transform: scale(1);\n }\n 50% {\n opacity: 0.4;\n transform: scale(1.3);\n }\n}\n\n/* 重试动画 - 旋转脉冲 */\n@keyframes _retryPulse_1j0ct_1 {\n 0%,\n 100% {\n opacity: 1;\n transform: scale(1) rotate(0deg);\n }\n 25% {\n opacity: 0.6;\n transform: scale(1.2) rotate(90deg);\n }\n 50% {\n opacity: 0.8;\n transform: scale(1.1) rotate(180deg);\n }\n 75% {\n opacity: 0.6;\n transform: scale(1.2) rotate(270deg);\n }\n}\n\n/* 庆祝动画 */\n@keyframes _celebrate_1j0ct_1 {\n 0%,\n 100% {\n transform: scale(1);\n }\n 25% {\n transform: scale(1.2) rotate(-5deg);\n }\n 75% {\n transform: scale(1.2) rotate(5deg);\n }\n}\n\n/* done 卡片的光泽效果 */\n@keyframes _shimmer_1j0ct_1 {\n 0% {\n left: -100%;\n }\n 100% {\n left: 100%;\n }\n}\n\n/* 输入区域样式 */\n._inputSectionWrapper_1j0ct_535 {\n position: absolute;\n width: var(--history-width);\n top: var(--height);\n left: var(--side-space);\n z-index: -1;\n\n visibility: visible;\n overflow: hidden;\n\n height: 48px;\n\n transition: all 0.2s;\n\n background: rgba(186, 186, 186, 0.2);\n backdrop-filter: blur(10px);\n\n border-bottom-left-radius: calc(var(--border-radius) + 4px);\n border-bottom-right-radius: calc(var(--border-radius) + 4px);\n\n border: 2px solid rgba(255, 255, 255, 0.3);\n box-shadow: 0 1px 16px rgba(0, 0, 0, 0.4);\n\n &._hidden_1j0ct_558 {\n visibility: collapse;\n height: 0;\n }\n\n ._inputSection_1j0ct_535 {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 8px 8px;\n\n ._taskInput_1j0ct_569 {\n flex: 1;\n background: rgba(255, 255, 255, 0.4);\n border: 1px solid rgba(255, 255, 255, 0.3);\n border-radius: 10px;\n padding-inline: 10px;\n color: rgb(20, 20, 20);\n font-size: 12px;\n height: 28px;\n line-height: 1;\n outline: none;\n transition: all 0.2s ease;\n\n /* text-shadow: 0 0 2px rgba(255, 255, 255, 0.8); */\n\n /* border-color: rgba(57, 182, 255, 0.3); */\n\n &::placeholder {\n color: rgb(53, 53, 53);\n }\n\n &:focus {\n background: rgba(255, 255, 255, 0.8);\n border-color: rgba(57, 182, 255, 0.6);\n box-shadow: 0 0 0 2px rgba(57, 182, 255, 0.2);\n }\n }\n }\n}\n._wrapper_1oy2s_1 {\n position: fixed;\n inset: 0;\n z-index: 2147483641; /* 确保在所有元素之上,除了 panel */\n /* pointer-events: none; */\n cursor: not-allowed;\n overflow: hidden;\n\n display: none;\n}\n/* AI 光标样式 */\n._cursor_1vrf3_2 {\n position: absolute;\n width: var(--cursor-size, 75px);\n height: var(--cursor-size, 75px);\n pointer-events: none;\n z-index: 10000;\n transform: translate(-30%, -30%);\n\n animation: _cursor-enter_1vrf3_1 300ms ease-out forwards;\n}\n\n._cursorBorder_1vrf3_13 {\n position: absolute;\n inset: 0;\n background: linear-gradient(45deg, rgb(57, 182, 255), rgb(189, 69, 251));\n mask-image: url(https://img.alicdn.com/imgextra/i1/O1CN01YHLVYR1LvqWIyo5kH_!!6000000001362-2-tps-202-202.png);\n mask-size: 100% 100%;\n mask-repeat: no-repeat;\n animation: _cursor-breathe_1vrf3_1 2s ease-in-out infinite;\n}\n\n._cursorFilling_1vrf3_23 {\n position: absolute;\n inset: 0;\n background: url(https://img.alicdn.com/imgextra/i3/O1CN01JZOqOS1Tu1sIKbPLW_!!6000000002441-2-tps-202-202.png);\n background-size: 100% 100%;\n background-repeat: no-repeat;\n}\n\n._cursorRipple_1vrf3_31 {\n position: absolute;\n inset: 0;\n pointer-events: none;\n}\n\n._cursor_1vrf3_2._clicking_1vrf3_37 ._cursorRipple_1vrf3_31::after {\n content: '';\n position: absolute;\n width: 100%;\n height: 100%;\n left: -30%;\n top: -30%;\n border: 4px solid rgba(57, 182, 255, 1);\n border-radius: 50%;\n animation: _cursor-ripple_1vrf3_1 300ms ease-out forwards;\n}\n\n/* 光标动画关键帧 */\n@keyframes _cursor-breathe_1vrf3_1 {\n 0%,\n 100% {\n transform: scale(1);\n opacity: 0.9;\n }\n 50% {\n transform: scale(1.05);\n opacity: 1;\n }\n}\n\n@keyframes _cursor-rotate_1vrf3_1 {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n\n@keyframes _cursor-enter_1vrf3_1 {\n 0% {\n transform: translate(-30%, -30%) scale(0.5);\n opacity: 0;\n }\n 100% {\n transform: translate(-30%, -30%) scale(1);\n opacity: 1;\n }\n}\n\n@keyframes _cursor-ripple_1vrf3_1 {\n 0% {\n transform: scale(0);\n opacity: 1;\n }\n 100% {\n transform: scale(2);\n opacity: 0;\n }\n}"));
|
|
6
|
+
elementStyle.appendChild(document.createTextNode("._wrapper_1j0ct_1 {\n position: fixed;\n bottom: 100px;\n left: 50%;\n transform: translateX(-50%) translateY(20px);\n opacity: 0;\n z-index: 2147483642; /* 比 SimulatorMask 高一层 */\n box-sizing: border-box;\n\n overflow: visible;\n\n * {\n box-sizing: border-box;\n }\n\n --width: 360px;\n --height: 40px;\n --border-radius: 12px;\n\n --side-space: 12px; /* 控制栏两侧的间距 */\n --history-width: calc(var(--width) - var(--side-space) * 2);\n\n --color-1: rgb(57, 182, 255);\n --color-2: rgb(189, 69, 251);\n --color-3: rgb(255, 87, 51);\n --color-4: rgb(255, 214, 0);\n\n width: var(--width);\n height: var(--height);\n\n transition: all 0.3s ease-in-out;\n\n /* 响应式设计 */\n @media (max-width: 480px) {\n width: calc(100vw - 40px);\n --width: calc(100vw - 40px);\n }\n\n ._background_1j0ct_39 {\n position: absolute;\n inset: -2px -8px;\n border-radius: calc(var(--border-radius) + 4px);\n filter: blur(16px);\n overflow: hidden;\n /* mix-blend-mode: lighten; */\n /* display: none; */\n\n &::before {\n content: '';\n z-index: -1;\n pointer-events: none;\n position: absolute;\n width: 100%;\n height: 100%;\n /* left: -100%; */\n left: 0;\n top: 0;\n\n background-image: linear-gradient(\n to bottom left,\n var(--color-1),\n var(--color-2),\n var(--color-1)\n );\n animation: _mask-running_1j0ct_1 2s linear infinite;\n }\n &::after {\n content: '';\n z-index: -1;\n pointer-events: none;\n position: absolute;\n width: 100%;\n height: 100%;\n left: 0;\n top: 0;\n\n background-image: linear-gradient(\n to bottom left,\n var(--color-2),\n var(--color-1),\n var(--color-2)\n );\n animation: _mask-running_1j0ct_1 2s linear infinite;\n animation-delay: 1s;\n }\n }\n}\n\n@keyframes _mask-running_1j0ct_1 {\n from {\n transform: translateX(-100%);\n }\n to {\n transform: translateX(100%);\n }\n}\n\n/* 控制栏 */\n._header_1j0ct_99 {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 12px;\n user-select: none;\n\n position: absolute;\n inset: 0;\n\n cursor: pointer;\n flex-shrink: 0; /* 防止 header 被压缩 */\n\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(10px);\n border-radius: var(--border-radius);\n background-clip: padding-box;\n\n box-shadow:\n 0 0 0px 2px rgba(255, 255, 255, 0.4),\n 0 0 5px 1px rgba(255, 255, 255, 0.3);\n\n ._statusSection_1j0ct_121 {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-height: 24px; /* 确保垂直居中 */\n\n ._indicator_1j0ct_128 {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: rgba(255, 255, 255, 0.5);\n flex-shrink: 0;\n animation: none; /* 默认无动画 */\n\n /* 运行状态 - 有动画 */\n &._thinking_1j0ct_137 {\n background: rgb(57, 182, 255);\n animation: _pulse_1j0ct_1 0.8s ease-in-out infinite;\n }\n\n &._tool_executing_1j0ct_142 {\n background: rgb(189, 69, 251);\n animation: _pulse_1j0ct_1 0.6s ease-in-out infinite;\n }\n\n &._retry_1j0ct_147 {\n background: rgb(255, 214, 0);\n animation: _retryPulse_1j0ct_1 1s ease-in-out infinite;\n }\n\n /* 静止状态 - 无动画 */\n &._completed_1j0ct_153,\n &._input_1j0ct_154,\n &._output_1j0ct_155 {\n background: rgb(34, 197, 94);\n animation: none;\n }\n\n &._error_1j0ct_160 {\n background: rgb(239, 68, 68);\n animation: none;\n }\n }\n\n ._statusText_1j0ct_166 {\n color: white;\n font-size: 12px;\n line-height: 1;\n font-weight: 500;\n transition: all 0.3s ease-in-out;\n position: relative;\n overflow: hidden;\n display: flex;\n align-items: center;\n min-height: 24px; /* 确保垂直居中 */\n\n &._fadeOut_1j0ct_178 {\n animation: _statusTextFadeOut_1j0ct_1 0.3s ease forwards;\n }\n\n &._fadeIn_1j0ct_182 {\n animation: _statusTextFadeIn_1j0ct_1 0.3s ease forwards;\n }\n }\n }\n\n ._controls_1j0ct_188 {\n display: flex;\n align-items: center;\n gap: 4px;\n\n ._controlButton_1j0ct_193 {\n width: 24px;\n height: 24px;\n border: none;\n border-radius: 4px;\n background: rgba(255, 255, 255, 0.1);\n color: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n line-height: 1;\n\n &:hover {\n background: rgba(255, 255, 255, 0.2);\n }\n }\n\n ._pauseButton_1j0ct_212 {\n font-weight: 600;\n &._paused_1j0ct_214 {\n background: rgba(34, 197, 94, 0.2); /* 绿色背景表示可以继续 */\n color: rgb(34, 197, 94);\n\n &:hover {\n background: rgba(34, 197, 94, 0.3);\n }\n }\n }\n\n ._stopButton_1j0ct_224 {\n background: rgba(239, 68, 68, 0.2);\n color: rgb(255, 41, 41);\n font-weight: 600;\n\n &:hover {\n background: rgba(239, 68, 68, 0.3);\n }\n }\n }\n}\n\n@keyframes _statusTextFadeIn_1j0ct_1 {\n 0% {\n opacity: 0;\n transform: translateY(5px);\n }\n 100% {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes _statusTextFadeOut_1j0ct_1 {\n 0% {\n opacity: 1;\n transform: translateY(0);\n }\n 100% {\n opacity: 0;\n transform: translateY(-5px);\n }\n}\n\n._historySectionWrapper_1j0ct_258 {\n position: absolute;\n width: var(--history-width);\n bottom: var(--height);\n left: var(--side-space);\n z-index: -2;\n\n padding-top: 0px;\n visibility: collapse;\n overflow: hidden;\n\n transition: all 0.2s;\n\n background: rgba(2, 0, 20, 0.5);\n /* background: rgba(186, 186, 186, 0.2); */\n backdrop-filter: blur(10px);\n\n text-shadow: 0 0 1px rgba(0, 0, 0, 0.2);\n\n border-top-left-radius: calc(var(--border-radius) + 4px);\n border-top-right-radius: calc(var(--border-radius) + 4px);\n\n /* border: 2px solid rgba(255, 255, 255, 0.8); */\n border: 2px solid rgba(255, 255, 255, 0.4);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.6);\n\n /* @media (prefers-color-scheme: dark) {\n box-shadow:\n 0 8px 32px 0 rgba(0, 0, 0, 0.85),\n 0 2px 12px 0 rgba(57, 182, 255, 0.1);\n } */\n\n ._expanded_1j0ct_290 & {\n padding-top: 8px;\n visibility: visible;\n }\n\n ._historySection_1j0ct_258 {\n position: relative;\n overflow-y: auto;\n overscroll-behavior: contain;\n scrollbar-width: none;\n max-height: 0;\n padding-inline: 8px;\n\n transition: max-height 0.2s;\n\n ._expanded_1j0ct_290 & {\n max-height: 400px;\n }\n\n ._historyItem_1j0ct_309 {\n /* backdrop-filter: blur(10px); */\n padding: 8px 10px;\n margin-bottom: 6px;\n background: linear-gradient(135deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.03));\n border-radius: 8px;\n border-left: 2px solid rgba(57, 182, 255, 0.5);\n font-size: 12px;\n color: white;\n /* color: black; */\n line-height: 1.3;\n position: relative;\n overflow: hidden;\n\n /* 微妙的内阴影 */\n box-shadow:\n inset 0 1px 0 rgba(255, 255, 255, 0.1),\n 0 1px 3px rgba(0, 0, 0, 0.1);\n\n &::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 1px;\n background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);\n }\n\n &:hover {\n background: linear-gradient(135deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.06));\n /* transform: translateY(-1px); */\n box-shadow:\n inset 0 1px 0 rgba(255, 255, 255, 0.15),\n 0 2px 4px rgba(0, 0, 0, 0.15);\n }\n\n &:last-child {\n margin-bottom: 10px;\n }\n\n &._completed_1j0ct_153,\n &._input_1j0ct_154,\n &._output_1j0ct_155 {\n border-left-color: rgb(34, 197, 94);\n background: linear-gradient(135deg, rgba(34, 197, 94, 0.1), rgba(34, 197, 94, 0.05));\n }\n\n &._error_1j0ct_160 {\n border-left-color: rgb(239, 68, 68);\n background: linear-gradient(135deg, rgba(239, 68, 68, 0.1), rgba(239, 68, 68, 0.05));\n }\n\n &._retry_1j0ct_147 {\n border-left-color: rgb(255, 214, 0);\n background: linear-gradient(135deg, rgba(255, 214, 0, 0.1), rgba(255, 214, 0, 0.05));\n }\n\n /* 突出显示 done 成功结果 */\n &._doneSuccess_1j0ct_368 {\n background: linear-gradient(\n 135deg,\n rgba(34, 197, 94, 0.25),\n rgba(34, 197, 94, 0.15),\n rgba(34, 197, 94, 0.08)\n );\n border: none;\n border-left: 4px solid rgb(34, 197, 94);\n box-shadow:\n 0 4px 12px rgba(34, 197, 94, 0.3),\n inset 0 1px 0 rgba(255, 255, 255, 0.2),\n 0 0 20px rgba(34, 197, 94, 0.1);\n font-weight: 600;\n color: rgb(220, 252, 231);\n padding: 10px 12px;\n margin-bottom: 8px;\n border-radius: 8px;\n position: relative;\n overflow: hidden;\n\n &::before {\n background: linear-gradient(90deg, transparent, rgba(34, 197, 94, 0.4), transparent);\n }\n\n &::after {\n content: '';\n position: absolute;\n top: 0;\n left: -100%;\n width: 100%;\n height: 100%;\n background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);\n animation: _shimmer_1j0ct_1 2s ease-in-out infinite;\n }\n\n ._historyContent_1j0ct_404 {\n ._statusIcon_1j0ct_405 {\n font-size: 16px;\n animation: _celebrate_1j0ct_1 0.8s ease-in-out;\n filter: drop-shadow(0 2px 4px rgba(34, 197, 94, 0.5));\n }\n }\n }\n\n /* 突出显示 done 失败结果 */\n &._doneError_1j0ct_414 {\n background: linear-gradient(\n 135deg,\n rgba(239, 68, 68, 0.25),\n rgba(239, 68, 68, 0.15),\n rgba(239, 68, 68, 0.08)\n );\n border: none;\n border-left: 4px solid rgb(239, 68, 68);\n box-shadow:\n 0 4px 12px rgba(239, 68, 68, 0.3),\n inset 0 1px 0 rgba(255, 255, 255, 0.2),\n 0 0 20px rgba(239, 68, 68, 0.1);\n font-weight: 600;\n color: rgb(254, 226, 226);\n padding: 10px 12px;\n margin-bottom: 8px;\n border-radius: 8px;\n position: relative;\n overflow: hidden;\n\n &::before {\n background: linear-gradient(90deg, transparent, rgba(239, 68, 68, 0.4), transparent);\n }\n\n ._historyContent_1j0ct_404 {\n ._statusIcon_1j0ct_405 {\n font-size: 16px;\n filter: drop-shadow(0 2px 4px rgba(239, 68, 68, 0.5));\n }\n }\n }\n\n ._historyContent_1j0ct_404 {\n display: flex;\n align-items: center;\n gap: 8px;\n\n word-break: break-all;\n white-space: pre-wrap;\n\n /* overflow-x: auto; */\n\n ._statusIcon_1j0ct_405 {\n font-size: 12px;\n flex-shrink: 0;\n line-height: 1;\n transition: all 0.3s ease;\n }\n }\n\n ._historyMeta_1j0ct_465 {\n font-size: 10px;\n color: rgba(255, 255, 255, 0.6);\n /* color: rgb(61, 61, 61); */\n margin-top: 8px;\n line-height: 1;\n }\n }\n }\n}\n\n/* 动画关键帧 - 更快的闪烁 */\n@keyframes _pulse_1j0ct_1 {\n 0%,\n 100% {\n opacity: 1;\n transform: scale(1);\n }\n 50% {\n opacity: 0.4;\n transform: scale(1.3);\n }\n}\n\n/* 重试动画 - 旋转脉冲 */\n@keyframes _retryPulse_1j0ct_1 {\n 0%,\n 100% {\n opacity: 1;\n transform: scale(1) rotate(0deg);\n }\n 25% {\n opacity: 0.6;\n transform: scale(1.2) rotate(90deg);\n }\n 50% {\n opacity: 0.8;\n transform: scale(1.1) rotate(180deg);\n }\n 75% {\n opacity: 0.6;\n transform: scale(1.2) rotate(270deg);\n }\n}\n\n/* 庆祝动画 */\n@keyframes _celebrate_1j0ct_1 {\n 0%,\n 100% {\n transform: scale(1);\n }\n 25% {\n transform: scale(1.2) rotate(-5deg);\n }\n 75% {\n transform: scale(1.2) rotate(5deg);\n }\n}\n\n/* done 卡片的光泽效果 */\n@keyframes _shimmer_1j0ct_1 {\n 0% {\n left: -100%;\n }\n 100% {\n left: 100%;\n }\n}\n\n/* 输入区域样式 */\n._inputSectionWrapper_1j0ct_535 {\n position: absolute;\n width: var(--history-width);\n top: var(--height);\n left: var(--side-space);\n z-index: -1;\n\n visibility: visible;\n overflow: hidden;\n\n height: 48px;\n\n transition: all 0.2s;\n\n background: rgba(186, 186, 186, 0.2);\n backdrop-filter: blur(10px);\n\n border-bottom-left-radius: calc(var(--border-radius) + 4px);\n border-bottom-right-radius: calc(var(--border-radius) + 4px);\n\n border: 2px solid rgba(255, 255, 255, 0.3);\n box-shadow: 0 1px 16px rgba(0, 0, 0, 0.4);\n\n &._hidden_1j0ct_558 {\n visibility: collapse;\n height: 0;\n }\n\n ._inputSection_1j0ct_535 {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 8px 8px;\n\n ._taskInput_1j0ct_569 {\n flex: 1;\n background: rgba(255, 255, 255, 0.4);\n border: 1px solid rgba(255, 255, 255, 0.3);\n border-radius: 10px;\n padding-inline: 10px;\n color: rgb(20, 20, 20);\n font-size: 12px;\n height: 28px;\n line-height: 1;\n outline: none;\n transition: all 0.2s ease;\n\n /* text-shadow: 0 0 2px rgba(255, 255, 255, 0.8); */\n\n /* border-color: rgba(57, 182, 255, 0.3); */\n\n &::placeholder {\n color: rgb(53, 53, 53);\n }\n\n &:focus {\n background: rgba(255, 255, 255, 0.8);\n border-color: rgba(57, 182, 255, 0.6);\n box-shadow: 0 0 0 2px rgba(57, 182, 255, 0.2);\n }\n }\n }\n}"));
|
|
7
7
|
document.head.appendChild(elementStyle);
|
|
8
8
|
}
|
|
9
9
|
} catch (e) {
|
|
@@ -14,16 +14,13 @@ var __defProp = Object.defineProperty;
|
|
|
14
14
|
var __typeError = (msg) => {
|
|
15
15
|
throw TypeError(msg);
|
|
16
16
|
};
|
|
17
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
18
17
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
19
|
-
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
20
18
|
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
21
19
|
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
22
20
|
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
21
|
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
24
22
|
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
25
|
-
var _wrapper, _indicator, _statusText, _historySection, _expandButton, _pauseButton, _stopButton, _inputSection, _taskInput, _state, _isExpanded, _config, _i18n, _userAnswerResolver, _isWaitingForUserAnswer, _headerUpdateTimer, _pendingHeaderText, _isAnimating, _Panel_instances, toStepData_fn, getToolExecutingText_fn, getToolCompletedText_fn, updateInternal_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
|
|
26
|
-
import { Motion } from "ai-motion";
|
|
23
|
+
var _wrapper, _indicator, _statusText, _historySection, _expandButton, _pauseButton, _stopButton, _inputSection, _taskInput, _state, _isExpanded, _config, _i18n, _userAnswerResolver, _isWaitingForUserAnswer, _headerUpdateTimer, _pendingHeaderText, _isAnimating, _Panel_instances, toStepData_fn, getToolExecutingText_fn, getToolCompletedText_fn, updateInternal_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;
|
|
27
24
|
const _UIState = class _UIState {
|
|
28
25
|
steps = [];
|
|
29
26
|
currentStep = null;
|
|
@@ -224,7 +221,7 @@ function truncate(text, maxLength) {
|
|
|
224
221
|
return text;
|
|
225
222
|
}
|
|
226
223
|
__name(truncate, "truncate");
|
|
227
|
-
const wrapper
|
|
224
|
+
const wrapper = "_wrapper_1j0ct_1";
|
|
228
225
|
const background = "_background_1j0ct_39";
|
|
229
226
|
const header = "_header_1j0ct_99";
|
|
230
227
|
const pulse = "_pulse_1j0ct_1";
|
|
@@ -263,8 +260,8 @@ const inputSectionWrapper = "_inputSectionWrapper_1j0ct_535";
|
|
|
263
260
|
const hidden = "_hidden_1j0ct_558";
|
|
264
261
|
const inputSection = "_inputSection_1j0ct_535";
|
|
265
262
|
const taskInput = "_taskInput_1j0ct_569";
|
|
266
|
-
const styles
|
|
267
|
-
wrapper
|
|
263
|
+
const styles = {
|
|
264
|
+
wrapper,
|
|
268
265
|
"mask-running": "_mask-running_1j0ct_1",
|
|
269
266
|
background,
|
|
270
267
|
header,
|
|
@@ -329,14 +326,14 @@ const _Panel = class _Panel {
|
|
|
329
326
|
__privateSet(this, _config, config);
|
|
330
327
|
__privateSet(this, _i18n, new I18n(config.language ?? "en-US"));
|
|
331
328
|
__privateSet(this, _wrapper, __privateMethod(this, _Panel_instances, createWrapper_fn).call(this));
|
|
332
|
-
__privateSet(this, _indicator, __privateGet(this, _wrapper).querySelector(`.${styles
|
|
333
|
-
__privateSet(this, _statusText, __privateGet(this, _wrapper).querySelector(`.${styles
|
|
334
|
-
__privateSet(this, _historySection, __privateGet(this, _wrapper).querySelector(`.${styles
|
|
335
|
-
__privateSet(this, _expandButton, __privateGet(this, _wrapper).querySelector(`.${styles
|
|
336
|
-
__privateSet(this, _pauseButton, __privateGet(this, _wrapper).querySelector(`.${styles
|
|
337
|
-
__privateSet(this, _stopButton, __privateGet(this, _wrapper).querySelector(`.${styles
|
|
338
|
-
__privateSet(this, _inputSection, __privateGet(this, _wrapper).querySelector(`.${styles
|
|
339
|
-
__privateSet(this, _taskInput, __privateGet(this, _wrapper).querySelector(`.${styles
|
|
329
|
+
__privateSet(this, _indicator, __privateGet(this, _wrapper).querySelector(`.${styles.indicator}`));
|
|
330
|
+
__privateSet(this, _statusText, __privateGet(this, _wrapper).querySelector(`.${styles.statusText}`));
|
|
331
|
+
__privateSet(this, _historySection, __privateGet(this, _wrapper).querySelector(`.${styles.historySection}`));
|
|
332
|
+
__privateSet(this, _expandButton, __privateGet(this, _wrapper).querySelector(`.${styles.expandButton}`));
|
|
333
|
+
__privateSet(this, _pauseButton, __privateGet(this, _wrapper).querySelector(`.${styles.pauseButton}`));
|
|
334
|
+
__privateSet(this, _stopButton, __privateGet(this, _wrapper).querySelector(`.${styles.stopButton}`));
|
|
335
|
+
__privateSet(this, _inputSection, __privateGet(this, _wrapper).querySelector(`.${styles.inputSectionWrapper}`));
|
|
336
|
+
__privateSet(this, _taskInput, __privateGet(this, _wrapper).querySelector(`.${styles.taskInput}`));
|
|
340
337
|
__privateMethod(this, _Panel_instances, setupEventListeners_fn).call(this);
|
|
341
338
|
__privateMethod(this, _Panel_instances, startHeaderUpdateLoop_fn).call(this);
|
|
342
339
|
__privateMethod(this, _Panel_instances, showInputArea_fn).call(this);
|
|
@@ -556,11 +553,11 @@ updatePauseButton_fn = /* @__PURE__ */ __name(function() {
|
|
|
556
553
|
if (paused2) {
|
|
557
554
|
__privateGet(this, _pauseButton).textContent = "▶";
|
|
558
555
|
__privateGet(this, _pauseButton).title = __privateGet(this, _i18n).t("ui.panel.continue");
|
|
559
|
-
__privateGet(this, _pauseButton).classList.add(styles
|
|
556
|
+
__privateGet(this, _pauseButton).classList.add(styles.paused);
|
|
560
557
|
} else {
|
|
561
558
|
__privateGet(this, _pauseButton).textContent = "⏸︎";
|
|
562
559
|
__privateGet(this, _pauseButton).title = __privateGet(this, _i18n).t("ui.panel.pause");
|
|
563
|
-
__privateGet(this, _pauseButton).classList.remove(styles
|
|
560
|
+
__privateGet(this, _pauseButton).classList.remove(styles.paused);
|
|
564
561
|
}
|
|
565
562
|
}, "#updatePauseButton");
|
|
566
563
|
/**
|
|
@@ -606,7 +603,7 @@ handleUserAnswer_fn = /* @__PURE__ */ __name(function(input2) {
|
|
|
606
603
|
showInputArea_fn = /* @__PURE__ */ __name(function(placeholder) {
|
|
607
604
|
__privateGet(this, _taskInput).value = "";
|
|
608
605
|
__privateGet(this, _taskInput).placeholder = placeholder || __privateGet(this, _i18n).t("ui.panel.taskInput");
|
|
609
|
-
__privateGet(this, _inputSection).classList.remove(styles
|
|
606
|
+
__privateGet(this, _inputSection).classList.remove(styles.hidden);
|
|
610
607
|
setTimeout(() => {
|
|
611
608
|
__privateGet(this, _taskInput).focus();
|
|
612
609
|
}, 100);
|
|
@@ -615,7 +612,7 @@ showInputArea_fn = /* @__PURE__ */ __name(function(placeholder) {
|
|
|
615
612
|
* Hide input area
|
|
616
613
|
*/
|
|
617
614
|
hideInputArea_fn = /* @__PURE__ */ __name(function() {
|
|
618
|
-
__privateGet(this, _inputSection).classList.add(styles
|
|
615
|
+
__privateGet(this, _inputSection).classList.add(styles.hidden);
|
|
619
616
|
}, "#hideInputArea");
|
|
620
617
|
/**
|
|
621
618
|
* Check if input area should be shown
|
|
@@ -632,12 +629,12 @@ shouldShowInputArea_fn = /* @__PURE__ */ __name(function() {
|
|
|
632
629
|
createWrapper_fn = /* @__PURE__ */ __name(function() {
|
|
633
630
|
const wrapper2 = document.createElement("div");
|
|
634
631
|
wrapper2.id = "page-agent-runtime_agent-panel";
|
|
635
|
-
wrapper2.className = `${styles
|
|
632
|
+
wrapper2.className = `${styles.wrapper} ${styles.collapsed}`;
|
|
636
633
|
wrapper2.setAttribute("data-browser-use-ignore", "true");
|
|
637
634
|
wrapper2.innerHTML = `
|
|
638
|
-
<div class="${styles
|
|
639
|
-
<div class="${styles
|
|
640
|
-
<div class="${styles
|
|
635
|
+
<div class="${styles.background}"></div>
|
|
636
|
+
<div class="${styles.historySectionWrapper}">
|
|
637
|
+
<div class="${styles.historySection}">
|
|
641
638
|
${__privateMethod(this, _Panel_instances, createHistoryItem_fn).call(this, {
|
|
642
639
|
id: "placeholder",
|
|
643
640
|
stepNumber: 0,
|
|
@@ -647,28 +644,28 @@ createWrapper_fn = /* @__PURE__ */ __name(function() {
|
|
|
647
644
|
})}
|
|
648
645
|
</div>
|
|
649
646
|
</div>
|
|
650
|
-
<div class="${styles
|
|
651
|
-
<div class="${styles
|
|
652
|
-
<div class="${styles
|
|
653
|
-
<div class="${styles
|
|
647
|
+
<div class="${styles.header}">
|
|
648
|
+
<div class="${styles.statusSection}">
|
|
649
|
+
<div class="${styles.indicator} ${styles.thinking}"></div>
|
|
650
|
+
<div class="${styles.statusText}">${__privateGet(this, _i18n).t("ui.panel.ready")}</div>
|
|
654
651
|
</div>
|
|
655
|
-
<div class="${styles
|
|
656
|
-
<button class="${styles
|
|
652
|
+
<div class="${styles.controls}">
|
|
653
|
+
<button class="${styles.controlButton} ${styles.expandButton}" title="${__privateGet(this, _i18n).t("ui.panel.expand")}">
|
|
657
654
|
▼
|
|
658
655
|
</button>
|
|
659
|
-
<button class="${styles
|
|
656
|
+
<button class="${styles.controlButton} ${styles.pauseButton}" title="${__privateGet(this, _i18n).t("ui.panel.pause")}">
|
|
660
657
|
⏸︎
|
|
661
658
|
</button>
|
|
662
|
-
<button class="${styles
|
|
659
|
+
<button class="${styles.controlButton} ${styles.stopButton}" title="${__privateGet(this, _i18n).t("ui.panel.stop")}">
|
|
663
660
|
X
|
|
664
661
|
</button>
|
|
665
662
|
</div>
|
|
666
663
|
</div>
|
|
667
|
-
<div class="${styles
|
|
668
|
-
<div class="${styles
|
|
664
|
+
<div class="${styles.inputSectionWrapper} ${styles.hidden}">
|
|
665
|
+
<div class="${styles.inputSection}">
|
|
669
666
|
<input
|
|
670
667
|
type="text"
|
|
671
|
-
class="${styles
|
|
668
|
+
class="${styles.taskInput}"
|
|
672
669
|
maxlength="200"
|
|
673
670
|
/>
|
|
674
671
|
</div>
|
|
@@ -678,9 +675,9 @@ createWrapper_fn = /* @__PURE__ */ __name(function() {
|
|
|
678
675
|
return wrapper2;
|
|
679
676
|
}, "#createWrapper");
|
|
680
677
|
setupEventListeners_fn = /* @__PURE__ */ __name(function() {
|
|
681
|
-
const header2 = this.wrapper.querySelector(`.${styles
|
|
678
|
+
const header2 = this.wrapper.querySelector(`.${styles.header}`);
|
|
682
679
|
header2.addEventListener("click", (e) => {
|
|
683
|
-
if (e.target.closest(`.${styles
|
|
680
|
+
if (e.target.closest(`.${styles.controlButton}`)) {
|
|
684
681
|
return;
|
|
685
682
|
}
|
|
686
683
|
__privateMethod(this, _Panel_instances, toggle_fn).call(this);
|
|
@@ -717,14 +714,14 @@ toggle_fn = /* @__PURE__ */ __name(function() {
|
|
|
717
714
|
}, "#toggle");
|
|
718
715
|
expand_fn = /* @__PURE__ */ __name(function() {
|
|
719
716
|
__privateSet(this, _isExpanded, true);
|
|
720
|
-
this.wrapper.classList.remove(styles
|
|
721
|
-
this.wrapper.classList.add(styles
|
|
717
|
+
this.wrapper.classList.remove(styles.collapsed);
|
|
718
|
+
this.wrapper.classList.add(styles.expanded);
|
|
722
719
|
__privateGet(this, _expandButton).textContent = "▲";
|
|
723
720
|
}, "#expand");
|
|
724
721
|
collapse_fn = /* @__PURE__ */ __name(function() {
|
|
725
722
|
__privateSet(this, _isExpanded, false);
|
|
726
|
-
this.wrapper.classList.remove(styles
|
|
727
|
-
this.wrapper.classList.add(styles
|
|
723
|
+
this.wrapper.classList.remove(styles.expanded);
|
|
724
|
+
this.wrapper.classList.add(styles.collapsed);
|
|
728
725
|
__privateGet(this, _expandButton).textContent = "▼";
|
|
729
726
|
}, "#collapse");
|
|
730
727
|
/**
|
|
@@ -764,20 +761,20 @@ checkAndUpdateHeader_fn = /* @__PURE__ */ __name(function() {
|
|
|
764
761
|
*/
|
|
765
762
|
animateTextChange_fn = /* @__PURE__ */ __name(function(newText) {
|
|
766
763
|
__privateSet(this, _isAnimating, true);
|
|
767
|
-
__privateGet(this, _statusText).classList.add(styles
|
|
764
|
+
__privateGet(this, _statusText).classList.add(styles.fadeOut);
|
|
768
765
|
setTimeout(() => {
|
|
769
766
|
__privateGet(this, _statusText).textContent = newText;
|
|
770
|
-
__privateGet(this, _statusText).classList.remove(styles
|
|
771
|
-
__privateGet(this, _statusText).classList.add(styles
|
|
767
|
+
__privateGet(this, _statusText).classList.remove(styles.fadeOut);
|
|
768
|
+
__privateGet(this, _statusText).classList.add(styles.fadeIn);
|
|
772
769
|
setTimeout(() => {
|
|
773
|
-
__privateGet(this, _statusText).classList.remove(styles
|
|
770
|
+
__privateGet(this, _statusText).classList.remove(styles.fadeIn);
|
|
774
771
|
__privateSet(this, _isAnimating, false);
|
|
775
772
|
}, 300);
|
|
776
773
|
}, 150);
|
|
777
774
|
}, "#animateTextChange");
|
|
778
775
|
updateStatusIndicator_fn = /* @__PURE__ */ __name(function(type) {
|
|
779
|
-
__privateGet(this, _indicator).className = styles
|
|
780
|
-
__privateGet(this, _indicator).classList.add(styles
|
|
776
|
+
__privateGet(this, _indicator).className = styles.indicator;
|
|
777
|
+
__privateGet(this, _indicator).classList.add(styles[type]);
|
|
781
778
|
}, "#updateStatusIndicator");
|
|
782
779
|
updateHistory_fn = /* @__PURE__ */ __name(function() {
|
|
783
780
|
const steps = __privateGet(this, _state).getAllSteps();
|
|
@@ -803,25 +800,25 @@ createHistoryItem_fn = /* @__PURE__ */ __name(function(step) {
|
|
|
803
800
|
const failureKeyword = __privateGet(this, _i18n).t("ui.tools.resultFailure");
|
|
804
801
|
const errorKeyword = __privateGet(this, _i18n).t("ui.tools.resultError");
|
|
805
802
|
const isSuccess = !step.toolResult || !step.toolResult.includes(failureKeyword) && !step.toolResult.includes(errorKeyword);
|
|
806
|
-
typeClass = isSuccess ? styles
|
|
803
|
+
typeClass = isSuccess ? styles.doneSuccess : styles.doneError;
|
|
807
804
|
statusIcon2 = isSuccess ? "🎉" : "❌";
|
|
808
805
|
} else {
|
|
809
|
-
typeClass = styles
|
|
806
|
+
typeClass = styles.completed;
|
|
810
807
|
statusIcon2 = "✅";
|
|
811
808
|
}
|
|
812
809
|
} else if (step.type === "error") {
|
|
813
|
-
typeClass = styles
|
|
810
|
+
typeClass = styles.error;
|
|
814
811
|
statusIcon2 = "❌";
|
|
815
812
|
} else if (step.type === "tool_executing") {
|
|
816
813
|
statusIcon2 = "⚙️";
|
|
817
814
|
} else if (step.type === "output") {
|
|
818
|
-
typeClass = styles
|
|
815
|
+
typeClass = styles.output;
|
|
819
816
|
statusIcon2 = "🤖";
|
|
820
817
|
} else if (step.type === "input") {
|
|
821
|
-
typeClass = styles
|
|
818
|
+
typeClass = styles.input;
|
|
822
819
|
statusIcon2 = "🎯";
|
|
823
820
|
} else if (step.type === "retry") {
|
|
824
|
-
typeClass = styles
|
|
821
|
+
typeClass = styles.retry;
|
|
825
822
|
statusIcon2 = "🔄";
|
|
826
823
|
} else {
|
|
827
824
|
statusIcon2 = "🧠";
|
|
@@ -834,12 +831,12 @@ createHistoryItem_fn = /* @__PURE__ */ __name(function(step) {
|
|
|
834
831
|
// Explicitly pass empty string to replace template
|
|
835
832
|
});
|
|
836
833
|
return `
|
|
837
|
-
<div class="${styles
|
|
838
|
-
<div class="${styles
|
|
839
|
-
<span class="${styles
|
|
834
|
+
<div class="${styles.historyItem} ${typeClass}">
|
|
835
|
+
<div class="${styles.historyContent}">
|
|
836
|
+
<span class="${styles.statusIcon}">${statusIcon2}</span>
|
|
840
837
|
<span>${step.displayText}</span>
|
|
841
838
|
</div>
|
|
842
|
-
<div class="${styles
|
|
839
|
+
<div class="${styles.historyMeta}">
|
|
843
840
|
${stepLabel}
|
|
844
841
|
</div>
|
|
845
842
|
</div>
|
|
@@ -847,231 +844,9 @@ createHistoryItem_fn = /* @__PURE__ */ __name(function(step) {
|
|
|
847
844
|
}, "#createHistoryItem");
|
|
848
845
|
__name(_Panel, "Panel");
|
|
849
846
|
let Panel = _Panel;
|
|
850
|
-
function hasDarkModeClass() {
|
|
851
|
-
const DEFAULT_DARK_MODE_CLASSES = ["dark", "dark-mode", "theme-dark", "night", "night-mode"];
|
|
852
|
-
const htmlElement = document.documentElement;
|
|
853
|
-
const bodyElement = document.body || document.documentElement;
|
|
854
|
-
for (const className of DEFAULT_DARK_MODE_CLASSES) {
|
|
855
|
-
if (htmlElement.classList.contains(className) || bodyElement?.classList.contains(className)) {
|
|
856
|
-
return true;
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
const darkThemeAttribute = htmlElement.getAttribute("data-theme");
|
|
860
|
-
if (darkThemeAttribute?.toLowerCase().includes("dark")) {
|
|
861
|
-
return true;
|
|
862
|
-
}
|
|
863
|
-
return false;
|
|
864
|
-
}
|
|
865
|
-
__name(hasDarkModeClass, "hasDarkModeClass");
|
|
866
|
-
function parseRgbColor(colorString) {
|
|
867
|
-
const rgbMatch = /rgba?\((\d+),\s*(\d+),\s*(\d+)/.exec(colorString);
|
|
868
|
-
if (!rgbMatch) {
|
|
869
|
-
return null;
|
|
870
|
-
}
|
|
871
|
-
return {
|
|
872
|
-
r: parseInt(rgbMatch[1]),
|
|
873
|
-
g: parseInt(rgbMatch[2]),
|
|
874
|
-
b: parseInt(rgbMatch[3])
|
|
875
|
-
};
|
|
876
|
-
}
|
|
877
|
-
__name(parseRgbColor, "parseRgbColor");
|
|
878
|
-
function isColorDark(colorString, threshold = 128) {
|
|
879
|
-
if (!colorString || colorString === "transparent" || colorString.startsWith("rgba(0, 0, 0, 0)")) {
|
|
880
|
-
return false;
|
|
881
|
-
}
|
|
882
|
-
const rgb = parseRgbColor(colorString);
|
|
883
|
-
if (!rgb) {
|
|
884
|
-
return false;
|
|
885
|
-
}
|
|
886
|
-
const luminance = 0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b;
|
|
887
|
-
return luminance < threshold;
|
|
888
|
-
}
|
|
889
|
-
__name(isColorDark, "isColorDark");
|
|
890
|
-
function isBackgroundDark() {
|
|
891
|
-
const htmlStyle = window.getComputedStyle(document.documentElement);
|
|
892
|
-
const bodyStyle = window.getComputedStyle(document.body || document.documentElement);
|
|
893
|
-
const htmlBgColor = htmlStyle.backgroundColor;
|
|
894
|
-
const bodyBgColor = bodyStyle.backgroundColor;
|
|
895
|
-
if (isColorDark(bodyBgColor)) {
|
|
896
|
-
return true;
|
|
897
|
-
} else if (bodyBgColor === "transparent" || bodyBgColor.startsWith("rgba(0, 0, 0, 0)")) {
|
|
898
|
-
return isColorDark(htmlBgColor);
|
|
899
|
-
}
|
|
900
|
-
return false;
|
|
901
|
-
}
|
|
902
|
-
__name(isBackgroundDark, "isBackgroundDark");
|
|
903
|
-
function isPageDark() {
|
|
904
|
-
try {
|
|
905
|
-
if (hasDarkModeClass()) {
|
|
906
|
-
return true;
|
|
907
|
-
}
|
|
908
|
-
if (isBackgroundDark()) {
|
|
909
|
-
return true;
|
|
910
|
-
}
|
|
911
|
-
return false;
|
|
912
|
-
} catch (error2) {
|
|
913
|
-
console.warn("Error determining if page is dark:", error2);
|
|
914
|
-
return false;
|
|
915
|
-
}
|
|
916
|
-
}
|
|
917
|
-
__name(isPageDark, "isPageDark");
|
|
918
|
-
const wrapper = "_wrapper_1oy2s_1";
|
|
919
|
-
const styles = {
|
|
920
|
-
wrapper
|
|
921
|
-
};
|
|
922
|
-
const cursor = "_cursor_1vrf3_2";
|
|
923
|
-
const cursorBorder = "_cursorBorder_1vrf3_13";
|
|
924
|
-
const cursorFilling = "_cursorFilling_1vrf3_23";
|
|
925
|
-
const cursorRipple = "_cursorRipple_1vrf3_31";
|
|
926
|
-
const clicking = "_clicking_1vrf3_37";
|
|
927
|
-
const cursorStyles = {
|
|
928
|
-
cursor,
|
|
929
|
-
cursorBorder,
|
|
930
|
-
cursorFilling,
|
|
931
|
-
cursorRipple,
|
|
932
|
-
clicking
|
|
933
|
-
};
|
|
934
|
-
const _SimulatorMask = class _SimulatorMask {
|
|
935
|
-
constructor() {
|
|
936
|
-
__privateAdd(this, _SimulatorMask_instances);
|
|
937
|
-
__publicField(this, "wrapper", document.createElement("div"));
|
|
938
|
-
__publicField(this, "motion", new Motion({
|
|
939
|
-
mode: isPageDark() ? "dark" : "light",
|
|
940
|
-
styles: {
|
|
941
|
-
position: "absolute",
|
|
942
|
-
inset: "0"
|
|
943
|
-
}
|
|
944
|
-
}));
|
|
945
|
-
__privateAdd(this, _cursor, document.createElement("div"));
|
|
946
|
-
__privateAdd(this, _currentCursorX, 0);
|
|
947
|
-
__privateAdd(this, _currentCursorY, 0);
|
|
948
|
-
__privateAdd(this, _targetCursorX, 0);
|
|
949
|
-
__privateAdd(this, _targetCursorY, 0);
|
|
950
|
-
this.wrapper.id = "page-agent-runtime_simulator-mask";
|
|
951
|
-
this.wrapper.className = styles.wrapper;
|
|
952
|
-
this.wrapper.setAttribute("data-browser-use-ignore", "true");
|
|
953
|
-
this.wrapper.appendChild(this.motion.element);
|
|
954
|
-
this.motion.autoResize(this.wrapper);
|
|
955
|
-
this.wrapper.addEventListener("click", (e) => {
|
|
956
|
-
e.stopPropagation();
|
|
957
|
-
e.preventDefault();
|
|
958
|
-
});
|
|
959
|
-
this.wrapper.addEventListener("mousedown", (e) => {
|
|
960
|
-
e.stopPropagation();
|
|
961
|
-
e.preventDefault();
|
|
962
|
-
});
|
|
963
|
-
this.wrapper.addEventListener("mouseup", (e) => {
|
|
964
|
-
e.stopPropagation();
|
|
965
|
-
e.preventDefault();
|
|
966
|
-
});
|
|
967
|
-
this.wrapper.addEventListener("mousemove", (e) => {
|
|
968
|
-
e.stopPropagation();
|
|
969
|
-
e.preventDefault();
|
|
970
|
-
});
|
|
971
|
-
this.wrapper.addEventListener("wheel", (e) => {
|
|
972
|
-
e.stopPropagation();
|
|
973
|
-
e.preventDefault();
|
|
974
|
-
});
|
|
975
|
-
this.wrapper.addEventListener("keydown", (e) => {
|
|
976
|
-
e.stopPropagation();
|
|
977
|
-
e.preventDefault();
|
|
978
|
-
});
|
|
979
|
-
this.wrapper.addEventListener("keyup", (e) => {
|
|
980
|
-
e.stopPropagation();
|
|
981
|
-
e.preventDefault();
|
|
982
|
-
});
|
|
983
|
-
__privateMethod(this, _SimulatorMask_instances, createCursor_fn).call(this);
|
|
984
|
-
document.body.appendChild(this.wrapper);
|
|
985
|
-
__privateMethod(this, _SimulatorMask_instances, moveCursorToTarget_fn).call(this);
|
|
986
|
-
window.addEventListener("PageAgent::MovePointerTo", (event) => {
|
|
987
|
-
const { x, y } = event.detail;
|
|
988
|
-
this.setCursorPosition(x, y);
|
|
989
|
-
});
|
|
990
|
-
window.addEventListener("PageAgent::ClickPointer", (event) => {
|
|
991
|
-
this.triggerClickAnimation();
|
|
992
|
-
});
|
|
993
|
-
}
|
|
994
|
-
setCursorPosition(x, y) {
|
|
995
|
-
__privateSet(this, _targetCursorX, x);
|
|
996
|
-
__privateSet(this, _targetCursorY, y);
|
|
997
|
-
}
|
|
998
|
-
triggerClickAnimation() {
|
|
999
|
-
__privateGet(this, _cursor).classList.remove(cursorStyles.clicking);
|
|
1000
|
-
void __privateGet(this, _cursor).offsetHeight;
|
|
1001
|
-
__privateGet(this, _cursor).classList.add(cursorStyles.clicking);
|
|
1002
|
-
}
|
|
1003
|
-
show() {
|
|
1004
|
-
this.motion.start();
|
|
1005
|
-
this.motion.fadeIn();
|
|
1006
|
-
this.wrapper.style.display = "block";
|
|
1007
|
-
__privateSet(this, _currentCursorX, window.innerWidth / 2);
|
|
1008
|
-
__privateSet(this, _currentCursorY, window.innerHeight / 2);
|
|
1009
|
-
__privateSet(this, _targetCursorX, __privateGet(this, _currentCursorX));
|
|
1010
|
-
__privateSet(this, _targetCursorY, __privateGet(this, _currentCursorY));
|
|
1011
|
-
__privateGet(this, _cursor).style.left = `${__privateGet(this, _currentCursorX)}px`;
|
|
1012
|
-
__privateGet(this, _cursor).style.top = `${__privateGet(this, _currentCursorY)}px`;
|
|
1013
|
-
}
|
|
1014
|
-
hide() {
|
|
1015
|
-
this.motion.fadeOut();
|
|
1016
|
-
this.motion.pause();
|
|
1017
|
-
__privateGet(this, _cursor).classList.remove(cursorStyles.clicking);
|
|
1018
|
-
setTimeout(() => {
|
|
1019
|
-
this.wrapper.style.display = "none";
|
|
1020
|
-
}, 800);
|
|
1021
|
-
}
|
|
1022
|
-
dispose() {
|
|
1023
|
-
this.motion.dispose();
|
|
1024
|
-
this.wrapper.remove();
|
|
1025
|
-
}
|
|
1026
|
-
};
|
|
1027
|
-
_cursor = new WeakMap();
|
|
1028
|
-
_currentCursorX = new WeakMap();
|
|
1029
|
-
_currentCursorY = new WeakMap();
|
|
1030
|
-
_targetCursorX = new WeakMap();
|
|
1031
|
-
_targetCursorY = new WeakMap();
|
|
1032
|
-
_SimulatorMask_instances = new WeakSet();
|
|
1033
|
-
createCursor_fn = /* @__PURE__ */ __name(function() {
|
|
1034
|
-
__privateGet(this, _cursor).className = cursorStyles.cursor;
|
|
1035
|
-
const rippleContainer = document.createElement("div");
|
|
1036
|
-
rippleContainer.className = cursorStyles.cursorRipple;
|
|
1037
|
-
__privateGet(this, _cursor).appendChild(rippleContainer);
|
|
1038
|
-
const fillingLayer = document.createElement("div");
|
|
1039
|
-
fillingLayer.className = cursorStyles.cursorFilling;
|
|
1040
|
-
__privateGet(this, _cursor).appendChild(fillingLayer);
|
|
1041
|
-
const borderLayer = document.createElement("div");
|
|
1042
|
-
borderLayer.className = cursorStyles.cursorBorder;
|
|
1043
|
-
__privateGet(this, _cursor).appendChild(borderLayer);
|
|
1044
|
-
this.wrapper.appendChild(__privateGet(this, _cursor));
|
|
1045
|
-
}, "#createCursor");
|
|
1046
|
-
moveCursorToTarget_fn = /* @__PURE__ */ __name(function() {
|
|
1047
|
-
const newX = __privateGet(this, _currentCursorX) + (__privateGet(this, _targetCursorX) - __privateGet(this, _currentCursorX)) * 0.2;
|
|
1048
|
-
const newY = __privateGet(this, _currentCursorY) + (__privateGet(this, _targetCursorY) - __privateGet(this, _currentCursorY)) * 0.2;
|
|
1049
|
-
const xDistance = Math.abs(newX - __privateGet(this, _targetCursorX));
|
|
1050
|
-
if (xDistance > 0) {
|
|
1051
|
-
if (xDistance < 2) {
|
|
1052
|
-
__privateSet(this, _currentCursorX, __privateGet(this, _targetCursorX));
|
|
1053
|
-
} else {
|
|
1054
|
-
__privateSet(this, _currentCursorX, newX);
|
|
1055
|
-
}
|
|
1056
|
-
__privateGet(this, _cursor).style.left = `${__privateGet(this, _currentCursorX)}px`;
|
|
1057
|
-
}
|
|
1058
|
-
const yDistance = Math.abs(newY - __privateGet(this, _targetCursorY));
|
|
1059
|
-
if (yDistance > 0) {
|
|
1060
|
-
if (yDistance < 2) {
|
|
1061
|
-
__privateSet(this, _currentCursorY, __privateGet(this, _targetCursorY));
|
|
1062
|
-
} else {
|
|
1063
|
-
__privateSet(this, _currentCursorY, newY);
|
|
1064
|
-
}
|
|
1065
|
-
__privateGet(this, _cursor).style.top = `${__privateGet(this, _currentCursorY)}px`;
|
|
1066
|
-
}
|
|
1067
|
-
requestAnimationFrame(() => __privateMethod(this, _SimulatorMask_instances, moveCursorToTarget_fn).call(this));
|
|
1068
|
-
}, "#moveCursorToTarget");
|
|
1069
|
-
__name(_SimulatorMask, "SimulatorMask");
|
|
1070
|
-
let SimulatorMask = _SimulatorMask;
|
|
1071
847
|
export {
|
|
1072
848
|
I18n,
|
|
1073
849
|
Panel,
|
|
1074
|
-
SimulatorMask,
|
|
1075
850
|
UIState
|
|
1076
851
|
};
|
|
1077
852
|
//# sourceMappingURL=page-agent-ui.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page-agent-ui.js","sources":["../../src/UIState.ts","../../src/i18n/locales.ts","../../src/i18n/index.ts","../../src/utils.ts","../../src/Panel.ts","../../src/checkDarkMode.ts","../../src/SimulatorMask.ts"],"sourcesContent":["/**\n * Agent execution state management\n */\n\nexport interface Step {\n\tid: string\n\tstepNumber: number\n\ttimestamp: Date\n\ttype: 'thinking' | 'tool_executing' | 'completed' | 'error' | 'output' | 'input' | 'retry'\n\n\t// Tool execution related\n\ttoolName?: string\n\ttoolArgs?: any\n\ttoolResult?: any\n\n\t// Display data\n\tdisplayText: string\n\tduration?: number\n}\n\nexport type AgentStatus = 'idle' | 'running' | 'paused' | 'completed' | 'error'\n\nexport class UIState {\n\tprivate steps: Step[] = []\n\tprivate currentStep: Step | null = null\n\tprivate status: AgentStatus = 'idle'\n\tprivate stepCounter = 0\n\n\taddStep(stepData: Omit<Step, 'id' | 'stepNumber' | 'timestamp'>): Step {\n\t\tconst step: Step = {\n\t\t\tid: this.generateId(),\n\t\t\tstepNumber: ++this.stepCounter,\n\t\t\ttimestamp: new Date(),\n\t\t\t...stepData,\n\t\t}\n\n\t\tthis.steps.push(step)\n\t\tthis.currentStep = step\n\n\t\t// Update overall status\n\t\tthis.updateStatus(step.type)\n\n\t\treturn step\n\t}\n\n\tupdateCurrentStep(updates: Partial<Step>): Step | null {\n\t\tif (!this.currentStep) return null\n\n\t\tObject.assign(this.currentStep, updates)\n\t\treturn this.currentStep\n\t}\n\n\tgetCurrentStep(): Step | null {\n\t\treturn this.currentStep\n\t}\n\n\tgetAllSteps(): Step[] {\n\t\treturn [...this.steps]\n\t}\n\n\tgetStatus(): AgentStatus {\n\t\treturn this.status\n\t}\n\n\treset(): void {\n\t\tthis.steps = []\n\t\tthis.currentStep = null\n\t\tthis.status = 'idle'\n\t\tthis.stepCounter = 0\n\t}\n\n\tprivate updateStatus(stepType: Step['type']): void {\n\t\tswitch (stepType) {\n\t\t\tcase 'thinking':\n\t\t\tcase 'tool_executing':\n\t\t\tcase 'output':\n\t\t\tcase 'input':\n\t\t\tcase 'retry':\n\t\t\t\tthis.status = 'running'\n\t\t\t\tbreak\n\t\t\tcase 'completed':\n\t\t\t\tthis.status = 'completed'\n\t\t\t\tbreak\n\t\t\tcase 'error':\n\t\t\t\tthis.status = 'error'\n\t\t\t\tbreak\n\t\t}\n\t}\n\n\tprivate generateId(): string {\n\t\treturn `step_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`\n\t}\n}\n","// English translations (base/reference language)\nconst enUS = {\n\tui: {\n\t\tpanel: {\n\t\t\tready: 'Ready',\n\t\t\tthinking: 'Thinking...',\n\t\t\tpaused: 'Paused',\n\t\t\ttaskInput: 'Enter new task, describe steps in detail, press Enter to submit',\n\t\t\tuserAnswerPrompt: 'Please answer the question above, press Enter to submit',\n\t\t\ttaskTerminated: 'Task terminated',\n\t\t\ttaskCompleted: 'Task completed',\n\t\t\tcontinueExecution: 'Continue execution',\n\t\t\tuserAnswer: 'User answer: {{input}}',\n\t\t\tquestion: 'Question: {{question}}',\n\t\t\twaitingPlaceholder: 'Waiting for task to start...',\n\t\t\tpause: 'Pause',\n\t\t\tcontinue: 'Continue',\n\t\t\tstop: 'Stop',\n\t\t\texpand: 'Expand history',\n\t\t\tcollapse: 'Collapse history',\n\t\t\tstep: 'Step {{number}} · {{time}}{{duration}}',\n\t\t},\n\t\ttools: {\n\t\t\tclicking: 'Clicking element [{{index}}]...',\n\t\t\tinputting: 'Inputting text to element [{{index}}]...',\n\t\t\tselecting: 'Selecting option \"{{text}}\"...',\n\t\t\tscrolling: 'Scrolling page...',\n\t\t\twaiting: 'Waiting {{seconds}} seconds...',\n\t\t\tdone: 'Task done',\n\t\t\tclicked: '🖱️ Clicked element [{{index}}]',\n\t\t\tinputted: '⌨️ Inputted text \"{{text}}\"',\n\t\t\tselected: '☑️ Selected option \"{{text}}\"',\n\t\t\tscrolled: '🛞 Page scrolled',\n\t\t\twaited: '⌛️ Wait completed',\n\t\t\texecuting: 'Executing {{toolName}}...',\n\t\t\tresultSuccess: 'success',\n\t\t\tresultFailure: 'failed',\n\t\t\tresultError: 'error',\n\t\t},\n\t\terrors: {\n\t\t\telementNotFound: 'No interactive element found at index {{index}}',\n\t\t\ttaskRequired: 'Task description is required',\n\t\t\texecutionFailed: 'Task execution failed',\n\t\t\tnotInputElement: 'Element is not an input or textarea',\n\t\t\tnotSelectElement: 'Element is not a select element',\n\t\t\toptionNotFound: 'Option \"{{text}}\" not found',\n\t\t},\n\t},\n} as const\n\n// Chinese translations (must match the structure of enUS)\nconst zhCN = {\n\tui: {\n\t\tpanel: {\n\t\t\tready: '准备就绪',\n\t\t\tthinking: '正在思考...',\n\t\t\tpaused: '暂停中,稍后',\n\t\t\ttaskInput: '输入新任务,详细描述步骤,回车提交',\n\t\t\tuserAnswerPrompt: '请回答上面问题,回车提交',\n\t\t\ttaskTerminated: '任务已终止',\n\t\t\ttaskCompleted: '任务结束',\n\t\t\tcontinueExecution: '继续执行',\n\t\t\tuserAnswer: '用户回答: {{input}}',\n\t\t\tquestion: '询问: {{question}}',\n\t\t\twaitingPlaceholder: '等待任务开始...',\n\t\t\tpause: '暂停',\n\t\t\tcontinue: '继续',\n\t\t\tstop: '终止',\n\t\t\texpand: '展开历史',\n\t\t\tcollapse: '收起历史',\n\t\t\tstep: '步骤 {{number}} · {{time}}{{duration}}',\n\t\t},\n\t\ttools: {\n\t\t\tclicking: '正在点击元素 [{{index}}]...',\n\t\t\tinputting: '正在输入文本到元素 [{{index}}]...',\n\t\t\tselecting: '正在选择选项 \"{{text}}\"...',\n\t\t\tscrolling: '正在滚动页面...',\n\t\t\twaiting: '等待 {{seconds}} 秒...',\n\t\t\tdone: '结束任务',\n\t\t\tclicked: '🖱️ 已点击元素 [{{index}}]',\n\t\t\tinputted: '⌨️ 已输入文本 \"{{text}}\"',\n\t\t\tselected: '☑️ 已选择选项 \"{{text}}\"',\n\t\t\tscrolled: '🛞 页面滚动完成',\n\t\t\twaited: '⌛️ 等待完成',\n\t\t\texecuting: '正在执行 {{toolName}}...',\n\t\t\tresultSuccess: '成功',\n\t\t\tresultFailure: '失败',\n\t\t\tresultError: '错误',\n\t\t},\n\t\terrors: {\n\t\t\telementNotFound: '未找到索引为 {{index}} 的交互元素',\n\t\t\ttaskRequired: '任务描述不能为空',\n\t\t\texecutionFailed: '任务执行失败',\n\t\t\tnotInputElement: '元素不是输入框或文本域',\n\t\t\tnotSelectElement: '元素不是选择框',\n\t\t\toptionNotFound: '未找到选项 \"{{text}}\"',\n\t\t},\n\t},\n} as const\n\n// Type definitions generated from English base structure (but with string values)\ntype DeepStringify<T> = {\n\t[K in keyof T]: T[K] extends string ? string : T[K] extends object ? DeepStringify<T[K]> : T[K]\n}\n\nexport type TranslationSchema = DeepStringify<typeof enUS>\n\n// Utility type: Extract all nested paths from translation object\ntype NestedKeyOf<ObjectType extends object> = {\n\t[Key in keyof ObjectType & (string | number)]: ObjectType[Key] extends object\n\t\t? `${Key}` | `${Key}.${NestedKeyOf<ObjectType[Key]>}`\n\t\t: `${Key}`\n}[keyof ObjectType & (string | number)]\n\n// Extract all possible key paths from translation structure\nexport type TranslationKey = NestedKeyOf<TranslationSchema>\n\n// Parameterized translation types\nexport type TranslationParams = Record<string, string | number>\n\nexport const locales = {\n\t'en-US': enUS,\n\t'zh-CN': zhCN,\n} as const\n\nexport type SupportedLanguage = keyof typeof locales\n","import {\n\ttype SupportedLanguage,\n\ttype TranslationKey,\n\ttype TranslationParams,\n\ttype TranslationSchema,\n\tlocales,\n} from './locales'\n\nexport class I18n {\n\tprivate language: SupportedLanguage\n\tprivate translations: TranslationSchema\n\n\tconstructor(language: SupportedLanguage = 'en-US') {\n\t\tthis.language = language in locales ? language : 'en-US'\n\t\tthis.translations = locales[this.language]\n\t}\n\n\t// 类型安全的翻译方法\n\tt(key: TranslationKey, params?: TranslationParams): string {\n\t\tconst value = this.getNestedValue(this.translations, key)\n\t\tif (!value) {\n\t\t\tconsole.warn(`Translation key \"${key}\" not found for language \"${this.language}\"`)\n\t\t\treturn key\n\t\t}\n\n\t\tif (params) {\n\t\t\treturn this.interpolate(value, params)\n\t\t}\n\t\treturn value\n\t}\n\n\tprivate getNestedValue(obj: any, path: string): string | undefined {\n\t\treturn path.split('.').reduce((current, key) => current?.[key], obj)\n\t}\n\n\tprivate interpolate(template: string, params: TranslationParams): string {\n\t\treturn template.replace(/\\{\\{(\\w+)\\}\\}/g, (match, key) => {\n\t\t\t// Use != null to check for both null and undefined, allow empty strings\n\t\t\treturn params[key] != null ? params[key].toString() : match\n\t\t})\n\t}\n\n\tgetLanguage(): SupportedLanguage {\n\t\treturn this.language\n\t}\n}\n\n// 导出类型和实例创建函数\nexport type { TranslationKey, SupportedLanguage, TranslationParams }\nexport { locales }\n","export function truncate(text: string, maxLength: number): string {\n\tif (text.length > maxLength) {\n\t\treturn text.substring(0, maxLength) + '...'\n\t}\n\treturn text\n}\n","import { type Step, UIState } from './UIState'\nimport { I18n, type SupportedLanguage } from './i18n'\nimport { truncate } from './utils'\n\nimport styles from './Panel.module.css'\n\n/**\n * Panel configuration\n */\nexport interface PanelConfig {\n\tlanguage?: SupportedLanguage\n\tonExecuteTask: (task: string) => void\n\tonStop: () => void\n\tonPauseToggle: () => boolean // returns new paused state\n\tgetPaused: () => boolean\n}\n\n/**\n * Semantic update types - Panel handles i18n internally\n */\nexport type PanelUpdate =\n\t| { type: 'thinking'; text?: string } // text is optional, defaults to i18n thinking text\n\t| { type: 'input'; task: string }\n\t| { type: 'question'; question: string }\n\t| { type: 'userAnswer'; input: string }\n\t| { type: 'retry'; current: number; max: number }\n\t| { type: 'error'; message: string }\n\t| { type: 'output'; text: string }\n\t| { type: 'completed' }\n\t| { type: 'toolExecuting'; toolName: string; args: any }\n\t| { type: 'toolCompleted'; toolName: string; args: any; result?: string; duration?: number }\n\n/**\n * Agent control panel\n */\nexport class Panel {\n\t#wrapper: HTMLElement\n\t#indicator: HTMLElement\n\t#statusText: HTMLElement\n\t#historySection: HTMLElement\n\t#expandButton: HTMLElement\n\t#pauseButton: HTMLElement\n\t#stopButton: HTMLElement\n\t#inputSection: HTMLElement\n\t#taskInput: HTMLInputElement\n\n\t#state = new UIState()\n\t#isExpanded = false\n\t#config: PanelConfig\n\t#i18n: I18n\n\t#userAnswerResolver: ((input: string) => void) | null = null\n\t#isWaitingForUserAnswer: boolean = false\n\t#headerUpdateTimer: ReturnType<typeof setInterval> | null = null\n\t#pendingHeaderText: string | null = null\n\t#isAnimating = false\n\n\tget wrapper(): HTMLElement {\n\t\treturn this.#wrapper\n\t}\n\n\tconstructor(config: PanelConfig) {\n\t\tthis.#config = config\n\t\tthis.#i18n = new I18n(config.language ?? 'en-US')\n\t\tthis.#wrapper = this.#createWrapper()\n\t\tthis.#indicator = this.#wrapper.querySelector(`.${styles.indicator}`)!\n\t\tthis.#statusText = this.#wrapper.querySelector(`.${styles.statusText}`)!\n\t\tthis.#historySection = this.#wrapper.querySelector(`.${styles.historySection}`)!\n\t\tthis.#expandButton = this.#wrapper.querySelector(`.${styles.expandButton}`)!\n\t\tthis.#pauseButton = this.#wrapper.querySelector(`.${styles.pauseButton}`)!\n\t\tthis.#stopButton = this.#wrapper.querySelector(`.${styles.stopButton}`)!\n\t\tthis.#inputSection = this.#wrapper.querySelector(`.${styles.inputSectionWrapper}`)!\n\t\tthis.#taskInput = this.#wrapper.querySelector(`.${styles.taskInput}`)!\n\n\t\tthis.#setupEventListeners()\n\t\tthis.#startHeaderUpdateLoop()\n\n\t\tthis.#showInputArea()\n\t}\n\n\t/**\n\t * Ask for user input\n\t */\n\tasync askUser(question: string): Promise<string> {\n\t\treturn new Promise((resolve) => {\n\t\t\t// Set `waiting for user answer` state\n\t\t\tthis.#isWaitingForUserAnswer = true\n\t\t\tthis.#userAnswerResolver = resolve\n\n\t\t\t// Update state to `running`\n\t\t\tthis.#updateInternal({\n\t\t\t\ttype: 'output',\n\t\t\t\tdisplayText: this.#i18n.t('ui.panel.question', { question }),\n\t\t\t}) // Expand history panel\n\t\t\tif (!this.#isExpanded) {\n\t\t\t\tthis.#expand()\n\t\t\t}\n\n\t\t\tthis.#showInputArea(this.#i18n.t('ui.panel.userAnswerPrompt'))\n\t\t})\n\t}\n\n\t// ========== Public control methods ==========\n\n\tshow(): void {\n\t\tthis.wrapper.style.display = 'block'\n\t\tvoid this.wrapper.offsetHeight\n\t\tthis.wrapper.style.opacity = '1'\n\t\tthis.wrapper.style.transform = 'translateX(-50%) translateY(0)'\n\t}\n\n\thide(): void {\n\t\tthis.wrapper.style.opacity = '0'\n\t\tthis.wrapper.style.transform = 'translateX(-50%) translateY(20px)'\n\t\tthis.wrapper.style.display = 'none'\n\t}\n\n\treset(): void {\n\t\tthis.#state.reset()\n\t\tthis.#statusText.textContent = this.#i18n.t('ui.panel.ready')\n\t\tthis.#updateStatusIndicator('thinking')\n\t\tthis.#updateHistory()\n\t\tthis.#collapse()\n\t\t// Reset pause state via callback\n\t\tif (this.#config.getPaused()) {\n\t\t\tthis.#config.onPauseToggle()\n\t\t}\n\t\tthis.#updatePauseButton()\n\t\t// Reset user input state\n\t\tthis.#isWaitingForUserAnswer = false\n\t\tthis.#userAnswerResolver = null\n\t\t// Show input area\n\t\tthis.#showInputArea()\n\t}\n\n\texpand(): void {\n\t\tthis.#expand()\n\t}\n\n\tcollapse(): void {\n\t\tthis.#collapse()\n\t}\n\n\t/**\n\t * Update panel with semantic data - i18n handled internally\n\t */\n\tupdate(data: PanelUpdate): void {\n\t\tconst stepData = this.#toStepData(data)\n\t\tthis.#updateInternal(stepData)\n\t}\n\n\t/**\n\t * Dispose panel\n\t */\n\tdispose(): void {\n\t\tthis.#isWaitingForUserAnswer = false\n\t\tthis.#stopHeaderUpdateLoop()\n\t\tthis.wrapper.remove()\n\t}\n\n\t// ========== Private methods ==========\n\n\t/**\n\t * Convert semantic update to step data with i18n\n\t */\n\t#toStepData(data: PanelUpdate): Omit<Step, 'id' | 'stepNumber' | 'timestamp'> {\n\t\tswitch (data.type) {\n\t\t\tcase 'thinking':\n\t\t\t\treturn { type: 'thinking', displayText: data.text ?? this.#i18n.t('ui.panel.thinking') }\n\t\t\tcase 'input':\n\t\t\t\treturn { type: 'input', displayText: data.task }\n\t\t\tcase 'question':\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'output',\n\t\t\t\t\tdisplayText: this.#i18n.t('ui.panel.question', { question: data.question }),\n\t\t\t\t}\n\t\t\tcase 'userAnswer':\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'input',\n\t\t\t\t\tdisplayText: this.#i18n.t('ui.panel.userAnswer', { input: data.input }),\n\t\t\t\t}\n\t\t\tcase 'retry':\n\t\t\t\treturn { type: 'retry', displayText: `retry-ing (${data.current} / ${data.max})` }\n\t\t\tcase 'error':\n\t\t\t\treturn { type: 'error', displayText: data.message }\n\t\t\tcase 'output':\n\t\t\t\treturn { type: 'output', displayText: data.text }\n\t\t\tcase 'completed':\n\t\t\t\treturn { type: 'completed', displayText: this.#i18n.t('ui.panel.taskCompleted') }\n\t\t\tcase 'toolExecuting':\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'tool_executing',\n\t\t\t\t\ttoolName: data.toolName,\n\t\t\t\t\ttoolArgs: data.args,\n\t\t\t\t\tdisplayText: this.#getToolExecutingText(data.toolName, data.args),\n\t\t\t\t}\n\t\t\tcase 'toolCompleted': {\n\t\t\t\tconst displayText = this.#getToolCompletedText(data.toolName, data.args)\n\t\t\t\tif (!displayText) return { type: 'tool_executing', displayText: '' } // will be filtered\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'tool_executing',\n\t\t\t\t\ttoolName: data.toolName,\n\t\t\t\t\ttoolArgs: data.args,\n\t\t\t\t\ttoolResult: data.result,\n\t\t\t\t\tdisplayText,\n\t\t\t\t\tduration: data.duration,\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t#getToolExecutingText(toolName: string, args: any): string {\n\t\tswitch (toolName) {\n\t\t\tcase 'click_element_by_index':\n\t\t\t\treturn this.#i18n.t('ui.tools.clicking', { index: args.index })\n\t\t\tcase 'input_text':\n\t\t\t\treturn this.#i18n.t('ui.tools.inputting', { index: args.index })\n\t\t\tcase 'select_dropdown_option':\n\t\t\t\treturn this.#i18n.t('ui.tools.selecting', { text: args.text })\n\t\t\tcase 'scroll':\n\t\t\t\treturn this.#i18n.t('ui.tools.scrolling')\n\t\t\tcase 'wait':\n\t\t\t\treturn this.#i18n.t('ui.tools.waiting', { seconds: args.seconds })\n\t\t\tcase 'done':\n\t\t\t\treturn this.#i18n.t('ui.tools.done')\n\t\t\tdefault:\n\t\t\t\treturn this.#i18n.t('ui.tools.executing', { toolName })\n\t\t}\n\t}\n\n\t#getToolCompletedText(toolName: string, args: any): string | null {\n\t\tswitch (toolName) {\n\t\t\tcase 'click_element_by_index':\n\t\t\t\treturn this.#i18n.t('ui.tools.clicked', { index: args.index })\n\t\t\tcase 'input_text':\n\t\t\t\treturn this.#i18n.t('ui.tools.inputted', { text: args.text })\n\t\t\tcase 'select_dropdown_option':\n\t\t\t\treturn this.#i18n.t('ui.tools.selected', { text: args.text })\n\t\t\tcase 'scroll':\n\t\t\t\treturn this.#i18n.t('ui.tools.scrolled')\n\t\t\tcase 'wait':\n\t\t\t\treturn this.#i18n.t('ui.tools.waited')\n\t\t\tcase 'done':\n\t\t\t\treturn null\n\t\t\tdefault:\n\t\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Update status (internal)\n\t */\n\t#updateInternal(stepData: Omit<Step, 'id' | 'stepNumber' | 'timestamp'>): void {\n\t\t// Skip empty displayText (filtered toolCompleted for 'done')\n\t\tif (!stepData.displayText) return\n\n\t\tconst step = this.#state.addStep(stepData)\n\n\t\t// Queue header text update (will be processed by periodic check)\n\t\tconst headerText = truncate(step.displayText, 20)\n\t\tthis.#pendingHeaderText = headerText\n\n\t\tthis.#updateStatusIndicator(step.type)\n\t\tthis.#updateHistory()\n\n\t\t// Auto-expand history after task completion\n\t\tif (step.type === 'completed' || step.type === 'error') {\n\t\t\tif (!this.#isExpanded) {\n\t\t\t\tthis.#expand()\n\t\t\t}\n\t\t}\n\n\t\t// Control input area display based on status\n\t\tif (this.#shouldShowInputArea()) {\n\t\t\tthis.#showInputArea()\n\t\t} else {\n\t\t\tthis.#hideInputArea()\n\t\t}\n\t}\n\n\t/**\n\t * Toggle pause state\n\t */\n\t#togglePause(): void {\n\t\tconst paused = this.#config.onPauseToggle()\n\t\tthis.#updatePauseButton()\n\n\t\t// Update status display\n\t\tif (paused) {\n\t\t\tthis.#statusText.textContent = this.#i18n.t('ui.panel.paused')\n\t\t\tthis.#updateStatusIndicator('thinking')\n\t\t} else {\n\t\t\tthis.#statusText.textContent = this.#i18n.t('ui.panel.continueExecution')\n\t\t\tthis.#updateStatusIndicator('tool_executing')\n\t\t}\n\t}\n\n\t/**\n\t * Update pause button state\n\t */\n\t#updatePauseButton(): void {\n\t\tconst paused = this.#config.getPaused()\n\t\tif (paused) {\n\t\t\tthis.#pauseButton.textContent = '▶'\n\t\t\tthis.#pauseButton.title = this.#i18n.t('ui.panel.continue')\n\t\t\tthis.#pauseButton.classList.add(styles.paused)\n\t\t} else {\n\t\t\tthis.#pauseButton.textContent = '⏸︎'\n\t\t\tthis.#pauseButton.title = this.#i18n.t('ui.panel.pause')\n\t\t\tthis.#pauseButton.classList.remove(styles.paused)\n\t\t}\n\t}\n\n\t/**\n\t * Stop Agent\n\t */\n\t#stopAgent(): void {\n\t\t// Update status display\n\t\tthis.#updateInternal({\n\t\t\ttype: 'error',\n\t\t\tdisplayText: this.#i18n.t('ui.panel.taskTerminated'),\n\t\t})\n\n\t\tthis.#config.onStop()\n\t}\n\n\t/**\n\t * Submit task\n\t */\n\t#submitTask() {\n\t\tconst input = this.#taskInput.value.trim()\n\t\tif (!input) return\n\n\t\t// Hide input area\n\t\tthis.#hideInputArea()\n\n\t\tif (this.#isWaitingForUserAnswer) {\n\t\t\t// Handle user input mode\n\t\t\tthis.#handleUserAnswer(input)\n\t\t} else {\n\t\t\tthis.#config.onExecuteTask(input)\n\t\t}\n\t}\n\n\t/**\n\t * Handle user answer\n\t */\n\t#handleUserAnswer(input: string): void {\n\t\t// Add user input to history\n\t\tthis.#updateInternal({\n\t\t\ttype: 'input',\n\t\t\tdisplayText: this.#i18n.t('ui.panel.userAnswer', { input }),\n\t\t})\n\n\t\t// Reset state\n\t\tthis.#isWaitingForUserAnswer = false\n\n\t\t// Call resolver to return user input\n\t\tif (this.#userAnswerResolver) {\n\t\t\tthis.#userAnswerResolver(input)\n\t\t\tthis.#userAnswerResolver = null\n\t\t}\n\t}\n\n\t/**\n\t * Show input area\n\t */\n\t#showInputArea(placeholder?: string): void {\n\t\t// Clear input field\n\t\tthis.#taskInput.value = ''\n\t\tthis.#taskInput.placeholder = placeholder || this.#i18n.t('ui.panel.taskInput')\n\t\tthis.#inputSection.classList.remove(styles.hidden)\n\t\t// Focus on input field\n\t\tsetTimeout(() => {\n\t\t\tthis.#taskInput.focus()\n\t\t}, 100)\n\t}\n\n\t/**\n\t * Hide input area\n\t */\n\t#hideInputArea(): void {\n\t\tthis.#inputSection.classList.add(styles.hidden)\n\t}\n\n\t/**\n\t * Check if input area should be shown\n\t */\n\t#shouldShowInputArea(): boolean {\n\t\t// Always show input area if waiting for user input\n\t\tif (this.#isWaitingForUserAnswer) return true\n\n\t\tconst steps = this.#state.getAllSteps()\n\t\tif (steps.length === 0) {\n\t\t\treturn true // Initial state\n\t\t}\n\n\t\tconst lastStep = steps[steps.length - 1]\n\t\treturn lastStep.type === 'completed' || lastStep.type === 'error'\n\t}\n\n\t#createWrapper(): HTMLElement {\n\t\tconst wrapper = document.createElement('div')\n\t\twrapper.id = 'page-agent-runtime_agent-panel'\n\t\twrapper.className = `${styles.wrapper} ${styles.collapsed}`\n\t\twrapper.setAttribute('data-browser-use-ignore', 'true')\n\n\t\twrapper.innerHTML = `\n\t\t\t<div class=\"${styles.background}\"></div>\n\t\t\t<div class=\"${styles.historySectionWrapper}\">\n\t\t\t\t<div class=\"${styles.historySection}\">\n\t\t\t\t\t${this.#createHistoryItem({\n\t\t\t\t\t\tid: 'placeholder',\n\t\t\t\t\t\tstepNumber: 0,\n\t\t\t\t\t\ttimestamp: new Date(),\n\t\t\t\t\t\ttype: 'thinking',\n\t\t\t\t\t\tdisplayText: this.#i18n.t('ui.panel.waitingPlaceholder'),\n\t\t\t\t\t})}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div class=\"${styles.header}\">\n\t\t\t\t<div class=\"${styles.statusSection}\">\n\t\t\t\t\t<div class=\"${styles.indicator} ${styles.thinking}\"></div>\n\t\t\t\t\t<div class=\"${styles.statusText}\">${this.#i18n.t('ui.panel.ready')}</div>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"${styles.controls}\">\n\t\t\t\t\t<button class=\"${styles.controlButton} ${styles.expandButton}\" title=\"${this.#i18n.t('ui.panel.expand')}\">\n\t\t\t\t\t\t▼\n\t\t\t\t\t</button>\n\t\t\t\t\t<button class=\"${styles.controlButton} ${styles.pauseButton}\" title=\"${this.#i18n.t('ui.panel.pause')}\">\n\t\t\t\t\t\t⏸︎\n\t\t\t\t\t</button>\n\t\t\t\t\t<button class=\"${styles.controlButton} ${styles.stopButton}\" title=\"${this.#i18n.t('ui.panel.stop')}\">\n\t\t\t\t\t\tX\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div class=\"${styles.inputSectionWrapper} ${styles.hidden}\">\n\t\t\t\t<div class=\"${styles.inputSection}\">\n\t\t\t\t\t<input \n\t\t\t\t\t\ttype=\"text\" \n\t\t\t\t\t\tclass=\"${styles.taskInput}\" \n\t\t\t\t\t\tmaxlength=\"200\"\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t`\n\n\t\tdocument.body.appendChild(wrapper)\n\t\treturn wrapper\n\t}\n\n\t#setupEventListeners(): void {\n\t\t// Click header area to expand/collapse\n\t\tconst header = this.wrapper.querySelector(`.${styles.header}`)!\n\t\theader.addEventListener('click', (e) => {\n\t\t\t// Don't trigger expand/collapse if clicking on buttons\n\t\t\tif ((e.target as HTMLElement).closest(`.${styles.controlButton}`)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.#toggle()\n\t\t})\n\n\t\t// Expand button\n\t\tthis.#expandButton.addEventListener('click', (e) => {\n\t\t\te.stopPropagation()\n\t\t\tthis.#toggle()\n\t\t})\n\n\t\t// Pause/continue button\n\t\tthis.#pauseButton.addEventListener('click', (e) => {\n\t\t\te.stopPropagation()\n\t\t\tthis.#togglePause()\n\t\t})\n\n\t\t// Stop button\n\t\tthis.#stopButton.addEventListener('click', (e) => {\n\t\t\te.stopPropagation()\n\t\t\tthis.#stopAgent()\n\t\t})\n\n\t\t// Submit on Enter key in input field\n\t\tthis.#taskInput.addEventListener('keydown', (e) => {\n\t\t\tif (e.isComposing) return // Ignore IME composition keys\n\t\t\tif (e.key === 'Enter') {\n\t\t\t\te.preventDefault()\n\t\t\t\tthis.#submitTask()\n\t\t\t}\n\t\t})\n\n\t\t// Prevent input area click event bubbling\n\t\tthis.#inputSection.addEventListener('click', (e) => {\n\t\t\te.stopPropagation()\n\t\t})\n\t}\n\n\t#toggle(): void {\n\t\tif (this.#isExpanded) {\n\t\t\tthis.#collapse()\n\t\t} else {\n\t\t\tthis.#expand()\n\t\t}\n\t}\n\n\t#expand(): void {\n\t\tthis.#isExpanded = true\n\t\tthis.wrapper.classList.remove(styles.collapsed)\n\t\tthis.wrapper.classList.add(styles.expanded)\n\t\tthis.#expandButton.textContent = '▲'\n\t}\n\n\t#collapse(): void {\n\t\tthis.#isExpanded = false\n\t\tthis.wrapper.classList.remove(styles.expanded)\n\t\tthis.wrapper.classList.add(styles.collapsed)\n\t\tthis.#expandButton.textContent = '▼'\n\t}\n\n\t/**\n\t * Start periodic header update loop\n\t */\n\t#startHeaderUpdateLoop(): void {\n\t\t// Check every 450ms (same as total animation duration)\n\t\tthis.#headerUpdateTimer = setInterval(() => {\n\t\t\tthis.#checkAndUpdateHeader()\n\t\t}, 450)\n\t}\n\n\t/**\n\t * Stop periodic header update loop\n\t */\n\t#stopHeaderUpdateLoop(): void {\n\t\tif (this.#headerUpdateTimer) {\n\t\t\tclearInterval(this.#headerUpdateTimer)\n\t\t\tthis.#headerUpdateTimer = null\n\t\t}\n\t}\n\n\t/**\n\t * Check if header needs update and trigger animation if not currently animating\n\t */\n\t#checkAndUpdateHeader(): void {\n\t\t// If no pending text or currently animating, skip\n\t\tif (!this.#pendingHeaderText || this.#isAnimating) {\n\t\t\treturn\n\t\t}\n\n\t\t// If text is already displayed, clear pending and skip\n\t\tif (this.#statusText.textContent === this.#pendingHeaderText) {\n\t\t\tthis.#pendingHeaderText = null\n\t\t\treturn\n\t\t}\n\n\t\t// Start animation\n\t\tconst textToShow = this.#pendingHeaderText\n\t\tthis.#pendingHeaderText = null\n\t\tthis.#animateTextChange(textToShow)\n\t}\n\n\t/**\n\t * Animate text change with fade out/in effect\n\t */\n\t#animateTextChange(newText: string): void {\n\t\tthis.#isAnimating = true\n\n\t\t// Fade out current text\n\t\tthis.#statusText.classList.add(styles.fadeOut)\n\n\t\tsetTimeout(() => {\n\t\t\t// Update text content\n\t\t\tthis.#statusText.textContent = newText\n\n\t\t\t// Fade in new text\n\t\t\tthis.#statusText.classList.remove(styles.fadeOut)\n\t\t\tthis.#statusText.classList.add(styles.fadeIn)\n\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.#statusText.classList.remove(styles.fadeIn)\n\t\t\t\tthis.#isAnimating = false\n\t\t\t}, 300)\n\t\t}, 150) // Half the duration of fade out animation\n\t}\n\n\t#updateStatusIndicator(type: Step['type']): void {\n\t\t// Clear all status classes\n\t\tthis.#indicator.className = styles.indicator\n\n\t\t// Add corresponding status class\n\t\tthis.#indicator.classList.add(styles[type])\n\t}\n\n\t#updateHistory(): void {\n\t\tconst steps = this.#state.getAllSteps()\n\n\t\tthis.#historySection.innerHTML = steps.map((step) => this.#createHistoryItem(step)).join('')\n\n\t\t// Scroll to bottom to show latest records\n\t\tthis.#scrollToBottom()\n\t}\n\n\t#scrollToBottom(): void {\n\t\t// Execute in next event loop to ensure DOM update completion\n\t\tsetTimeout(() => {\n\t\t\tthis.#historySection.scrollTop = this.#historySection.scrollHeight\n\t\t}, 0)\n\t}\n\n\t#createHistoryItem(step: Step): string {\n\t\tconst time = step.timestamp.toLocaleTimeString('zh-CN', {\n\t\t\thour12: false,\n\t\t\thour: '2-digit',\n\t\t\tminute: '2-digit',\n\t\t\tsecond: '2-digit',\n\t\t})\n\n\t\tlet typeClass = ''\n\t\tlet statusIcon = ''\n\n\t\t// Set styles and icons based on step type\n\t\tif (step.type === 'completed') {\n\t\t\t// Check if this is a result from done tool\n\t\t\tif (step.toolName === 'done') {\n\t\t\t\t// Judge success or failure based on result\n\t\t\t\tconst failureKeyword = this.#i18n.t('ui.tools.resultFailure')\n\t\t\t\tconst errorKeyword = this.#i18n.t('ui.tools.resultError')\n\t\t\t\tconst isSuccess =\n\t\t\t\t\t!step.toolResult ||\n\t\t\t\t\t(!step.toolResult.includes(failureKeyword) && !step.toolResult.includes(errorKeyword))\n\t\t\t\ttypeClass = isSuccess ? styles.doneSuccess : styles.doneError\n\t\t\t\tstatusIcon = isSuccess ? '🎉' : '❌'\n\t\t\t} else {\n\t\t\t\ttypeClass = styles.completed\n\t\t\t\tstatusIcon = '✅'\n\t\t\t}\n\t\t} else if (step.type === 'error') {\n\t\t\ttypeClass = styles.error\n\t\t\tstatusIcon = '❌'\n\t\t} else if (step.type === 'tool_executing') {\n\t\t\tstatusIcon = '⚙️'\n\t\t} else if (step.type === 'output') {\n\t\t\ttypeClass = styles.output\n\t\t\tstatusIcon = '🤖'\n\t\t} else if (step.type === 'input') {\n\t\t\ttypeClass = styles.input\n\t\t\tstatusIcon = '🎯'\n\t\t} else if (step.type === 'retry') {\n\t\t\ttypeClass = styles.retry\n\t\t\tstatusIcon = '🔄'\n\t\t} else {\n\t\t\tstatusIcon = '🧠'\n\t\t}\n\n\t\tconst durationText = step.duration ? ` · ${step.duration}ms` : ''\n\t\tconst stepLabel = this.#i18n.t('ui.panel.step', {\n\t\t\tnumber: step.stepNumber.toString(),\n\t\t\ttime,\n\t\t\tduration: durationText || '', // Explicitly pass empty string to replace template\n\t\t})\n\n\t\treturn `\n\t\t\t<div class=\"${styles.historyItem} ${typeClass}\">\n\t\t\t\t<div class=\"${styles.historyContent}\">\n\t\t\t\t\t<span class=\"${styles.statusIcon}\">${statusIcon}</span>\n\t\t\t\t\t<span>${step.displayText}</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"${styles.historyMeta}\">\n\t\t\t\t\t${stepLabel}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t`\n\t}\n}\n","/**\n * Checks for common dark mode CSS classes on the html or body elements.\n * @returns {boolean} - True if a common dark mode class is found.\n */\nfunction hasDarkModeClass() {\n\tconst DEFAULT_DARK_MODE_CLASSES = ['dark', 'dark-mode', 'theme-dark', 'night', 'night-mode']\n\n\tconst htmlElement = document.documentElement\n\tconst bodyElement = document.body || document.documentElement // can be null in some cases\n\n\t// Check class names on <html> and <body>\n\tfor (const className of DEFAULT_DARK_MODE_CLASSES) {\n\t\tif (htmlElement.classList.contains(className) || bodyElement?.classList.contains(className)) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\t// Some sites use data attributes\n\tconst darkThemeAttribute = htmlElement.getAttribute('data-theme')\n\tif (darkThemeAttribute?.toLowerCase().includes('dark')) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n/**\n * Parses an RGB or RGBA color string and returns an object with r, g, b properties.\n * @param {string} colorString - e.g., \"rgb(34, 34, 34)\" or \"rgba(0, 0, 0, 0.5)\"\n * @returns {{r: number, g: number, b: number}|null}\n */\nfunction parseRgbColor(colorString: string) {\n\tconst rgbMatch = /rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)/.exec(colorString)\n\tif (!rgbMatch) {\n\t\treturn null // Not a valid rgb/rgba string\n\t}\n\treturn {\n\t\tr: parseInt(rgbMatch[1]),\n\t\tg: parseInt(rgbMatch[2]),\n\t\tb: parseInt(rgbMatch[3]),\n\t}\n}\n\n/**\n * Determines if a color is \"dark\" based on its calculated luminance.\n * @param {string} colorString - The CSS color string (e.g., \"rgb(50, 50, 50)\").\n * @param {number} threshold - A value between 0 and 255. Colors with luminance below this will be considered dark. Default is 128.\n * @returns {boolean} - True if the color is considered dark.\n */\nfunction isColorDark(colorString: string, threshold = 128) {\n\tif (!colorString || colorString === 'transparent' || colorString.startsWith('rgba(0, 0, 0, 0)')) {\n\t\treturn false // Transparent is not dark\n\t}\n\n\tconst rgb = parseRgbColor(colorString)\n\tif (!rgb) {\n\t\treturn false // Could not parse color\n\t}\n\n\t// Calculate perceived luminance using the standard formula\n\tconst luminance = 0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b\n\n\treturn luminance < threshold\n}\n\n/**\n * Checks the background color of the body element to determine if the page is dark.\n * @returns {boolean}\n */\nfunction isBackgroundDark() {\n\t// We check both <html> and <body> because some pages set the color on <html>\n\tconst htmlStyle = window.getComputedStyle(document.documentElement)\n\tconst bodyStyle = window.getComputedStyle(document.body || document.documentElement)\n\n\t// Get background colors\n\tconst htmlBgColor = htmlStyle.backgroundColor\n\tconst bodyBgColor = bodyStyle.backgroundColor\n\n\t// The body's background might be transparent, in which case we should\n\t// fall back to the html element's background.\n\tif (isColorDark(bodyBgColor)) {\n\t\treturn true\n\t} else if (bodyBgColor === 'transparent' || bodyBgColor.startsWith('rgba(0, 0, 0, 0)')) {\n\t\treturn isColorDark(htmlBgColor)\n\t}\n\n\treturn false\n}\n\n/**\n * A comprehensive function to determine if the page is currently in a dark theme.\n * It combines class checking and background color analysis.\n * @returns {boolean} - True if the page is likely dark.\n */\nexport function isPageDark() {\n\ttry {\n\t\t// Strategy 1: Check for common dark mode classes\n\t\tif (hasDarkModeClass()) {\n\t\t\treturn true\n\t\t}\n\n\t\t// Strategy 2: Analyze the computed background color\n\t\tif (isBackgroundDark()) {\n\t\t\treturn true\n\t\t}\n\n\t\t// @TODO add more checks here, e.g., analyzing text color,\n\t\t// or checking the background of major layout elements like <main> or #app.\n\n\t\treturn false\n\t} catch (error) {\n\t\tconsole.warn('Error determining if page is dark:', error)\n\t\treturn false\n\t}\n}\n","import { Motion } from 'ai-motion'\n\nimport { isPageDark } from './checkDarkMode'\n\nimport styles from './SimulatorMask.module.css'\nimport cursorStyles from './cursor.module.css'\n\nexport class SimulatorMask {\n\twrapper = document.createElement('div')\n\tmotion = new Motion({\n\t\tmode: isPageDark() ? 'dark' : 'light',\n\t\tstyles: {\n\t\t\tposition: 'absolute',\n\t\t\tinset: '0',\n\t\t},\n\t})\n\n\t#cursor = document.createElement('div')\n\n\t#currentCursorX = 0\n\t#currentCursorY = 0\n\n\t#targetCursorX = 0\n\t#targetCursorY = 0\n\n\tconstructor() {\n\t\tthis.wrapper.id = 'page-agent-runtime_simulator-mask'\n\t\tthis.wrapper.className = styles.wrapper\n\t\tthis.wrapper.setAttribute('data-browser-use-ignore', 'true')\n\n\t\tthis.wrapper.appendChild(this.motion.element)\n\t\tthis.motion.autoResize(this.wrapper)\n\n\t\t// Capture all mouse, keyboard, and wheel events\n\t\tthis.wrapper.addEventListener('click', (e) => {\n\t\t\te.stopPropagation()\n\t\t\te.preventDefault()\n\t\t})\n\t\tthis.wrapper.addEventListener('mousedown', (e) => {\n\t\t\te.stopPropagation()\n\t\t\te.preventDefault()\n\t\t})\n\t\tthis.wrapper.addEventListener('mouseup', (e) => {\n\t\t\te.stopPropagation()\n\t\t\te.preventDefault()\n\t\t})\n\t\tthis.wrapper.addEventListener('mousemove', (e) => {\n\t\t\te.stopPropagation()\n\t\t\te.preventDefault()\n\t\t})\n\t\tthis.wrapper.addEventListener('wheel', (e) => {\n\t\t\te.stopPropagation()\n\t\t\te.preventDefault()\n\t\t})\n\t\tthis.wrapper.addEventListener('keydown', (e) => {\n\t\t\te.stopPropagation()\n\t\t\te.preventDefault()\n\t\t})\n\t\tthis.wrapper.addEventListener('keyup', (e) => {\n\t\t\te.stopPropagation()\n\t\t\te.preventDefault()\n\t\t})\n\n\t\t// Create AI cursor\n\t\tthis.#createCursor()\n\t\t// this.show()\n\n\t\tdocument.body.appendChild(this.wrapper)\n\n\t\tthis.#moveCursorToTarget()\n\n\t\twindow.addEventListener('PageAgent::MovePointerTo', (event: Event) => {\n\t\t\tconst { x, y } = (event as CustomEvent).detail\n\t\t\tthis.setCursorPosition(x, y)\n\t\t})\n\n\t\twindow.addEventListener('PageAgent::ClickPointer', (event: Event) => {\n\t\t\tthis.triggerClickAnimation()\n\t\t})\n\t}\n\n\t#createCursor() {\n\t\tthis.#cursor.className = cursorStyles.cursor\n\n\t\t// Create ripple effect container\n\t\tconst rippleContainer = document.createElement('div')\n\t\trippleContainer.className = cursorStyles.cursorRipple\n\t\tthis.#cursor.appendChild(rippleContainer)\n\n\t\t// Create filling layer\n\t\tconst fillingLayer = document.createElement('div')\n\t\tfillingLayer.className = cursorStyles.cursorFilling\n\t\tthis.#cursor.appendChild(fillingLayer)\n\n\t\t// Create border layer\n\t\tconst borderLayer = document.createElement('div')\n\t\tborderLayer.className = cursorStyles.cursorBorder\n\t\tthis.#cursor.appendChild(borderLayer)\n\n\t\tthis.wrapper.appendChild(this.#cursor)\n\t}\n\n\t#moveCursorToTarget() {\n\t\tconst newX = this.#currentCursorX + (this.#targetCursorX - this.#currentCursorX) * 0.2\n\t\tconst newY = this.#currentCursorY + (this.#targetCursorY - this.#currentCursorY) * 0.2\n\n\t\tconst xDistance = Math.abs(newX - this.#targetCursorX)\n\t\tif (xDistance > 0) {\n\t\t\tif (xDistance < 2) {\n\t\t\t\tthis.#currentCursorX = this.#targetCursorX\n\t\t\t} else {\n\t\t\t\tthis.#currentCursorX = newX\n\t\t\t}\n\t\t\tthis.#cursor.style.left = `${this.#currentCursorX}px`\n\t\t}\n\n\t\tconst yDistance = Math.abs(newY - this.#targetCursorY)\n\t\tif (yDistance > 0) {\n\t\t\tif (yDistance < 2) {\n\t\t\t\tthis.#currentCursorY = this.#targetCursorY\n\t\t\t} else {\n\t\t\t\tthis.#currentCursorY = newY\n\t\t\t}\n\t\t\tthis.#cursor.style.top = `${this.#currentCursorY}px`\n\t\t}\n\n\t\trequestAnimationFrame(() => this.#moveCursorToTarget())\n\t}\n\n\tsetCursorPosition(x: number, y: number) {\n\t\tthis.#targetCursorX = x\n\t\tthis.#targetCursorY = y\n\t}\n\n\ttriggerClickAnimation() {\n\t\tthis.#cursor.classList.remove(cursorStyles.clicking)\n\t\t// Force reflow to restart animation\n\t\tvoid this.#cursor.offsetHeight\n\t\tthis.#cursor.classList.add(cursorStyles.clicking)\n\t}\n\n\tshow() {\n\t\tthis.motion.start()\n\t\tthis.motion.fadeIn()\n\n\t\tthis.wrapper.style.display = 'block'\n\n\t\t// Initialize cursor position\n\t\tthis.#currentCursorX = window.innerWidth / 2\n\t\tthis.#currentCursorY = window.innerHeight / 2\n\t\tthis.#targetCursorX = this.#currentCursorX\n\t\tthis.#targetCursorY = this.#currentCursorY\n\t\tthis.#cursor.style.left = `${this.#currentCursorX}px`\n\t\tthis.#cursor.style.top = `${this.#currentCursorY}px`\n\t}\n\n\thide() {\n\t\tthis.motion.fadeOut()\n\t\tthis.motion.pause()\n\n\t\tthis.#cursor.classList.remove(cursorStyles.clicking)\n\n\t\tsetTimeout(() => {\n\t\t\tthis.wrapper.style.display = 'none'\n\t\t}, 800) // Match the animation duration\n\t}\n\n\tdispose() {\n\t\tthis.motion.dispose()\n\t\tthis.wrapper.remove()\n\t}\n}\n"],"names":["styles","paused","input","wrapper","header","statusIcon","error"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"page-agent-ui.js","sources":["../../src/UIState.ts","../../src/i18n/locales.ts","../../src/i18n/index.ts","../../src/utils.ts","../../src/Panel.ts"],"sourcesContent":["/**\n * Agent execution state management\n */\n\nexport interface Step {\n\tid: string\n\tstepNumber: number\n\ttimestamp: Date\n\ttype: 'thinking' | 'tool_executing' | 'completed' | 'error' | 'output' | 'input' | 'retry'\n\n\t// Tool execution related\n\ttoolName?: string\n\ttoolArgs?: any\n\ttoolResult?: any\n\n\t// Display data\n\tdisplayText: string\n\tduration?: number\n}\n\nexport type AgentStatus = 'idle' | 'running' | 'paused' | 'completed' | 'error'\n\nexport class UIState {\n\tprivate steps: Step[] = []\n\tprivate currentStep: Step | null = null\n\tprivate status: AgentStatus = 'idle'\n\tprivate stepCounter = 0\n\n\taddStep(stepData: Omit<Step, 'id' | 'stepNumber' | 'timestamp'>): Step {\n\t\tconst step: Step = {\n\t\t\tid: this.generateId(),\n\t\t\tstepNumber: ++this.stepCounter,\n\t\t\ttimestamp: new Date(),\n\t\t\t...stepData,\n\t\t}\n\n\t\tthis.steps.push(step)\n\t\tthis.currentStep = step\n\n\t\t// Update overall status\n\t\tthis.updateStatus(step.type)\n\n\t\treturn step\n\t}\n\n\tupdateCurrentStep(updates: Partial<Step>): Step | null {\n\t\tif (!this.currentStep) return null\n\n\t\tObject.assign(this.currentStep, updates)\n\t\treturn this.currentStep\n\t}\n\n\tgetCurrentStep(): Step | null {\n\t\treturn this.currentStep\n\t}\n\n\tgetAllSteps(): Step[] {\n\t\treturn [...this.steps]\n\t}\n\n\tgetStatus(): AgentStatus {\n\t\treturn this.status\n\t}\n\n\treset(): void {\n\t\tthis.steps = []\n\t\tthis.currentStep = null\n\t\tthis.status = 'idle'\n\t\tthis.stepCounter = 0\n\t}\n\n\tprivate updateStatus(stepType: Step['type']): void {\n\t\tswitch (stepType) {\n\t\t\tcase 'thinking':\n\t\t\tcase 'tool_executing':\n\t\t\tcase 'output':\n\t\t\tcase 'input':\n\t\t\tcase 'retry':\n\t\t\t\tthis.status = 'running'\n\t\t\t\tbreak\n\t\t\tcase 'completed':\n\t\t\t\tthis.status = 'completed'\n\t\t\t\tbreak\n\t\t\tcase 'error':\n\t\t\t\tthis.status = 'error'\n\t\t\t\tbreak\n\t\t}\n\t}\n\n\tprivate generateId(): string {\n\t\treturn `step_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`\n\t}\n}\n","// English translations (base/reference language)\nconst enUS = {\n\tui: {\n\t\tpanel: {\n\t\t\tready: 'Ready',\n\t\t\tthinking: 'Thinking...',\n\t\t\tpaused: 'Paused',\n\t\t\ttaskInput: 'Enter new task, describe steps in detail, press Enter to submit',\n\t\t\tuserAnswerPrompt: 'Please answer the question above, press Enter to submit',\n\t\t\ttaskTerminated: 'Task terminated',\n\t\t\ttaskCompleted: 'Task completed',\n\t\t\tcontinueExecution: 'Continue execution',\n\t\t\tuserAnswer: 'User answer: {{input}}',\n\t\t\tquestion: 'Question: {{question}}',\n\t\t\twaitingPlaceholder: 'Waiting for task to start...',\n\t\t\tpause: 'Pause',\n\t\t\tcontinue: 'Continue',\n\t\t\tstop: 'Stop',\n\t\t\texpand: 'Expand history',\n\t\t\tcollapse: 'Collapse history',\n\t\t\tstep: 'Step {{number}} · {{time}}{{duration}}',\n\t\t},\n\t\ttools: {\n\t\t\tclicking: 'Clicking element [{{index}}]...',\n\t\t\tinputting: 'Inputting text to element [{{index}}]...',\n\t\t\tselecting: 'Selecting option \"{{text}}\"...',\n\t\t\tscrolling: 'Scrolling page...',\n\t\t\twaiting: 'Waiting {{seconds}} seconds...',\n\t\t\tdone: 'Task done',\n\t\t\tclicked: '🖱️ Clicked element [{{index}}]',\n\t\t\tinputted: '⌨️ Inputted text \"{{text}}\"',\n\t\t\tselected: '☑️ Selected option \"{{text}}\"',\n\t\t\tscrolled: '🛞 Page scrolled',\n\t\t\twaited: '⌛️ Wait completed',\n\t\t\texecuting: 'Executing {{toolName}}...',\n\t\t\tresultSuccess: 'success',\n\t\t\tresultFailure: 'failed',\n\t\t\tresultError: 'error',\n\t\t},\n\t\terrors: {\n\t\t\telementNotFound: 'No interactive element found at index {{index}}',\n\t\t\ttaskRequired: 'Task description is required',\n\t\t\texecutionFailed: 'Task execution failed',\n\t\t\tnotInputElement: 'Element is not an input or textarea',\n\t\t\tnotSelectElement: 'Element is not a select element',\n\t\t\toptionNotFound: 'Option \"{{text}}\" not found',\n\t\t},\n\t},\n} as const\n\n// Chinese translations (must match the structure of enUS)\nconst zhCN = {\n\tui: {\n\t\tpanel: {\n\t\t\tready: '准备就绪',\n\t\t\tthinking: '正在思考...',\n\t\t\tpaused: '暂停中,稍后',\n\t\t\ttaskInput: '输入新任务,详细描述步骤,回车提交',\n\t\t\tuserAnswerPrompt: '请回答上面问题,回车提交',\n\t\t\ttaskTerminated: '任务已终止',\n\t\t\ttaskCompleted: '任务结束',\n\t\t\tcontinueExecution: '继续执行',\n\t\t\tuserAnswer: '用户回答: {{input}}',\n\t\t\tquestion: '询问: {{question}}',\n\t\t\twaitingPlaceholder: '等待任务开始...',\n\t\t\tpause: '暂停',\n\t\t\tcontinue: '继续',\n\t\t\tstop: '终止',\n\t\t\texpand: '展开历史',\n\t\t\tcollapse: '收起历史',\n\t\t\tstep: '步骤 {{number}} · {{time}}{{duration}}',\n\t\t},\n\t\ttools: {\n\t\t\tclicking: '正在点击元素 [{{index}}]...',\n\t\t\tinputting: '正在输入文本到元素 [{{index}}]...',\n\t\t\tselecting: '正在选择选项 \"{{text}}\"...',\n\t\t\tscrolling: '正在滚动页面...',\n\t\t\twaiting: '等待 {{seconds}} 秒...',\n\t\t\tdone: '结束任务',\n\t\t\tclicked: '🖱️ 已点击元素 [{{index}}]',\n\t\t\tinputted: '⌨️ 已输入文本 \"{{text}}\"',\n\t\t\tselected: '☑️ 已选择选项 \"{{text}}\"',\n\t\t\tscrolled: '🛞 页面滚动完成',\n\t\t\twaited: '⌛️ 等待完成',\n\t\t\texecuting: '正在执行 {{toolName}}...',\n\t\t\tresultSuccess: '成功',\n\t\t\tresultFailure: '失败',\n\t\t\tresultError: '错误',\n\t\t},\n\t\terrors: {\n\t\t\telementNotFound: '未找到索引为 {{index}} 的交互元素',\n\t\t\ttaskRequired: '任务描述不能为空',\n\t\t\texecutionFailed: '任务执行失败',\n\t\t\tnotInputElement: '元素不是输入框或文本域',\n\t\t\tnotSelectElement: '元素不是选择框',\n\t\t\toptionNotFound: '未找到选项 \"{{text}}\"',\n\t\t},\n\t},\n} as const\n\n// Type definitions generated from English base structure (but with string values)\ntype DeepStringify<T> = {\n\t[K in keyof T]: T[K] extends string ? string : T[K] extends object ? DeepStringify<T[K]> : T[K]\n}\n\nexport type TranslationSchema = DeepStringify<typeof enUS>\n\n// Utility type: Extract all nested paths from translation object\ntype NestedKeyOf<ObjectType extends object> = {\n\t[Key in keyof ObjectType & (string | number)]: ObjectType[Key] extends object\n\t\t? `${Key}` | `${Key}.${NestedKeyOf<ObjectType[Key]>}`\n\t\t: `${Key}`\n}[keyof ObjectType & (string | number)]\n\n// Extract all possible key paths from translation structure\nexport type TranslationKey = NestedKeyOf<TranslationSchema>\n\n// Parameterized translation types\nexport type TranslationParams = Record<string, string | number>\n\nexport const locales = {\n\t'en-US': enUS,\n\t'zh-CN': zhCN,\n} as const\n\nexport type SupportedLanguage = keyof typeof locales\n","import {\n\ttype SupportedLanguage,\n\ttype TranslationKey,\n\ttype TranslationParams,\n\ttype TranslationSchema,\n\tlocales,\n} from './locales'\n\nexport class I18n {\n\tprivate language: SupportedLanguage\n\tprivate translations: TranslationSchema\n\n\tconstructor(language: SupportedLanguage = 'en-US') {\n\t\tthis.language = language in locales ? language : 'en-US'\n\t\tthis.translations = locales[this.language]\n\t}\n\n\t// 类型安全的翻译方法\n\tt(key: TranslationKey, params?: TranslationParams): string {\n\t\tconst value = this.getNestedValue(this.translations, key)\n\t\tif (!value) {\n\t\t\tconsole.warn(`Translation key \"${key}\" not found for language \"${this.language}\"`)\n\t\t\treturn key\n\t\t}\n\n\t\tif (params) {\n\t\t\treturn this.interpolate(value, params)\n\t\t}\n\t\treturn value\n\t}\n\n\tprivate getNestedValue(obj: any, path: string): string | undefined {\n\t\treturn path.split('.').reduce((current, key) => current?.[key], obj)\n\t}\n\n\tprivate interpolate(template: string, params: TranslationParams): string {\n\t\treturn template.replace(/\\{\\{(\\w+)\\}\\}/g, (match, key) => {\n\t\t\t// Use != null to check for both null and undefined, allow empty strings\n\t\t\treturn params[key] != null ? params[key].toString() : match\n\t\t})\n\t}\n\n\tgetLanguage(): SupportedLanguage {\n\t\treturn this.language\n\t}\n}\n\n// 导出类型和实例创建函数\nexport type { TranslationKey, SupportedLanguage, TranslationParams }\nexport { locales }\n","export function truncate(text: string, maxLength: number): string {\n\tif (text.length > maxLength) {\n\t\treturn text.substring(0, maxLength) + '...'\n\t}\n\treturn text\n}\n","import { type Step, UIState } from './UIState'\nimport { I18n, type SupportedLanguage } from './i18n'\nimport { truncate } from './utils'\n\nimport styles from './Panel.module.css'\n\n/**\n * Panel configuration\n */\nexport interface PanelConfig {\n\tlanguage?: SupportedLanguage\n\tonExecuteTask: (task: string) => void\n\tonStop: () => void\n\tonPauseToggle: () => boolean // returns new paused state\n\tgetPaused: () => boolean\n}\n\n/**\n * Semantic update types - Panel handles i18n internally\n */\nexport type PanelUpdate =\n\t| { type: 'thinking'; text?: string } // text is optional, defaults to i18n thinking text\n\t| { type: 'input'; task: string }\n\t| { type: 'question'; question: string }\n\t| { type: 'userAnswer'; input: string }\n\t| { type: 'retry'; current: number; max: number }\n\t| { type: 'error'; message: string }\n\t| { type: 'output'; text: string }\n\t| { type: 'completed' }\n\t| { type: 'toolExecuting'; toolName: string; args: any }\n\t| { type: 'toolCompleted'; toolName: string; args: any; result?: string; duration?: number }\n\n/**\n * Agent control panel\n */\nexport class Panel {\n\t#wrapper: HTMLElement\n\t#indicator: HTMLElement\n\t#statusText: HTMLElement\n\t#historySection: HTMLElement\n\t#expandButton: HTMLElement\n\t#pauseButton: HTMLElement\n\t#stopButton: HTMLElement\n\t#inputSection: HTMLElement\n\t#taskInput: HTMLInputElement\n\n\t#state = new UIState()\n\t#isExpanded = false\n\t#config: PanelConfig\n\t#i18n: I18n\n\t#userAnswerResolver: ((input: string) => void) | null = null\n\t#isWaitingForUserAnswer: boolean = false\n\t#headerUpdateTimer: ReturnType<typeof setInterval> | null = null\n\t#pendingHeaderText: string | null = null\n\t#isAnimating = false\n\n\tget wrapper(): HTMLElement {\n\t\treturn this.#wrapper\n\t}\n\n\tconstructor(config: PanelConfig) {\n\t\tthis.#config = config\n\t\tthis.#i18n = new I18n(config.language ?? 'en-US')\n\t\tthis.#wrapper = this.#createWrapper()\n\t\tthis.#indicator = this.#wrapper.querySelector(`.${styles.indicator}`)!\n\t\tthis.#statusText = this.#wrapper.querySelector(`.${styles.statusText}`)!\n\t\tthis.#historySection = this.#wrapper.querySelector(`.${styles.historySection}`)!\n\t\tthis.#expandButton = this.#wrapper.querySelector(`.${styles.expandButton}`)!\n\t\tthis.#pauseButton = this.#wrapper.querySelector(`.${styles.pauseButton}`)!\n\t\tthis.#stopButton = this.#wrapper.querySelector(`.${styles.stopButton}`)!\n\t\tthis.#inputSection = this.#wrapper.querySelector(`.${styles.inputSectionWrapper}`)!\n\t\tthis.#taskInput = this.#wrapper.querySelector(`.${styles.taskInput}`)!\n\n\t\tthis.#setupEventListeners()\n\t\tthis.#startHeaderUpdateLoop()\n\n\t\tthis.#showInputArea()\n\t}\n\n\t/**\n\t * Ask for user input\n\t */\n\tasync askUser(question: string): Promise<string> {\n\t\treturn new Promise((resolve) => {\n\t\t\t// Set `waiting for user answer` state\n\t\t\tthis.#isWaitingForUserAnswer = true\n\t\t\tthis.#userAnswerResolver = resolve\n\n\t\t\t// Update state to `running`\n\t\t\tthis.#updateInternal({\n\t\t\t\ttype: 'output',\n\t\t\t\tdisplayText: this.#i18n.t('ui.panel.question', { question }),\n\t\t\t}) // Expand history panel\n\t\t\tif (!this.#isExpanded) {\n\t\t\t\tthis.#expand()\n\t\t\t}\n\n\t\t\tthis.#showInputArea(this.#i18n.t('ui.panel.userAnswerPrompt'))\n\t\t})\n\t}\n\n\t// ========== Public control methods ==========\n\n\tshow(): void {\n\t\tthis.wrapper.style.display = 'block'\n\t\tvoid this.wrapper.offsetHeight\n\t\tthis.wrapper.style.opacity = '1'\n\t\tthis.wrapper.style.transform = 'translateX(-50%) translateY(0)'\n\t}\n\n\thide(): void {\n\t\tthis.wrapper.style.opacity = '0'\n\t\tthis.wrapper.style.transform = 'translateX(-50%) translateY(20px)'\n\t\tthis.wrapper.style.display = 'none'\n\t}\n\n\treset(): void {\n\t\tthis.#state.reset()\n\t\tthis.#statusText.textContent = this.#i18n.t('ui.panel.ready')\n\t\tthis.#updateStatusIndicator('thinking')\n\t\tthis.#updateHistory()\n\t\tthis.#collapse()\n\t\t// Reset pause state via callback\n\t\tif (this.#config.getPaused()) {\n\t\t\tthis.#config.onPauseToggle()\n\t\t}\n\t\tthis.#updatePauseButton()\n\t\t// Reset user input state\n\t\tthis.#isWaitingForUserAnswer = false\n\t\tthis.#userAnswerResolver = null\n\t\t// Show input area\n\t\tthis.#showInputArea()\n\t}\n\n\texpand(): void {\n\t\tthis.#expand()\n\t}\n\n\tcollapse(): void {\n\t\tthis.#collapse()\n\t}\n\n\t/**\n\t * Update panel with semantic data - i18n handled internally\n\t */\n\tupdate(data: PanelUpdate): void {\n\t\tconst stepData = this.#toStepData(data)\n\t\tthis.#updateInternal(stepData)\n\t}\n\n\t/**\n\t * Dispose panel\n\t */\n\tdispose(): void {\n\t\tthis.#isWaitingForUserAnswer = false\n\t\tthis.#stopHeaderUpdateLoop()\n\t\tthis.wrapper.remove()\n\t}\n\n\t// ========== Private methods ==========\n\n\t/**\n\t * Convert semantic update to step data with i18n\n\t */\n\t#toStepData(data: PanelUpdate): Omit<Step, 'id' | 'stepNumber' | 'timestamp'> {\n\t\tswitch (data.type) {\n\t\t\tcase 'thinking':\n\t\t\t\treturn { type: 'thinking', displayText: data.text ?? this.#i18n.t('ui.panel.thinking') }\n\t\t\tcase 'input':\n\t\t\t\treturn { type: 'input', displayText: data.task }\n\t\t\tcase 'question':\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'output',\n\t\t\t\t\tdisplayText: this.#i18n.t('ui.panel.question', { question: data.question }),\n\t\t\t\t}\n\t\t\tcase 'userAnswer':\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'input',\n\t\t\t\t\tdisplayText: this.#i18n.t('ui.panel.userAnswer', { input: data.input }),\n\t\t\t\t}\n\t\t\tcase 'retry':\n\t\t\t\treturn { type: 'retry', displayText: `retry-ing (${data.current} / ${data.max})` }\n\t\t\tcase 'error':\n\t\t\t\treturn { type: 'error', displayText: data.message }\n\t\t\tcase 'output':\n\t\t\t\treturn { type: 'output', displayText: data.text }\n\t\t\tcase 'completed':\n\t\t\t\treturn { type: 'completed', displayText: this.#i18n.t('ui.panel.taskCompleted') }\n\t\t\tcase 'toolExecuting':\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'tool_executing',\n\t\t\t\t\ttoolName: data.toolName,\n\t\t\t\t\ttoolArgs: data.args,\n\t\t\t\t\tdisplayText: this.#getToolExecutingText(data.toolName, data.args),\n\t\t\t\t}\n\t\t\tcase 'toolCompleted': {\n\t\t\t\tconst displayText = this.#getToolCompletedText(data.toolName, data.args)\n\t\t\t\tif (!displayText) return { type: 'tool_executing', displayText: '' } // will be filtered\n\t\t\t\treturn {\n\t\t\t\t\ttype: 'tool_executing',\n\t\t\t\t\ttoolName: data.toolName,\n\t\t\t\t\ttoolArgs: data.args,\n\t\t\t\t\ttoolResult: data.result,\n\t\t\t\t\tdisplayText,\n\t\t\t\t\tduration: data.duration,\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t#getToolExecutingText(toolName: string, args: any): string {\n\t\tswitch (toolName) {\n\t\t\tcase 'click_element_by_index':\n\t\t\t\treturn this.#i18n.t('ui.tools.clicking', { index: args.index })\n\t\t\tcase 'input_text':\n\t\t\t\treturn this.#i18n.t('ui.tools.inputting', { index: args.index })\n\t\t\tcase 'select_dropdown_option':\n\t\t\t\treturn this.#i18n.t('ui.tools.selecting', { text: args.text })\n\t\t\tcase 'scroll':\n\t\t\t\treturn this.#i18n.t('ui.tools.scrolling')\n\t\t\tcase 'wait':\n\t\t\t\treturn this.#i18n.t('ui.tools.waiting', { seconds: args.seconds })\n\t\t\tcase 'done':\n\t\t\t\treturn this.#i18n.t('ui.tools.done')\n\t\t\tdefault:\n\t\t\t\treturn this.#i18n.t('ui.tools.executing', { toolName })\n\t\t}\n\t}\n\n\t#getToolCompletedText(toolName: string, args: any): string | null {\n\t\tswitch (toolName) {\n\t\t\tcase 'click_element_by_index':\n\t\t\t\treturn this.#i18n.t('ui.tools.clicked', { index: args.index })\n\t\t\tcase 'input_text':\n\t\t\t\treturn this.#i18n.t('ui.tools.inputted', { text: args.text })\n\t\t\tcase 'select_dropdown_option':\n\t\t\t\treturn this.#i18n.t('ui.tools.selected', { text: args.text })\n\t\t\tcase 'scroll':\n\t\t\t\treturn this.#i18n.t('ui.tools.scrolled')\n\t\t\tcase 'wait':\n\t\t\t\treturn this.#i18n.t('ui.tools.waited')\n\t\t\tcase 'done':\n\t\t\t\treturn null\n\t\t\tdefault:\n\t\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Update status (internal)\n\t */\n\t#updateInternal(stepData: Omit<Step, 'id' | 'stepNumber' | 'timestamp'>): void {\n\t\t// Skip empty displayText (filtered toolCompleted for 'done')\n\t\tif (!stepData.displayText) return\n\n\t\tconst step = this.#state.addStep(stepData)\n\n\t\t// Queue header text update (will be processed by periodic check)\n\t\tconst headerText = truncate(step.displayText, 20)\n\t\tthis.#pendingHeaderText = headerText\n\n\t\tthis.#updateStatusIndicator(step.type)\n\t\tthis.#updateHistory()\n\n\t\t// Auto-expand history after task completion\n\t\tif (step.type === 'completed' || step.type === 'error') {\n\t\t\tif (!this.#isExpanded) {\n\t\t\t\tthis.#expand()\n\t\t\t}\n\t\t}\n\n\t\t// Control input area display based on status\n\t\tif (this.#shouldShowInputArea()) {\n\t\t\tthis.#showInputArea()\n\t\t} else {\n\t\t\tthis.#hideInputArea()\n\t\t}\n\t}\n\n\t/**\n\t * Toggle pause state\n\t */\n\t#togglePause(): void {\n\t\tconst paused = this.#config.onPauseToggle()\n\t\tthis.#updatePauseButton()\n\n\t\t// Update status display\n\t\tif (paused) {\n\t\t\tthis.#statusText.textContent = this.#i18n.t('ui.panel.paused')\n\t\t\tthis.#updateStatusIndicator('thinking')\n\t\t} else {\n\t\t\tthis.#statusText.textContent = this.#i18n.t('ui.panel.continueExecution')\n\t\t\tthis.#updateStatusIndicator('tool_executing')\n\t\t}\n\t}\n\n\t/**\n\t * Update pause button state\n\t */\n\t#updatePauseButton(): void {\n\t\tconst paused = this.#config.getPaused()\n\t\tif (paused) {\n\t\t\tthis.#pauseButton.textContent = '▶'\n\t\t\tthis.#pauseButton.title = this.#i18n.t('ui.panel.continue')\n\t\t\tthis.#pauseButton.classList.add(styles.paused)\n\t\t} else {\n\t\t\tthis.#pauseButton.textContent = '⏸︎'\n\t\t\tthis.#pauseButton.title = this.#i18n.t('ui.panel.pause')\n\t\t\tthis.#pauseButton.classList.remove(styles.paused)\n\t\t}\n\t}\n\n\t/**\n\t * Stop Agent\n\t */\n\t#stopAgent(): void {\n\t\t// Update status display\n\t\tthis.#updateInternal({\n\t\t\ttype: 'error',\n\t\t\tdisplayText: this.#i18n.t('ui.panel.taskTerminated'),\n\t\t})\n\n\t\tthis.#config.onStop()\n\t}\n\n\t/**\n\t * Submit task\n\t */\n\t#submitTask() {\n\t\tconst input = this.#taskInput.value.trim()\n\t\tif (!input) return\n\n\t\t// Hide input area\n\t\tthis.#hideInputArea()\n\n\t\tif (this.#isWaitingForUserAnswer) {\n\t\t\t// Handle user input mode\n\t\t\tthis.#handleUserAnswer(input)\n\t\t} else {\n\t\t\tthis.#config.onExecuteTask(input)\n\t\t}\n\t}\n\n\t/**\n\t * Handle user answer\n\t */\n\t#handleUserAnswer(input: string): void {\n\t\t// Add user input to history\n\t\tthis.#updateInternal({\n\t\t\ttype: 'input',\n\t\t\tdisplayText: this.#i18n.t('ui.panel.userAnswer', { input }),\n\t\t})\n\n\t\t// Reset state\n\t\tthis.#isWaitingForUserAnswer = false\n\n\t\t// Call resolver to return user input\n\t\tif (this.#userAnswerResolver) {\n\t\t\tthis.#userAnswerResolver(input)\n\t\t\tthis.#userAnswerResolver = null\n\t\t}\n\t}\n\n\t/**\n\t * Show input area\n\t */\n\t#showInputArea(placeholder?: string): void {\n\t\t// Clear input field\n\t\tthis.#taskInput.value = ''\n\t\tthis.#taskInput.placeholder = placeholder || this.#i18n.t('ui.panel.taskInput')\n\t\tthis.#inputSection.classList.remove(styles.hidden)\n\t\t// Focus on input field\n\t\tsetTimeout(() => {\n\t\t\tthis.#taskInput.focus()\n\t\t}, 100)\n\t}\n\n\t/**\n\t * Hide input area\n\t */\n\t#hideInputArea(): void {\n\t\tthis.#inputSection.classList.add(styles.hidden)\n\t}\n\n\t/**\n\t * Check if input area should be shown\n\t */\n\t#shouldShowInputArea(): boolean {\n\t\t// Always show input area if waiting for user input\n\t\tif (this.#isWaitingForUserAnswer) return true\n\n\t\tconst steps = this.#state.getAllSteps()\n\t\tif (steps.length === 0) {\n\t\t\treturn true // Initial state\n\t\t}\n\n\t\tconst lastStep = steps[steps.length - 1]\n\t\treturn lastStep.type === 'completed' || lastStep.type === 'error'\n\t}\n\n\t#createWrapper(): HTMLElement {\n\t\tconst wrapper = document.createElement('div')\n\t\twrapper.id = 'page-agent-runtime_agent-panel'\n\t\twrapper.className = `${styles.wrapper} ${styles.collapsed}`\n\t\twrapper.setAttribute('data-browser-use-ignore', 'true')\n\n\t\twrapper.innerHTML = `\n\t\t\t<div class=\"${styles.background}\"></div>\n\t\t\t<div class=\"${styles.historySectionWrapper}\">\n\t\t\t\t<div class=\"${styles.historySection}\">\n\t\t\t\t\t${this.#createHistoryItem({\n\t\t\t\t\t\tid: 'placeholder',\n\t\t\t\t\t\tstepNumber: 0,\n\t\t\t\t\t\ttimestamp: new Date(),\n\t\t\t\t\t\ttype: 'thinking',\n\t\t\t\t\t\tdisplayText: this.#i18n.t('ui.panel.waitingPlaceholder'),\n\t\t\t\t\t})}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div class=\"${styles.header}\">\n\t\t\t\t<div class=\"${styles.statusSection}\">\n\t\t\t\t\t<div class=\"${styles.indicator} ${styles.thinking}\"></div>\n\t\t\t\t\t<div class=\"${styles.statusText}\">${this.#i18n.t('ui.panel.ready')}</div>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"${styles.controls}\">\n\t\t\t\t\t<button class=\"${styles.controlButton} ${styles.expandButton}\" title=\"${this.#i18n.t('ui.panel.expand')}\">\n\t\t\t\t\t\t▼\n\t\t\t\t\t</button>\n\t\t\t\t\t<button class=\"${styles.controlButton} ${styles.pauseButton}\" title=\"${this.#i18n.t('ui.panel.pause')}\">\n\t\t\t\t\t\t⏸︎\n\t\t\t\t\t</button>\n\t\t\t\t\t<button class=\"${styles.controlButton} ${styles.stopButton}\" title=\"${this.#i18n.t('ui.panel.stop')}\">\n\t\t\t\t\t\tX\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div class=\"${styles.inputSectionWrapper} ${styles.hidden}\">\n\t\t\t\t<div class=\"${styles.inputSection}\">\n\t\t\t\t\t<input \n\t\t\t\t\t\ttype=\"text\" \n\t\t\t\t\t\tclass=\"${styles.taskInput}\" \n\t\t\t\t\t\tmaxlength=\"200\"\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t`\n\n\t\tdocument.body.appendChild(wrapper)\n\t\treturn wrapper\n\t}\n\n\t#setupEventListeners(): void {\n\t\t// Click header area to expand/collapse\n\t\tconst header = this.wrapper.querySelector(`.${styles.header}`)!\n\t\theader.addEventListener('click', (e) => {\n\t\t\t// Don't trigger expand/collapse if clicking on buttons\n\t\t\tif ((e.target as HTMLElement).closest(`.${styles.controlButton}`)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.#toggle()\n\t\t})\n\n\t\t// Expand button\n\t\tthis.#expandButton.addEventListener('click', (e) => {\n\t\t\te.stopPropagation()\n\t\t\tthis.#toggle()\n\t\t})\n\n\t\t// Pause/continue button\n\t\tthis.#pauseButton.addEventListener('click', (e) => {\n\t\t\te.stopPropagation()\n\t\t\tthis.#togglePause()\n\t\t})\n\n\t\t// Stop button\n\t\tthis.#stopButton.addEventListener('click', (e) => {\n\t\t\te.stopPropagation()\n\t\t\tthis.#stopAgent()\n\t\t})\n\n\t\t// Submit on Enter key in input field\n\t\tthis.#taskInput.addEventListener('keydown', (e) => {\n\t\t\tif (e.isComposing) return // Ignore IME composition keys\n\t\t\tif (e.key === 'Enter') {\n\t\t\t\te.preventDefault()\n\t\t\t\tthis.#submitTask()\n\t\t\t}\n\t\t})\n\n\t\t// Prevent input area click event bubbling\n\t\tthis.#inputSection.addEventListener('click', (e) => {\n\t\t\te.stopPropagation()\n\t\t})\n\t}\n\n\t#toggle(): void {\n\t\tif (this.#isExpanded) {\n\t\t\tthis.#collapse()\n\t\t} else {\n\t\t\tthis.#expand()\n\t\t}\n\t}\n\n\t#expand(): void {\n\t\tthis.#isExpanded = true\n\t\tthis.wrapper.classList.remove(styles.collapsed)\n\t\tthis.wrapper.classList.add(styles.expanded)\n\t\tthis.#expandButton.textContent = '▲'\n\t}\n\n\t#collapse(): void {\n\t\tthis.#isExpanded = false\n\t\tthis.wrapper.classList.remove(styles.expanded)\n\t\tthis.wrapper.classList.add(styles.collapsed)\n\t\tthis.#expandButton.textContent = '▼'\n\t}\n\n\t/**\n\t * Start periodic header update loop\n\t */\n\t#startHeaderUpdateLoop(): void {\n\t\t// Check every 450ms (same as total animation duration)\n\t\tthis.#headerUpdateTimer = setInterval(() => {\n\t\t\tthis.#checkAndUpdateHeader()\n\t\t}, 450)\n\t}\n\n\t/**\n\t * Stop periodic header update loop\n\t */\n\t#stopHeaderUpdateLoop(): void {\n\t\tif (this.#headerUpdateTimer) {\n\t\t\tclearInterval(this.#headerUpdateTimer)\n\t\t\tthis.#headerUpdateTimer = null\n\t\t}\n\t}\n\n\t/**\n\t * Check if header needs update and trigger animation if not currently animating\n\t */\n\t#checkAndUpdateHeader(): void {\n\t\t// If no pending text or currently animating, skip\n\t\tif (!this.#pendingHeaderText || this.#isAnimating) {\n\t\t\treturn\n\t\t}\n\n\t\t// If text is already displayed, clear pending and skip\n\t\tif (this.#statusText.textContent === this.#pendingHeaderText) {\n\t\t\tthis.#pendingHeaderText = null\n\t\t\treturn\n\t\t}\n\n\t\t// Start animation\n\t\tconst textToShow = this.#pendingHeaderText\n\t\tthis.#pendingHeaderText = null\n\t\tthis.#animateTextChange(textToShow)\n\t}\n\n\t/**\n\t * Animate text change with fade out/in effect\n\t */\n\t#animateTextChange(newText: string): void {\n\t\tthis.#isAnimating = true\n\n\t\t// Fade out current text\n\t\tthis.#statusText.classList.add(styles.fadeOut)\n\n\t\tsetTimeout(() => {\n\t\t\t// Update text content\n\t\t\tthis.#statusText.textContent = newText\n\n\t\t\t// Fade in new text\n\t\t\tthis.#statusText.classList.remove(styles.fadeOut)\n\t\t\tthis.#statusText.classList.add(styles.fadeIn)\n\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.#statusText.classList.remove(styles.fadeIn)\n\t\t\t\tthis.#isAnimating = false\n\t\t\t}, 300)\n\t\t}, 150) // Half the duration of fade out animation\n\t}\n\n\t#updateStatusIndicator(type: Step['type']): void {\n\t\t// Clear all status classes\n\t\tthis.#indicator.className = styles.indicator\n\n\t\t// Add corresponding status class\n\t\tthis.#indicator.classList.add(styles[type])\n\t}\n\n\t#updateHistory(): void {\n\t\tconst steps = this.#state.getAllSteps()\n\n\t\tthis.#historySection.innerHTML = steps.map((step) => this.#createHistoryItem(step)).join('')\n\n\t\t// Scroll to bottom to show latest records\n\t\tthis.#scrollToBottom()\n\t}\n\n\t#scrollToBottom(): void {\n\t\t// Execute in next event loop to ensure DOM update completion\n\t\tsetTimeout(() => {\n\t\t\tthis.#historySection.scrollTop = this.#historySection.scrollHeight\n\t\t}, 0)\n\t}\n\n\t#createHistoryItem(step: Step): string {\n\t\tconst time = step.timestamp.toLocaleTimeString('zh-CN', {\n\t\t\thour12: false,\n\t\t\thour: '2-digit',\n\t\t\tminute: '2-digit',\n\t\t\tsecond: '2-digit',\n\t\t})\n\n\t\tlet typeClass = ''\n\t\tlet statusIcon = ''\n\n\t\t// Set styles and icons based on step type\n\t\tif (step.type === 'completed') {\n\t\t\t// Check if this is a result from done tool\n\t\t\tif (step.toolName === 'done') {\n\t\t\t\t// Judge success or failure based on result\n\t\t\t\tconst failureKeyword = this.#i18n.t('ui.tools.resultFailure')\n\t\t\t\tconst errorKeyword = this.#i18n.t('ui.tools.resultError')\n\t\t\t\tconst isSuccess =\n\t\t\t\t\t!step.toolResult ||\n\t\t\t\t\t(!step.toolResult.includes(failureKeyword) && !step.toolResult.includes(errorKeyword))\n\t\t\t\ttypeClass = isSuccess ? styles.doneSuccess : styles.doneError\n\t\t\t\tstatusIcon = isSuccess ? '🎉' : '❌'\n\t\t\t} else {\n\t\t\t\ttypeClass = styles.completed\n\t\t\t\tstatusIcon = '✅'\n\t\t\t}\n\t\t} else if (step.type === 'error') {\n\t\t\ttypeClass = styles.error\n\t\t\tstatusIcon = '❌'\n\t\t} else if (step.type === 'tool_executing') {\n\t\t\tstatusIcon = '⚙️'\n\t\t} else if (step.type === 'output') {\n\t\t\ttypeClass = styles.output\n\t\t\tstatusIcon = '🤖'\n\t\t} else if (step.type === 'input') {\n\t\t\ttypeClass = styles.input\n\t\t\tstatusIcon = '🎯'\n\t\t} else if (step.type === 'retry') {\n\t\t\ttypeClass = styles.retry\n\t\t\tstatusIcon = '🔄'\n\t\t} else {\n\t\t\tstatusIcon = '🧠'\n\t\t}\n\n\t\tconst durationText = step.duration ? ` · ${step.duration}ms` : ''\n\t\tconst stepLabel = this.#i18n.t('ui.panel.step', {\n\t\t\tnumber: step.stepNumber.toString(),\n\t\t\ttime,\n\t\t\tduration: durationText || '', // Explicitly pass empty string to replace template\n\t\t})\n\n\t\treturn `\n\t\t\t<div class=\"${styles.historyItem} ${typeClass}\">\n\t\t\t\t<div class=\"${styles.historyContent}\">\n\t\t\t\t\t<span class=\"${styles.statusIcon}\">${statusIcon}</span>\n\t\t\t\t\t<span>${step.displayText}</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"${styles.historyMeta}\">\n\t\t\t\t\t${stepLabel}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t`\n\t}\n}\n"],"names":["paused","input","wrapper","header","statusIcon"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@page-agent/ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.22",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/lib/page-agent-ui.js",
|
|
6
6
|
"module": "./dist/lib/page-agent-ui.js",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"files": [
|
|
16
16
|
"dist/"
|
|
17
17
|
],
|
|
18
|
-
"description": "UI components for page-agent - Panel
|
|
18
|
+
"description": "UI components for page-agent - Panel and i18n",
|
|
19
19
|
"keywords": [
|
|
20
20
|
"page-agent",
|
|
21
21
|
"ui",
|
|
@@ -34,8 +34,5 @@
|
|
|
34
34
|
"build": "vite build",
|
|
35
35
|
"prepublishOnly": "node -e \"const fs=require('fs');['LICENSE'].forEach(f=>fs.copyFileSync('../../'+f,f))\"",
|
|
36
36
|
"postpublish": "node -e \"['LICENSE'].forEach(f=>{try{require('fs').unlinkSync(f)}catch{}})\""
|
|
37
|
-
},
|
|
38
|
-
"dependencies": {
|
|
39
|
-
"ai-motion": "^0.4.7"
|
|
40
37
|
}
|
|
41
38
|
}
|