@dexto/tools-builtins 1.6.0 → 1.6.1
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/implementations/ask-user-tool.cjs +40 -9
- package/dist/implementations/ask-user-tool.d.ts +5 -5
- package/dist/implementations/ask-user-tool.d.ts.map +1 -1
- package/dist/implementations/ask-user-tool.js +41 -10
- package/dist/implementations/delegate-to-url-tool.cjs +6 -1
- package/dist/implementations/delegate-to-url-tool.d.ts.map +1 -1
- package/dist/implementations/delegate-to-url-tool.js +14 -2
- package/dist/implementations/delegate-to-url-tool.test.cjs +1 -0
- package/dist/implementations/delegate-to-url-tool.test.js +1 -0
- package/dist/implementations/exa-code-search-tool.cjs +6 -1
- package/dist/implementations/exa-code-search-tool.d.ts.map +1 -1
- package/dist/implementations/exa-code-search-tool.js +7 -2
- package/dist/implementations/exa-tools.test.cjs +1 -0
- package/dist/implementations/exa-tools.test.js +1 -0
- package/dist/implementations/exa-web-search-tool.cjs +6 -1
- package/dist/implementations/exa-web-search-tool.d.ts.map +1 -1
- package/dist/implementations/exa-web-search-tool.js +7 -2
- package/dist/implementations/get-resource-tool.cjs +9 -1
- package/dist/implementations/get-resource-tool.d.ts.map +1 -1
- package/dist/implementations/get-resource-tool.js +10 -2
- package/dist/implementations/http-request-tool.cjs +90 -40
- package/dist/implementations/http-request-tool.d.ts +5 -0
- package/dist/implementations/http-request-tool.d.ts.map +1 -1
- package/dist/implementations/http-request-tool.js +96 -40
- package/dist/implementations/http-request-tool.test.cjs +50 -0
- package/dist/implementations/http-request-tool.test.d.ts +2 -0
- package/dist/implementations/http-request-tool.test.d.ts.map +1 -0
- package/dist/implementations/http-request-tool.test.js +49 -0
- package/dist/implementations/invoke-skill-tool.cjs +11 -1
- package/dist/implementations/invoke-skill-tool.d.ts.map +1 -1
- package/dist/implementations/invoke-skill-tool.js +12 -2
- package/dist/implementations/list-resources-tool.cjs +12 -1
- package/dist/implementations/list-resources-tool.d.ts.map +1 -1
- package/dist/implementations/list-resources-tool.js +13 -2
- package/dist/implementations/sleep-tool.cjs +6 -1
- package/dist/implementations/sleep-tool.d.ts.map +1 -1
- package/dist/implementations/sleep-tool.js +7 -2
- package/dist/index.d.cts +19 -3
- package/package.json +4 -4
- package/dist/builtin-tools-factory.d.cts +0 -19
- package/dist/builtin-tools-factory.test.d.cts +0 -2
- package/dist/implementations/ask-user-tool.d.cts +0 -46
- package/dist/implementations/delegate-to-url-tool.d.cts +0 -27
- package/dist/implementations/delegate-to-url-tool.test.d.cts +0 -2
- package/dist/implementations/exa-code-search-tool.d.cts +0 -21
- package/dist/implementations/exa-mcp.d.cts +0 -24
- package/dist/implementations/exa-tools.test.d.cts +0 -2
- package/dist/implementations/exa-web-search-tool.d.cts +0 -30
- package/dist/implementations/get-resource-tool.d.cts +0 -22
- package/dist/implementations/http-request-tool.d.cts +0 -31
- package/dist/implementations/invoke-skill-tool.d.cts +0 -26
- package/dist/implementations/list-resources-tool.d.cts +0 -26
- package/dist/implementations/sleep-tool.d.cts +0 -16
|
@@ -24,21 +24,54 @@ module.exports = __toCommonJS(ask_user_tool_exports);
|
|
|
24
24
|
var import_zod = require("zod");
|
|
25
25
|
var import_core = require("@dexto/core");
|
|
26
26
|
const AskUserInputSchema = import_zod.z.object({
|
|
27
|
-
question: import_zod.z.string().describe(
|
|
27
|
+
question: import_zod.z.string().describe(
|
|
28
|
+
"High-level prompt/title for the form. Keep this short; clients may display or ignore it."
|
|
29
|
+
),
|
|
28
30
|
schema: import_zod.z.object({
|
|
29
31
|
type: import_zod.z.literal("object"),
|
|
30
|
-
properties: import_zod.z.record(import_zod.z.unknown()),
|
|
32
|
+
properties: import_zod.z.record(import_zod.z.string(), import_zod.z.record(import_zod.z.unknown())),
|
|
31
33
|
required: import_zod.z.array(import_zod.z.string()).optional()
|
|
32
34
|
}).passthrough().describe(
|
|
33
|
-
|
|
35
|
+
[
|
|
36
|
+
"JSON Schema defining form fields (object schema only).",
|
|
37
|
+
"Deterministic UI mapping (recommended):",
|
|
38
|
+
"- `properties[field].title`: main question/label shown prominently (keep \u2272 80 chars).",
|
|
39
|
+
"- `properties[field].description`: optional help text (keep \u2272 120 chars).",
|
|
40
|
+
'- `properties[field]["x-dexto"].stepLabel`: short wizard/step label (keep \u2272 16 chars).',
|
|
41
|
+
'Use stable, descriptive property keys (avoid generic names like "q1").',
|
|
42
|
+
"Use `enum` for single-choice lists, `boolean` for yes/no, `number` for numeric inputs, `string` for text.",
|
|
43
|
+
'For multi-select, use `type: "array"` with `items: { enum: [...] }`.',
|
|
44
|
+
"Include a top-level `required` array for mandatory fields."
|
|
45
|
+
].join(" ")
|
|
34
46
|
)
|
|
35
47
|
}).strict();
|
|
48
|
+
function toTitleCase(value) {
|
|
49
|
+
return value.trim().replace(/[_-]+/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/\s+/g, " ").split(" ").map((part) => part ? part.charAt(0).toUpperCase() + part.slice(1) : part).join(" ");
|
|
50
|
+
}
|
|
51
|
+
function enrichSchemaTitles(schema) {
|
|
52
|
+
if (schema.type !== "object") return schema;
|
|
53
|
+
const properties = schema.properties;
|
|
54
|
+
if (!properties) return schema;
|
|
55
|
+
const nextProperties = { ...properties };
|
|
56
|
+
for (const [key, value] of Object.entries(nextProperties)) {
|
|
57
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) continue;
|
|
58
|
+
const title = typeof value.title === "string" ? value.title.trim() : "";
|
|
59
|
+
if (title) continue;
|
|
60
|
+
nextProperties[key] = { ...value, title: toTitleCase(key) };
|
|
61
|
+
}
|
|
62
|
+
return { ...schema, properties: nextProperties };
|
|
63
|
+
}
|
|
36
64
|
function createAskUserTool() {
|
|
37
65
|
return (0, import_core.defineTool)({
|
|
38
66
|
id: "ask_user",
|
|
39
|
-
displayName: "Ask",
|
|
40
67
|
description: 'Collect structured input from the user through a form interface. ONLY use this tool when you need: 1) Multiple fields at once (e.g., name + email + preferences), 2) Pre-defined options/choices (use enum for dropdowns like ["small","medium","large"]), 3) Specific data types with validation (boolean for yes/no, number for quantities). DO NOT use for simple conversational questions - just ask those naturally in your response. This tool is for form-like data collection, not chat. Examples: collecting user profile info, configuration settings, or selecting from preset options.',
|
|
41
68
|
inputSchema: AskUserInputSchema,
|
|
69
|
+
presentation: {
|
|
70
|
+
describeHeader: (input) => (0, import_core.createLocalToolCallHeader)({
|
|
71
|
+
title: "Ask",
|
|
72
|
+
argsText: (0, import_core.truncateForHeader)(input.question, 140)
|
|
73
|
+
})
|
|
74
|
+
},
|
|
42
75
|
async execute(input, context) {
|
|
43
76
|
const { question, schema } = input;
|
|
44
77
|
const approvalManager = context.services?.approval;
|
|
@@ -48,13 +81,11 @@ function createAskUserTool() {
|
|
|
48
81
|
);
|
|
49
82
|
}
|
|
50
83
|
const elicitationRequest = {
|
|
51
|
-
schema,
|
|
84
|
+
schema: enrichSchemaTitles(input.schema),
|
|
52
85
|
prompt: question,
|
|
53
|
-
serverName: "Dexto Agent"
|
|
86
|
+
serverName: "Dexto Agent",
|
|
87
|
+
...context.sessionId && { sessionId: context.sessionId }
|
|
54
88
|
};
|
|
55
|
-
if (context.sessionId !== void 0) {
|
|
56
|
-
elicitationRequest.sessionId = context.sessionId;
|
|
57
|
-
}
|
|
58
89
|
return approvalManager.getElicitationData(elicitationRequest);
|
|
59
90
|
}
|
|
60
91
|
});
|
|
@@ -4,22 +4,22 @@ declare const AskUserInputSchema: z.ZodObject<{
|
|
|
4
4
|
question: z.ZodString;
|
|
5
5
|
schema: z.ZodObject<{
|
|
6
6
|
type: z.ZodLiteral<"object">;
|
|
7
|
-
properties: z.ZodRecord<z.ZodString, z.ZodUnknown
|
|
7
|
+
properties: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
8
8
|
required: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
9
9
|
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
10
10
|
type: z.ZodLiteral<"object">;
|
|
11
|
-
properties: z.ZodRecord<z.ZodString, z.ZodUnknown
|
|
11
|
+
properties: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
12
12
|
required: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
13
13
|
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
14
14
|
type: z.ZodLiteral<"object">;
|
|
15
|
-
properties: z.ZodRecord<z.ZodString, z.ZodUnknown
|
|
15
|
+
properties: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
16
16
|
required: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
17
17
|
}, z.ZodTypeAny, "passthrough">>;
|
|
18
18
|
}, "strict", z.ZodTypeAny, {
|
|
19
19
|
question: string;
|
|
20
20
|
schema: {
|
|
21
21
|
type: "object";
|
|
22
|
-
properties: Record<string, unknown
|
|
22
|
+
properties: Record<string, Record<string, unknown>>;
|
|
23
23
|
required?: string[] | undefined;
|
|
24
24
|
} & {
|
|
25
25
|
[k: string]: unknown;
|
|
@@ -28,7 +28,7 @@ declare const AskUserInputSchema: z.ZodObject<{
|
|
|
28
28
|
question: string;
|
|
29
29
|
schema: {
|
|
30
30
|
type: "object";
|
|
31
|
-
properties: Record<string, unknown
|
|
31
|
+
properties: Record<string, Record<string, unknown>>;
|
|
32
32
|
required?: string[] | undefined;
|
|
33
33
|
} & {
|
|
34
34
|
[k: string]: unknown;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ask-user-tool.d.ts","sourceRoot":"","sources":["../../src/implementations/ask-user-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,IAAI,EAAwB,MAAM,aAAa,CAAC;AAE9D,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"ask-user-tool.d.ts","sourceRoot":"","sources":["../../src/implementations/ask-user-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,IAAI,EAAwB,MAAM,aAAa,CAAC;AAE9D,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BX,CAAC;AAiCd;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAAC,OAAO,kBAAkB,CAAC,CAiCnE"}
|
|
@@ -1,21 +1,54 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { ToolError, defineTool } from "@dexto/core";
|
|
2
|
+
import { ToolError, createLocalToolCallHeader, defineTool, truncateForHeader } from "@dexto/core";
|
|
3
3
|
const AskUserInputSchema = z.object({
|
|
4
|
-
question: z.string().describe(
|
|
4
|
+
question: z.string().describe(
|
|
5
|
+
"High-level prompt/title for the form. Keep this short; clients may display or ignore it."
|
|
6
|
+
),
|
|
5
7
|
schema: z.object({
|
|
6
8
|
type: z.literal("object"),
|
|
7
|
-
properties: z.record(z.unknown()),
|
|
9
|
+
properties: z.record(z.string(), z.record(z.unknown())),
|
|
8
10
|
required: z.array(z.string()).optional()
|
|
9
11
|
}).passthrough().describe(
|
|
10
|
-
|
|
12
|
+
[
|
|
13
|
+
"JSON Schema defining form fields (object schema only).",
|
|
14
|
+
"Deterministic UI mapping (recommended):",
|
|
15
|
+
"- `properties[field].title`: main question/label shown prominently (keep \u2272 80 chars).",
|
|
16
|
+
"- `properties[field].description`: optional help text (keep \u2272 120 chars).",
|
|
17
|
+
'- `properties[field]["x-dexto"].stepLabel`: short wizard/step label (keep \u2272 16 chars).',
|
|
18
|
+
'Use stable, descriptive property keys (avoid generic names like "q1").',
|
|
19
|
+
"Use `enum` for single-choice lists, `boolean` for yes/no, `number` for numeric inputs, `string` for text.",
|
|
20
|
+
'For multi-select, use `type: "array"` with `items: { enum: [...] }`.',
|
|
21
|
+
"Include a top-level `required` array for mandatory fields."
|
|
22
|
+
].join(" ")
|
|
11
23
|
)
|
|
12
24
|
}).strict();
|
|
25
|
+
function toTitleCase(value) {
|
|
26
|
+
return value.trim().replace(/[_-]+/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/\s+/g, " ").split(" ").map((part) => part ? part.charAt(0).toUpperCase() + part.slice(1) : part).join(" ");
|
|
27
|
+
}
|
|
28
|
+
function enrichSchemaTitles(schema) {
|
|
29
|
+
if (schema.type !== "object") return schema;
|
|
30
|
+
const properties = schema.properties;
|
|
31
|
+
if (!properties) return schema;
|
|
32
|
+
const nextProperties = { ...properties };
|
|
33
|
+
for (const [key, value] of Object.entries(nextProperties)) {
|
|
34
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) continue;
|
|
35
|
+
const title = typeof value.title === "string" ? value.title.trim() : "";
|
|
36
|
+
if (title) continue;
|
|
37
|
+
nextProperties[key] = { ...value, title: toTitleCase(key) };
|
|
38
|
+
}
|
|
39
|
+
return { ...schema, properties: nextProperties };
|
|
40
|
+
}
|
|
13
41
|
function createAskUserTool() {
|
|
14
42
|
return defineTool({
|
|
15
43
|
id: "ask_user",
|
|
16
|
-
displayName: "Ask",
|
|
17
44
|
description: 'Collect structured input from the user through a form interface. ONLY use this tool when you need: 1) Multiple fields at once (e.g., name + email + preferences), 2) Pre-defined options/choices (use enum for dropdowns like ["small","medium","large"]), 3) Specific data types with validation (boolean for yes/no, number for quantities). DO NOT use for simple conversational questions - just ask those naturally in your response. This tool is for form-like data collection, not chat. Examples: collecting user profile info, configuration settings, or selecting from preset options.',
|
|
18
45
|
inputSchema: AskUserInputSchema,
|
|
46
|
+
presentation: {
|
|
47
|
+
describeHeader: (input) => createLocalToolCallHeader({
|
|
48
|
+
title: "Ask",
|
|
49
|
+
argsText: truncateForHeader(input.question, 140)
|
|
50
|
+
})
|
|
51
|
+
},
|
|
19
52
|
async execute(input, context) {
|
|
20
53
|
const { question, schema } = input;
|
|
21
54
|
const approvalManager = context.services?.approval;
|
|
@@ -25,13 +58,11 @@ function createAskUserTool() {
|
|
|
25
58
|
);
|
|
26
59
|
}
|
|
27
60
|
const elicitationRequest = {
|
|
28
|
-
schema,
|
|
61
|
+
schema: enrichSchemaTitles(input.schema),
|
|
29
62
|
prompt: question,
|
|
30
|
-
serverName: "Dexto Agent"
|
|
63
|
+
serverName: "Dexto Agent",
|
|
64
|
+
...context.sessionId && { sessionId: context.sessionId }
|
|
31
65
|
};
|
|
32
|
-
if (context.sessionId !== void 0) {
|
|
33
|
-
elicitationRequest.sessionId = context.sessionId;
|
|
34
|
-
}
|
|
35
66
|
return approvalManager.getElicitationData(elicitationRequest);
|
|
36
67
|
}
|
|
37
68
|
});
|
|
@@ -147,9 +147,14 @@ class SimpleA2AClient {
|
|
|
147
147
|
function createDelegateToUrlTool() {
|
|
148
148
|
return (0, import_core.defineTool)({
|
|
149
149
|
id: "delegate_to_url",
|
|
150
|
-
displayName: "Delegate",
|
|
151
150
|
description: 'Delegate a task to another A2A-compliant agent at a specific URL. Supports STATEFUL multi-turn conversations via sessionId parameter. USAGE: (1) First delegation: provide url + message. Tool returns a response AND a sessionId. (2) Follow-up: use the SAME sessionId to continue the conversation with that agent. The agent remembers previous context. EXAMPLE: First call {url: "http://agent:3001", message: "Analyze data X"} returns {sessionId: "xyz", response: "..."}. Second call {url: "http://agent:3001", message: "What was the top insight?", sessionId: "xyz"}. The agent will remember the first analysis and can answer specifically.',
|
|
152
151
|
inputSchema: DelegateToUrlInputSchema,
|
|
152
|
+
presentation: {
|
|
153
|
+
describeHeader: (input) => (0, import_core.createLocalToolCallHeader)({
|
|
154
|
+
title: "Delegate",
|
|
155
|
+
argsText: (0, import_core.truncateForHeader)(`${input.url} ${input.message}`, 140)
|
|
156
|
+
})
|
|
157
|
+
},
|
|
153
158
|
async execute(input, _context) {
|
|
154
159
|
const { url, message, sessionId, timeout } = input;
|
|
155
160
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delegate-to-url-tool.d.ts","sourceRoot":"","sources":["../../src/implementations/delegate-to-url-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,IAAI,EAAwB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"delegate-to-url-tool.d.ts","sourceRoot":"","sources":["../../src/implementations/delegate-to-url-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,IAAI,EAAwB,MAAM,aAAa,CAAC;AAU9D,QAAA,MAAM,wBAAwB;;;;;;;;;;;;;;;EA0BjB,CAAC;AAsJd;;;;GAIG;AACH,wBAAgB,uBAAuB,IAAI,IAAI,CAAC,OAAO,wBAAwB,CAAC,CA+C/E"}
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
DextoRuntimeError,
|
|
4
|
+
ErrorScope,
|
|
5
|
+
ErrorType,
|
|
6
|
+
createLocalToolCallHeader,
|
|
7
|
+
defineTool,
|
|
8
|
+
truncateForHeader
|
|
9
|
+
} from "@dexto/core";
|
|
3
10
|
const DelegateToUrlInputSchema = z.object({
|
|
4
11
|
url: z.string().url().describe(
|
|
5
12
|
'The A2A-compliant agent URL (e.g., "http://localhost:3001" or "https://agent.example.com"). The tool will automatically append the correct JSON-RPC endpoint.'
|
|
@@ -124,9 +131,14 @@ class SimpleA2AClient {
|
|
|
124
131
|
function createDelegateToUrlTool() {
|
|
125
132
|
return defineTool({
|
|
126
133
|
id: "delegate_to_url",
|
|
127
|
-
displayName: "Delegate",
|
|
128
134
|
description: 'Delegate a task to another A2A-compliant agent at a specific URL. Supports STATEFUL multi-turn conversations via sessionId parameter. USAGE: (1) First delegation: provide url + message. Tool returns a response AND a sessionId. (2) Follow-up: use the SAME sessionId to continue the conversation with that agent. The agent remembers previous context. EXAMPLE: First call {url: "http://agent:3001", message: "Analyze data X"} returns {sessionId: "xyz", response: "..."}. Second call {url: "http://agent:3001", message: "What was the top insight?", sessionId: "xyz"}. The agent will remember the first analysis and can answer specifically.',
|
|
129
135
|
inputSchema: DelegateToUrlInputSchema,
|
|
136
|
+
presentation: {
|
|
137
|
+
describeHeader: (input) => createLocalToolCallHeader({
|
|
138
|
+
title: "Delegate",
|
|
139
|
+
argsText: truncateForHeader(`${input.url} ${input.message}`, 140)
|
|
140
|
+
})
|
|
141
|
+
},
|
|
130
142
|
async execute(input, _context) {
|
|
131
143
|
const { url, message, sessionId, timeout } = input;
|
|
132
144
|
try {
|
|
@@ -11,6 +11,7 @@ function createMockLogger() {
|
|
|
11
11
|
error: import_vitest.vi.fn(),
|
|
12
12
|
trackException: import_vitest.vi.fn(),
|
|
13
13
|
createChild: import_vitest.vi.fn(() => logger),
|
|
14
|
+
createFileOnlyChild: import_vitest.vi.fn(() => logger),
|
|
14
15
|
setLevel: import_vitest.vi.fn(),
|
|
15
16
|
getLevel: import_vitest.vi.fn(() => "debug"),
|
|
16
17
|
getLogFilePath: import_vitest.vi.fn(() => null),
|
|
@@ -33,9 +33,14 @@ const CodeSearchInputSchema = import_zod.z.object({
|
|
|
33
33
|
function createCodeSearchTool() {
|
|
34
34
|
return (0, import_core.defineTool)({
|
|
35
35
|
id: "code_search",
|
|
36
|
-
displayName: "Code Search",
|
|
37
36
|
description: "Search for code examples and documentation across sources like official docs, GitHub, and Stack Overflow. Returns formatted text context.",
|
|
38
37
|
inputSchema: CodeSearchInputSchema,
|
|
38
|
+
presentation: {
|
|
39
|
+
describeHeader: (input) => (0, import_core.createLocalToolCallHeader)({
|
|
40
|
+
title: "Code Search",
|
|
41
|
+
argsText: (0, import_core.truncateForHeader)(input.query, 140)
|
|
42
|
+
})
|
|
43
|
+
},
|
|
39
44
|
async execute(input, context) {
|
|
40
45
|
const { query, tokensNum } = input;
|
|
41
46
|
return await (0, import_exa_mcp.callExaTool)({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exa-code-search-tool.d.ts","sourceRoot":"","sources":["../../src/implementations/exa-code-search-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,IAAI,EAAwB,MAAM,aAAa,CAAC;AAG9D,QAAA,MAAM,qBAAqB;;;;;;;;;EAiBd,CAAC;AACd;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAAC,OAAO,qBAAqB,CAAC,
|
|
1
|
+
{"version":3,"file":"exa-code-search-tool.d.ts","sourceRoot":"","sources":["../../src/implementations/exa-code-search-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,IAAI,EAAwB,MAAM,aAAa,CAAC;AAG9D,QAAA,MAAM,qBAAqB;;;;;;;;;EAiBd,CAAC;AACd;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAAC,OAAO,qBAAqB,CAAC,CA4BzE"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { defineTool } from "@dexto/core";
|
|
2
|
+
import { createLocalToolCallHeader, defineTool, truncateForHeader } from "@dexto/core";
|
|
3
3
|
import { callExaTool } from "./exa-mcp.js";
|
|
4
4
|
const CodeSearchInputSchema = z.object({
|
|
5
5
|
query: z.string().min(1).describe(
|
|
@@ -10,9 +10,14 @@ const CodeSearchInputSchema = z.object({
|
|
|
10
10
|
function createCodeSearchTool() {
|
|
11
11
|
return defineTool({
|
|
12
12
|
id: "code_search",
|
|
13
|
-
displayName: "Code Search",
|
|
14
13
|
description: "Search for code examples and documentation across sources like official docs, GitHub, and Stack Overflow. Returns formatted text context.",
|
|
15
14
|
inputSchema: CodeSearchInputSchema,
|
|
15
|
+
presentation: {
|
|
16
|
+
describeHeader: (input) => createLocalToolCallHeader({
|
|
17
|
+
title: "Code Search",
|
|
18
|
+
argsText: truncateForHeader(input.query, 140)
|
|
19
|
+
})
|
|
20
|
+
},
|
|
16
21
|
async execute(input, context) {
|
|
17
22
|
const { query, tokensNum } = input;
|
|
18
23
|
return await callExaTool({
|
|
@@ -12,6 +12,7 @@ function createMockLogger() {
|
|
|
12
12
|
error: import_vitest.vi.fn(),
|
|
13
13
|
trackException: import_vitest.vi.fn(),
|
|
14
14
|
createChild: import_vitest.vi.fn(() => logger),
|
|
15
|
+
createFileOnlyChild: import_vitest.vi.fn(() => logger),
|
|
15
16
|
setLevel: import_vitest.vi.fn(),
|
|
16
17
|
getLevel: import_vitest.vi.fn(() => "debug"),
|
|
17
18
|
getLogFilePath: import_vitest.vi.fn(() => null),
|
|
@@ -36,9 +36,14 @@ const WebSearchInputSchema = import_zod.z.object({
|
|
|
36
36
|
function createWebSearchTool() {
|
|
37
37
|
return (0, import_core.defineTool)({
|
|
38
38
|
id: "web_search",
|
|
39
|
-
displayName: "Web Search",
|
|
40
39
|
description: "Search the web for current information and return clean, ready-to-use text. Use for news, facts, and up-to-date context.",
|
|
41
40
|
inputSchema: WebSearchInputSchema,
|
|
41
|
+
presentation: {
|
|
42
|
+
describeHeader: (input) => (0, import_core.createLocalToolCallHeader)({
|
|
43
|
+
title: "Web Search",
|
|
44
|
+
argsText: (0, import_core.truncateForHeader)(input.query, 140)
|
|
45
|
+
})
|
|
46
|
+
},
|
|
42
47
|
async execute(input, context) {
|
|
43
48
|
const { query, numResults, livecrawl, type, contextMaxCharacters } = input;
|
|
44
49
|
return await (0, import_exa_mcp.callExaTool)({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exa-web-search-tool.d.ts","sourceRoot":"","sources":["../../src/implementations/exa-web-search-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,IAAI,EAAwB,MAAM,aAAa,CAAC;AAG9D,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;EA8Bb,CAAC;AACd;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAAC,OAAO,oBAAoB,CAAC,
|
|
1
|
+
{"version":3,"file":"exa-web-search-tool.d.ts","sourceRoot":"","sources":["../../src/implementations/exa-web-search-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,IAAI,EAAwB,MAAM,aAAa,CAAC;AAG9D,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;EA8Bb,CAAC;AACd;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAAC,OAAO,oBAAoB,CAAC,CA+BvE"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { defineTool } from "@dexto/core";
|
|
2
|
+
import { createLocalToolCallHeader, defineTool, truncateForHeader } from "@dexto/core";
|
|
3
3
|
import { callExaTool } from "./exa-mcp.js";
|
|
4
4
|
const WebSearchInputSchema = z.object({
|
|
5
5
|
query: z.string().min(1).describe("Web search query"),
|
|
@@ -13,9 +13,14 @@ const WebSearchInputSchema = z.object({
|
|
|
13
13
|
function createWebSearchTool() {
|
|
14
14
|
return defineTool({
|
|
15
15
|
id: "web_search",
|
|
16
|
-
displayName: "Web Search",
|
|
17
16
|
description: "Search the web for current information and return clean, ready-to-use text. Use for news, facts, and up-to-date context.",
|
|
18
17
|
inputSchema: WebSearchInputSchema,
|
|
18
|
+
presentation: {
|
|
19
|
+
describeHeader: (input) => createLocalToolCallHeader({
|
|
20
|
+
title: "Web Search",
|
|
21
|
+
argsText: truncateForHeader(input.query, 140)
|
|
22
|
+
})
|
|
23
|
+
},
|
|
19
24
|
async execute(input, context) {
|
|
20
25
|
const { query, numResults, livecrawl, type, contextMaxCharacters } = input;
|
|
21
26
|
return await callExaTool({
|
|
@@ -34,9 +34,17 @@ const GetResourceInputSchema = import_zod.z.object({
|
|
|
34
34
|
function createGetResourceTool() {
|
|
35
35
|
return (0, import_core.defineTool)({
|
|
36
36
|
id: "get_resource",
|
|
37
|
-
displayName: "Get Resource",
|
|
38
37
|
description: 'Access a stored resource. Use format "url" to get a shareable URL for other agents or external systems (requires remote storage like Supabase). Use format "metadata" to get resource information without loading data. References can be obtained from tool result annotations or list_resources.',
|
|
39
38
|
inputSchema: GetResourceInputSchema,
|
|
39
|
+
presentation: {
|
|
40
|
+
describeHeader: (input) => (0, import_core.createLocalToolCallHeader)({
|
|
41
|
+
title: "Get Resource",
|
|
42
|
+
argsText: (0, import_core.truncateForHeader)(
|
|
43
|
+
input.format === "metadata" ? `${input.reference} (metadata)` : input.reference,
|
|
44
|
+
140
|
|
45
|
+
)
|
|
46
|
+
})
|
|
47
|
+
},
|
|
40
48
|
async execute(input, context) {
|
|
41
49
|
const { reference, format } = input;
|
|
42
50
|
const resourceManager = context.services?.resources;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-resource-tool.d.ts","sourceRoot":"","sources":["../../src/implementations/get-resource-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,IAAI,EAAwB,MAAM,aAAa,CAAC;AAE9D,QAAA,MAAM,sBAAsB;;;;;;;;;EAgBf,CAAC;AAEd;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAAC,OAAO,sBAAsB,CAAC,
|
|
1
|
+
{"version":3,"file":"get-resource-tool.d.ts","sourceRoot":"","sources":["../../src/implementations/get-resource-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,IAAI,EAAwB,MAAM,aAAa,CAAC;AAE9D,QAAA,MAAM,sBAAsB;;;;;;;;;EAgBf,CAAC;AAEd;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAAC,OAAO,sBAAsB,CAAC,CAiH3E"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { ToolError, defineTool } from "@dexto/core";
|
|
2
|
+
import { ToolError, createLocalToolCallHeader, defineTool, truncateForHeader } from "@dexto/core";
|
|
3
3
|
const GetResourceInputSchema = z.object({
|
|
4
4
|
reference: z.string().describe(
|
|
5
5
|
'The resource reference to access. Formats: "blob:abc123" (from list_resources), "resource_ref:blob:abc123" (from tool annotations)'
|
|
@@ -11,9 +11,17 @@ const GetResourceInputSchema = z.object({
|
|
|
11
11
|
function createGetResourceTool() {
|
|
12
12
|
return defineTool({
|
|
13
13
|
id: "get_resource",
|
|
14
|
-
displayName: "Get Resource",
|
|
15
14
|
description: 'Access a stored resource. Use format "url" to get a shareable URL for other agents or external systems (requires remote storage like Supabase). Use format "metadata" to get resource information without loading data. References can be obtained from tool result annotations or list_resources.',
|
|
16
15
|
inputSchema: GetResourceInputSchema,
|
|
16
|
+
presentation: {
|
|
17
|
+
describeHeader: (input) => createLocalToolCallHeader({
|
|
18
|
+
title: "Get Resource",
|
|
19
|
+
argsText: truncateForHeader(
|
|
20
|
+
input.format === "metadata" ? `${input.reference} (metadata)` : input.reference,
|
|
21
|
+
140
|
|
22
|
+
)
|
|
23
|
+
})
|
|
24
|
+
},
|
|
17
25
|
async execute(input, context) {
|
|
18
26
|
const { reference, format } = input;
|
|
19
27
|
const resourceManager = context.services?.resources;
|
|
@@ -18,7 +18,8 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var http_request_tool_exports = {};
|
|
20
20
|
__export(http_request_tool_exports, {
|
|
21
|
-
createHttpRequestTool: () => createHttpRequestTool
|
|
21
|
+
createHttpRequestTool: () => createHttpRequestTool,
|
|
22
|
+
createSafeLookup: () => createSafeLookup
|
|
22
23
|
});
|
|
23
24
|
module.exports = __toCommonJS(http_request_tool_exports);
|
|
24
25
|
var import_zod = require("zod");
|
|
@@ -96,61 +97,101 @@ function isPrivateAddress(ip) {
|
|
|
96
97
|
if (version === 6) return isPrivateIpv6(ip);
|
|
97
98
|
return false;
|
|
98
99
|
}
|
|
99
|
-
function
|
|
100
|
-
const
|
|
100
|
+
function createSafeLookup(config) {
|
|
101
|
+
const dnsLookup = config?.dnsLookup ?? import_node_dns.promises.lookup;
|
|
102
|
+
return (hostname, options, callback) => {
|
|
101
103
|
void (async () => {
|
|
104
|
+
const toErrnoException = (err) => err;
|
|
105
|
+
const emitError = (err) => {
|
|
106
|
+
try {
|
|
107
|
+
if (options.all) {
|
|
108
|
+
callback(err, []);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
callback(err, "", 0);
|
|
112
|
+
} catch {
|
|
113
|
+
}
|
|
114
|
+
};
|
|
102
115
|
try {
|
|
103
116
|
if (BLOCKED_HOSTNAMES.has(hostname) || hostname.endsWith(".localhost")) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
117
|
+
emitError(
|
|
118
|
+
toErrnoException(
|
|
119
|
+
new import_core.DextoRuntimeError(
|
|
120
|
+
"HTTP_REQUEST_UNSAFE_TARGET",
|
|
121
|
+
import_core.ErrorScope.TOOLS,
|
|
122
|
+
import_core.ErrorType.FORBIDDEN,
|
|
123
|
+
`Blocked request to local hostname: ${hostname}`
|
|
124
|
+
)
|
|
125
|
+
)
|
|
113
126
|
);
|
|
114
127
|
return;
|
|
115
128
|
}
|
|
116
|
-
const records = await
|
|
129
|
+
const records = await dnsLookup(hostname, {
|
|
117
130
|
all: true,
|
|
118
|
-
verbatim: true
|
|
131
|
+
verbatim: true,
|
|
132
|
+
family: options.family,
|
|
133
|
+
hints: options.hints
|
|
119
134
|
});
|
|
120
135
|
if (!records.length) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
136
|
+
emitError(
|
|
137
|
+
toErrnoException(
|
|
138
|
+
new import_core.DextoRuntimeError(
|
|
139
|
+
"HTTP_REQUEST_DNS_FAILED",
|
|
140
|
+
import_core.ErrorScope.TOOLS,
|
|
141
|
+
import_core.ErrorType.THIRD_PARTY,
|
|
142
|
+
`Failed to resolve hostname: ${hostname}`
|
|
143
|
+
)
|
|
144
|
+
)
|
|
130
145
|
);
|
|
131
146
|
return;
|
|
132
147
|
}
|
|
133
148
|
for (const record of records) {
|
|
134
149
|
if (isPrivateAddress(record.address)) {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
150
|
+
emitError(
|
|
151
|
+
toErrnoException(
|
|
152
|
+
new import_core.DextoRuntimeError(
|
|
153
|
+
"HTTP_REQUEST_UNSAFE_TARGET",
|
|
154
|
+
import_core.ErrorScope.TOOLS,
|
|
155
|
+
import_core.ErrorType.FORBIDDEN,
|
|
156
|
+
`Blocked request to private address: ${record.address}`
|
|
157
|
+
)
|
|
158
|
+
)
|
|
144
159
|
);
|
|
145
160
|
return;
|
|
146
161
|
}
|
|
147
162
|
}
|
|
163
|
+
if (options.all) {
|
|
164
|
+
try {
|
|
165
|
+
callback(
|
|
166
|
+
null,
|
|
167
|
+
records
|
|
168
|
+
);
|
|
169
|
+
} catch {
|
|
170
|
+
}
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
148
173
|
const selected = records[0];
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
174
|
+
if (!selected) {
|
|
175
|
+
emitError(
|
|
176
|
+
toErrnoException(
|
|
177
|
+
new import_core.DextoRuntimeError(
|
|
178
|
+
"HTTP_REQUEST_DNS_FAILED",
|
|
179
|
+
import_core.ErrorScope.TOOLS,
|
|
180
|
+
import_core.ErrorType.THIRD_PARTY,
|
|
181
|
+
`Failed to resolve hostname: ${hostname}`
|
|
182
|
+
)
|
|
183
|
+
)
|
|
184
|
+
);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
try {
|
|
188
|
+
callback(
|
|
189
|
+
null,
|
|
190
|
+
selected.address,
|
|
191
|
+
selected.family ?? ((0, import_node_net.isIP)(selected.address) === 6 ? 6 : 4)
|
|
192
|
+
);
|
|
193
|
+
} catch {
|
|
194
|
+
}
|
|
154
195
|
} catch (error) {
|
|
155
196
|
const err = error instanceof import_core.DextoRuntimeError ? error : new import_core.DextoRuntimeError(
|
|
156
197
|
"HTTP_REQUEST_DNS_FAILED",
|
|
@@ -158,10 +199,13 @@ function createSafeDispatcher() {
|
|
|
158
199
|
import_core.ErrorType.THIRD_PARTY,
|
|
159
200
|
`Failed to resolve hostname: ${hostname}`
|
|
160
201
|
);
|
|
161
|
-
|
|
202
|
+
emitError(toErrnoException(err));
|
|
162
203
|
}
|
|
163
204
|
})();
|
|
164
205
|
};
|
|
206
|
+
}
|
|
207
|
+
function createSafeDispatcher() {
|
|
208
|
+
const lookup = createSafeLookup();
|
|
165
209
|
return new import_undici.Agent({ connect: { lookup } });
|
|
166
210
|
}
|
|
167
211
|
async function assertSafeUrl(requestUrl) {
|
|
@@ -241,9 +285,14 @@ async function readResponseTextWithLimit(response) {
|
|
|
241
285
|
function createHttpRequestTool() {
|
|
242
286
|
return (0, import_core.defineTool)({
|
|
243
287
|
id: "http_request",
|
|
244
|
-
displayName: "Fetch",
|
|
245
288
|
description: "Make a direct HTTP request using fetch. Supports method, headers, query params, JSON bodies, and timeouts. Returns status, headers, raw body text, and parsed JSON when available.",
|
|
246
289
|
inputSchema: HttpRequestInputSchema,
|
|
290
|
+
presentation: {
|
|
291
|
+
describeHeader: (input) => (0, import_core.createLocalToolCallHeader)({
|
|
292
|
+
title: "Fetch",
|
|
293
|
+
argsText: (0, import_core.truncateForHeader)(input.url, 140)
|
|
294
|
+
})
|
|
295
|
+
},
|
|
247
296
|
async execute(input, _context) {
|
|
248
297
|
const { url, method, headers, query, body, timeoutMs } = input;
|
|
249
298
|
const requestUrl = new URL(url);
|
|
@@ -323,5 +372,6 @@ function createHttpRequestTool() {
|
|
|
323
372
|
}
|
|
324
373
|
// Annotate the CommonJS export names for ESM import in node:
|
|
325
374
|
0 && (module.exports = {
|
|
326
|
-
createHttpRequestTool
|
|
375
|
+
createHttpRequestTool,
|
|
376
|
+
createSafeLookup
|
|
327
377
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { Tool } from '@dexto/core';
|
|
3
|
+
import { promises as dns, type LookupAddress, type LookupOptions } from 'node:dns';
|
|
3
4
|
declare const HttpRequestInputSchema: z.ZodObject<{
|
|
4
5
|
url: z.ZodString;
|
|
5
6
|
method: z.ZodDefault<z.ZodEnum<["GET", "POST", "PUT", "PATCH", "DELETE"]>>;
|
|
@@ -22,6 +23,10 @@ declare const HttpRequestInputSchema: z.ZodObject<{
|
|
|
22
23
|
body?: string | unknown[] | Record<string, unknown> | undefined;
|
|
23
24
|
timeoutMs?: number | undefined;
|
|
24
25
|
}>;
|
|
26
|
+
type LookupCallback = ((err: NodeJS.ErrnoException | null, address: string, family: number) => void) | ((err: NodeJS.ErrnoException | null, addresses: LookupAddress[]) => void);
|
|
27
|
+
export declare function createSafeLookup(config?: {
|
|
28
|
+
dnsLookup?: typeof dns.lookup;
|
|
29
|
+
}): (hostname: string, options: LookupOptions, callback: LookupCallback) => void;
|
|
25
30
|
/**
|
|
26
31
|
* Internal tool for basic HTTP requests.
|
|
27
32
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-request-tool.d.ts","sourceRoot":"","sources":["../../src/implementations/http-request-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,IAAI,EAAwB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"http-request-tool.d.ts","sourceRoot":"","sources":["../../src/implementations/http-request-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,IAAI,EAAwB,MAAM,aAAa,CAAC;AAS9D,OAAO,EAAE,QAAQ,IAAI,GAAG,EAAE,KAAK,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AAKnF,QAAA,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;EA2Bf,CAAC;AA8Bd,KAAK,cAAc,GACb,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,cAAc,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC,GAC9E,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,cAAc,GAAG,IAAI,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,IAAI,CAAC,CAAC;AAoDhF,wBAAgB,gBAAgB,CAAC,MAAM,CAAC,EAAE;IACtC,SAAS,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,CAAC;CACjC,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,cAAc,KAAK,IAAI,CAyI/E;AA2FD;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAAC,OAAO,sBAAsB,CAAC,CAuG3E"}
|