From babb39ac960650011bf314b6f1276deae06ac71e Mon Sep 17 00:00:00 2001 From: tiye Date: Mon, 23 Jun 2025 16:33:52 +0800 Subject: [PATCH 1/9] enable thinking --- src/main.mts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main.mts b/src/main.mts index a93de1e..afaeae7 100644 --- a/src/main.mts +++ b/src/main.mts @@ -122,7 +122,8 @@ const main = async () => { // Create a chat session with the defined tool const chat = genAi.chats.create({ - model: process.env["MACROPHYLLA_MODEL"] || "gemini-2.0-flash", + model: + process.env["MACROPHYLLA_MODEL"] || "gemini-2.5-flash-preview-05-20", config: { systemInstruction: toolContextPrompt(), httpOptions: { @@ -131,6 +132,10 @@ const main = async () => { tools, toolConfig, temperature: 0.2, + thinkingConfig: { + includeThoughts: true, + thinkingBudget: 600, + }, }, history: [ // { @@ -237,8 +242,13 @@ const main = async () => { } } } - - if (responseMessage == null && responseFunctionCalls == null) { + if (chunk.candidates?.[0].content?.parts?.[0]?.text) { + console.log( + chalk.gray( + `\nThinking: ${chunk.candidates[0].content.parts[0].text}\n` + ) + ); + } else if (responseMessage == null && responseFunctionCalls == null) { console.warn("unknown chunk:", chunk); } } From ff0a87776c84cab63ca746b491c3a77a8644ffc7 Mon Sep 17 00:00:00 2001 From: tiye Date: Mon, 23 Jun 2025 18:29:23 +0800 Subject: [PATCH 2/9] control verbose mode --- src/main.mts | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/main.mts b/src/main.mts index afaeae7..113e247 100644 --- a/src/main.mts +++ b/src/main.mts @@ -27,6 +27,13 @@ const genAi = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY! }); const geminiBaseUrl = process.env.GEMINI_BASE_URL; +const verbose = + (process.env.verbose || process.env.VERBOSE) === "true" || false; +const thinkingBudget = parseInt( + process.env.thinking_budget || process.env.THINKING_BUDGET || "1024", + 10 +); + // 添加一个函数来生成上下文提醒 const toolContextPrompt = () => { let osInfo = `${process.platform}, 架构: ${process.arch}, CPU 核心数: ${ @@ -134,7 +141,7 @@ const main = async () => { temperature: 0.2, thinkingConfig: { includeThoughts: true, - thinkingBudget: 600, + thinkingBudget: thinkingBudget, }, }, history: [ @@ -149,7 +156,7 @@ const main = async () => { let messageCount = 0; outerWhile: while (true) { - if (nextQuestion) { + if (verbose && nextQuestion) { console.log(chalk.gray("\n" + nextQuestion + "\n")); } let question = @@ -165,7 +172,9 @@ const main = async () => { messageCount++; if (messageCount % 10 === 0) { const reminder = "重要提醒: " + toolContextPrompt(); - console.log(chalk.gray("\n\n(提醒)\n\n")); + if (verbose) { + console.log(chalk.gray("\n\n(提醒)\n\n")); + } question = `${reminder}\n\n${question}`; } @@ -210,6 +219,8 @@ const main = async () => { } else { console.log(chalk.green("运行完成.")); } + result.originalQuestion = question; + result.toolName = tool.shortName; nextQuestion = "answer based previous command response:\n" + @@ -243,11 +254,13 @@ const main = async () => { } } if (chunk.candidates?.[0].content?.parts?.[0]?.text) { - console.log( - chalk.gray( - `\nThinking: ${chunk.candidates[0].content.parts[0].text}\n` - ) - ); + if (verbose) { + console.log( + chalk.gray( + `\nThinking: ${chunk.candidates[0].content.parts[0].text}\n` + ) + ); + } } else if (responseMessage == null && responseFunctionCalls == null) { console.warn("unknown chunk:", chunk); } From 3dae5e28331beddde0958caaa86fd28c9fa41d79 Mon Sep 17 00:00:00 2001 From: tiye Date: Mon, 23 Jun 2025 19:36:30 +0800 Subject: [PATCH 3/9] refine prompt message with help from gemini --- src/main.mts | 33 ++---------- src/tools/files-read.mts | 102 +++++++++++--------------------------- src/tools/files-write.mts | 102 +++++++++++++++++++++++++++----------- src/tools/guide-steps.mts | 64 +++++++++++++++++++++--- 4 files changed, 164 insertions(+), 137 deletions(-) diff --git a/src/main.mts b/src/main.mts index 113e247..1d739ad 100644 --- a/src/main.mts +++ b/src/main.mts @@ -14,13 +14,13 @@ import { import { handleChildSIGINT } from "./tools/task-state.mjs"; import { bashCommandTool } from "./tools/bash-commad.mjs"; import { nodejsScriptTool } from "./tools/nodejs-script.mjs"; -import { filesWriteTool } from "./tools/files-read.mjs"; -import { filesReadTool } from "./tools/files-write.mjs"; +import { filesWriteTool } from "./tools/files-write.mjs"; +import { filesReadTool } from "./tools/files-read.mjs"; import { googleSearchTool } from "./tools/google-search.mjs"; import { MacrophyllaTool } from "./tools/type.mjs"; import { currentDirTool } from "./tools/current-dir.mjs"; import { changeDirTool } from "./tools/change-dir.mjs"; -import { guideSteps } from "./tools/guide-steps.mjs"; +import { toolContextPrompt } from "./tools/guide-steps.mjs"; // Initialize the Generative AI client const genAi = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY! }); @@ -30,35 +30,10 @@ const geminiBaseUrl = process.env.GEMINI_BASE_URL; const verbose = (process.env.verbose || process.env.VERBOSE) === "true" || false; const thinkingBudget = parseInt( - process.env.thinking_budget || process.env.THINKING_BUDGET || "1024", + process.env.thinking_budget || process.env.THINKING_BUDGET || "600", 10 ); -// 添加一个函数来生成上下文提醒 -const toolContextPrompt = () => { - let osInfo = `${process.platform}, 架构: ${process.arch}, CPU 核心数: ${ - os.cpus().length - }.`; - let nodeInfo = `${process.version}, 当前目录: ${process.cwd()}.`; - let bashInfo = execSync("bash --version | head -n 1"); - - return ( - guideSteps + - "使用中文回复,但代码保持英文. 输出环境为命令行, Markdown 效果不大减少使用. 你的职责是命令行助手, 请在每次回答时都尝试用工具来帮助用户, 如果可以就调用:\n" + - "- 使用 current_dir tool 获取当前目录信息\n" + - "- 使用 bash_command tool 执行 bash 命令\n" + - "- 使用 nodejs_script tool 执行 Node.js 代码\n" + - "- 使用 write_files tool 同时创建多个文件\n" + - "- 使用 read_files tool 读取文件内容\n" + - "- 使用 web_search tool 搜索最新信息\n" + - "\n" + - `你并不是完全隔离在沙箱当中的, 调用 nodejs 可以完成大量任务. 当前系统信息: ${osInfo}\n` + - `Node.js 信息: ${nodeInfo}\n` + - `Bash 信息: ${bashInfo}\n` + - "如果输入的信息直接就是 Unix 命令, 那么直接用 bash_command tool 执行即可.\n" - ); -}; - const rl = readline.createInterface({ input: process.stdin, output: process.stdout, diff --git a/src/tools/files-read.mts b/src/tools/files-read.mts index 8ee1661..0d34ed3 100644 --- a/src/tools/files-read.mts +++ b/src/tools/files-read.mts @@ -1,94 +1,52 @@ -import path from "path"; -import chalk from "chalk"; import fs from "node:fs/promises"; import { Type } from "@google/genai"; +import path from "path"; import { displayBoxedText } from "../util.mjs"; import { MacrophyllaTool } from "./type.mjs"; -export let filesWriteTool: MacrophyllaTool = { - shortName: "batch create/save files", - skipConfirmation: true, +export let filesReadTool: MacrophyllaTool = { + shortName: "read multiple files", previewFn: (args: any) => { - let entries = args.entries as Array<{ - code: string; - filepath: string; - }>; - let previews = entries - .map((entry) => { - return `File: ${chalk.yellow(entry.filepath)}\n-------------\nCode:\n${ - entry.code - }`; - }) - .join("\n--------------\n"); - displayBoxedText(previews); - }, - toolFn: async (args: any) => { - let entries = args.entries as Array<{ - code: string; - filepath: string; - }>; - let results = await Promise.allSettled( - entries.map(async (entry) => { - const code = entry.code; - const filepath = entry.filepath as string; - - const filePath = filepath.startsWith("/") - ? filepath - : path.join("./", filepath); - - // Ensure the directory exists - const dirPath = path.dirname(filePath); - await fs.mkdir(dirPath, { recursive: true }); - // The recursive option means it won't error if directory already exists - console.log(chalk.gray(`Ensured directory exists: ${dirPath}`)); - - console.log(`created ${filePath}`); - await fs.writeFile(filePath, code); - return `Created ${filePath}.`; - }) - ); - return { - stdout: results - .map((result) => { - if (result.status === "fulfilled") { - return result.value; - } else { - return `Error saving file: ${result.reason}`; - } - }) - .join("\n"), - stderr: "", - success: results.every((result) => result.status === "fulfilled"), - }; + displayBoxedText(`Reading file ${args.entries.join(", ")}`); }, declaration: { - name: "createMultipleFiles", + name: "read_files", description: - "create multiple files called entries, on the current working directory", + "read multiple files in utf8. it can access the file system. also called '读取文本文件'", parameters: { type: Type.OBJECT, properties: { entries: { - description: "an array of entries to create", type: Type.ARRAY, + description: "an array of entries to read", items: { - type: Type.OBJECT, - properties: { - code: { - type: Type.STRING, - description: "any code that you want to save to file", - }, - filepath: { - type: Type.STRING, - description: - "the path to save the file, relative to the current working directory", - }, - }, - required: ["code", "filepath"], + type: Type.STRING, + description: + "the path to read, relative to the current working directory", }, }, }, }, }, + toolFn: async (args: any) => { + let entries = args.entries as Array; + let results = await Promise.allSettled( + entries.map(async (entry) => { + const filepath = entry as string; + const filePath = filepath.startsWith("/") + ? filepath + : path.join("./", filepath); + console.log(`Reading file ${filePath}`); + const data = await fs.readFile(filePath, "utf8"); + return data; + }) + ); + + return { + stdout: JSON.stringify(results), + stderr: "", + success: results.every((result) => result.status === "fulfilled"), + }; + }, }; diff --git a/src/tools/files-write.mts b/src/tools/files-write.mts index 0d34ed3..8ee1661 100644 --- a/src/tools/files-write.mts +++ b/src/tools/files-write.mts @@ -1,52 +1,94 @@ +import path from "path"; +import chalk from "chalk"; import fs from "node:fs/promises"; import { Type } from "@google/genai"; -import path from "path"; import { displayBoxedText } from "../util.mjs"; import { MacrophyllaTool } from "./type.mjs"; -export let filesReadTool: MacrophyllaTool = { - shortName: "read multiple files", +export let filesWriteTool: MacrophyllaTool = { + shortName: "batch create/save files", + skipConfirmation: true, previewFn: (args: any) => { - displayBoxedText(`Reading file ${args.entries.join(", ")}`); - }, - declaration: { - name: "read_files", - description: - "read multiple files in utf8. it can access the file system. also called '读取文本文件'", - parameters: { - type: Type.OBJECT, - properties: { - entries: { - type: Type.ARRAY, - description: "an array of entries to read", - items: { - type: Type.STRING, - description: - "the path to read, relative to the current working directory", - }, - }, - }, - }, + let entries = args.entries as Array<{ + code: string; + filepath: string; + }>; + let previews = entries + .map((entry) => { + return `File: ${chalk.yellow(entry.filepath)}\n-------------\nCode:\n${ + entry.code + }`; + }) + .join("\n--------------\n"); + displayBoxedText(previews); }, toolFn: async (args: any) => { - let entries = args.entries as Array; + let entries = args.entries as Array<{ + code: string; + filepath: string; + }>; let results = await Promise.allSettled( entries.map(async (entry) => { - const filepath = entry as string; + const code = entry.code; + const filepath = entry.filepath as string; + const filePath = filepath.startsWith("/") ? filepath : path.join("./", filepath); - console.log(`Reading file ${filePath}`); - const data = await fs.readFile(filePath, "utf8"); - return data; + + // Ensure the directory exists + const dirPath = path.dirname(filePath); + await fs.mkdir(dirPath, { recursive: true }); + // The recursive option means it won't error if directory already exists + console.log(chalk.gray(`Ensured directory exists: ${dirPath}`)); + + console.log(`created ${filePath}`); + await fs.writeFile(filePath, code); + return `Created ${filePath}.`; }) ); - return { - stdout: JSON.stringify(results), + stdout: results + .map((result) => { + if (result.status === "fulfilled") { + return result.value; + } else { + return `Error saving file: ${result.reason}`; + } + }) + .join("\n"), stderr: "", success: results.every((result) => result.status === "fulfilled"), }; }, + declaration: { + name: "createMultipleFiles", + description: + "create multiple files called entries, on the current working directory", + parameters: { + type: Type.OBJECT, + properties: { + entries: { + description: "an array of entries to create", + type: Type.ARRAY, + items: { + type: Type.OBJECT, + properties: { + code: { + type: Type.STRING, + description: "any code that you want to save to file", + }, + filepath: { + type: Type.STRING, + description: + "the path to save the file, relative to the current working directory", + }, + }, + required: ["code", "filepath"], + }, + }, + }, + }, + }, }; diff --git a/src/tools/guide-steps.mts b/src/tools/guide-steps.mts index 2163f65..f5eb2e2 100644 --- a/src/tools/guide-steps.mts +++ b/src/tools/guide-steps.mts @@ -1,8 +1,60 @@ -export let guideSteps = `你现在是命令行助手, 需要自己安排计划来完成制定任务. -识别到新的任务发出时, 展开名词理解一下任务内容, 开始做任务规划, -将规划拆解成可执行的步骤, 考虑明白会调用那些 tool, 以及之后怎样校验. -展示你的计划, 有不确定也可以跟用户再确认一下. -然后再按照这个规划一步步完成任务, 逐个说明结果, 给出最后的答案之前一般都要做一下校验. -结果给出以后, 用户如果提出异议, 那么审视一下计划当中的问题, 重新制定计划然后重新执行. +import { execSync } from "node:child_process"; +import os from "node:os"; +export let guideSteps = `你现在是命令行助手,需要自己安排计划来完成指定任务。 +在每次与用户交互时,都要积极、主动地思考并提供帮助。 + +**任务理解与规划:** +1. **明确目标:** 首先,彻底理解用户的请求,分解任务目标。如果请求模糊或有歧义,请主动询问,直到目标清晰。 +2. **当前环境感知:** 在开始任何操作前,**务必先通过 current_dir 工具了解当前目录结构**(使用 'ls -F' 命令或其他工具),这是理解上下文的关键。必要时,也会考虑使用 'read_files' 查看关键文件内容。 +3. **制定详细计划:** 将任务拆解为逻辑清晰、可执行的步骤。对于每个步骤,思考: + * 需要什么信息?(是否需要 web_search?) + * 应该调用哪个工具?(bash_command, nodejs_script, write_files, read_files?) + * 预期的输出是什么? + * 如何验证这个步骤的结果? + * 可能遇到什么问题,如何处理? +4. **展示并确认计划:** **在执行前,总是向用户展示你的初步计划**,说明你将如何完成任务,并征求用户的确认。如果计划有不确定性或需要用户输入,请明确提出。 + +**执行与反馈:** +5. **逐步执行:** 按照确认的计划一步步执行。每完成一个步骤,都要简要说明做了什么,以及执行结果。 +6. **结果校验:** 每执行一个重要步骤或完成整个任务后,**务必进行校验**。例如,创建文件后检查文件是否存在,修改内容后读取验证。 +7. **提供最终答案:** 在所有步骤完成并校验无误后,给出最终的答案或任务完成的确认。 + +**错误处理与迭代:** +8. **故障诊断:** 如果工具执行失败,不要轻易放弃。**尝试分析错误信息(例如,查看 bash 命令的 stderr 输出)**,思考失败的原因。是路径问题?权限问题?命令语法错误?还是依赖缺失? +9. **重新规划:** 根据诊断结果,审视原计划的问题点,重新制定解决问题的策略或步骤,并告知用户你将如何尝试修复。 +10. **持续交互:** 如果在任何阶段遇到无法解决的问题,或者需要用户提供更多信息或决策,请清晰地说明情况并请求用户帮助。 `; + +// 添加一个函数来生成上下文提醒 +export const toolContextPrompt = () => { + let osInfo = `${process.platform}, 架构: ${process.arch}, CPU 核心数: ${ + os.cpus().length + }.`; + let nodeInfo = `${process.version}, 当前目录: ${process.cwd()}.`; + let bashInfo = execSync("bash --version | head -n 1"); + + return ( + guideSteps + // 确保 guideSteps 总是优先加载 + "\n" + + "--- 命令行助手环境与工具指南 ---\n" + + "使用中文回复,但代码保持英文。输出环境为命令行,请尽量减少使用 Markdown 格式(除非用于清晰地表示代码块或列表)。\n" + + "你的职责是命令行助手,请在每次回答时都尝试用工具来帮助用户,优先通过工具解决问题。\n" + + "\n" + + "**可用的工具及其使用策略:**\n" + + "- `current_dir` tool: 获取当前目录信息(`ls -F` 命令)。**在开始任何任务或环境不确定时,优先使用此工具以获取当前上下文。**\n" + + "- `bash_command` tool: 执行 Bash 命令。适用于大多数命令行操作,如文件操作(mv, cp, rm, mkdir),程序执行,查看系统信息等。**对于直接的 Unix 命令输入,直接调用此工具。**\n" + + "- `nodejs_script` tool: 执行 Node.js 代码。当你需要进行更复杂的逻辑处理、文件内容解析(JSON, YAML)、网络请求、或者需要访问 Node.js 内置模块功能时使用。例如,计算、字符串处理、简单的服务器/脚本逻辑。\n" + + "- `write_files` tool: 同时创建或更新多个文件。当你需要生成多个配置文件、代码文件或文档时,此工具效率最高。传入多个对象数组,键为文件名,值为文件内容。\n" + + "- `read_files` tool: 读取文件内容。在需要分析现有文件内容,或者确认文件是否按预期创建/修改时使用。\n" + + "- `web_search` tool: 搜索最新信息或不确定的知识。当你对某个概念、技术或错误信息不了解时,或者需要获取最新教程、API 文档时使用。\n" + + "\n" + + `**当前系统与环境信息:**\n` + + `系统: ${osInfo}\n` + + `Node.js: ${nodeInfo}\n` + + `Bash: ${bashInfo}\n` + + `你并不是完全隔离在沙箱当中的,调用 nodejs 可以完成大量任务,例如使用 'fs' 模块进行复杂文件操作,或者 'http' 模块进行网络通信。\n` + + `记住,如果输入的信息直接就是 Unix 命令(例如 'ls -al' 或 'mkdir my_project'),那么直接用 bash_command tool 执行即可,无需额外解释或规划。\n` + + `每次执行完一个工具后,请清晰地说明结果。如果执行失败,请尝试诊断问题并提出解决方案。\n` + ); +}; From c745ee6337375d90be6c65a13960e79d1fcc0ccd Mon Sep 17 00:00:00 2001 From: tiye Date: Mon, 23 Jun 2025 19:50:47 +0800 Subject: [PATCH 4/9] try gemini flash stable --- src/main.mts | 3 +-- src/tools/google-search.mts | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main.mts b/src/main.mts index 1d739ad..5180e58 100644 --- a/src/main.mts +++ b/src/main.mts @@ -104,8 +104,7 @@ const main = async () => { // Create a chat session with the defined tool const chat = genAi.chats.create({ - model: - process.env["MACROPHYLLA_MODEL"] || "gemini-2.5-flash-preview-05-20", + model: process.env["MACROPHYLLA_MODEL"] || "gemini-2.5-flash", config: { systemInstruction: toolContextPrompt(), httpOptions: { diff --git a/src/tools/google-search.mts b/src/tools/google-search.mts index 4361252..e7c320c 100644 --- a/src/tools/google-search.mts +++ b/src/tools/google-search.mts @@ -35,7 +35,7 @@ export let googleSearchTool: MacrophyllaTool = { try { const response = await genAi.models.generateContent({ - model: "gemini-2.5-flash-preview-04-17", + model: "gemini-2.5-flash", contents: [query], config: { tools: [{ googleSearch: {} }], From 93cefd0dcbd0eac6d2c129d71379e3eb252f1d70 Mon Sep 17 00:00:00 2001 From: tiye Date: Mon, 21 Jul 2025 01:54:44 +0800 Subject: [PATCH 5/9] fix dup tool config; random updates --- package.json | 9 +- src/main.mts | 54 ++- src/tools/current-dir.mts | 2 +- src/util.mts | 18 + yarn.lock | 816 +++++++++++++++++++------------------- 5 files changed, 454 insertions(+), 445 deletions(-) diff --git a/package.json b/package.json index e0dee52..496144b 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "macrophylla", "dependencies": { - "@calcit/procs": "^0.9.11", - "@google/genai": "^0.10.0", + "@calcit/procs": "^0.9.14", + "@google/genai": "^1.10.0", "chalk": "^5.4.1", "string-width": "^7.2.0" }, @@ -10,17 +10,18 @@ "compile-page": "cr --once js", "release-page": "vite build --base=./", "watch-page": "cr js", + "tool-inspect": "tsc && VERBOSE=true node --inspect lib/main.mjs", "tool": "tsc && node lib/main.mjs" }, "bin": { "mcpl": "./bin.mjs" }, "devDependencies": { - "@types/node": "^22.15.3", + "@types/node": "^24.0.15", "bottom-tip": "^0.1.5", "typescript": "^5.8.3", "url-parse": "^1.5.10", - "vite": "^6.3.3" + "vite": "^7.0.5" }, "version": "0.0.1", "cirruInfo": { diff --git a/src/main.mts b/src/main.mts index 5180e58..6080c96 100644 --- a/src/main.mts +++ b/src/main.mts @@ -1,6 +1,4 @@ -import os from "os"; import * as readline from "readline"; -import { execSync } from "child_process"; import chalk from "chalk"; import { FunctionCallingConfigMode, @@ -21,6 +19,7 @@ import { MacrophyllaTool } from "./tools/type.mjs"; import { currentDirTool } from "./tools/current-dir.mjs"; import { changeDirTool } from "./tools/change-dir.mjs"; import { toolContextPrompt } from "./tools/guide-steps.mjs"; +import { formatThinObject } from "./util.mjs"; // Initialize the Generative AI client const genAi = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY! }); @@ -30,7 +29,7 @@ const geminiBaseUrl = process.env.GEMINI_BASE_URL; const verbose = (process.env.verbose || process.env.VERBOSE) === "true" || false; const thinkingBudget = parseInt( - process.env.thinking_budget || process.env.THINKING_BUDGET || "600", + process.env.thinking_budget || process.env.THINKING_BUDGET || "400", 10 ); @@ -93,7 +92,7 @@ const main = async () => { functionDeclarations: [ bashCommandTool.declaration, nodejsScriptTool.declaration, - filesWriteTool.declaration, + filesReadTool.declaration, filesWriteTool.declaration, googleSearchTool.declaration, currentDirTool.declaration, @@ -105,25 +104,7 @@ const main = async () => { // Create a chat session with the defined tool const chat = genAi.chats.create({ model: process.env["MACROPHYLLA_MODEL"] || "gemini-2.5-flash", - config: { - systemInstruction: toolContextPrompt(), - httpOptions: { - baseUrl: geminiBaseUrl, - }, - tools, - toolConfig, - temperature: 0.2, - thinkingConfig: { - includeThoughts: true, - thinkingBudget: thinkingBudget, - }, - }, - history: [ - // { - // role: "user", - // parts: [{ text: toolContextPrompt() }], - // }, - ], + // history: [{ role: "user", parts: [{ text: toolContextPrompt() }] }], }); let nextQuestion: string = ""; @@ -155,9 +136,23 @@ const main = async () => { console.log(chalk.gray("\nResponding...\n")); // Use the chat API to send messages and get streaming responses - const response = await chat.sendMessageStream({ message: question }); + const response = await chat.sendMessageStream({ + message: question, + config: { + httpOptions: { baseUrl: geminiBaseUrl }, + systemInstruction: toolContextPrompt(), + tools, + toolConfig, + temperature: 0.2, + // thinkingConfig: { + // includeThoughts: true, + // thinkingBudget: thinkingBudget, + // }, + }, + }); for await (const chunk of response) { let responseMessage = chunk.text; + let textWritten = false; let responseFunctionCalls = chunk.functionCalls != null && chunk.functionCalls.length > 0 ? chunk.functionCalls @@ -165,6 +160,7 @@ const main = async () => { if (responseMessage != null) { process.stdout.write(responseMessage); + textWritten = true; } if (responseFunctionCalls) { for (const functionCall of responseFunctionCalls) { @@ -193,12 +189,12 @@ const main = async () => { } else { console.log(chalk.green("运行完成.")); } - result.originalQuestion = question; - result.toolName = tool.shortName; + // result.originalQuestion = question; + // result.toolName = tool.shortName; nextQuestion = "answer based previous command response:\n" + - JSON.stringify(result); + formatThinObject(result); continue outerWhile; } catch (error) { const result = { @@ -228,7 +224,7 @@ const main = async () => { } } if (chunk.candidates?.[0].content?.parts?.[0]?.text) { - if (verbose) { + if (!textWritten && verbose) { console.log( chalk.gray( `\nThinking: ${chunk.candidates[0].content.parts[0].text}\n` @@ -236,7 +232,7 @@ const main = async () => { ); } } else if (responseMessage == null && responseFunctionCalls == null) { - console.warn("unknown chunk:", chunk); + console.warn("unknown chunk:", JSON.stringify(chunk)); } } diff --git a/src/tools/current-dir.mts b/src/tools/current-dir.mts index 4c7cbe4..1c960b3 100644 --- a/src/tools/current-dir.mts +++ b/src/tools/current-dir.mts @@ -7,7 +7,7 @@ export let currentDirTool: MacrophyllaTool = { shortName: "current directory", skipConfirmation: true, previewFn: (args: any) => { - console.log(`Current directory: ${args.path}`); + console.log(`Read current directory.`); }, declaration: { name: "current_dir", diff --git a/src/util.mts b/src/util.mts index 702c7be..0cd4209 100644 --- a/src/util.mts +++ b/src/util.mts @@ -21,3 +21,21 @@ export const displayBoxedText = (text: string) => { }); console.log(chalk.gray("└" + "─".repeat(maxLength + 2) + "┘")); }; + +/** Format an object into a thin string representation */ +export const formatThinObject = (obj: any): string => { + if (obj === null || obj === undefined) { + return undefined as any; + } + if (typeof obj !== "object") { + return `${obj}`; + } + + return Object.entries(obj) + .filter(([key, value]) => value != null) + .map( + ([key, value]) => + `---- ${key} ----\n${formatThinObject(value) || "(empty)"}\n` + ) + .join("\n"); +}; diff --git a/yarn.lock b/yarn.lock index 98da97f..bcbf637 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@calcit/procs@^0.9.11": - version "0.9.11" - resolved "https://registry.npmmirror.com/@calcit/procs/-/procs-0.9.11.tgz#b57d033e6d4d70891a0820e8f25c4e2d21a6be20" - integrity sha512-vrmPKvzE/zSHXaP+cuBF0/jO+/8oN8gDN7QzAK+axvjVyzH8uJJA56d9dKyfkS5eR5fQAp7ll4xp4AVZ45qivg== +"@calcit/procs@^0.9.14": + version "0.9.14" + resolved "https://registry.yarnpkg.com/@calcit/procs/-/procs-0.9.14.tgz#db093d5b2b08a112f445e8d9615ea201a5e83820" + integrity sha512-omEUfKuGVXAc32GqktJy58XRkhZBNKhMrtJN3o2QPLEjGg/l0/U9mz2vN7r5REE6mjLdNk0M0bBmGPbXHQnqcg== dependencies: "@calcit/ternary-tree" "0.0.24" "@cirru/parser.ts" "^0.0.6" @@ -13,289 +13,292 @@ "@calcit/ternary-tree@0.0.24": version "0.0.24" - resolved "https://registry.npmmirror.com/@calcit/ternary-tree/-/ternary-tree-0.0.24.tgz#9b58cf9f76c08c3995b98b59c71b85e1da32385c" + resolved "https://registry.yarnpkg.com/@calcit/ternary-tree/-/ternary-tree-0.0.24.tgz#9b58cf9f76c08c3995b98b59c71b85e1da32385c" integrity sha512-IGs+VNYIrIF2bI3/cnQe2lFmZYaJe3+A0LArDloGbNaEzUTRoyba37FTZ8K9C+XRpUAO9K0q61sKY2vb4teWAA== "@cirru/parser.ts@^0.0.6": version "0.0.6" - resolved "https://registry.npmmirror.com/@cirru/parser.ts/-/parser.ts-0.0.6.tgz#b95a84e02273fcbd71ff100925782b6f86410234" + resolved "https://registry.yarnpkg.com/@cirru/parser.ts/-/parser.ts-0.0.6.tgz#b95a84e02273fcbd71ff100925782b6f86410234" integrity sha512-qpDNPq+IuuwYjQFI+wzpd3ntbF7lwJs90v1XWyLQbL9Ru4ld4aHxVGwW/9F/QOu5mEGCMXtagCoYDf0HtOpDZg== "@cirru/writer.ts@^0.1.5": version "0.1.5" - resolved "https://registry.npmmirror.com/@cirru/writer.ts/-/writer.ts-0.1.5.tgz#890d96cd4a69609f1682932dad5d2d467abb327e" + resolved "https://registry.yarnpkg.com/@cirru/writer.ts/-/writer.ts-0.1.5.tgz#890d96cd4a69609f1682932dad5d2d467abb327e" integrity sha512-QQVFJAOIdUtVJZwT23THZOzumSDXCLMQ0yFz5DzIGlWGXPNBuB7BwUvGtRuiQrzM2XV7ALOWmNsVC7vEOjObQQ== -"@esbuild/aix-ppc64@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.3.tgz#014180d9a149cffd95aaeead37179433f5ea5437" - integrity sha512-W8bFfPA8DowP8l//sxjJLSLkD8iEjMc7cBVyP+u4cEv9sM7mdUCkgsj+t0n/BWPFtv7WWCN5Yzj0N6FJNUUqBQ== - -"@esbuild/android-arm64@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.25.3.tgz#649e47e04ddb24a27dc05c395724bc5f4c55cbfe" - integrity sha512-XelR6MzjlZuBM4f5z2IQHK6LkK34Cvv6Rj2EntER3lwCBFdg6h2lKbtRjpTTsdEjD/WSe1q8UyPBXP1x3i/wYQ== - -"@esbuild/android-arm@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.25.3.tgz#8a0f719c8dc28a4a6567ef7328c36ea85f568ff4" - integrity sha512-PuwVXbnP87Tcff5I9ngV0lmiSu40xw1At6i3GsU77U7cjDDB4s0X2cyFuBiDa1SBk9DnvWwnGvVaGBqoFWPb7A== - -"@esbuild/android-x64@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.25.3.tgz#e2ab182d1fd06da9bef0784a13c28a7602d78009" - integrity sha512-ogtTpYHT/g1GWS/zKM0cc/tIebFjm1F9Aw1boQ2Y0eUQ+J89d0jFY//s9ei9jVIlkYi8AfOjiixcLJSGNSOAdQ== - -"@esbuild/darwin-arm64@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.3.tgz#c7f3166fcece4d158a73dcfe71b2672ca0b1668b" - integrity sha512-eESK5yfPNTqpAmDfFWNsOhmIOaQA59tAcF/EfYvo5/QWQCzXn5iUSOnqt3ra3UdzBv073ykTtmeLJZGt3HhA+w== - -"@esbuild/darwin-x64@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.25.3.tgz#d8c5342ec1a4bf4b1915643dfe031ba4b173a87a" - integrity sha512-Kd8glo7sIZtwOLcPbW0yLpKmBNWMANZhrC1r6K++uDR2zyzb6AeOYtI6udbtabmQpFaxJ8uduXMAo1gs5ozz8A== - -"@esbuild/freebsd-arm64@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.3.tgz#9f7d789e2eb7747d4868817417cc968ffa84f35b" - integrity sha512-EJiyS70BYybOBpJth3M0KLOus0n+RRMKTYzhYhFeMwp7e/RaajXvP+BWlmEXNk6uk+KAu46j/kaQzr6au+JcIw== - -"@esbuild/freebsd-x64@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.3.tgz#8ad35c51d084184a8e9e76bb4356e95350a64709" - integrity sha512-Q+wSjaLpGxYf7zC0kL0nDlhsfuFkoN+EXrx2KSB33RhinWzejOd6AvgmP5JbkgXKmjhmpfgKZq24pneodYqE8Q== - -"@esbuild/linux-arm64@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.25.3.tgz#3af0da3d9186092a9edd4e28fa342f57d9e3cd30" - integrity sha512-xCUgnNYhRD5bb1C1nqrDV1PfkwgbswTTBRbAd8aH5PhYzikdf/ddtsYyMXFfGSsb/6t6QaPSzxtbfAZr9uox4A== - -"@esbuild/linux-arm@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.25.3.tgz#e91cafa95e4474b3ae3d54da12e006b782e57225" - integrity sha512-dUOVmAUzuHy2ZOKIHIKHCm58HKzFqd+puLaS424h6I85GlSDRZIA5ycBixb3mFgM0Jdh+ZOSB6KptX30DD8YOQ== - -"@esbuild/linux-ia32@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.25.3.tgz#81025732d85b68ee510161b94acdf7e3007ea177" - integrity sha512-yplPOpczHOO4jTYKmuYuANI3WhvIPSVANGcNUeMlxH4twz/TeXuzEP41tGKNGWJjuMhotpGabeFYGAOU2ummBw== - -"@esbuild/linux-loong64@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.25.3.tgz#3c744e4c8d5e1148cbe60a71a11b58ed8ee5deb8" - integrity sha512-P4BLP5/fjyihmXCELRGrLd793q/lBtKMQl8ARGpDxgzgIKJDRJ/u4r1A/HgpBpKpKZelGct2PGI4T+axcedf6g== - -"@esbuild/linux-mips64el@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.3.tgz#1dfe2a5d63702db9034cc6b10b3087cc0424ec26" - integrity sha512-eRAOV2ODpu6P5divMEMa26RRqb2yUoYsuQQOuFUexUoQndm4MdpXXDBbUoKIc0iPa4aCO7gIhtnYomkn2x+bag== - -"@esbuild/linux-ppc64@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.3.tgz#2e85d9764c04a1ebb346dc0813ea05952c9a5c56" - integrity sha512-ZC4jV2p7VbzTlnl8nZKLcBkfzIf4Yad1SJM4ZMKYnJqZFD4rTI+pBG65u8ev4jk3/MPwY9DvGn50wi3uhdaghg== - -"@esbuild/linux-riscv64@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.3.tgz#a9ea3334556b09f85ccbfead58c803d305092415" - integrity sha512-LDDODcFzNtECTrUUbVCs6j9/bDVqy7DDRsuIXJg6so+mFksgwG7ZVnTruYi5V+z3eE5y+BJZw7VvUadkbfg7QA== - -"@esbuild/linux-s390x@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.25.3.tgz#f6a7cb67969222b200974de58f105dfe8e99448d" - integrity sha512-s+w/NOY2k0yC2p9SLen+ymflgcpRkvwwa02fqmAwhBRI3SC12uiS10edHHXlVWwfAagYSY5UpmT/zISXPMW3tQ== - -"@esbuild/linux-x64@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.25.3.tgz#a237d3578ecdd184a3066b1f425e314ade0f8033" - integrity sha512-nQHDz4pXjSDC6UfOE1Fw9Q8d6GCAd9KdvMZpfVGWSJztYCarRgSDfOVBY5xwhQXseiyxapkiSJi/5/ja8mRFFA== - -"@esbuild/netbsd-arm64@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.3.tgz#4c15c68d8149614ddb6a56f9c85ae62ccca08259" - integrity sha512-1QaLtOWq0mzK6tzzp0jRN3eccmN3hezey7mhLnzC6oNlJoUJz4nym5ZD7mDnS/LZQgkrhEbEiTn515lPeLpgWA== - -"@esbuild/netbsd-x64@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.3.tgz#12f6856f8c54c2d7d0a8a64a9711c01a743878d5" - integrity sha512-i5Hm68HXHdgv8wkrt+10Bc50zM0/eonPb/a/OFVfB6Qvpiirco5gBA5bz7S2SHuU+Y4LWn/zehzNX14Sp4r27g== - -"@esbuild/openbsd-arm64@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.3.tgz#ca078dad4a34df192c60233b058db2ca3d94bc5c" - integrity sha512-zGAVApJEYTbOC6H/3QBr2mq3upG/LBEXr85/pTtKiv2IXcgKV0RT0QA/hSXZqSvLEpXeIxah7LczB4lkiYhTAQ== - -"@esbuild/openbsd-x64@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.3.tgz#c9178adb60e140e03a881d0791248489c79f95b2" - integrity sha512-fpqctI45NnCIDKBH5AXQBsD0NDPbEFczK98hk/aa6HJxbl+UtLkJV2+Bvy5hLSLk3LHmqt0NTkKNso1A9y1a4w== - -"@esbuild/sunos-x64@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.25.3.tgz#03765eb6d4214ff27e5230af779e80790d1ee09f" - integrity sha512-ROJhm7d8bk9dMCUZjkS8fgzsPAZEjtRJqCAmVgB0gMrvG7hfmPmz9k1rwO4jSiblFjYmNvbECL9uhaPzONMfgA== - -"@esbuild/win32-arm64@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.25.3.tgz#f1c867bd1730a9b8dfc461785ec6462e349411ea" - integrity sha512-YWcow8peiHpNBiIXHwaswPnAXLsLVygFwCB3A7Bh5jRkIBFWHGmNQ48AlX4xDvQNoMZlPYzjVOQDYEzWCqufMQ== - -"@esbuild/win32-ia32@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.25.3.tgz#77491f59ef6c9ddf41df70670d5678beb3acc322" - integrity sha512-qspTZOIGoXVS4DpNqUYUs9UxVb04khS1Degaw/MnfMe7goQ3lTfQ13Vw4qY/Nj0979BGvMRpAYbs/BAxEvU8ew== - -"@esbuild/win32-x64@0.25.3": - version "0.25.3" - resolved "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.25.3.tgz#b17a2171f9074df9e91bfb07ef99a892ac06412a" - integrity sha512-ICgUR+kPimx0vvRzf+N/7L7tVSQeE3BYY+NhHRHXS1kBuPO7z2+7ea2HbhDyZdTephgvNvKrlDDKUexuCVBVvg== - -"@google/genai@^0.10.0": - version "0.10.0" - resolved "https://registry.npmmirror.com/@google/genai/-/genai-0.10.0.tgz#1a3ae479b36e242c5077dd471f2d1f4faaacaf9f" - integrity sha512-LAbp0em5A+wRtQR2+r5ckRBg2U2cBy8cJHgyTHa9PUbK8zucApw6A93HWyom/qlUQBNCpnIHFp20RiJuYMQwAw== +"@esbuild/aix-ppc64@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.8.tgz#a1414903bb38027382f85f03dda6065056757727" + integrity sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA== + +"@esbuild/android-arm64@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.8.tgz#c859994089e9767224269884061f89dae6fb51c6" + integrity sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w== + +"@esbuild/android-arm@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.8.tgz#96a8f2ca91c6cd29ea90b1af79d83761c8ba0059" + integrity sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw== + +"@esbuild/android-x64@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.8.tgz#a3a626c4fec4a024a9fa8c7679c39996e92916f0" + integrity sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA== + +"@esbuild/darwin-arm64@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.8.tgz#a5e1252ca2983d566af1c0ea39aded65736fc66d" + integrity sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw== + +"@esbuild/darwin-x64@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.8.tgz#5271b0df2bb12ce8df886704bfdd1c7cc01385d2" + integrity sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg== + +"@esbuild/freebsd-arm64@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.8.tgz#d0a0e7fdf19733b8bb1566b81df1aa0bb7e46ada" + integrity sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA== + +"@esbuild/freebsd-x64@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.8.tgz#2de8b2e0899d08f1cb1ef3128e159616e7e85343" + integrity sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw== + +"@esbuild/linux-arm64@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.8.tgz#a4209efadc0c2975716458484a4e90c237c48ae9" + integrity sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w== + +"@esbuild/linux-arm@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.8.tgz#ccd9e291c24cd8d9142d819d463e2e7200d25b19" + integrity sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg== + +"@esbuild/linux-ia32@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.8.tgz#006ad1536d0c2b28fb3a1cf0b53bcb85aaf92c4d" + integrity sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg== + +"@esbuild/linux-loong64@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.8.tgz#127b3fbfb2c2e08b1397e985932f718f09a8f5c4" + integrity sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ== + +"@esbuild/linux-mips64el@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.8.tgz#837d1449517791e3fa7d82675a2d06d9f56cb340" + integrity sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw== + +"@esbuild/linux-ppc64@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.8.tgz#aa2e3bd93ab8df084212f1895ca4b03c42d9e0fe" + integrity sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ== + +"@esbuild/linux-riscv64@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.8.tgz#a340620e31093fef72767dd28ab04214b3442083" + integrity sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg== + +"@esbuild/linux-s390x@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.8.tgz#ddfed266c8c13f5efb3105a0cd47f6dcd0e79e71" + integrity sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg== + +"@esbuild/linux-x64@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.8.tgz#9a4f78c75c051e8c060183ebb39a269ba936a2ac" + integrity sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ== + +"@esbuild/netbsd-arm64@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.8.tgz#902c80e1d678047926387230bc037e63e00697d0" + integrity sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw== + +"@esbuild/netbsd-x64@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.8.tgz#2d9eb4692add2681ff05a14ce99de54fbed7079c" + integrity sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg== + +"@esbuild/openbsd-arm64@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.8.tgz#89c3b998c6de739db38ab7fb71a8a76b3fa84a45" + integrity sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ== + +"@esbuild/openbsd-x64@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.8.tgz#2f01615cf472b0e48c077045cfd96b5c149365cc" + integrity sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ== + +"@esbuild/openharmony-arm64@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.8.tgz#a201f720cd2c3ebf9a6033fcc3feb069a54b509a" + integrity sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg== + +"@esbuild/sunos-x64@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.8.tgz#07046c977985a3334667f19e6ab3a01a80862afb" + integrity sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w== + +"@esbuild/win32-arm64@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.8.tgz#4a5470caf0d16127c05d4833d4934213c69392d1" + integrity sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ== + +"@esbuild/win32-ia32@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.8.tgz#3de3e8470b7b328d99dbc3e9ec1eace207e5bbc4" + integrity sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg== + +"@esbuild/win32-x64@0.25.8": + version "0.25.8" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz#610d7ea539d2fcdbe39237b5cc175eb2c4451f9c" + integrity sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw== + +"@google/genai@^1.10.0": + version "1.10.0" + resolved "https://registry.yarnpkg.com/@google/genai/-/genai-1.10.0.tgz#92b85a6f8c065f26bb773141bbd488a0a5810717" + integrity sha512-PR4tLuiIFMrpAiiCko2Z16ydikFsPF1c5TBfI64hlZcv3xBEApSCceLuDYu1pNMq2SkNh4r66J4AG+ZexBnMLw== dependencies: google-auth-library "^9.14.2" ws "^8.18.0" - zod "^3.22.4" - zod-to-json-schema "^3.22.4" - -"@rollup/rollup-android-arm-eabi@4.40.1": - version "4.40.1" - resolved "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.1.tgz#e1562d360bca73c7bef6feef86098de3a2f1d442" - integrity sha512-kxz0YeeCrRUHz3zyqvd7n+TVRlNyTifBsmnmNPtk3hQURUyG9eAB+usz6DAwagMusjx/zb3AjvDUvhFGDAexGw== - -"@rollup/rollup-android-arm64@4.40.1": - version "4.40.1" - resolved "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.40.1.tgz#37ba63940211673e15dcc5f469a78e34276dbca7" - integrity sha512-PPkxTOisoNC6TpnDKatjKkjRMsdaWIhyuMkA4UsBXT9WEZY4uHezBTjs6Vl4PbqQQeu6oION1w2voYZv9yquCw== - -"@rollup/rollup-darwin-arm64@4.40.1": - version "4.40.1" - resolved "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.40.1.tgz#58b1eb86d997d71dabc5b78903233a3c27438ca0" - integrity sha512-VWXGISWFY18v/0JyNUy4A46KCFCb9NVsH+1100XP31lud+TzlezBbz24CYzbnA4x6w4hx+NYCXDfnvDVO6lcAA== - -"@rollup/rollup-darwin-x64@4.40.1": - version "4.40.1" - resolved "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.40.1.tgz#5e22dab3232b1e575d930ce891abb18fe19c58c9" - integrity sha512-nIwkXafAI1/QCS7pxSpv/ZtFW6TXcNUEHAIA9EIyw5OzxJZQ1YDrX+CL6JAIQgZ33CInl1R6mHet9Y/UZTg2Bw== - -"@rollup/rollup-freebsd-arm64@4.40.1": - version "4.40.1" - resolved "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.40.1.tgz#04c892d9ff864d66e31419634726ab0bebb33707" - integrity sha512-BdrLJ2mHTrIYdaS2I99mriyJfGGenSaP+UwGi1kB9BLOCu9SR8ZpbkmmalKIALnRw24kM7qCN0IOm6L0S44iWw== - -"@rollup/rollup-freebsd-x64@4.40.1": - version "4.40.1" - resolved "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.40.1.tgz#f4b1e091f7cf5afc9e3a029d70128ad56409ecfb" - integrity sha512-VXeo/puqvCG8JBPNZXZf5Dqq7BzElNJzHRRw3vjBE27WujdzuOPecDPc/+1DcdcTptNBep3861jNq0mYkT8Z6Q== - -"@rollup/rollup-linux-arm-gnueabihf@4.40.1": - version "4.40.1" - resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.40.1.tgz#c8814bb5ce047a81b1fe4a33628dfd4ac52bd864" - integrity sha512-ehSKrewwsESPt1TgSE/na9nIhWCosfGSFqv7vwEtjyAqZcvbGIg4JAcV7ZEh2tfj/IlfBeZjgOXm35iOOjadcg== - -"@rollup/rollup-linux-arm-musleabihf@4.40.1": - version "4.40.1" - resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.40.1.tgz#5b4e7bd83cbebbf5ffe958802dcfd4ee34bf73a3" - integrity sha512-m39iO/aaurh5FVIu/F4/Zsl8xppd76S4qoID8E+dSRQvTyZTOI2gVk3T4oqzfq1PtcvOfAVlwLMK3KRQMaR8lg== - -"@rollup/rollup-linux-arm64-gnu@4.40.1": - version "4.40.1" - resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.40.1.tgz#141c848e53cee011e82a11777b8a51f1b3e8d77c" - integrity sha512-Y+GHnGaku4aVLSgrT0uWe2o2Rq8te9hi+MwqGF9r9ORgXhmHK5Q71N757u0F8yU1OIwUIFy6YiJtKjtyktk5hg== - -"@rollup/rollup-linux-arm64-musl@4.40.1": - version "4.40.1" - resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.40.1.tgz#22ebeaf2fa301aa4aa6c84b760e6cd1d1ac7eb1e" - integrity sha512-jEwjn3jCA+tQGswK3aEWcD09/7M5wGwc6+flhva7dsQNRZZTe30vkalgIzV4tjkopsTS9Jd7Y1Bsj6a4lzz8gQ== - -"@rollup/rollup-linux-loongarch64-gnu@4.40.1": - version "4.40.1" - resolved "https://registry.npmmirror.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.40.1.tgz#20b77dc78e622f5814ff8e90c14c938ceb8043bc" - integrity sha512-ySyWikVhNzv+BV/IDCsrraOAZ3UaC8SZB67FZlqVwXwnFhPihOso9rPOxzZbjp81suB1O2Topw+6Ug3JNegejQ== - -"@rollup/rollup-linux-powerpc64le-gnu@4.40.1": - version "4.40.1" - resolved "https://registry.npmmirror.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.40.1.tgz#2c90f99c987ef1198d4f8d15d754c286e1f07b13" - integrity sha512-BvvA64QxZlh7WZWqDPPdt0GH4bznuL6uOO1pmgPnnv86rpUpc8ZxgZwcEgXvo02GRIZX1hQ0j0pAnhwkhwPqWg== - -"@rollup/rollup-linux-riscv64-gnu@4.40.1": - version "4.40.1" - resolved "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.40.1.tgz#9336fd5e47d7f4760d02aa85f76976176eef53ca" - integrity sha512-EQSP+8+1VuSulm9RKSMKitTav89fKbHymTf25n5+Yr6gAPZxYWpj3DzAsQqoaHAk9YX2lwEyAf9S4W8F4l3VBQ== - -"@rollup/rollup-linux-riscv64-musl@4.40.1": - version "4.40.1" - resolved "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.40.1.tgz#d75b4d54d46439bb5c6c13762788f57e798f5670" - integrity sha512-n/vQ4xRZXKuIpqukkMXZt9RWdl+2zgGNx7Uda8NtmLJ06NL8jiHxUawbwC+hdSq1rrw/9CghCpEONor+l1e2gA== - -"@rollup/rollup-linux-s390x-gnu@4.40.1": - version "4.40.1" - resolved "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.40.1.tgz#e9f09b802f1291839247399028beaef9ce034c81" - integrity sha512-h8d28xzYb98fMQKUz0w2fMc1XuGzLLjdyxVIbhbil4ELfk5/orZlSTpF/xdI9C8K0I8lCkq+1En2RJsawZekkg== - -"@rollup/rollup-linux-x64-gnu@4.40.1": - version "4.40.1" - resolved "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.40.1.tgz#0413169dc00470667dea8575c1129d4e7a73eb29" - integrity sha512-XiK5z70PEFEFqcNj3/zRSz/qX4bp4QIraTy9QjwJAb/Z8GM7kVUsD0Uk8maIPeTyPCP03ChdI+VVmJriKYbRHQ== - -"@rollup/rollup-linux-x64-musl@4.40.1": - version "4.40.1" - resolved "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.40.1.tgz#c76fd593323c60ea219439a00da6c6d33ffd0ea6" - integrity sha512-2BRORitq5rQ4Da9blVovzNCMaUlyKrzMSvkVR0D4qPuOy/+pMCrh1d7o01RATwVy+6Fa1WBw+da7QPeLWU/1mQ== - -"@rollup/rollup-win32-arm64-msvc@4.40.1": - version "4.40.1" - resolved "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.40.1.tgz#c7724c386eed0bda5ae7143e4081c1910cab349b" - integrity sha512-b2bcNm9Kbde03H+q+Jjw9tSfhYkzrDUf2d5MAd1bOJuVplXvFhWz7tRtWvD8/ORZi7qSCy0idW6tf2HgxSXQSg== - -"@rollup/rollup-win32-ia32-msvc@4.40.1": - version "4.40.1" - resolved "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.40.1.tgz#7749e1b65cb64fe6d41ad1ad9e970a0ccc8ac350" - integrity sha512-DfcogW8N7Zg7llVEfpqWMZcaErKfsj9VvmfSyRjCyo4BI3wPEfrzTtJkZG6gKP/Z92wFm6rz2aDO7/JfiR/whA== - -"@rollup/rollup-win32-x64-msvc@4.40.1": - version "4.40.1" - resolved "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.40.1.tgz#8078b71fe0d5825dcbf83d52a7dc858b39da165c" - integrity sha512-ECyOuDeH3C1I8jH2MK1RtBJW+YPMvSfT0a5NN0nHfQYnDSJ6tUiZH3gzwVP5/Kfh/+Tt7tpWVF9LXNTnhTJ3kA== - -"@types/estree@1.0.7": - version "1.0.7" - resolved "https://registry.npmmirror.com/@types/estree/-/estree-1.0.7.tgz#4158d3105276773d5b7695cd4834b1722e4f37a8" - integrity sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ== - -"@types/node@^22.15.3": - version "22.15.3" - resolved "https://registry.npmmirror.com/@types/node/-/node-22.15.3.tgz#b7fb9396a8ec5b5dfb1345d8ac2502060e9af68b" - integrity sha512-lX7HFZeHf4QG/J7tBZqrCAXwz9J5RD56Y6MpP0eJkka8p+K0RY/yBTW7CYFJ4VGCclxqOLKmiGP5juQc6MKgcw== + +"@rollup/rollup-android-arm-eabi@4.45.1": + version "4.45.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.45.1.tgz#8560592f0dcf43b8cb0949af9f1d916205148d12" + integrity sha512-NEySIFvMY0ZQO+utJkgoMiCAjMrGvnbDLHvcmlA33UXJpYBCvlBEbMMtV837uCkS+plG2umfhn0T5mMAxGrlRA== + +"@rollup/rollup-android-arm64@4.45.1": + version "4.45.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.45.1.tgz#6bfb777bbce998691b6fd3e916b05cd46392d020" + integrity sha512-ujQ+sMXJkg4LRJaYreaVx7Z/VMgBBd89wGS4qMrdtfUFZ+TSY5Rs9asgjitLwzeIbhwdEhyj29zhst3L1lKsRQ== + +"@rollup/rollup-darwin-arm64@4.45.1": + version "4.45.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.45.1.tgz#7efce10220293a22e7b7b595d05d8b8400a7bcf3" + integrity sha512-FSncqHvqTm3lC6Y13xncsdOYfxGSLnP+73k815EfNmpewPs+EyM49haPS105Rh4aF5mJKywk9X0ogzLXZzN9lA== + +"@rollup/rollup-darwin-x64@4.45.1": + version "4.45.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.45.1.tgz#c617a8ece21050bfbea299c126767d2e70cfa79a" + integrity sha512-2/vVn/husP5XI7Fsf/RlhDaQJ7x9zjvC81anIVbr4b/f0xtSmXQTFcGIQ/B1cXIYM6h2nAhJkdMHTnD7OtQ9Og== + +"@rollup/rollup-freebsd-arm64@4.45.1": + version "4.45.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.45.1.tgz#5a6af0a9acf82162d2910933649ae24fc0ea3ecb" + integrity sha512-4g1kaDxQItZsrkVTdYQ0bxu4ZIQ32cotoQbmsAnW1jAE4XCMbcBPDirX5fyUzdhVCKgPcrwWuucI8yrVRBw2+g== + +"@rollup/rollup-freebsd-x64@4.45.1": + version "4.45.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.45.1.tgz#ae9709463560196fc275bd0da598668a2e341023" + integrity sha512-L/6JsfiL74i3uK1Ti2ZFSNsp5NMiM4/kbbGEcOCps99aZx3g8SJMO1/9Y0n/qKlWZfn6sScf98lEOUe2mBvW9A== + +"@rollup/rollup-linux-arm-gnueabihf@4.45.1": + version "4.45.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.45.1.tgz#6ec52661764dbd54c19d6520a403aa385a5c0fbf" + integrity sha512-RkdOTu2jK7brlu+ZwjMIZfdV2sSYHK2qR08FUWcIoqJC2eywHbXr0L8T/pONFwkGukQqERDheaGTeedG+rra6Q== + +"@rollup/rollup-linux-arm-musleabihf@4.45.1": + version "4.45.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.45.1.tgz#fd33ba4a43ef8419e96811236493d19436271923" + integrity sha512-3kJ8pgfBt6CIIr1o+HQA7OZ9mp/zDk3ctekGl9qn/pRBgrRgfwiffaUmqioUGN9hv0OHv2gxmvdKOkARCtRb8Q== + +"@rollup/rollup-linux-arm64-gnu@4.45.1": + version "4.45.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.45.1.tgz#933b3d99b73c9d7bf4506cab0d5d313c7e74fd2d" + integrity sha512-k3dOKCfIVixWjG7OXTCOmDfJj3vbdhN0QYEqB+OuGArOChek22hn7Uy5A/gTDNAcCy5v2YcXRJ/Qcnm4/ma1xw== + +"@rollup/rollup-linux-arm64-musl@4.45.1": + version "4.45.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.45.1.tgz#dbe9ae24ee9e97b75662fddcb69eb7f23c89280a" + integrity sha512-PmI1vxQetnM58ZmDFl9/Uk2lpBBby6B6rF4muJc65uZbxCs0EA7hhKCk2PKlmZKuyVSHAyIw3+/SiuMLxKxWog== + +"@rollup/rollup-linux-loongarch64-gnu@4.45.1": + version "4.45.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.45.1.tgz#818c5a071eec744436dbcdd76fe9c3c869dc9a8d" + integrity sha512-9UmI0VzGmNJ28ibHW2GpE2nF0PBQqsyiS4kcJ5vK+wuwGnV5RlqdczVocDSUfGX/Na7/XINRVoUgJyFIgipoRg== + +"@rollup/rollup-linux-powerpc64le-gnu@4.45.1": + version "4.45.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.45.1.tgz#6b8591def27d886fa147fb0340126c7d6682a7e4" + integrity sha512-7nR2KY8oEOUTD3pBAxIBBbZr0U7U+R9HDTPNy+5nVVHDXI4ikYniH1oxQz9VoB5PbBU1CZuDGHkLJkd3zLMWsg== + +"@rollup/rollup-linux-riscv64-gnu@4.45.1": + version "4.45.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.45.1.tgz#f1861ac4ee8da64e0b0d23853ff26fe2baa876cf" + integrity sha512-nlcl3jgUultKROfZijKjRQLUu9Ma0PeNv/VFHkZiKbXTBQXhpytS8CIj5/NfBeECZtY2FJQubm6ltIxm/ftxpw== + +"@rollup/rollup-linux-riscv64-musl@4.45.1": + version "4.45.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.45.1.tgz#320c961401a923b374e358664527b188e374e1ae" + integrity sha512-HJV65KLS51rW0VY6rvZkiieiBnurSzpzore1bMKAhunQiECPuxsROvyeaot/tcK3A3aGnI+qTHqisrpSgQrpgA== + +"@rollup/rollup-linux-s390x-gnu@4.45.1": + version "4.45.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.45.1.tgz#1763eed3362b50b6164d3f0947486c03cc7e616d" + integrity sha512-NITBOCv3Qqc6hhwFt7jLV78VEO/il4YcBzoMGGNxznLgRQf43VQDae0aAzKiBeEPIxnDrACiMgbqjuihx08OOw== + +"@rollup/rollup-linux-x64-gnu@4.45.1": + version "4.45.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.45.1.tgz#0d4c8d0b8f801902f0844a40a9d981a0179f4971" + integrity sha512-+E/lYl6qu1zqgPEnTrs4WysQtvc/Sh4fC2nByfFExqgYrqkKWp1tWIbe+ELhixnenSpBbLXNi6vbEEJ8M7fiHw== + +"@rollup/rollup-linux-x64-musl@4.45.1": + version "4.45.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.45.1.tgz#ec30bb48b5fe22a3aaba98072f2d5b7139e1a8eb" + integrity sha512-a6WIAp89p3kpNoYStITT9RbTbTnqarU7D8N8F2CV+4Cl9fwCOZraLVuVFvlpsW0SbIiYtEnhCZBPLoNdRkjQFw== + +"@rollup/rollup-win32-arm64-msvc@4.45.1": + version "4.45.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.45.1.tgz#27a6e48d1502e8e4bed96bedfb533738655874f2" + integrity sha512-T5Bi/NS3fQiJeYdGvRpTAP5P02kqSOpqiopwhj0uaXB6nzs5JVi2XMJb18JUSKhCOX8+UE1UKQufyD6Or48dJg== + +"@rollup/rollup-win32-ia32-msvc@4.45.1": + version "4.45.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.45.1.tgz#a2fbad3bec20ff879f3fd51720adf33692ca8f3d" + integrity sha512-lxV2Pako3ujjuUe9jiU3/s7KSrDfH6IgTSQOnDWr9aJ92YsFd7EurmClK0ly/t8dzMkDtd04g60WX6yl0sGfdw== + +"@rollup/rollup-win32-x64-msvc@4.45.1": + version "4.45.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.45.1.tgz#e5085c6d13da15b4c5133cd2a6bb11f25b6bb77a" + integrity sha512-M/fKi4sasCdM8i0aWJjCSFm2qEnYRR8AMLG2kxp6wD13+tMGA4Z1tVAuHkNRjud5SW2EM3naLuK35w9twvf6aA== + +"@types/estree@1.0.8": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" + integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== + +"@types/node@^24.0.15": + version "24.0.15" + resolved "https://registry.yarnpkg.com/@types/node/-/node-24.0.15.tgz#f34fbc973e7d64217106e0c59ed8761e6b51381e" + integrity sha512-oaeTSbCef7U/z7rDeJA138xpG3NuKc64/rZ2qmUFkFJmnMsAPaluIifqyWd8hSSMxyP9oie3dLAqYPblag9KgA== dependencies: - undici-types "~6.21.0" + undici-types "~7.8.0" agent-base@^7.1.2: - version "7.1.3" - resolved "https://registry.npmmirror.com/agent-base/-/agent-base-7.1.3.tgz#29435eb821bc4194633a5b89e5bc4703bafc25a1" - integrity sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw== + version "7.1.4" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.4.tgz#e3cd76d4c548ee895d3c3fd8dc1f6c5b9032e7a8" + integrity sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ== ansi-regex@^6.0.1: version "6.1.0" - resolved "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654" integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA== base64-js@^1.3.0: version "1.5.1" - resolved "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== bignumber.js@^9.0.0: - version "9.3.0" - resolved "https://registry.npmmirror.com/bignumber.js/-/bignumber.js-9.3.0.tgz#bdba7e2a4c1a2eba08290e8dcad4f36393c92acd" - integrity sha512-EM7aMFTXbptt/wZdMlBv2t8IViwQL+h6SLHosp8Yf0dqJMTnY6iL32opnAB6kAdL0SZPuvcAzFr31o0c/R3/RA== + version "9.3.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.3.1.tgz#759c5aaddf2ffdc4f154f7b493e1c8770f88c4d7" + integrity sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ== bottom-tip@^0.1.5: version "0.1.5" - resolved "https://registry.npmmirror.com/bottom-tip/-/bottom-tip-0.1.5.tgz#ca81e738fba6ae956a5b4c55a78a127820c9b99e" + resolved "https://registry.yarnpkg.com/bottom-tip/-/bottom-tip-0.1.5.tgz#ca81e738fba6ae956a5b4c55a78a127820c9b99e" integrity sha512-53RCkWg6hY8M7Y9lPgU2f2bAEejQh0H6SCL9B8ufFdYAOAH/cUEwxSsBIH0AcPbOcNaSgdEJr9OhdnTUENe5bA== dependencies: nanoid "^4.0.1" @@ -303,51 +306,51 @@ bottom-tip@^0.1.5: browser-split@0.0.1: version "0.0.1" - resolved "https://registry.npmmirror.com/browser-split/-/browser-split-0.0.1.tgz#7b097574f8e3ead606fb4664e64adfdda2981a93" + resolved "https://registry.yarnpkg.com/browser-split/-/browser-split-0.0.1.tgz#7b097574f8e3ead606fb4664e64adfdda2981a93" integrity sha512-JhvgRb2ihQhsljNda3BI8/UcRHVzrVwo3Q+P8vDtSiyobXuFpuZ9mq+MbRGMnC22CjW3RrfXdg6j6ITX8M+7Ow== -buffer-equal-constant-time@1.0.1: +buffer-equal-constant-time@^1.0.1: version "1.0.1" - resolved "https://registry.npmmirror.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== camelize@^1.0.0: version "1.0.1" - resolved "https://registry.npmmirror.com/camelize/-/camelize-1.0.1.tgz#89b7e16884056331a35d6b5ad064332c91daa6c3" + resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.1.tgz#89b7e16884056331a35d6b5ad064332c91daa6c3" integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ== chalk@^5.4.1: version "5.4.1" - resolved "https://registry.npmmirror.com/chalk/-/chalk-5.4.1.tgz#1b48bf0963ec158dce2aacf69c093ae2dd2092d8" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.4.1.tgz#1b48bf0963ec158dce2aacf69c093ae2dd2092d8" integrity sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w== debug@4: - version "4.4.0" - resolved "https://registry.npmmirror.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a" - integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== + version "4.4.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b" + integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== dependencies: ms "^2.1.3" dom-walk@^0.1.0: version "0.1.2" - resolved "https://registry.npmmirror.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== ecdsa-sig-formatter@1.0.11, ecdsa-sig-formatter@^1.0.11: version "1.0.11" - resolved "https://registry.npmmirror.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== dependencies: safe-buffer "^5.0.1" emoji-regex@^10.3.0: version "10.4.0" - resolved "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-10.4.0.tgz#03553afea80b3975749cfcb36f776ca268e413d4" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.4.0.tgz#03553afea80b3975749cfcb36f776ca268e413d4" integrity sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw== error@^4.3.0: version "4.4.0" - resolved "https://registry.npmmirror.com/error/-/error-4.4.0.tgz#bf69ff251fb4a279c19adccdaa6b61e90d9bf12a" + resolved "https://registry.yarnpkg.com/error/-/error-4.4.0.tgz#bf69ff251fb4a279c19adccdaa6b61e90d9bf12a" integrity sha512-SNDKualLUtT4StGFP7xNfuFybL2f6iJujFtrWuvJqGbVQGaN+adE23veqzPz1hjUjTunLi2EnJ+0SJxtbJreKw== dependencies: camelize "^1.0.0" @@ -355,61 +358,62 @@ error@^4.3.0: xtend "~4.0.0" esbuild@^0.25.0: - version "0.25.3" - resolved "https://registry.npmmirror.com/esbuild/-/esbuild-0.25.3.tgz#371f7cb41283e5b2191a96047a7a89562965a285" - integrity sha512-qKA6Pvai73+M2FtftpNKRxJ78GIjmFXFxd/1DVBqGo/qNhLSfv+G12n9pNoWdytJC8U00TrViOwpjT0zgqQS8Q== + version "0.25.8" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.8.tgz#482d42198b427c9c2f3a81b63d7663aecb1dda07" + integrity sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q== optionalDependencies: - "@esbuild/aix-ppc64" "0.25.3" - "@esbuild/android-arm" "0.25.3" - "@esbuild/android-arm64" "0.25.3" - "@esbuild/android-x64" "0.25.3" - "@esbuild/darwin-arm64" "0.25.3" - "@esbuild/darwin-x64" "0.25.3" - "@esbuild/freebsd-arm64" "0.25.3" - "@esbuild/freebsd-x64" "0.25.3" - "@esbuild/linux-arm" "0.25.3" - "@esbuild/linux-arm64" "0.25.3" - "@esbuild/linux-ia32" "0.25.3" - "@esbuild/linux-loong64" "0.25.3" - "@esbuild/linux-mips64el" "0.25.3" - "@esbuild/linux-ppc64" "0.25.3" - "@esbuild/linux-riscv64" "0.25.3" - "@esbuild/linux-s390x" "0.25.3" - "@esbuild/linux-x64" "0.25.3" - "@esbuild/netbsd-arm64" "0.25.3" - "@esbuild/netbsd-x64" "0.25.3" - "@esbuild/openbsd-arm64" "0.25.3" - "@esbuild/openbsd-x64" "0.25.3" - "@esbuild/sunos-x64" "0.25.3" - "@esbuild/win32-arm64" "0.25.3" - "@esbuild/win32-ia32" "0.25.3" - "@esbuild/win32-x64" "0.25.3" + "@esbuild/aix-ppc64" "0.25.8" + "@esbuild/android-arm" "0.25.8" + "@esbuild/android-arm64" "0.25.8" + "@esbuild/android-x64" "0.25.8" + "@esbuild/darwin-arm64" "0.25.8" + "@esbuild/darwin-x64" "0.25.8" + "@esbuild/freebsd-arm64" "0.25.8" + "@esbuild/freebsd-x64" "0.25.8" + "@esbuild/linux-arm" "0.25.8" + "@esbuild/linux-arm64" "0.25.8" + "@esbuild/linux-ia32" "0.25.8" + "@esbuild/linux-loong64" "0.25.8" + "@esbuild/linux-mips64el" "0.25.8" + "@esbuild/linux-ppc64" "0.25.8" + "@esbuild/linux-riscv64" "0.25.8" + "@esbuild/linux-s390x" "0.25.8" + "@esbuild/linux-x64" "0.25.8" + "@esbuild/netbsd-arm64" "0.25.8" + "@esbuild/netbsd-x64" "0.25.8" + "@esbuild/openbsd-arm64" "0.25.8" + "@esbuild/openbsd-x64" "0.25.8" + "@esbuild/openharmony-arm64" "0.25.8" + "@esbuild/sunos-x64" "0.25.8" + "@esbuild/win32-arm64" "0.25.8" + "@esbuild/win32-ia32" "0.25.8" + "@esbuild/win32-x64" "0.25.8" ev-store@^7.0.0: version "7.0.0" - resolved "https://registry.npmmirror.com/ev-store/-/ev-store-7.0.0.tgz#1ab0c7f82136505dd74b31d17701cb2be6d26558" + resolved "https://registry.yarnpkg.com/ev-store/-/ev-store-7.0.0.tgz#1ab0c7f82136505dd74b31d17701cb2be6d26558" integrity sha512-otazchNRnGzp2YarBJ+GXKVGvhxVATB1zmaStxJBYet0Dyq7A9VhH8IUEB/gRcL6Ch52lfpgPTRJ2m49epyMsQ== dependencies: individual "^3.0.0" extend@^3.0.2: version "3.0.2" - resolved "https://registry.npmmirror.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -fdir@^6.4.4: - version "6.4.4" - resolved "https://registry.npmmirror.com/fdir/-/fdir-6.4.4.tgz#1cfcf86f875a883e19a8fab53622cfe992e8d2f9" - integrity sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg== +fdir@^6.4.4, fdir@^6.4.6: + version "6.4.6" + resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.6.tgz#2b268c0232697063111bbf3f64810a2a741ba281" + integrity sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w== fsevents@~2.3.2, fsevents@~2.3.3: version "2.3.3" - resolved "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== gaxios@^6.0.0, gaxios@^6.1.1: version "6.7.1" - resolved "https://registry.npmmirror.com/gaxios/-/gaxios-6.7.1.tgz#ebd9f7093ede3ba502685e73390248bb5b7f71fb" + resolved "https://registry.yarnpkg.com/gaxios/-/gaxios-6.7.1.tgz#ebd9f7093ede3ba502685e73390248bb5b7f71fb" integrity sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ== dependencies: extend "^3.0.2" @@ -420,7 +424,7 @@ gaxios@^6.0.0, gaxios@^6.1.1: gcp-metadata@^6.1.0: version "6.1.1" - resolved "https://registry.npmmirror.com/gcp-metadata/-/gcp-metadata-6.1.1.tgz#f65aa69f546bc56e116061d137d3f5f90bdec494" + resolved "https://registry.yarnpkg.com/gcp-metadata/-/gcp-metadata-6.1.1.tgz#f65aa69f546bc56e116061d137d3f5f90bdec494" integrity sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A== dependencies: gaxios "^6.1.1" @@ -429,12 +433,12 @@ gcp-metadata@^6.1.0: get-east-asian-width@^1.0.0: version "1.3.0" - resolved "https://registry.npmmirror.com/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz#21b4071ee58ed04ee0db653371b55b4299875389" + resolved "https://registry.yarnpkg.com/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz#21b4071ee58ed04ee0db653371b55b4299875389" integrity sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ== global@^4.3.0: version "4.4.0" - resolved "https://registry.npmmirror.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" + resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== dependencies: min-document "^2.19.0" @@ -442,7 +446,7 @@ global@^4.3.0: google-auth-library@^9.14.2: version "9.15.1" - resolved "https://registry.npmmirror.com/google-auth-library/-/google-auth-library-9.15.1.tgz#0c5d84ed1890b2375f1cd74f03ac7b806b392928" + resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-9.15.1.tgz#0c5d84ed1890b2375f1cd74f03ac7b806b392928" integrity sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng== dependencies: base64-js "^1.3.0" @@ -454,12 +458,12 @@ google-auth-library@^9.14.2: google-logging-utils@^0.0.2: version "0.0.2" - resolved "https://registry.npmmirror.com/google-logging-utils/-/google-logging-utils-0.0.2.tgz#5fd837e06fa334da450433b9e3e1870c1594466a" + resolved "https://registry.yarnpkg.com/google-logging-utils/-/google-logging-utils-0.0.2.tgz#5fd837e06fa334da450433b9e3e1870c1594466a" integrity sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ== gtoken@^7.0.0: version "7.1.0" - resolved "https://registry.npmmirror.com/gtoken/-/gtoken-7.1.0.tgz#d61b4ebd10132222817f7222b1e6064bd463fc26" + resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-7.1.0.tgz#d61b4ebd10132222817f7222b1e6064bd463fc26" integrity sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw== dependencies: gaxios "^6.0.0" @@ -467,7 +471,7 @@ gtoken@^7.0.0: https-proxy-agent@^7.0.1: version "7.0.6" - resolved "https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz#da8dfeac7da130b05c2ba4b59c9b6cd66611a6b9" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz#da8dfeac7da130b05c2ba4b59c9b6cd66611a6b9" integrity sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw== dependencies: agent-base "^7.1.2" @@ -475,38 +479,38 @@ https-proxy-agent@^7.0.1: individual@^3.0.0: version "3.0.0" - resolved "https://registry.npmmirror.com/individual/-/individual-3.0.0.tgz#e7ca4f85f8957b018734f285750dc22ec2f9862d" + resolved "https://registry.yarnpkg.com/individual/-/individual-3.0.0.tgz#e7ca4f85f8957b018734f285750dc22ec2f9862d" integrity sha512-rUY5vtT748NMRbEMrTNiFfy29BgGZwGXUi2NFUVMWQrogSLzlJvQV9eeMWi+g1aVaQ53tpyLAQtd5x/JH0Nh1g== is-object@^1.0.1: version "1.0.2" - resolved "https://registry.npmmirror.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== is-stream@^2.0.0: version "2.0.1" - resolved "https://registry.npmmirror.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== json-bigint@^1.0.0: version "1.0.0" - resolved "https://registry.npmmirror.com/json-bigint/-/json-bigint-1.0.0.tgz#ae547823ac0cad8398667f8cd9ef4730f5b01ff1" + resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-1.0.0.tgz#ae547823ac0cad8398667f8cd9ef4730f5b01ff1" integrity sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ== dependencies: bignumber.js "^9.0.0" jwa@^2.0.0: - version "2.0.0" - resolved "https://registry.npmmirror.com/jwa/-/jwa-2.0.0.tgz#a7e9c3f29dae94027ebcaf49975c9345593410fc" - integrity sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA== + version "2.0.1" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-2.0.1.tgz#bf8176d1ad0cd72e0f3f58338595a13e110bc804" + integrity sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg== dependencies: - buffer-equal-constant-time "1.0.1" + buffer-equal-constant-time "^1.0.1" ecdsa-sig-formatter "1.0.11" safe-buffer "^5.0.1" jws@^4.0.0: version "4.0.0" - resolved "https://registry.npmmirror.com/jws/-/jws-4.0.0.tgz#2d4e8cf6a318ffaa12615e9dec7e86e6c97310f4" + resolved "https://registry.yarnpkg.com/jws/-/jws-4.0.0.tgz#2d4e8cf6a318ffaa12615e9dec7e86e6c97310f4" integrity sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg== dependencies: jwa "^2.0.0" @@ -514,119 +518,119 @@ jws@^4.0.0: min-document@^2.19.0: version "2.19.0" - resolved "https://registry.npmmirror.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" integrity sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ== dependencies: dom-walk "^0.1.0" ms@^2.1.3: version "2.1.3" - resolved "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -nanoid@^3.3.8: +nanoid@^3.3.11: version "3.3.11" - resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b" integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== nanoid@^4.0.1: version "4.0.2" - resolved "https://registry.npmmirror.com/nanoid/-/nanoid-4.0.2.tgz#140b3c5003959adbebf521c170f282c5e7f9fb9e" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-4.0.2.tgz#140b3c5003959adbebf521c170f282c5e7f9fb9e" integrity sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw== next-tick@^0.2.2: version "0.2.2" - resolved "https://registry.npmmirror.com/next-tick/-/next-tick-0.2.2.tgz#75da4a927ee5887e39065880065b7336413b310d" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-0.2.2.tgz#75da4a927ee5887e39065880065b7336413b310d" integrity sha512-f7h4svPtl+QidoBv4taKXUjJ70G2asaZ8G28nS0OkqaalX8dwwrtWtyxEDPK62AC00ur/+/E0pUwBwY5EPn15Q== node-fetch@^2.6.9: version "2.7.0" - resolved "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== dependencies: whatwg-url "^5.0.0" picocolors@^1.1.1: version "1.1.1" - resolved "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== picomatch@^4.0.2: - version "4.0.2" - resolved "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab" - integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg== - -postcss@^8.5.3: - version "8.5.3" - resolved "https://registry.npmmirror.com/postcss/-/postcss-8.5.3.tgz#1463b6f1c7fb16fe258736cba29a2de35237eafb" - integrity sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A== + version "4.0.3" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.3.tgz#796c76136d1eead715db1e7bad785dedd695a042" + integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q== + +postcss@^8.5.6: + version "8.5.6" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.6.tgz#2825006615a619b4f62a9e7426cc120b349a8f3c" + integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg== dependencies: - nanoid "^3.3.8" + nanoid "^3.3.11" picocolors "^1.1.1" source-map-js "^1.2.1" process@^0.11.10: version "0.11.10" - resolved "https://registry.npmmirror.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== querystringify@^2.1.1: version "2.2.0" - resolved "https://registry.npmmirror.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== requires-port@^1.0.0: version "1.0.0" - resolved "https://registry.npmmirror.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== -rollup@^4.34.9: - version "4.40.1" - resolved "https://registry.npmmirror.com/rollup/-/rollup-4.40.1.tgz#03d6c53ebb6a9c2c060ae686a61e72a2472b366f" - integrity sha512-C5VvvgCCyfyotVITIAv+4efVytl5F7wt+/I2i9q9GZcEXW9BP52YYOXC58igUi+LFZVHukErIIqQSWwv/M3WRw== +rollup@^4.40.0: + version "4.45.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.45.1.tgz#d0ef72a8d0a9210d832f9c3c5f3b6a2aa4b0ba64" + integrity sha512-4iya7Jb76fVpQyLoiVpzUrsjQ12r3dM7fIVz+4NwoYvZOShknRmiv+iu9CClZml5ZLGb0XMcYLutK6w9tgxHDw== dependencies: - "@types/estree" "1.0.7" + "@types/estree" "1.0.8" optionalDependencies: - "@rollup/rollup-android-arm-eabi" "4.40.1" - "@rollup/rollup-android-arm64" "4.40.1" - "@rollup/rollup-darwin-arm64" "4.40.1" - "@rollup/rollup-darwin-x64" "4.40.1" - "@rollup/rollup-freebsd-arm64" "4.40.1" - "@rollup/rollup-freebsd-x64" "4.40.1" - "@rollup/rollup-linux-arm-gnueabihf" "4.40.1" - "@rollup/rollup-linux-arm-musleabihf" "4.40.1" - "@rollup/rollup-linux-arm64-gnu" "4.40.1" - "@rollup/rollup-linux-arm64-musl" "4.40.1" - "@rollup/rollup-linux-loongarch64-gnu" "4.40.1" - "@rollup/rollup-linux-powerpc64le-gnu" "4.40.1" - "@rollup/rollup-linux-riscv64-gnu" "4.40.1" - "@rollup/rollup-linux-riscv64-musl" "4.40.1" - "@rollup/rollup-linux-s390x-gnu" "4.40.1" - "@rollup/rollup-linux-x64-gnu" "4.40.1" - "@rollup/rollup-linux-x64-musl" "4.40.1" - "@rollup/rollup-win32-arm64-msvc" "4.40.1" - "@rollup/rollup-win32-ia32-msvc" "4.40.1" - "@rollup/rollup-win32-x64-msvc" "4.40.1" + "@rollup/rollup-android-arm-eabi" "4.45.1" + "@rollup/rollup-android-arm64" "4.45.1" + "@rollup/rollup-darwin-arm64" "4.45.1" + "@rollup/rollup-darwin-x64" "4.45.1" + "@rollup/rollup-freebsd-arm64" "4.45.1" + "@rollup/rollup-freebsd-x64" "4.45.1" + "@rollup/rollup-linux-arm-gnueabihf" "4.45.1" + "@rollup/rollup-linux-arm-musleabihf" "4.45.1" + "@rollup/rollup-linux-arm64-gnu" "4.45.1" + "@rollup/rollup-linux-arm64-musl" "4.45.1" + "@rollup/rollup-linux-loongarch64-gnu" "4.45.1" + "@rollup/rollup-linux-powerpc64le-gnu" "4.45.1" + "@rollup/rollup-linux-riscv64-gnu" "4.45.1" + "@rollup/rollup-linux-riscv64-musl" "4.45.1" + "@rollup/rollup-linux-s390x-gnu" "4.45.1" + "@rollup/rollup-linux-x64-gnu" "4.45.1" + "@rollup/rollup-linux-x64-musl" "4.45.1" + "@rollup/rollup-win32-arm64-msvc" "4.45.1" + "@rollup/rollup-win32-ia32-msvc" "4.45.1" + "@rollup/rollup-win32-x64-msvc" "4.45.1" fsevents "~2.3.2" safe-buffer@^5.0.1: version "5.2.1" - resolved "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== source-map-js@^1.2.1: version "1.2.1" - resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== string-template@~0.2.0: version "0.2.1" - resolved "https://registry.npmmirror.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" + resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" integrity sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw== string-width@^7.2.0: version "7.2.0" - resolved "https://registry.npmmirror.com/string-width/-/string-width-7.2.0.tgz#b5bb8e2165ce275d4d43476dd2700ad9091db6dc" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-7.2.0.tgz#b5bb8e2165ce275d4d43476dd2700ad9091db6dc" integrity sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ== dependencies: emoji-regex "^10.3.0" @@ -635,37 +639,37 @@ string-width@^7.2.0: strip-ansi@^7.1.0: version "7.1.0" - resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== dependencies: ansi-regex "^6.0.1" -tinyglobby@^0.2.13: - version "0.2.13" - resolved "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.13.tgz#a0e46515ce6cbcd65331537e57484af5a7b2ff7e" - integrity sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw== +tinyglobby@^0.2.14: + version "0.2.14" + resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.14.tgz#5280b0cf3f972b050e74ae88406c0a6a58f4079d" + integrity sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ== dependencies: fdir "^6.4.4" picomatch "^4.0.2" tr46@~0.0.3: version "0.0.3" - resolved "https://registry.npmmirror.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== typescript@^5.8.3: version "5.8.3" - resolved "https://registry.npmmirror.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e" integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ== -undici-types@~6.21.0: - version "6.21.0" - resolved "https://registry.npmmirror.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb" - integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== +undici-types@~7.8.0: + version "7.8.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.8.0.tgz#de00b85b710c54122e44fbfd911f8d70174cd294" + integrity sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw== url-parse@^1.5.10: version "1.5.10" - resolved "https://registry.npmmirror.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== dependencies: querystringify "^2.1.1" @@ -673,12 +677,12 @@ url-parse@^1.5.10: uuid@^9.0.1: version "9.0.1" - resolved "https://registry.npmmirror.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== virtual-dom@^2.1.1: version "2.1.1" - resolved "https://registry.npmmirror.com/virtual-dom/-/virtual-dom-2.1.1.tgz#80eda2d481b9ede0c049118cefcb4a05f21d1375" + resolved "https://registry.yarnpkg.com/virtual-dom/-/virtual-dom-2.1.1.tgz#80eda2d481b9ede0c049118cefcb4a05f21d1375" integrity sha512-wb6Qc9Lbqug0kRqo/iuApfBpJJAq14Sk1faAnSmtqXiwahg7PVTvWMs9L02Z8nNIMqbwsxzBAA90bbtRLbw0zg== dependencies: browser-split "0.0.1" @@ -690,59 +694,49 @@ virtual-dom@^2.1.1: x-is-array "0.1.0" x-is-string "0.1.0" -vite@^6.3.3: - version "6.3.3" - resolved "https://registry.npmmirror.com/vite/-/vite-6.3.3.tgz#497392c3f2243194e4dbf09ea83e9a3dddf49b88" - integrity sha512-5nXH+QsELbFKhsEfWLkHrvgRpTdGJzqOZ+utSdmPTvwHmvU6ITTm3xx+mRusihkcI8GeC7lCDyn3kDtiki9scw== +vite@^7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/vite/-/vite-7.0.5.tgz#deb2d3b777378f6d3e47c3d41b59f3c93f485738" + integrity sha512-1mncVwJxy2C9ThLwz0+2GKZyEXuC3MyWtAAlNftlZZXZDP3AJt5FmwcMit/IGGaNZ8ZOB2BNO/HFUB+CpN0NQw== dependencies: esbuild "^0.25.0" - fdir "^6.4.4" + fdir "^6.4.6" picomatch "^4.0.2" - postcss "^8.5.3" - rollup "^4.34.9" - tinyglobby "^0.2.13" + postcss "^8.5.6" + rollup "^4.40.0" + tinyglobby "^0.2.14" optionalDependencies: fsevents "~2.3.3" webidl-conversions@^3.0.0: version "3.0.1" - resolved "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== whatwg-url@^5.0.0: version "5.0.0" - resolved "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== dependencies: tr46 "~0.0.3" webidl-conversions "^3.0.0" ws@^8.18.0: - version "8.18.1" - resolved "https://registry.npmmirror.com/ws/-/ws-8.18.1.tgz#ea131d3784e1dfdff91adb0a4a116b127515e3cb" - integrity sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w== + version "8.18.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.3.tgz#b56b88abffde62791c639170400c93dcb0c95472" + integrity sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg== x-is-array@0.1.0: version "0.1.0" - resolved "https://registry.npmmirror.com/x-is-array/-/x-is-array-0.1.0.tgz#de520171d47b3f416f5587d629b89d26b12dc29d" + resolved "https://registry.yarnpkg.com/x-is-array/-/x-is-array-0.1.0.tgz#de520171d47b3f416f5587d629b89d26b12dc29d" integrity sha512-goHPif61oNrr0jJgsXRfc8oqtYzvfiMJpTqwE7Z4y9uH+T3UozkGqQ4d2nX9mB9khvA8U2o/UbPOFjgC7hLWIA== x-is-string@0.1.0: version "0.1.0" - resolved "https://registry.npmmirror.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82" + resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82" integrity sha512-GojqklwG8gpzOVEVki5KudKNoq7MbbjYZCbyWzEz7tyPA7eleiE0+ePwOWQQRb5fm86rD3S8Tc0tSFf3AOv50w== xtend@~4.0.0: version "4.0.2" - resolved "https://registry.npmmirror.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -zod-to-json-schema@^3.22.4: - version "3.24.5" - resolved "https://registry.npmmirror.com/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz#d1095440b147fb7c2093812a53c54df8d5df50a3" - integrity sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g== - -zod@^3.22.4: - version "3.24.3" - resolved "https://registry.npmmirror.com/zod/-/zod-3.24.3.tgz#1f40f750a05e477396da64438e0e1c0995dafd87" - integrity sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg== From 56c6bbac42cae6d099753e61f09c5818681b3d36 Mon Sep 17 00:00:00 2001 From: tiye Date: Mon, 21 Jul 2025 02:28:34 +0800 Subject: [PATCH 6/9] random fixes --- src/main.mts | 30 +++++++++++++++++------------- src/tools/files-read.mts | 30 +++++++++++++++++++----------- src/util.mts | 12 +++++++++--- 3 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/main.mts b/src/main.mts index 6080c96..6a9f484 100644 --- a/src/main.mts +++ b/src/main.mts @@ -4,6 +4,7 @@ import { FunctionCallingConfigMode, FunctionDeclaration, GoogleGenAI, + HarmBlockThreshold, Tool, ToolConfig, Type, @@ -104,6 +105,9 @@ const main = async () => { // Create a chat session with the defined tool const chat = genAi.chats.create({ model: process.env["MACROPHYLLA_MODEL"] || "gemini-2.5-flash", + config: { + systemInstruction: toolContextPrompt(), + }, // history: [{ role: "user", parts: [{ text: toolContextPrompt() }] }], }); @@ -125,13 +129,13 @@ const main = async () => { } // 每隔 5 轮对话,插入上下文提醒 messageCount++; - if (messageCount % 10 === 0) { - const reminder = "重要提醒: " + toolContextPrompt(); - if (verbose) { - console.log(chalk.gray("\n\n(提醒)\n\n")); - } - question = `${reminder}\n\n${question}`; - } + // if (messageCount % 10 === 0) { + // const reminder = "重要提醒: " + toolContextPrompt(); + // if (verbose) { + // console.log(chalk.gray("\n\n(提醒)\n\n")); + // } + // question = `${reminder}\n\n${question}`; + // } console.log(chalk.gray("\nResponding...\n")); @@ -140,14 +144,14 @@ const main = async () => { message: question, config: { httpOptions: { baseUrl: geminiBaseUrl }, - systemInstruction: toolContextPrompt(), tools, toolConfig, temperature: 0.2, - // thinkingConfig: { - // includeThoughts: true, - // thinkingBudget: thinkingBudget, - // }, + // safetySettings: [{ threshold: HarmBlockThreshold.OFF }], + thinkingConfig: + thinkingBudget > 256 + ? { includeThoughts: true, thinkingBudget: thinkingBudget } + : undefined, }, }); for await (const chunk of response) { @@ -209,7 +213,7 @@ const main = async () => { continue outerWhile; } } else { - nextQuestion = `用户拒绝了这条命令: (${confirmation}), 尝试改进一下方案.`; + nextQuestion = `存在问题, 要求改进调用方式: ${confirmation}.`; continue outerWhile; } } else { diff --git a/src/tools/files-read.mts b/src/tools/files-read.mts index 0d34ed3..ff946a6 100644 --- a/src/tools/files-read.mts +++ b/src/tools/files-read.mts @@ -6,45 +6,53 @@ import { displayBoxedText } from "../util.mjs"; import { MacrophyllaTool } from "./type.mjs"; export let filesReadTool: MacrophyllaTool = { - shortName: "read multiple files", + shortName: "read multiple paths", previewFn: (args: any) => { - displayBoxedText(`Reading file ${args.entries.join(", ")}`); + displayBoxedText(`Reading file ${args.paths.join(", ")}`); }, declaration: { - name: "read_files", + name: "read_paths", description: - "read multiple files in utf8. it can access the file system. also called '读取文本文件'", + "read multiple paths into utf8, path relative to the current working directory or absolute path.", parameters: { type: Type.OBJECT, properties: { - entries: { + paths: { type: Type.ARRAY, - description: "an array of entries to read", + description: "an array of paths to read", items: { type: Type.STRING, description: - "the path to read, relative to the current working directory", + "the path to read, relative to the current working directory, or absolute path", }, }, }, }, }, toolFn: async (args: any) => { - let entries = args.entries as Array; + let paths = args.paths as Array; let results = await Promise.allSettled( - entries.map(async (entry) => { + paths.map(async (entry) => { const filepath = entry as string; const filePath = filepath.startsWith("/") ? filepath : path.join("./", filepath); console.log(`Reading file ${filePath}`); const data = await fs.readFile(filePath, "utf8"); - return data; + return { path: entry, content: data }; }) ); return { - stdout: JSON.stringify(results), + stdout: JSON.stringify( + results.map((result) => { + if (result.status === "fulfilled") { + return result.value; + } else { + return `Error reading file: ${result.reason}`; + } + }) + ), stderr: "", success: results.every((result) => result.status === "fulfilled"), }; diff --git a/src/util.mts b/src/util.mts index 0cd4209..4709fb3 100644 --- a/src/util.mts +++ b/src/util.mts @@ -23,19 +23,25 @@ export const displayBoxedText = (text: string) => { }; /** Format an object into a thin string representation */ -export const formatThinObject = (obj: any): string => { +export const formatThinObject = (obj: any, base: string = ""): string => { if (obj === null || obj === undefined) { return undefined as any; } if (typeof obj !== "object") { return `${obj}`; } - + if (Array.isArray(obj)) { + return obj + .map((item, idx) => formatThinObject(item, base + `[${idx}]`)) + .join("\n---- Next Item ----\n"); + } return Object.entries(obj) .filter(([key, value]) => value != null) .map( ([key, value]) => - `---- ${key} ----\n${formatThinObject(value) || "(empty)"}\n` + `---- ${base + "." + key} ----\n${ + formatThinObject(value, base + "." + key) || "(empty)" + }\n` ) .join("\n"); }; From ac3ef486ee0434b0cbd5ac35b8819d51c24201cb Mon Sep 17 00:00:00 2001 From: tiye Date: Mon, 21 Jul 2025 03:06:35 +0800 Subject: [PATCH 7/9] experimental work related to goal remembering --- src/main.mts | 11 ++++- src/tools/files-read.mts | 16 +++---- src/tools/goal.mts | 99 +++++++++++++++++++++++++++++++++++++++ src/tools/guide-steps.mts | 14 +++--- src/util.mts | 3 +- 5 files changed, 123 insertions(+), 20 deletions(-) create mode 100644 src/tools/goal.mts diff --git a/src/main.mts b/src/main.mts index 6a9f484..6a776b6 100644 --- a/src/main.mts +++ b/src/main.mts @@ -19,7 +19,8 @@ import { googleSearchTool } from "./tools/google-search.mjs"; import { MacrophyllaTool } from "./tools/type.mjs"; import { currentDirTool } from "./tools/current-dir.mjs"; import { changeDirTool } from "./tools/change-dir.mjs"; -import { toolContextPrompt } from "./tools/guide-steps.mjs"; +import { guideSteps, toolContextPrompt } from "./tools/guide-steps.mjs"; +import { goalTool, getGoal } from "./tools/goal.mjs"; import { formatThinObject } from "./util.mjs"; // Initialize the Generative AI client @@ -67,6 +68,8 @@ const sayingOk = (message: string) => { }; let toolsDict: Record = { + [getGoal.declaration.name!]: getGoal, + [goalTool.declaration.name!]: goalTool, [bashCommandTool.declaration.name!]: bashCommandTool, [nodejsScriptTool.declaration.name!]: nodejsScriptTool, [filesReadTool.declaration.name!]: filesReadTool, @@ -91,6 +94,8 @@ const main = async () => { let tools: Tool[] = [ { functionDeclarations: [ + getGoal.declaration, + goalTool.declaration, bashCommandTool.declaration, nodejsScriptTool.declaration, filesReadTool.declaration, @@ -141,7 +146,9 @@ const main = async () => { // Use the chat API to send messages and get streaming responses const response = await chat.sendMessageStream({ - message: question, + message: + question + + "(注意识别意图, 有新意图的话写入 remember_goal 工具, 记录任务目标和步骤. 不大清楚的时候查询通过 get_goal 工具来了解当前任务目标和步骤. 使用中文回复.)", config: { httpOptions: { baseUrl: geminiBaseUrl }, tools, diff --git a/src/tools/files-read.mts b/src/tools/files-read.mts index ff946a6..b55d103 100644 --- a/src/tools/files-read.mts +++ b/src/tools/files-read.mts @@ -44,15 +44,13 @@ export let filesReadTool: MacrophyllaTool = { ); return { - stdout: JSON.stringify( - results.map((result) => { - if (result.status === "fulfilled") { - return result.value; - } else { - return `Error reading file: ${result.reason}`; - } - }) - ), + stdout: results.map((result) => { + if (result.status === "fulfilled") { + return result.value; + } else { + return `Error reading file: ${result.reason}`; + } + }), stderr: "", success: results.every((result) => result.status === "fulfilled"), }; diff --git a/src/tools/goal.mts b/src/tools/goal.mts new file mode 100644 index 0000000..5a7770b --- /dev/null +++ b/src/tools/goal.mts @@ -0,0 +1,99 @@ +import { Type } from "@google/genai"; +import { MacrophyllaTool } from "./type.mjs"; +import { exec } from "child_process"; +import { promisify } from "util"; + +let goal = { + goal: "(not defined yet)", + description: "(not defined yet)", + workSteps: [] as { done: boolean; step: string }[], + confirmSteps: [] as { done: boolean; step: string }[], +}; + +export let getGoal: MacrophyllaTool = { + shortName: "get goal", + skipConfirmation: true, + previewFn: (args: any) => { + console.log(`Current goal: ${goal.goal}`); + }, + declaration: { + name: "get_goal", + description: "get the current goal and work steps.", + parameters: { + type: Type.OBJECT, + properties: {}, + }, + }, + toolFn: async (args: any) => { + return { + goal: goal.goal, + description: goal.description, + workSteps: goal.workSteps, + confirmSteps: goal.confirmSteps, + }; + }, +}; + +export let goalTool: MacrophyllaTool = { + shortName: "remember goal", + skipConfirmation: true, + previewFn: (args: any) => { + console.log(`Remembering goal: ${args.goal}`); + }, + declaration: { + name: "remember_goal", + description: + "read/write this state. remember the goal of this task, and the work steps to do.", + parameters: { + type: Type.OBJECT, + properties: { + goal: { + type: Type.STRING, + description: "The goal of this task.", + }, + description: { + type: Type.STRING, + description: "A detailed description of the task.", + }, + workSteps: { + type: Type.ARRAY, + items: { + type: Type.OBJECT, + properties: { + done: { type: Type.BOOLEAN, description: "Is this step done?" }, + step: { type: Type.STRING, description: "The work step." }, + }, + }, + }, + confirmSteps: { + type: Type.ARRAY, + items: { + type: Type.OBJECT, + properties: { + done: { + type: Type.BOOLEAN, + description: "Is this step confirmed?", + }, + step: { + type: Type.STRING, + description: "The confirmation step.", + }, + }, + }, + }, + }, + }, + }, + toolFn: async (args: any) => { + goal.goal = args.goal || goal.goal; + goal.description = args.description || goal.description; + goal.workSteps = args.workSteps || goal.workSteps; + goal.confirmSteps = args.confirmSteps || goal.confirmSteps; + + return { + goal: goal.goal, + progress: goal.workSteps.map((step) => step.done), + confirmSteps: goal.confirmSteps.map((step) => step.done), + }; + }, +}; diff --git a/src/tools/guide-steps.mts b/src/tools/guide-steps.mts index f5eb2e2..ef0511b 100644 --- a/src/tools/guide-steps.mts +++ b/src/tools/guide-steps.mts @@ -1,7 +1,8 @@ import { execSync } from "node:child_process"; import os from "node:os"; -export let guideSteps = `你现在是命令行助手,需要自己安排计划来完成指定任务。 +export let guideSteps = `你现在是命令行助手,需要自己安排计划来完成指定任务, 通过 remember_goal 工具记录任务目标和步骤。后续可以通过 get_goal 工具来获取当前任务目标和步骤。 + 在每次与用户交互时,都要积极、主动地思考并提供帮助。 **任务理解与规划:** @@ -9,8 +10,8 @@ export let guideSteps = `你现在是命令行助手,需要自己安排计划 2. **当前环境感知:** 在开始任何操作前,**务必先通过 current_dir 工具了解当前目录结构**(使用 'ls -F' 命令或其他工具),这是理解上下文的关键。必要时,也会考虑使用 'read_files' 查看关键文件内容。 3. **制定详细计划:** 将任务拆解为逻辑清晰、可执行的步骤。对于每个步骤,思考: * 需要什么信息?(是否需要 web_search?) - * 应该调用哪个工具?(bash_command, nodejs_script, write_files, read_files?) - * 预期的输出是什么? + * 应该调用哪个工具? + * 预期的输出是什么 * 如何验证这个步骤的结果? * 可能遇到什么问题,如何处理? 4. **展示并确认计划:** **在执行前,总是向用户展示你的初步计划**,说明你将如何完成任务,并征求用户的确认。如果计划有不确定性或需要用户输入,请明确提出。 @@ -19,11 +20,6 @@ export let guideSteps = `你现在是命令行助手,需要自己安排计划 5. **逐步执行:** 按照确认的计划一步步执行。每完成一个步骤,都要简要说明做了什么,以及执行结果。 6. **结果校验:** 每执行一个重要步骤或完成整个任务后,**务必进行校验**。例如,创建文件后检查文件是否存在,修改内容后读取验证。 7. **提供最终答案:** 在所有步骤完成并校验无误后,给出最终的答案或任务完成的确认。 - -**错误处理与迭代:** -8. **故障诊断:** 如果工具执行失败,不要轻易放弃。**尝试分析错误信息(例如,查看 bash 命令的 stderr 输出)**,思考失败的原因。是路径问题?权限问题?命令语法错误?还是依赖缺失? -9. **重新规划:** 根据诊断结果,审视原计划的问题点,重新制定解决问题的策略或步骤,并告知用户你将如何尝试修复。 -10. **持续交互:** 如果在任何阶段遇到无法解决的问题,或者需要用户提供更多信息或决策,请清晰地说明情况并请求用户帮助。 `; // 添加一个函数来生成上下文提醒 @@ -42,6 +38,8 @@ export const toolContextPrompt = () => { "你的职责是命令行助手,请在每次回答时都尝试用工具来帮助用户,优先通过工具解决问题。\n" + "\n" + "**可用的工具及其使用策略:**\n" + + "- `get_goal` tool: 获取当前任务目标和步骤。**在开始任何任务前,先使用此工具了解当前任务目标和步骤。**\n" + + "- `remember_goal` tool: 记住任务目标和步骤。**在开始任何任务前,先使用此工具记录目标和计划。任务完成以后确认.**\n" + "- `current_dir` tool: 获取当前目录信息(`ls -F` 命令)。**在开始任何任务或环境不确定时,优先使用此工具以获取当前上下文。**\n" + "- `bash_command` tool: 执行 Bash 命令。适用于大多数命令行操作,如文件操作(mv, cp, rm, mkdir),程序执行,查看系统信息等。**对于直接的 Unix 命令输入,直接调用此工具。**\n" + "- `nodejs_script` tool: 执行 Node.js 代码。当你需要进行更复杂的逻辑处理、文件内容解析(JSON, YAML)、网络请求、或者需要访问 Node.js 内置模块功能时使用。例如,计算、字符串处理、简单的服务器/脚本逻辑。\n" + diff --git a/src/util.mts b/src/util.mts index 4709fb3..fdc18b2 100644 --- a/src/util.mts +++ b/src/util.mts @@ -27,7 +27,7 @@ export const formatThinObject = (obj: any, base: string = ""): string => { if (obj === null || obj === undefined) { return undefined as any; } - if (typeof obj !== "object") { + if (["string", "number", "boolean"].includes(typeof obj)) { return `${obj}`; } if (Array.isArray(obj)) { @@ -35,6 +35,7 @@ export const formatThinObject = (obj: any, base: string = ""): string => { .map((item, idx) => formatThinObject(item, base + `[${idx}]`)) .join("\n---- Next Item ----\n"); } + return Object.entries(obj) .filter(([key, value]) => value != null) .map( From 9d49789a0bd6fcecddb334cbf0f6e47bf37ee456 Mon Sep 17 00:00:00 2001 From: tiye Date: Mon, 21 Jul 2025 14:22:23 +0800 Subject: [PATCH 8/9] more goal tools --- src/main.mts | 25 +++++++++---- src/tools/goal.mts | 78 +++++++++++++++++++++++++++++++++++++-- src/tools/guide-steps.mts | 8 +++- 3 files changed, 99 insertions(+), 12 deletions(-) diff --git a/src/main.mts b/src/main.mts index 6a776b6..4c48cfe 100644 --- a/src/main.mts +++ b/src/main.mts @@ -20,7 +20,12 @@ import { MacrophyllaTool } from "./tools/type.mjs"; import { currentDirTool } from "./tools/current-dir.mjs"; import { changeDirTool } from "./tools/change-dir.mjs"; import { guideSteps, toolContextPrompt } from "./tools/guide-steps.mjs"; -import { goalTool, getGoal } from "./tools/goal.mjs"; +import { + rememberGoal, + getGoal, + finishGoal, + updateWorkStepStatus, +} from "./tools/goal.mjs"; import { formatThinObject } from "./util.mjs"; // Initialize the Generative AI client @@ -69,7 +74,9 @@ const sayingOk = (message: string) => { let toolsDict: Record = { [getGoal.declaration.name!]: getGoal, - [goalTool.declaration.name!]: goalTool, + [finishGoal.declaration.name!]: finishGoal, + [rememberGoal.declaration.name!]: rememberGoal, + [updateWorkStepStatus.declaration.name!]: updateWorkStepStatus, [bashCommandTool.declaration.name!]: bashCommandTool, [nodejsScriptTool.declaration.name!]: nodejsScriptTool, [filesReadTool.declaration.name!]: filesReadTool, @@ -95,7 +102,9 @@ const main = async () => { { functionDeclarations: [ getGoal.declaration, - goalTool.declaration, + finishGoal.declaration, + rememberGoal.declaration, + updateWorkStepStatus.declaration, bashCommandTool.declaration, nodejsScriptTool.declaration, filesReadTool.declaration, @@ -146,9 +155,7 @@ const main = async () => { // Use the chat API to send messages and get streaming responses const response = await chat.sendMessageStream({ - message: - question + - "(注意识别意图, 有新意图的话写入 remember_goal 工具, 记录任务目标和步骤. 不大清楚的时候查询通过 get_goal 工具来了解当前任务目标和步骤. 使用中文回复.)", + message: question, config: { httpOptions: { baseUrl: geminiBaseUrl }, tools, @@ -203,8 +210,12 @@ const main = async () => { // result.originalQuestion = question; // result.toolName = tool.shortName; + const goalState = await getGoal.toolFn({}); + nextQuestion = - "answer based previous command response:\n" + + "current goal state:\n" + + formatThinObject(goalState) + + "\nanswer based previous command response:\n" + formatThinObject(result); continue outerWhile; } catch (error) { diff --git a/src/tools/goal.mts b/src/tools/goal.mts index 5a7770b..7a944f5 100644 --- a/src/tools/goal.mts +++ b/src/tools/goal.mts @@ -4,6 +4,7 @@ import { exec } from "child_process"; import { promisify } from "util"; let goal = { + hasGoal: false, goal: "(not defined yet)", description: "(not defined yet)", workSteps: [] as { done: boolean; step: string }[], @@ -25,16 +26,84 @@ export let getGoal: MacrophyllaTool = { }, }, toolFn: async (args: any) => { + if (goal.hasGoal) { + return { + goal: goal.goal, + description: goal.description, + workSteps: goal.workSteps, + confirmSteps: goal.confirmSteps, + }; + } + + return { + goal: "任务目标未定义, 提示用户输入新的任务, 或者结束会话", + }; + }, +}; + +export let finishGoal: MacrophyllaTool = { + shortName: "finish goal", + skipConfirmation: true, + previewFn: (args: any) => { + console.log(`Finishing goal: ${args.goal}`); + }, + declaration: { + name: "finish_goal", + description: "Finish the current goal.", + parameters: { + type: Type.OBJECT, + properties: {}, + }, + }, + toolFn: async (args: any) => { + goal.hasGoal = false; + goal.goal = "(not defined yet)"; + goal.description = "(not defined yet)"; + goal.workSteps = []; + goal.confirmSteps = []; + + return { + message: "(finished goal, now goal is not defined)", + }; + }, +}; + +export let updateWorkStepStatus: MacrophyllaTool = { + shortName: "update work step status", + skipConfirmation: true, + previewFn: (args: any) => { + console.log(`Updating work step status: ${args.step}`); + }, + declaration: { + name: "update_work_step_status", + description: "Update the status of a work step.", + parameters: { + type: Type.OBJECT, + properties: { + step: { + type: Type.STRING, + description: "The work step to update.", + }, + status: { + type: Type.BOOLEAN, + description: "The new status of the work step.", + }, + }, + }, + }, + toolFn: async (args: any) => { + const step = goal.workSteps.find((s) => s.step === args.step); + if (step) { + step.done = args.status; + } return { goal: goal.goal, - description: goal.description, - workSteps: goal.workSteps, - confirmSteps: goal.confirmSteps, + progress: goal.workSteps.map((step) => step.done), }; }, }; -export let goalTool: MacrophyllaTool = { +export let rememberGoal: MacrophyllaTool = { shortName: "remember goal", skipConfirmation: true, previewFn: (args: any) => { @@ -85,6 +154,7 @@ export let goalTool: MacrophyllaTool = { }, }, toolFn: async (args: any) => { + goal.hasGoal = true; goal.goal = args.goal || goal.goal; goal.description = args.description || goal.description; goal.workSteps = args.workSteps || goal.workSteps; diff --git a/src/tools/guide-steps.mts b/src/tools/guide-steps.mts index ef0511b..1bf1ea2 100644 --- a/src/tools/guide-steps.mts +++ b/src/tools/guide-steps.mts @@ -1,7 +1,11 @@ import { execSync } from "node:child_process"; import os from "node:os"; -export let guideSteps = `你现在是命令行助手,需要自己安排计划来完成指定任务, 通过 remember_goal 工具记录任务目标和步骤。后续可以通过 get_goal 工具来获取当前任务目标和步骤。 +export let guideSteps = `你现在是 Agent, 现在系统中提供了可以记录修改状态的工具, +- get_goal 工具来获取当前任务目标和步骤, 初始是未设置的。 +- remember_goal 用于写入任务和步骤, 记录任务目标和步骤. 要求在第一次接受到任务时分解任务目标和步骤, 并写入 remember_goal 工具。 +- update_work_step_status 用于更新某个步骤的完成状态. +- finish_goal 工具来确认任务已完成并清除当前目标。 在每次与用户交互时,都要积极、主动地思考并提供帮助。 @@ -39,7 +43,9 @@ export const toolContextPrompt = () => { "\n" + "**可用的工具及其使用策略:**\n" + "- `get_goal` tool: 获取当前任务目标和步骤。**在开始任何任务前,先使用此工具了解当前任务目标和步骤。**\n" + + "- `finish_goal` tool: 完成当前任务目标。**在任务完成后,使用此工具来确认任务已完成并清除当前目标。**\n" + "- `remember_goal` tool: 记住任务目标和步骤。**在开始任何任务前,先使用此工具记录目标和计划。任务完成以后确认.**\n" + + "- `update_work_step_status` tool: 更新某个步骤的完成状态。**在完成一个步骤后,使用此工具来更新步骤的完成状态。**\n" + "- `current_dir` tool: 获取当前目录信息(`ls -F` 命令)。**在开始任何任务或环境不确定时,优先使用此工具以获取当前上下文。**\n" + "- `bash_command` tool: 执行 Bash 命令。适用于大多数命令行操作,如文件操作(mv, cp, rm, mkdir),程序执行,查看系统信息等。**对于直接的 Unix 命令输入,直接调用此工具。**\n" + "- `nodejs_script` tool: 执行 Node.js 代码。当你需要进行更复杂的逻辑处理、文件内容解析(JSON, YAML)、网络请求、或者需要访问 Node.js 内置模块功能时使用。例如,计算、字符串处理、简单的服务器/脚本逻辑。\n" + From 53d6cd0e97a448e61dde1bab1c0abeb117a2e2b2 Mon Sep 17 00:00:00 2001 From: tiye Date: Mon, 21 Jul 2025 15:05:03 +0800 Subject: [PATCH 9/9] gemini refactor --- src/main.mts | 387 ++++++++++++++++++-------------------- src/tools/goal.mts | 67 ++++++- src/tools/guide-steps.mts | 83 ++++---- 3 files changed, 293 insertions(+), 244 deletions(-) diff --git a/src/main.mts b/src/main.mts index 4c48cfe..d02e087 100644 --- a/src/main.mts +++ b/src/main.mts @@ -1,13 +1,13 @@ import * as readline from "readline"; import chalk from "chalk"; import { + Content, + FunctionCall, FunctionCallingConfigMode, - FunctionDeclaration, GoogleGenAI, - HarmBlockThreshold, + Part, Tool, ToolConfig, - Type, } from "@google/genai"; import { handleChildSIGINT } from "./tools/task-state.mjs"; @@ -19,20 +19,24 @@ import { googleSearchTool } from "./tools/google-search.mjs"; import { MacrophyllaTool } from "./tools/type.mjs"; import { currentDirTool } from "./tools/current-dir.mjs"; import { changeDirTool } from "./tools/change-dir.mjs"; -import { guideSteps, toolContextPrompt } from "./tools/guide-steps.mjs"; +import { toolContextPrompt } from "./tools/guide-steps.mjs"; import { rememberGoal, getGoal, finishGoal, updateWorkStepStatus, + recordFailedAttempt, } from "./tools/goal.mjs"; -import { formatThinObject } from "./util.mjs"; -// Initialize the Generative AI client -const genAi = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY! }); +// --- Agent State Definition --- +interface AgentState { + history: Content[]; + currentMessageParts: Part[]; +} +// --- Tool & Model Configuration --- +const genAi = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY! }); const geminiBaseUrl = process.env.GEMINI_BASE_URL; - const verbose = (process.env.verbose || process.env.VERBOSE) === "true" || false; const thinkingBudget = parseInt( @@ -40,43 +44,12 @@ const thinkingBudget = parseInt( 10 ); -const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout, -}); - -rl.on("SIGINT", () => { - let hitChild = handleChildSIGINT(); - if (hitChild) { - console.log(chalk.gray("\nReceived SIGINT signal, killed child process")); - } else { - rl.close(); - process.exit(0); - } -}); - -const ask = (question: string, seperator: boolean = false) => { - if (seperator) { - console.log(chalk.gray("\n" + "─".repeat(50))); - } - return new Promise((resolve) => { - rl.question(chalk.cyan(question), (answer) => { - resolve(answer); - }); - }); -}; - -const sayingOk = (message: string) => { - return ( - message === "ok" || message === "yes" || message === "y" || message === "" - ); -}; - -let toolsDict: Record = { +const toolsDict: Record = { [getGoal.declaration.name!]: getGoal, [finishGoal.declaration.name!]: finishGoal, [rememberGoal.declaration.name!]: rememberGoal, [updateWorkStepStatus.declaration.name!]: updateWorkStepStatus, + [recordFailedAttempt.declaration.name!]: recordFailedAttempt, [bashCommandTool.declaration.name!]: bashCommandTool, [nodejsScriptTool.declaration.name!]: nodejsScriptTool, [filesReadTool.declaration.name!]: filesReadTool, @@ -86,188 +59,202 @@ let toolsDict: Record = { [changeDirTool.declaration.name!]: changeDirTool, }; -const main = async () => { - try { - // Create a chat session - // Define a function declaration tool +const toolConfig: ToolConfig = { + functionCallingConfig: { mode: FunctionCallingConfigMode.AUTO }, +}; +const tools: Tool[] = [ + { functionDeclarations: Object.values(toolsDict).map((t) => t.declaration) }, +]; + +// --- Agent Nodes (Core Logic) --- + +async function callModel( + state: AgentState +): Promise<{ modelResponseParts: Part[]; toolCalls?: FunctionCall[] }> { + console.log(chalk.gray("\nThinking...\n")); + + const chat = genAi.chats.create({ + model: process.env["MACROPHYLLA_MODEL"] || "gemini-2.5-flash", + config: { systemInstruction: toolContextPrompt() }, + history: state.history, + }); + + const response = await chat.sendMessageStream({ + message: state.currentMessageParts, + config: { + httpOptions: { baseUrl: geminiBaseUrl }, + tools, + toolConfig, + temperature: 0.2, + thinkingConfig: + thinkingBudget > 256 + ? { includeThoughts: true, thinkingBudget: thinkingBudget } + : undefined, + }, + }); - // Configure tool settings - const toolConfig: ToolConfig = { - functionCallingConfig: { - mode: FunctionCallingConfigMode.AUTO, // Let the model decide when to call the function - }, - }; + const newToolCalls: FunctionCall[] = []; + const modelResponseParts: Part[] = []; + let textResponse = ""; - let tools: Tool[] = [ - { - functionDeclarations: [ - getGoal.declaration, - finishGoal.declaration, - rememberGoal.declaration, - updateWorkStepStatus.declaration, - bashCommandTool.declaration, - nodejsScriptTool.declaration, - filesReadTool.declaration, - filesWriteTool.declaration, - googleSearchTool.declaration, - currentDirTool.declaration, - changeDirTool.declaration, - ], - }, - ]; + for await (const chunk of response) { + if (chunk.functionCalls) { + newToolCalls.push(...chunk.functionCalls); + } + const text = chunk.text; + if (text) { + textResponse += text; + process.stdout.write(text); + } + } - // Create a chat session with the defined tool - const chat = genAi.chats.create({ - model: process.env["MACROPHYLLA_MODEL"] || "gemini-2.5-flash", - config: { - systemInstruction: toolContextPrompt(), - }, - // history: [{ role: "user", parts: [{ text: toolContextPrompt() }] }], + if (textResponse) { + modelResponseParts.push({ text: textResponse }); + } + if (newToolCalls.length > 0) { + newToolCalls.forEach(call => { + modelResponseParts.push({ functionCall: call }); }); + } - let nextQuestion: string = ""; - let messageCount = 0; + return { + modelResponseParts, + toolCalls: newToolCalls.length > 0 ? newToolCalls : undefined, + }; +} - outerWhile: while (true) { - if (verbose && nextQuestion) { - console.log(chalk.gray("\n" + nextQuestion + "\n")); - } - let question = - nextQuestion || - (await ask("\nWhat's the task: ", true)) || - "继续上一个会话的计划"; +async function executeTools( + toolCalls: FunctionCall[] +): Promise<{ toolResultParts: Part[] }> { + const toolResultParts: Part[] = []; - if (question.toLowerCase() === "exit") { - console.log("\nBye!"); - break; - } - // 每隔 5 轮对话,插入上下文提醒 - messageCount++; - // if (messageCount % 10 === 0) { - // const reminder = "重要提醒: " + toolContextPrompt(); - // if (verbose) { - // console.log(chalk.gray("\n\n(提醒)\n\n")); - // } - // question = `${reminder}\n\n${question}`; - // } + for (const call of toolCalls) { + const tool = call.name ? toolsDict[call.name] : undefined; + if (!tool) { + console.log(chalk.red(`\nError: Unsupported tool ${call.name}`)); + toolResultParts.push({ + functionResponse: { + name: call.name, + response: { error: `Unsupported tool: ${call.name}` }, + }, + }); + continue; + } - console.log(chalk.gray("\nResponding...\n")); + console.log(chalk.yellow(`\nExecuting ${tool.shortName}...`)); + tool.previewFn(call.args); - // Use the chat API to send messages and get streaming responses - const response = await chat.sendMessageStream({ - message: question, - config: { - httpOptions: { baseUrl: geminiBaseUrl }, - tools, - toolConfig, - temperature: 0.2, - // safetySettings: [{ threshold: HarmBlockThreshold.OFF }], - thinkingConfig: - thinkingBudget > 256 - ? { includeThoughts: true, thinkingBudget: thinkingBudget } - : undefined, + let confirmation = "y"; + if (!tool.skipConfirmation) { + confirmation = await ask( + `\nExecute this ${tool.shortName} script? (y/n): ` + ); + } + + if (sayingOk(confirmation)) { + try { + const result = await tool.toolFn(call.args); + toolResultParts.push({ + functionResponse: { name: call.name, response: result }, + }); + console.log(chalk.green("Execution finished.")); + } catch (error) { + const errorMsg = error.stderr || error.message; + console.log(chalk.red(`\nExecution failed: ${errorMsg}`)); + await recordFailedAttempt.toolFn({ + step: `(Attempting) ${tool.shortName}`, + toolName: tool.shortName, + toolArgs: call.args, + error: errorMsg, + }); + toolResultParts.push({ + functionResponse: { + name: call.name, + response: { error: errorMsg }, + }, + }); + } + } else { + console.log(chalk.gray("Execution skipped by user.")); + toolResultParts.push({ + functionResponse: { + name: call.name, + response: { error: "User skipped execution." }, }, }); - for await (const chunk of response) { - let responseMessage = chunk.text; - let textWritten = false; - let responseFunctionCalls = - chunk.functionCalls != null && chunk.functionCalls.length > 0 - ? chunk.functionCalls - : undefined; + } + } - if (responseMessage != null) { - process.stdout.write(responseMessage); - textWritten = true; - } - if (responseFunctionCalls) { - for (const functionCall of responseFunctionCalls) { - let tool = toolsDict[functionCall.name!]; - const args: any = functionCall.args; - if (tool) { - // Ask for user confirmation - console.log(`\n${tool.shortName} to execute:\n`); - tool.previewFn(args); - let confirmation = "ok"; - if (!tool.skipConfirmation) { - confirmation = await ask( - `\nExecute this ${tool.shortName} script? (y/n): ` - ); - } + return { toolResultParts }; +} - if (sayingOk(confirmation)) { - console.log( - chalk.gray(`\nExecuting ${tool.shortName} command...`) - ); +// --- User Interaction --- +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, +}); - try { - const result = await tool.toolFn(args); - if (result.stderr) { - console.log(chalk.red("运行失败\n" + result.stderr)); - } else { - console.log(chalk.green("运行完成.")); - } - // result.originalQuestion = question; - // result.toolName = tool.shortName; +rl.on("SIGINT", () => { + if (handleChildSIGINT()) { + console.log(chalk.gray("\nSIGINT: Killed child process.")); + } else { + rl.close(); + process.exit(0); + } +}); - const goalState = await getGoal.toolFn({}); +const ask = (question: string, seperator: boolean = false) => { + if (seperator) console.log(chalk.gray("\n" + "─".repeat(50))); + return new Promise((resolve) => { + rl.question(chalk.cyan(question), resolve); + }); +}; - nextQuestion = - "current goal state:\n" + - formatThinObject(goalState) + - "\nanswer based previous command response:\n" + - formatThinObject(result); - continue outerWhile; - } catch (error) { - const result = { - stdout: error.stdout || "", - stderr: error.stderr || error.message, - success: false, - }; - console.log("\n"); - console.log("Command failed:", result); +const sayingOk = (message: string) => + ["ok", "yes", "y", ""].includes(message.toLowerCase()); - nextQuestion = `命令执行过程当中失败: ${result.stderr}, 你能否改进一下方案?`; - continue outerWhile; - } - } else { - nextQuestion = `存在问题, 要求改进调用方式: ${confirmation}.`; - continue outerWhile; - } - } else { - console.log( - chalk.red( - `\n\nError: Unsupported function call ${functionCall.name}` - ) - ); - nextQuestion = `不支持的函数调用: ${functionCall.name}, 你能否改进一下方案?`; - continue outerWhile; - } - } - } - if (chunk.candidates?.[0].content?.parts?.[0]?.text) { - if (!textWritten && verbose) { - console.log( - chalk.gray( - `\nThinking: ${chunk.candidates[0].content.parts[0].text}\n` - ) - ); - } - } else if (responseMessage == null && responseFunctionCalls == null) { - console.warn("unknown chunk:", JSON.stringify(chunk)); - } +// --- Main Agent Runner --- +const main = async () => { + try { + let history: Content[] = []; + while (true) { + const userInput = + (await ask("\nWhat's the task: ", true)) || "继续上一个会话的计划"; + if (userInput.toLowerCase() === "exit") { + console.log("\nBye!"); + break; } - // clear the next question cache - nextQuestion = ""; + let state: AgentState = { + history: history, + currentMessageParts: [{ text: userInput }], + }; + + // The "Graph" or State Machine Loop + while (true) { + const { modelResponseParts, toolCalls } = await callModel(state); + + state.history.push( + { role: "user", parts: state.currentMessageParts }, + { role: "model", parts: modelResponseParts } + ); + + if (!toolCalls || toolCalls.length === 0) { + console.log(chalk.green("\nTask iteration complete.")); + history = state.history; + break; + } + + const { toolResultParts } = await executeTools(toolCalls); + + state.currentMessageParts = toolResultParts; + } } } catch (err) { - console.error("Error:", err); - rl.close(); - process.exit(1); + console.error("Fatal Error:", err); } finally { rl.close(); } }; -main(); +main(); \ No newline at end of file diff --git a/src/tools/goal.mts b/src/tools/goal.mts index 7a944f5..c714b99 100644 --- a/src/tools/goal.mts +++ b/src/tools/goal.mts @@ -1,7 +1,5 @@ import { Type } from "@google/genai"; import { MacrophyllaTool } from "./type.mjs"; -import { exec } from "child_process"; -import { promisify } from "util"; let goal = { hasGoal: false, @@ -9,6 +7,12 @@ let goal = { description: "(not defined yet)", workSteps: [] as { done: boolean; step: string }[], confirmSteps: [] as { done: boolean; step: string }[], + failedAttempts: [] as { + step: string; + toolName: string; + toolArgs: any; + error: string; + }[], }; export let getGoal: MacrophyllaTool = { @@ -19,7 +23,7 @@ export let getGoal: MacrophyllaTool = { }, declaration: { name: "get_goal", - description: "get the current goal and work steps.", + description: "Get the current goal, work steps, and failed attempts.", parameters: { type: Type.OBJECT, properties: {}, @@ -32,6 +36,7 @@ export let getGoal: MacrophyllaTool = { description: goal.description, workSteps: goal.workSteps, confirmSteps: goal.confirmSteps, + failedAttempts: goal.failedAttempts, }; } @@ -49,7 +54,7 @@ export let finishGoal: MacrophyllaTool = { }, declaration: { name: "finish_goal", - description: "Finish the current goal.", + description: "Finish the current goal and clear all states.", parameters: { type: Type.OBJECT, properties: {}, @@ -61,9 +66,56 @@ export let finishGoal: MacrophyllaTool = { goal.description = "(not defined yet)"; goal.workSteps = []; goal.confirmSteps = []; + goal.failedAttempts = []; return { - message: "(finished goal, now goal is not defined)", + message: "(finished goal, all states have been cleared)", + }; + }, +}; + +export let recordFailedAttempt: MacrophyllaTool = { + shortName: "record failed attempt", + skipConfirmation: true, + previewFn: (args: any) => { + console.log(`Recording failed attempt for step: ${args.step}`); + }, + declaration: { + name: "record_failed_attempt", + description: "Record a failed tool execution attempt for learning.", + parameters: { + type: Type.OBJECT, + properties: { + step: { + type: Type.STRING, + description: "The work step that was being attempted.", + }, + toolName: { + type: Type.STRING, + description: "The name of the tool that failed.", + }, + toolArgs: { + type: Type.OBJECT, + description: "The arguments passed to the failed tool.", + }, + error: { + type: Type.STRING, + description: "The error message (stderr) from the tool.", + }, + }, + required: ["step", "toolName", "toolArgs", "error"], + }, + }, + toolFn: async (args: any) => { + goal.failedAttempts.push({ + step: args.step, + toolName: args.toolName, + toolArgs: args.toolArgs, + error: args.error, + }); + return { + status: "failed attempt recorded", + failedAttempts: goal.failedAttempts, }; }, }; @@ -89,6 +141,7 @@ export let updateWorkStepStatus: MacrophyllaTool = { description: "The new status of the work step.", }, }, + required: ["step", "status"], }, }, toolFn: async (args: any) => { @@ -112,7 +165,7 @@ export let rememberGoal: MacrophyllaTool = { declaration: { name: "remember_goal", description: - "read/write this state. remember the goal of this task, and the work steps to do.", + "Remember the goal and work steps. This should be the first step.", parameters: { type: Type.OBJECT, properties: { @@ -151,6 +204,7 @@ export let rememberGoal: MacrophyllaTool = { }, }, }, + required: ["goal", "description", "workSteps"], }, }, toolFn: async (args: any) => { @@ -159,6 +213,7 @@ export let rememberGoal: MacrophyllaTool = { goal.description = args.description || goal.description; goal.workSteps = args.workSteps || goal.workSteps; goal.confirmSteps = args.confirmSteps || goal.confirmSteps; + goal.failedAttempts = []; // Clear previous failures when a new goal is set return { goal: goal.goal, diff --git a/src/tools/guide-steps.mts b/src/tools/guide-steps.mts index 1bf1ea2..7503f41 100644 --- a/src/tools/guide-steps.mts +++ b/src/tools/guide-steps.mts @@ -1,29 +1,43 @@ import { execSync } from "node:child_process"; import os from "node:os"; -export let guideSteps = `你现在是 Agent, 现在系统中提供了可以记录修改状态的工具, -- get_goal 工具来获取当前任务目标和步骤, 初始是未设置的。 -- remember_goal 用于写入任务和步骤, 记录任务目标和步骤. 要求在第一次接受到任务时分解任务目标和步骤, 并写入 remember_goal 工具。 -- update_work_step_status 用于更新某个步骤的完成状态. -- finish_goal 工具来确认任务已完成并清除当前目标。 +export let guideSteps = `你是一个有自主能力的 AI Agent,你的目标是高效、准确地帮助用户完成任务。请严格遵循以下工作流程和思维模式: -在每次与用户交互时,都要积极、主动地思考并提供帮助。 +**=== 核心规则 #1: 必须先定义目标 ===** +**当接收到新的用户任务时,你的第一个、也是唯一允许的初始行动,就是调用 \`remember_goal\` 工具。** +1. **分析用户请求**: 理解用户的最终意图。 +2. **分解任务**: 将任务分解为清晰、可执行的步骤 (\`workSteps\`)。 +3. **立即记录**: 调用 \`remember_goal\`,将分析出的目标 (\`goal\`)、描述 (\`description\`) 和工作步骤 (\`workSteps\`) 记录下来。所有步骤的 \`done\` 状态必须初始化为 \`false\`。 -**任务理解与规划:** -1. **明确目标:** 首先,彻底理解用户的请求,分解任务目标。如果请求模糊或有歧义,请主动询问,直到目标清晰。 -2. **当前环境感知:** 在开始任何操作前,**务必先通过 current_dir 工具了解当前目录结构**(使用 'ls -F' 命令或其他工具),这是理解上下文的关键。必要时,也会考虑使用 'read_files' 查看关键文件内容。 -3. **制定详细计划:** 将任务拆解为逻辑清晰、可执行的步骤。对于每个步骤,思考: - * 需要什么信息?(是否需要 web_search?) - * 应该调用哪个工具? - * 预期的输出是什么 - * 如何验证这个步骤的结果? - * 可能遇到什么问题,如何处理? -4. **展示并确认计划:** **在执行前,总是向用户展示你的初步计划**,说明你将如何完成任务,并征求用户的确认。如果计划有不确定性或需要用户输入,请明确提出。 +**在目标被记录之后**,你才能开始下面的标准工作流程。 -**执行与反馈:** -5. **逐步执行:** 按照确认的计划一步步执行。每完成一个步骤,都要简要说明做了什么,以及执行结果。 -6. **结果校验:** 每执行一个重要步骤或完成整个任务后,**务必进行校验**。例如,创建文件后检查文件是否存在,修改内容后读取验证。 -7. **提供最终答案:** 在所有步骤完成并校验无误后,给出最终的答案或任务完成的确认。 +**核心工作流程: 规划 -> 行动 -> 观察 -> 调整** + +1. **规划 (Plan) - 决定下一步** + * **审视状态**: 调用 \`get_goal\` 查看当前整体目标、所有步骤的完成状态以及过去的失败记录(\`failedAttempts\`)。 + * **选择步骤**: 从 \`workSteps\` 中选择一个未完成的步骤 (\`done: false\`) 作为当前要执行的任务。 + * **选择工具**: 根据要执行的步骤和失败记录,选择最合适的工具,避免重复犯错。 + +2. **行动 (Act) - 执行工具** + * **执行**: 调用你选择的工具。 + * **用户确认**: 在执行可能产生副作用的工具前(如 \`bash_command\`, \`files_write\`),清晰地向用户展示你将要执行的操作,并请求确认。 + +3. **观察 (Observe) - 分析结果** + * **评估输出**: 仔细检查工具的执行结果(stdout, stderr)。 + * **成功**: 如果工具成功执行并达到预期,调用 \`update_work_step_status\` 将刚刚完成的步骤标记为 \`done: true\`。然后回到“规划”阶段。 + * **失败/意外**: 如果出现错误 (\`stderr\`) 或结果不符合预期,**必须立即进入“调整”阶段**。 + +4. **调整 (Adjust) - 从失败中学习** + * **核心规则 #2: 必须记录失败**: 如果一个工具调用失败,你的首要任务是调用 \`record_failed_attempt\` 工具,把你尝试的步骤、工具、参数和收到的错误信息(\`stderr\`)都记录下来。 + * **分析问题**: 在记录失败后,分析失败的原因。是命令错了?还是需要额外的信息? + * **提出方案**: 提出一个修正计划。可能需要: + * 使用 \`web_search\` 查找错误信息。 + * 修改工具的参数。 + * 甚至修改原有的工作步骤(通过调用 \`remember_goal\` 更新步骤列表)。 + * **循环**: 回到“规划”阶段,执行你的修正计划。 + +**任务完成** +* 当所有 \`workSteps\` 和 \`confirmSteps\` 都标记为 \`done: true\` 后,调用 \`finish_goal\` 来结束任务,并向用户报告任务已成功完成。 `; // 添加一个函数来生成上下文提醒 @@ -37,28 +51,21 @@ export const toolContextPrompt = () => { return ( guideSteps + // 确保 guideSteps 总是优先加载 "\n" + - "--- 命令行助手环境与工具指南 ---\n" + - "使用中文回复,但代码保持英文。输出环境为命令行,请尽量减少使用 Markdown 格式(除非用于清晰地表示代码块或列表)。\n" + - "你的职责是命令行助手,请在每次回答时都尝试用工具来帮助用户,优先通过工具解决问题。\n" + + "--- 环境与工具指南 ---\n" + + "**回复语言**: 使用中文,但代码和命令保持英文。\n" + + "**输出格式**: 尽量减少 Markdown,除非需要代码块或列表。\n" + "\n" + - "**可用的工具及其使用策略:**\n" + - "- `get_goal` tool: 获取当前任务目标和步骤。**在开始任何任务前,先使用此工具了解当前任务目标和步骤。**\n" + - "- `finish_goal` tool: 完成当前任务目标。**在任务完成后,使用此工具来确认任务已完成并清除当前目标。**\n" + - "- `remember_goal` tool: 记住任务目标和步骤。**在开始任何任务前,先使用此工具记录目标和计划。任务完成以后确认.**\n" + - "- `update_work_step_status` tool: 更新某个步骤的完成状态。**在完成一个步骤后,使用此工具来更新步骤的完成状态。**\n" + - "- `current_dir` tool: 获取当前目录信息(`ls -F` 命令)。**在开始任何任务或环境不确定时,优先使用此工具以获取当前上下文。**\n" + - "- `bash_command` tool: 执行 Bash 命令。适用于大多数命令行操作,如文件操作(mv, cp, rm, mkdir),程序执行,查看系统信息等。**对于直接的 Unix 命令输入,直接调用此工具。**\n" + - "- `nodejs_script` tool: 执行 Node.js 代码。当你需要进行更复杂的逻辑处理、文件内容解析(JSON, YAML)、网络请求、或者需要访问 Node.js 内置模块功能时使用。例如,计算、字符串处理、简单的服务器/脚本逻辑。\n" + - "- `write_files` tool: 同时创建或更新多个文件。当你需要生成多个配置文件、代码文件或文档时,此工具效率最高。传入多个对象数组,键为文件名,值为文件内容。\n" + - "- `read_files` tool: 读取文件内容。在需要分析现有文件内容,或者确认文件是否按预期创建/修改时使用。\n" + - "- `web_search` tool: 搜索最新信息或不确定的知识。当你对某个概念、技术或错误信息不了解时,或者需要获取最新教程、API 文档时使用。\n" + + "**工具使用策略:**\n" + + "- **状态管理**: \`get_goal\`, \`remember_goal\`, \`update_work_step_status\`, \`finish_goal\`, \`record_failed_attempt\` 是你的核心记忆,严格按照上述工作流程使用它们。\n" + + "- **环境感知**: \`current_dir\` 是你的眼睛,在执行任何文件操作或不确定环境时,优先使用它。\n" + + "- **文件操作**: \`read_files\`, \`write_files\` 用于读写文件。\n" + + "- **命令执行**: \`bash_command\` (通用命令), \`nodejs_script\` (复杂逻辑、计算、解析)。\n" + + "- **信息获取**: \`web_search\` 用于获取外部信息和解决未知问题。\n" + "\n" + - `**当前系统与环境信息:**\n` + + `**当前系统环境:**\n` + `系统: ${osInfo}\n` + `Node.js: ${nodeInfo}\n` + `Bash: ${bashInfo}\n` + - `你并不是完全隔离在沙箱当中的,调用 nodejs 可以完成大量任务,例如使用 'fs' 模块进行复杂文件操作,或者 'http' 模块进行网络通信。\n` + - `记住,如果输入的信息直接就是 Unix 命令(例如 'ls -al' 或 'mkdir my_project'),那么直接用 bash_command tool 执行即可,无需额外解释或规划。\n` + - `每次执行完一个工具后,请清晰地说明结果。如果执行失败,请尝试诊断问题并提出解决方案。\n` + `你可以调用 nodejs 的 'fs' 和 'http' 模块。如果用户输入直接是 shell 命令,请直接用 \`bash_command\` 执行。\n` ); };