@axiom-lattice/core 2.0.2 → 2.0.4
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/index.js +472 -211
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +440 -179
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -574,19 +574,272 @@ registerToolLattice(
|
|
|
574
574
|
topic = "general",
|
|
575
575
|
includeRawContent = false
|
|
576
576
|
}, config) => {
|
|
577
|
+
console.log("[DEBUG][internet_search] Starting search with params:", {
|
|
578
|
+
query,
|
|
579
|
+
maxResults,
|
|
580
|
+
topic,
|
|
581
|
+
includeRawContent
|
|
582
|
+
});
|
|
583
|
+
console.log("[DEBUG][internet_search] Creating TavilySearch instance...");
|
|
577
584
|
const tavilySearch = new TavilySearch({
|
|
578
585
|
maxResults,
|
|
579
586
|
tavilyApiKey: process.env.TAVILY_API_KEY,
|
|
580
587
|
includeRawContent,
|
|
581
588
|
topic
|
|
582
589
|
});
|
|
590
|
+
console.log("[DEBUG][internet_search] Invoking search for query:", query);
|
|
583
591
|
const tavilyResponse = await tavilySearch.invoke({ query });
|
|
584
|
-
|
|
592
|
+
console.log(
|
|
593
|
+
"[DEBUG][internet_search] Search completed. Results count:",
|
|
594
|
+
tavilyResponse.results?.length ?? 0
|
|
595
|
+
);
|
|
596
|
+
const result = genUICard("Internet Search:" + query, "generic_data_table", {
|
|
585
597
|
dataSource: tavilyResponse.results
|
|
586
598
|
});
|
|
599
|
+
console.log("[DEBUG][internet_search] Returning UI card result");
|
|
600
|
+
return result;
|
|
587
601
|
}
|
|
588
602
|
);
|
|
589
603
|
|
|
604
|
+
// src/tool_lattice/write_todos/index.ts
|
|
605
|
+
import z3 from "zod";
|
|
606
|
+
import { ToolMessage } from "@langchain/core/messages";
|
|
607
|
+
import { Command } from "@langchain/langgraph";
|
|
608
|
+
var WRITE_TODOS_DESCRIPTION = `Use this tool to create and manage a structured task list for your current work session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user. It also helps the user understand the progress of the task and overall progress of their requests.
|
|
609
|
+
|
|
610
|
+
When to Use This Tool
|
|
611
|
+
Use this tool proactively in these scenarios:
|
|
612
|
+
|
|
613
|
+
Complex multi-step tasks - When a task requires 3 or more distinct steps or actions
|
|
614
|
+
Non-trivial and complex tasks - Tasks that require careful planning or multiple operations
|
|
615
|
+
User explicitly requests todo list - When the user directly asks you to use the todo list
|
|
616
|
+
User provides multiple tasks - When users provide a list of things to be done (numbered or comma-separated)
|
|
617
|
+
After receiving new instructions - Immediately capture user requirements as todos
|
|
618
|
+
When you start working on a task - Mark it as in_progress BEFORE beginning work. Ideally you should only have one todo as in_progress at a time
|
|
619
|
+
After completing a task - Mark it as completed and add any new follow-up tasks discovered during implementation
|
|
620
|
+
|
|
621
|
+
When NOT to Use This Tool
|
|
622
|
+
Skip using this tool when:
|
|
623
|
+
|
|
624
|
+
There is only a single, straightforward task
|
|
625
|
+
The task is trivial and tracking it provides no organizational benefit
|
|
626
|
+
The task can be completed in less than 3 trivial steps
|
|
627
|
+
The task is purely conversational or informational
|
|
628
|
+
|
|
629
|
+
NOTE that you should not use this tool if there is only one trivial task to do. In this case you are better off just doing the task directly.`;
|
|
630
|
+
registerToolLattice(
|
|
631
|
+
"write_todos",
|
|
632
|
+
{
|
|
633
|
+
name: "write_todos",
|
|
634
|
+
description: WRITE_TODOS_DESCRIPTION,
|
|
635
|
+
needUserApprove: false,
|
|
636
|
+
schema: z3.object({
|
|
637
|
+
todos: z3.array(
|
|
638
|
+
z3.object({
|
|
639
|
+
content: z3.string().describe("Content of the todo item"),
|
|
640
|
+
status: z3.enum(["pending", "in_progress", "completed"]).describe("Status of the todo")
|
|
641
|
+
})
|
|
642
|
+
).describe("List of todo items to update")
|
|
643
|
+
})
|
|
644
|
+
},
|
|
645
|
+
((input, config) => {
|
|
646
|
+
return new Command({
|
|
647
|
+
update: {
|
|
648
|
+
todos: input.todos,
|
|
649
|
+
messages: [
|
|
650
|
+
new ToolMessage({
|
|
651
|
+
content: genUIMarkdown("todo_list", input.todos),
|
|
652
|
+
tool_call_id: config.toolCall?.id
|
|
653
|
+
})
|
|
654
|
+
]
|
|
655
|
+
}
|
|
656
|
+
});
|
|
657
|
+
})
|
|
658
|
+
);
|
|
659
|
+
|
|
660
|
+
// src/tool_lattice/read_file/index.ts
|
|
661
|
+
import z4 from "zod";
|
|
662
|
+
import { getCurrentTaskInput } from "@langchain/langgraph";
|
|
663
|
+
var READ_FILE_DESCRIPTION = `Reads a file from the local filesystem. You can access any file directly by using this tool. Assume this tool is able to read all files on the machine. If the User provides a path to a file assume that path is valid. It is okay to read a file that does not exist; an error will be returned.
|
|
664
|
+
Usage:
|
|
665
|
+
|
|
666
|
+
The file_path parameter must be an absolute path, not a relative path
|
|
667
|
+
By default, it reads up to 2000 lines starting from the beginning of the file
|
|
668
|
+
You can optionally specify a line offset and limit (especially handy for long files), but it's recommended to read the whole file by not providing these parameters
|
|
669
|
+
Any lines longer than 2000 characters will be truncated
|
|
670
|
+
Results are returned using cat -n format, with line numbers starting at 1
|
|
671
|
+
You have the capability to call multiple tools in a single response. It is always better to speculatively read multiple files as a batch that are potentially useful.
|
|
672
|
+
If you read a file that exists but has empty contents you will receive a system reminder warning in place of file contents.`;
|
|
673
|
+
registerToolLattice(
|
|
674
|
+
"read_file",
|
|
675
|
+
{
|
|
676
|
+
name: "read_file",
|
|
677
|
+
description: READ_FILE_DESCRIPTION,
|
|
678
|
+
needUserApprove: false,
|
|
679
|
+
schema: z4.object({
|
|
680
|
+
file_path: z4.string().describe("Absolute path to the file to read"),
|
|
681
|
+
offset: z4.number().optional().default(0).describe("Line offset to start reading from"),
|
|
682
|
+
limit: z4.number().optional().default(2e3).describe("Maximum number of lines to read")
|
|
683
|
+
})
|
|
684
|
+
},
|
|
685
|
+
((input) => {
|
|
686
|
+
const state = getCurrentTaskInput();
|
|
687
|
+
const mockFilesystem = state.files || {};
|
|
688
|
+
const { file_path, offset = 0, limit = 2e3 } = input;
|
|
689
|
+
if (!(file_path in mockFilesystem)) {
|
|
690
|
+
return `Error: File '${file_path}' not found`;
|
|
691
|
+
}
|
|
692
|
+
const content = mockFilesystem[file_path];
|
|
693
|
+
if (!content || content.trim() === "") {
|
|
694
|
+
return "System reminder: File exists but has empty contents";
|
|
695
|
+
}
|
|
696
|
+
const lines = content.split("\n");
|
|
697
|
+
const startIdx = offset;
|
|
698
|
+
const endIdx = Math.min(startIdx + limit, lines.length);
|
|
699
|
+
if (startIdx >= lines.length) {
|
|
700
|
+
return `Error: Line offset ${offset} exceeds file length (${lines.length} lines)`;
|
|
701
|
+
}
|
|
702
|
+
const resultLines = [];
|
|
703
|
+
for (let i = startIdx; i < endIdx; i++) {
|
|
704
|
+
let lineContent = lines[i];
|
|
705
|
+
if (lineContent.length > 2e3) {
|
|
706
|
+
lineContent = lineContent.substring(0, 2e3);
|
|
707
|
+
}
|
|
708
|
+
const lineNumber = i + 1;
|
|
709
|
+
resultLines.push(`${lineNumber.toString().padStart(6)} ${lineContent}`);
|
|
710
|
+
}
|
|
711
|
+
return resultLines.join("\n");
|
|
712
|
+
})
|
|
713
|
+
);
|
|
714
|
+
|
|
715
|
+
// src/tool_lattice/write_file/index.ts
|
|
716
|
+
import z5 from "zod";
|
|
717
|
+
import { ToolMessage as ToolMessage2 } from "@langchain/core/messages";
|
|
718
|
+
import { Command as Command2, getCurrentTaskInput as getCurrentTaskInput2 } from "@langchain/langgraph";
|
|
719
|
+
registerToolLattice(
|
|
720
|
+
"write_file",
|
|
721
|
+
{
|
|
722
|
+
name: "write_file",
|
|
723
|
+
description: "Write content to a file in the mock filesystem",
|
|
724
|
+
needUserApprove: false,
|
|
725
|
+
schema: z5.object({
|
|
726
|
+
file_path: z5.string().describe("Absolute path to the file to write"),
|
|
727
|
+
content: z5.string().describe("Content to write to the file")
|
|
728
|
+
})
|
|
729
|
+
},
|
|
730
|
+
((input, config) => {
|
|
731
|
+
const state = getCurrentTaskInput2();
|
|
732
|
+
const files = { ...state.files || {} };
|
|
733
|
+
files[input.file_path] = input.content;
|
|
734
|
+
return new Command2({
|
|
735
|
+
update: {
|
|
736
|
+
files,
|
|
737
|
+
messages: [
|
|
738
|
+
new ToolMessage2({
|
|
739
|
+
content: `Updated file ${input.file_path}`,
|
|
740
|
+
tool_call_id: config.toolCall?.id
|
|
741
|
+
})
|
|
742
|
+
]
|
|
743
|
+
}
|
|
744
|
+
});
|
|
745
|
+
})
|
|
746
|
+
);
|
|
747
|
+
|
|
748
|
+
// src/tool_lattice/edit_file/index.ts
|
|
749
|
+
import z6 from "zod";
|
|
750
|
+
import { ToolMessage as ToolMessage3 } from "@langchain/core/messages";
|
|
751
|
+
import { Command as Command3, getCurrentTaskInput as getCurrentTaskInput3 } from "@langchain/langgraph";
|
|
752
|
+
var EDIT_FILE_DESCRIPTION = `Performs exact string replacements in files.
|
|
753
|
+
Usage:
|
|
754
|
+
|
|
755
|
+
You must use your Read tool at least once in the conversation before editing. This tool will error if you attempt an edit without reading the file.
|
|
756
|
+
When editing text from Read tool output, ensure you preserve the exact indentation (tabs/spaces) as it appears AFTER the line number prefix. The line number prefix format is: spaces + line number + tab. Everything after that tab is the actual file content to match. Never include any part of the line number prefix in the old_string or new_string.
|
|
757
|
+
ALWAYS prefer editing existing files. NEVER write new files unless explicitly required.
|
|
758
|
+
Only use emojis if the user explicitly requests it. Avoid adding emojis to files unless asked.
|
|
759
|
+
The edit will FAIL if old_string is not unique in the file. Either provide a larger string with more surrounding context to make it unique or use replace_all to change every instance of old_string.
|
|
760
|
+
Use replace_all for replacing and renaming strings across the file. This parameter is useful if you want to rename a variable for instance.`;
|
|
761
|
+
registerToolLattice(
|
|
762
|
+
"edit_file",
|
|
763
|
+
{
|
|
764
|
+
name: "edit_file",
|
|
765
|
+
description: EDIT_FILE_DESCRIPTION,
|
|
766
|
+
needUserApprove: false,
|
|
767
|
+
schema: z6.object({
|
|
768
|
+
file_path: z6.string().describe("Absolute path to the file to edit"),
|
|
769
|
+
old_string: z6.string().describe("String to be replaced (must match exactly)"),
|
|
770
|
+
new_string: z6.string().describe("String to replace with"),
|
|
771
|
+
replace_all: z6.boolean().optional().default(false).describe("Whether to replace all occurrences")
|
|
772
|
+
})
|
|
773
|
+
},
|
|
774
|
+
((input, config) => {
|
|
775
|
+
const state = getCurrentTaskInput3();
|
|
776
|
+
const mockFilesystem = { ...state.files || {} };
|
|
777
|
+
const { file_path, old_string, new_string, replace_all = false } = input;
|
|
778
|
+
if (!(file_path in mockFilesystem)) {
|
|
779
|
+
return `Error: File '${file_path}' not found`;
|
|
780
|
+
}
|
|
781
|
+
const content = mockFilesystem[file_path];
|
|
782
|
+
if (!content.includes(old_string)) {
|
|
783
|
+
return `Error: String not found in file: '${old_string}'`;
|
|
784
|
+
}
|
|
785
|
+
if (!replace_all) {
|
|
786
|
+
const escapedOldString = old_string.replace(
|
|
787
|
+
/[.*+?^${}()|[\]\\]/g,
|
|
788
|
+
"\\$&"
|
|
789
|
+
);
|
|
790
|
+
const occurrences = (content.match(new RegExp(escapedOldString, "g")) || []).length;
|
|
791
|
+
if (occurrences > 1) {
|
|
792
|
+
return `Error: String '${old_string}' appears ${occurrences} times in file. Use replace_all=True to replace all instances, or provide a more specific string with surrounding context.`;
|
|
793
|
+
} else if (occurrences === 0) {
|
|
794
|
+
return `Error: String not found in file: '${old_string}'`;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
let newContent;
|
|
798
|
+
if (replace_all) {
|
|
799
|
+
const escapedOldString = old_string.replace(
|
|
800
|
+
/[.*+?^${}()|[\]\\]/g,
|
|
801
|
+
"\\$&"
|
|
802
|
+
);
|
|
803
|
+
newContent = content.replace(
|
|
804
|
+
new RegExp(escapedOldString, "g"),
|
|
805
|
+
new_string
|
|
806
|
+
);
|
|
807
|
+
} else {
|
|
808
|
+
newContent = content.replace(old_string, new_string);
|
|
809
|
+
}
|
|
810
|
+
mockFilesystem[file_path] = newContent;
|
|
811
|
+
return new Command3({
|
|
812
|
+
update: {
|
|
813
|
+
files: mockFilesystem,
|
|
814
|
+
messages: [
|
|
815
|
+
new ToolMessage3({
|
|
816
|
+
content: `Updated file ${file_path}`,
|
|
817
|
+
tool_call_id: config.toolCall?.id
|
|
818
|
+
})
|
|
819
|
+
]
|
|
820
|
+
}
|
|
821
|
+
});
|
|
822
|
+
})
|
|
823
|
+
);
|
|
824
|
+
|
|
825
|
+
// src/tool_lattice/ls/index.ts
|
|
826
|
+
import z7 from "zod";
|
|
827
|
+
import { getCurrentTaskInput as getCurrentTaskInput4 } from "@langchain/langgraph";
|
|
828
|
+
registerToolLattice(
|
|
829
|
+
"ls",
|
|
830
|
+
{
|
|
831
|
+
name: "ls",
|
|
832
|
+
description: "List all files in the mock filesystem",
|
|
833
|
+
needUserApprove: false,
|
|
834
|
+
schema: z7.object({})
|
|
835
|
+
},
|
|
836
|
+
(() => {
|
|
837
|
+
const state = getCurrentTaskInput4();
|
|
838
|
+
const files = state.files || {};
|
|
839
|
+
return Object.keys(files);
|
|
840
|
+
})
|
|
841
|
+
);
|
|
842
|
+
|
|
590
843
|
// src/agent_lattice/types.ts
|
|
591
844
|
import {
|
|
592
845
|
AgentType,
|
|
@@ -689,10 +942,10 @@ registerCheckpointSaver("default", memory);
|
|
|
689
942
|
// src/agent_lattice/builders/state.ts
|
|
690
943
|
import "@langchain/langgraph/zod";
|
|
691
944
|
import { MessagesZodState } from "@langchain/langgraph";
|
|
692
|
-
import { z as
|
|
945
|
+
import { z as z8 } from "zod";
|
|
693
946
|
var ReActAgentState = MessagesZodState.extend({
|
|
694
|
-
files:
|
|
695
|
-
final_output:
|
|
947
|
+
files: z8.object({
|
|
948
|
+
final_output: z8.record(z8.any())
|
|
696
949
|
})
|
|
697
950
|
});
|
|
698
951
|
var createReactAgentSchema = (schema) => {
|
|
@@ -726,23 +979,17 @@ var ReActAgentGraphBuilder = class {
|
|
|
726
979
|
};
|
|
727
980
|
|
|
728
981
|
// src/deep_agent/subAgent.ts
|
|
729
|
-
import { tool as
|
|
730
|
-
import { ToolMessage as
|
|
982
|
+
import { tool as tool2 } from "@langchain/core/tools";
|
|
983
|
+
import { ToolMessage as ToolMessage4 } from "@langchain/core/messages";
|
|
731
984
|
import {
|
|
732
|
-
Command as
|
|
733
|
-
getCurrentTaskInput as
|
|
985
|
+
Command as Command4,
|
|
986
|
+
getCurrentTaskInput as getCurrentTaskInput5,
|
|
734
987
|
GraphInterrupt
|
|
735
988
|
} from "@langchain/langgraph";
|
|
736
|
-
import { z as
|
|
737
|
-
|
|
738
|
-
// src/deep_agent/tools.ts
|
|
739
|
-
import { tool as tool2 } from "@langchain/core/tools";
|
|
740
|
-
import { ToolMessage } from "@langchain/core/messages";
|
|
741
|
-
import { Command, getCurrentTaskInput } from "@langchain/langgraph";
|
|
742
|
-
import { z as z4 } from "zod";
|
|
989
|
+
import { z as z9 } from "zod";
|
|
743
990
|
|
|
744
991
|
// src/deep_agent/prompts.ts
|
|
745
|
-
var
|
|
992
|
+
var WRITE_TODOS_DESCRIPTION2 = `Use this tool to create and manage a structured task list for your current work session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user. It also helps the user understand the progress of the task and overall progress of their requests.
|
|
746
993
|
|
|
747
994
|
When to Use This Tool
|
|
748
995
|
Use this tool proactively in these scenarios:
|
|
@@ -996,14 +1243,143 @@ Results are returned using cat -n format, with line numbers starting at 1
|
|
|
996
1243
|
You have the capability to call multiple tools in a single response. It is always better to speculatively read multiple files as a batch that are potentially useful.
|
|
997
1244
|
If you read a file that exists but has empty contents you will receive a system reminder warning in place of file contents.`;
|
|
998
1245
|
|
|
1246
|
+
// src/deep_agent/subAgent.ts
|
|
1247
|
+
import {
|
|
1248
|
+
getToolsFromConfig as getToolsFromConfig2,
|
|
1249
|
+
hasTools as hasTools2
|
|
1250
|
+
} from "@axiom-lattice/protocols";
|
|
1251
|
+
var BUILTIN_TOOL_NAMES = [
|
|
1252
|
+
"write_todos",
|
|
1253
|
+
"read_file",
|
|
1254
|
+
"write_file",
|
|
1255
|
+
"edit_file",
|
|
1256
|
+
"ls"
|
|
1257
|
+
];
|
|
1258
|
+
function getBuiltinTools() {
|
|
1259
|
+
const tools = {};
|
|
1260
|
+
for (const name of BUILTIN_TOOL_NAMES) {
|
|
1261
|
+
try {
|
|
1262
|
+
tools[name] = getToolClient(name);
|
|
1263
|
+
} catch {
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
return tools;
|
|
1267
|
+
}
|
|
1268
|
+
function createTaskTool(inputs) {
|
|
1269
|
+
const {
|
|
1270
|
+
subagents,
|
|
1271
|
+
tools = {},
|
|
1272
|
+
model = getModelLattice("default")?.client,
|
|
1273
|
+
stateSchema,
|
|
1274
|
+
postModelHook
|
|
1275
|
+
} = inputs;
|
|
1276
|
+
if (!model) {
|
|
1277
|
+
throw new Error("Model not found");
|
|
1278
|
+
}
|
|
1279
|
+
const allTools = { ...getBuiltinTools(), ...tools };
|
|
1280
|
+
const agentsMap = /* @__PURE__ */ new Map();
|
|
1281
|
+
for (const subagent of subagents) {
|
|
1282
|
+
let reactAgent;
|
|
1283
|
+
const agentLattice = getAgentLattice(subagent.key);
|
|
1284
|
+
if (agentLattice) {
|
|
1285
|
+
reactAgent = agentLattice.client;
|
|
1286
|
+
} else {
|
|
1287
|
+
const subagentTools = [];
|
|
1288
|
+
if (hasTools2(subagent)) {
|
|
1289
|
+
for (const toolName of getToolsFromConfig2(subagent)) {
|
|
1290
|
+
const resolvedTool = allTools[toolName];
|
|
1291
|
+
if (resolvedTool) {
|
|
1292
|
+
subagentTools.push(resolvedTool);
|
|
1293
|
+
} else {
|
|
1294
|
+
console.warn(
|
|
1295
|
+
`Warning: Tool '${toolName}' not found for agent '${subagent.name}'`
|
|
1296
|
+
);
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
} else {
|
|
1300
|
+
subagentTools.push(...Object.values(allTools));
|
|
1301
|
+
}
|
|
1302
|
+
reactAgent = createAgentClientFromAgentLattice({ config: subagent });
|
|
1303
|
+
}
|
|
1304
|
+
agentsMap.set(subagent.name, reactAgent);
|
|
1305
|
+
}
|
|
1306
|
+
return tool2(
|
|
1307
|
+
async (input, config) => {
|
|
1308
|
+
const { description, subagent_type } = input;
|
|
1309
|
+
const reactAgent = agentsMap.get(subagent_type);
|
|
1310
|
+
if (!reactAgent) {
|
|
1311
|
+
return `Error: Agent '${subagent_type}' not found. Available agents: ${Array.from(
|
|
1312
|
+
agentsMap.keys()
|
|
1313
|
+
).join(", ")}`;
|
|
1314
|
+
}
|
|
1315
|
+
try {
|
|
1316
|
+
const currentState = getCurrentTaskInput5();
|
|
1317
|
+
const modifiedState = {
|
|
1318
|
+
...currentState,
|
|
1319
|
+
messages: [
|
|
1320
|
+
{
|
|
1321
|
+
role: "user",
|
|
1322
|
+
content: description
|
|
1323
|
+
}
|
|
1324
|
+
]
|
|
1325
|
+
};
|
|
1326
|
+
const result = await reactAgent.invoke(modifiedState, config);
|
|
1327
|
+
return new Command4({
|
|
1328
|
+
update: {
|
|
1329
|
+
files: result.files || {},
|
|
1330
|
+
messages: [
|
|
1331
|
+
new ToolMessage4({
|
|
1332
|
+
content: result.messages?.slice(-1)[0]?.content || "Task completed",
|
|
1333
|
+
tool_call_id: config.toolCall?.id
|
|
1334
|
+
})
|
|
1335
|
+
]
|
|
1336
|
+
}
|
|
1337
|
+
});
|
|
1338
|
+
} catch (error) {
|
|
1339
|
+
if (error instanceof GraphInterrupt) {
|
|
1340
|
+
throw error;
|
|
1341
|
+
}
|
|
1342
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1343
|
+
return new Command4({
|
|
1344
|
+
update: {
|
|
1345
|
+
messages: [
|
|
1346
|
+
new ToolMessage4({
|
|
1347
|
+
content: `Error executing task '${description}' with agent '${subagent_type}': ${errorMessage}`,
|
|
1348
|
+
tool_call_id: config.toolCall?.id
|
|
1349
|
+
})
|
|
1350
|
+
]
|
|
1351
|
+
}
|
|
1352
|
+
});
|
|
1353
|
+
}
|
|
1354
|
+
},
|
|
1355
|
+
{
|
|
1356
|
+
name: "task",
|
|
1357
|
+
description: TASK_DESCRIPTION_PREFIX.replace(
|
|
1358
|
+
"{other_agents}",
|
|
1359
|
+
subagents.map((a) => `- ${a.name}: ${a.description}`).join("\n")
|
|
1360
|
+
) + TASK_DESCRIPTION_SUFFIX,
|
|
1361
|
+
schema: z9.object({
|
|
1362
|
+
description: z9.string().describe("The task to execute with the selected agent"),
|
|
1363
|
+
subagent_type: z9.string().describe(
|
|
1364
|
+
`Name of the agent to use. Available: ${subagents.map((a) => a.name).join(", ")}`
|
|
1365
|
+
)
|
|
1366
|
+
})
|
|
1367
|
+
}
|
|
1368
|
+
);
|
|
1369
|
+
}
|
|
1370
|
+
|
|
999
1371
|
// src/deep_agent/tools.ts
|
|
1000
|
-
|
|
1372
|
+
import { tool as tool3 } from "@langchain/core/tools";
|
|
1373
|
+
import { ToolMessage as ToolMessage5 } from "@langchain/core/messages";
|
|
1374
|
+
import { Command as Command5, getCurrentTaskInput as getCurrentTaskInput6 } from "@langchain/langgraph";
|
|
1375
|
+
import { z as z10 } from "zod";
|
|
1376
|
+
var writeTodos = tool3(
|
|
1001
1377
|
(input, config) => {
|
|
1002
|
-
return new
|
|
1378
|
+
return new Command5({
|
|
1003
1379
|
update: {
|
|
1004
1380
|
todos: input.todos,
|
|
1005
1381
|
messages: [
|
|
1006
|
-
new
|
|
1382
|
+
new ToolMessage5({
|
|
1007
1383
|
content: genUIMarkdown("todo_list", input.todos),
|
|
1008
1384
|
tool_call_id: config.toolCall?.id
|
|
1009
1385
|
})
|
|
@@ -1013,32 +1389,32 @@ var writeTodos = tool2(
|
|
|
1013
1389
|
},
|
|
1014
1390
|
{
|
|
1015
1391
|
name: "write_todos",
|
|
1016
|
-
description:
|
|
1017
|
-
schema:
|
|
1018
|
-
todos:
|
|
1019
|
-
|
|
1020
|
-
content:
|
|
1021
|
-
status:
|
|
1392
|
+
description: WRITE_TODOS_DESCRIPTION2,
|
|
1393
|
+
schema: z10.object({
|
|
1394
|
+
todos: z10.array(
|
|
1395
|
+
z10.object({
|
|
1396
|
+
content: z10.string().describe("Content of the todo item"),
|
|
1397
|
+
status: z10.enum(["pending", "in_progress", "completed"]).describe("Status of the todo")
|
|
1022
1398
|
})
|
|
1023
1399
|
).describe("List of todo items to update")
|
|
1024
1400
|
})
|
|
1025
1401
|
}
|
|
1026
1402
|
);
|
|
1027
|
-
var ls =
|
|
1403
|
+
var ls = tool3(
|
|
1028
1404
|
() => {
|
|
1029
|
-
const state =
|
|
1405
|
+
const state = getCurrentTaskInput6();
|
|
1030
1406
|
const files = state.files || {};
|
|
1031
1407
|
return Object.keys(files);
|
|
1032
1408
|
},
|
|
1033
1409
|
{
|
|
1034
1410
|
name: "ls",
|
|
1035
1411
|
description: "List all files in the mock filesystem",
|
|
1036
|
-
schema:
|
|
1412
|
+
schema: z10.object({})
|
|
1037
1413
|
}
|
|
1038
1414
|
);
|
|
1039
|
-
var readFile =
|
|
1415
|
+
var readFile = tool3(
|
|
1040
1416
|
(input) => {
|
|
1041
|
-
const state =
|
|
1417
|
+
const state = getCurrentTaskInput6();
|
|
1042
1418
|
const mockFilesystem = state.files || {};
|
|
1043
1419
|
const { file_path, offset = 0, limit = 2e3 } = input;
|
|
1044
1420
|
if (!(file_path in mockFilesystem)) {
|
|
@@ -1068,23 +1444,23 @@ var readFile = tool2(
|
|
|
1068
1444
|
{
|
|
1069
1445
|
name: "read_file",
|
|
1070
1446
|
description: TOOL_DESCRIPTION,
|
|
1071
|
-
schema:
|
|
1072
|
-
file_path:
|
|
1073
|
-
offset:
|
|
1074
|
-
limit:
|
|
1447
|
+
schema: z10.object({
|
|
1448
|
+
file_path: z10.string().describe("Absolute path to the file to read"),
|
|
1449
|
+
offset: z10.number().optional().default(0).describe("Line offset to start reading from"),
|
|
1450
|
+
limit: z10.number().optional().default(2e3).describe("Maximum number of lines to read")
|
|
1075
1451
|
})
|
|
1076
1452
|
}
|
|
1077
1453
|
);
|
|
1078
|
-
var writeFile =
|
|
1454
|
+
var writeFile = tool3(
|
|
1079
1455
|
(input, config) => {
|
|
1080
|
-
const state =
|
|
1456
|
+
const state = getCurrentTaskInput6();
|
|
1081
1457
|
const files = { ...state.files || {} };
|
|
1082
1458
|
files[input.file_path] = input.content;
|
|
1083
|
-
return new
|
|
1459
|
+
return new Command5({
|
|
1084
1460
|
update: {
|
|
1085
1461
|
files,
|
|
1086
1462
|
messages: [
|
|
1087
|
-
new
|
|
1463
|
+
new ToolMessage5({
|
|
1088
1464
|
content: `Updated file ${input.file_path}`,
|
|
1089
1465
|
tool_call_id: config.toolCall?.id
|
|
1090
1466
|
})
|
|
@@ -1095,15 +1471,15 @@ var writeFile = tool2(
|
|
|
1095
1471
|
{
|
|
1096
1472
|
name: "write_file",
|
|
1097
1473
|
description: "Write content to a file in the mock filesystem",
|
|
1098
|
-
schema:
|
|
1099
|
-
file_path:
|
|
1100
|
-
content:
|
|
1474
|
+
schema: z10.object({
|
|
1475
|
+
file_path: z10.string().describe("Absolute path to the file to write"),
|
|
1476
|
+
content: z10.string().describe("Content to write to the file")
|
|
1101
1477
|
})
|
|
1102
1478
|
}
|
|
1103
1479
|
);
|
|
1104
|
-
var editFile =
|
|
1480
|
+
var editFile = tool3(
|
|
1105
1481
|
(input, config) => {
|
|
1106
|
-
const state =
|
|
1482
|
+
const state = getCurrentTaskInput6();
|
|
1107
1483
|
const mockFilesystem = { ...state.files || {} };
|
|
1108
1484
|
const { file_path, old_string, new_string, replace_all = false } = input;
|
|
1109
1485
|
if (!(file_path in mockFilesystem)) {
|
|
@@ -1139,11 +1515,11 @@ var editFile = tool2(
|
|
|
1139
1515
|
newContent = content.replace(old_string, new_string);
|
|
1140
1516
|
}
|
|
1141
1517
|
mockFilesystem[file_path] = newContent;
|
|
1142
|
-
return new
|
|
1518
|
+
return new Command5({
|
|
1143
1519
|
update: {
|
|
1144
1520
|
files: mockFilesystem,
|
|
1145
1521
|
messages: [
|
|
1146
|
-
new
|
|
1522
|
+
new ToolMessage5({
|
|
1147
1523
|
content: `Updated file ${file_path}`,
|
|
1148
1524
|
tool_call_id: config.toolCall?.id
|
|
1149
1525
|
})
|
|
@@ -1154,135 +1530,20 @@ var editFile = tool2(
|
|
|
1154
1530
|
{
|
|
1155
1531
|
name: "edit_file",
|
|
1156
1532
|
description: EDIT_DESCRIPTION,
|
|
1157
|
-
schema:
|
|
1158
|
-
file_path:
|
|
1159
|
-
old_string:
|
|
1160
|
-
new_string:
|
|
1161
|
-
replace_all:
|
|
1533
|
+
schema: z10.object({
|
|
1534
|
+
file_path: z10.string().describe("Absolute path to the file to edit"),
|
|
1535
|
+
old_string: z10.string().describe("String to be replaced (must match exactly)"),
|
|
1536
|
+
new_string: z10.string().describe("String to replace with"),
|
|
1537
|
+
replace_all: z10.boolean().optional().default(false).describe("Whether to replace all occurrences")
|
|
1162
1538
|
})
|
|
1163
1539
|
}
|
|
1164
1540
|
);
|
|
1165
1541
|
|
|
1166
|
-
// src/deep_agent/subAgent.ts
|
|
1167
|
-
import {
|
|
1168
|
-
getToolsFromConfig as getToolsFromConfig2,
|
|
1169
|
-
hasTools as hasTools2
|
|
1170
|
-
} from "@axiom-lattice/protocols";
|
|
1171
|
-
var BUILTIN_TOOLS = {
|
|
1172
|
-
write_todos: writeTodos,
|
|
1173
|
-
read_file: readFile,
|
|
1174
|
-
write_file: writeFile,
|
|
1175
|
-
edit_file: editFile,
|
|
1176
|
-
ls
|
|
1177
|
-
};
|
|
1178
|
-
function createTaskTool(inputs) {
|
|
1179
|
-
const {
|
|
1180
|
-
subagents,
|
|
1181
|
-
tools = {},
|
|
1182
|
-
model = getModelLattice("default")?.client,
|
|
1183
|
-
stateSchema,
|
|
1184
|
-
postModelHook
|
|
1185
|
-
} = inputs;
|
|
1186
|
-
if (!model) {
|
|
1187
|
-
throw new Error("Model not found");
|
|
1188
|
-
}
|
|
1189
|
-
const allTools = { ...BUILTIN_TOOLS, ...tools };
|
|
1190
|
-
const agentsMap = /* @__PURE__ */ new Map();
|
|
1191
|
-
for (const subagent of subagents) {
|
|
1192
|
-
let reactAgent;
|
|
1193
|
-
const agentLattice = getAgentLattice(subagent.key);
|
|
1194
|
-
if (agentLattice) {
|
|
1195
|
-
reactAgent = agentLattice.client;
|
|
1196
|
-
} else {
|
|
1197
|
-
const subagentTools = [];
|
|
1198
|
-
if (hasTools2(subagent)) {
|
|
1199
|
-
for (const toolName of getToolsFromConfig2(subagent)) {
|
|
1200
|
-
const resolvedTool = allTools[toolName];
|
|
1201
|
-
if (resolvedTool) {
|
|
1202
|
-
subagentTools.push(resolvedTool);
|
|
1203
|
-
} else {
|
|
1204
|
-
console.warn(
|
|
1205
|
-
`Warning: Tool '${toolName}' not found for agent '${subagent.name}'`
|
|
1206
|
-
);
|
|
1207
|
-
}
|
|
1208
|
-
}
|
|
1209
|
-
} else {
|
|
1210
|
-
subagentTools.push(...Object.values(allTools));
|
|
1211
|
-
}
|
|
1212
|
-
reactAgent = createAgentClientFromAgentLattice({ config: subagent });
|
|
1213
|
-
}
|
|
1214
|
-
agentsMap.set(subagent.name, reactAgent);
|
|
1215
|
-
}
|
|
1216
|
-
return tool3(
|
|
1217
|
-
async (input, config) => {
|
|
1218
|
-
const { description, subagent_type } = input;
|
|
1219
|
-
const reactAgent = agentsMap.get(subagent_type);
|
|
1220
|
-
if (!reactAgent) {
|
|
1221
|
-
return `Error: Agent '${subagent_type}' not found. Available agents: ${Array.from(
|
|
1222
|
-
agentsMap.keys()
|
|
1223
|
-
).join(", ")}`;
|
|
1224
|
-
}
|
|
1225
|
-
try {
|
|
1226
|
-
const currentState = getCurrentTaskInput2();
|
|
1227
|
-
const modifiedState = {
|
|
1228
|
-
...currentState,
|
|
1229
|
-
messages: [
|
|
1230
|
-
{
|
|
1231
|
-
role: "user",
|
|
1232
|
-
content: description
|
|
1233
|
-
}
|
|
1234
|
-
]
|
|
1235
|
-
};
|
|
1236
|
-
const result = await reactAgent.invoke(modifiedState, config);
|
|
1237
|
-
return new Command2({
|
|
1238
|
-
update: {
|
|
1239
|
-
files: result.files || {},
|
|
1240
|
-
messages: [
|
|
1241
|
-
new ToolMessage2({
|
|
1242
|
-
content: result.messages?.slice(-1)[0]?.content || "Task completed",
|
|
1243
|
-
tool_call_id: config.toolCall?.id
|
|
1244
|
-
})
|
|
1245
|
-
]
|
|
1246
|
-
}
|
|
1247
|
-
});
|
|
1248
|
-
} catch (error) {
|
|
1249
|
-
if (error instanceof GraphInterrupt) {
|
|
1250
|
-
throw error;
|
|
1251
|
-
}
|
|
1252
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1253
|
-
return new Command2({
|
|
1254
|
-
update: {
|
|
1255
|
-
messages: [
|
|
1256
|
-
new ToolMessage2({
|
|
1257
|
-
content: `Error executing task '${description}' with agent '${subagent_type}': ${errorMessage}`,
|
|
1258
|
-
tool_call_id: config.toolCall?.id
|
|
1259
|
-
})
|
|
1260
|
-
]
|
|
1261
|
-
}
|
|
1262
|
-
});
|
|
1263
|
-
}
|
|
1264
|
-
},
|
|
1265
|
-
{
|
|
1266
|
-
name: "task",
|
|
1267
|
-
description: TASK_DESCRIPTION_PREFIX.replace(
|
|
1268
|
-
"{other_agents}",
|
|
1269
|
-
subagents.map((a) => `- ${a.name}: ${a.description}`).join("\n")
|
|
1270
|
-
) + TASK_DESCRIPTION_SUFFIX,
|
|
1271
|
-
schema: z5.object({
|
|
1272
|
-
description: z5.string().describe("The task to execute with the selected agent"),
|
|
1273
|
-
subagent_type: z5.string().describe(
|
|
1274
|
-
`Name of the agent to use. Available: ${subagents.map((a) => a.name).join(", ")}`
|
|
1275
|
-
)
|
|
1276
|
-
})
|
|
1277
|
-
}
|
|
1278
|
-
);
|
|
1279
|
-
}
|
|
1280
|
-
|
|
1281
1542
|
// src/deep_agent/state.ts
|
|
1282
1543
|
import "@langchain/langgraph/zod";
|
|
1283
1544
|
import { MessagesZodState as MessagesZodState2 } from "@langchain/langgraph";
|
|
1284
1545
|
import { withLangGraph } from "@langchain/langgraph/zod";
|
|
1285
|
-
import { z as
|
|
1546
|
+
import { z as z11 } from "zod";
|
|
1286
1547
|
function fileReducer(left, right) {
|
|
1287
1548
|
if (left == null) {
|
|
1288
1549
|
return right || {};
|
|
@@ -1299,15 +1560,15 @@ function todoReducer(left, right) {
|
|
|
1299
1560
|
return left || [];
|
|
1300
1561
|
}
|
|
1301
1562
|
var DeepAgentState = MessagesZodState2.extend({
|
|
1302
|
-
todos: withLangGraph(
|
|
1563
|
+
todos: withLangGraph(z11.custom(), {
|
|
1303
1564
|
reducer: {
|
|
1304
|
-
schema:
|
|
1565
|
+
schema: z11.custom(),
|
|
1305
1566
|
fn: todoReducer
|
|
1306
1567
|
}
|
|
1307
1568
|
}),
|
|
1308
|
-
files: withLangGraph(
|
|
1569
|
+
files: withLangGraph(z11.custom(), {
|
|
1309
1570
|
reducer: {
|
|
1310
|
-
schema:
|
|
1571
|
+
schema: z11.custom(),
|
|
1311
1572
|
fn: fileReducer
|
|
1312
1573
|
}
|
|
1313
1574
|
})
|
|
@@ -1326,7 +1587,7 @@ It is critical that you mark todos as completed as soon as you are done with a t
|
|
|
1326
1587
|
## \`task\`
|
|
1327
1588
|
|
|
1328
1589
|
- When doing web search, prefer to use the \`task\` tool in order to reduce context usage.`;
|
|
1329
|
-
var
|
|
1590
|
+
var BUILTIN_TOOLS = [
|
|
1330
1591
|
writeTodos,
|
|
1331
1592
|
readFile,
|
|
1332
1593
|
writeFile,
|
|
@@ -1344,7 +1605,7 @@ function createDeepAgent(params = {}) {
|
|
|
1344
1605
|
throw new Error("Model not found");
|
|
1345
1606
|
}
|
|
1346
1607
|
const stateSchema = params.stateSchema ? DeepAgentState.extend(params.stateSchema.shape) : DeepAgentState;
|
|
1347
|
-
const allTools = [...
|
|
1608
|
+
const allTools = [...BUILTIN_TOOLS, ...tools];
|
|
1348
1609
|
if (subagents.length > 0) {
|
|
1349
1610
|
const toolsMap = {};
|
|
1350
1611
|
for (const tool5 of allTools) {
|
|
@@ -1406,7 +1667,7 @@ import {
|
|
|
1406
1667
|
import {
|
|
1407
1668
|
HumanMessage as HumanMessage2
|
|
1408
1669
|
} from "@langchain/core/messages";
|
|
1409
|
-
import { z as
|
|
1670
|
+
import { z as z12 } from "zod";
|
|
1410
1671
|
|
|
1411
1672
|
// src/logger/Logger.ts
|
|
1412
1673
|
import pino from "pino";
|
|
@@ -1547,14 +1808,14 @@ var Logger = class _Logger {
|
|
|
1547
1808
|
};
|
|
1548
1809
|
|
|
1549
1810
|
// src/util/returnToolResponse.ts
|
|
1550
|
-
import { ToolMessage as
|
|
1811
|
+
import { ToolMessage as ToolMessage6 } from "@langchain/core/messages";
|
|
1551
1812
|
import { v4 } from "uuid";
|
|
1552
1813
|
var returnToolResponse = (config, think) => {
|
|
1553
1814
|
const { think_id = v4(), content, title, status, type, data } = think;
|
|
1554
1815
|
const contents = type ? [title, content, genUIMarkdown(type, data)] : [title, content];
|
|
1555
1816
|
const message = {
|
|
1556
1817
|
messages: [
|
|
1557
|
-
new
|
|
1818
|
+
new ToolMessage6({
|
|
1558
1819
|
content: contents.filter((item) => item).join("\n\n"),
|
|
1559
1820
|
tool_call_id: config.configurable?.run_id + "_tool_" + think_id,
|
|
1560
1821
|
status: status || "success"
|
|
@@ -1649,11 +1910,11 @@ var PlanExecuteState = Annotation.Root({
|
|
|
1649
1910
|
default: () => []
|
|
1650
1911
|
})
|
|
1651
1912
|
});
|
|
1652
|
-
var planSchema =
|
|
1653
|
-
steps:
|
|
1913
|
+
var planSchema = z12.object({
|
|
1914
|
+
steps: z12.array(z12.string()).describe("\u9700\u8981\u6267\u884C\u7684\u6B65\u9AA4\u5217\u8868\uFF0C\u5E94\u6309\u7167\u6267\u884C\u987A\u5E8F\u6392\u5E8F")
|
|
1654
1915
|
});
|
|
1655
|
-
var responseSchema =
|
|
1656
|
-
response:
|
|
1916
|
+
var responseSchema = z12.object({
|
|
1917
|
+
response: z12.string().describe("\u7ED9\u7528\u6237\u7684\u6700\u7EC8\u54CD\u5E94\uFF0C\u5982\u679C\u4E0D\u9700\u8981\u6267\u884C\u6B65\u9AA4\uFF0C\u5219\u8FD4\u56DE\u8FD9\u4E2A\u5B57\u6BB5")
|
|
1657
1918
|
});
|
|
1658
1919
|
function createPlanExecuteAgent(config) {
|
|
1659
1920
|
const {
|