@townco/agent 0.1.42 → 0.1.43
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/acp-server/cli.d.ts +1 -3
- package/dist/acp-server/test-acp-summarize.d.ts +7 -0
- package/dist/acp-server/test-acp-summarize.js +127 -0
- package/dist/acp-server/test-summarizer.d.ts +7 -0
- package/dist/acp-server/test-summarizer.js +170 -0
- package/dist/acp-server/tool-summarizer.d.ts +125 -0
- package/dist/acp-server/tool-summarizer.js +182 -0
- package/dist/bin.js +0 -0
- package/dist/definition/index.d.ts +2 -0
- package/dist/definition/index.js +2 -0
- package/dist/definition/mcp.js +1 -0
- package/dist/runner/agent-runner.d.ts +6 -1
- package/dist/runner/index.d.ts +1 -3
- package/dist/runner/langchain/index.js +16 -2
- package/dist/runner/langchain/tools/filesystem.js +6 -0
- package/dist/runner/langchain/tools/todo.js +2 -0
- package/dist/runner/langchain/tools/web_search.js +4 -0
- package/dist/runner/tool-loader.d.ts +4 -0
- package/dist/runner/tool-loader.js +2 -0
- package/dist/runner/tools.d.ts +4 -0
- package/dist/runner/tools.js +2 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/tool.d.ts +2 -0
- package/dist/utils/tool.js +2 -0
- package/package.json +5 -5
- package/dist/definition/tools/todo.d.ts +0 -49
- package/dist/definition/tools/todo.js +0 -80
- package/dist/definition/tools/web_search.d.ts +0 -4
- package/dist/definition/tools/web_search.js +0 -26
- package/dist/dev-agent/index.d.ts +0 -2
- package/dist/dev-agent/index.js +0 -18
- package/dist/example.d.ts +0 -2
- package/dist/example.js +0 -19
package/dist/acp-server/cli.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
1
|
import type { AgentDefinition } from "../definition";
|
|
2
2
|
import { type AgentRunner } from "../runner";
|
|
3
|
-
export declare function makeStdioTransport(
|
|
4
|
-
agent: AgentRunner | AgentDefinition,
|
|
5
|
-
): void;
|
|
3
|
+
export declare function makeStdioTransport(agent: AgentRunner | AgentDefinition): void;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test the agent/summarize ACP method via the /rpc endpoint
|
|
3
|
+
*
|
|
4
|
+
* This test does NOT require an Anthropic API key because
|
|
5
|
+
* summarization just analyzes existing messages without calling the API
|
|
6
|
+
*/
|
|
7
|
+
// Make this a module
|
|
8
|
+
export {};
|
|
9
|
+
// Sample Anthropic API request with tool calls
|
|
10
|
+
const request = {
|
|
11
|
+
jsonrpc: "2.0",
|
|
12
|
+
id: "test-123",
|
|
13
|
+
method: "agent/summarize",
|
|
14
|
+
params: {
|
|
15
|
+
messages: [
|
|
16
|
+
{
|
|
17
|
+
role: "assistant",
|
|
18
|
+
content: [
|
|
19
|
+
{
|
|
20
|
+
type: "tool_use",
|
|
21
|
+
id: "toolu_01ABC",
|
|
22
|
+
name: "read_file",
|
|
23
|
+
input: {
|
|
24
|
+
target_file: "package.json",
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
role: "user",
|
|
31
|
+
content: [
|
|
32
|
+
{
|
|
33
|
+
type: "tool_result",
|
|
34
|
+
tool_use_id: "toolu_01ABC",
|
|
35
|
+
content: '{"name":"my-project"}',
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
role: "assistant",
|
|
41
|
+
content: [
|
|
42
|
+
{
|
|
43
|
+
type: "tool_use",
|
|
44
|
+
id: "toolu_02DEF",
|
|
45
|
+
name: "codebase_search",
|
|
46
|
+
input: {
|
|
47
|
+
query: "React components",
|
|
48
|
+
target_directories: [],
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
role: "user",
|
|
55
|
+
content: [
|
|
56
|
+
{
|
|
57
|
+
type: "tool_result",
|
|
58
|
+
tool_use_id: "toolu_02DEF",
|
|
59
|
+
content: "Found 5 components",
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
const serverUrl = process.env.ACP_SERVER_URL || "http://localhost:3100";
|
|
67
|
+
console.log("=".repeat(60));
|
|
68
|
+
console.log("Testing agent/summarize via ACP Protocol");
|
|
69
|
+
console.log("=".repeat(60));
|
|
70
|
+
console.log();
|
|
71
|
+
console.log(`Server URL: ${serverUrl}`);
|
|
72
|
+
console.log(`Method: agent/summarize`);
|
|
73
|
+
console.log(`Tool Calls: 2 (read_file, codebase_search)`);
|
|
74
|
+
console.log();
|
|
75
|
+
try {
|
|
76
|
+
const response = await fetch(`${serverUrl}/rpc`, {
|
|
77
|
+
method: "POST",
|
|
78
|
+
headers: {
|
|
79
|
+
"Content-Type": "application/json",
|
|
80
|
+
},
|
|
81
|
+
body: JSON.stringify(request),
|
|
82
|
+
});
|
|
83
|
+
if (!response.ok) {
|
|
84
|
+
console.error(`HTTP Error: ${response.status} ${response.statusText}`);
|
|
85
|
+
const errorText = await response.text();
|
|
86
|
+
console.error("Response:", errorText);
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
const data = await response.json();
|
|
90
|
+
// Check for JSON-RPC error
|
|
91
|
+
if (data.error) {
|
|
92
|
+
console.error("JSON-RPC Error:", JSON.stringify(data.error, null, 2));
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
console.log("✅ Success! JSON-RPC Response:");
|
|
96
|
+
console.log(JSON.stringify(data, null, 2));
|
|
97
|
+
console.log();
|
|
98
|
+
// Display the summary in a nice format
|
|
99
|
+
if (data.result && data.result.summary) {
|
|
100
|
+
console.log("Summary:");
|
|
101
|
+
console.log(` Total: ${data.result.summary.total}`);
|
|
102
|
+
console.log(` Completed: ${data.result.summary.byStatus.completed || 0}`);
|
|
103
|
+
console.log(` Errors: ${data.result.summary.byStatus.error || 0}`);
|
|
104
|
+
console.log();
|
|
105
|
+
console.log("Tool Calls:");
|
|
106
|
+
for (const toolCall of data.result.toolCalls || []) {
|
|
107
|
+
const statusEmoji = toolCall.status === "completed"
|
|
108
|
+
? "✓"
|
|
109
|
+
: toolCall.status === "error"
|
|
110
|
+
? "✗"
|
|
111
|
+
: "⋯";
|
|
112
|
+
console.log(` ${statusEmoji} ${toolCall.description}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
console.log();
|
|
116
|
+
console.log("=".repeat(60));
|
|
117
|
+
console.log("Test Complete - No API Key Required! ✅");
|
|
118
|
+
console.log("=".repeat(60));
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
console.error("Connection Error:");
|
|
122
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
123
|
+
console.log();
|
|
124
|
+
console.log("Make sure the ACP server is running:");
|
|
125
|
+
console.log(" bun run dev:agent-http --no-session");
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test script for the /summarize endpoint
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* bun packages/agent/acp-server/test-summarizer.ts
|
|
6
|
+
*/
|
|
7
|
+
import { extractToolCalls, generateTextSummary, summarizeToolCalls, } from "./tool-summarizer";
|
|
8
|
+
// Test data: Sample Anthropic API request with tool calls
|
|
9
|
+
const sampleRequest = {
|
|
10
|
+
model: "claude-sonnet-4-5-20250929",
|
|
11
|
+
messages: [
|
|
12
|
+
{
|
|
13
|
+
role: "user",
|
|
14
|
+
content: "Please read the package.json file",
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
role: "assistant",
|
|
18
|
+
content: [
|
|
19
|
+
{
|
|
20
|
+
type: "text",
|
|
21
|
+
text: "I'll read the package.json file for you.",
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
type: "tool_use",
|
|
25
|
+
id: "toolu_01ABC123",
|
|
26
|
+
name: "read_file",
|
|
27
|
+
input: {
|
|
28
|
+
target_file: "package.json",
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
role: "user",
|
|
35
|
+
content: [
|
|
36
|
+
{
|
|
37
|
+
type: "tool_result",
|
|
38
|
+
tool_use_id: "toolu_01ABC123",
|
|
39
|
+
content: JSON.stringify({
|
|
40
|
+
name: "my-project",
|
|
41
|
+
version: "1.0.0",
|
|
42
|
+
dependencies: {
|
|
43
|
+
react: "^18.0.0",
|
|
44
|
+
},
|
|
45
|
+
}),
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
role: "assistant",
|
|
51
|
+
content: [
|
|
52
|
+
{
|
|
53
|
+
type: "text",
|
|
54
|
+
text: "Now let me search for React components.",
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
type: "tool_use",
|
|
58
|
+
id: "toolu_02DEF456",
|
|
59
|
+
name: "codebase_search",
|
|
60
|
+
input: {
|
|
61
|
+
query: "React components using hooks",
|
|
62
|
+
target_directories: [],
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
role: "user",
|
|
69
|
+
content: [
|
|
70
|
+
{
|
|
71
|
+
type: "tool_result",
|
|
72
|
+
tool_use_id: "toolu_02DEF456",
|
|
73
|
+
content: "Found 5 components...",
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
role: "assistant",
|
|
79
|
+
content: [
|
|
80
|
+
{
|
|
81
|
+
type: "text",
|
|
82
|
+
text: "Let me try to run a command that will fail.",
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
type: "tool_use",
|
|
86
|
+
id: "toolu_03GHI789",
|
|
87
|
+
name: "run_terminal_cmd",
|
|
88
|
+
input: {
|
|
89
|
+
command: "invalid-command",
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
role: "user",
|
|
96
|
+
content: [
|
|
97
|
+
{
|
|
98
|
+
type: "tool_result",
|
|
99
|
+
tool_use_id: "toolu_03GHI789",
|
|
100
|
+
content: "Command not found: invalid-command",
|
|
101
|
+
is_error: true,
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
};
|
|
107
|
+
console.log("=".repeat(60));
|
|
108
|
+
console.log("Testing Tool Call Summarizer");
|
|
109
|
+
console.log("=".repeat(60));
|
|
110
|
+
console.log();
|
|
111
|
+
// Test 1: Extract tool calls
|
|
112
|
+
console.log("Test 1: Extract Tool Calls");
|
|
113
|
+
console.log("-".repeat(60));
|
|
114
|
+
const toolCalls = extractToolCalls(sampleRequest.messages);
|
|
115
|
+
console.log(`Found ${toolCalls.length} tool calls`);
|
|
116
|
+
console.log();
|
|
117
|
+
for (const toolCall of toolCalls) {
|
|
118
|
+
console.log(`- ${toolCall.description} [${toolCall.status}]`);
|
|
119
|
+
console.log(` ID: ${toolCall.id}`);
|
|
120
|
+
console.log(` Name: ${toolCall.name}`);
|
|
121
|
+
}
|
|
122
|
+
console.log();
|
|
123
|
+
// Test 2: Generate summary
|
|
124
|
+
console.log("Test 2: Generate Summary");
|
|
125
|
+
console.log("-".repeat(60));
|
|
126
|
+
const summary = summarizeToolCalls(sampleRequest);
|
|
127
|
+
console.log(`Total: ${summary.total}`);
|
|
128
|
+
console.log(`By Status:`, summary.byStatus);
|
|
129
|
+
console.log(`By Tool:`, summary.byTool);
|
|
130
|
+
console.log();
|
|
131
|
+
// Test 3: Generate text summary
|
|
132
|
+
console.log("Test 3: Generate Text Summary");
|
|
133
|
+
console.log("-".repeat(60));
|
|
134
|
+
const textSummary = generateTextSummary(summary.summaries, {
|
|
135
|
+
includeDetails: true,
|
|
136
|
+
});
|
|
137
|
+
console.log(textSummary);
|
|
138
|
+
console.log();
|
|
139
|
+
// Test 4: Test with HTTP endpoint (if server is running)
|
|
140
|
+
console.log("Test 4: Test HTTP Endpoint");
|
|
141
|
+
console.log("-".repeat(60));
|
|
142
|
+
const serverUrl = process.env.ACP_SERVER_URL || "http://localhost:3100";
|
|
143
|
+
console.log(`Testing endpoint: ${serverUrl}/summarize`);
|
|
144
|
+
try {
|
|
145
|
+
const response = await fetch(`${serverUrl}/summarize`, {
|
|
146
|
+
method: "POST",
|
|
147
|
+
headers: {
|
|
148
|
+
"Content-Type": "application/json",
|
|
149
|
+
},
|
|
150
|
+
body: JSON.stringify(sampleRequest),
|
|
151
|
+
});
|
|
152
|
+
if (!response.ok) {
|
|
153
|
+
const errorData = await response.json();
|
|
154
|
+
console.error("Error:", errorData);
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
const data = await response.json();
|
|
158
|
+
console.log("Success! Response:");
|
|
159
|
+
console.log(JSON.stringify(data, null, 2));
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
console.error("Could not connect to server. Make sure the ACP server is running.");
|
|
164
|
+
console.error("Start it with: bun packages/agent/acp-server/cli.ts");
|
|
165
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
166
|
+
}
|
|
167
|
+
console.log();
|
|
168
|
+
console.log("=".repeat(60));
|
|
169
|
+
console.log("Tests Complete");
|
|
170
|
+
console.log("=".repeat(60));
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Anthropic API tool call format
|
|
4
|
+
*/
|
|
5
|
+
export declare const AnthropicToolCallSchema: z.ZodObject<{
|
|
6
|
+
id: z.ZodString;
|
|
7
|
+
type: z.ZodLiteral<"tool_use">;
|
|
8
|
+
name: z.ZodString;
|
|
9
|
+
input: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
10
|
+
}, z.core.$strip>;
|
|
11
|
+
export type AnthropicToolCall = z.infer<typeof AnthropicToolCallSchema>;
|
|
12
|
+
/**
|
|
13
|
+
* Anthropic API content block format
|
|
14
|
+
*/
|
|
15
|
+
export declare const AnthropicContentBlockSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
16
|
+
type: z.ZodLiteral<"text">;
|
|
17
|
+
text: z.ZodString;
|
|
18
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
19
|
+
id: z.ZodString;
|
|
20
|
+
type: z.ZodLiteral<"tool_use">;
|
|
21
|
+
name: z.ZodString;
|
|
22
|
+
input: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
23
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
24
|
+
type: z.ZodLiteral<"tool_result">;
|
|
25
|
+
tool_use_id: z.ZodString;
|
|
26
|
+
content: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodObject<{
|
|
27
|
+
type: z.ZodLiteral<"text">;
|
|
28
|
+
text: z.ZodString;
|
|
29
|
+
}, z.core.$strip>>]>;
|
|
30
|
+
is_error: z.ZodOptional<z.ZodBoolean>;
|
|
31
|
+
}, z.core.$strip>], "type">;
|
|
32
|
+
export type AnthropicContentBlock = z.infer<typeof AnthropicContentBlockSchema>;
|
|
33
|
+
/**
|
|
34
|
+
* Anthropic API message format
|
|
35
|
+
*/
|
|
36
|
+
export declare const AnthropicMessageSchema: z.ZodObject<{
|
|
37
|
+
role: z.ZodEnum<{
|
|
38
|
+
assistant: "assistant";
|
|
39
|
+
user: "user";
|
|
40
|
+
}>;
|
|
41
|
+
content: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
42
|
+
type: z.ZodLiteral<"text">;
|
|
43
|
+
text: z.ZodString;
|
|
44
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
45
|
+
id: z.ZodString;
|
|
46
|
+
type: z.ZodLiteral<"tool_use">;
|
|
47
|
+
name: z.ZodString;
|
|
48
|
+
input: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
49
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
50
|
+
type: z.ZodLiteral<"tool_result">;
|
|
51
|
+
tool_use_id: z.ZodString;
|
|
52
|
+
content: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodObject<{
|
|
53
|
+
type: z.ZodLiteral<"text">;
|
|
54
|
+
text: z.ZodString;
|
|
55
|
+
}, z.core.$strip>>]>;
|
|
56
|
+
is_error: z.ZodOptional<z.ZodBoolean>;
|
|
57
|
+
}, z.core.$strip>], "type">>]>;
|
|
58
|
+
}, z.core.$strip>;
|
|
59
|
+
export type AnthropicMessage = z.infer<typeof AnthropicMessageSchema>;
|
|
60
|
+
/**
|
|
61
|
+
* Anthropic API request format
|
|
62
|
+
*/
|
|
63
|
+
export declare const AnthropicRequestSchema: z.ZodObject<{
|
|
64
|
+
model: z.ZodOptional<z.ZodString>;
|
|
65
|
+
messages: z.ZodArray<z.ZodObject<{
|
|
66
|
+
role: z.ZodEnum<{
|
|
67
|
+
assistant: "assistant";
|
|
68
|
+
user: "user";
|
|
69
|
+
}>;
|
|
70
|
+
content: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
71
|
+
type: z.ZodLiteral<"text">;
|
|
72
|
+
text: z.ZodString;
|
|
73
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
74
|
+
id: z.ZodString;
|
|
75
|
+
type: z.ZodLiteral<"tool_use">;
|
|
76
|
+
name: z.ZodString;
|
|
77
|
+
input: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
78
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
79
|
+
type: z.ZodLiteral<"tool_result">;
|
|
80
|
+
tool_use_id: z.ZodString;
|
|
81
|
+
content: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodObject<{
|
|
82
|
+
type: z.ZodLiteral<"text">;
|
|
83
|
+
text: z.ZodString;
|
|
84
|
+
}, z.core.$strip>>]>;
|
|
85
|
+
is_error: z.ZodOptional<z.ZodBoolean>;
|
|
86
|
+
}, z.core.$strip>], "type">>]>;
|
|
87
|
+
}, z.core.$strip>>;
|
|
88
|
+
max_tokens: z.ZodOptional<z.ZodNumber>;
|
|
89
|
+
temperature: z.ZodOptional<z.ZodNumber>;
|
|
90
|
+
tools: z.ZodOptional<z.ZodArray<z.ZodAny>>;
|
|
91
|
+
system: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodAny>]>>;
|
|
92
|
+
}, z.core.$strip>;
|
|
93
|
+
export type AnthropicRequest = z.infer<typeof AnthropicRequestSchema>;
|
|
94
|
+
/**
|
|
95
|
+
* Tool call summary for display
|
|
96
|
+
*/
|
|
97
|
+
export interface ToolCallSummary {
|
|
98
|
+
id: string;
|
|
99
|
+
name: string;
|
|
100
|
+
description: string;
|
|
101
|
+
input: Record<string, unknown>;
|
|
102
|
+
output?: string | undefined;
|
|
103
|
+
status: "pending" | "completed" | "error";
|
|
104
|
+
error?: string | undefined;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Extract tool calls from Anthropic API messages
|
|
108
|
+
*/
|
|
109
|
+
export declare function extractToolCalls(messages: AnthropicMessage[]): ToolCallSummary[];
|
|
110
|
+
/**
|
|
111
|
+
* Generate a summary of tool calls for the entire conversation
|
|
112
|
+
*/
|
|
113
|
+
export declare function summarizeToolCalls(request: AnthropicRequest): {
|
|
114
|
+
total: number;
|
|
115
|
+
byStatus: Record<string, number>;
|
|
116
|
+
byTool: Record<string, number>;
|
|
117
|
+
summaries: ToolCallSummary[];
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Generate a text summary of tool calls
|
|
121
|
+
*/
|
|
122
|
+
export declare function generateTextSummary(summaries: ToolCallSummary[], options?: {
|
|
123
|
+
includeDetails?: boolean;
|
|
124
|
+
maxLength?: number;
|
|
125
|
+
}): string;
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Anthropic API tool call format
|
|
4
|
+
*/
|
|
5
|
+
export const AnthropicToolCallSchema = z.object({
|
|
6
|
+
id: z.string(),
|
|
7
|
+
type: z.literal("tool_use"),
|
|
8
|
+
name: z.string(),
|
|
9
|
+
input: z.record(z.string(), z.unknown()),
|
|
10
|
+
});
|
|
11
|
+
/**
|
|
12
|
+
* Anthropic API content block format
|
|
13
|
+
*/
|
|
14
|
+
export const AnthropicContentBlockSchema = z.discriminatedUnion("type", [
|
|
15
|
+
z.object({
|
|
16
|
+
type: z.literal("text"),
|
|
17
|
+
text: z.string(),
|
|
18
|
+
}),
|
|
19
|
+
AnthropicToolCallSchema,
|
|
20
|
+
z.object({
|
|
21
|
+
type: z.literal("tool_result"),
|
|
22
|
+
tool_use_id: z.string(),
|
|
23
|
+
content: z.union([
|
|
24
|
+
z.string(),
|
|
25
|
+
z.array(z.object({
|
|
26
|
+
type: z.literal("text"),
|
|
27
|
+
text: z.string(),
|
|
28
|
+
})),
|
|
29
|
+
]),
|
|
30
|
+
is_error: z.boolean().optional(),
|
|
31
|
+
}),
|
|
32
|
+
]);
|
|
33
|
+
/**
|
|
34
|
+
* Anthropic API message format
|
|
35
|
+
*/
|
|
36
|
+
export const AnthropicMessageSchema = z.object({
|
|
37
|
+
role: z.enum(["user", "assistant"]),
|
|
38
|
+
content: z.union([z.string(), z.array(AnthropicContentBlockSchema)]),
|
|
39
|
+
});
|
|
40
|
+
/**
|
|
41
|
+
* Anthropic API request format
|
|
42
|
+
*/
|
|
43
|
+
export const AnthropicRequestSchema = z.object({
|
|
44
|
+
model: z.string().optional(),
|
|
45
|
+
messages: z.array(AnthropicMessageSchema),
|
|
46
|
+
max_tokens: z.number().optional(),
|
|
47
|
+
temperature: z.number().optional(),
|
|
48
|
+
tools: z.array(z.any()).optional(),
|
|
49
|
+
system: z.union([z.string(), z.array(z.any())]).optional(),
|
|
50
|
+
});
|
|
51
|
+
/**
|
|
52
|
+
* Extract tool calls from Anthropic API messages
|
|
53
|
+
*/
|
|
54
|
+
export function extractToolCalls(messages) {
|
|
55
|
+
const summaries = [];
|
|
56
|
+
const toolResultsMap = new Map();
|
|
57
|
+
// First pass: collect all tool results
|
|
58
|
+
for (const message of messages) {
|
|
59
|
+
if (typeof message.content === "string")
|
|
60
|
+
continue;
|
|
61
|
+
for (const block of message.content) {
|
|
62
|
+
if (block.type === "tool_result") {
|
|
63
|
+
const content = typeof block.content === "string"
|
|
64
|
+
? block.content
|
|
65
|
+
: block.content.map((c) => c.text).join("\n");
|
|
66
|
+
toolResultsMap.set(block.tool_use_id, {
|
|
67
|
+
content,
|
|
68
|
+
isError: block.is_error ?? false,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Second pass: collect all tool calls and match with results
|
|
74
|
+
for (const message of messages) {
|
|
75
|
+
if (typeof message.content === "string")
|
|
76
|
+
continue;
|
|
77
|
+
for (const block of message.content) {
|
|
78
|
+
if (block.type === "tool_use") {
|
|
79
|
+
const result = toolResultsMap.get(block.id);
|
|
80
|
+
const summary = {
|
|
81
|
+
id: block.id,
|
|
82
|
+
name: block.name,
|
|
83
|
+
description: generateToolDescription(block.name, block.input),
|
|
84
|
+
input: block.input,
|
|
85
|
+
output: result?.content ?? undefined,
|
|
86
|
+
status: result
|
|
87
|
+
? result.isError
|
|
88
|
+
? "error"
|
|
89
|
+
: "completed"
|
|
90
|
+
: "pending",
|
|
91
|
+
error: result?.isError ? result.content : undefined,
|
|
92
|
+
};
|
|
93
|
+
summaries.push(summary);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return summaries;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Generate a human-readable description for a tool call
|
|
101
|
+
*/
|
|
102
|
+
function generateToolDescription(toolName, input) {
|
|
103
|
+
switch (toolName) {
|
|
104
|
+
case "read_file":
|
|
105
|
+
return `Reading file: ${input.target_file || "unknown"}`;
|
|
106
|
+
case "write":
|
|
107
|
+
return `Writing file: ${input.file_path || "unknown"}`;
|
|
108
|
+
case "search_replace":
|
|
109
|
+
return `Editing file: ${input.file_path || "unknown"}`;
|
|
110
|
+
case "grep":
|
|
111
|
+
return `Searching for: "${input.pattern || "unknown"}"`;
|
|
112
|
+
case "codebase_search":
|
|
113
|
+
return `Semantic search: "${input.query || "unknown"}"`;
|
|
114
|
+
case "run_terminal_cmd":
|
|
115
|
+
return `Running command: ${input.command || "unknown"}`;
|
|
116
|
+
case "list_dir":
|
|
117
|
+
return `Listing directory: ${input.target_directory || "unknown"}`;
|
|
118
|
+
case "glob_file_search":
|
|
119
|
+
return `Finding files: ${input.glob_pattern || "unknown"}`;
|
|
120
|
+
case "delete_file":
|
|
121
|
+
return `Deleting file: ${input.target_file || "unknown"}`;
|
|
122
|
+
case "todo_write":
|
|
123
|
+
return `Updating TODO list (${input.todos?.length || 0} items)`;
|
|
124
|
+
default:
|
|
125
|
+
return `${toolName}(${Object.keys(input).join(", ")})`;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Generate a summary of tool calls for the entire conversation
|
|
130
|
+
*/
|
|
131
|
+
export function summarizeToolCalls(request) {
|
|
132
|
+
const summaries = extractToolCalls(request.messages);
|
|
133
|
+
const byStatus = {
|
|
134
|
+
pending: 0,
|
|
135
|
+
completed: 0,
|
|
136
|
+
error: 0,
|
|
137
|
+
};
|
|
138
|
+
const byTool = {};
|
|
139
|
+
for (const summary of summaries) {
|
|
140
|
+
byStatus[summary.status] = (byStatus[summary.status] || 0) + 1;
|
|
141
|
+
byTool[summary.name] = (byTool[summary.name] || 0) + 1;
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
total: summaries.length,
|
|
145
|
+
byStatus,
|
|
146
|
+
byTool,
|
|
147
|
+
summaries,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Generate a text summary of tool calls
|
|
152
|
+
*/
|
|
153
|
+
export function generateTextSummary(summaries, options) {
|
|
154
|
+
if (summaries.length === 0) {
|
|
155
|
+
return "No tool calls in this conversation.";
|
|
156
|
+
}
|
|
157
|
+
const { includeDetails = false, maxLength = 1000 } = options || {};
|
|
158
|
+
let text = `Found ${summaries.length} tool call(s):\n\n`;
|
|
159
|
+
for (const summary of summaries) {
|
|
160
|
+
const statusEmoji = summary.status === "completed"
|
|
161
|
+
? "✓"
|
|
162
|
+
: summary.status === "error"
|
|
163
|
+
? "✗"
|
|
164
|
+
: "⋯";
|
|
165
|
+
text += `${statusEmoji} ${summary.description}\n`;
|
|
166
|
+
if (includeDetails) {
|
|
167
|
+
if (summary.output) {
|
|
168
|
+
const outputPreview = summary.output.length > 100
|
|
169
|
+
? `${summary.output.slice(0, 100)}...`
|
|
170
|
+
: summary.output;
|
|
171
|
+
text += ` Output: ${outputPreview}\n`;
|
|
172
|
+
}
|
|
173
|
+
if (summary.error) {
|
|
174
|
+
text += ` Error: ${summary.error}\n`;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (text.length > maxLength) {
|
|
179
|
+
text = `${text.slice(0, maxLength)}...\n\n(truncated)`;
|
|
180
|
+
}
|
|
181
|
+
return text;
|
|
182
|
+
}
|
package/dist/bin.js
CHANGED
|
File without changes
|
|
@@ -28,6 +28,8 @@ export declare const AgentDefinitionSchema: z.ZodObject<{
|
|
|
28
28
|
description: z.ZodString;
|
|
29
29
|
fn: z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>;
|
|
30
30
|
schema: z.ZodAny;
|
|
31
|
+
prettyName: z.ZodOptional<z.ZodString>;
|
|
32
|
+
icon: z.ZodOptional<z.ZodString>;
|
|
31
33
|
}, z.core.$strip>]>>>;
|
|
32
34
|
mcps: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
33
35
|
name: z.ZodString;
|
package/dist/definition/index.js
CHANGED
|
@@ -42,6 +42,8 @@ const DirectToolSchema = z.object({
|
|
|
42
42
|
description: z.string(),
|
|
43
43
|
fn: z.function(),
|
|
44
44
|
schema: z.any(), // Accept any Zod schema
|
|
45
|
+
prettyName: z.string().optional(),
|
|
46
|
+
icon: z.string().optional(),
|
|
45
47
|
});
|
|
46
48
|
/** Tool schema - can be a string (built-in tool) or custom tool object. */
|
|
47
49
|
const ToolSchema = z.union([
|
package/dist/definition/mcp.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -16,6 +16,8 @@ export declare const zAgentRunnerParams: z.ZodObject<{
|
|
|
16
16
|
description: z.ZodString;
|
|
17
17
|
fn: z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>;
|
|
18
18
|
schema: z.ZodAny;
|
|
19
|
+
prettyName: z.ZodOptional<z.ZodString>;
|
|
20
|
+
icon: z.ZodOptional<z.ZodString>;
|
|
19
21
|
}, z.core.$strip>]>>>;
|
|
20
22
|
mcps: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
21
23
|
name: z.ZodString;
|
|
@@ -56,7 +58,10 @@ export interface AgentMessageChunkWithTokens {
|
|
|
56
58
|
[key: string]: unknown;
|
|
57
59
|
};
|
|
58
60
|
}
|
|
59
|
-
export type ExtendedSessionUpdate = SessionNotification["update"]
|
|
61
|
+
export type ExtendedSessionUpdate = (SessionNotification["update"] & {
|
|
62
|
+
prettyName?: string;
|
|
63
|
+
icon?: string;
|
|
64
|
+
}) | {
|
|
60
65
|
sessionUpdate: "tool_output";
|
|
61
66
|
toolCallId: string;
|
|
62
67
|
content?: Array<{
|
package/dist/runner/index.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import type { AgentDefinition } from "../definition";
|
|
2
2
|
import { type AgentRunner } from "./agent-runner";
|
|
3
3
|
export type { AgentRunner };
|
|
4
|
-
export declare const makeRunnerFromDefinition: (
|
|
5
|
-
definition: AgentDefinition,
|
|
6
|
-
) => AgentRunner;
|
|
4
|
+
export declare const makeRunnerFromDefinition: (definition: AgentDefinition) => AgentRunner;
|