@axiom-lattice/core 2.1.16 → 2.1.17
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.d.mts +158 -2
- package/dist/index.d.ts +158 -2
- package/dist/index.js +1830 -118
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1852 -148
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -3
package/dist/index.mjs
CHANGED
|
@@ -503,6 +503,27 @@ var ToolLatticeManager = class _ToolLatticeManager extends BaseLatticeManager {
|
|
|
503
503
|
getAllToolDefinitions() {
|
|
504
504
|
return this.getAllLattices().map((lattice) => lattice.config);
|
|
505
505
|
}
|
|
506
|
+
/**
|
|
507
|
+
* 注册已有的StructuredTool到Lattice
|
|
508
|
+
* @param key Lattice键名
|
|
509
|
+
* @param tool 已有的StructuredTool实例
|
|
510
|
+
*/
|
|
511
|
+
registerExistingTool(key, tool7) {
|
|
512
|
+
const config = {
|
|
513
|
+
name: tool7.name,
|
|
514
|
+
description: tool7.description,
|
|
515
|
+
schema: tool7.schema,
|
|
516
|
+
// StructuredTool的schema已经是Zod兼容的
|
|
517
|
+
needUserApprove: false
|
|
518
|
+
// MCP工具默认不需要用户批准
|
|
519
|
+
};
|
|
520
|
+
const toolLattice = {
|
|
521
|
+
key,
|
|
522
|
+
config,
|
|
523
|
+
client: tool7
|
|
524
|
+
};
|
|
525
|
+
this.register(key, toolLattice);
|
|
526
|
+
}
|
|
506
527
|
/**
|
|
507
528
|
* 验证工具输入参数
|
|
508
529
|
* @param key Lattice键名
|
|
@@ -525,6 +546,7 @@ var ToolLatticeManager = class _ToolLatticeManager extends BaseLatticeManager {
|
|
|
525
546
|
};
|
|
526
547
|
var toolLatticeManager = ToolLatticeManager.getInstance();
|
|
527
548
|
var registerToolLattice = (key, config, executor) => toolLatticeManager.registerLattice(key, config, executor);
|
|
549
|
+
var registerExistingTool = (key, tool7) => toolLatticeManager.registerExistingTool(key, tool7);
|
|
528
550
|
var getToolLattice = (key) => toolLatticeManager.getToolLattice(key);
|
|
529
551
|
var getToolDefinition = (key) => toolLatticeManager.getToolDefinition(key);
|
|
530
552
|
var getToolClient = (key) => toolLatticeManager.getToolClient(key);
|
|
@@ -1906,88 +1928,1333 @@ storeLatticeManager.registerLattice(
|
|
|
1906
1928
|
"assistant",
|
|
1907
1929
|
defaultAssistantStore
|
|
1908
1930
|
);
|
|
1909
|
-
storeLatticeManager.registerLattice("default", "skill", defaultSkillStore);
|
|
1931
|
+
storeLatticeManager.registerLattice("default", "skill", defaultSkillStore);
|
|
1932
|
+
|
|
1933
|
+
// src/tool_lattice/load_skills/index.ts
|
|
1934
|
+
var LOAD_SKILLS_DESCRIPTION = `Load all available skills and return their metadata (name, description, license, compatibility, metadata, and subSkills) without the content. This tool returns skill information including hierarchical relationships (subSkills). Use this to discover what skills are available and their structure. Skills can have sub-skills, creating a tree structure for organizing capabilities.`;
|
|
1935
|
+
registerToolLattice(
|
|
1936
|
+
"load_skills",
|
|
1937
|
+
{
|
|
1938
|
+
name: "load_skills",
|
|
1939
|
+
description: LOAD_SKILLS_DESCRIPTION,
|
|
1940
|
+
needUserApprove: false,
|
|
1941
|
+
schema: z7.object({})
|
|
1942
|
+
},
|
|
1943
|
+
async () => {
|
|
1944
|
+
try {
|
|
1945
|
+
const storeLattice = getStoreLattice("default", "skill");
|
|
1946
|
+
const skillStore = storeLattice.store;
|
|
1947
|
+
const skills = await skillStore.getAllSkills();
|
|
1948
|
+
const skillsMeta = skills.map((skill) => ({
|
|
1949
|
+
name: skill.name,
|
|
1950
|
+
description: skill.description,
|
|
1951
|
+
license: skill.license,
|
|
1952
|
+
compatibility: skill.compatibility,
|
|
1953
|
+
metadata: skill.metadata,
|
|
1954
|
+
subSkills: skill.subSkills
|
|
1955
|
+
}));
|
|
1956
|
+
return JSON.stringify(skillsMeta, null, 2);
|
|
1957
|
+
} catch (error) {
|
|
1958
|
+
return `Error loading skills: ${error instanceof Error ? error.message : String(error)}`;
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1961
|
+
);
|
|
1962
|
+
|
|
1963
|
+
// src/tool_lattice/load_skill_content/index.ts
|
|
1964
|
+
import z8 from "zod";
|
|
1965
|
+
var LOAD_SKILL_CONTENT_DESCRIPTION = `Load a specific skill's content by name and return its full content including markdown body. This tool returns the complete skill content including frontmatter and markdown body. If the skill has sub-skills defined, they will be listed in the frontmatter. Use this tool to get the complete skill content for a skill that you want to use.`;
|
|
1966
|
+
registerToolLattice(
|
|
1967
|
+
"load_skill_content",
|
|
1968
|
+
{
|
|
1969
|
+
name: "load_skill_content",
|
|
1970
|
+
description: LOAD_SKILL_CONTENT_DESCRIPTION,
|
|
1971
|
+
needUserApprove: false,
|
|
1972
|
+
schema: z8.object({
|
|
1973
|
+
skill_name: z8.string().describe("The name of the skill to load")
|
|
1974
|
+
})
|
|
1975
|
+
},
|
|
1976
|
+
async (input) => {
|
|
1977
|
+
try {
|
|
1978
|
+
const storeLattice = getStoreLattice("default", "skill");
|
|
1979
|
+
const skillStore = storeLattice.store;
|
|
1980
|
+
const skill = await skillStore.getSkillById(input.skill_name);
|
|
1981
|
+
if (!skill) {
|
|
1982
|
+
const allSkills = await skillStore.getAllSkills();
|
|
1983
|
+
const availableSkills = allSkills.map((s) => s.name).join(", ");
|
|
1984
|
+
return `Skill "${input.skill_name}" not found. Available skills: ${availableSkills}`;
|
|
1985
|
+
}
|
|
1986
|
+
const frontmatter = ["---"];
|
|
1987
|
+
frontmatter.push(`name: ${skill.name}`);
|
|
1988
|
+
frontmatter.push(`description: ${skill.description}`);
|
|
1989
|
+
if (skill.license) {
|
|
1990
|
+
frontmatter.push(`license: ${skill.license}`);
|
|
1991
|
+
}
|
|
1992
|
+
if (skill.compatibility) {
|
|
1993
|
+
frontmatter.push(`compatibility: ${skill.compatibility}`);
|
|
1994
|
+
}
|
|
1995
|
+
if (skill.metadata && Object.keys(skill.metadata).length > 0) {
|
|
1996
|
+
frontmatter.push("metadata:");
|
|
1997
|
+
for (const [key, value] of Object.entries(skill.metadata)) {
|
|
1998
|
+
frontmatter.push(` ${key}: ${value}`);
|
|
1999
|
+
}
|
|
2000
|
+
}
|
|
2001
|
+
if (skill.subSkills && skill.subSkills.length > 0) {
|
|
2002
|
+
frontmatter.push("subSkills:");
|
|
2003
|
+
for (const subSkill of skill.subSkills) {
|
|
2004
|
+
frontmatter.push(` - ${subSkill}`);
|
|
2005
|
+
}
|
|
2006
|
+
}
|
|
2007
|
+
frontmatter.push("---");
|
|
2008
|
+
const content = skill.content || "";
|
|
2009
|
+
return `${frontmatter.join("\n")}
|
|
2010
|
+
${content}`;
|
|
2011
|
+
} catch (error) {
|
|
2012
|
+
return `Error loading skill content: ${error instanceof Error ? error.message : String(error)}`;
|
|
2013
|
+
}
|
|
2014
|
+
}
|
|
2015
|
+
);
|
|
2016
|
+
|
|
2017
|
+
// src/tool_lattice/code_eval/index.ts
|
|
2018
|
+
import z9 from "zod";
|
|
2019
|
+
|
|
2020
|
+
// src/sandbox_lattice/SandboxLatticeManager.ts
|
|
2021
|
+
import { SandboxClient } from "@agent-infra/sandbox";
|
|
2022
|
+
|
|
2023
|
+
// src/sandbox_lattice/utils.ts
|
|
2024
|
+
function normalizeSandboxName(name) {
|
|
2025
|
+
if (!name || typeof name !== "string") {
|
|
2026
|
+
throw new Error("Sandbox name must be a non-empty string");
|
|
2027
|
+
}
|
|
2028
|
+
let normalized = name.toLowerCase();
|
|
2029
|
+
normalized = normalized.replace(/_/g, "-");
|
|
2030
|
+
normalized = normalized.replace(/[^a-z0-9.-]/g, "");
|
|
2031
|
+
normalized = normalized.replace(/^[.-]+|[.-]+$/g, "");
|
|
2032
|
+
normalized = normalized.replace(/[.-]{2,}/g, "-");
|
|
2033
|
+
normalized = normalized.replace(/^[.-]+|[.-]+$/g, "");
|
|
2034
|
+
if (!normalized) {
|
|
2035
|
+
throw new Error(
|
|
2036
|
+
`Sandbox name "${name}" cannot be normalized to a valid RFC 1123 subdomain name`
|
|
2037
|
+
);
|
|
2038
|
+
}
|
|
2039
|
+
if (!/^[a-z0-9]/.test(normalized)) {
|
|
2040
|
+
normalized = `sandbox-${normalized}`;
|
|
2041
|
+
}
|
|
2042
|
+
if (!/[a-z0-9]$/.test(normalized)) {
|
|
2043
|
+
normalized = `${normalized}-0`;
|
|
2044
|
+
}
|
|
2045
|
+
const rfc1123Pattern = /^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$/;
|
|
2046
|
+
if (!rfc1123Pattern.test(normalized)) {
|
|
2047
|
+
normalized = normalized.replace(/[^a-z0-9-]/g, "-").replace(/^-+|-+$/g, "").replace(/-{2,}/g, "-");
|
|
2048
|
+
if (!/^[a-z0-9]/.test(normalized)) {
|
|
2049
|
+
normalized = `sandbox-${normalized}`;
|
|
2050
|
+
}
|
|
2051
|
+
if (!/[a-z0-9]$/.test(normalized)) {
|
|
2052
|
+
normalized = `${normalized}0`;
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
return normalized;
|
|
2056
|
+
}
|
|
2057
|
+
function isValidSandboxName(name) {
|
|
2058
|
+
if (!name || typeof name !== "string") {
|
|
2059
|
+
return false;
|
|
2060
|
+
}
|
|
2061
|
+
const rfc1123Pattern = /^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$/;
|
|
2062
|
+
return rfc1123Pattern.test(name.toLowerCase());
|
|
2063
|
+
}
|
|
2064
|
+
|
|
2065
|
+
// src/sandbox_lattice/SandboxLatticeManager.ts
|
|
2066
|
+
var DefaultSandboxManager = class {
|
|
2067
|
+
constructor(baseURL = "http://localhost:8080") {
|
|
2068
|
+
this.sandboxes = /* @__PURE__ */ new Map();
|
|
2069
|
+
/**
|
|
2070
|
+
* Track in-flight sandbox creation promises by normalized sandbox name.
|
|
2071
|
+
* This ensures that concurrent calls with the same name share the same Promise
|
|
2072
|
+
* and we do not trigger multiple creations for the same sandbox.
|
|
2073
|
+
*/
|
|
2074
|
+
this.creatingSandboxes = /* @__PURE__ */ new Map();
|
|
2075
|
+
this.baseURL = baseURL;
|
|
2076
|
+
}
|
|
2077
|
+
async createSandbox(sandboxName) {
|
|
2078
|
+
if (sandboxName === "global") {
|
|
2079
|
+
const client = new SandboxClient({ baseUrl: `${this.baseURL}/sandbox/global`, environment: "" });
|
|
2080
|
+
this.sandboxes.set("global", client);
|
|
2081
|
+
return client;
|
|
2082
|
+
}
|
|
2083
|
+
const normalizedName = normalizeSandboxName(sandboxName);
|
|
2084
|
+
const existingClient = this.sandboxes.get(normalizedName);
|
|
2085
|
+
if (existingClient) {
|
|
2086
|
+
return existingClient;
|
|
2087
|
+
}
|
|
2088
|
+
const inFlight = this.creatingSandboxes.get(normalizedName);
|
|
2089
|
+
if (inFlight) {
|
|
2090
|
+
return inFlight;
|
|
2091
|
+
}
|
|
2092
|
+
const creationPromise = (async () => {
|
|
2093
|
+
const response = await fetch(`${this.baseURL}/api/v1/sandbox`, {
|
|
2094
|
+
method: "POST",
|
|
2095
|
+
headers: {
|
|
2096
|
+
"Content-Type": "application/json"
|
|
2097
|
+
},
|
|
2098
|
+
body: JSON.stringify({
|
|
2099
|
+
name: normalizedName,
|
|
2100
|
+
image: "enterprise-public-cn-beijing.cr.volces.com/vefaas-public/all-in-one-sandbox:latest"
|
|
2101
|
+
})
|
|
2102
|
+
});
|
|
2103
|
+
if (!response.ok) {
|
|
2104
|
+
throw new Error(`Failed to create sandbox: ${response.statusText}`);
|
|
2105
|
+
}
|
|
2106
|
+
const data = await response.json();
|
|
2107
|
+
const sandboxURL = `${this.baseURL}/sandbox/${normalizedName}`;
|
|
2108
|
+
const client = new SandboxClient({ baseUrl: sandboxURL, environment: "" });
|
|
2109
|
+
this.sandboxes.set(normalizedName, client);
|
|
2110
|
+
return client;
|
|
2111
|
+
})();
|
|
2112
|
+
this.creatingSandboxes.set(normalizedName, creationPromise);
|
|
2113
|
+
creationPromise.catch(() => {
|
|
2114
|
+
this.creatingSandboxes.delete(normalizedName);
|
|
2115
|
+
}).then(() => {
|
|
2116
|
+
this.creatingSandboxes.delete(normalizedName);
|
|
2117
|
+
});
|
|
2118
|
+
return creationPromise;
|
|
2119
|
+
}
|
|
2120
|
+
async deleteSandbox(sandboxName) {
|
|
2121
|
+
const normalizedName = normalizeSandboxName(sandboxName);
|
|
2122
|
+
if (!this.sandboxes.has(normalizedName)) {
|
|
2123
|
+
throw new Error(`Sandbox ${sandboxName} (normalized: ${normalizedName}) not found`);
|
|
2124
|
+
}
|
|
2125
|
+
const response = await fetch(`${this.baseURL}/api/v1/sandbox/${normalizedName}`, {
|
|
2126
|
+
method: "DELETE"
|
|
2127
|
+
});
|
|
2128
|
+
if (!response.ok) {
|
|
2129
|
+
throw new Error(`Failed to delete sandbox: ${response.statusText}`);
|
|
2130
|
+
}
|
|
2131
|
+
this.sandboxes.delete(normalizedName);
|
|
2132
|
+
}
|
|
2133
|
+
async getSandbox(sandboxName) {
|
|
2134
|
+
const normalizedName = normalizeSandboxName(sandboxName);
|
|
2135
|
+
const client = this.sandboxes.get(normalizedName);
|
|
2136
|
+
if (!client) {
|
|
2137
|
+
throw new Error(`Sandbox ${sandboxName} (normalized: ${normalizedName}) not found`);
|
|
2138
|
+
}
|
|
2139
|
+
return client;
|
|
2140
|
+
}
|
|
2141
|
+
async listSandboxes() {
|
|
2142
|
+
return Array.from(this.sandboxes.values());
|
|
2143
|
+
}
|
|
2144
|
+
async getSandboxStatus(sandboxName) {
|
|
2145
|
+
const normalizedName = normalizeSandboxName(sandboxName);
|
|
2146
|
+
if (!this.sandboxes.has(normalizedName)) {
|
|
2147
|
+
throw new Error(`Sandbox ${sandboxName} (normalized: ${normalizedName}) not found`);
|
|
2148
|
+
}
|
|
2149
|
+
try {
|
|
2150
|
+
const client = this.sandboxes.get(normalizedName);
|
|
2151
|
+
const context = await client.sandbox.getContext();
|
|
2152
|
+
return context.ok ? "active" : "inactive";
|
|
2153
|
+
} catch {
|
|
2154
|
+
return "unknown";
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
async getSandboxFromConfig(config) {
|
|
2158
|
+
if (config.sandboxConfig.isolatedLevel === "agent") {
|
|
2159
|
+
return this.createSandbox(config.assistant_id);
|
|
2160
|
+
} else if (config.sandboxConfig.isolatedLevel === "thread") {
|
|
2161
|
+
return this.createSandbox(config.thread_id);
|
|
2162
|
+
} else {
|
|
2163
|
+
return this.createSandbox("global");
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2166
|
+
};
|
|
2167
|
+
var SandboxLatticeManager = class _SandboxLatticeManager extends BaseLatticeManager {
|
|
2168
|
+
/**
|
|
2169
|
+
* Get SandboxLatticeManager singleton instance
|
|
2170
|
+
*/
|
|
2171
|
+
static getInstance() {
|
|
2172
|
+
if (!_SandboxLatticeManager._instance) {
|
|
2173
|
+
_SandboxLatticeManager._instance = new _SandboxLatticeManager();
|
|
2174
|
+
}
|
|
2175
|
+
return _SandboxLatticeManager._instance;
|
|
2176
|
+
}
|
|
2177
|
+
/**
|
|
2178
|
+
* Get Lattice type prefix
|
|
2179
|
+
*/
|
|
2180
|
+
getLatticeType() {
|
|
2181
|
+
return "sandbox_manager";
|
|
2182
|
+
}
|
|
2183
|
+
/**
|
|
2184
|
+
* Register sandbox Lattice
|
|
2185
|
+
* @param key Lattice key name
|
|
2186
|
+
* @param manager Optional sandbox manager. If not provided, will create a default one.
|
|
2187
|
+
* @param baseURL Base URL for sandbox service (used when creating default manager)
|
|
2188
|
+
*/
|
|
2189
|
+
registerLattice(key, config) {
|
|
2190
|
+
const { manager, baseURL } = config;
|
|
2191
|
+
const sandboxManager = manager || new DefaultSandboxManager(baseURL);
|
|
2192
|
+
this.register(key, sandboxManager);
|
|
2193
|
+
}
|
|
2194
|
+
/**
|
|
2195
|
+
* Get SandboxLattice
|
|
2196
|
+
* @param key Lattice key name
|
|
2197
|
+
*/
|
|
2198
|
+
getSandboxLattice(key) {
|
|
2199
|
+
const sandboxLattice = this.get(key);
|
|
2200
|
+
if (!sandboxLattice) {
|
|
2201
|
+
throw new Error(`SandboxLattice ${key} not found`);
|
|
2202
|
+
}
|
|
2203
|
+
return sandboxLattice;
|
|
2204
|
+
}
|
|
2205
|
+
/**
|
|
2206
|
+
* Get all Lattices
|
|
2207
|
+
*/
|
|
2208
|
+
getAllLattices() {
|
|
2209
|
+
return this.getAll();
|
|
2210
|
+
}
|
|
2211
|
+
/**
|
|
2212
|
+
* Check if Lattice exists
|
|
2213
|
+
* @param key Lattice key name
|
|
2214
|
+
*/
|
|
2215
|
+
hasLattice(key) {
|
|
2216
|
+
return this.has(key);
|
|
2217
|
+
}
|
|
2218
|
+
/**
|
|
2219
|
+
* Remove Lattice
|
|
2220
|
+
* @param key Lattice key name
|
|
2221
|
+
*/
|
|
2222
|
+
removeLattice(key) {
|
|
2223
|
+
return this.remove(key);
|
|
2224
|
+
}
|
|
2225
|
+
/**
|
|
2226
|
+
* Clear all Lattices
|
|
2227
|
+
*/
|
|
2228
|
+
clearLattices() {
|
|
2229
|
+
this.clear();
|
|
2230
|
+
}
|
|
2231
|
+
/**
|
|
2232
|
+
* Get Lattice count
|
|
2233
|
+
*/
|
|
2234
|
+
getLatticeCount() {
|
|
2235
|
+
return this.count();
|
|
2236
|
+
}
|
|
2237
|
+
/**
|
|
2238
|
+
* Get Lattice key list
|
|
2239
|
+
*/
|
|
2240
|
+
getLatticeKeys() {
|
|
2241
|
+
return this.keys();
|
|
2242
|
+
}
|
|
2243
|
+
};
|
|
2244
|
+
var sandboxLatticeManager = SandboxLatticeManager.getInstance();
|
|
2245
|
+
var getSandBoxManager = (key = "default") => {
|
|
2246
|
+
if (!sandboxLatticeManager.hasLattice(key)) {
|
|
2247
|
+
throw new Error(`Sandbox ${key} not configured. Ensure the sandbox manager is registered and the agent is built with connectedSandbox.`);
|
|
2248
|
+
}
|
|
2249
|
+
const sandboxManager = sandboxLatticeManager.getSandboxLattice(key);
|
|
2250
|
+
return sandboxManager;
|
|
2251
|
+
};
|
|
2252
|
+
|
|
2253
|
+
// src/tool_lattice/code_eval/index.ts
|
|
2254
|
+
var CODE_EVAL_DESCRIPTION = `Execute code in Python or JavaScript runtime.
|
|
2255
|
+
|
|
2256
|
+
Args:
|
|
2257
|
+
code: Code to execute
|
|
2258
|
+
language: Programming language ('python', 'javascript')
|
|
2259
|
+
|
|
2260
|
+
Returns:
|
|
2261
|
+
Dict containing output, errors, and execution details`;
|
|
2262
|
+
registerToolLattice(
|
|
2263
|
+
"execute_code",
|
|
2264
|
+
{
|
|
2265
|
+
name: "execute_code",
|
|
2266
|
+
description: CODE_EVAL_DESCRIPTION,
|
|
2267
|
+
needUserApprove: false,
|
|
2268
|
+
schema: z9.object({
|
|
2269
|
+
language: z9.enum(["python", "javascript"]).describe("Programming language: 'python' or 'javascript'"),
|
|
2270
|
+
code: z9.string().describe("Code to execute")
|
|
2271
|
+
})
|
|
2272
|
+
},
|
|
2273
|
+
async (input, exe_config) => {
|
|
2274
|
+
try {
|
|
2275
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
2276
|
+
const sandboxManager = getSandBoxManager();
|
|
2277
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
2278
|
+
const result = await sandbox.code.executeCode({
|
|
2279
|
+
language: input.language,
|
|
2280
|
+
code: input.code,
|
|
2281
|
+
timeout: 300
|
|
2282
|
+
});
|
|
2283
|
+
if (!result.ok) {
|
|
2284
|
+
const err = result.error;
|
|
2285
|
+
return `Error executing ${input.language} code: ${err?.content?.message + (err?.content?.errors ? `
|
|
2286
|
+
${err?.content?.errors.join("\n")}` : "")}`;
|
|
2287
|
+
}
|
|
2288
|
+
const data = result.body?.data;
|
|
2289
|
+
if (!data) {
|
|
2290
|
+
return "Error: No response data from sandbox code execution.";
|
|
2291
|
+
}
|
|
2292
|
+
const { stdout = "", stderr = "", exit_code, traceback } = data;
|
|
2293
|
+
const parts = [];
|
|
2294
|
+
if (stdout) {
|
|
2295
|
+
parts.push(`stdout:
|
|
2296
|
+
${stdout}`);
|
|
2297
|
+
}
|
|
2298
|
+
if (stderr) {
|
|
2299
|
+
parts.push(`stderr:
|
|
2300
|
+
${stderr}`);
|
|
2301
|
+
}
|
|
2302
|
+
if (traceback && traceback.length > 0) {
|
|
2303
|
+
parts.push(`traceback:
|
|
2304
|
+
${traceback.join("\n")}`);
|
|
2305
|
+
}
|
|
2306
|
+
parts.push(`exit_code: ${exit_code ?? "\u2014"}`);
|
|
2307
|
+
return parts.length > 0 ? parts.join("\n\n") : `exit_code: ${exit_code ?? 0}`;
|
|
2308
|
+
} catch (e) {
|
|
2309
|
+
return `Error: ${e instanceof Error ? e.message : String(e)}`;
|
|
2310
|
+
}
|
|
2311
|
+
}
|
|
2312
|
+
);
|
|
2313
|
+
|
|
2314
|
+
// src/tool_lattice/code_execute_file/index.ts
|
|
2315
|
+
import z10 from "zod";
|
|
2316
|
+
import * as path2 from "path";
|
|
2317
|
+
var CODE_EXECUTE_FILE_DESCRIPTION = `Execute a code file from the sandbox filesystem. Only supports Python (.py) and JavaScript (.js, .mjs) files. Other file types are not supported. The tool reads the file content and executes it in an isolated sandbox environment. Language is automatically inferred from the file extension. Output is returned via stdout; errors appear in stderr and traceback.`;
|
|
2318
|
+
function inferLanguageFromPath(filePath) {
|
|
2319
|
+
const ext = path2.extname(filePath).toLowerCase();
|
|
2320
|
+
if (ext === ".py") {
|
|
2321
|
+
return "python";
|
|
2322
|
+
} else if (ext === ".js" || ext === ".mjs") {
|
|
2323
|
+
return "javascript";
|
|
2324
|
+
}
|
|
2325
|
+
return null;
|
|
2326
|
+
}
|
|
2327
|
+
registerToolLattice(
|
|
2328
|
+
"execute_code_file",
|
|
2329
|
+
{
|
|
2330
|
+
name: "execute_code_file",
|
|
2331
|
+
description: CODE_EXECUTE_FILE_DESCRIPTION,
|
|
2332
|
+
needUserApprove: false,
|
|
2333
|
+
schema: z10.object({
|
|
2334
|
+
file_path: z10.string().describe("Path to the code file to execute (absolute path in sandbox filesystem). Only supports .py (Python) and .js/.mjs (JavaScript) files.")
|
|
2335
|
+
})
|
|
2336
|
+
},
|
|
2337
|
+
async (input, exe_config) => {
|
|
2338
|
+
try {
|
|
2339
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
2340
|
+
const sandboxManager = getSandBoxManager();
|
|
2341
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
2342
|
+
const context = await sandbox.sandbox.getContext();
|
|
2343
|
+
if (!context.ok) {
|
|
2344
|
+
return `Error: ${context.error}`;
|
|
2345
|
+
}
|
|
2346
|
+
const homeDir = context.body?.home_dir;
|
|
2347
|
+
const resolvedFilePath = path2.join(homeDir, input.file_path);
|
|
2348
|
+
const language = inferLanguageFromPath(input.file_path);
|
|
2349
|
+
if (!language) {
|
|
2350
|
+
return `Error: Unsupported file type. This tool only supports Python (.py) and JavaScript (.js, .mjs) files. Other file types cannot be executed.`;
|
|
2351
|
+
}
|
|
2352
|
+
const readResult = await sandbox.file.readFile({
|
|
2353
|
+
file: resolvedFilePath
|
|
2354
|
+
});
|
|
2355
|
+
if (!readResult.ok) {
|
|
2356
|
+
const err = readResult.error;
|
|
2357
|
+
return `Error reading file '${input.file_path}': ${err?.content?.message ?? JSON.stringify(readResult.error)}`;
|
|
2358
|
+
}
|
|
2359
|
+
const fileContent = readResult.body?.data?.content;
|
|
2360
|
+
if (fileContent === void 0 || fileContent === null) {
|
|
2361
|
+
return `Error: File '${input.file_path}' is empty or could not be read.`;
|
|
2362
|
+
}
|
|
2363
|
+
const result = await sandbox.code.executeCode({
|
|
2364
|
+
language,
|
|
2365
|
+
code: fileContent,
|
|
2366
|
+
timeout: 300
|
|
2367
|
+
});
|
|
2368
|
+
if (!result.ok) {
|
|
2369
|
+
const err = result.error;
|
|
2370
|
+
return `Error executing ${language} file '${input.file_path}': ${err?.content?.message ?? JSON.stringify(result.error)}`;
|
|
2371
|
+
}
|
|
2372
|
+
const data = result.body?.data;
|
|
2373
|
+
if (!data) {
|
|
2374
|
+
return "Error: No response data from sandbox code execution.";
|
|
2375
|
+
}
|
|
2376
|
+
const { stdout = "", stderr = "", exit_code, traceback } = data;
|
|
2377
|
+
const parts = [];
|
|
2378
|
+
if (stdout) {
|
|
2379
|
+
parts.push(`stdout:
|
|
2380
|
+
${stdout}`);
|
|
2381
|
+
}
|
|
2382
|
+
if (stderr) {
|
|
2383
|
+
parts.push(`stderr:
|
|
2384
|
+
${stderr}`);
|
|
2385
|
+
}
|
|
2386
|
+
if (traceback && traceback.length > 0) {
|
|
2387
|
+
parts.push(`traceback:
|
|
2388
|
+
${traceback.join("\n")}`);
|
|
2389
|
+
}
|
|
2390
|
+
parts.push(`exit_code: ${exit_code ?? "\u2014"}`);
|
|
2391
|
+
return parts.length > 0 ? parts.join("\n\n") : `exit_code: ${exit_code ?? 0}`;
|
|
2392
|
+
} catch (e) {
|
|
2393
|
+
return `Error: ${e instanceof Error ? e.message : String(e)}`;
|
|
2394
|
+
}
|
|
2395
|
+
}
|
|
2396
|
+
);
|
|
2397
|
+
|
|
2398
|
+
// src/tool_lattice/convert_to_markdown/index.ts
|
|
2399
|
+
import z11 from "zod";
|
|
2400
|
+
var CONVERT_TO_MARKDOWN_DESCRIPTION = `Convert a resource described by an http:, https:, file: or data: URI to markdown.
|
|
2401
|
+
|
|
2402
|
+
Args:
|
|
2403
|
+
uri (str): The URI to convert. Supported schemes:
|
|
2404
|
+
- http:// or https://: Fetch content from URL
|
|
2405
|
+
- file://: Read content from local file
|
|
2406
|
+
- data:: Decode data URI content
|
|
2407
|
+
|
|
2408
|
+
Returns:
|
|
2409
|
+
str: The content converted to markdown format.`;
|
|
2410
|
+
registerToolLattice(
|
|
2411
|
+
"convert_to_markdown",
|
|
2412
|
+
{
|
|
2413
|
+
name: "convert_to_markdown",
|
|
2414
|
+
description: CONVERT_TO_MARKDOWN_DESCRIPTION,
|
|
2415
|
+
needUserApprove: false,
|
|
2416
|
+
schema: z11.object({
|
|
2417
|
+
uri: z11.string().describe("The URI to convert.")
|
|
2418
|
+
})
|
|
2419
|
+
},
|
|
2420
|
+
async (input, exe_config) => {
|
|
2421
|
+
try {
|
|
2422
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
2423
|
+
const sandboxManager = getSandBoxManager();
|
|
2424
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
2425
|
+
sandbox;
|
|
2426
|
+
const result = await sandbox.util.convertToMarkdown({
|
|
2427
|
+
uri: input.uri
|
|
2428
|
+
});
|
|
2429
|
+
if (!result.ok) {
|
|
2430
|
+
return `Error converting to markdown: ${result.error}`;
|
|
2431
|
+
}
|
|
2432
|
+
return result.body.data;
|
|
2433
|
+
} catch (e) {
|
|
2434
|
+
return `Error converting to markdown: ${e instanceof Error ? e.message : String(e)}`;
|
|
2435
|
+
}
|
|
2436
|
+
}
|
|
2437
|
+
);
|
|
2438
|
+
|
|
2439
|
+
// src/tool_lattice/browser/browser_navigate.ts
|
|
2440
|
+
import z12 from "zod";
|
|
2441
|
+
var BROWSER_NAVIGATE_DESCRIPTION = `Navigate to a URL.
|
|
2442
|
+
|
|
2443
|
+
Args:
|
|
2444
|
+
url (str): The URL to navigate to.
|
|
2445
|
+
|
|
2446
|
+
`;
|
|
2447
|
+
registerToolLattice(
|
|
2448
|
+
"browser_navigate",
|
|
2449
|
+
{
|
|
2450
|
+
name: "browser_navigate",
|
|
2451
|
+
description: BROWSER_NAVIGATE_DESCRIPTION,
|
|
2452
|
+
needUserApprove: false,
|
|
2453
|
+
schema: z12.object({
|
|
2454
|
+
url: z12.string().describe("The URL to navigate to.")
|
|
2455
|
+
})
|
|
2456
|
+
},
|
|
2457
|
+
async (input, exe_config) => {
|
|
2458
|
+
try {
|
|
2459
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
2460
|
+
const sandboxManager = getSandBoxManager();
|
|
2461
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
2462
|
+
const result = await sandbox.mcp.executeMcpTool("browser", "browser_navigate", {
|
|
2463
|
+
url: input.url
|
|
2464
|
+
});
|
|
2465
|
+
if (!result.ok) {
|
|
2466
|
+
return `Error navigating to URL: ${JSON.stringify(result.error.content)}`;
|
|
2467
|
+
}
|
|
2468
|
+
return result.body?.data?.content?.map((item) => item.text).join("\n") ?? "Navigated to URL";
|
|
2469
|
+
} catch (e) {
|
|
2470
|
+
return `Error navigating to URL: ${e instanceof Error ? e.message : String(e)}`;
|
|
2471
|
+
}
|
|
2472
|
+
}
|
|
2473
|
+
);
|
|
2474
|
+
|
|
2475
|
+
// src/tool_lattice/browser/get_info.ts
|
|
2476
|
+
var BROWSER_GET_INFO_DESCRIPTION = `Get information about browser, like CDP URL, viewport size, etc.
|
|
2477
|
+
|
|
2478
|
+
Args:
|
|
2479
|
+
request (Dict): The incoming request context.
|
|
2480
|
+
|
|
2481
|
+
Returns:
|
|
2482
|
+
Dict containing browser information including CDP URL, viewport dimensions, and other browser metadata.`;
|
|
2483
|
+
registerToolLattice(
|
|
2484
|
+
"browser_get_info",
|
|
2485
|
+
{
|
|
2486
|
+
name: "browser_get_info",
|
|
2487
|
+
description: BROWSER_GET_INFO_DESCRIPTION,
|
|
2488
|
+
needUserApprove: false
|
|
2489
|
+
},
|
|
2490
|
+
async (input, exe_config) => {
|
|
2491
|
+
try {
|
|
2492
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
2493
|
+
const sandboxManager = getSandBoxManager();
|
|
2494
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
2495
|
+
const result = await sandbox.browser.getInfo();
|
|
2496
|
+
if (!result.ok) {
|
|
2497
|
+
return `Error getting browser info: ${result.error}`;
|
|
2498
|
+
}
|
|
2499
|
+
return JSON.stringify(result.body.data, void 0, 2);
|
|
2500
|
+
} catch (e) {
|
|
2501
|
+
return `Error getting browser info: ${e instanceof Error ? e.message : String(e)}`;
|
|
2502
|
+
}
|
|
2503
|
+
}
|
|
2504
|
+
);
|
|
2505
|
+
|
|
2506
|
+
// src/tool_lattice/browser/browser_go_back.ts
|
|
2507
|
+
import z13 from "zod";
|
|
2508
|
+
var BROWSER_GO_BACK_DESCRIPTION = `Go back to the previous page.
|
|
2509
|
+
|
|
2510
|
+
Args:
|
|
2511
|
+
None
|
|
2512
|
+
|
|
2513
|
+
`;
|
|
2514
|
+
registerToolLattice(
|
|
2515
|
+
"browser_go_back",
|
|
2516
|
+
{
|
|
2517
|
+
name: "browser_go_back",
|
|
2518
|
+
description: BROWSER_GO_BACK_DESCRIPTION,
|
|
2519
|
+
needUserApprove: false,
|
|
2520
|
+
schema: z13.object({})
|
|
2521
|
+
},
|
|
2522
|
+
async (input, exe_config) => {
|
|
2523
|
+
try {
|
|
2524
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
2525
|
+
const sandboxManager = getSandBoxManager();
|
|
2526
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
2527
|
+
const result = await sandbox.mcp.executeMcpTool("browser", "browser_go_back", {});
|
|
2528
|
+
if (!result.ok) {
|
|
2529
|
+
return `Error going back: ${JSON.stringify(result.error.content)}`;
|
|
2530
|
+
}
|
|
2531
|
+
return result.body?.data?.content?.map((item) => item.text).join("\n") ?? "Went back to previous page";
|
|
2532
|
+
} catch (e) {
|
|
2533
|
+
return `Error going back: ${e instanceof Error ? e.message : String(e)}`;
|
|
2534
|
+
}
|
|
2535
|
+
}
|
|
2536
|
+
);
|
|
2537
|
+
|
|
2538
|
+
// src/tool_lattice/browser/browser_go_forward.ts
|
|
2539
|
+
import z14 from "zod";
|
|
2540
|
+
var BROWSER_GO_FORWARD_DESCRIPTION = `Go forward to the next page.
|
|
2541
|
+
|
|
2542
|
+
Args:
|
|
2543
|
+
None
|
|
2544
|
+
|
|
2545
|
+
`;
|
|
2546
|
+
registerToolLattice(
|
|
2547
|
+
"browser_go_forward",
|
|
2548
|
+
{
|
|
2549
|
+
name: "browser_go_forward",
|
|
2550
|
+
description: BROWSER_GO_FORWARD_DESCRIPTION,
|
|
2551
|
+
needUserApprove: false,
|
|
2552
|
+
schema: z14.object({})
|
|
2553
|
+
},
|
|
2554
|
+
async (input, exe_config) => {
|
|
2555
|
+
try {
|
|
2556
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
2557
|
+
const sandboxManager = getSandBoxManager();
|
|
2558
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
2559
|
+
const result = await sandbox.mcp.executeMcpTool("browser", "browser_go_forward", {});
|
|
2560
|
+
if (!result.ok) {
|
|
2561
|
+
return `Error going forward: ${JSON.stringify(result.error.content)}`;
|
|
2562
|
+
}
|
|
2563
|
+
return result.body?.data?.content?.map((item) => item.text).join("\n") ?? "Went forward to next page";
|
|
2564
|
+
} catch (e) {
|
|
2565
|
+
return `Error going forward: ${e instanceof Error ? e.message : String(e)}`;
|
|
2566
|
+
}
|
|
2567
|
+
}
|
|
2568
|
+
);
|
|
2569
|
+
|
|
2570
|
+
// src/tool_lattice/browser/browser_form_input_fill.ts
|
|
2571
|
+
import z15 from "zod";
|
|
2572
|
+
var BROWSER_FORM_INPUT_FILL_DESCRIPTION = `Fill out an input field, before using the tool, Either 'index' or 'selector' must be provided.
|
|
2573
|
+
|
|
2574
|
+
Args:
|
|
2575
|
+
selector (str): CSS selector for input field, priority use index, if index is not provided, use selector
|
|
2576
|
+
index (int): Index of the element to fill
|
|
2577
|
+
value (str): Value to fill
|
|
2578
|
+
clear (bool): Whether to clear existing text before filling
|
|
2579
|
+
|
|
2580
|
+
`;
|
|
2581
|
+
registerToolLattice(
|
|
2582
|
+
"browser_form_input_fill",
|
|
2583
|
+
{
|
|
2584
|
+
name: "browser_form_input_fill",
|
|
2585
|
+
description: BROWSER_FORM_INPUT_FILL_DESCRIPTION,
|
|
2586
|
+
needUserApprove: false,
|
|
2587
|
+
schema: z15.object({
|
|
2588
|
+
selector: z15.string().optional().describe("CSS selector for input field, priority use index, if index is not provided, use selector"),
|
|
2589
|
+
index: z15.number().optional().describe("Index of the element to fill"),
|
|
2590
|
+
value: z15.string().describe("Value to fill"),
|
|
2591
|
+
clear: z15.boolean().default(false).describe("Whether to clear existing text before filling")
|
|
2592
|
+
})
|
|
2593
|
+
},
|
|
2594
|
+
async (input, exe_config) => {
|
|
2595
|
+
try {
|
|
2596
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
2597
|
+
const sandboxManager = getSandBoxManager();
|
|
2598
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
2599
|
+
const result = await sandbox.mcp.executeMcpTool("browser", "browser_form_input_fill", {
|
|
2600
|
+
selector: input.selector,
|
|
2601
|
+
index: input.index,
|
|
2602
|
+
value: input.value,
|
|
2603
|
+
clear: input.clear
|
|
2604
|
+
});
|
|
2605
|
+
if (!result.ok) {
|
|
2606
|
+
return `Error filling input field: ${JSON.stringify(result.error.content)}`;
|
|
2607
|
+
}
|
|
2608
|
+
return result.body?.data?.content?.map((item) => item.text).join("\n") ?? "Input field filled successfully";
|
|
2609
|
+
} catch (e) {
|
|
2610
|
+
return `Error filling input field: ${e instanceof Error ? e.message : String(e)}`;
|
|
2611
|
+
}
|
|
2612
|
+
}
|
|
2613
|
+
);
|
|
2614
|
+
|
|
2615
|
+
// src/tool_lattice/browser/browser_get_markdown.ts
|
|
2616
|
+
import z16 from "zod";
|
|
2617
|
+
var BROWSER_GET_MARKDOWN_DESCRIPTION = `Get the markdown content of the current page.
|
|
2618
|
+
|
|
2619
|
+
Args:
|
|
2620
|
+
None
|
|
2621
|
+
|
|
2622
|
+
`;
|
|
2623
|
+
registerToolLattice(
|
|
2624
|
+
"browser_get_markdown",
|
|
2625
|
+
{
|
|
2626
|
+
name: "browser_get_markdown",
|
|
2627
|
+
description: BROWSER_GET_MARKDOWN_DESCRIPTION,
|
|
2628
|
+
needUserApprove: false,
|
|
2629
|
+
schema: z16.object({})
|
|
2630
|
+
},
|
|
2631
|
+
async (input, exe_config) => {
|
|
2632
|
+
try {
|
|
2633
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
2634
|
+
const sandboxManager = getSandBoxManager();
|
|
2635
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
2636
|
+
const result = await sandbox.mcp.executeMcpTool("browser", "browser_get_markdown", {});
|
|
2637
|
+
if (!result.ok) {
|
|
2638
|
+
return `Error getting markdown content: ${JSON.stringify(result.error.content)}`;
|
|
2639
|
+
}
|
|
2640
|
+
return result.body?.data?.content?.map((item) => item.text).join("\n") ?? "Markdown content retrieved";
|
|
2641
|
+
} catch (e) {
|
|
2642
|
+
return `Error getting markdown content: ${e instanceof Error ? e.message : String(e)}`;
|
|
2643
|
+
}
|
|
2644
|
+
}
|
|
2645
|
+
);
|
|
2646
|
+
|
|
2647
|
+
// src/tool_lattice/browser/browser_get_text.ts
|
|
2648
|
+
import z17 from "zod";
|
|
2649
|
+
var BROWSER_GET_TEXT_DESCRIPTION = `Get the text content of the current page.
|
|
2650
|
+
|
|
2651
|
+
Args:
|
|
2652
|
+
None
|
|
2653
|
+
|
|
2654
|
+
`;
|
|
2655
|
+
registerToolLattice(
|
|
2656
|
+
"browser_get_text",
|
|
2657
|
+
{
|
|
2658
|
+
name: "browser_get_text",
|
|
2659
|
+
description: BROWSER_GET_TEXT_DESCRIPTION,
|
|
2660
|
+
needUserApprove: false,
|
|
2661
|
+
schema: z17.object({})
|
|
2662
|
+
},
|
|
2663
|
+
async (input, exe_config) => {
|
|
2664
|
+
try {
|
|
2665
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
2666
|
+
const sandboxManager = getSandBoxManager();
|
|
2667
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
2668
|
+
const result = await sandbox.mcp.executeMcpTool("browser", "browser_get_text", {});
|
|
2669
|
+
if (!result.ok) {
|
|
2670
|
+
return `Error getting text content: ${JSON.stringify(result.error.content)}`;
|
|
2671
|
+
}
|
|
2672
|
+
return result.body?.data?.content?.map((item) => item.text).join("\n") ?? "Text content retrieved";
|
|
2673
|
+
} catch (e) {
|
|
2674
|
+
return `Error getting text content: ${e instanceof Error ? e.message : String(e)}`;
|
|
2675
|
+
}
|
|
2676
|
+
}
|
|
2677
|
+
);
|
|
2678
|
+
|
|
2679
|
+
// src/tool_lattice/browser/browser_read_links.ts
|
|
2680
|
+
import z18 from "zod";
|
|
2681
|
+
var BROWSER_READ_LINKS_DESCRIPTION = `Get all links on the current page.
|
|
2682
|
+
|
|
2683
|
+
Args:
|
|
2684
|
+
None
|
|
2685
|
+
|
|
2686
|
+
`;
|
|
2687
|
+
registerToolLattice(
|
|
2688
|
+
"browser_read_links",
|
|
2689
|
+
{
|
|
2690
|
+
name: "browser_read_links",
|
|
2691
|
+
description: BROWSER_READ_LINKS_DESCRIPTION,
|
|
2692
|
+
needUserApprove: false,
|
|
2693
|
+
schema: z18.object({})
|
|
2694
|
+
},
|
|
2695
|
+
async (input, exe_config) => {
|
|
2696
|
+
try {
|
|
2697
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
2698
|
+
const sandboxManager = getSandBoxManager();
|
|
2699
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
2700
|
+
const result = await sandbox.mcp.executeMcpTool("browser", "browser_read_links", {});
|
|
2701
|
+
if (!result.ok) {
|
|
2702
|
+
return `Error reading links: ${JSON.stringify(result.error.content)}`;
|
|
2703
|
+
}
|
|
2704
|
+
return result.body?.data?.content?.map((item) => item.text).join("\n") ?? "Links retrieved successfully";
|
|
2705
|
+
} catch (e) {
|
|
2706
|
+
return `Error reading links: ${e instanceof Error ? e.message : String(e)}`;
|
|
2707
|
+
}
|
|
2708
|
+
}
|
|
2709
|
+
);
|
|
2710
|
+
|
|
2711
|
+
// src/tool_lattice/browser/browser_new_tab.ts
|
|
2712
|
+
import z19 from "zod";
|
|
2713
|
+
var BROWSER_NEW_TAB_DESCRIPTION = `Open a new tab.
|
|
2714
|
+
|
|
2715
|
+
Args:
|
|
2716
|
+
url (str): URL to open in the new tab
|
|
2717
|
+
|
|
2718
|
+
`;
|
|
2719
|
+
registerToolLattice(
|
|
2720
|
+
"browser_new_tab",
|
|
2721
|
+
{
|
|
2722
|
+
name: "browser_new_tab",
|
|
2723
|
+
description: BROWSER_NEW_TAB_DESCRIPTION,
|
|
2724
|
+
needUserApprove: false,
|
|
2725
|
+
schema: z19.object({
|
|
2726
|
+
url: z19.string().describe("URL to open in the new tab")
|
|
2727
|
+
})
|
|
2728
|
+
},
|
|
2729
|
+
async (input, exe_config) => {
|
|
2730
|
+
try {
|
|
2731
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
2732
|
+
const sandboxManager = getSandBoxManager();
|
|
2733
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
2734
|
+
const result = await sandbox.mcp.executeMcpTool("browser", "browser_new_tab", {
|
|
2735
|
+
url: input.url
|
|
2736
|
+
});
|
|
2737
|
+
if (!result.ok) {
|
|
2738
|
+
return `Error opening new tab: ${JSON.stringify(result.error.content)}`;
|
|
2739
|
+
}
|
|
2740
|
+
return result.body?.data?.content?.map((item) => item.text).join("\n") ?? "New tab opened successfully";
|
|
2741
|
+
} catch (e) {
|
|
2742
|
+
return `Error opening new tab: ${e instanceof Error ? e.message : String(e)}`;
|
|
2743
|
+
}
|
|
2744
|
+
}
|
|
2745
|
+
);
|
|
2746
|
+
|
|
2747
|
+
// src/tool_lattice/browser/browser_tab_list.ts
|
|
2748
|
+
import z20 from "zod";
|
|
2749
|
+
var BROWSER_TAB_LIST_DESCRIPTION = `Get the list of tabs.
|
|
2750
|
+
|
|
2751
|
+
Args:
|
|
2752
|
+
None
|
|
2753
|
+
|
|
2754
|
+
`;
|
|
2755
|
+
registerToolLattice(
|
|
2756
|
+
"browser_tab_list",
|
|
2757
|
+
{
|
|
2758
|
+
name: "browser_tab_list",
|
|
2759
|
+
description: BROWSER_TAB_LIST_DESCRIPTION,
|
|
2760
|
+
needUserApprove: false,
|
|
2761
|
+
schema: z20.object({})
|
|
2762
|
+
},
|
|
2763
|
+
async (input, exe_config) => {
|
|
2764
|
+
try {
|
|
2765
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
2766
|
+
const sandboxManager = getSandBoxManager();
|
|
2767
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
2768
|
+
const result = await sandbox.mcp.executeMcpTool("browser", "browser_tab_list", {});
|
|
2769
|
+
if (!result.ok) {
|
|
2770
|
+
return `Error getting tab list: ${JSON.stringify(result.error.content)}`;
|
|
2771
|
+
}
|
|
2772
|
+
return result.body?.data?.content?.map((item) => item.text).join("\n") ?? "Tab list retrieved successfully";
|
|
2773
|
+
} catch (e) {
|
|
2774
|
+
return `Error getting tab list: ${e instanceof Error ? e.message : String(e)}`;
|
|
2775
|
+
}
|
|
2776
|
+
}
|
|
2777
|
+
);
|
|
2778
|
+
|
|
2779
|
+
// src/tool_lattice/browser/browser_switch_tab.ts
|
|
2780
|
+
import z21 from "zod";
|
|
2781
|
+
var BROWSER_SWITCH_TAB_DESCRIPTION = `Switch to a specific tab.
|
|
2782
|
+
|
|
2783
|
+
Args:
|
|
2784
|
+
index (int): Tab index to switch to
|
|
2785
|
+
|
|
2786
|
+
`;
|
|
2787
|
+
registerToolLattice(
|
|
2788
|
+
"browser_switch_tab",
|
|
2789
|
+
{
|
|
2790
|
+
name: "browser_switch_tab",
|
|
2791
|
+
description: BROWSER_SWITCH_TAB_DESCRIPTION,
|
|
2792
|
+
needUserApprove: false,
|
|
2793
|
+
schema: z21.object({
|
|
2794
|
+
index: z21.number().describe("Tab index to switch to")
|
|
2795
|
+
})
|
|
2796
|
+
},
|
|
2797
|
+
async (input, exe_config) => {
|
|
2798
|
+
try {
|
|
2799
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
2800
|
+
const sandboxManager = getSandBoxManager();
|
|
2801
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
2802
|
+
const result = await sandbox.mcp.executeMcpTool("browser", "browser_switch_tab", {
|
|
2803
|
+
index: input.index
|
|
2804
|
+
});
|
|
2805
|
+
if (!result.ok) {
|
|
2806
|
+
return `Error switching tab: ${JSON.stringify(result.error.content)}`;
|
|
2807
|
+
}
|
|
2808
|
+
return result.body?.data?.content?.map((item) => item.text).join("\n") ?? "Tab switched successfully";
|
|
2809
|
+
} catch (e) {
|
|
2810
|
+
return `Error switching tab: ${e instanceof Error ? e.message : String(e)}`;
|
|
2811
|
+
}
|
|
2812
|
+
}
|
|
2813
|
+
);
|
|
2814
|
+
|
|
2815
|
+
// src/tool_lattice/browser/browser_close_tab.ts
|
|
2816
|
+
import z22 from "zod";
|
|
2817
|
+
var BROWSER_CLOSE_TAB_DESCRIPTION = `Close the current tab.
|
|
2818
|
+
|
|
2819
|
+
Args:
|
|
2820
|
+
None
|
|
2821
|
+
|
|
2822
|
+
`;
|
|
2823
|
+
registerToolLattice(
|
|
2824
|
+
"browser_close_tab",
|
|
2825
|
+
{
|
|
2826
|
+
name: "browser_close_tab",
|
|
2827
|
+
description: BROWSER_CLOSE_TAB_DESCRIPTION,
|
|
2828
|
+
needUserApprove: false,
|
|
2829
|
+
schema: z22.object({})
|
|
2830
|
+
},
|
|
2831
|
+
async (input, exe_config) => {
|
|
2832
|
+
try {
|
|
2833
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
2834
|
+
const sandboxManager = getSandBoxManager();
|
|
2835
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
2836
|
+
const result = await sandbox.mcp.executeMcpTool("browser", "browser_close_tab", {});
|
|
2837
|
+
if (!result.ok) {
|
|
2838
|
+
return `Error closing tab: ${JSON.stringify(result.error.content)}`;
|
|
2839
|
+
}
|
|
2840
|
+
return result.body?.data?.content?.map((item) => item.text).join("\n") ?? "Current tab closed successfully";
|
|
2841
|
+
} catch (e) {
|
|
2842
|
+
return `Error closing tab: ${e instanceof Error ? e.message : String(e)}`;
|
|
2843
|
+
}
|
|
2844
|
+
}
|
|
2845
|
+
);
|
|
2846
|
+
|
|
2847
|
+
// src/tool_lattice/browser/browser_evaluate.ts
|
|
2848
|
+
import z23 from "zod";
|
|
2849
|
+
var BROWSER_EVALUATE_DESCRIPTION = `Execute JavaScript in the browser console.
|
|
2850
|
+
|
|
2851
|
+
Args:
|
|
2852
|
+
script (str): JavaScript code to execute, () => { /* code */ }
|
|
2853
|
+
|
|
2854
|
+
`;
|
|
2855
|
+
registerToolLattice(
|
|
2856
|
+
"browser_evaluate",
|
|
2857
|
+
{
|
|
2858
|
+
name: "browser_evaluate",
|
|
2859
|
+
description: BROWSER_EVALUATE_DESCRIPTION,
|
|
2860
|
+
needUserApprove: false,
|
|
2861
|
+
schema: z23.object({
|
|
2862
|
+
script: z23.string().describe("JavaScript code to execute, () => { /* code */ }")
|
|
2863
|
+
})
|
|
2864
|
+
},
|
|
2865
|
+
async (input, exe_config) => {
|
|
2866
|
+
try {
|
|
2867
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
2868
|
+
const sandboxManager = getSandBoxManager();
|
|
2869
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
2870
|
+
const result = await sandbox.mcp.executeMcpTool("browser", "browser_evaluate", {
|
|
2871
|
+
script: input.script
|
|
2872
|
+
});
|
|
2873
|
+
if (!result.ok) {
|
|
2874
|
+
return `Error executing JavaScript: ${JSON.stringify(result.error.content)}`;
|
|
2875
|
+
}
|
|
2876
|
+
return result.body?.data?.content?.map((item) => item.text).join("\n") ?? "JavaScript executed successfully";
|
|
2877
|
+
} catch (e) {
|
|
2878
|
+
return `Error executing JavaScript: ${e instanceof Error ? e.message : String(e)}`;
|
|
2879
|
+
}
|
|
2880
|
+
}
|
|
2881
|
+
);
|
|
2882
|
+
|
|
2883
|
+
// src/tool_lattice/browser/browser_get_download_list.ts
|
|
2884
|
+
import z24 from "zod";
|
|
2885
|
+
var BROWSER_GET_DOWNLOAD_LIST_DESCRIPTION = `Get the list of downloaded files.
|
|
2886
|
+
|
|
2887
|
+
Args:
|
|
2888
|
+
None
|
|
2889
|
+
|
|
2890
|
+
`;
|
|
2891
|
+
registerToolLattice(
|
|
2892
|
+
"browser_get_download_list",
|
|
2893
|
+
{
|
|
2894
|
+
name: "browser_get_download_list",
|
|
2895
|
+
description: BROWSER_GET_DOWNLOAD_LIST_DESCRIPTION,
|
|
2896
|
+
needUserApprove: false,
|
|
2897
|
+
schema: z24.object({})
|
|
2898
|
+
},
|
|
2899
|
+
async (input, exe_config) => {
|
|
2900
|
+
try {
|
|
2901
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
2902
|
+
const sandboxManager = getSandBoxManager();
|
|
2903
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
2904
|
+
const result = await sandbox.mcp.executeMcpTool("browser", "browser_get_download_list", {});
|
|
2905
|
+
if (!result.ok) {
|
|
2906
|
+
return `Error getting download list: ${JSON.stringify(result.error.content)}`;
|
|
2907
|
+
}
|
|
2908
|
+
return result.body?.data?.content?.map((item) => item.text).join("\n") ?? "Download list retrieved successfully";
|
|
2909
|
+
} catch (e) {
|
|
2910
|
+
return `Error getting download list: ${e instanceof Error ? e.message : String(e)}`;
|
|
2911
|
+
}
|
|
2912
|
+
}
|
|
2913
|
+
);
|
|
2914
|
+
|
|
2915
|
+
// src/tool_lattice/browser/browser_screenshot.ts
|
|
2916
|
+
import z25 from "zod";
|
|
2917
|
+
var BROWSER_SCREENSHOT_DESCRIPTION = `Take a screenshot of the current page or a specific element.
|
|
2918
|
+
|
|
2919
|
+
Args:
|
|
2920
|
+
name (str): Name for the screenshot
|
|
2921
|
+
selector (str): CSS selector for element to screenshot
|
|
2922
|
+
index (int): index of the element to screenshot
|
|
2923
|
+
width (int): Width in pixels (default: viewport width)
|
|
2924
|
+
height (int): Height in pixels (default: viewport height)
|
|
2925
|
+
fullPage (bool): Full page screenshot (default: false)
|
|
2926
|
+
highlight (bool): Highlight the element
|
|
2927
|
+
|
|
2928
|
+
`;
|
|
2929
|
+
registerToolLattice(
|
|
2930
|
+
"browser_screenshot",
|
|
2931
|
+
{
|
|
2932
|
+
name: "browser_screenshot",
|
|
2933
|
+
description: BROWSER_SCREENSHOT_DESCRIPTION,
|
|
2934
|
+
needUserApprove: false,
|
|
2935
|
+
schema: z25.object({
|
|
2936
|
+
name: z25.string().optional().describe("Name for the screenshot"),
|
|
2937
|
+
selector: z25.string().optional().describe("CSS selector for element to screenshot"),
|
|
2938
|
+
index: z25.number().optional().describe("index of the element to screenshot"),
|
|
2939
|
+
width: z25.number().optional().describe("Width in pixels (default: viewport width)"),
|
|
2940
|
+
height: z25.number().optional().describe("Height in pixels (default: viewport height)"),
|
|
2941
|
+
fullPage: z25.boolean().optional().describe("Full page screenshot (default: false)"),
|
|
2942
|
+
highlight: z25.boolean().default(false).describe("Highlight the element")
|
|
2943
|
+
})
|
|
2944
|
+
},
|
|
2945
|
+
async (input, exe_config) => {
|
|
2946
|
+
try {
|
|
2947
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
2948
|
+
const sandboxManager = getSandBoxManager();
|
|
2949
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
2950
|
+
const result = await sandbox.mcp.executeMcpTool("browser", "browser_screenshot", {
|
|
2951
|
+
name: input.name,
|
|
2952
|
+
selector: input.selector,
|
|
2953
|
+
index: input.index,
|
|
2954
|
+
width: input.width,
|
|
2955
|
+
height: input.height,
|
|
2956
|
+
fullPage: input.fullPage,
|
|
2957
|
+
highlight: input.highlight
|
|
2958
|
+
});
|
|
2959
|
+
if (!result.ok) {
|
|
2960
|
+
return `Error taking screenshot: ${JSON.stringify(result.error.content)}`;
|
|
2961
|
+
}
|
|
2962
|
+
return result.body?.data?.content?.map((item) => item.text).join("\n") ?? "Screenshot taken successfully";
|
|
2963
|
+
} catch (e) {
|
|
2964
|
+
return `Error taking screenshot: ${e instanceof Error ? e.message : String(e)}`;
|
|
2965
|
+
}
|
|
2966
|
+
}
|
|
2967
|
+
);
|
|
2968
|
+
|
|
2969
|
+
// src/tool_lattice/browser/browser_click.ts
|
|
2970
|
+
import z26 from "zod";
|
|
2971
|
+
var BROWSER_CLICK_DESCRIPTION = `Click an element on the page, before using the tool, use \`browser_get_clickable_elements\` to get the index of the element, but not call \`browser_get_clickable_elements\` multiple times.
|
|
2972
|
+
|
|
2973
|
+
Args:
|
|
2974
|
+
index (int): Index of the element to click
|
|
2975
|
+
|
|
2976
|
+
`;
|
|
2977
|
+
registerToolLattice(
|
|
2978
|
+
"browser_click",
|
|
2979
|
+
{
|
|
2980
|
+
name: "browser_click",
|
|
2981
|
+
description: BROWSER_CLICK_DESCRIPTION,
|
|
2982
|
+
needUserApprove: false,
|
|
2983
|
+
schema: z26.object({
|
|
2984
|
+
index: z26.number().describe("Index of the element to click")
|
|
2985
|
+
})
|
|
2986
|
+
},
|
|
2987
|
+
async (input, exe_config) => {
|
|
2988
|
+
try {
|
|
2989
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
2990
|
+
const sandboxManager = getSandBoxManager();
|
|
2991
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
2992
|
+
const result = await sandbox.mcp.executeMcpTool("browser", "browser_click", {
|
|
2993
|
+
index: input.index
|
|
2994
|
+
});
|
|
2995
|
+
if (!result.ok) {
|
|
2996
|
+
return `Error clicking element: ${JSON.stringify(result.error.content)}`;
|
|
2997
|
+
}
|
|
2998
|
+
return result.body?.data?.content?.map((item) => item.text).join("\n") ?? "Element clicked successfully";
|
|
2999
|
+
} catch (e) {
|
|
3000
|
+
return `Error clicking element: ${e instanceof Error ? e.message : String(e)}`;
|
|
3001
|
+
}
|
|
3002
|
+
}
|
|
3003
|
+
);
|
|
3004
|
+
|
|
3005
|
+
// src/tool_lattice/browser/browser_select.ts
|
|
3006
|
+
import z27 from "zod";
|
|
3007
|
+
var BROWSER_SELECT_DESCRIPTION = `Select an element on the page with index, Either 'index' or 'selector' must be provided.
|
|
3008
|
+
|
|
3009
|
+
Args:
|
|
3010
|
+
index (int): Index of the element to select
|
|
3011
|
+
selector (str): CSS selector for element to select
|
|
3012
|
+
value (str): Value to select
|
|
3013
|
+
|
|
3014
|
+
`;
|
|
3015
|
+
registerToolLattice(
|
|
3016
|
+
"browser_select",
|
|
3017
|
+
{
|
|
3018
|
+
name: "browser_select",
|
|
3019
|
+
description: BROWSER_SELECT_DESCRIPTION,
|
|
3020
|
+
needUserApprove: false,
|
|
3021
|
+
schema: z27.object({
|
|
3022
|
+
index: z27.number().optional().describe("Index of the element to select"),
|
|
3023
|
+
selector: z27.string().optional().describe("CSS selector for element to select"),
|
|
3024
|
+
value: z27.string().describe("Value to select")
|
|
3025
|
+
})
|
|
3026
|
+
},
|
|
3027
|
+
async (input, exe_config) => {
|
|
3028
|
+
try {
|
|
3029
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
3030
|
+
const sandboxManager = getSandBoxManager();
|
|
3031
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
3032
|
+
const result = await sandbox.mcp.executeMcpTool("browser", "browser_select", {
|
|
3033
|
+
index: input.index,
|
|
3034
|
+
selector: input.selector,
|
|
3035
|
+
value: input.value
|
|
3036
|
+
});
|
|
3037
|
+
if (!result.ok) {
|
|
3038
|
+
return `Error selecting element: ${JSON.stringify(result.error.content)}`;
|
|
3039
|
+
}
|
|
3040
|
+
return result.body?.data?.content?.map((item) => item.text).join("\n") ?? "Element selected successfully";
|
|
3041
|
+
} catch (e) {
|
|
3042
|
+
return `Error selecting element: ${e instanceof Error ? e.message : String(e)}`;
|
|
3043
|
+
}
|
|
3044
|
+
}
|
|
3045
|
+
);
|
|
3046
|
+
|
|
3047
|
+
// src/tool_lattice/browser/browser_hover.ts
|
|
3048
|
+
import z28 from "zod";
|
|
3049
|
+
var BROWSER_HOVER_DESCRIPTION = `Hover an element on the page, Either 'index' or 'selector' must be provided.
|
|
3050
|
+
|
|
3051
|
+
Args:
|
|
3052
|
+
index (int): Index of the element to hover
|
|
3053
|
+
selector (str): CSS selector for element to hover
|
|
3054
|
+
|
|
3055
|
+
`;
|
|
3056
|
+
registerToolLattice(
|
|
3057
|
+
"browser_hover",
|
|
3058
|
+
{
|
|
3059
|
+
name: "browser_hover",
|
|
3060
|
+
description: BROWSER_HOVER_DESCRIPTION,
|
|
3061
|
+
needUserApprove: false,
|
|
3062
|
+
schema: z28.object({
|
|
3063
|
+
index: z28.number().optional().describe("Index of the element to hover"),
|
|
3064
|
+
selector: z28.string().optional().describe("CSS selector for element to hover")
|
|
3065
|
+
})
|
|
3066
|
+
},
|
|
3067
|
+
async (input, exe_config) => {
|
|
3068
|
+
try {
|
|
3069
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
3070
|
+
const sandboxManager = getSandBoxManager();
|
|
3071
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
3072
|
+
const result = await sandbox.mcp.executeMcpTool("browser", "browser_hover", {
|
|
3073
|
+
index: input.index,
|
|
3074
|
+
selector: input.selector
|
|
3075
|
+
});
|
|
3076
|
+
if (!result.ok) {
|
|
3077
|
+
return `Error hovering element: ${JSON.stringify(result.error.content)}`;
|
|
3078
|
+
}
|
|
3079
|
+
return result.body?.data?.content?.map((item) => item.text).join("\n") ?? "Element hovered successfully";
|
|
3080
|
+
} catch (e) {
|
|
3081
|
+
return `Error hovering element: ${e instanceof Error ? e.message : String(e)}`;
|
|
3082
|
+
}
|
|
3083
|
+
}
|
|
3084
|
+
);
|
|
1910
3085
|
|
|
1911
|
-
// src/tool_lattice/
|
|
1912
|
-
|
|
3086
|
+
// src/tool_lattice/browser/browser_get_clickable_elements.ts
|
|
3087
|
+
import z29 from "zod";
|
|
3088
|
+
var BROWSER_GET_CLICKABLE_ELEMENTS_DESCRIPTION = `Get the clickable or hoverable or selectable elements on the current page, don't call this tool multiple times.
|
|
3089
|
+
|
|
3090
|
+
Args:
|
|
3091
|
+
None
|
|
3092
|
+
|
|
3093
|
+
`;
|
|
1913
3094
|
registerToolLattice(
|
|
1914
|
-
"
|
|
3095
|
+
"browser_get_clickable_elements",
|
|
1915
3096
|
{
|
|
1916
|
-
name: "
|
|
1917
|
-
description:
|
|
3097
|
+
name: "browser_get_clickable_elements",
|
|
3098
|
+
description: BROWSER_GET_CLICKABLE_ELEMENTS_DESCRIPTION,
|
|
1918
3099
|
needUserApprove: false,
|
|
1919
|
-
schema:
|
|
3100
|
+
schema: z29.object({})
|
|
1920
3101
|
},
|
|
1921
|
-
async () => {
|
|
3102
|
+
async (input, exe_config) => {
|
|
1922
3103
|
try {
|
|
1923
|
-
const
|
|
1924
|
-
const
|
|
1925
|
-
const
|
|
1926
|
-
const
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
}));
|
|
1934
|
-
return JSON.stringify(skillsMeta, null, 2);
|
|
1935
|
-
} catch (error) {
|
|
1936
|
-
return `Error loading skills: ${error instanceof Error ? error.message : String(error)}`;
|
|
3104
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
3105
|
+
const sandboxManager = getSandBoxManager();
|
|
3106
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
3107
|
+
const result = await sandbox.mcp.executeMcpTool("browser", "browser_get_clickable_elements", {});
|
|
3108
|
+
if (!result.ok) {
|
|
3109
|
+
return `Error getting clickable elements: ${JSON.stringify(result.error.content)}`;
|
|
3110
|
+
}
|
|
3111
|
+
return result.body?.data?.content?.map((item) => item.text).join("\n") ?? "Clickable elements retrieved successfully";
|
|
3112
|
+
} catch (e) {
|
|
3113
|
+
return `Error getting clickable elements: ${e instanceof Error ? e.message : String(e)}`;
|
|
1937
3114
|
}
|
|
1938
3115
|
}
|
|
1939
3116
|
);
|
|
1940
3117
|
|
|
1941
|
-
// src/tool_lattice/
|
|
1942
|
-
import
|
|
1943
|
-
var
|
|
3118
|
+
// src/tool_lattice/browser/browser_scroll.ts
|
|
3119
|
+
import z30 from "zod";
|
|
3120
|
+
var BROWSER_SCROLL_DESCRIPTION = `Scroll the page.
|
|
3121
|
+
|
|
3122
|
+
Args:
|
|
3123
|
+
amount (int): Pixels to scroll (positive for down, negative for up), if the amount is not provided, scroll to the bottom of the page
|
|
3124
|
+
|
|
3125
|
+
`;
|
|
1944
3126
|
registerToolLattice(
|
|
1945
|
-
"
|
|
3127
|
+
"browser_scroll",
|
|
1946
3128
|
{
|
|
1947
|
-
name: "
|
|
1948
|
-
description:
|
|
3129
|
+
name: "browser_scroll",
|
|
3130
|
+
description: BROWSER_SCROLL_DESCRIPTION,
|
|
1949
3131
|
needUserApprove: false,
|
|
1950
|
-
schema:
|
|
1951
|
-
|
|
3132
|
+
schema: z30.object({
|
|
3133
|
+
amount: z30.number().optional().describe("Pixels to scroll (positive for down, negative for up), if the amount is not provided, scroll to the bottom of the page")
|
|
1952
3134
|
})
|
|
1953
3135
|
},
|
|
1954
|
-
async (input) => {
|
|
3136
|
+
async (input, exe_config) => {
|
|
1955
3137
|
try {
|
|
1956
|
-
const
|
|
1957
|
-
const
|
|
1958
|
-
const
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
const frontmatter = ["---"];
|
|
1965
|
-
frontmatter.push(`name: ${skill.name}`);
|
|
1966
|
-
frontmatter.push(`description: ${skill.description}`);
|
|
1967
|
-
if (skill.license) {
|
|
1968
|
-
frontmatter.push(`license: ${skill.license}`);
|
|
1969
|
-
}
|
|
1970
|
-
if (skill.compatibility) {
|
|
1971
|
-
frontmatter.push(`compatibility: ${skill.compatibility}`);
|
|
3138
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
3139
|
+
const sandboxManager = getSandBoxManager();
|
|
3140
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
3141
|
+
const result = await sandbox.mcp.executeMcpTool("browser", "browser_scroll", {
|
|
3142
|
+
amount: input.amount
|
|
3143
|
+
});
|
|
3144
|
+
if (!result.ok) {
|
|
3145
|
+
return `Error scrolling page: ${JSON.stringify(result.error.content)}`;
|
|
1972
3146
|
}
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
3147
|
+
return result.body?.data?.content?.map((item) => item.text).join("\n") ?? "Page scrolled successfully";
|
|
3148
|
+
} catch (e) {
|
|
3149
|
+
return `Error scrolling page: ${e instanceof Error ? e.message : String(e)}`;
|
|
3150
|
+
}
|
|
3151
|
+
}
|
|
3152
|
+
);
|
|
3153
|
+
|
|
3154
|
+
// src/tool_lattice/browser/browser_close.ts
|
|
3155
|
+
import z31 from "zod";
|
|
3156
|
+
var BROWSER_CLOSE_DESCRIPTION = `Close the browser when the task is done and the browser is not needed anymore.
|
|
3157
|
+
|
|
3158
|
+
Args:
|
|
3159
|
+
None
|
|
3160
|
+
|
|
3161
|
+
`;
|
|
3162
|
+
registerToolLattice(
|
|
3163
|
+
"browser_close",
|
|
3164
|
+
{
|
|
3165
|
+
name: "browser_close",
|
|
3166
|
+
description: BROWSER_CLOSE_DESCRIPTION,
|
|
3167
|
+
needUserApprove: false,
|
|
3168
|
+
schema: z31.object({})
|
|
3169
|
+
},
|
|
3170
|
+
async (input, exe_config) => {
|
|
3171
|
+
try {
|
|
3172
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
3173
|
+
const sandboxManager = getSandBoxManager();
|
|
3174
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
3175
|
+
const result = await sandbox.mcp.executeMcpTool("browser", "browser_close", {});
|
|
3176
|
+
if (!result.ok) {
|
|
3177
|
+
return `Error closing browser: ${JSON.stringify(result.error.content)}`;
|
|
1978
3178
|
}
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
3179
|
+
return result.body?.data?.content?.map((item) => item.text).join("\n") ?? "Browser closed successfully";
|
|
3180
|
+
} catch (e) {
|
|
3181
|
+
return `Error closing browser: ${e instanceof Error ? e.message : String(e)}`;
|
|
3182
|
+
}
|
|
3183
|
+
}
|
|
3184
|
+
);
|
|
3185
|
+
|
|
3186
|
+
// src/tool_lattice/browser/browser_press_key.ts
|
|
3187
|
+
import z32 from "zod";
|
|
3188
|
+
var BROWSER_PRESS_KEY_DESCRIPTION = `Press a key on the keyboard.
|
|
3189
|
+
|
|
3190
|
+
Args:
|
|
3191
|
+
key (str): Name of the key to press or a character to generate, such as Enter, Tab, Escape, Backspace, Delete, Insert, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, ArrowLeft, ArrowRight, ArrowUp, ArrowDown, PageUp, PageDown, Home, End, ShiftLeft, ShiftRight, ControlLeft, ControlRight, AltLeft, AltRight, MetaLeft, MetaRight, CapsLock, PrintScreen, ScrollLock, Pause, ContextMenu
|
|
3192
|
+
|
|
3193
|
+
`;
|
|
3194
|
+
registerToolLattice(
|
|
3195
|
+
"browser_press_key",
|
|
3196
|
+
{
|
|
3197
|
+
name: "browser_press_key",
|
|
3198
|
+
description: BROWSER_PRESS_KEY_DESCRIPTION,
|
|
3199
|
+
needUserApprove: false,
|
|
3200
|
+
schema: z32.object({
|
|
3201
|
+
key: z32.enum([
|
|
3202
|
+
"Enter",
|
|
3203
|
+
"Tab",
|
|
3204
|
+
"Escape",
|
|
3205
|
+
"Backspace",
|
|
3206
|
+
"Delete",
|
|
3207
|
+
"Insert",
|
|
3208
|
+
"F1",
|
|
3209
|
+
"F2",
|
|
3210
|
+
"F3",
|
|
3211
|
+
"F4",
|
|
3212
|
+
"F5",
|
|
3213
|
+
"F6",
|
|
3214
|
+
"F7",
|
|
3215
|
+
"F8",
|
|
3216
|
+
"F9",
|
|
3217
|
+
"F10",
|
|
3218
|
+
"F11",
|
|
3219
|
+
"F12",
|
|
3220
|
+
"ArrowLeft",
|
|
3221
|
+
"ArrowRight",
|
|
3222
|
+
"ArrowUp",
|
|
3223
|
+
"ArrowDown",
|
|
3224
|
+
"PageUp",
|
|
3225
|
+
"PageDown",
|
|
3226
|
+
"Home",
|
|
3227
|
+
"End",
|
|
3228
|
+
"ShiftLeft",
|
|
3229
|
+
"ShiftRight",
|
|
3230
|
+
"ControlLeft",
|
|
3231
|
+
"ControlRight",
|
|
3232
|
+
"AltLeft",
|
|
3233
|
+
"AltRight",
|
|
3234
|
+
"MetaLeft",
|
|
3235
|
+
"MetaRight",
|
|
3236
|
+
"CapsLock",
|
|
3237
|
+
"PrintScreen",
|
|
3238
|
+
"ScrollLock",
|
|
3239
|
+
"Pause",
|
|
3240
|
+
"ContextMenu"
|
|
3241
|
+
]).describe("Name of the key to press or a character to generate, such as Enter, Tab, Escape, Backspace, Delete, Insert, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, ArrowLeft, ArrowRight, ArrowUp, ArrowDown, PageUp, PageDown, Home, End, ShiftLeft, ShiftRight, ControlLeft, ControlRight, AltLeft, AltRight, MetaLeft, MetaRight, CapsLock, PrintScreen, ScrollLock, Pause, ContextMenu")
|
|
3242
|
+
})
|
|
3243
|
+
},
|
|
3244
|
+
async (input, exe_config) => {
|
|
3245
|
+
try {
|
|
3246
|
+
const runConfig = exe_config.configurable?.runConfig;
|
|
3247
|
+
const sandboxManager = getSandBoxManager();
|
|
3248
|
+
const sandbox = await sandboxManager.getSandboxFromConfig(runConfig);
|
|
3249
|
+
const result = await sandbox.mcp.executeMcpTool("browser", "browser_press_key", {
|
|
3250
|
+
key: input.key
|
|
3251
|
+
});
|
|
3252
|
+
if (!result.ok) {
|
|
3253
|
+
return `Error pressing key: ${JSON.stringify(result.error.content)}`;
|
|
1984
3254
|
}
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
return
|
|
1988
|
-
${content}`;
|
|
1989
|
-
} catch (error) {
|
|
1990
|
-
return `Error loading skill content: ${error instanceof Error ? error.message : String(error)}`;
|
|
3255
|
+
return result.body?.data?.content?.map((item) => item.text).join("\n") ?? `Key ${input.key} pressed successfully`;
|
|
3256
|
+
} catch (e) {
|
|
3257
|
+
return `Error pressing key: ${e instanceof Error ? e.message : String(e)}`;
|
|
1991
3258
|
}
|
|
1992
3259
|
}
|
|
1993
3260
|
);
|
|
@@ -2105,9 +3372,9 @@ var ReActAgentGraphBuilder = class {
|
|
|
2105
3372
|
*/
|
|
2106
3373
|
build(agentLattice, params) {
|
|
2107
3374
|
const tools = params.tools.map((t) => {
|
|
2108
|
-
const
|
|
2109
|
-
return
|
|
2110
|
-
}).filter((
|
|
3375
|
+
const tool7 = getToolClient(t.key);
|
|
3376
|
+
return tool7;
|
|
3377
|
+
}).filter((tool7) => tool7 !== void 0);
|
|
2111
3378
|
const stateSchema2 = createReactAgentSchema(params.stateSchema);
|
|
2112
3379
|
return createAgent({
|
|
2113
3380
|
model: params.model,
|
|
@@ -2131,7 +3398,7 @@ import {
|
|
|
2131
3398
|
// src/deep_agent_new/middleware/fs.ts
|
|
2132
3399
|
import { createMiddleware, tool as tool2, ToolMessage } from "langchain";
|
|
2133
3400
|
import { Command, isCommand, getCurrentTaskInput } from "@langchain/langgraph";
|
|
2134
|
-
import { z as
|
|
3401
|
+
import { z as z33 } from "zod/v3";
|
|
2135
3402
|
import { withLangGraph } from "@langchain/langgraph/zod";
|
|
2136
3403
|
|
|
2137
3404
|
// src/deep_agent_new/backends/utils.ts
|
|
@@ -2235,8 +3502,8 @@ function performStringReplacement(content, oldString, newString, replaceAll) {
|
|
|
2235
3502
|
const newContent = content.split(oldString).join(newString);
|
|
2236
3503
|
return [newContent, occurrences];
|
|
2237
3504
|
}
|
|
2238
|
-
function validatePath(
|
|
2239
|
-
const pathStr =
|
|
3505
|
+
function validatePath(path4) {
|
|
3506
|
+
const pathStr = path4 || "/";
|
|
2240
3507
|
if (!pathStr || pathStr.trim() === "") {
|
|
2241
3508
|
throw new Error("Path cannot be empty");
|
|
2242
3509
|
}
|
|
@@ -2246,10 +3513,10 @@ function validatePath(path2) {
|
|
|
2246
3513
|
}
|
|
2247
3514
|
return normalized;
|
|
2248
3515
|
}
|
|
2249
|
-
function globSearchFiles(files, pattern,
|
|
3516
|
+
function globSearchFiles(files, pattern, path4 = "/") {
|
|
2250
3517
|
let normalizedPath;
|
|
2251
3518
|
try {
|
|
2252
|
-
normalizedPath = validatePath(
|
|
3519
|
+
normalizedPath = validatePath(path4);
|
|
2253
3520
|
} catch {
|
|
2254
3521
|
return "No files found";
|
|
2255
3522
|
}
|
|
@@ -2259,15 +3526,15 @@ function globSearchFiles(files, pattern, path2 = "/") {
|
|
|
2259
3526
|
const effectivePattern = pattern;
|
|
2260
3527
|
const matches = [];
|
|
2261
3528
|
for (const [filePath, fileData] of Object.entries(filtered)) {
|
|
2262
|
-
let
|
|
2263
|
-
if (
|
|
2264
|
-
|
|
3529
|
+
let relative2 = filePath.substring(normalizedPath.length);
|
|
3530
|
+
if (relative2.startsWith("/")) {
|
|
3531
|
+
relative2 = relative2.substring(1);
|
|
2265
3532
|
}
|
|
2266
|
-
if (!
|
|
3533
|
+
if (!relative2) {
|
|
2267
3534
|
const parts = filePath.split("/");
|
|
2268
|
-
|
|
3535
|
+
relative2 = parts[parts.length - 1] || "";
|
|
2269
3536
|
}
|
|
2270
|
-
if (micromatch.isMatch(
|
|
3537
|
+
if (micromatch.isMatch(relative2, effectivePattern, {
|
|
2271
3538
|
dot: true,
|
|
2272
3539
|
nobrace: false
|
|
2273
3540
|
})) {
|
|
@@ -2280,7 +3547,7 @@ function globSearchFiles(files, pattern, path2 = "/") {
|
|
|
2280
3547
|
}
|
|
2281
3548
|
return matches.map(([fp]) => fp).join("\n");
|
|
2282
3549
|
}
|
|
2283
|
-
function grepMatchesFromFiles(files, pattern,
|
|
3550
|
+
function grepMatchesFromFiles(files, pattern, path4 = null, glob = null) {
|
|
2284
3551
|
let regex;
|
|
2285
3552
|
try {
|
|
2286
3553
|
regex = new RegExp(pattern);
|
|
@@ -2289,7 +3556,7 @@ function grepMatchesFromFiles(files, pattern, path2 = null, glob = null) {
|
|
|
2289
3556
|
}
|
|
2290
3557
|
let normalizedPath;
|
|
2291
3558
|
try {
|
|
2292
|
-
normalizedPath = validatePath(
|
|
3559
|
+
normalizedPath = validatePath(path4);
|
|
2293
3560
|
} catch {
|
|
2294
3561
|
return [];
|
|
2295
3562
|
}
|
|
@@ -2334,18 +3601,18 @@ var StateBackend = class {
|
|
|
2334
3601
|
* @returns List of FileInfo objects for files and directories directly in the directory.
|
|
2335
3602
|
* Directories have a trailing / in their path and is_dir=true.
|
|
2336
3603
|
*/
|
|
2337
|
-
lsInfo(
|
|
3604
|
+
lsInfo(path4) {
|
|
2338
3605
|
const files = this.getFiles();
|
|
2339
3606
|
const infos = [];
|
|
2340
3607
|
const subdirs = /* @__PURE__ */ new Set();
|
|
2341
|
-
const normalizedPath =
|
|
3608
|
+
const normalizedPath = path4.endsWith("/") ? path4 : path4 + "/";
|
|
2342
3609
|
for (const [k, fd] of Object.entries(files)) {
|
|
2343
3610
|
if (!k.startsWith(normalizedPath)) {
|
|
2344
3611
|
continue;
|
|
2345
3612
|
}
|
|
2346
|
-
const
|
|
2347
|
-
if (
|
|
2348
|
-
const subdirName =
|
|
3613
|
+
const relative2 = k.substring(normalizedPath.length);
|
|
3614
|
+
if (relative2.includes("/")) {
|
|
3615
|
+
const subdirName = relative2.split("/")[0];
|
|
2349
3616
|
subdirs.add(normalizedPath + subdirName + "/");
|
|
2350
3617
|
continue;
|
|
2351
3618
|
}
|
|
@@ -2444,16 +3711,16 @@ var StateBackend = class {
|
|
|
2444
3711
|
/**
|
|
2445
3712
|
* Structured search results or error string for invalid input.
|
|
2446
3713
|
*/
|
|
2447
|
-
grepRaw(pattern,
|
|
3714
|
+
grepRaw(pattern, path4 = "/", glob = null) {
|
|
2448
3715
|
const files = this.getFiles();
|
|
2449
|
-
return grepMatchesFromFiles(files, pattern,
|
|
3716
|
+
return grepMatchesFromFiles(files, pattern, path4, glob);
|
|
2450
3717
|
}
|
|
2451
3718
|
/**
|
|
2452
3719
|
* Structured glob matching returning FileInfo objects.
|
|
2453
3720
|
*/
|
|
2454
|
-
globInfo(pattern,
|
|
3721
|
+
globInfo(pattern, path4 = "/") {
|
|
2455
3722
|
const files = this.getFiles();
|
|
2456
|
-
const result = globSearchFiles(files, pattern,
|
|
3723
|
+
const result = globSearchFiles(files, pattern, path4);
|
|
2457
3724
|
if (result === "No files found") {
|
|
2458
3725
|
return [];
|
|
2459
3726
|
}
|
|
@@ -2474,10 +3741,10 @@ var StateBackend = class {
|
|
|
2474
3741
|
};
|
|
2475
3742
|
|
|
2476
3743
|
// src/deep_agent_new/middleware/fs.ts
|
|
2477
|
-
var FileDataSchema =
|
|
2478
|
-
content:
|
|
2479
|
-
created_at:
|
|
2480
|
-
modified_at:
|
|
3744
|
+
var FileDataSchema = z33.object({
|
|
3745
|
+
content: z33.array(z33.string()),
|
|
3746
|
+
created_at: z33.string(),
|
|
3747
|
+
modified_at: z33.string()
|
|
2481
3748
|
});
|
|
2482
3749
|
function fileDataReducer(left, right) {
|
|
2483
3750
|
if (left === void 0) {
|
|
@@ -2499,20 +3766,20 @@ function fileDataReducer(left, right) {
|
|
|
2499
3766
|
}
|
|
2500
3767
|
return result;
|
|
2501
3768
|
}
|
|
2502
|
-
var FilesystemStateSchema =
|
|
3769
|
+
var FilesystemStateSchema = z33.object({
|
|
2503
3770
|
files: withLangGraph(
|
|
2504
|
-
|
|
3771
|
+
z33.record(z33.string(), FileDataSchema).default({}),
|
|
2505
3772
|
{
|
|
2506
3773
|
reducer: {
|
|
2507
3774
|
fn: fileDataReducer,
|
|
2508
|
-
schema:
|
|
3775
|
+
schema: z33.record(z33.string(), FileDataSchema.nullable())
|
|
2509
3776
|
}
|
|
2510
3777
|
}
|
|
2511
3778
|
)
|
|
2512
3779
|
});
|
|
2513
|
-
function getBackend(backend, stateAndStore) {
|
|
3780
|
+
async function getBackend(backend, stateAndStore) {
|
|
2514
3781
|
if (typeof backend === "function") {
|
|
2515
|
-
return backend(stateAndStore);
|
|
3782
|
+
return await backend(stateAndStore);
|
|
2516
3783
|
}
|
|
2517
3784
|
return backend;
|
|
2518
3785
|
}
|
|
@@ -2538,11 +3805,11 @@ function createLsTool(backend, options) {
|
|
|
2538
3805
|
state: getCurrentTaskInput(config),
|
|
2539
3806
|
store: config.store
|
|
2540
3807
|
};
|
|
2541
|
-
const resolvedBackend = getBackend(backend, stateAndStore);
|
|
2542
|
-
const
|
|
2543
|
-
const infos = await resolvedBackend.lsInfo(
|
|
3808
|
+
const resolvedBackend = await getBackend(backend, stateAndStore);
|
|
3809
|
+
const path4 = input.path || "/";
|
|
3810
|
+
const infos = await resolvedBackend.lsInfo(path4);
|
|
2544
3811
|
if (infos.length === 0) {
|
|
2545
|
-
return `No files found in ${
|
|
3812
|
+
return `No files found in ${path4}`;
|
|
2546
3813
|
}
|
|
2547
3814
|
const lines = [];
|
|
2548
3815
|
for (const info of infos) {
|
|
@@ -2558,8 +3825,8 @@ function createLsTool(backend, options) {
|
|
|
2558
3825
|
{
|
|
2559
3826
|
name: "ls",
|
|
2560
3827
|
description: customDescription || LS_TOOL_DESCRIPTION,
|
|
2561
|
-
schema:
|
|
2562
|
-
path:
|
|
3828
|
+
schema: z33.object({
|
|
3829
|
+
path: z33.string().optional().default("/").describe("Directory path to list (default: /)")
|
|
2563
3830
|
})
|
|
2564
3831
|
}
|
|
2565
3832
|
);
|
|
@@ -2572,17 +3839,17 @@ function createReadFileTool(backend, options) {
|
|
|
2572
3839
|
state: getCurrentTaskInput(config),
|
|
2573
3840
|
store: config.store
|
|
2574
3841
|
};
|
|
2575
|
-
const resolvedBackend = getBackend(backend, stateAndStore);
|
|
3842
|
+
const resolvedBackend = await getBackend(backend, stateAndStore);
|
|
2576
3843
|
const { file_path, offset = 0, limit = 2e3 } = input;
|
|
2577
3844
|
return await resolvedBackend.read(file_path, offset, limit);
|
|
2578
3845
|
},
|
|
2579
3846
|
{
|
|
2580
3847
|
name: "read_file",
|
|
2581
3848
|
description: customDescription || READ_FILE_TOOL_DESCRIPTION,
|
|
2582
|
-
schema:
|
|
2583
|
-
file_path:
|
|
2584
|
-
offset:
|
|
2585
|
-
limit:
|
|
3849
|
+
schema: z33.object({
|
|
3850
|
+
file_path: z33.string().describe("Absolute path to the file to read"),
|
|
3851
|
+
offset: z33.number({ coerce: true }).optional().default(0).describe("Line offset to start reading from (0-indexed)"),
|
|
3852
|
+
limit: z33.number({ coerce: true }).optional().default(2e3).describe("Maximum number of lines to read")
|
|
2586
3853
|
})
|
|
2587
3854
|
}
|
|
2588
3855
|
);
|
|
@@ -2595,7 +3862,7 @@ function createWriteFileTool(backend, options) {
|
|
|
2595
3862
|
state: getCurrentTaskInput(config),
|
|
2596
3863
|
store: config.store
|
|
2597
3864
|
};
|
|
2598
|
-
const resolvedBackend = getBackend(backend, stateAndStore);
|
|
3865
|
+
const resolvedBackend = await getBackend(backend, stateAndStore);
|
|
2599
3866
|
const { file_path, content } = input;
|
|
2600
3867
|
const result = await resolvedBackend.write(file_path, content);
|
|
2601
3868
|
if (result.error) {
|
|
@@ -2617,9 +3884,9 @@ function createWriteFileTool(backend, options) {
|
|
|
2617
3884
|
{
|
|
2618
3885
|
name: "write_file",
|
|
2619
3886
|
description: customDescription || WRITE_FILE_TOOL_DESCRIPTION,
|
|
2620
|
-
schema:
|
|
2621
|
-
file_path:
|
|
2622
|
-
content:
|
|
3887
|
+
schema: z33.object({
|
|
3888
|
+
file_path: z33.string().describe("Absolute path to the file to write"),
|
|
3889
|
+
content: z33.string().describe("Content to write to the file")
|
|
2623
3890
|
})
|
|
2624
3891
|
}
|
|
2625
3892
|
);
|
|
@@ -2632,7 +3899,7 @@ function createEditFileTool(backend, options) {
|
|
|
2632
3899
|
state: getCurrentTaskInput(config),
|
|
2633
3900
|
store: config.store
|
|
2634
3901
|
};
|
|
2635
|
-
const resolvedBackend = getBackend(backend, stateAndStore);
|
|
3902
|
+
const resolvedBackend = await getBackend(backend, stateAndStore);
|
|
2636
3903
|
const { file_path, old_string, new_string, replace_all = false } = input;
|
|
2637
3904
|
const result = await resolvedBackend.edit(
|
|
2638
3905
|
file_path,
|
|
@@ -2659,11 +3926,11 @@ function createEditFileTool(backend, options) {
|
|
|
2659
3926
|
{
|
|
2660
3927
|
name: "edit_file",
|
|
2661
3928
|
description: customDescription || EDIT_FILE_TOOL_DESCRIPTION,
|
|
2662
|
-
schema:
|
|
2663
|
-
file_path:
|
|
2664
|
-
old_string:
|
|
2665
|
-
new_string:
|
|
2666
|
-
replace_all:
|
|
3929
|
+
schema: z33.object({
|
|
3930
|
+
file_path: z33.string().describe("Absolute path to the file to edit"),
|
|
3931
|
+
old_string: z33.string().describe("String to be replaced (must match exactly)"),
|
|
3932
|
+
new_string: z33.string().describe("String to replace with"),
|
|
3933
|
+
replace_all: z33.boolean().optional().default(false).describe("Whether to replace all occurrences")
|
|
2667
3934
|
})
|
|
2668
3935
|
}
|
|
2669
3936
|
);
|
|
@@ -2676,9 +3943,9 @@ function createGlobTool(backend, options) {
|
|
|
2676
3943
|
state: getCurrentTaskInput(config),
|
|
2677
3944
|
store: config.store
|
|
2678
3945
|
};
|
|
2679
|
-
const resolvedBackend = getBackend(backend, stateAndStore);
|
|
2680
|
-
const { pattern, path:
|
|
2681
|
-
const infos = await resolvedBackend.globInfo(pattern,
|
|
3946
|
+
const resolvedBackend = await getBackend(backend, stateAndStore);
|
|
3947
|
+
const { pattern, path: path4 = "/" } = input;
|
|
3948
|
+
const infos = await resolvedBackend.globInfo(pattern, path4);
|
|
2682
3949
|
if (infos.length === 0) {
|
|
2683
3950
|
return `No files found matching pattern '${pattern}'`;
|
|
2684
3951
|
}
|
|
@@ -2687,9 +3954,9 @@ function createGlobTool(backend, options) {
|
|
|
2687
3954
|
{
|
|
2688
3955
|
name: "glob",
|
|
2689
3956
|
description: customDescription || GLOB_TOOL_DESCRIPTION,
|
|
2690
|
-
schema:
|
|
2691
|
-
pattern:
|
|
2692
|
-
path:
|
|
3957
|
+
schema: z33.object({
|
|
3958
|
+
pattern: z33.string().describe("Glob pattern (e.g., '*.py', '**/*.ts')"),
|
|
3959
|
+
path: z33.string().optional().default("/").describe("Base path to search from (default: /)")
|
|
2693
3960
|
})
|
|
2694
3961
|
}
|
|
2695
3962
|
);
|
|
@@ -2702,9 +3969,9 @@ function createGrepTool(backend, options) {
|
|
|
2702
3969
|
state: getCurrentTaskInput(config),
|
|
2703
3970
|
store: config.store
|
|
2704
3971
|
};
|
|
2705
|
-
const resolvedBackend = getBackend(backend, stateAndStore);
|
|
2706
|
-
const { pattern, path:
|
|
2707
|
-
const result = await resolvedBackend.grepRaw(pattern,
|
|
3972
|
+
const resolvedBackend = await getBackend(backend, stateAndStore);
|
|
3973
|
+
const { pattern, path: path4 = "/", glob = null } = input;
|
|
3974
|
+
const result = await resolvedBackend.grepRaw(pattern, path4, glob);
|
|
2708
3975
|
if (typeof result === "string") {
|
|
2709
3976
|
return result;
|
|
2710
3977
|
}
|
|
@@ -2726,17 +3993,17 @@ ${currentFile}:`);
|
|
|
2726
3993
|
{
|
|
2727
3994
|
name: "grep",
|
|
2728
3995
|
description: customDescription || GREP_TOOL_DESCRIPTION,
|
|
2729
|
-
schema:
|
|
2730
|
-
pattern:
|
|
2731
|
-
path:
|
|
2732
|
-
glob:
|
|
3996
|
+
schema: z33.object({
|
|
3997
|
+
pattern: z33.string().describe("Regex pattern to search for"),
|
|
3998
|
+
path: z33.string().optional().default("/").describe("Base path to search from (default: /)"),
|
|
3999
|
+
glob: z33.string().optional().nullable().describe("Optional glob pattern to filter files (e.g., '*.py')")
|
|
2733
4000
|
})
|
|
2734
4001
|
}
|
|
2735
4002
|
);
|
|
2736
4003
|
}
|
|
2737
4004
|
function createFilesystemMiddleware(options = {}) {
|
|
2738
4005
|
const {
|
|
2739
|
-
backend = (stateAndStore) => new StateBackend(stateAndStore),
|
|
4006
|
+
backend = async (stateAndStore) => new StateBackend(stateAndStore),
|
|
2740
4007
|
systemPrompt: customSystemPrompt = null,
|
|
2741
4008
|
customToolDescriptions = null,
|
|
2742
4009
|
toolTokenLimitBeforeEvict = 2e4
|
|
@@ -2781,7 +4048,7 @@ ${systemPrompt}` : systemPrompt;
|
|
|
2781
4048
|
state: request.state || {},
|
|
2782
4049
|
store: request.config?.store
|
|
2783
4050
|
};
|
|
2784
|
-
const resolvedBackend = getBackend(backend, stateAndStore);
|
|
4051
|
+
const resolvedBackend = await getBackend(backend, stateAndStore);
|
|
2785
4052
|
const sanitizedId = sanitizeToolCallId(
|
|
2786
4053
|
request.toolCall?.id || msg.tool_call_id
|
|
2787
4054
|
);
|
|
@@ -2857,7 +4124,7 @@ ${systemPrompt}` : systemPrompt;
|
|
|
2857
4124
|
}
|
|
2858
4125
|
|
|
2859
4126
|
// src/deep_agent_new/middleware/subagents.ts
|
|
2860
|
-
import { z as
|
|
4127
|
+
import { z as z34 } from "zod/v3";
|
|
2861
4128
|
import {
|
|
2862
4129
|
createMiddleware as createMiddleware2,
|
|
2863
4130
|
createAgent as createAgent2,
|
|
@@ -3534,9 +4801,9 @@ function createTaskTool(options) {
|
|
|
3534
4801
|
{
|
|
3535
4802
|
name: "task",
|
|
3536
4803
|
description: finalTaskDescription,
|
|
3537
|
-
schema:
|
|
3538
|
-
description:
|
|
3539
|
-
subagent_type:
|
|
4804
|
+
schema: z34.object({
|
|
4805
|
+
description: z34.string().describe("The task to execute with the selected agent"),
|
|
4806
|
+
subagent_type: z34.string().describe(
|
|
3540
4807
|
`Name of the agent to use. Available: ${Object.keys(
|
|
3541
4808
|
subagentGraphs
|
|
3542
4809
|
).join(", ")}`
|
|
@@ -3640,7 +4907,7 @@ var SUPPORTS_NOFOLLOW = fsSync.constants.O_NOFOLLOW !== void 0;
|
|
|
3640
4907
|
|
|
3641
4908
|
// src/deep_agent_new/middleware/todos.ts
|
|
3642
4909
|
import { Command as Command3 } from "@langchain/langgraph";
|
|
3643
|
-
import { z as
|
|
4910
|
+
import { z as z35 } from "zod";
|
|
3644
4911
|
import { createMiddleware as createMiddleware4, tool as tool4, ToolMessage as ToolMessage4 } from "langchain";
|
|
3645
4912
|
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.
|
|
3646
4913
|
It also helps the user understand the progress of the task and overall progress of their requests.
|
|
@@ -3868,12 +5135,12 @@ Writing todos takes time and tokens, use it when it is helpful for managing comp
|
|
|
3868
5135
|
## Important To-Do List Usage Notes to Remember
|
|
3869
5136
|
- The \`write_todos\` tool should never be called multiple times in parallel.
|
|
3870
5137
|
- Don't be afraid to revise the To-Do list as you go. New information may reveal new tasks that need to be done, or old tasks that are irrelevant.`;
|
|
3871
|
-
var TodoStatus =
|
|
3872
|
-
var TodoSchema =
|
|
3873
|
-
content:
|
|
5138
|
+
var TodoStatus = z35.enum(["pending", "in_progress", "completed"]).describe("Status of the todo");
|
|
5139
|
+
var TodoSchema = z35.object({
|
|
5140
|
+
content: z35.string().describe("Content of the todo item"),
|
|
3874
5141
|
status: TodoStatus
|
|
3875
5142
|
});
|
|
3876
|
-
var stateSchema =
|
|
5143
|
+
var stateSchema = z35.object({ todos: z35.array(TodoSchema).default([]) });
|
|
3877
5144
|
function todoListMiddleware(options) {
|
|
3878
5145
|
const writeTodos = tool4(
|
|
3879
5146
|
({ todos }, config) => {
|
|
@@ -3892,8 +5159,8 @@ function todoListMiddleware(options) {
|
|
|
3892
5159
|
{
|
|
3893
5160
|
name: "write_todos",
|
|
3894
5161
|
description: options?.toolDescription ?? WRITE_TODOS_DESCRIPTION,
|
|
3895
|
-
schema:
|
|
3896
|
-
todos:
|
|
5162
|
+
schema: z35.object({
|
|
5163
|
+
todos: z35.array(TodoSchema).describe("List of todo items to update")
|
|
3897
5164
|
})
|
|
3898
5165
|
}
|
|
3899
5166
|
);
|
|
@@ -3981,7 +5248,7 @@ function createDeepAgent(params = {}) {
|
|
|
3981
5248
|
const finalSystemPrompt = systemPrompt ? `${systemPrompt}
|
|
3982
5249
|
|
|
3983
5250
|
${BASE_PROMPT}` : BASE_PROMPT;
|
|
3984
|
-
const filesystemBackend = backend ? backend : (config) => new StateBackend(config);
|
|
5251
|
+
const filesystemBackend = backend ? backend : async (config) => new StateBackend(config);
|
|
3985
5252
|
const middleware = [
|
|
3986
5253
|
// Provides todo list management capabilities for tracking tasks
|
|
3987
5254
|
todoListMiddleware(),
|
|
@@ -4046,6 +5313,303 @@ ${BASE_PROMPT}` : BASE_PROMPT;
|
|
|
4046
5313
|
});
|
|
4047
5314
|
}
|
|
4048
5315
|
|
|
5316
|
+
// src/deep_agent_new/backends/sandboxFiles.ts
|
|
5317
|
+
import { SandboxClient as SandboxClient2 } from "@agent-infra/sandbox";
|
|
5318
|
+
import * as path3 from "path";
|
|
5319
|
+
var SandboxFilesystem = class {
|
|
5320
|
+
/**
|
|
5321
|
+
* Create a new SandboxFilesystem instance.
|
|
5322
|
+
*
|
|
5323
|
+
* @param options - Configuration options
|
|
5324
|
+
* @param options.baseURL - Base URL of the sandbox service (default: 'http://localhost:8080')
|
|
5325
|
+
* @param options.maxFileSizeMb - Maximum file size in MB (default: 10)
|
|
5326
|
+
* @param options.sandboxInstance - Optional Sandbox instance (if provided, baseURL is ignored)
|
|
5327
|
+
*/
|
|
5328
|
+
constructor(options = {}) {
|
|
5329
|
+
const {
|
|
5330
|
+
baseURL = "http://localhost:8080",
|
|
5331
|
+
workingDirectory = "/",
|
|
5332
|
+
maxFileSizeMb = 10,
|
|
5333
|
+
sandboxInstance
|
|
5334
|
+
} = options;
|
|
5335
|
+
this.sandbox = sandboxInstance || new SandboxClient2({ baseUrl: baseURL, environment: "" });
|
|
5336
|
+
this.sandbox.mcp.listMcpServers().then((servers) => {
|
|
5337
|
+
});
|
|
5338
|
+
this.sandbox.mcp.listMcpTools("browser").then((tools) => {
|
|
5339
|
+
console.log(tools);
|
|
5340
|
+
});
|
|
5341
|
+
this.baseURL = baseURL;
|
|
5342
|
+
this.maxFileSizeBytes = maxFileSizeMb * 1024 * 1024;
|
|
5343
|
+
this.workingDirectory = workingDirectory;
|
|
5344
|
+
this.homeDir = "/home/gem";
|
|
5345
|
+
}
|
|
5346
|
+
resolvePath(virtualPath) {
|
|
5347
|
+
return path3.join(this.homeDir, this.workingDirectory, virtualPath);
|
|
5348
|
+
}
|
|
5349
|
+
/**
|
|
5350
|
+
* Convert a real filesystem path to a virtual path.
|
|
5351
|
+
*
|
|
5352
|
+
* @param realPath - Real filesystem path
|
|
5353
|
+
* @returns Virtual path starting with /
|
|
5354
|
+
*/
|
|
5355
|
+
toVirtualPath(realPath) {
|
|
5356
|
+
const rootPath = path3.join(this.homeDir, this.workingDirectory);
|
|
5357
|
+
const relative2 = path3.relative(rootPath, realPath);
|
|
5358
|
+
const normalized = relative2.split(path3.sep).join("/");
|
|
5359
|
+
return "/" + normalized;
|
|
5360
|
+
}
|
|
5361
|
+
/**
|
|
5362
|
+
* List files and directories in the specified directory (non-recursive).
|
|
5363
|
+
*
|
|
5364
|
+
* @param dirPath - Virtual directory path (must start with /)
|
|
5365
|
+
* @returns List of FileInfo objects for files and directories directly in the directory.
|
|
5366
|
+
* Directories have a trailing / in their path and is_dir=true.
|
|
5367
|
+
*/
|
|
5368
|
+
async lsInfo(dirPath) {
|
|
5369
|
+
try {
|
|
5370
|
+
const resolvedPath = this.resolvePath(dirPath);
|
|
5371
|
+
const result = await this.sandbox.file.listPath({
|
|
5372
|
+
path: resolvedPath,
|
|
5373
|
+
recursive: false,
|
|
5374
|
+
show_hidden: false,
|
|
5375
|
+
max_depth: 0,
|
|
5376
|
+
include_size: false,
|
|
5377
|
+
include_permissions: false,
|
|
5378
|
+
sort_by: "name",
|
|
5379
|
+
sort_desc: false
|
|
5380
|
+
});
|
|
5381
|
+
if (!result.ok) {
|
|
5382
|
+
throw result.error;
|
|
5383
|
+
}
|
|
5384
|
+
const files = result.body?.data?.files?.map((file) => ({
|
|
5385
|
+
path: this.toVirtualPath(file.path),
|
|
5386
|
+
is_dir: file.is_directory,
|
|
5387
|
+
size: file.size,
|
|
5388
|
+
modified_at: file.modified_time
|
|
5389
|
+
})) || [];
|
|
5390
|
+
return files;
|
|
5391
|
+
} catch (e) {
|
|
5392
|
+
console.error(`Error listing files in ${dirPath}:`, e);
|
|
5393
|
+
return [];
|
|
5394
|
+
}
|
|
5395
|
+
}
|
|
5396
|
+
/**
|
|
5397
|
+
* Read file content with line numbers.
|
|
5398
|
+
*
|
|
5399
|
+
* @param filePath - Virtual file path (must start with /)
|
|
5400
|
+
* @param offset - Line offset to start reading from (0-indexed)
|
|
5401
|
+
* @param limit - Maximum number of lines to read
|
|
5402
|
+
* @returns Formatted file content with line numbers, or error message
|
|
5403
|
+
*/
|
|
5404
|
+
async read(filePath, offset = 0, limit = 1e4) {
|
|
5405
|
+
try {
|
|
5406
|
+
const resolvedPath = this.resolvePath(filePath);
|
|
5407
|
+
let content;
|
|
5408
|
+
const result = await this.sandbox.file.readFile({
|
|
5409
|
+
file: resolvedPath,
|
|
5410
|
+
start_line: offset,
|
|
5411
|
+
end_line: limit
|
|
5412
|
+
});
|
|
5413
|
+
if (!result.ok) {
|
|
5414
|
+
throw result.error;
|
|
5415
|
+
}
|
|
5416
|
+
content = result.body?.data?.content || "";
|
|
5417
|
+
return content;
|
|
5418
|
+
} catch (e) {
|
|
5419
|
+
return `Error: File '${filePath}' not found`;
|
|
5420
|
+
}
|
|
5421
|
+
}
|
|
5422
|
+
/**
|
|
5423
|
+
* Read file content as raw FileData.
|
|
5424
|
+
*
|
|
5425
|
+
* @param filePath - Virtual file path (must start with /)
|
|
5426
|
+
* @returns Raw file content as FileData
|
|
5427
|
+
*/
|
|
5428
|
+
async readRaw(filePath) {
|
|
5429
|
+
try {
|
|
5430
|
+
const content = await this.read(filePath);
|
|
5431
|
+
return {
|
|
5432
|
+
content: content.split("\n"),
|
|
5433
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5434
|
+
modified_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
5435
|
+
};
|
|
5436
|
+
} catch (e) {
|
|
5437
|
+
throw new Error(`Error reading file '${filePath}': ${e.message}`);
|
|
5438
|
+
}
|
|
5439
|
+
}
|
|
5440
|
+
/**
|
|
5441
|
+
* Create a new file with content.
|
|
5442
|
+
* Returns WriteResult. External storage sets filesUpdate=null.
|
|
5443
|
+
*
|
|
5444
|
+
* @param filePath - Virtual file path (must start with /)
|
|
5445
|
+
* @param content - File content as string
|
|
5446
|
+
* @returns WriteResult with error populated on failure
|
|
5447
|
+
*/
|
|
5448
|
+
async write(filePath, content) {
|
|
5449
|
+
try {
|
|
5450
|
+
const resolvedPath = this.resolvePath(filePath);
|
|
5451
|
+
const result = await this.sandbox.file.writeFile({
|
|
5452
|
+
file: resolvedPath,
|
|
5453
|
+
content,
|
|
5454
|
+
"encoding": "utf-8",
|
|
5455
|
+
"append": false
|
|
5456
|
+
// sudo: true
|
|
5457
|
+
});
|
|
5458
|
+
if (!result.ok) {
|
|
5459
|
+
console.error(result.error);
|
|
5460
|
+
throw result.error;
|
|
5461
|
+
}
|
|
5462
|
+
return {
|
|
5463
|
+
path: filePath,
|
|
5464
|
+
filesUpdate: {
|
|
5465
|
+
[filePath]: {
|
|
5466
|
+
content: content.split("\n"),
|
|
5467
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5468
|
+
modified_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
5469
|
+
}
|
|
5470
|
+
}
|
|
5471
|
+
};
|
|
5472
|
+
} catch (e) {
|
|
5473
|
+
throw new Error(`Error writing file '${filePath}': ${e.message}`);
|
|
5474
|
+
}
|
|
5475
|
+
}
|
|
5476
|
+
/**
|
|
5477
|
+
* Edit a file by replacing string occurrences.
|
|
5478
|
+
* Returns EditResult. External storage sets filesUpdate=null.
|
|
5479
|
+
*
|
|
5480
|
+
* @param filePath - Virtual file path (must start with /)
|
|
5481
|
+
* @param oldString - String to find and replace
|
|
5482
|
+
* @param newString - Replacement string
|
|
5483
|
+
* @param replaceAll - If true, replace all occurrences (default: false)
|
|
5484
|
+
* @returns EditResult with error, path, filesUpdate, and occurrences
|
|
5485
|
+
*/
|
|
5486
|
+
async edit(filePath, oldString, newString, replaceAll = false) {
|
|
5487
|
+
try {
|
|
5488
|
+
const resolvedPath = this.resolvePath(filePath);
|
|
5489
|
+
const result = await this.sandbox.file.strReplaceEditor({
|
|
5490
|
+
command: "str_replace",
|
|
5491
|
+
path: resolvedPath,
|
|
5492
|
+
old_str: oldString,
|
|
5493
|
+
new_str: newString,
|
|
5494
|
+
replace_mode: replaceAll ? "ALL" : "FIRST"
|
|
5495
|
+
});
|
|
5496
|
+
if (!result.ok) {
|
|
5497
|
+
throw result.error;
|
|
5498
|
+
}
|
|
5499
|
+
return {
|
|
5500
|
+
path: filePath,
|
|
5501
|
+
filesUpdate: null
|
|
5502
|
+
};
|
|
5503
|
+
} catch (e) {
|
|
5504
|
+
throw new Error(`Error editing file '${filePath}': ${e.message}`);
|
|
5505
|
+
}
|
|
5506
|
+
}
|
|
5507
|
+
/**
|
|
5508
|
+
* Structured search results or error string for invalid input.
|
|
5509
|
+
*
|
|
5510
|
+
* Searches file contents for a regex pattern within the sandbox.
|
|
5511
|
+
*
|
|
5512
|
+
* @param pattern - Regex pattern to search for
|
|
5513
|
+
* @param searchPath - Base path to search from (default: "/")
|
|
5514
|
+
* @param glob - Optional glob pattern to filter files (e.g., "*.py")
|
|
5515
|
+
* @returns List of GrepMatch objects or error string for invalid regex
|
|
5516
|
+
*/
|
|
5517
|
+
async grepRaw(pattern, searchPath = "/", glob = null) {
|
|
5518
|
+
let baseFull;
|
|
5519
|
+
baseFull = this.resolvePath(searchPath || "/");
|
|
5520
|
+
const result = await this.sandbox.file.findFiles({
|
|
5521
|
+
path: baseFull,
|
|
5522
|
+
glob: glob || "**/*"
|
|
5523
|
+
});
|
|
5524
|
+
if (!result.ok) {
|
|
5525
|
+
throw result.error;
|
|
5526
|
+
}
|
|
5527
|
+
const filePaths = result.body?.data?.files || [];
|
|
5528
|
+
const matches = [];
|
|
5529
|
+
for (const absolutePath of filePaths) {
|
|
5530
|
+
const fileData = await this.sandbox.file.searchInFile({
|
|
5531
|
+
file: absolutePath,
|
|
5532
|
+
regex: pattern
|
|
5533
|
+
});
|
|
5534
|
+
if (!fileData.ok) {
|
|
5535
|
+
continue;
|
|
5536
|
+
}
|
|
5537
|
+
const matchesData = fileData.body?.data?.matches || [];
|
|
5538
|
+
const matchLines = fileData.body?.data?.line_numbers || [];
|
|
5539
|
+
matchesData.forEach((match, index) => {
|
|
5540
|
+
matches.push({
|
|
5541
|
+
path: this.toVirtualPath(absolutePath),
|
|
5542
|
+
line: matchLines[index],
|
|
5543
|
+
text: match
|
|
5544
|
+
});
|
|
5545
|
+
});
|
|
5546
|
+
}
|
|
5547
|
+
return matches;
|
|
5548
|
+
}
|
|
5549
|
+
/**
|
|
5550
|
+
* Structured glob matching returning FileInfo objects.
|
|
5551
|
+
*
|
|
5552
|
+
* @param pattern - Glob pattern (e.g., `*.py`, `**\/*.ts`)
|
|
5553
|
+
* @param searchPath - Base path to search from (default: "/")
|
|
5554
|
+
* @returns List of FileInfo objects matching the pattern
|
|
5555
|
+
*/
|
|
5556
|
+
async globInfo(pattern, searchPath = "/") {
|
|
5557
|
+
if (pattern.startsWith("/")) {
|
|
5558
|
+
pattern = pattern.substring(1);
|
|
5559
|
+
}
|
|
5560
|
+
const resolvedSearchPath = this.resolvePath(searchPath);
|
|
5561
|
+
const result = await this.sandbox.file.findFiles({
|
|
5562
|
+
path: resolvedSearchPath,
|
|
5563
|
+
glob: pattern || "**/*"
|
|
5564
|
+
});
|
|
5565
|
+
if (!result.ok) {
|
|
5566
|
+
throw result.error;
|
|
5567
|
+
}
|
|
5568
|
+
const results = [];
|
|
5569
|
+
for (const filePath of result.body?.data?.files || []) {
|
|
5570
|
+
const fileInfo = await this.sandbox.file.listPath({
|
|
5571
|
+
path: filePath,
|
|
5572
|
+
recursive: false,
|
|
5573
|
+
show_hidden: false,
|
|
5574
|
+
max_depth: 1,
|
|
5575
|
+
include_size: false,
|
|
5576
|
+
include_permissions: false
|
|
5577
|
+
});
|
|
5578
|
+
if (!fileInfo.ok) {
|
|
5579
|
+
continue;
|
|
5580
|
+
}
|
|
5581
|
+
results.push({
|
|
5582
|
+
path: this.toVirtualPath(filePath),
|
|
5583
|
+
is_dir: false,
|
|
5584
|
+
size: fileInfo.body?.data?.files?.[0]?.size,
|
|
5585
|
+
modified_at: fileInfo.body?.data?.files?.[0]?.modified_time
|
|
5586
|
+
});
|
|
5587
|
+
}
|
|
5588
|
+
return results;
|
|
5589
|
+
}
|
|
5590
|
+
};
|
|
5591
|
+
|
|
5592
|
+
// src/middlewares/codeEvalMiddleware.ts
|
|
5593
|
+
import { createMiddleware as createMiddleware6 } from "langchain";
|
|
5594
|
+
function createCodeEvalMiddleware(params = {}) {
|
|
5595
|
+
const codeEvalTool = getToolClient("execute_code");
|
|
5596
|
+
const codeExecuteFileTool = getToolClient("execute_code_file");
|
|
5597
|
+
return createMiddleware6({
|
|
5598
|
+
name: "codeEvalMiddleware",
|
|
5599
|
+
tools: [codeEvalTool, codeExecuteFileTool, getToolClient("convert_to_markdown")]
|
|
5600
|
+
});
|
|
5601
|
+
}
|
|
5602
|
+
|
|
5603
|
+
// src/middlewares/browserMiddleware.ts
|
|
5604
|
+
import { createMiddleware as createMiddleware7 } from "langchain";
|
|
5605
|
+
function createBrowserMiddleware(params = {}) {
|
|
5606
|
+
const browserTools = toolLatticeManager.getAllLattices().filter((tool7) => tool7.key.startsWith("browser_"));
|
|
5607
|
+
return createMiddleware7({
|
|
5608
|
+
name: "browserMiddleware",
|
|
5609
|
+
tools: browserTools.map((tool7) => tool7.client)
|
|
5610
|
+
});
|
|
5611
|
+
}
|
|
5612
|
+
|
|
4049
5613
|
// src/agent_lattice/builders/DeepAgentGraphBuilder.ts
|
|
4050
5614
|
var DeepAgentGraphBuilder = class {
|
|
4051
5615
|
/**
|
|
@@ -4059,7 +5623,7 @@ var DeepAgentGraphBuilder = class {
|
|
|
4059
5623
|
const tools = params.tools.map((t) => {
|
|
4060
5624
|
const toolClient = getToolClient(t.key);
|
|
4061
5625
|
return toolClient;
|
|
4062
|
-
}).filter((
|
|
5626
|
+
}).filter((tool7) => tool7 !== void 0);
|
|
4063
5627
|
const subagents = params.subAgents.map((sa) => {
|
|
4064
5628
|
if (sa.client) {
|
|
4065
5629
|
return {
|
|
@@ -4078,6 +5642,35 @@ var DeepAgentGraphBuilder = class {
|
|
|
4078
5642
|
};
|
|
4079
5643
|
}
|
|
4080
5644
|
});
|
|
5645
|
+
let filesystemBackend;
|
|
5646
|
+
let middlewares = [];
|
|
5647
|
+
if (params.connectedSandbox) {
|
|
5648
|
+
const availabledModules = params.connectedSandbox?.availabledModules || ["filesystem", "code_eval", "browser"];
|
|
5649
|
+
if (availabledModules.includes("filesystem")) {
|
|
5650
|
+
const sandboxManager = sandboxLatticeManager.getSandboxLattice("default");
|
|
5651
|
+
if (!sandboxManager) {
|
|
5652
|
+
throw new Error("Sandbox manager not found");
|
|
5653
|
+
}
|
|
5654
|
+
let sandboxName = "global";
|
|
5655
|
+
if (params.connectedSandbox.isolatedLevel === "agent") {
|
|
5656
|
+
sandboxName = agentLattice.config.key;
|
|
5657
|
+
filesystemBackend = async (agentAndState) => new SandboxFilesystem({
|
|
5658
|
+
sandboxInstance: await sandboxManager.createSandbox(sandboxName)
|
|
5659
|
+
});
|
|
5660
|
+
} else if (params.connectedSandbox.isolatedLevel === "thread") {
|
|
5661
|
+
filesystemBackend = async (agentAndState) => new SandboxFilesystem({
|
|
5662
|
+
sandboxInstance: await sandboxManager.createSandbox(sandboxName)
|
|
5663
|
+
//TODO: add threadId to sandbox
|
|
5664
|
+
});
|
|
5665
|
+
}
|
|
5666
|
+
}
|
|
5667
|
+
if (availabledModules.includes("code_eval")) {
|
|
5668
|
+
middlewares.push(createCodeEvalMiddleware());
|
|
5669
|
+
}
|
|
5670
|
+
if (availabledModules.includes("browser")) {
|
|
5671
|
+
middlewares.push(createBrowserMiddleware());
|
|
5672
|
+
}
|
|
5673
|
+
}
|
|
4081
5674
|
const deepAgent = createDeepAgent({
|
|
4082
5675
|
tools,
|
|
4083
5676
|
model: params.model,
|
|
@@ -4085,7 +5678,9 @@ var DeepAgentGraphBuilder = class {
|
|
|
4085
5678
|
systemPrompt: params.prompt,
|
|
4086
5679
|
subagents,
|
|
4087
5680
|
checkpointer: getCheckpointSaver("default"),
|
|
4088
|
-
skillCategories: params.skillCategories
|
|
5681
|
+
skillCategories: params.skillCategories,
|
|
5682
|
+
backend: filesystemBackend,
|
|
5683
|
+
middleware: middlewares
|
|
4089
5684
|
});
|
|
4090
5685
|
return deepAgent;
|
|
4091
5686
|
}
|
|
@@ -4203,7 +5798,8 @@ var AgentParamsBuilder = class {
|
|
|
4203
5798
|
subAgents: [...subAgents, ...internalSubAgents],
|
|
4204
5799
|
prompt: agentLattice.config.prompt,
|
|
4205
5800
|
stateSchema: agentLattice.config.schema,
|
|
4206
|
-
skillCategories
|
|
5801
|
+
skillCategories,
|
|
5802
|
+
connectedSandbox: agentLattice.config.connectedSandbox
|
|
4207
5803
|
};
|
|
4208
5804
|
}
|
|
4209
5805
|
};
|
|
@@ -6488,6 +8084,106 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
6488
8084
|
};
|
|
6489
8085
|
var skillLatticeManager = SkillLatticeManager.getInstance();
|
|
6490
8086
|
|
|
8087
|
+
// src/mcp_lattice/McpLatticeManager.ts
|
|
8088
|
+
import { MultiServerMCPClient } from "@langchain/mcp-adapters";
|
|
8089
|
+
var McpLatticeManager = class _McpLatticeManager extends BaseLatticeManager {
|
|
8090
|
+
constructor() {
|
|
8091
|
+
super(...arguments);
|
|
8092
|
+
this.client = null;
|
|
8093
|
+
this.servers = /* @__PURE__ */ new Map();
|
|
8094
|
+
}
|
|
8095
|
+
static getInstance() {
|
|
8096
|
+
if (!_McpLatticeManager._instance) {
|
|
8097
|
+
_McpLatticeManager._instance = new _McpLatticeManager();
|
|
8098
|
+
}
|
|
8099
|
+
return _McpLatticeManager._instance;
|
|
8100
|
+
}
|
|
8101
|
+
getLatticeType() {
|
|
8102
|
+
return "mcp";
|
|
8103
|
+
}
|
|
8104
|
+
registerServers(servers) {
|
|
8105
|
+
for (const server of servers) {
|
|
8106
|
+
if (this.servers.has(server.name)) {
|
|
8107
|
+
console.warn(`[MCP] Server '${server.name}' already registered, skipping`);
|
|
8108
|
+
continue;
|
|
8109
|
+
}
|
|
8110
|
+
this.servers.set(server.name, server);
|
|
8111
|
+
console.log(`[MCP] Registered server: ${server.name}`);
|
|
8112
|
+
}
|
|
8113
|
+
}
|
|
8114
|
+
addServer(name, connection) {
|
|
8115
|
+
this.registerServers([{ name, connection }]);
|
|
8116
|
+
}
|
|
8117
|
+
removeServer(name) {
|
|
8118
|
+
const deleted = this.servers.delete(name);
|
|
8119
|
+
if (deleted) {
|
|
8120
|
+
console.log(`[MCP] Removed server: ${name}`);
|
|
8121
|
+
}
|
|
8122
|
+
return deleted;
|
|
8123
|
+
}
|
|
8124
|
+
async connect() {
|
|
8125
|
+
if (this.client) {
|
|
8126
|
+
console.warn("[MCP] Client already connected");
|
|
8127
|
+
return;
|
|
8128
|
+
}
|
|
8129
|
+
const serverConfigs = {};
|
|
8130
|
+
for (const [name, info] of this.servers) {
|
|
8131
|
+
serverConfigs[name] = info.connection;
|
|
8132
|
+
}
|
|
8133
|
+
if (Object.keys(serverConfigs).length === 0) {
|
|
8134
|
+
console.warn("[MCP] No servers registered");
|
|
8135
|
+
return;
|
|
8136
|
+
}
|
|
8137
|
+
this.client = new MultiServerMCPClient({
|
|
8138
|
+
mcpServers: serverConfigs
|
|
8139
|
+
});
|
|
8140
|
+
console.log(`[MCP] Connecting to ${this.servers.size} servers...`);
|
|
8141
|
+
await this.client.initializeConnections();
|
|
8142
|
+
console.log("[MCP] All servers connected");
|
|
8143
|
+
}
|
|
8144
|
+
async disconnect() {
|
|
8145
|
+
if (this.client) {
|
|
8146
|
+
await this.client.close();
|
|
8147
|
+
this.client = null;
|
|
8148
|
+
console.log("[MCP] Disconnected");
|
|
8149
|
+
}
|
|
8150
|
+
}
|
|
8151
|
+
isConnected() {
|
|
8152
|
+
return this.client !== null;
|
|
8153
|
+
}
|
|
8154
|
+
async getAllTools() {
|
|
8155
|
+
if (!this.client) {
|
|
8156
|
+
throw new Error("MCP client not connected");
|
|
8157
|
+
}
|
|
8158
|
+
return this.client.getTools();
|
|
8159
|
+
}
|
|
8160
|
+
getServerNames() {
|
|
8161
|
+
return Array.from(this.servers.keys());
|
|
8162
|
+
}
|
|
8163
|
+
hasServer(name) {
|
|
8164
|
+
return this.servers.has(name);
|
|
8165
|
+
}
|
|
8166
|
+
/**
|
|
8167
|
+
* 将 MCP 工具注册到 Tool Lattice
|
|
8168
|
+
* @param prefix 工具键名前缀,用于区分不同服务器的工具
|
|
8169
|
+
*/
|
|
8170
|
+
async registerToolsToToolLattice(prefix) {
|
|
8171
|
+
if (!this.client) {
|
|
8172
|
+
throw new Error("MCP client not connected");
|
|
8173
|
+
}
|
|
8174
|
+
const tools = await this.getAllTools();
|
|
8175
|
+
console.log(`[MCP] Registering ${tools.length} tools to Tool Lattice...`);
|
|
8176
|
+
for (const tool7 of tools) {
|
|
8177
|
+
const toolKey = prefix ? `${prefix}_${tool7.name}` : tool7.name;
|
|
8178
|
+
tool7.name = toolKey;
|
|
8179
|
+
toolLatticeManager.registerExistingTool(toolKey, tool7);
|
|
8180
|
+
console.log(`[MCP] Registered tool: ${toolKey}`);
|
|
8181
|
+
}
|
|
8182
|
+
console.log(`[MCP] Successfully registered ${tools.length} tools to Tool Lattice`);
|
|
8183
|
+
}
|
|
8184
|
+
};
|
|
8185
|
+
var mcpManager = McpLatticeManager.getInstance();
|
|
8186
|
+
|
|
6491
8187
|
// src/index.ts
|
|
6492
8188
|
import * as Protocols from "@axiom-lattice/protocols";
|
|
6493
8189
|
export {
|
|
@@ -6507,6 +8203,7 @@ export {
|
|
|
6507
8203
|
InMemoryChunkBuffer,
|
|
6508
8204
|
InMemoryThreadStore,
|
|
6509
8205
|
LoggerLatticeManager,
|
|
8206
|
+
McpLatticeManager,
|
|
6510
8207
|
MemoryLatticeManager,
|
|
6511
8208
|
MemoryQueueClient,
|
|
6512
8209
|
MemoryScheduleStorage,
|
|
@@ -6516,6 +8213,7 @@ export {
|
|
|
6516
8213
|
PostgresDatabase,
|
|
6517
8214
|
Protocols,
|
|
6518
8215
|
QueueLatticeManager,
|
|
8216
|
+
SandboxLatticeManager,
|
|
6519
8217
|
ScheduleLatticeManager,
|
|
6520
8218
|
SkillLatticeManager,
|
|
6521
8219
|
SqlDatabaseManager,
|
|
@@ -6541,6 +8239,7 @@ export {
|
|
|
6541
8239
|
getModelLattice,
|
|
6542
8240
|
getNextCronTime,
|
|
6543
8241
|
getQueueLattice,
|
|
8242
|
+
getSandBoxManager,
|
|
6544
8243
|
getScheduleLattice,
|
|
6545
8244
|
getStoreLattice,
|
|
6546
8245
|
getToolClient,
|
|
@@ -6550,9 +8249,12 @@ export {
|
|
|
6550
8249
|
getVectorStoreLattice,
|
|
6551
8250
|
hasChunkBuffer,
|
|
6552
8251
|
isValidCronExpression,
|
|
8252
|
+
isValidSandboxName,
|
|
6553
8253
|
isValidSkillName,
|
|
6554
8254
|
loggerLatticeManager,
|
|
8255
|
+
mcpManager,
|
|
6555
8256
|
modelLatticeManager,
|
|
8257
|
+
normalizeSandboxName,
|
|
6556
8258
|
parseCronExpression,
|
|
6557
8259
|
queueLatticeManager,
|
|
6558
8260
|
registerAgentLattice,
|
|
@@ -6560,6 +8262,7 @@ export {
|
|
|
6560
8262
|
registerCheckpointSaver,
|
|
6561
8263
|
registerChunkBuffer,
|
|
6562
8264
|
registerEmbeddingsLattice,
|
|
8265
|
+
registerExistingTool,
|
|
6563
8266
|
registerLoggerLattice,
|
|
6564
8267
|
registerModelLattice,
|
|
6565
8268
|
registerQueueLattice,
|
|
@@ -6567,6 +8270,7 @@ export {
|
|
|
6567
8270
|
registerStoreLattice,
|
|
6568
8271
|
registerToolLattice,
|
|
6569
8272
|
registerVectorStoreLattice,
|
|
8273
|
+
sandboxLatticeManager,
|
|
6570
8274
|
scheduleLatticeManager,
|
|
6571
8275
|
skillLatticeManager,
|
|
6572
8276
|
sqlDatabaseManager,
|