@coolkiller007/my-page-agent 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # My Page Agent
2
2
 
3
- 面向茶颜悦色 Vue 2 多品牌中台的页面内嵌 GUI Agent。项目将自然语言任务转换为受控的页面读取与操作,并以单一 npm 包交付。
3
+ 面向中台的页面内嵌 GUI Agent。项目将自然语言任务转换为受控的页面读取与操作,并以单一 npm 包交付。
4
4
 
5
5
  ## Installation
6
6
 
package/dist/index.js CHANGED
@@ -1,7 +1,6 @@
1
1
  (function() { try { if (typeof document != "undefined") { var elementStyle = document.createElement("style"); elementStyle.appendChild(document.createTextNode("._wrapper_ur79v_1 {\n position: fixed;\n inset: 0;\n z-index: 2147483641; /* 确保在所有元素之上,除了 Agent UI */\n cursor: wait;\n overflow: hidden;\n\n display: none;\n}\n\n._wrapper_ur79v_1._visible_ur79v_11 {\n display: block;\n}\n/* AI 光标样式 */\n._cursor_1dgwb_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}\n\n._cursorBorder_1dgwb_10 {\n position: absolute;\n width: 100%;\n height: 100%;\n background: linear-gradient(45deg, rgb(57, 182, 255), rgb(189, 69, 251));\n mask-image: url(\"data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20100%20100'%20fill='none'%3e%3cg%3e%3cpath%20d='M%2015%2042%20L%2015%2036.99%20Q%2015%2031.99%2023.7%2031.99%20L%2028.05%2031.99%20Q%2032.41%2031.99%2032.41%2021.99%20L%2032.41%2017%20Q%2032.41%2012%2041.09%2016.95%20L%2076.31%2037.05%20Q%2085%2042%2076.31%2046.95%20L%2041.09%2067.05%20Q%2032.41%2072%2032.41%2062.01%20L%2032.41%2057.01%20Q%2032.41%2052.01%2023.7%2052.01%20L%2019.35%2052.01%20Q%2015%2052.01%2015%2047.01%20Z'%20fill='none'%20stroke='%23000000'%20stroke-width='6'%20stroke-miterlimit='10'%20style='stroke:%20light-dark(rgb(0,%200,%200),%20rgb(255,%20255,%20255));'/%3e%3c/g%3e%3c/svg%3e\");\n mask-size: 100% 100%;\n mask-repeat: no-repeat;\n\n transform-origin: center;\n transform: rotate(-135deg) scale(1.2);\n margin-left: -10px;\n margin-top: -18px;\n}\n\n._cursorFilling_1dgwb_25 {\n position: absolute;\n width: 100%;\n height: 100%;\n background: url(\"data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20100%20100'%3e%3cdefs%3e%3c/defs%3e%3cg%20xmlns='http://www.w3.org/2000/svg'%20style='filter:%20drop-shadow(light-dark(rgba(0,%200,%200,%200.4),%20rgba(237,%20237,%20237,%200.4))%203px%204px%204px);'%3e%3cpath%20d='M%2015%2042%20L%2015%2036.99%20Q%2015%2031.99%2023.7%2031.99%20L%2028.05%2031.99%20Q%2032.41%2031.99%2032.41%2021.99%20L%2032.41%2017%20Q%2032.41%2012%2041.09%2016.95%20L%2076.31%2037.05%20Q%2085%2042%2076.31%2046.95%20L%2041.09%2067.05%20Q%2032.41%2072%2032.41%2062.01%20L%2032.41%2057.01%20Q%2032.41%2052.01%2023.7%2052.01%20L%2019.35%2052.01%20Q%2015%2052.01%2015%2047.01%20Z'%20fill='%23ffffff'%20stroke='none'%20style='fill:%20%23ffffff;'/%3e%3c/g%3e%3c/svg%3e\");\n background-size: 100% 100%;\n background-repeat: no-repeat;\n\n transform-origin: center;\n transform: rotate(-135deg) scale(1.2);\n margin-left: -10px;\n margin-top: -18px;\n}\n\n._cursorRipple_1dgwb_39 {\n position: absolute;\n width: 100%;\n height: 100%;\n pointer-events: none;\n margin-left: -50%;\n margin-top: -50%;\n\n &::after {\n content: '';\n opacity: 0;\n position: absolute;\n inset: 0;\n border: 4px solid rgba(57, 182, 255, 1);\n border-radius: 50%;\n }\n}\n\n._cursor_1dgwb_2._clicking_1dgwb_57 ._cursorRipple_1dgwb_39::after {\n animation: _cursor-ripple_1dgwb_1 300ms ease-out forwards;\n}\n\n@keyframes _cursor-ripple_1dgwb_1 {\n 0% {\n transform: scale(0);\n opacity: 1;\n }\n 100% {\n transform: scale(2);\n opacity: 0;\n }\n}\n._wrapper_1tu05_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_1tu05_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_1tu05_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_1tu05_1 2s linear infinite;\n animation-delay: 1s;\n }\n }\n}\n\n@keyframes _mask-running_1tu05_1 {\n from {\n transform: translateX(-100%);\n }\n to {\n transform: translateX(100%);\n }\n}\n\n/* 控制栏 */\n._header_1tu05_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_1tu05_121 {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-height: 24px; /* 确保垂直居中 */\n\n ._indicator_1tu05_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_1tu05_137 {\n background: rgb(57, 182, 255);\n animation: _pulse_1tu05_1 0.8s ease-in-out infinite;\n }\n\n &._tool_executing_1tu05_142 {\n background: rgb(189, 69, 251);\n animation: _pulse_1tu05_1 0.6s ease-in-out infinite;\n }\n\n &._retry_1tu05_147 {\n background: rgb(255, 214, 0);\n animation: _retryPulse_1tu05_1 1s ease-in-out infinite;\n }\n\n /* 静止状态 - 无动画 */\n &._completed_1tu05_153,\n &._input_1tu05_154,\n &._output_1tu05_155 {\n background: rgb(34, 197, 94);\n animation: none;\n }\n\n &._error_1tu05_160 {\n background: rgb(239, 68, 68);\n animation: none;\n }\n }\n\n ._statusText_1tu05_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_1tu05_178 {\n animation: _statusTextFadeOut_1tu05_1 0.3s ease forwards;\n }\n\n &._fadeIn_1tu05_182 {\n animation: _statusTextFadeIn_1tu05_1 0.3s ease forwards;\n }\n }\n }\n\n ._controls_1tu05_188 {\n display: flex;\n align-items: center;\n gap: 4px;\n\n ._controlButton_1tu05_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 ._stopButton_1tu05_212 {\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_1tu05_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_1tu05_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_1tu05_246 {\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_1tu05_278 & {\n padding-top: 8px;\n visibility: visible;\n }\n\n ._historySection_1tu05_246 {\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_1tu05_278 & {\n max-height: min(500px, calc(100vh - 200px - var(--height)));\n }\n\n ._historyItem_1tu05_297 {\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_1tu05_153,\n &._input_1tu05_154,\n &._output_1tu05_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_1tu05_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_1tu05_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 &._observation_1tu05_355 {\n border-left-color: rgb(147, 51, 234);\n background: linear-gradient(135deg, rgba(147, 51, 234, 0.1), rgba(147, 51, 234, 0.05));\n }\n\n &._question_1tu05_360 {\n border-left-color: rgb(255, 159, 67);\n background: linear-gradient(135deg, rgba(255, 159, 67, 0.15), rgba(255, 159, 67, 0.08));\n }\n\n /* 突出显示 done 成功结果 */\n &._doneSuccess_1tu05_366 {\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_1tu05_1 2s ease-in-out infinite;\n }\n\n ._historyContent_1tu05_402 {\n ._statusIcon_1tu05_403 {\n font-size: 16px;\n animation: _celebrate_1tu05_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_1tu05_412 {\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_1tu05_402 {\n ._statusIcon_1tu05_403 {\n font-size: 16px;\n filter: drop-shadow(0 2px 4px rgba(239, 68, 68, 0.5));\n }\n }\n }\n\n ._historyContent_1tu05_402 {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n\n word-break: break-all;\n white-space: pre-wrap;\n\n /* overflow-x: auto; */\n\n ._statusIcon_1tu05_403 {\n font-size: 12px;\n flex-shrink: 0;\n line-height: 1;\n transition: all 0.3s ease;\n }\n\n ._reflectionLines_1tu05_462 {\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n }\n\n ._historyMeta_1tu05_469 {\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_1tu05_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_1tu05_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_1tu05_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_1tu05_1 {\n 0% {\n left: -100%;\n }\n 100% {\n left: 100%;\n }\n}\n\n/* 输入区域样式 */\n._inputSectionWrapper_1tu05_539 {\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_1tu05_562 {\n visibility: collapse;\n height: 0;\n }\n\n ._inputSection_1tu05_539 {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 8px 8px;\n\n ._taskInput_1tu05_573 {\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/*$vite$:1*/")); document.head.appendChild(elementStyle); } } catch (e) { console.error("vite-plugin-css-injected-by-js", e); }})();
