@travisennis/acai 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/agent/index.d.ts +119 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +406 -0
- package/dist/agent/manual-loop.d.ts +41 -0
- package/dist/agent/manual-loop.d.ts.map +1 -0
- package/dist/agent/manual-loop.js +278 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +27 -33
- package/dist/commands/add-directory-command.d.ts +3 -0
- package/dist/commands/add-directory-command.d.ts.map +1 -0
- package/dist/commands/add-directory-command.js +85 -0
- package/dist/commands/application-log-command.d.ts.map +1 -1
- package/dist/commands/application-log-command.js +34 -0
- package/dist/commands/clear-command.d.ts.map +1 -1
- package/dist/commands/clear-command.js +8 -0
- package/dist/commands/compact-command.d.ts.map +1 -1
- package/dist/commands/compact-command.js +15 -2
- package/dist/commands/context-command.d.ts +3 -0
- package/dist/commands/context-command.d.ts.map +1 -0
- package/dist/commands/context-command.js +183 -0
- package/dist/commands/copy-command.d.ts.map +1 -1
- package/dist/commands/copy-command.js +28 -0
- package/dist/commands/edit-command.d.ts.map +1 -1
- package/dist/commands/edit-command.js +33 -0
- package/dist/commands/edit-prompt-command.d.ts.map +1 -1
- package/dist/commands/edit-prompt-command.js +28 -0
- package/dist/commands/exit-command.d.ts.map +1 -1
- package/dist/commands/exit-command.js +20 -0
- package/dist/commands/files-command.d.ts.map +1 -1
- package/dist/commands/files-command.js +57 -0
- package/dist/commands/generate-rules-command.d.ts.map +1 -1
- package/dist/commands/generate-rules-command.js +311 -1
- package/dist/commands/handoff-command.d.ts +3 -0
- package/dist/commands/handoff-command.d.ts.map +1 -0
- package/dist/commands/handoff-command.js +202 -0
- package/dist/commands/health-command.d.ts.map +1 -1
- package/dist/commands/health-command.js +119 -2
- package/dist/commands/help-command.d.ts.map +1 -1
- package/dist/commands/help-command.js +28 -0
- package/dist/commands/history-command.d.ts +3 -0
- package/dist/commands/history-command.d.ts.map +1 -0
- package/dist/commands/history-command.js +534 -0
- package/dist/commands/init-command.d.ts +1 -1
- package/dist/commands/init-command.d.ts.map +1 -1
- package/dist/commands/init-command.js +55 -18
- package/dist/commands/last-log-command.d.ts.map +1 -1
- package/dist/commands/last-log-command.js +27 -0
- package/dist/commands/list-directories-command.d.ts +3 -0
- package/dist/commands/list-directories-command.d.ts.map +1 -0
- package/dist/commands/list-directories-command.js +48 -0
- package/dist/commands/list-tools-command.d.ts.map +1 -1
- package/dist/commands/list-tools-command.js +66 -3
- package/dist/commands/manager.d.ts +15 -3
- package/dist/commands/manager.d.ts.map +1 -1
- package/dist/commands/manager.js +86 -26
- package/dist/commands/model-command.d.ts +22 -0
- package/dist/commands/model-command.d.ts.map +1 -1
- package/dist/commands/model-command.js +256 -0
- package/dist/commands/paste-command.d.ts.map +1 -1
- package/dist/commands/paste-command.js +92 -0
- package/dist/commands/pickup-command.d.ts +3 -0
- package/dist/commands/pickup-command.d.ts.map +1 -0
- package/dist/commands/pickup-command.js +161 -0
- package/dist/commands/prompt-command.d.ts +1 -1
- package/dist/commands/prompt-command.d.ts.map +1 -1
- package/dist/commands/prompt-command.js +117 -2
- package/dist/commands/remove-directory-command.d.ts +3 -0
- package/dist/commands/remove-directory-command.d.ts.map +1 -0
- package/dist/commands/remove-directory-command.js +87 -0
- package/dist/commands/reset-command.d.ts +1 -1
- package/dist/commands/reset-command.d.ts.map +1 -1
- package/dist/commands/reset-command.js +13 -2
- package/dist/commands/rules-command.d.ts.map +1 -1
- package/dist/commands/rules-command.js +65 -0
- package/dist/commands/save-command.d.ts.map +1 -1
- package/dist/commands/save-command.js +12 -0
- package/dist/commands/shell-command.d.ts.map +1 -1
- package/dist/commands/shell-command.js +68 -0
- package/dist/commands/types.d.ts +9 -4
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/usage-command.d.ts.map +1 -1
- package/dist/commands/usage-command.js +22 -0
- package/dist/config.d.ts +6 -7
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +23 -29
- package/dist/formatting.d.ts +108 -0
- package/dist/formatting.d.ts.map +1 -1
- package/dist/formatting.js +147 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +140 -38
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +47 -18
- package/dist/mentions.d.ts +2 -1
- package/dist/mentions.d.ts.map +1 -1
- package/dist/mentions.js +16 -1
- package/dist/messages.d.ts +8 -0
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +56 -19
- package/dist/middleware/cache.d.ts +3 -0
- package/dist/middleware/cache.d.ts.map +1 -0
- package/dist/middleware/cache.js +53 -0
- package/dist/middleware/index.d.ts +1 -0
- package/dist/middleware/index.d.ts.map +1 -1
- package/dist/middleware/index.js +1 -0
- package/dist/models/ai-config.d.ts +4 -2
- package/dist/models/ai-config.d.ts.map +1 -1
- package/dist/models/ai-config.js +12 -2
- package/dist/models/anthropic-provider.d.ts.map +1 -1
- package/dist/models/anthropic-provider.js +3 -60
- package/dist/models/manager.d.ts +2 -1
- package/dist/models/manager.d.ts.map +1 -1
- package/dist/models/manager.js +26 -2
- package/dist/models/openrouter-provider.d.ts +7 -14
- package/dist/models/openrouter-provider.d.ts.map +1 -1
- package/dist/models/openrouter-provider.js +114 -169
- package/dist/models/providers.d.ts +1 -1
- package/dist/models/providers.d.ts.map +1 -1
- package/dist/prompts.d.ts +1 -0
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +53 -4
- package/dist/repl/display-tool-messages.d.ts +1 -1
- package/dist/repl/display-tool-messages.d.ts.map +1 -1
- package/dist/repl/display-tool-messages.js +47 -44
- package/dist/repl/get-prompt-header.d.ts.map +1 -1
- package/dist/repl/get-prompt-header.js +1 -30
- package/dist/repl/project-status-line.d.ts +2 -0
- package/dist/repl/project-status-line.d.ts.map +1 -0
- package/dist/repl/project-status-line.js +31 -0
- package/dist/repl/prompt.d.ts +21 -0
- package/dist/repl/prompt.d.ts.map +1 -0
- package/dist/{repl-prompt.js → repl/prompt.js} +119 -22
- package/dist/repl/tool-call-repair.d.ts.map +1 -1
- package/dist/repl/tool-call-repair.js +8 -4
- package/dist/repl-new.d.ts +53 -0
- package/dist/repl-new.d.ts.map +1 -0
- package/dist/repl-new.js +374 -0
- package/dist/repl.d.ts +3 -5
- package/dist/repl.d.ts.map +1 -1
- package/dist/repl.js +74 -166
- package/dist/terminal/checkbox-prompt.d.ts.map +1 -1
- package/dist/terminal/checkbox-prompt.js +10 -4
- package/dist/terminal/index.d.ts +7 -0
- package/dist/terminal/index.d.ts.map +1 -1
- package/dist/terminal/index.js +94 -0
- package/dist/terminal/input-prompt.d.ts +2 -1
- package/dist/terminal/input-prompt.d.ts.map +1 -1
- package/dist/terminal/markdown.js +3 -0
- package/dist/terminal/search-prompt.d.ts.map +1 -1
- package/dist/terminal/search-prompt.js +11 -10
- package/dist/terminal/select-prompt.d.ts +2 -2
- package/dist/terminal/select-prompt.d.ts.map +1 -1
- package/dist/terminal/select-prompt.js +47 -39
- package/dist/tokens/threshold.d.ts +35 -0
- package/dist/tokens/threshold.d.ts.map +1 -0
- package/dist/tokens/threshold.js +85 -0
- package/dist/tools/advanced-edit-file.d.ts +69 -0
- package/dist/tools/advanced-edit-file.d.ts.map +1 -0
- package/dist/tools/advanced-edit-file.js +281 -0
- package/dist/tools/agent.d.ts +16 -5
- package/dist/tools/agent.d.ts.map +1 -1
- package/dist/tools/agent.js +71 -58
- package/dist/tools/bash-utils.d.ts +1 -1
- package/dist/tools/bash-utils.d.ts.map +1 -1
- package/dist/tools/bash-utils.js +14 -6
- package/dist/tools/bash.d.ts +21 -12
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +88 -135
- package/dist/tools/code-interpreter.d.ts +21 -9
- package/dist/tools/code-interpreter.d.ts.map +1 -1
- package/dist/tools/code-interpreter.js +138 -137
- package/dist/tools/delete-file.d.ts +17 -10
- package/dist/tools/delete-file.d.ts.map +1 -1
- package/dist/tools/delete-file.js +51 -95
- package/dist/tools/directory-tree.d.ts +17 -6
- package/dist/tools/directory-tree.d.ts.map +1 -1
- package/dist/tools/directory-tree.js +47 -49
- package/dist/tools/dynamic-tool-loader.d.ts +18 -8
- package/dist/tools/dynamic-tool-loader.d.ts.map +1 -1
- package/dist/tools/dynamic-tool-loader.js +121 -129
- package/dist/tools/dynamic-tool-parser.d.ts +1 -0
- package/dist/tools/dynamic-tool-parser.d.ts.map +1 -1
- package/dist/tools/dynamic-tool-parser.js +1 -0
- package/dist/tools/edit-file.d.ts +35 -15
- package/dist/tools/edit-file.d.ts.map +1 -1
- package/dist/tools/edit-file.js +112 -112
- package/dist/tools/filesystem-utils.d.ts +2 -1
- package/dist/tools/filesystem-utils.d.ts.map +1 -1
- package/dist/tools/filesystem-utils.js +31 -17
- package/dist/tools/glob.d.ts +36 -0
- package/dist/tools/glob.d.ts.map +1 -0
- package/dist/tools/glob.js +143 -0
- package/dist/tools/grep.d.ts +73 -12
- package/dist/tools/grep.d.ts.map +1 -1
- package/dist/tools/grep.js +413 -168
- package/dist/tools/index.d.ts +204 -124
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +242 -135
- package/dist/tools/llm-edit-fixer.d.ts +25 -0
- package/dist/tools/llm-edit-fixer.d.ts.map +1 -0
- package/dist/tools/llm-edit-fixer.js +150 -0
- package/dist/tools/move-file.d.ts +19 -7
- package/dist/tools/move-file.d.ts.map +1 -1
- package/dist/tools/move-file.js +40 -33
- package/dist/tools/read-file.d.ts +47 -9
- package/dist/tools/read-file.d.ts.map +1 -1
- package/dist/tools/read-file.js +74 -69
- package/dist/tools/read-multiple-files.d.ts +17 -6
- package/dist/tools/read-multiple-files.d.ts.map +1 -1
- package/dist/tools/read-multiple-files.js +76 -73
- package/dist/tools/save-file.d.ts +45 -12
- package/dist/tools/save-file.d.ts.map +1 -1
- package/dist/tools/save-file.js +58 -101
- package/dist/tools/think.d.ts +15 -7
- package/dist/tools/think.d.ts.map +1 -1
- package/dist/tools/think.js +30 -22
- package/dist/tools/types.d.ts +4 -10
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/types.js +9 -0
- package/dist/tools/utils.d.ts +14 -0
- package/dist/tools/utils.d.ts.map +1 -0
- package/dist/tools/utils.js +16 -0
- package/dist/tools/web-fetch.d.ts +11 -4
- package/dist/tools/web-fetch.d.ts.map +1 -1
- package/dist/tools/web-fetch.js +39 -38
- package/dist/tools/web-search.d.ts +15 -6
- package/dist/tools/web-search.d.ts.map +1 -1
- package/dist/tools/web-search.js +50 -32
- package/dist/tui/autocomplete.d.ts +44 -0
- package/dist/tui/autocomplete.d.ts.map +1 -0
- package/dist/tui/autocomplete.js +466 -0
- package/dist/tui/components/assistant-message.d.ts +18 -0
- package/dist/tui/components/assistant-message.d.ts.map +1 -0
- package/dist/tui/components/assistant-message.js +29 -0
- package/dist/tui/components/editor.d.ts +51 -0
- package/dist/tui/components/editor.d.ts.map +1 -0
- package/dist/tui/components/editor.js +758 -0
- package/dist/tui/components/footer.d.ts +24 -0
- package/dist/tui/components/footer.d.ts.map +1 -0
- package/dist/tui/components/footer.js +197 -0
- package/dist/tui/components/input.d.ts +14 -0
- package/dist/tui/components/input.d.ts.map +1 -0
- package/dist/tui/components/input.js +122 -0
- package/dist/tui/components/loader.d.ts +19 -0
- package/dist/tui/components/loader.d.ts.map +1 -0
- package/dist/tui/components/loader.js +45 -0
- package/dist/tui/components/markdown.d.ts +103 -0
- package/dist/tui/components/markdown.d.ts.map +1 -0
- package/dist/tui/components/markdown.js +533 -0
- package/dist/tui/components/modal.d.ts +40 -0
- package/dist/tui/components/modal.d.ts.map +1 -0
- package/dist/tui/components/modal.js +292 -0
- package/dist/tui/components/prompt-status.d.ts +16 -0
- package/dist/tui/components/prompt-status.d.ts.map +1 -0
- package/dist/tui/components/prompt-status.js +21 -0
- package/dist/tui/components/select-list.d.ts +22 -0
- package/dist/tui/components/select-list.d.ts.map +1 -0
- package/dist/tui/components/select-list.js +143 -0
- package/dist/tui/components/spacer.d.ts +16 -0
- package/dist/tui/components/spacer.d.ts.map +1 -0
- package/dist/tui/components/spacer.js +27 -0
- package/dist/tui/components/text.d.ts +26 -0
- package/dist/tui/components/text.d.ts.map +1 -0
- package/dist/tui/components/text.js +143 -0
- package/dist/tui/components/thinking-block.d.ts +14 -0
- package/dist/tui/components/thinking-block.d.ts.map +1 -0
- package/dist/tui/components/thinking-block.js +30 -0
- package/dist/tui/components/tool-execution.d.ts +17 -0
- package/dist/tui/components/tool-execution.d.ts.map +1 -0
- package/dist/tui/components/tool-execution.js +153 -0
- package/dist/tui/components/user-message.d.ts +9 -0
- package/dist/tui/components/user-message.d.ts.map +1 -0
- package/dist/tui/components/user-message.js +21 -0
- package/dist/tui/components/welcome.d.ts +6 -0
- package/dist/tui/components/welcome.d.ts.map +1 -0
- package/dist/tui/components/welcome.js +30 -0
- package/dist/tui/index.d.ts +14 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +18 -0
- package/dist/tui/terminal.d.ts +37 -0
- package/dist/tui/terminal.d.ts.map +1 -0
- package/dist/tui/terminal.js +104 -0
- package/dist/tui/tui.d.ts +67 -0
- package/dist/tui/tui.d.ts.map +1 -0
- package/dist/tui/tui.js +184 -0
- package/dist/tui/utils.d.ts +19 -0
- package/dist/tui/utils.d.ts.map +1 -0
- package/dist/tui/utils.js +31 -0
- package/dist/utils/generators.d.ts +3 -0
- package/dist/utils/generators.d.ts.map +1 -0
- package/dist/utils/generators.js +25 -0
- package/dist/utils/iterables.d.ts +2 -0
- package/dist/utils/iterables.d.ts.map +1 -0
- package/dist/utils/iterables.js +6 -0
- package/package.json +16 -16
- package/dist/conversation-analyzer.d.ts +0 -11
- package/dist/conversation-analyzer.d.ts.map +0 -1
- package/dist/conversation-analyzer.js +0 -88
- package/dist/repl-prompt.d.ts +0 -15
- package/dist/repl-prompt.d.ts.map +0 -1
- package/dist/tokens/manage-output.d.ts +0 -34
- package/dist/tokens/manage-output.d.ts.map +0 -1
- package/dist/tokens/manage-output.js +0 -44
- package/dist/tool-executor.d.ts +0 -28
- package/dist/tool-executor.d.ts.map +0 -1
- package/dist/tool-executor.js +0 -74
- package/dist/tools/file-editing-utils.d.ts +0 -2
- package/dist/tools/file-editing-utils.d.ts.map +0 -1
- package/dist/tools/file-editing-utils.js +0 -135
package/dist/tools/agent.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { generateText, stepCountIs
|
|
1
|
+
import { generateText, stepCountIs } from "ai";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { AiConfig } from "../models/ai-config.js";
|
|
4
4
|
import style from "../terminal/style.js";
|
|
5
|
-
import {
|
|
6
|
-
|
|
5
|
+
import { DirectoryTreeTool } from "./directory-tree.js";
|
|
6
|
+
import { GlobTool } from "./glob.js";
|
|
7
7
|
import { GrepTool } from "./grep.js";
|
|
8
8
|
import { initCliTools } from "./index.js";
|
|
9
9
|
import { ReadFileTool } from "./read-file.js";
|
|
@@ -13,18 +13,24 @@ export const AgentTool = {
|
|
|
13
13
|
};
|
|
14
14
|
const TOOLS = [
|
|
15
15
|
GrepTool.name,
|
|
16
|
-
|
|
16
|
+
GlobTool.name,
|
|
17
17
|
ReadFileTool.name,
|
|
18
18
|
ReadMultipleFilesTool.name,
|
|
19
|
-
|
|
19
|
+
DirectoryTreeTool.name,
|
|
20
20
|
];
|
|
21
21
|
function getToolDescription() {
|
|
22
22
|
const toolNames = TOOLS.join(", ");
|
|
23
|
-
return `Launch a new agent that has access to the following tools: ${toolNames}.
|
|
23
|
+
return `Launch a new agent that has access to the following tools: ${toolNames}. This agent is specifically designed for file discovery and code search tasks. Use the ${AgentTool.name} tool when you need to search for files or code patterns across the codebase.
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
25
|
+
Use cases:
|
|
26
|
+
- Search for files matching specific patterns (e.g., "*.ts", "**/*.test.ts") using ${GlobTool.name}
|
|
27
|
+
- Find code patterns or text within files using ${GrepTool.name}
|
|
28
|
+
- Read specific files or multiple files using ${ReadFileTool.name} and ${ReadMultipleFilesTool.name}
|
|
29
|
+
|
|
30
|
+
Important limitations:
|
|
31
|
+
- This agent cannot execute shell commands or run external tools
|
|
32
|
+
- It is focused purely on file discovery and content reading
|
|
33
|
+
- For complex operations or command execution, use the main assistant directly
|
|
28
34
|
|
|
29
35
|
Usage notes:
|
|
30
36
|
1. Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple tool uses
|
|
@@ -36,55 +42,62 @@ const inputSchema = z.object({
|
|
|
36
42
|
prompt: z.string().describe("The task for the agent to perform"),
|
|
37
43
|
});
|
|
38
44
|
export const createAgentTools = (options) => {
|
|
39
|
-
const { modelManager, tokenTracker, tokenCounter
|
|
45
|
+
const { modelManager, tokenTracker, tokenCounter } = options;
|
|
46
|
+
const toolDef = {
|
|
47
|
+
description: getToolDescription(),
|
|
48
|
+
inputSchema,
|
|
49
|
+
};
|
|
50
|
+
async function* execute({ prompt }, { toolCallId, abortSignal }) {
|
|
51
|
+
if (abortSignal?.aborted) {
|
|
52
|
+
throw new Error("Agent execution aborted");
|
|
53
|
+
}
|
|
54
|
+
yield {
|
|
55
|
+
name: AgentTool.name,
|
|
56
|
+
event: "tool-init",
|
|
57
|
+
id: toolCallId,
|
|
58
|
+
data: `\n${style.cyan(prompt)}`,
|
|
59
|
+
};
|
|
60
|
+
try {
|
|
61
|
+
const modelConfig = modelManager.getModelMetadata("task-agent");
|
|
62
|
+
const aiConfig = new AiConfig({
|
|
63
|
+
modelMetadata: modelConfig,
|
|
64
|
+
prompt: prompt,
|
|
65
|
+
});
|
|
66
|
+
const { text, usage } = await generateText({
|
|
67
|
+
model: modelManager.getModel("task-agent"),
|
|
68
|
+
maxOutputTokens: aiConfig.maxOutputTokens(),
|
|
69
|
+
system: "You are a code search assistant that will be given a task that will require you to search a code base to find relevant code and files.",
|
|
70
|
+
prompt: prompt,
|
|
71
|
+
temperature: aiConfig.temperature(),
|
|
72
|
+
topP: aiConfig.topP(),
|
|
73
|
+
stopWhen: stepCountIs(30),
|
|
74
|
+
providerOptions: aiConfig.providerOptions(),
|
|
75
|
+
tools: (await initCliTools({ tokenCounter, workspace: options.workspace })).toolDefs,
|
|
76
|
+
abortSignal: abortSignal,
|
|
77
|
+
// biome-ignore lint/style/useNamingConvention: third-party code
|
|
78
|
+
experimental_activeTools: [...TOOLS],
|
|
79
|
+
});
|
|
80
|
+
tokenTracker.trackUsage("task-agent", usage);
|
|
81
|
+
yield {
|
|
82
|
+
name: AgentTool.name,
|
|
83
|
+
event: "tool-completion",
|
|
84
|
+
id: toolCallId,
|
|
85
|
+
data: `Finished running the agent tool (${usage.totalTokens} tokens)`,
|
|
86
|
+
};
|
|
87
|
+
yield text;
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
yield {
|
|
91
|
+
name: AgentTool.name,
|
|
92
|
+
event: "tool-error",
|
|
93
|
+
id: toolCallId,
|
|
94
|
+
data: error.message,
|
|
95
|
+
};
|
|
96
|
+
yield error.message;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
40
99
|
return {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
inputSchema: inputSchema,
|
|
44
|
-
execute: async ({ prompt }, { abortSignal, toolCallId }) => {
|
|
45
|
-
if (abortSignal?.aborted) {
|
|
46
|
-
throw new Error("Agent execution aborted");
|
|
47
|
-
}
|
|
48
|
-
sendData?.({
|
|
49
|
-
event: "tool-init",
|
|
50
|
-
id: toolCallId,
|
|
51
|
-
data: `Initializing agent with prompt: ${style.cyan(prompt)}`,
|
|
52
|
-
});
|
|
53
|
-
try {
|
|
54
|
-
const modelConfig = modelManager.getModelMetadata("task-agent");
|
|
55
|
-
const aiConfig = new AiConfig({
|
|
56
|
-
modelMetadata: modelConfig,
|
|
57
|
-
prompt: prompt,
|
|
58
|
-
});
|
|
59
|
-
const { text, usage } = await generateText({
|
|
60
|
-
model: modelManager.getModel("task-agent"),
|
|
61
|
-
maxOutputTokens: aiConfig.getMaxTokens(),
|
|
62
|
-
system: "You are a code search assistant that will be given a task that will require you to search a code base to find relevant code and files.",
|
|
63
|
-
prompt: prompt,
|
|
64
|
-
stopWhen: stepCountIs(30),
|
|
65
|
-
providerOptions: aiConfig.getProviderOptions(),
|
|
66
|
-
tools: await initCliTools({ tokenCounter }),
|
|
67
|
-
abortSignal: abortSignal,
|
|
68
|
-
// biome-ignore lint/style/useNamingConvention: third-party code
|
|
69
|
-
experimental_activeTools: [...TOOLS],
|
|
70
|
-
});
|
|
71
|
-
tokenTracker.trackUsage("task-agent", usage);
|
|
72
|
-
sendData?.({
|
|
73
|
-
event: "tool-completion",
|
|
74
|
-
id: toolCallId,
|
|
75
|
-
data: "Finished running the agent tool.",
|
|
76
|
-
});
|
|
77
|
-
return text;
|
|
78
|
-
}
|
|
79
|
-
catch (error) {
|
|
80
|
-
sendData?.({
|
|
81
|
-
event: "tool-error",
|
|
82
|
-
id: toolCallId,
|
|
83
|
-
data: "Error running agent tool.",
|
|
84
|
-
});
|
|
85
|
-
return Promise.resolve(error.message);
|
|
86
|
-
}
|
|
87
|
-
},
|
|
88
|
-
}),
|
|
100
|
+
toolDef,
|
|
101
|
+
execute,
|
|
89
102
|
};
|
|
90
103
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bash-utils.d.ts","sourceRoot":"","sources":["../../source/tools/bash-utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bash-utils.d.ts","sourceRoot":"","sources":["../../source/tools/bash-utils.ts"],"names":[],"mappings":"AAMA,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EAAE,EACrB,GAAG,EAAE,MAAM,EACX,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAgFtC;AAED,eAAO,MAAM,UAAU,GACrB,UAAU,MAAM,GAAG,IAAI,GAAG,SAAS,EACnC,YAAY,MAAM,KACjB,MAiDF,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,YAAY,MAAM,KAAG,OAmHtD,CAAC"}
|
package/dist/tools/bash-utils.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
2
3
|
import path from "node:path";
|
|
3
|
-
import {
|
|
4
|
+
import { isPathWithinAllowedDirs } from "./filesystem-utils.js";
|
|
4
5
|
// Validate path arguments to ensure they're within the project
|
|
5
|
-
export function validatePaths(command,
|
|
6
|
+
export function validatePaths(command, allowedDirs, cwd, allowedPaths) {
|
|
6
7
|
// Simple tokenization - split on spaces but respect quotes
|
|
7
8
|
const tokens = [];
|
|
8
9
|
let current = "";
|
|
@@ -43,7 +44,7 @@ export function validatePaths(command, baseDir, cwd) {
|
|
|
43
44
|
// Skip if it's clearly not a path
|
|
44
45
|
if (cleanToken.startsWith("-") ||
|
|
45
46
|
cleanToken.includes("://") ||
|
|
46
|
-
!cleanToken.includes("/")) {
|
|
47
|
+
(!cleanToken.includes("/") && cleanToken !== "~")) {
|
|
47
48
|
continue;
|
|
48
49
|
}
|
|
49
50
|
// Skip git commit messages and other special cases
|
|
@@ -52,11 +53,18 @@ export function validatePaths(command, baseDir, cwd) {
|
|
|
52
53
|
continue;
|
|
53
54
|
}
|
|
54
55
|
try {
|
|
55
|
-
|
|
56
|
-
|
|
56
|
+
// Expand ~ to home directory for proper validation
|
|
57
|
+
const expandedToken = cleanToken.startsWith("~/") || cleanToken === "~"
|
|
58
|
+
? path.join(os.homedir(), cleanToken.slice(1))
|
|
59
|
+
: cleanToken;
|
|
60
|
+
const resolvedPath = path.resolve(cwd, expandedToken);
|
|
61
|
+
// Allow access to explicitly allowed paths
|
|
62
|
+
const isAllowedPath = allowedPaths?.some((allowedPath) => resolvedPath === path.resolve(allowedPath));
|
|
63
|
+
if (!isAllowedPath &&
|
|
64
|
+
!isPathWithinAllowedDirs(resolvedPath, allowedDirs)) {
|
|
57
65
|
return {
|
|
58
66
|
isValid: false,
|
|
59
|
-
error: `Path '${cleanToken}' resolves outside the
|
|
67
|
+
error: `Path '${cleanToken}' resolves outside the allowed directories (${resolvedPath}). All paths must be within ${allowedDirs.join(", ")}`,
|
|
60
68
|
};
|
|
61
69
|
}
|
|
62
70
|
}
|
package/dist/tools/bash.d.ts
CHANGED
|
@@ -1,21 +1,30 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ToolCallOptions } from "ai";
|
|
2
|
+
import { z } from "zod";
|
|
2
3
|
import type { TokenCounter } from "../tokens/counter.ts";
|
|
3
|
-
import type {
|
|
4
|
-
import type { SendData } from "./types.ts";
|
|
4
|
+
import type { ToolResult } from "./types.ts";
|
|
5
5
|
export declare const BashTool: {
|
|
6
6
|
name: "bash";
|
|
7
7
|
};
|
|
8
|
-
|
|
8
|
+
declare const inputSchema: z.ZodObject<{
|
|
9
|
+
command: z.ZodString;
|
|
10
|
+
cwd: z.ZodNullable<z.ZodString>;
|
|
11
|
+
timeout: z.ZodNullable<z.ZodCoercedNumber<unknown>>;
|
|
12
|
+
}, z.core.$strip>;
|
|
13
|
+
type BashInputSchema = z.infer<typeof inputSchema>;
|
|
14
|
+
export declare const createBashTool: ({ baseDir, allowedDirs, tokenCounter, }: {
|
|
9
15
|
baseDir: string;
|
|
10
|
-
|
|
16
|
+
allowedDirs?: string[];
|
|
11
17
|
tokenCounter: TokenCounter;
|
|
12
|
-
terminal?: Terminal;
|
|
13
|
-
toolExecutor?: ToolExecutor;
|
|
14
18
|
}) => Promise<{
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
toolDef: {
|
|
20
|
+
description: string;
|
|
21
|
+
inputSchema: z.ZodObject<{
|
|
22
|
+
command: z.ZodString;
|
|
23
|
+
cwd: z.ZodNullable<z.ZodString>;
|
|
24
|
+
timeout: z.ZodNullable<z.ZodCoercedNumber<unknown>>;
|
|
25
|
+
}, z.core.$strip>;
|
|
26
|
+
};
|
|
27
|
+
execute({ command, cwd, timeout }: BashInputSchema, { toolCallId, abortSignal }: ToolCallOptions): AsyncGenerator<ToolResult>;
|
|
20
28
|
}>;
|
|
29
|
+
export {};
|
|
21
30
|
//# sourceMappingURL=bash.d.ts.map
|
package/dist/tools/bash.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../source/tools/bash.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../source/tools/bash.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAC1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAIzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,eAAO,MAAM,QAAQ;;CAEpB,CAAC;AAKF,QAAA,MAAM,WAAW;;;;iBAcf,CAAC;AAEH,KAAK,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEnD,eAAO,MAAM,cAAc,GAAU,yCAIlC;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,YAAY,CAAC;CAC5B;;;;;;;;;uCAcgC,eAAe,+BACb,eAAe,GAC3C,cAAc,CAAC,UAAU,CAAC;EAyFhC,CAAC"}
|
package/dist/tools/bash.js
CHANGED
|
@@ -1,155 +1,108 @@
|
|
|
1
|
-
import { tool } from "ai";
|
|
2
1
|
import { z } from "zod";
|
|
3
2
|
import { config } from "../config.js";
|
|
4
3
|
import { initExecutionEnvironment } from "../execution/index.js";
|
|
5
4
|
import { logger } from "../logger.js";
|
|
6
5
|
import style from "../terminal/style.js";
|
|
6
|
+
import { manageTokenLimit } from "../tokens/threshold.js";
|
|
7
7
|
import { isMutatingCommand, resolveCwd, validatePaths } from "./bash-utils.js";
|
|
8
|
-
import {
|
|
8
|
+
import { isPathWithinAllowedDirs } from "./filesystem-utils.js";
|
|
9
9
|
export const BashTool = {
|
|
10
10
|
name: "bash",
|
|
11
11
|
};
|
|
12
12
|
// Command execution timeout in milliseconds
|
|
13
13
|
const DEFAULT_TIMEOUT = 1.5 * 60 * 1000; // 1.5 minutes
|
|
14
|
-
|
|
14
|
+
const inputSchema = z.object({
|
|
15
|
+
command: z.string().describe("Full CLI command to execute."),
|
|
16
|
+
cwd: z
|
|
17
|
+
.string()
|
|
18
|
+
.nullable()
|
|
19
|
+
.describe("Working directory file path (default: project root). Must be within the project directory."),
|
|
20
|
+
timeout: z.coerce
|
|
21
|
+
.number()
|
|
22
|
+
.nullable()
|
|
23
|
+
.describe(`Command execution timeout in milliseconds. Default: ${DEFAULT_TIMEOUT}ms`),
|
|
24
|
+
});
|
|
25
|
+
export const createBashTool = async ({ baseDir, allowedDirs, tokenCounter, }) => {
|
|
15
26
|
const execEnv = await initExecutionEnvironment();
|
|
27
|
+
const projectConfig = await config.readProjectConfig();
|
|
28
|
+
const allowedPaths = projectConfig.logs?.path
|
|
29
|
+
? [projectConfig.logs.path]
|
|
30
|
+
: [];
|
|
31
|
+
const allowedDirectories = allowedDirs ?? [baseDir];
|
|
16
32
|
return {
|
|
17
|
-
|
|
33
|
+
toolDef: {
|
|
18
34
|
description: "Execute commands in a shell. Commands execute only within the project directory. Always use absolute paths.",
|
|
19
|
-
inputSchema
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
});
|
|
44
|
-
if (!isPathWithinBaseDir(resolvedCwd, baseDir)) {
|
|
45
|
-
const errorMsg = `Working directory must be within the project directory: ${baseDir}`;
|
|
46
|
-
sendData?.({ event: "tool-error", id: toolCallId, data: errorMsg });
|
|
47
|
-
return errorMsg;
|
|
48
|
-
}
|
|
49
|
-
const pathValidation = validatePaths(command, baseDir, resolvedCwd);
|
|
50
|
-
if (!pathValidation.isValid) {
|
|
51
|
-
sendData?.({
|
|
52
|
-
event: "tool-error",
|
|
53
|
-
id: toolCallId,
|
|
54
|
-
data: pathValidation.error ?? "Unknown error.",
|
|
55
|
-
});
|
|
56
|
-
return pathValidation.error ?? "Unknown error.";
|
|
57
|
-
}
|
|
58
|
-
if (terminal) {
|
|
59
|
-
let userResponse;
|
|
60
|
-
// Prompt only for potentially mutating commands when a toolExecutor is present
|
|
61
|
-
if (toolExecutor && isMutatingCommand(command)) {
|
|
62
|
-
// Display if autoAccept is false
|
|
63
|
-
if (!toolExecutor.autoAccept(BashTool.name)) {
|
|
64
|
-
terminal.writeln(`\n${style.blue.bold("●")} Proposing to execute command: ${style.cyan(command)} in ${style.cyan(resolvedCwd)}`);
|
|
65
|
-
terminal.lineBreak();
|
|
66
|
-
}
|
|
67
|
-
const ctx = {
|
|
68
|
-
toolName: BashTool.name,
|
|
69
|
-
toolCallId,
|
|
70
|
-
message: "What would you like to do with this command execution?",
|
|
71
|
-
choices: {
|
|
72
|
-
accept: "Execute this command",
|
|
73
|
-
acceptAll: "Accept all future command executions (including this)",
|
|
74
|
-
reject: "Reject this command execution",
|
|
75
|
-
},
|
|
76
|
-
};
|
|
77
|
-
try {
|
|
78
|
-
userResponse = await toolExecutor.ask(ctx, { abortSignal });
|
|
79
|
-
}
|
|
80
|
-
catch (e) {
|
|
81
|
-
if (e.name === "AbortError") {
|
|
82
|
-
throw new Error("Command execution aborted during user input");
|
|
83
|
-
}
|
|
84
|
-
throw e;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
const { result: userChoice, reason } = userResponse ?? {
|
|
88
|
-
result: "accept",
|
|
89
|
-
};
|
|
90
|
-
terminal.lineBreak();
|
|
91
|
-
if (userChoice === "accept-all") {
|
|
92
|
-
terminal.writeln(style.yellow("✓ Auto-accept mode enabled for all command executions"));
|
|
93
|
-
terminal.lineBreak();
|
|
94
|
-
}
|
|
95
|
-
if (userChoice === "reject") {
|
|
96
|
-
terminal.lineBreak();
|
|
97
|
-
const rejectionReason = reason || "No reason provided";
|
|
98
|
-
sendData?.({
|
|
99
|
-
event: "tool-completion",
|
|
100
|
-
id: toolCallId,
|
|
101
|
-
data: `Command execution rejected by user. Reason: ${rejectionReason}`,
|
|
102
|
-
});
|
|
103
|
-
return `The user rejected this command execution. Reason: ${rejectionReason}`;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
if (abortSignal?.aborted) {
|
|
107
|
-
throw new Error("Command execution aborted before running the command");
|
|
108
|
-
}
|
|
109
|
-
terminal?.startProgress();
|
|
110
|
-
const { output, exitCode } = await execEnv.executeCommand(command, {
|
|
111
|
-
cwd: resolvedCwd,
|
|
112
|
-
timeout: safeTimeout,
|
|
113
|
-
abortSignal,
|
|
114
|
-
preserveOutputOnError: true,
|
|
115
|
-
captureStderr: true,
|
|
116
|
-
throwOnError: false,
|
|
117
|
-
});
|
|
118
|
-
sendData?.({
|
|
119
|
-
event: "tool-update",
|
|
35
|
+
inputSchema,
|
|
36
|
+
},
|
|
37
|
+
async *execute({ command, cwd, timeout }, { toolCallId, abortSignal }) {
|
|
38
|
+
try {
|
|
39
|
+
if (abortSignal?.aborted) {
|
|
40
|
+
throw new Error("Command execution aborted");
|
|
41
|
+
}
|
|
42
|
+
// grok doesn't follow my instructions
|
|
43
|
+
const safeCwd = cwd === "null" ? null : cwd;
|
|
44
|
+
const resolvedCwd = resolveCwd(safeCwd, baseDir);
|
|
45
|
+
const safeTimeout = timeout ?? DEFAULT_TIMEOUT;
|
|
46
|
+
// Safety warning for potentially mutating commands
|
|
47
|
+
const isMutating = isMutatingCommand(command);
|
|
48
|
+
yield {
|
|
49
|
+
name: BashTool.name,
|
|
50
|
+
event: "tool-init",
|
|
51
|
+
id: toolCallId,
|
|
52
|
+
data: `${style.cyan(command)}${isMutating ? " *" : ""}`,
|
|
53
|
+
};
|
|
54
|
+
if (!isPathWithinAllowedDirs(resolvedCwd, allowedDirectories)) {
|
|
55
|
+
const errorMsg = `Working directory must be within the allowed directories: ${allowedDirectories.join(", ")}`;
|
|
56
|
+
yield {
|
|
57
|
+
name: BashTool.name,
|
|
58
|
+
event: "tool-error",
|
|
120
59
|
id: toolCallId,
|
|
121
|
-
data:
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
console.info("Error calculating token count:", tokenError);
|
|
132
|
-
}
|
|
133
|
-
const maxTokens = (await config.readProjectConfig()).tools.maxTokens;
|
|
134
|
-
const maxTokenMessage = `Output of command (${tokenCount} tokens) exceeds maximum allowed tokens (${maxTokens}). Please adjust how you call the command to get back more specific results.`;
|
|
135
|
-
const finalResult = tokenCount <= maxTokens ? output : maxTokenMessage;
|
|
136
|
-
sendData?.({
|
|
137
|
-
event: "tool-completion",
|
|
60
|
+
data: errorMsg,
|
|
61
|
+
};
|
|
62
|
+
yield errorMsg;
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const pathValidation = validatePaths(command, allowedDirectories, resolvedCwd, allowedPaths);
|
|
66
|
+
if (!pathValidation.isValid) {
|
|
67
|
+
yield {
|
|
68
|
+
name: BashTool.name,
|
|
69
|
+
event: "tool-error",
|
|
138
70
|
id: toolCallId,
|
|
139
|
-
data:
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
terminal?.stopProgress();
|
|
144
|
-
return finalResult;
|
|
71
|
+
data: pathValidation.error ?? "Unknown error.",
|
|
72
|
+
};
|
|
73
|
+
yield pathValidation.error ?? "Unknown error.";
|
|
74
|
+
return;
|
|
145
75
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const errorMsg = `Command failed: ${error.message}`;
|
|
149
|
-
sendData?.({ event: "tool-error", id: toolCallId, data: errorMsg });
|
|
150
|
-
return errorMsg;
|
|
76
|
+
if (abortSignal?.aborted) {
|
|
77
|
+
throw new Error("Command execution aborted before running the command");
|
|
151
78
|
}
|
|
152
|
-
|
|
153
|
-
|
|
79
|
+
const { output, exitCode } = await execEnv.executeCommand(command, {
|
|
80
|
+
cwd: resolvedCwd,
|
|
81
|
+
timeout: safeTimeout,
|
|
82
|
+
abortSignal,
|
|
83
|
+
preserveOutputOnError: true,
|
|
84
|
+
captureStderr: true,
|
|
85
|
+
throwOnError: false,
|
|
86
|
+
});
|
|
87
|
+
const result = await manageTokenLimit(output, tokenCounter, "Bash", "Adjust command to return more specific results");
|
|
88
|
+
yield {
|
|
89
|
+
name: BashTool.name,
|
|
90
|
+
event: "tool-completion",
|
|
91
|
+
id: toolCallId,
|
|
92
|
+
data: `${exitCode} (${result.tokenCount} tokens)`,
|
|
93
|
+
};
|
|
94
|
+
yield result.content;
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
logger.error(error, "Bash Tool Error:");
|
|
98
|
+
yield {
|
|
99
|
+
name: BashTool.name,
|
|
100
|
+
event: "tool-error",
|
|
101
|
+
id: toolCallId,
|
|
102
|
+
data: error.message,
|
|
103
|
+
};
|
|
104
|
+
yield error.message;
|
|
105
|
+
}
|
|
106
|
+
},
|
|
154
107
|
};
|
|
155
108
|
};
|
|
@@ -1,13 +1,25 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ToolCallOptions } from "ai";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import type { TokenCounter } from "../tokens/counter.ts";
|
|
4
|
+
import type { ToolResult } from "./types.ts";
|
|
2
5
|
export declare const CodeInterpreterTool: {
|
|
3
6
|
name: "codeInterpreter";
|
|
4
7
|
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
declare const inputSchema: z.ZodObject<{
|
|
9
|
+
code: z.ZodString;
|
|
10
|
+
timeoutSeconds: z.ZodNullable<z.ZodNumber>;
|
|
11
|
+
}, z.core.$strip>;
|
|
12
|
+
export declare const createCodeInterpreterTool: ({ tokenCounter, }: {
|
|
13
|
+
tokenCounter: TokenCounter;
|
|
14
|
+
}) => Promise<{
|
|
15
|
+
toolDef: {
|
|
16
|
+
description: string;
|
|
17
|
+
inputSchema: z.ZodObject<{
|
|
18
|
+
code: z.ZodString;
|
|
19
|
+
timeoutSeconds: z.ZodNullable<z.ZodNumber>;
|
|
20
|
+
}, z.core.$strip>;
|
|
21
|
+
};
|
|
22
|
+
execute: ({ code, timeoutSeconds }: z.infer<typeof inputSchema>, { toolCallId, abortSignal }: ToolCallOptions) => AsyncGenerator<ToolResult>;
|
|
23
|
+
}>;
|
|
24
|
+
export {};
|
|
13
25
|
//# sourceMappingURL=code-interpreter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-interpreter.d.ts","sourceRoot":"","sources":["../../source/tools/code-interpreter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"code-interpreter.d.ts","sourceRoot":"","sources":["../../source/tools/code-interpreter.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAC1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,eAAO,MAAM,mBAAmB;;CAE/B,CAAC;AAmBF,QAAA,MAAM,WAAW;;;iBASf,CAAC;AAEH,eAAO,MAAM,yBAAyB,GAAU,mBAE7C;IACD,YAAY,EAAE,YAAY,CAAC;CAC5B;;;;;;;;wCAO6B,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,+BACxB,eAAe,KAC3C,cAAc,CAAC,UAAU,CAAC;EAqK9B,CAAC"}
|