@amical/aiagent-sdk 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/WebMemoryManager-Bk19j8i6.d.mts +26 -0
- package/dist/WebMemoryManager-DXxLUDBB.d.ts +26 -0
- package/dist/index.d.mts +1 -165
- package/dist/index.d.ts +1 -165
- package/dist/index.js +26 -1077
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +27 -1048
- package/dist/index.mjs.map +1 -1
- package/dist/runtime/nodeRuntime.d.mts +110 -0
- package/dist/runtime/nodeRuntime.d.ts +110 -0
- package/dist/runtime/nodeRuntime.js +1618 -0
- package/dist/runtime/nodeRuntime.js.map +1 -0
- package/dist/runtime/nodeRuntime.mjs +1577 -0
- package/dist/runtime/nodeRuntime.mjs.map +1 -0
- package/dist/runtime/webRuntime.d.mts +73 -0
- package/dist/runtime/webRuntime.d.ts +73 -0
- package/dist/runtime/webRuntime.js +1515 -0
- package/dist/runtime/webRuntime.js.map +1 -0
- package/dist/runtime/webRuntime.mjs +1494 -0
- package/dist/runtime/webRuntime.mjs.map +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,45 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var nanoid = require('nanoid');
|
|
4
|
-
var ai = require('ai');
|
|
5
|
-
var openai = require('@ai-sdk/openai');
|
|
6
|
-
var difyAiProvider = require('dify-ai-provider');
|
|
7
4
|
var matter = require('gray-matter');
|
|
8
|
-
var fs2 = require('fs/promises');
|
|
9
|
-
var path2 = require('path');
|
|
10
|
-
var os = require('os');
|
|
11
|
-
var child_process = require('child_process');
|
|
12
|
-
var util = require('util');
|
|
13
|
-
require('@modelcontextprotocol/sdk/client/index.js');
|
|
14
|
-
require('@modelcontextprotocol/sdk/client/stdio.js');
|
|
15
|
-
var memfs = require('memfs');
|
|
16
|
-
var path3 = require('path-browserify');
|
|
17
5
|
|
|
18
6
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
19
7
|
|
|
20
|
-
function _interopNamespace(e) {
|
|
21
|
-
if (e && e.__esModule) return e;
|
|
22
|
-
var n = Object.create(null);
|
|
23
|
-
if (e) {
|
|
24
|
-
Object.keys(e).forEach(function (k) {
|
|
25
|
-
if (k !== 'default') {
|
|
26
|
-
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
27
|
-
Object.defineProperty(n, k, d.get ? d : {
|
|
28
|
-
enumerable: true,
|
|
29
|
-
get: function () { return e[k]; }
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
n.default = e;
|
|
35
|
-
return Object.freeze(n);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
8
|
var matter__default = /*#__PURE__*/_interopDefault(matter);
|
|
39
|
-
var fs2__namespace = /*#__PURE__*/_interopNamespace(fs2);
|
|
40
|
-
var path2__namespace = /*#__PURE__*/_interopNamespace(path2);
|
|
41
|
-
var os__namespace = /*#__PURE__*/_interopNamespace(os);
|
|
42
|
-
var path3__default = /*#__PURE__*/_interopDefault(path3);
|
|
43
9
|
|
|
44
10
|
// src/shared/tools.ts
|
|
45
11
|
var AgentDefaultTool = /* @__PURE__ */ ((AgentDefaultTool2) => {
|
|
@@ -505,728 +471,6 @@ var toolParamNames = [
|
|
|
505
471
|
"start_line",
|
|
506
472
|
"end_line"
|
|
507
473
|
];
|
|
508
|
-
|
|
509
|
-
// src/prompt/NodePromptManager.ts
|
|
510
|
-
var NodePromptManager = class {
|
|
511
|
-
async getSystemPrompt(context) {
|
|
512
|
-
let prompt = `# Role
|
|
513
|
-
you are a highly skilled software engineer AI running in a Node.js/Desktop environment.
|
|
514
|
-
You have FULL access to the local file system and can execute arbitrary shell commands on the user's machine.
|
|
515
|
-
|
|
516
|
-
# Capabilities & Rules
|
|
517
|
-
1. **File System**: You can read, write, create, and delete files/directories anywhere accessible to the user process. Always use absolute paths or paths relative to the Current Working Directory.
|
|
518
|
-
2. **Terminal**: You can execute system commands (e.g., git, npm, python, file manipulation) directly.
|
|
519
|
-
3. **Context**: You are running on a real machine, meaning you have access to real environment variables, local servers (localhost), and local network.
|
|
520
|
-
4. **Destructive Actions**: Be extremely careful when executing commands that modify system state or delete files. Double-check paths and commands before execution.
|
|
521
|
-
5. **Step-by-step**: Use tools one at a time. Do not assume the outcome of any tool use. Each step must be informed by the previous step's result.
|
|
522
|
-
6. **Verification**: Always verify the result of your actions (e.g., run tests, compile code, list directories) before proceeding to the next step or completing the task.
|
|
523
|
-
7. **Communication**: Be concise and technical. Formulate your output strictly according to the tools' XML specification.
|
|
524
|
-
|
|
525
|
-
TOOL USE
|
|
526
|
-
|
|
527
|
-
You have access to a set of tools that are executed upon the user's approval. You can use one tool per message, and will receive the result of that tool use in the user's response. You use tools step-by-step to accomplish a given task, with each tool use informed by the result of the previous tool use.
|
|
528
|
-
|
|
529
|
-
# Tool Use Formatting
|
|
530
|
-
|
|
531
|
-
Tool use is formatted using XML-style tags. The tool name is enclosed in opening and closing tags, and each parameter is similarly enclosed within its own set of tags. Here's the structure:
|
|
532
|
-
|
|
533
|
-
<tool_name>
|
|
534
|
-
<parameter1_name>value1</parameter1_name>
|
|
535
|
-
<parameter2_name>value2</parameter2_name>
|
|
536
|
-
...
|
|
537
|
-
</tool_name>
|
|
538
|
-
|
|
539
|
-
For example:
|
|
540
|
-
|
|
541
|
-
<agent_read_file>
|
|
542
|
-
<path>src/main.js</path>
|
|
543
|
-
<task_progress>
|
|
544
|
-
Checklist here (optional)
|
|
545
|
-
</task_progress>
|
|
546
|
-
</agent_read_file>
|
|
547
|
-
|
|
548
|
-
Always adhere to this format for the tool use to ensure proper parsing and execution.
|
|
549
|
-
`;
|
|
550
|
-
const skillsPrompt = await this.getSkillsPrompt(context.skills);
|
|
551
|
-
if (skillsPrompt) {
|
|
552
|
-
prompt += `
|
|
553
|
-
${skillsPrompt}
|
|
554
|
-
`;
|
|
555
|
-
}
|
|
556
|
-
prompt += `
|
|
557
|
-
${this.getToolInstructions(context)}
|
|
558
|
-
`;
|
|
559
|
-
const envPrompt = this.getEnvironmentInfoPrompt(context);
|
|
560
|
-
if (envPrompt) {
|
|
561
|
-
prompt += `
|
|
562
|
-
${envPrompt}
|
|
563
|
-
`;
|
|
564
|
-
}
|
|
565
|
-
if (context.customInstructions) {
|
|
566
|
-
prompt += `
|
|
567
|
-
# User Custom Instructions
|
|
568
|
-
${context.customInstructions}
|
|
569
|
-
`;
|
|
570
|
-
}
|
|
571
|
-
return prompt;
|
|
572
|
-
}
|
|
573
|
-
getEnvironmentInfoPrompt(context) {
|
|
574
|
-
let environmentPrompt = `<environment_details>
|
|
575
|
-
# Environment Info
|
|
576
|
-
- **Current Working Directory**: \`${context.cwd}\`
|
|
577
|
-
- **Operating System**: \`${context.os}\`
|
|
578
|
-
`;
|
|
579
|
-
if (context.shell) {
|
|
580
|
-
environmentPrompt += `- **Current Shell**: \`${context.shell}\`
|
|
581
|
-
`;
|
|
582
|
-
}
|
|
583
|
-
return environmentPrompt + `
|
|
584
|
-
</environment_details>`;
|
|
585
|
-
}
|
|
586
|
-
async getSkillsPrompt(skills) {
|
|
587
|
-
if (!skills || skills.length === 0) return "";
|
|
588
|
-
try {
|
|
589
|
-
let prompt = `# Available Skills
|
|
590
|
-
`;
|
|
591
|
-
prompt += `You have access to the following skills. You can use the \`agent_load_skill\` tool to load any of them when needed.
|
|
592
|
-
`;
|
|
593
|
-
for (const skill of skills) {
|
|
594
|
-
if (skill && skill.name && skill.description) {
|
|
595
|
-
prompt += `- **${skill.name}**: ${skill.description}
|
|
596
|
-
`;
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
return prompt;
|
|
600
|
-
} catch (e) {
|
|
601
|
-
return "";
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
getToolInstructions(context) {
|
|
605
|
-
const allowDefaultTools = context.allowDefaultTools;
|
|
606
|
-
const customTools = context.customTools || [];
|
|
607
|
-
let useDefaultTools = [...defaultTools];
|
|
608
|
-
if (allowDefaultTools) {
|
|
609
|
-
useDefaultTools = defaultTools.filter((tool) => allowDefaultTools.includes(tool.name));
|
|
610
|
-
}
|
|
611
|
-
return `# Available Tools
|
|
612
|
-
You can use the following tools by formatting your output as XML blocks. Only use ONE tool per message, and ALWAYS wait for the user's response with the execution result before proceeding.
|
|
613
|
-
|
|
614
|
-
${[...useDefaultTools, ...customTools].map((tool) => {
|
|
615
|
-
return `### ${tool.name}
|
|
616
|
-
Description: ${tool.description}
|
|
617
|
-
Parameters:
|
|
618
|
-
${Object.entries(tool.params).map(([name, description]) => `- ${name}: ${description.replaceAll("${context.cwd}", context.cwd)}`).join("\n")}
|
|
619
|
-
- task_progress: (optional) A checklist showing task progress after this tool use is completed. The task_progress parameter must be included as a separate parameter inside of the parent tool call, it must be separate from other parameters such as content, arguments, etc. (See 'UPDATING TASK PROGRESS' section for more details)
|
|
620
|
-
Usage:
|
|
621
|
-
<${tool.name}>
|
|
622
|
-
${Object.entries(tool.params).map(([name, description]) => `<${name}>${description.replaceAll("${context.cwd}", context.cwd)}</${name}>`).join("\n")}
|
|
623
|
-
<task_progress>Checklist here (optional)</task_progress>
|
|
624
|
-
</${tool.name}>
|
|
625
|
-
`;
|
|
626
|
-
}).join("\n")}
|
|
627
|
-
|
|
628
|
-
# Tool Use Examples
|
|
629
|
-
${useDefaultTools.filter((item) => Boolean(item.example)).map((item) => item.example).join("\n")}}
|
|
630
|
-
|
|
631
|
-
# Tool Use Guidelines
|
|
632
|
-
|
|
633
|
-
1. In <thinking> tags, assess what information you already have and what information you need to proceed with the task.
|
|
634
|
-
2. Choose the most appropriate tool based on the task and the tool descriptions provided. Assess if you need additional information to proceed, and which of the available tools would be most effective for gathering this information. For example using the list_files tool is more effective than running a command like \`ls\` in the terminal. It's critical that you think about each available tool and use the one that best fits the current step in the task.
|
|
635
|
-
3. If multiple actions are needed, use one tool at a time per message to accomplish the task iteratively, with each tool use being informed by the result of the previous tool use. Do not assume the outcome of any tool use. Each step must be informed by the previous step's result.
|
|
636
|
-
4. Formulate your tool use using the XML format specified for each tool.
|
|
637
|
-
5. After each tool use, the user will respond with the result of that tool use. This result will provide you with the necessary information to continue your task or make further decisions. This response may include:
|
|
638
|
-
- Information about whether the tool succeeded or failed, along with any reasons for failure.
|
|
639
|
-
- Linter errors that may have arisen due to the changes you made, which you'll need to address.
|
|
640
|
-
- New terminal output in reaction to the changes, which you may need to consider or act upon.
|
|
641
|
-
- Any other relevant feedback or information related to the tool use.
|
|
642
|
-
6. ALWAYS wait for user confirmation after each tool use before proceeding. Never assume the success of a tool use without explicit confirmation of the result from the user.
|
|
643
|
-
|
|
644
|
-
It is crucial to proceed step-by-step, waiting for the user's message after each tool use before moving forward with the task. This approach allows you to:
|
|
645
|
-
1. Confirm the success of each step before proceeding.
|
|
646
|
-
2. Address any issues or errors that arise immediately.
|
|
647
|
-
3. Adapt your approach based on new information or unexpected results.
|
|
648
|
-
4. Ensure that each action builds correctly on the previous ones.
|
|
649
|
-
|
|
650
|
-
By waiting for and carefully considering the user's response after each tool use, you can react accordingly and make informed decisions about how to proceed with the task. This iterative process helps ensure the overall success and accuracy of your work.
|
|
651
|
-
|
|
652
|
-
====
|
|
653
|
-
|
|
654
|
-
UPDATING TASK PROGRESS
|
|
655
|
-
|
|
656
|
-
You can track and communicate your progress on the overall task using the task_progress parameter supported by every tool call. Using task_progress ensures you remain on task, and stay focused on completing the user's objective. This parameter can be used in any mode, and with any tool call.
|
|
657
|
-
|
|
658
|
-
- When switching from PLAN MODE to ACT MODE, you must create a comprehensive todo list for the task using the task_progress parameter
|
|
659
|
-
- Todo list updates should be done silently using the task_progress parameter - do not announce these updates to the user
|
|
660
|
-
- Use standard Markdown checklist format: "- [ ]" for incomplete items and "- [x]" for completed items
|
|
661
|
-
- Keep items focused on meaningful progress milestones rather than minor technical details. The checklist should not be so granular that minor implementation details clutter the progress tracking.
|
|
662
|
-
- For simple tasks, short checklists with even a single item are acceptable. For complex tasks, avoid making the checklist too long or verbose.
|
|
663
|
-
- If you are creating this checklist for the first time, and the tool use completes the first step in the checklist, make sure to mark it as completed in your task_progress parameter.
|
|
664
|
-
- Provide the whole checklist of steps you intend to complete in the task, and keep the checkboxes updated as you make progress. It's okay to rewrite this checklist as needed if it becomes invalid due to scope changes or new information.
|
|
665
|
-
- If a checklist is being used, be sure to update it any time a step has been completed.
|
|
666
|
-
- The system will automatically include todo list context in your prompts when appropriate - these reminders are important.
|
|
667
|
-
|
|
668
|
-
Example:
|
|
669
|
-
<agent_execute_command>
|
|
670
|
-
<command>npm install react</command>
|
|
671
|
-
<requires_approval>false</requires_approval>
|
|
672
|
-
<task_progress>
|
|
673
|
-
- [x] Set up project structure
|
|
674
|
-
- [x] Install dependencies
|
|
675
|
-
- [ ] Create components
|
|
676
|
-
- [ ] Test application
|
|
677
|
-
</task_progress>
|
|
678
|
-
</agent_execute_command>
|
|
679
|
-
|
|
680
|
-
====
|
|
681
|
-
|
|
682
|
-
EDITING FILES
|
|
683
|
-
|
|
684
|
-
You have access to two tools for working with files: **agent_write_to_file** and **agent_replace_in_file**. Understanding their roles and selecting the right one for the job will help ensure efficient and accurate modifications.
|
|
685
|
-
|
|
686
|
-
# agent_write_to_file
|
|
687
|
-
|
|
688
|
-
## Purpose
|
|
689
|
-
|
|
690
|
-
- Create a new file, or overwrite the entire contents of an existing file.
|
|
691
|
-
|
|
692
|
-
## When to Use
|
|
693
|
-
|
|
694
|
-
- Initial file creation, such as when scaffolding a new project.
|
|
695
|
-
- Overwriting large boilerplate files where you want to replace the entire content at once.
|
|
696
|
-
- When the complexity or number of changes would make agent_replace_in_file unwieldy or error-prone.
|
|
697
|
-
- When you need to completely restructure a file's content or change its fundamental organization.
|
|
698
|
-
|
|
699
|
-
## Important Considerations
|
|
700
|
-
|
|
701
|
-
- Using agent_write_to_file requires providing the file's complete final content.
|
|
702
|
-
- If you only need to make small changes to an existing file, consider using agent_replace_in_file instead to avoid unnecessarily rewriting the entire file.
|
|
703
|
-
- While agent_write_to_file should not be your default choice, don't hesitate to use it when the situation truly calls for it.
|
|
704
|
-
|
|
705
|
-
# agent_replace_in_file
|
|
706
|
-
|
|
707
|
-
## Purpose
|
|
708
|
-
|
|
709
|
-
- Make targeted edits to specific parts of an existing file without overwriting the entire file.
|
|
710
|
-
|
|
711
|
-
## When to Use
|
|
712
|
-
|
|
713
|
-
- Small, localized changes like updating a few lines, function implementations, changing variable names, modifying a section of text, etc.
|
|
714
|
-
- Targeted improvements where only specific portions of the file's content needs to be altered.
|
|
715
|
-
- Especially useful for long files where much of the file will remain unchanged.
|
|
716
|
-
|
|
717
|
-
## Advantages
|
|
718
|
-
|
|
719
|
-
- More efficient for minor edits, since you don't need to supply the entire file content.
|
|
720
|
-
- Reduces the chance of errors that can occur when overwriting large files.
|
|
721
|
-
|
|
722
|
-
# Choosing the Appropriate Tool
|
|
723
|
-
|
|
724
|
-
- **Default to agent_replace_in_file** for most changes. It's the safer, more precise option that minimizes potential issues.
|
|
725
|
-
- **Use agent_write_to_file** when:
|
|
726
|
-
- Creating new files
|
|
727
|
-
- The changes are so extensive that using agent_replace_in_file would be more complex or risky
|
|
728
|
-
- You need to completely reorganize or restructure a file
|
|
729
|
-
- The file is relatively small and the changes affect most of its content
|
|
730
|
-
- You're generating boilerplate or template files
|
|
731
|
-
|
|
732
|
-
# Auto-formatting Considerations
|
|
733
|
-
|
|
734
|
-
- After using either agent_write_to_file or agent_replace_in_file, the user's editor may automatically format the file
|
|
735
|
-
- This auto-formatting may modify the file contents, for example:
|
|
736
|
-
- Breaking single lines into multiple lines
|
|
737
|
-
- Adjusting indentation to match project style (e.g. 2 spaces vs 4 spaces vs tabs)
|
|
738
|
-
- Converting single quotes to double quotes (or vice versa based on project preferences)
|
|
739
|
-
- Organizing imports (e.g. sorting, grouping by type)
|
|
740
|
-
- Adding/removing trailing commas in objects and arrays
|
|
741
|
-
- Enforcing consistent brace style (e.g. same-line vs new-line)
|
|
742
|
-
- Standardizing semicolon usage (adding or removing based on style)
|
|
743
|
-
- The agent_write_to_file and agent_replace_in_file tool responses will include the final state of the file after any auto-formatting
|
|
744
|
-
- Use this final state as your reference point for any subsequent edits. This is ESPECIALLY important when crafting SEARCH blocks for replace_in_file which require the content to match what's in the file exactly.
|
|
745
|
-
|
|
746
|
-
# Workflow Tips
|
|
747
|
-
|
|
748
|
-
1. Before editing, assess the scope of your changes and decide which tool to use.
|
|
749
|
-
2. For targeted edits, apply agent_replace_in_file with carefully crafted SEARCH/REPLACE blocks. If you need multiple changes, you can stack multiple SEARCH/REPLACE blocks within a single agent_replace_in_file call.
|
|
750
|
-
3. IMPORTANT: When you determine that you need to make several changes to the same file, prefer to use a single replace_in_file call with multiple SEARCH/REPLACE blocks. DO NOT prefer to make multiple successive replace_in_file calls for the same file. For example, if you were to add a component to a file, you would use a single replace_in_file call with a SEARCH/REPLACE block to add the import statement and another SEARCH/REPLACE block to add the component usage, rather than making one replace_in_file call for the import statement and then another separate replace_in_file call for the component usage.
|
|
751
|
-
4. For major overhauls or initial file creation, rely on agent_write_to_file.
|
|
752
|
-
5. Once the file has been edited with either agent_write_to_file or agent_replace_in_file, the system will provide you with the final state of the modified file. Use this updated content as the reference point for any subsequent SEARCH/REPLACE operations, since it reflects any auto-formatting or user-applied changes.
|
|
753
|
-
By thoughtfully selecting between agent_write_to_file and agent_replace_in_file, you can make your file editing process smoother, safer, and more efficient.
|
|
754
|
-
|
|
755
|
-
====
|
|
756
|
-
`;
|
|
757
|
-
}
|
|
758
|
-
getNoUseToolInstructions(context) {
|
|
759
|
-
return `[ERROR] You did not use a tool in your previous response! Please retry with a tool use.
|
|
760
|
-
|
|
761
|
-
# Reminder: Instructions for Tool Use
|
|
762
|
-
Tool uses are formatted using XML-style tags. The tool name is enclosed in opening and closing tags, and each parameter is similarly enclosed within its own set of tags. Here's the structure:
|
|
763
|
-
<tool_name>
|
|
764
|
-
<parameter1_name>value1</parameter1_name>
|
|
765
|
-
<parameter2_name>value2</parameter2_name>
|
|
766
|
-
...
|
|
767
|
-
</tool_name>
|
|
768
|
-
For example:
|
|
769
|
-
<agent_attempt_completion>
|
|
770
|
-
<result>
|
|
771
|
-
I have completed the task...
|
|
772
|
-
</result>
|
|
773
|
-
</agent_attempt_completion>
|
|
774
|
-
Always adhere to this format for all tool uses to ensure proper parsing and execution.
|
|
775
|
-
|
|
776
|
-
# Next Steps
|
|
777
|
-
|
|
778
|
-
If you have completed the user's task, use the attempt_completion tool.
|
|
779
|
-
If you require additional information from the user, use the ask_followup_question tool.
|
|
780
|
-
Otherwise, if you have not completed the task and do not need additional information, then proceed with the next step of the task.
|
|
781
|
-
(This is an automated message, so do not respond to it conversationally.)
|
|
782
|
-
${this?.getEnvironmentInfoPrompt?.(context)}`;
|
|
783
|
-
}
|
|
784
|
-
};
|
|
785
|
-
|
|
786
|
-
// src/prompt/WebPromptManager.ts
|
|
787
|
-
var WebPromptManager = class {
|
|
788
|
-
async getSystemPrompt(context) {
|
|
789
|
-
let prompt = `# Role
|
|
790
|
-
you are a highly skilled software engineer AI running in a Node.js/Desktop environment.
|
|
791
|
-
You have FULL access to the local file system and can execute arbitrary shell commands on the user's machine.
|
|
792
|
-
|
|
793
|
-
# Capabilities & Rules
|
|
794
|
-
1. **File System**: You can read, write, create, and delete files/directories anywhere accessible to the user process. Always use absolute paths or paths relative to the Current Working Directory.
|
|
795
|
-
2. **Terminal**: You can execute system commands (e.g., git, npm, python, file manipulation) directly.
|
|
796
|
-
3. **Context**: You are running on a real machine, meaning you have access to real environment variables, local servers (localhost), and local network.
|
|
797
|
-
4. **Destructive Actions**: Be extremely careful when executing commands that modify system state or delete files. Double-check paths and commands before execution.
|
|
798
|
-
5. **Step-by-step**: Use tools one at a time. Do not assume the outcome of any tool use. Each step must be informed by the previous step's result.
|
|
799
|
-
6. **Verification**: Always verify the result of your actions (e.g., run tests, compile code, list directories) before proceeding to the next step or completing the task.
|
|
800
|
-
7. **Communication**: Be concise and technical. Formulate your output strictly according to the tools' XML specification.
|
|
801
|
-
|
|
802
|
-
TOOL USE
|
|
803
|
-
|
|
804
|
-
You have access to a set of tools that are executed upon the user's approval. You can use one tool per message, and will receive the result of that tool use in the user's response. You use tools step-by-step to accomplish a given task, with each tool use informed by the result of the previous tool use.
|
|
805
|
-
|
|
806
|
-
# Tool Use Formatting
|
|
807
|
-
|
|
808
|
-
Tool use is formatted using XML-style tags. The tool name is enclosed in opening and closing tags, and each parameter is similarly enclosed within its own set of tags. Here's the structure:
|
|
809
|
-
|
|
810
|
-
<tool_name>
|
|
811
|
-
<parameter1_name>value1</parameter1_name>
|
|
812
|
-
<parameter2_name>value2</parameter2_name>
|
|
813
|
-
...
|
|
814
|
-
</tool_name>
|
|
815
|
-
|
|
816
|
-
For example:
|
|
817
|
-
|
|
818
|
-
<agent_read_file>
|
|
819
|
-
<path>src/main.js</path>
|
|
820
|
-
<task_progress>
|
|
821
|
-
Checklist here (optional)
|
|
822
|
-
</task_progress>
|
|
823
|
-
</agent_read_file>
|
|
824
|
-
|
|
825
|
-
Always adhere to this format for the tool use to ensure proper parsing and execution.
|
|
826
|
-
`;
|
|
827
|
-
const skillsPrompt = await this.getSkillsPrompt(context.skills);
|
|
828
|
-
if (skillsPrompt) {
|
|
829
|
-
prompt += `
|
|
830
|
-
${skillsPrompt}
|
|
831
|
-
`;
|
|
832
|
-
}
|
|
833
|
-
prompt += `
|
|
834
|
-
${this.getToolInstructions(context)}
|
|
835
|
-
`;
|
|
836
|
-
const envPrompt = this.getEnvironmentInfoPrompt(context);
|
|
837
|
-
if (envPrompt) {
|
|
838
|
-
prompt += `
|
|
839
|
-
${envPrompt}
|
|
840
|
-
`;
|
|
841
|
-
}
|
|
842
|
-
if (context.customInstructions) {
|
|
843
|
-
prompt += `
|
|
844
|
-
# User Custom Instructions
|
|
845
|
-
${context.customInstructions}
|
|
846
|
-
`;
|
|
847
|
-
}
|
|
848
|
-
return prompt;
|
|
849
|
-
}
|
|
850
|
-
getEnvironmentInfoPrompt(context) {
|
|
851
|
-
let environmentPrompt = `<environment_details>
|
|
852
|
-
# Environment Info
|
|
853
|
-
- **Current Working Directory**: \`${context.cwd}\`
|
|
854
|
-
- **Operating System**: \`${context.os}\`
|
|
855
|
-
`;
|
|
856
|
-
if (context.shell) {
|
|
857
|
-
environmentPrompt += `- **Current Shell**: \`${context.shell}\`
|
|
858
|
-
`;
|
|
859
|
-
}
|
|
860
|
-
return environmentPrompt + `
|
|
861
|
-
</environment_details>`;
|
|
862
|
-
}
|
|
863
|
-
async getSkillsPrompt(skills) {
|
|
864
|
-
if (!skills || skills.length === 0) return "";
|
|
865
|
-
try {
|
|
866
|
-
let prompt = `# Available Skills
|
|
867
|
-
`;
|
|
868
|
-
prompt += `You have access to the following skills. You can use the \`agent_load_skill\` tool to load any of them when needed.
|
|
869
|
-
`;
|
|
870
|
-
for (const skill of skills) {
|
|
871
|
-
if (skill && skill.name && skill.description) {
|
|
872
|
-
prompt += `- **${skill.name}**: ${skill.description}
|
|
873
|
-
`;
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
return prompt;
|
|
877
|
-
} catch (e) {
|
|
878
|
-
return "";
|
|
879
|
-
}
|
|
880
|
-
}
|
|
881
|
-
getToolInstructions(context) {
|
|
882
|
-
const allowDefaultTools = context.allowDefaultTools;
|
|
883
|
-
const customTools = context.customTools || [];
|
|
884
|
-
let useDefaultTools = [...defaultTools];
|
|
885
|
-
if (allowDefaultTools) {
|
|
886
|
-
useDefaultTools = defaultTools.filter((tool) => allowDefaultTools.includes(tool.name));
|
|
887
|
-
}
|
|
888
|
-
return `# Available Tools
|
|
889
|
-
You can use the following tools by formatting your output as XML blocks. Only use ONE tool per message, and ALWAYS wait for the user's response with the execution result before proceeding.
|
|
890
|
-
|
|
891
|
-
${[...useDefaultTools, ...customTools].map((tool) => {
|
|
892
|
-
return `### ${tool.name}
|
|
893
|
-
Description: ${tool.description}
|
|
894
|
-
Parameters:
|
|
895
|
-
${Object.entries(tool.params).map(([name, description]) => `- ${name}: ${description.replaceAll("${context.cwd}", context.cwd)}`).join("\n")}
|
|
896
|
-
- task_progress: (optional) A checklist showing task progress after this tool use is completed. The task_progress parameter must be included as a separate parameter inside of the parent tool call, it must be separate from other parameters such as content, arguments, etc. (See 'UPDATING TASK PROGRESS' section for more details)
|
|
897
|
-
Usage:
|
|
898
|
-
<${tool.name}>
|
|
899
|
-
${Object.entries(tool.params).map(([name, description]) => `<${name}>${description.replaceAll("${context.cwd}", context.cwd)}</${name}>`).join("\n")}
|
|
900
|
-
<task_progress>Checklist here (optional)</task_progress>
|
|
901
|
-
</${tool.name}>
|
|
902
|
-
`;
|
|
903
|
-
}).join("\n")}
|
|
904
|
-
|
|
905
|
-
# Tool Use Examples
|
|
906
|
-
${useDefaultTools.filter((item) => Boolean(item.example)).map((item) => item.example).join("\n")}}
|
|
907
|
-
|
|
908
|
-
# Tool Use Guidelines
|
|
909
|
-
|
|
910
|
-
1. In <thinking> tags, assess what information you already have and what information you need to proceed with the task.
|
|
911
|
-
2. Choose the most appropriate tool based on the task and the tool descriptions provided. Assess if you need additional information to proceed, and which of the available tools would be most effective for gathering this information. For example using the list_files tool is more effective than running a command like \`ls\` in the terminal. It's critical that you think about each available tool and use the one that best fits the current step in the task.
|
|
912
|
-
3. If multiple actions are needed, use one tool at a time per message to accomplish the task iteratively, with each tool use being informed by the result of the previous tool use. Do not assume the outcome of any tool use. Each step must be informed by the previous step's result.
|
|
913
|
-
4. Formulate your tool use using the XML format specified for each tool.
|
|
914
|
-
5. After each tool use, the user will respond with the result of that tool use. This result will provide you with the necessary information to continue your task or make further decisions. This response may include:
|
|
915
|
-
- Information about whether the tool succeeded or failed, along with any reasons for failure.
|
|
916
|
-
- Linter errors that may have arisen due to the changes you made, which you'll need to address.
|
|
917
|
-
- New terminal output in reaction to the changes, which you may need to consider or act upon.
|
|
918
|
-
- Any other relevant feedback or information related to the tool use.
|
|
919
|
-
6. ALWAYS wait for user confirmation after each tool use before proceeding. Never assume the success of a tool use without explicit confirmation of the result from the user.
|
|
920
|
-
|
|
921
|
-
It is crucial to proceed step-by-step, waiting for the user's message after each tool use before moving forward with the task. This approach allows you to:
|
|
922
|
-
1. Confirm the success of each step before proceeding.
|
|
923
|
-
2. Address any issues or errors that arise immediately.
|
|
924
|
-
3. Adapt your approach based on new information or unexpected results.
|
|
925
|
-
4. Ensure that each action builds correctly on the previous ones.
|
|
926
|
-
|
|
927
|
-
By waiting for and carefully considering the user's response after each tool use, you can react accordingly and make informed decisions about how to proceed with the task. This iterative process helps ensure the overall success and accuracy of your work.
|
|
928
|
-
|
|
929
|
-
====
|
|
930
|
-
|
|
931
|
-
UPDATING TASK PROGRESS
|
|
932
|
-
|
|
933
|
-
You can track and communicate your progress on the overall task using the task_progress parameter supported by every tool call. Using task_progress ensures you remain on task, and stay focused on completing the user's objective. This parameter can be used in any mode, and with any tool call.
|
|
934
|
-
|
|
935
|
-
- When switching from PLAN MODE to ACT MODE, you must create a comprehensive todo list for the task using the task_progress parameter
|
|
936
|
-
- Todo list updates should be done silently using the task_progress parameter - do not announce these updates to the user
|
|
937
|
-
- Use standard Markdown checklist format: "- [ ]" for incomplete items and "- [x]" for completed items
|
|
938
|
-
- Keep items focused on meaningful progress milestones rather than minor technical details. The checklist should not be so granular that minor implementation details clutter the progress tracking.
|
|
939
|
-
- For simple tasks, short checklists with even a single item are acceptable. For complex tasks, avoid making the checklist too long or verbose.
|
|
940
|
-
- If you are creating this checklist for the first time, and the tool use completes the first step in the checklist, make sure to mark it as completed in your task_progress parameter.
|
|
941
|
-
- Provide the whole checklist of steps you intend to complete in the task, and keep the checkboxes updated as you make progress. It's okay to rewrite this checklist as needed if it becomes invalid due to scope changes or new information.
|
|
942
|
-
- If a checklist is being used, be sure to update it any time a step has been completed.
|
|
943
|
-
- The system will automatically include todo list context in your prompts when appropriate - these reminders are important.
|
|
944
|
-
|
|
945
|
-
Example:
|
|
946
|
-
<agent_execute_command>
|
|
947
|
-
<command>npm install react</command>
|
|
948
|
-
<requires_approval>false</requires_approval>
|
|
949
|
-
<task_progress>
|
|
950
|
-
- [x] Set up project structure
|
|
951
|
-
- [x] Install dependencies
|
|
952
|
-
- [ ] Create components
|
|
953
|
-
- [ ] Test application
|
|
954
|
-
</task_progress>
|
|
955
|
-
</agent_execute_command>
|
|
956
|
-
|
|
957
|
-
====
|
|
958
|
-
|
|
959
|
-
EDITING FILES
|
|
960
|
-
|
|
961
|
-
You have access to two tools for working with files: **agent_write_to_file** and **agent_replace_in_file**. Understanding their roles and selecting the right one for the job will help ensure efficient and accurate modifications.
|
|
962
|
-
|
|
963
|
-
# agent_write_to_file
|
|
964
|
-
|
|
965
|
-
## Purpose
|
|
966
|
-
|
|
967
|
-
- Create a new file, or overwrite the entire contents of an existing file.
|
|
968
|
-
|
|
969
|
-
## When to Use
|
|
970
|
-
|
|
971
|
-
- Initial file creation, such as when scaffolding a new project.
|
|
972
|
-
- Overwriting large boilerplate files where you want to replace the entire content at once.
|
|
973
|
-
- When the complexity or number of changes would make agent_replace_in_file unwieldy or error-prone.
|
|
974
|
-
- When you need to completely restructure a file's content or change its fundamental organization.
|
|
975
|
-
|
|
976
|
-
## Important Considerations
|
|
977
|
-
|
|
978
|
-
- Using agent_write_to_file requires providing the file's complete final content.
|
|
979
|
-
- If you only need to make small changes to an existing file, consider using agent_replace_in_file instead to avoid unnecessarily rewriting the entire file.
|
|
980
|
-
- While agent_write_to_file should not be your default choice, don't hesitate to use it when the situation truly calls for it.
|
|
981
|
-
|
|
982
|
-
# agent_replace_in_file
|
|
983
|
-
|
|
984
|
-
## Purpose
|
|
985
|
-
|
|
986
|
-
- Make targeted edits to specific parts of an existing file without overwriting the entire file.
|
|
987
|
-
|
|
988
|
-
## When to Use
|
|
989
|
-
|
|
990
|
-
- Small, localized changes like updating a few lines, function implementations, changing variable names, modifying a section of text, etc.
|
|
991
|
-
- Targeted improvements where only specific portions of the file's content needs to be altered.
|
|
992
|
-
- Especially useful for long files where much of the file will remain unchanged.
|
|
993
|
-
|
|
994
|
-
## Advantages
|
|
995
|
-
|
|
996
|
-
- More efficient for minor edits, since you don't need to supply the entire file content.
|
|
997
|
-
- Reduces the chance of errors that can occur when overwriting large files.
|
|
998
|
-
|
|
999
|
-
# Choosing the Appropriate Tool
|
|
1000
|
-
|
|
1001
|
-
- **Default to agent_replace_in_file** for most changes. It's the safer, more precise option that minimizes potential issues.
|
|
1002
|
-
- **Use agent_write_to_file** when:
|
|
1003
|
-
- Creating new files
|
|
1004
|
-
- The changes are so extensive that using agent_replace_in_file would be more complex or risky
|
|
1005
|
-
- You need to completely reorganize or restructure a file
|
|
1006
|
-
- The file is relatively small and the changes affect most of its content
|
|
1007
|
-
- You're generating boilerplate or template files
|
|
1008
|
-
|
|
1009
|
-
# Auto-formatting Considerations
|
|
1010
|
-
|
|
1011
|
-
- After using either agent_write_to_file or agent_replace_in_file, the user's editor may automatically format the file
|
|
1012
|
-
- This auto-formatting may modify the file contents, for example:
|
|
1013
|
-
- Breaking single lines into multiple lines
|
|
1014
|
-
- Adjusting indentation to match project style (e.g. 2 spaces vs 4 spaces vs tabs)
|
|
1015
|
-
- Converting single quotes to double quotes (or vice versa based on project preferences)
|
|
1016
|
-
- Organizing imports (e.g. sorting, grouping by type)
|
|
1017
|
-
- Adding/removing trailing commas in objects and arrays
|
|
1018
|
-
- Enforcing consistent brace style (e.g. same-line vs new-line)
|
|
1019
|
-
- Standardizing semicolon usage (adding or removing based on style)
|
|
1020
|
-
- The agent_write_to_file and agent_replace_in_file tool responses will include the final state of the file after any auto-formatting
|
|
1021
|
-
- Use this final state as your reference point for any subsequent edits. This is ESPECIALLY important when crafting SEARCH blocks for replace_in_file which require the content to match what's in the file exactly.
|
|
1022
|
-
|
|
1023
|
-
# Workflow Tips
|
|
1024
|
-
|
|
1025
|
-
1. Before editing, assess the scope of your changes and decide which tool to use.
|
|
1026
|
-
2. For targeted edits, apply agent_replace_in_file with carefully crafted SEARCH/REPLACE blocks. If you need multiple changes, you can stack multiple SEARCH/REPLACE blocks within a single agent_replace_in_file call.
|
|
1027
|
-
3. IMPORTANT: When you determine that you need to make several changes to the same file, prefer to use a single replace_in_file call with multiple SEARCH/REPLACE blocks. DO NOT prefer to make multiple successive replace_in_file calls for the same file. For example, if you were to add a component to a file, you would use a single replace_in_file call with a SEARCH/REPLACE block to add the import statement and another SEARCH/REPLACE block to add the component usage, rather than making one replace_in_file call for the import statement and then another separate replace_in_file call for the component usage.
|
|
1028
|
-
4. For major overhauls or initial file creation, rely on agent_write_to_file.
|
|
1029
|
-
5. Once the file has been edited with either agent_write_to_file or agent_replace_in_file, the system will provide you with the final state of the modified file. Use this updated content as the reference point for any subsequent SEARCH/REPLACE operations, since it reflects any auto-formatting or user-applied changes.
|
|
1030
|
-
By thoughtfully selecting between agent_write_to_file and agent_replace_in_file, you can make your file editing process smoother, safer, and more efficient.
|
|
1031
|
-
|
|
1032
|
-
====
|
|
1033
|
-
`;
|
|
1034
|
-
}
|
|
1035
|
-
getNoUseToolInstructions(context) {
|
|
1036
|
-
return `[ERROR] You did not use a tool in your previous response! Please retry with a tool use.
|
|
1037
|
-
|
|
1038
|
-
# Reminder: Instructions for Tool Use
|
|
1039
|
-
Tool uses are formatted using XML-style tags. The tool name is enclosed in opening and closing tags, and each parameter is similarly enclosed within its own set of tags. Here's the structure:
|
|
1040
|
-
<tool_name>
|
|
1041
|
-
<parameter1_name>value1</parameter1_name>
|
|
1042
|
-
<parameter2_name>value2</parameter2_name>
|
|
1043
|
-
...
|
|
1044
|
-
</tool_name>
|
|
1045
|
-
For example:
|
|
1046
|
-
<agent_attempt_completion>
|
|
1047
|
-
<result>
|
|
1048
|
-
I have completed the task...
|
|
1049
|
-
</result>
|
|
1050
|
-
</agent_attempt_completion>
|
|
1051
|
-
Always adhere to this format for all tool uses to ensure proper parsing and execution.
|
|
1052
|
-
|
|
1053
|
-
# Next Steps
|
|
1054
|
-
|
|
1055
|
-
If you have completed the user's task, use the attempt_completion tool.
|
|
1056
|
-
If you require additional information from the user, use the ask_followup_question tool.
|
|
1057
|
-
Otherwise, if you have not completed the task and do not need additional information, then proceed with the next step of the task.
|
|
1058
|
-
(This is an automated message, so do not respond to it conversationally.)
|
|
1059
|
-
${this?.getEnvironmentInfoPrompt?.(context)}`;
|
|
1060
|
-
}
|
|
1061
|
-
};
|
|
1062
|
-
var NodeApiHandler = class {
|
|
1063
|
-
config;
|
|
1064
|
-
conversationId;
|
|
1065
|
-
constructor(config) {
|
|
1066
|
-
this.config = config;
|
|
1067
|
-
}
|
|
1068
|
-
getModelInfo() {
|
|
1069
|
-
return {
|
|
1070
|
-
providerId: this.config.providerId || "openai-compatible",
|
|
1071
|
-
modelId: this.config.modelId
|
|
1072
|
-
};
|
|
1073
|
-
}
|
|
1074
|
-
async *createMessage(systemPrompt, messages) {
|
|
1075
|
-
let model;
|
|
1076
|
-
if (this.config.providerId === "dify") {
|
|
1077
|
-
const customDify = difyAiProvider.createDifyProvider({
|
|
1078
|
-
baseURL: this.config.baseURL,
|
|
1079
|
-
headers: this.config.headers,
|
|
1080
|
-
fetch: this.config.fetch
|
|
1081
|
-
});
|
|
1082
|
-
model = customDify(this.config.modelId || "", {
|
|
1083
|
-
apiKey: this.config.apiKey,
|
|
1084
|
-
responseMode: "streaming"
|
|
1085
|
-
});
|
|
1086
|
-
} else {
|
|
1087
|
-
const customOpenAI = openai.createOpenAI({
|
|
1088
|
-
baseURL: this.config.baseURL,
|
|
1089
|
-
apiKey: this.config.apiKey,
|
|
1090
|
-
headers: this.config.headers,
|
|
1091
|
-
fetch: this.config.fetch
|
|
1092
|
-
});
|
|
1093
|
-
model = customOpenAI(this.config.modelId || "");
|
|
1094
|
-
}
|
|
1095
|
-
try {
|
|
1096
|
-
const streamOptions = {
|
|
1097
|
-
model,
|
|
1098
|
-
headers: {
|
|
1099
|
-
...this.config.headers
|
|
1100
|
-
},
|
|
1101
|
-
allowSystemInMessages: true
|
|
1102
|
-
};
|
|
1103
|
-
if (this.config.providerId === "dify" && this.conversationId) {
|
|
1104
|
-
streamOptions.headers["chat-id"] = this.conversationId;
|
|
1105
|
-
}
|
|
1106
|
-
streamOptions.messages = [
|
|
1107
|
-
{ role: "system", content: systemPrompt },
|
|
1108
|
-
...messages.map((m) => ({
|
|
1109
|
-
role: m.role === "system" ? "system" : m.role === "user" ? "user" : "assistant",
|
|
1110
|
-
content: m.content
|
|
1111
|
-
}))
|
|
1112
|
-
];
|
|
1113
|
-
const { fullStream } = ai.streamText(streamOptions);
|
|
1114
|
-
for await (const part of fullStream) {
|
|
1115
|
-
if (this.config.providerId === "dify" && !this.conversationId && part?.providerMetadata?.difyWorkflowData?.conversationId || part?.providerMetadata?.dify?.conversationId) {
|
|
1116
|
-
this.conversationId = part.providerMetadata?.difyWorkflowData?.conversationId || part.providerMetadata?.dify?.conversationId;
|
|
1117
|
-
}
|
|
1118
|
-
if (part.type === "text-delta") {
|
|
1119
|
-
yield {
|
|
1120
|
-
type: "text",
|
|
1121
|
-
text: part.textDelta || part.text || ""
|
|
1122
|
-
};
|
|
1123
|
-
} else if (part.type === "finish") {
|
|
1124
|
-
yield {
|
|
1125
|
-
type: "usage",
|
|
1126
|
-
usage: {
|
|
1127
|
-
inputTokens: part.usage?.promptTokens || part.totalUsage?.promptTokens || part.totalUsage?.inputTokens || 0,
|
|
1128
|
-
outputTokens: part.usage?.completionTokens || part.totalUsage?.completionTokens || part.totalUsage?.outputTokens || 0
|
|
1129
|
-
}
|
|
1130
|
-
};
|
|
1131
|
-
} else if (part.type === "error") {
|
|
1132
|
-
yield {
|
|
1133
|
-
type: "error",
|
|
1134
|
-
error: part.error
|
|
1135
|
-
};
|
|
1136
|
-
}
|
|
1137
|
-
}
|
|
1138
|
-
} catch (err) {
|
|
1139
|
-
yield {
|
|
1140
|
-
type: "error",
|
|
1141
|
-
error: err
|
|
1142
|
-
};
|
|
1143
|
-
}
|
|
1144
|
-
}
|
|
1145
|
-
};
|
|
1146
|
-
var WebApiHandler = class {
|
|
1147
|
-
config;
|
|
1148
|
-
conversationId;
|
|
1149
|
-
constructor(config) {
|
|
1150
|
-
this.config = config;
|
|
1151
|
-
}
|
|
1152
|
-
getModelInfo() {
|
|
1153
|
-
return {
|
|
1154
|
-
providerId: this.config.providerId || "openai-compatible",
|
|
1155
|
-
modelId: this.config.modelId
|
|
1156
|
-
};
|
|
1157
|
-
}
|
|
1158
|
-
async *createMessage(systemPrompt, messages) {
|
|
1159
|
-
let model;
|
|
1160
|
-
if (this.config.providerId === "dify") {
|
|
1161
|
-
const customDify = difyAiProvider.createDifyProvider({
|
|
1162
|
-
baseURL: this.config.baseURL,
|
|
1163
|
-
headers: this.config.headers,
|
|
1164
|
-
fetch: this.config.fetch
|
|
1165
|
-
});
|
|
1166
|
-
model = customDify(this.config.modelId || "", {
|
|
1167
|
-
apiKey: this.config.apiKey,
|
|
1168
|
-
responseMode: "streaming"
|
|
1169
|
-
});
|
|
1170
|
-
} else {
|
|
1171
|
-
const customOpenAI = openai.createOpenAI({
|
|
1172
|
-
baseURL: this.config.baseURL,
|
|
1173
|
-
apiKey: this.config.apiKey,
|
|
1174
|
-
headers: this.config.headers,
|
|
1175
|
-
fetch: this.config.fetch
|
|
1176
|
-
});
|
|
1177
|
-
model = customOpenAI(this.config.modelId || "");
|
|
1178
|
-
}
|
|
1179
|
-
try {
|
|
1180
|
-
const streamOptions = {
|
|
1181
|
-
model,
|
|
1182
|
-
headers: {
|
|
1183
|
-
...this.config.headers
|
|
1184
|
-
},
|
|
1185
|
-
allowSystemInMessages: true
|
|
1186
|
-
};
|
|
1187
|
-
if (this.config.providerId === "dify" && this.conversationId) {
|
|
1188
|
-
streamOptions.headers["chat-id"] = this.conversationId;
|
|
1189
|
-
}
|
|
1190
|
-
streamOptions.messages = [
|
|
1191
|
-
{ role: "system", content: systemPrompt },
|
|
1192
|
-
...messages.map((m) => ({
|
|
1193
|
-
role: m.role === "system" ? "system" : m.role === "user" ? "user" : "assistant",
|
|
1194
|
-
content: m.content
|
|
1195
|
-
}))
|
|
1196
|
-
];
|
|
1197
|
-
const { fullStream } = ai.streamText(streamOptions);
|
|
1198
|
-
for await (const part of fullStream) {
|
|
1199
|
-
if (this.config.providerId === "dify" && !this.conversationId && part?.providerMetadata?.difyWorkflowData?.conversationId || part?.providerMetadata?.dify?.conversationId) {
|
|
1200
|
-
this.conversationId = part.providerMetadata?.difyWorkflowData?.conversationId || part.providerMetadata?.dify?.conversationId;
|
|
1201
|
-
}
|
|
1202
|
-
if (part.type === "text-delta") {
|
|
1203
|
-
yield {
|
|
1204
|
-
type: "text",
|
|
1205
|
-
text: part.textDelta || part.text || ""
|
|
1206
|
-
};
|
|
1207
|
-
} else if (part.type === "finish") {
|
|
1208
|
-
yield {
|
|
1209
|
-
type: "usage",
|
|
1210
|
-
usage: {
|
|
1211
|
-
inputTokens: part.usage?.promptTokens || part.totalUsage?.promptTokens || part.totalUsage?.inputTokens || 0,
|
|
1212
|
-
outputTokens: part.usage?.completionTokens || part.totalUsage?.completionTokens || part.totalUsage?.outputTokens || 0
|
|
1213
|
-
}
|
|
1214
|
-
};
|
|
1215
|
-
} else if (part.type === "error") {
|
|
1216
|
-
yield {
|
|
1217
|
-
type: "error",
|
|
1218
|
-
error: part.error
|
|
1219
|
-
};
|
|
1220
|
-
}
|
|
1221
|
-
}
|
|
1222
|
-
} catch (err) {
|
|
1223
|
-
yield {
|
|
1224
|
-
type: "error",
|
|
1225
|
-
error: err
|
|
1226
|
-
};
|
|
1227
|
-
}
|
|
1228
|
-
}
|
|
1229
|
-
};
|
|
1230
474
|
var AgentState = /* @__PURE__ */ ((AgentState2) => {
|
|
1231
475
|
AgentState2["IDLE"] = "idle";
|
|
1232
476
|
AgentState2["THINKING"] = "thinking";
|
|
@@ -1444,10 +688,10 @@ var ClineAgent = class {
|
|
|
1444
688
|
this.setState("finished" /* FINISHED */);
|
|
1445
689
|
break;
|
|
1446
690
|
} else if (tool.name === "agent_read_file" /* FILE_READ */) {
|
|
1447
|
-
const
|
|
1448
|
-
if (
|
|
691
|
+
const path = tool.params.path;
|
|
692
|
+
if (path) {
|
|
1449
693
|
try {
|
|
1450
|
-
const content = await this.runtime.fs.readFile(
|
|
694
|
+
const content = await this.runtime.fs.readFile(path);
|
|
1451
695
|
toolResults.push({ tool, result: content });
|
|
1452
696
|
} catch (error) {
|
|
1453
697
|
toolResults.push({ tool, result: `Error: ${error.message}` });
|
|
@@ -1463,33 +707,33 @@ var ClineAgent = class {
|
|
|
1463
707
|
STDERR: ${result.stderr}` });
|
|
1464
708
|
}
|
|
1465
709
|
} else if (tool.name === "agent_write_to_file" /* FILE_NEW */) {
|
|
1466
|
-
const
|
|
710
|
+
const path = tool.params.path;
|
|
1467
711
|
const content = tool.params.content;
|
|
1468
|
-
if (
|
|
712
|
+
if (path && content !== void 0) {
|
|
1469
713
|
try {
|
|
1470
|
-
await this.runtime.fs.writeFile(
|
|
1471
|
-
toolResults.push({ tool, result: `Successfully wrote to ${
|
|
714
|
+
await this.runtime.fs.writeFile(path, content);
|
|
715
|
+
toolResults.push({ tool, result: `Successfully wrote to ${path}` });
|
|
1472
716
|
} catch (error) {
|
|
1473
717
|
toolResults.push({ tool, result: `Error: ${error.message}` });
|
|
1474
718
|
}
|
|
1475
719
|
}
|
|
1476
720
|
} else if (tool.name === "agent_list_files" /* LIST_FILES */) {
|
|
1477
|
-
const
|
|
721
|
+
const path = tool.params.path || this.runtime.env.cwd();
|
|
1478
722
|
try {
|
|
1479
|
-
const files = await this.runtime.fs.readDir(
|
|
723
|
+
const files = await this.runtime.fs.readDir(path);
|
|
1480
724
|
toolResults.push({ tool, result: files.map((f) => f.name + (f.isDirectory() ? "/" : "")).join("\n") });
|
|
1481
725
|
} catch (e) {
|
|
1482
726
|
toolResults.push({ tool, result: `Error: ${e.message}` });
|
|
1483
727
|
}
|
|
1484
728
|
} else if (tool.name === "agent_replace_in_file" /* FILE_EDIT */) {
|
|
1485
|
-
const
|
|
729
|
+
const path = tool.params.path;
|
|
1486
730
|
const diff = tool.params.diff;
|
|
1487
|
-
if (
|
|
731
|
+
if (path && diff) {
|
|
1488
732
|
try {
|
|
1489
|
-
const content = await this.runtime.fs.readFile(
|
|
733
|
+
const content = await this.runtime.fs.readFile(path);
|
|
1490
734
|
const newContent = this.applyDiff(content, diff);
|
|
1491
|
-
await this.runtime.fs.writeFile(
|
|
1492
|
-
toolResults.push({ tool, result: `Successfully replaced content in ${
|
|
735
|
+
await this.runtime.fs.writeFile(path, newContent);
|
|
736
|
+
toolResults.push({ tool, result: `Successfully replaced content in ${path}` });
|
|
1493
737
|
} catch (e) {
|
|
1494
738
|
toolResults.push({ tool, result: `Error: ${e.message}` });
|
|
1495
739
|
}
|
|
@@ -1497,11 +741,11 @@ STDERR: ${result.stderr}` });
|
|
|
1497
741
|
toolResults.push({ tool, result: "Error: Missing path or diff." });
|
|
1498
742
|
}
|
|
1499
743
|
} else if (tool.name === "agent_delete_file" /* FILE_DELETE */) {
|
|
1500
|
-
const
|
|
1501
|
-
if (
|
|
744
|
+
const path = tool.params.path;
|
|
745
|
+
if (path) {
|
|
1502
746
|
try {
|
|
1503
|
-
await this.runtime.fs.deleteFile(
|
|
1504
|
-
toolResults.push({ tool, result: `Successfully deleted ${
|
|
747
|
+
await this.runtime.fs.deleteFile(path);
|
|
748
|
+
toolResults.push({ tool, result: `Successfully deleted ${path}` });
|
|
1505
749
|
} catch (e) {
|
|
1506
750
|
toolResults.push({ tool, result: `Error: ${e.message}` });
|
|
1507
751
|
}
|
|
@@ -1509,11 +753,11 @@ STDERR: ${result.stderr}` });
|
|
|
1509
753
|
toolResults.push({ tool, result: "Error: Missing path." });
|
|
1510
754
|
}
|
|
1511
755
|
} else if (tool.name === "agent_delete_directory" /* DIR_DELETE */) {
|
|
1512
|
-
const
|
|
1513
|
-
if (
|
|
756
|
+
const path = tool.params.path;
|
|
757
|
+
if (path) {
|
|
1514
758
|
try {
|
|
1515
|
-
await this.runtime.fs.deleteDirectory(
|
|
1516
|
-
toolResults.push({ tool, result: `Successfully deleted ${
|
|
759
|
+
await this.runtime.fs.deleteDirectory(path);
|
|
760
|
+
toolResults.push({ tool, result: `Successfully deleted ${path}` });
|
|
1517
761
|
} catch (e) {
|
|
1518
762
|
toolResults.push({ tool, result: `Error: ${e.message}` });
|
|
1519
763
|
}
|
|
@@ -1526,12 +770,12 @@ STDERR: ${result.stderr}` });
|
|
|
1526
770
|
this.setState("waiting_for_user" /* WAITING_FOR_USER */);
|
|
1527
771
|
break;
|
|
1528
772
|
} else if (tool.name === "agent_search_files" /* SEARCH */) {
|
|
1529
|
-
const
|
|
773
|
+
const path = tool.params.path || this.runtime.env.cwd();
|
|
1530
774
|
const regexStr = tool.params.regex;
|
|
1531
775
|
const filePattern = tool.params.file_pattern;
|
|
1532
776
|
if (regexStr && this.runtime.fs.searchFiles) {
|
|
1533
777
|
try {
|
|
1534
|
-
const result = await this.runtime.fs.searchFiles(
|
|
778
|
+
const result = await this.runtime.fs.searchFiles(path, regexStr, filePattern);
|
|
1535
779
|
toolResults.push({ tool, result: `${result}` });
|
|
1536
780
|
} catch (e) {
|
|
1537
781
|
toolResults.push({ tool, result: `Error: ${e.message}` });
|
|
@@ -1578,9 +822,9 @@ STDERR: ${result.stderr}` });
|
|
|
1578
822
|
const docs = `MCP (Model Context Protocol) is used to connect to external tools/resources. To build one, typically you create an HTTP/stdio server responding to MCP defined JSON-RPC messages...`;
|
|
1579
823
|
toolResults.push({ tool, result: docs });
|
|
1580
824
|
} else if (tool.name === "agent_list_code_definition_names" /* LIST_CODE_DEF */) {
|
|
1581
|
-
const
|
|
825
|
+
const path = tool.params.path || this.runtime.env.cwd();
|
|
1582
826
|
try {
|
|
1583
|
-
const result = await this.runtime.fs.searchFiles?.(
|
|
827
|
+
const result = await this.runtime.fs.searchFiles?.(path, "^(class|function|const|let|var|export|interface|type)\\s+\\w+", "*.ts|*.js");
|
|
1584
828
|
toolResults.push({ tool, result: `${result ? result : "No definitions found or searchFiles not supported."}` });
|
|
1585
829
|
} catch (e) {
|
|
1586
830
|
toolResults.push({ tool, result: `Error: ${e.message}` });
|
|
@@ -1703,293 +947,6 @@ ${searchBlock.substring(0, 100)}...`);
|
|
|
1703
947
|
return this.memory.getHistory();
|
|
1704
948
|
}
|
|
1705
949
|
};
|
|
1706
|
-
var NodeMemoryManager = class {
|
|
1707
|
-
filePath;
|
|
1708
|
-
maxMessages;
|
|
1709
|
-
/**
|
|
1710
|
-
* @param dbPath 存储历史记录的本地文件路径(例如:'./.cline_memory.json')
|
|
1711
|
-
* @param maxMessages 保留的最大消息数量,用于简单的历史截断(默认 150)
|
|
1712
|
-
*/
|
|
1713
|
-
constructor(dbPath, maxMessages = 150) {
|
|
1714
|
-
this.filePath = path2__namespace.resolve(dbPath);
|
|
1715
|
-
this.maxMessages = maxMessages;
|
|
1716
|
-
}
|
|
1717
|
-
async ensureFile() {
|
|
1718
|
-
try {
|
|
1719
|
-
await fs2__namespace.access(this.filePath);
|
|
1720
|
-
} catch {
|
|
1721
|
-
const dir = path2__namespace.dirname(this.filePath);
|
|
1722
|
-
await fs2__namespace.mkdir(dir, { recursive: true });
|
|
1723
|
-
await fs2__namespace.writeFile(this.filePath, "[]", "utf-8");
|
|
1724
|
-
}
|
|
1725
|
-
}
|
|
1726
|
-
async readMessages() {
|
|
1727
|
-
await this.ensureFile();
|
|
1728
|
-
const data = await fs2__namespace.readFile(this.filePath, "utf-8");
|
|
1729
|
-
try {
|
|
1730
|
-
return JSON.parse(data);
|
|
1731
|
-
} catch {
|
|
1732
|
-
return [];
|
|
1733
|
-
}
|
|
1734
|
-
}
|
|
1735
|
-
async writeMessages(messages) {
|
|
1736
|
-
await this.ensureFile();
|
|
1737
|
-
await fs2__namespace.writeFile(this.filePath, JSON.stringify(messages, null, 2), "utf-8");
|
|
1738
|
-
}
|
|
1739
|
-
async getHistory() {
|
|
1740
|
-
return this.readMessages();
|
|
1741
|
-
}
|
|
1742
|
-
async appendMessage(message) {
|
|
1743
|
-
const messages = await this.readMessages();
|
|
1744
|
-
messages.push(message);
|
|
1745
|
-
await this.writeMessages(messages);
|
|
1746
|
-
await this.condenseHistory();
|
|
1747
|
-
}
|
|
1748
|
-
async condenseHistory() {
|
|
1749
|
-
const messages = await this.readMessages();
|
|
1750
|
-
if (messages.length > this.maxMessages) {
|
|
1751
|
-
const firstMessage = messages[0];
|
|
1752
|
-
const isFirstSystem = firstMessage && firstMessage.role === "system";
|
|
1753
|
-
const sliceCount = messages.length - this.maxMessages;
|
|
1754
|
-
let condensed;
|
|
1755
|
-
if (isFirstSystem) {
|
|
1756
|
-
condensed = [firstMessage, ...messages.slice(sliceCount + 1)];
|
|
1757
|
-
} else {
|
|
1758
|
-
condensed = messages.slice(sliceCount);
|
|
1759
|
-
}
|
|
1760
|
-
await this.writeMessages(condensed);
|
|
1761
|
-
}
|
|
1762
|
-
}
|
|
1763
|
-
async clear() {
|
|
1764
|
-
await this.writeMessages([]);
|
|
1765
|
-
}
|
|
1766
|
-
};
|
|
1767
|
-
|
|
1768
|
-
// src/memory/WebMemoryManager.ts
|
|
1769
|
-
var WebMemoryManager = class {
|
|
1770
|
-
storageKey;
|
|
1771
|
-
maxMessages;
|
|
1772
|
-
inMemoryFallback = [];
|
|
1773
|
-
/**
|
|
1774
|
-
* @param storageKey SessionStorage 中的键名
|
|
1775
|
-
* @param maxMessages 保留的最大消息数量,用于简单的历史截断(默认 150)
|
|
1776
|
-
*/
|
|
1777
|
-
constructor(storageKey = "cline_agent_memory", maxMessages = 150) {
|
|
1778
|
-
this.storageKey = storageKey;
|
|
1779
|
-
this.maxMessages = maxMessages;
|
|
1780
|
-
}
|
|
1781
|
-
isStorageAvailable() {
|
|
1782
|
-
try {
|
|
1783
|
-
return typeof window !== "undefined" && typeof window.sessionStorage !== "undefined";
|
|
1784
|
-
} catch {
|
|
1785
|
-
return false;
|
|
1786
|
-
}
|
|
1787
|
-
}
|
|
1788
|
-
readMessages() {
|
|
1789
|
-
if (this.isStorageAvailable()) {
|
|
1790
|
-
const data = window.sessionStorage.getItem(this.storageKey);
|
|
1791
|
-
if (data) {
|
|
1792
|
-
try {
|
|
1793
|
-
return JSON.parse(data);
|
|
1794
|
-
} catch {
|
|
1795
|
-
return [];
|
|
1796
|
-
}
|
|
1797
|
-
}
|
|
1798
|
-
return [];
|
|
1799
|
-
}
|
|
1800
|
-
return this.inMemoryFallback;
|
|
1801
|
-
}
|
|
1802
|
-
writeMessages(messages) {
|
|
1803
|
-
if (this.isStorageAvailable()) {
|
|
1804
|
-
window.sessionStorage.setItem(this.storageKey, JSON.stringify(messages));
|
|
1805
|
-
} else {
|
|
1806
|
-
this.inMemoryFallback = messages;
|
|
1807
|
-
}
|
|
1808
|
-
}
|
|
1809
|
-
async getHistory() {
|
|
1810
|
-
return Promise.resolve(this.readMessages());
|
|
1811
|
-
}
|
|
1812
|
-
async appendMessage(message) {
|
|
1813
|
-
const messages = this.readMessages();
|
|
1814
|
-
messages.push(message);
|
|
1815
|
-
this.writeMessages(messages);
|
|
1816
|
-
await this.condenseHistory();
|
|
1817
|
-
}
|
|
1818
|
-
async condenseHistory() {
|
|
1819
|
-
const messages = this.readMessages();
|
|
1820
|
-
if (messages.length > this.maxMessages) {
|
|
1821
|
-
const firstMessage = messages[0];
|
|
1822
|
-
const isFirstSystem = firstMessage && firstMessage.role === "system";
|
|
1823
|
-
const sliceCount = messages.length - this.maxMessages;
|
|
1824
|
-
let condensed;
|
|
1825
|
-
if (isFirstSystem) {
|
|
1826
|
-
condensed = [firstMessage, ...messages.slice(sliceCount + 1)];
|
|
1827
|
-
} else {
|
|
1828
|
-
condensed = messages.slice(sliceCount);
|
|
1829
|
-
}
|
|
1830
|
-
this.writeMessages(condensed);
|
|
1831
|
-
}
|
|
1832
|
-
return Promise.resolve();
|
|
1833
|
-
}
|
|
1834
|
-
async clear() {
|
|
1835
|
-
this.writeMessages([]);
|
|
1836
|
-
return Promise.resolve();
|
|
1837
|
-
}
|
|
1838
|
-
};
|
|
1839
|
-
|
|
1840
|
-
// src/runtime/nodeRuntime.ts
|
|
1841
|
-
var execAsync = util.promisify(child_process.exec);
|
|
1842
|
-
var DefaultNodeRuntime = class {
|
|
1843
|
-
fs = {
|
|
1844
|
-
readFile: async (filepath) => fs2__namespace.readFile(filepath, "utf-8"),
|
|
1845
|
-
writeFile: async (filepath, content) => {
|
|
1846
|
-
await fs2__namespace.mkdir(path2__namespace.dirname(filepath), { recursive: true });
|
|
1847
|
-
await fs2__namespace.writeFile(filepath, content, "utf-8");
|
|
1848
|
-
},
|
|
1849
|
-
deleteFile: (filepath) => fs2__namespace.unlink(filepath),
|
|
1850
|
-
deleteDirectory: (dirpath) => fs2__namespace.rm(dirpath, { recursive: true, force: true }),
|
|
1851
|
-
fileExists: async (filepath) => {
|
|
1852
|
-
try {
|
|
1853
|
-
await fs2__namespace.access(filepath);
|
|
1854
|
-
return true;
|
|
1855
|
-
} catch {
|
|
1856
|
-
return false;
|
|
1857
|
-
}
|
|
1858
|
-
},
|
|
1859
|
-
readDir: (dirpath) => fs2__namespace.readdir(dirpath, { withFileTypes: true }),
|
|
1860
|
-
mkdir: async (dirpath) => {
|
|
1861
|
-
await fs2__namespace.mkdir(dirpath, { recursive: true });
|
|
1862
|
-
}
|
|
1863
|
-
};
|
|
1864
|
-
path = {
|
|
1865
|
-
join: (...paths) => path2__namespace.join(...paths)
|
|
1866
|
-
};
|
|
1867
|
-
env = {
|
|
1868
|
-
get: (key) => process.env[key],
|
|
1869
|
-
cwd: () => process.cwd(),
|
|
1870
|
-
osInfo: () => `${os__namespace.type()} ${os__namespace.release()} ${os__namespace.arch()}`,
|
|
1871
|
-
shell: () => process.env.SHELL || process.env.ComSpec || "unknown"
|
|
1872
|
-
};
|
|
1873
|
-
terminal = {
|
|
1874
|
-
execCommand: async (command, options) => {
|
|
1875
|
-
try {
|
|
1876
|
-
const { stdout, stderr } = await execAsync(command, { cwd: options?.cwd || process.cwd() });
|
|
1877
|
-
return { stdout, stderr, exitCode: 0 };
|
|
1878
|
-
} catch (err) {
|
|
1879
|
-
return { stdout: err.stdout || "", stderr: err.stderr || err.message, exitCode: err.code || 1 };
|
|
1880
|
-
}
|
|
1881
|
-
}
|
|
1882
|
-
};
|
|
1883
|
-
};
|
|
1884
|
-
function createNodeAgent(options) {
|
|
1885
|
-
const runtime = new DefaultNodeRuntime();
|
|
1886
|
-
const api = new NodeApiHandler(options.apiConfig);
|
|
1887
|
-
const memory = options.memory || new NodeMemoryManager(options.dbPath || path2__namespace.join(runtime.env.cwd(), ".cline_memory.json"));
|
|
1888
|
-
const customTools = options.customTools || [];
|
|
1889
|
-
const customToolNames = new Set(customTools.map((t) => t.name));
|
|
1890
|
-
const promptManager = new NodePromptManager();
|
|
1891
|
-
const agent = new ClineAgent({
|
|
1892
|
-
runtime,
|
|
1893
|
-
api,
|
|
1894
|
-
promptManager,
|
|
1895
|
-
memory,
|
|
1896
|
-
customTools,
|
|
1897
|
-
allowDefaultTools: options.allowDefaultTools,
|
|
1898
|
-
maxLoopCount: options.maxLoopCount,
|
|
1899
|
-
customInstructions: options.customInstructions
|
|
1900
|
-
});
|
|
1901
|
-
agent.onToolCall = async (tool) => {
|
|
1902
|
-
if (customToolNames.has(tool.name)) {
|
|
1903
|
-
const customTool = customTools.find((t) => t.name === tool.name);
|
|
1904
|
-
if (customTool.onCall) {
|
|
1905
|
-
return customTool.onCall(tool.params);
|
|
1906
|
-
}
|
|
1907
|
-
return `Error: Custom tool "${tool.name}" does not have an onCall method.`;
|
|
1908
|
-
}
|
|
1909
|
-
};
|
|
1910
|
-
return agent;
|
|
1911
|
-
}
|
|
1912
|
-
var DefaultWebRuntime = class {
|
|
1913
|
-
vol = new memfs.Volume();
|
|
1914
|
-
memfs = memfs.createFsFromVolume(this.vol).promises;
|
|
1915
|
-
fs = {
|
|
1916
|
-
readFile: async (filepath) => {
|
|
1917
|
-
const content = await this.memfs.readFile(filepath, "utf-8");
|
|
1918
|
-
return content.toString();
|
|
1919
|
-
},
|
|
1920
|
-
writeFile: async (filepath, content) => {
|
|
1921
|
-
const dir = filepath.substring(0, filepath.lastIndexOf("/"));
|
|
1922
|
-
if (dir && dir !== filepath) {
|
|
1923
|
-
await this.memfs.mkdir(dir, { recursive: true });
|
|
1924
|
-
}
|
|
1925
|
-
await this.memfs.writeFile(filepath, content);
|
|
1926
|
-
},
|
|
1927
|
-
deleteFile: (filepath) => this.memfs.unlink(filepath),
|
|
1928
|
-
deleteDirectory: (dirpath) => this.memfs.rm(dirpath, { recursive: true, force: true }),
|
|
1929
|
-
fileExists: async (filepath) => {
|
|
1930
|
-
try {
|
|
1931
|
-
await this.memfs.access(filepath);
|
|
1932
|
-
return true;
|
|
1933
|
-
} catch {
|
|
1934
|
-
return false;
|
|
1935
|
-
}
|
|
1936
|
-
},
|
|
1937
|
-
readDir: (dirpath) => {
|
|
1938
|
-
return this.memfs.readdir(dirpath, { withFileTypes: true });
|
|
1939
|
-
},
|
|
1940
|
-
mkdir: async (dirpath) => {
|
|
1941
|
-
await this.memfs.mkdir(dirpath, { recursive: true });
|
|
1942
|
-
}
|
|
1943
|
-
};
|
|
1944
|
-
path = {
|
|
1945
|
-
join: (...paths) => path3__default.default.join(...paths)
|
|
1946
|
-
};
|
|
1947
|
-
env = {
|
|
1948
|
-
get: (key) => void 0,
|
|
1949
|
-
// 浏览器环境中无系统环境变量
|
|
1950
|
-
cwd: () => "/workspace",
|
|
1951
|
-
osInfo: () => typeof navigator !== "undefined" ? navigator.userAgent : "Web Browser",
|
|
1952
|
-
shell: () => ""
|
|
1953
|
-
// 浏览器环境中无真实 shell
|
|
1954
|
-
};
|
|
1955
|
-
terminal = {
|
|
1956
|
-
execCommand: async (command, options) => {
|
|
1957
|
-
return {
|
|
1958
|
-
stdout: `[Mock] Command '${command}' executed in browser sandbox.`,
|
|
1959
|
-
stderr: "",
|
|
1960
|
-
exitCode: 0
|
|
1961
|
-
};
|
|
1962
|
-
}
|
|
1963
|
-
};
|
|
1964
|
-
};
|
|
1965
|
-
function createWebAgent(options) {
|
|
1966
|
-
const runtime = new DefaultWebRuntime();
|
|
1967
|
-
const api = new WebApiHandler(options.apiConfig);
|
|
1968
|
-
const promptManager = new WebPromptManager();
|
|
1969
|
-
const memory = new WebMemoryManager(options.storageKey || "cline_agent_memory");
|
|
1970
|
-
const customTools = options.customTools || [];
|
|
1971
|
-
const customToolNames = new Set(customTools.map((t) => t.name));
|
|
1972
|
-
const agent = new ClineAgent({
|
|
1973
|
-
runtime,
|
|
1974
|
-
api,
|
|
1975
|
-
promptManager,
|
|
1976
|
-
memory,
|
|
1977
|
-
customTools,
|
|
1978
|
-
allowDefaultTools: options.allowDefaultTools,
|
|
1979
|
-
maxLoopCount: options.maxLoopCount,
|
|
1980
|
-
customInstructions: options.customInstructions
|
|
1981
|
-
});
|
|
1982
|
-
agent.onToolCall = async (tool) => {
|
|
1983
|
-
if (customToolNames.has(tool.name)) {
|
|
1984
|
-
const customTool = customTools.find((t) => t.name === tool.name);
|
|
1985
|
-
if (customTool.onCall) {
|
|
1986
|
-
return customTool.onCall(tool.params);
|
|
1987
|
-
}
|
|
1988
|
-
return `Error: Custom tool "${tool.name}" does not have an onCall method.`;
|
|
1989
|
-
}
|
|
1990
|
-
};
|
|
1991
|
-
return agent;
|
|
1992
|
-
}
|
|
1993
950
|
|
|
1994
951
|
// src/index.ts
|
|
1995
952
|
var VERSION = "0.1.0";
|
|
@@ -1998,17 +955,9 @@ globalThis.AI_SDK_LOG_WARNINGS = false;
|
|
|
1998
955
|
exports.AgentDefaultTool = AgentDefaultTool;
|
|
1999
956
|
exports.AgentState = AgentState;
|
|
2000
957
|
exports.ClineAgent = ClineAgent;
|
|
2001
|
-
exports.NodeApiHandler = NodeApiHandler;
|
|
2002
|
-
exports.NodeMemoryManager = NodeMemoryManager;
|
|
2003
|
-
exports.NodePromptManager = NodePromptManager;
|
|
2004
958
|
exports.READ_ONLY_TOOLS = READ_ONLY_TOOLS;
|
|
2005
959
|
exports.TOOL_RESULT_BLOCK = TOOL_RESULT_BLOCK;
|
|
2006
960
|
exports.VERSION = VERSION;
|
|
2007
|
-
exports.WebApiHandler = WebApiHandler;
|
|
2008
|
-
exports.WebMemoryManager = WebMemoryManager;
|
|
2009
|
-
exports.WebPromptManager = WebPromptManager;
|
|
2010
|
-
exports.createNodeAgent = createNodeAgent;
|
|
2011
|
-
exports.createWebAgent = createWebAgent;
|
|
2012
961
|
exports.defaultTools = defaultTools;
|
|
2013
962
|
exports.getToolUseNames = getToolUseNames;
|
|
2014
963
|
exports.parseAssistantMessageV2 = parseAssistantMessageV2;
|