2
2
  import { Motion } from "ai-motion";
3
3
  import * as z from "zod/v4";
4
- import chalk from "chalk";
5
4
  //#region \0rolldown/runtime.js
6
5
  var __defProp = Object.defineProperty;
7
6
  var __esmMin = (fn, res, err) => () => {
@@ -3192,11 +3191,25 @@ var InvokeError = class extends Error {
3192
3191
  }
3193
3192
  };
3194
3193
  //#endregion
3194
+ //#region src/shared/terminal.ts
3195
+ var colorCodes = {
3196
+ blue: 34,
3197
+ cyan: 36,
3198
+ gray: 90,
3199
+ green: 32,
3200
+ red: 31,
3201
+ yellow: 33
3202
+ };
3203
+ /** Format text with standard ANSI terminal color escape sequences. */
3204
+ function formatTerminalText(text, color, bold = false) {
3205
+ return `${bold ? "\x1B[1m" : ""}\u001B[${colorCodes[color]}m${text}\u001B[0m`;
3206
+ }
3207
+ //#endregion
3195
3208
  //#region src/llm/utils.ts
3196
3209
  /**
3197
3210
  * Utility functions for LLM integration
3198
3211
  */
3199
- var debug = console.debug.bind(console, chalk.gray("[LLM]"));
3212
+ var debug = console.debug.bind(console, formatTerminalText("[LLM]", "gray"));
3200
3213
  /**
3201
3214
  * Convert Zod schema to OpenAI tool format
3202
3215
  * Uses Zod 4 native z.toJSONSchema()
@@ -3565,7 +3578,7 @@ function parseLLMConfig(config) {
3565
3578
  var system_prompt_default = "You are an AI agent designed to operate in an iterative loop to automate browser tasks. Your ultimate goal is accomplishing the task provided in <user_request>.\n\n<intro>\nYou excel at following tasks:\n1. Navigating complex websites and extracting precise information\n2. Automating form submissions and interactive web actions\n3. Gathering and saving information \n4. Operate effectively in an agent loop\n5. Efficiently performing diverse web tasks\n</intro>\n\n<language_settings>\n- Default working language: **English**\n- Use the language that user is using. Return in user's language.\n</language_settings>\n\n<input>\nAt every step, your input will consist of: \n1. <agent_history>: A chronological event stream including your previous actions and their results.\n2. <agent_state>: Current <user_request> and <step_info>.\n3. <browser_state>: Current URL, interactive elements indexed for actions, and visible page content.\n</input>\n\n<agent_history>\nAgent history will be given as a list of step information as follows:\n\n<step_{step_number}>:\nEvaluation of Previous Step: Assessment of last action\nMemory: Your memory of this step\nNext Goal: Your goal for this step\nAction Results: Your actions and their results\n</step_{step_number}>\n\nand system messages wrapped in <sys> tag.\n</agent_history>\n\n<user_request>\nUSER REQUEST: This is your ultimate objective and always remains visible.\n- This has the highest priority. Make the user happy.\n- If the user request is very specific - then carefully follow each step and don't skip or hallucinate steps.\n- If the task is open ended you can plan yourself how to get it done.\n</user_request>\n\n<browser_state>\n1. Browser State will be given as:\n\nCurrent URL: URL of the page you are currently viewing.\nInteractive Elements: All interactive elements will be provided in format as [index]<type>text</type> where\n- index: Numeric identifier for interaction\n- type: HTML element type (button, input, etc.)\n- text: Element description\n\nExamples:\n[33]<div>User form</div>\n\\t*[35]<button aria-label='Submit form'>Submit</button>\n\nNote that:\n- Only elements with numeric indexes in [] are interactive\n- (stacked) indentation (with \\t) is important and means that the element is a (html) child of the element above (with a lower index)\n- Elements tagged with `*[` are the new clickable elements that appeared on the website since the last step - if url has not changed.\n- Pure text elements without [] are not interactive.\n</browser_state>\n\n<browser_rules>\nStrictly follow these rules while using the browser and navigating the web:\n- Only interact with elements that have a numeric [index] assigned.\n- Only use indexes that are explicitly provided.\n- If the page changes after, for example, an input text action, analyze if you need to interact with new elements, e.g. selecting the right option from the list.\n- By default, only elements in the visible viewport are listed. Use scrolling actions if you suspect relevant content is offscreen which you need to interact with. Scroll ONLY if there are more pixels below or above the page.\n- You can scroll by a specific number of pages using the num_pages parameter (e.g., 0.5 for half page, 2.0 for two pages).\n- All the elements that are scrollable are marked with `data-scrollable` attribute. Including the scrollable distance in every directions. You can scroll *the element* in case some area are overflowed.\n- If a captcha appears, tell user you can not solve captcha. Finish the task and ask user to solve it.\n- If the page is not fully loaded, use the `wait` action.\n- Do not repeat one action for more than 3 times unless some conditions changed.\n- If you fill an input field and your action sequence is interrupted, most often something changed e.g. suggestions popped up under the field.\n- If the <user_request> includes specific page information such as product type, rating, price, location, etc., try to apply filters to be more efficient.\n- The <user_request> is the ultimate goal. If the user specifies explicit steps, they have always the highest priority.\n- If you input_text into a field, you might need to press enter, click the search button, or select from dropdown for completion.\n- Don't login into a page if you don't have to. Don't login if you don't have the credentials. \n- There are 2 types of tasks always first think which type of request you are dealing with:\n1. Very specific step by step instructions:\n- Follow them as very precise and don't skip steps. Try to complete everything as requested.\n2. Open ended tasks. Plan yourself, be creative in achieving them.\n- If you get stuck e.g. with logins or captcha in open-ended tasks you can re-evaluate the task and try alternative ways, e.g. sometimes accidentally login pops up, even though there some part of the page is accessible or you get some information via web search.\n</browser_rules>\n\n<capability>\n- You can only handle single page app. Do not jump out of current page.\n- Do not click on link if it will open in a new page (e.g., <a target=\"_blank\">)\n- It is ok to fail the task.\n - User can be wrong. If the request of user is not achievable, inappropriate or you do not have enough information or tools to achieve it. Tell user to make a better request.\n - Webpage can be broken. All webpages or apps have bugs. Some bug will make it hard for your job. It's encouraged to tell user the problem of current page. Your feedbacks (including failing) are valuable for user.\n - Trying too hard can be harmful. Repeating some action back and forth or pushing for a complex procedure with little knowledge can cause unwanted results and harmful side-effects. User would rather you complete the task with a fail.\n- If you do not have knowledge for the current webpage or task. You must require user to give specific instructions and detailed steps.\n</capability>\n\n<task_completion_rules>\nYou must call the `done` action in one of three cases:\n- When you have fully completed the USER REQUEST.\n- When you reach the final allowed step (`max_steps`), even if the task is incomplete.\n- When you feel stuck or unable to solve user request. Or user request is not clear or contains inappropriate content.\n- If it is ABSOLUTELY IMPOSSIBLE to continue.\n\nThe `done` action is your opportunity to terminate and share your findings with the user.\n- Set `success` to `true` only if the full USER REQUEST has been completed with no missing components.\n- If any part of the request is missing, incomplete, or uncertain, set `success` to `false`.\n- You can use the `text` field of the `done` action to communicate your findings and to provide a coherent reply to the user and fulfill the USER REQUEST.\n- You are ONLY ALLOWED to call `done` as a single action. Don't call it together with other actions.\n- If the user asks for specified format, such as \"return JSON with following structure\", \"return a list of format...\", MAKE sure to use the right format in your answer.\n- If the user asks for a structured output, your `done` action's schema may be modified. Take this schema into account when solving the task!\n</task_completion_rules>\n\n<reasoning_rules>\nExhibit the following reasoning patterns to successfully achieve the <user_request>:\n\n- Reason about <agent_history> to track progress and context toward <user_request>.\n- Analyze the most recent \"Next Goal\" and \"Action Result\" in <agent_history> and clearly state what you previously tried to achieve.\n- Analyze all relevant items in <agent_history> and <browser_state> to understand your state.\n- Explicitly judge success/failure/uncertainty of the last action. Never assume an action succeeded just because it appears to be executed in your last step in <agent_history>. If the expected change is missing, mark the last action as failed (or uncertain) and plan a recovery.\n- Analyze whether you are stuck, e.g. when you repeat the same actions multiple times without any progress. Then consider alternative approaches e.g. scrolling for more context or ask user for help.\n- Ask user for help if you have any difficulty. Keep user in the loop.\n- If you see information relevant to <user_request>, plan saving the information to memory.\n- Always reason about the <user_request>. Make sure to carefully analyze the specific steps and information required. E.g. specific filters, specific form fields, specific information to search. Make sure to always compare the current trajectory with the user request and think carefully if thats how the user requested it.\n</reasoning_rules>\n\n<examples>\nHere are examples of good output patterns. Use them as reference but never copy them directly.\n\n<evaluation_examples>\n\"evaluation_previous_goal\": \"Successfully navigated to the product page and found the target information. Verdict: Success\"\n\"evaluation_previous_goal\": \"Clicked the login button and user authentication form appeared. Verdict: Success\"\n</evaluation_examples>\n\n<memory_examples>\n\"memory\": \"Found many pending reports that need to be analyzed in the main page. Successfully processed the first 2 reports on quarterly sales data and moving on to inventory analysis and customer feedback reports.\"\n</memory_examples>\n\n<next_goal_examples>\n\"next_goal\": \"Click on the 'Add to Cart' button to proceed with the purchase flow.\"\n</next_goal_examples>\n</examples>\n\n<output>\n{\n \"evaluation_previous_goal\": \"Concise one-sentence analysis of your last action. Clearly state success, failure, or uncertain.\",\n \"memory\": \"1-3 concise sentences of specific memory of this step and overall progress. You should put here everything that will help you track progress in future steps. Like counting pages visited, items found, etc.\",\n \"next_goal\": \"State the next immediate goal and action to achieve it, in one clear sentence.\",\n \"action\":{\n \"Action name\": {// Action parameters}\n }\n}\n</output>\n";
3566
3579
  //#endregion
3567
3580
  //#region src/agent/utils/autoFixer.ts
3568
- var log = console.log.bind(console, chalk.yellow("[autoFixer]"));
3581
+ var log = console.log.bind(console, formatTerminalText("[autoFixer]", "yellow"));
3569
3582
  /**
3570
3583
  * Normalize LLM response and fix common format issues.
3571
3584
  *
@@ -3754,18 +3767,18 @@ async function fetchLlmsTxt(url) {
3754
3767
  const endpoint = `${origin}/llms.txt`;
3755
3768
  let result = null;
3756
3769
  try {
3757
- console.log(chalk.gray(`[llms.txt] Fetching ${endpoint}`));
3770
+ console.log(formatTerminalText(`[llms.txt] Fetching ${endpoint}`, "gray"));
3758
3771
  const res = await fetch(endpoint, { signal: AbortSignal.timeout(3e3) });
3759
3772
  if (res.ok) {
3760
3773
  result = await res.text();
3761
- console.log(chalk.green(`[llms.txt] Found (${result.length} chars)`));
3774
+ console.log(formatTerminalText(`[llms.txt] Found (${result.length} chars)`, "green"));
3762
3775
  if (result.length > 1e3) {
3763
- console.log(chalk.yellow(`[llms.txt] Truncating to 1000 chars`));
3776
+ console.log(formatTerminalText(`[llms.txt] Truncating to 1000 chars`, "yellow"));
3764
3777
  result = truncate(result, 1e3);
3765
3778
  }
3766
- } else console.debug(chalk.gray(`[llms.txt] ${res.status} for ${endpoint}`));
3779
+ } else console.debug(formatTerminalText(`[llms.txt] ${res.status} for ${endpoint}`, "gray"));
3767
3780
  } catch (e) {
3768
- console.debug(chalk.gray(`[llms.txt] not found for ${endpoint}`), e);
3781
+ console.debug(formatTerminalText(`[llms.txt] not found for ${endpoint}`, "gray"), e);
3769
3782
  }
3770
3783
  llmsTxtCache.set(origin, result);
3771
3784
  return result;
@@ -3779,7 +3792,7 @@ async function fetchLlmsTxt(url) {
3779
3792
  function assert(condition, message, silent) {
3780
3793
  if (!condition) {
3781
3794
  const errorMessage = message ?? "Assertion failed";
3782
- if (!silent) console.error(chalk.red(`❌ assert: ${errorMessage}`));
3795
+ if (!silent) console.error(formatTerminalText(`❌ assert: ${errorMessage}`, "red"));
3783
3796
  throw new Error(errorMessage);
3784
3797
  }
3785
3798
  }
@@ -4128,7 +4141,7 @@ var AgentRuntime = class extends EventTarget {
4128
4141
  console.group(`step: ${step}`);
4129
4142
  if (step > 0) await waitFor(stepDelay, signal);
4130
4143
  signal.throwIfAborted();
4131
- console.log(chalk.blue.bold("👀 Observing..."));
4144
+ console.log(formatTerminalText("👀 Observing...", "blue", true));
4132
4145
  this.#states.browserState = await this.browserController.getBrowserState();
4133
4146
  await this.#handleObservations(step);
4134
4147
  const messages = [{
@@ -4139,7 +4152,7 @@ var AgentRuntime = class extends EventTarget {
4139
4152
  content: await this.#assembleUserPrompt()
4140
4153
  }];
4141
4154
  const macroTool = { AgentOutput: this.#packMacroTool() };
4142
- console.log(chalk.blue.bold("🧠 Thinking..."));
4155
+ console.log(formatTerminalText("🧠 Thinking...", "blue", true));
4143
4156
  this.#emitActivity({ type: "thinking" });
4144
4157
  const result = await this.#llm.invoke(messages, macroTool, signal, {
4145
4158
  toolChoiceName: "AgentOutput",
@@ -4171,7 +4184,7 @@ var AgentRuntime = class extends EventTarget {
4171
4184
  if (actionName === "done") {
4172
4185
  const success = action.input?.success ?? false;
4173
4186
  const data = action.input?.text || "no text provided";
4174
- console.log(chalk.green.bold("Task completed"), success, data);
4187
+ console.log(formatTerminalText("Task completed", "green", true), success, data);
4175
4188
  taskResult = {
4176
4189
  success,
4177
4190
  data,
@@ -4251,7 +4264,7 @@ var AgentRuntime = class extends EventTarget {
4251
4264
  execute: async (input) => {
4252
4265
  const signal = this.#abortController.signal;
4253
4266
  signal.throwIfAborted();
4254
- console.log(chalk.blue.bold("MacroTool input"), input);
4267
+ console.log(formatTerminalText("MacroTool input", "blue", true), input);
4255
4268
  const action = input.action;
4256
4269
  const toolName = Object.keys(action)[0];
4257
4270
  const toolInput = action[toolName];
@@ -4263,7 +4276,7 @@ var AgentRuntime = class extends EventTarget {
4263
4276
  if (reflectionText) console.log(reflectionText);
4264
4277
  const tool = tools.get(toolName);
4265
4278
  assert(tool, `Tool ${toolName} not found`);
4266
- console.log(chalk.blue.bold(`Executing tool: ${toolName}`), toolInput);
4279
+ console.log(formatTerminalText(`Executing tool: ${toolName}`, "blue", true), toolInput);
4267
4280
  this.#emitActivity({
4268
4281
  type: "executing",
4269
4282
  tool: toolName,
@@ -4273,7 +4286,7 @@ var AgentRuntime = class extends EventTarget {
4273
4286
  const result = await tool.execute.bind(this)(toolInput, { signal });
4274
4287
  signal.throwIfAborted();
4275
4288
  const duration = Date.now() - startTime;
4276
- console.log(chalk.green.bold(`Tool (${toolName}) executed for ${duration}ms`), result);
4289
+ console.log(formatTerminalText(`Tool (${toolName}) executed for ${duration}ms`, "green", true), result);
4277
4290
  this.#emitActivity({
4278
4291
  type: "executed",
4279
4292
  tool: toolName,
@@ -4309,7 +4322,7 @@ var AgentRuntime = class extends EventTarget {
4309
4322
  if (instructions?.getPageInstructions && url) try {
4310
4323
  pageInstructions = instructions.getPageInstructions(url)?.trim();
4311
4324
  } catch (error) {
4312
- console.error(chalk.red("[PageAgent] Failed to execute getPageInstructions callback:"), error);
4325
+ console.error(formatTerminalText("[PageAgent] Failed to execute getPageInstructions callback:", "red"), error);
4313
4326
  }
4314
4327
  const llmsTxt = experimentalLlmsTxt && url ? await fetchLlmsTxt(url) : void 0;
4315
4328
  if (!systemInstructions && !pageInstructions && !llmsTxt) return "";
@@ -4342,7 +4355,7 @@ var AgentRuntime = class extends EventTarget {
4342
4355
  type: "observation",
4343
4356
  content
4344
4357
  });
4345
- console.log(chalk.cyan("Observation:"), content);
4358
+ console.log(formatTerminalText("Observation:", "cyan"), content);
4346
4359
  }
4347
4360
  this.#observations = [];
4348
4361
  this.#emitHistoryChange();