@townco/agent 0.1.50 ā 0.1.52
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/adapter.d.ts +10 -0
- package/dist/acp-server/adapter.js +287 -80
- package/dist/acp-server/cli.d.ts +1 -3
- package/dist/acp-server/http.js +8 -1
- package/dist/acp-server/index.js +5 -0
- package/dist/acp-server/session-storage.d.ts +17 -3
- package/dist/acp-server/session-storage.js +9 -0
- package/dist/bin.js +0 -0
- package/dist/check-jaeger.d.ts +5 -0
- package/dist/check-jaeger.js +82 -0
- package/dist/definition/index.d.ts +16 -4
- package/dist/definition/index.js +17 -4
- package/dist/index.js +1 -1
- package/dist/run-subagents.d.ts +9 -0
- package/dist/run-subagents.js +110 -0
- package/dist/runner/agent-runner.d.ts +10 -2
- package/dist/runner/agent-runner.js +4 -0
- package/dist/runner/hooks/executor.d.ts +17 -0
- package/dist/runner/hooks/executor.js +66 -0
- package/dist/runner/hooks/predefined/compaction-tool.js +9 -1
- package/dist/runner/hooks/predefined/tool-response-compactor.d.ts +6 -0
- package/dist/runner/hooks/predefined/tool-response-compactor.js +461 -0
- package/dist/runner/hooks/registry.js +2 -0
- package/dist/runner/hooks/types.d.ts +39 -3
- package/dist/runner/hooks/types.js +9 -4
- package/dist/runner/index.d.ts +1 -3
- package/dist/runner/langchain/custom-stream-types.d.ts +36 -0
- package/dist/runner/langchain/custom-stream-types.js +23 -0
- package/dist/runner/langchain/index.js +102 -76
- package/dist/runner/langchain/otel-callbacks.js +67 -1
- package/dist/runner/langchain/tools/bash.d.ts +14 -0
- package/dist/runner/langchain/tools/bash.js +135 -0
- package/dist/scaffold/link-local.d.ts +1 -0
- package/dist/scaffold/link-local.js +54 -0
- package/dist/scaffold/project-scaffold.js +1 -0
- package/dist/telemetry/setup.d.ts +3 -1
- package/dist/telemetry/setup.js +33 -3
- package/dist/templates/index.d.ts +7 -0
- package/dist/test-telemetry.d.ts +5 -0
- package/dist/test-telemetry.js +88 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/context-size-calculator.d.ts +29 -0
- package/dist/utils/context-size-calculator.js +78 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/token-counter.d.ts +19 -0
- package/dist/utils/token-counter.js +44 -0
- package/index.ts +1 -1
- package/package.json +7 -6
- package/templates/index.ts +18 -6
- package/dist/definition/mcp.d.ts +0 -0
- package/dist/definition/mcp.js +0 -0
- 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
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quick script to verify Jaeger connectivity
|
|
3
|
+
* Run with: bun check-jaeger.ts
|
|
4
|
+
*/
|
|
5
|
+
export {}; // Make this a module for top-level await
|
|
6
|
+
console.log("š Checking Jaeger connectivity...\n");
|
|
7
|
+
// Check if Jaeger collector is accepting OTLP on gRPC port
|
|
8
|
+
const checkPort = async (port, protocol) => {
|
|
9
|
+
try {
|
|
10
|
+
const net = await import("node:net");
|
|
11
|
+
const socket = new net.Socket();
|
|
12
|
+
return new Promise((resolve) => {
|
|
13
|
+
socket.setTimeout(2000);
|
|
14
|
+
socket.on("connect", () => {
|
|
15
|
+
console.log(`ā
${protocol} port ${port} is accepting connections`);
|
|
16
|
+
socket.destroy();
|
|
17
|
+
resolve(true);
|
|
18
|
+
});
|
|
19
|
+
socket.on("timeout", () => {
|
|
20
|
+
console.log(`ā ${protocol} port ${port} timed out`);
|
|
21
|
+
socket.destroy();
|
|
22
|
+
resolve(false);
|
|
23
|
+
});
|
|
24
|
+
socket.on("error", (error) => {
|
|
25
|
+
console.log(`ā ${protocol} port ${port} not reachable: ${error.message}`);
|
|
26
|
+
resolve(false);
|
|
27
|
+
});
|
|
28
|
+
socket.connect(port, "localhost");
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
console.log(`ā Error checking ${protocol} port ${port}:`, error);
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
// Check Jaeger ports
|
|
37
|
+
console.log("Checking Jaeger ports:");
|
|
38
|
+
console.log("āāāāāāāāāāāāāāāāāāāāāāāāāāāāā");
|
|
39
|
+
await checkPort(4317, "OTLP gRPC"); // Collector OTLP gRPC
|
|
40
|
+
await checkPort(4318, "OTLP HTTP"); // Collector OTLP HTTP
|
|
41
|
+
await checkPort(16686, "UI "); // Query UI
|
|
42
|
+
console.log("\nš Checking Docker container...\n");
|
|
43
|
+
// Check if Jaeger container is running
|
|
44
|
+
try {
|
|
45
|
+
const { execSync } = await import("node:child_process");
|
|
46
|
+
const output = execSync("docker ps --filter name=jaeger --format '{{.Status}}'", {
|
|
47
|
+
encoding: "utf-8",
|
|
48
|
+
}).trim();
|
|
49
|
+
if (output) {
|
|
50
|
+
console.log(`ā
Jaeger container is running: ${output}`);
|
|
51
|
+
// Check container logs for OTLP
|
|
52
|
+
try {
|
|
53
|
+
const logs = execSync("docker logs jaeger 2>&1 | tail -20", {
|
|
54
|
+
encoding: "utf-8",
|
|
55
|
+
});
|
|
56
|
+
console.log("\nš Recent container logs:");
|
|
57
|
+
console.log("āāāāāāāāāāāāāāāāāāāāāāāāāāāāā");
|
|
58
|
+
console.log(logs);
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
console.log("ā ļø Could not fetch container logs");
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
console.log("ā No Jaeger container running with name 'jaeger'");
|
|
66
|
+
console.log("\nš” Start Jaeger with:");
|
|
67
|
+
console.log("docker run -d --name jaeger \\");
|
|
68
|
+
console.log(" -e COLLECTOR_OTLP_ENABLED=true \\");
|
|
69
|
+
console.log(" -p 16686:16686 \\");
|
|
70
|
+
console.log(" -p 4317:4317 \\");
|
|
71
|
+
console.log(" -p 4318:4318 \\");
|
|
72
|
+
console.log(" jaegertracing/all-in-one:latest");
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
console.log("ā ļø Could not check Docker container:", error);
|
|
77
|
+
}
|
|
78
|
+
console.log("\nšÆ Next steps:");
|
|
79
|
+
console.log("āāāāāāāāāāāāāāāāāāāāāāāāāāāāā");
|
|
80
|
+
console.log("1. Make sure ports above show ā
");
|
|
81
|
+
console.log("2. Run the test: ENABLE_TELEMETRY=true bun test-telemetry.ts");
|
|
82
|
+
console.log("3. Check UI: http://localhost:16686");
|
|
@@ -16,14 +16,22 @@ export declare const McpConfigSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
16
16
|
export declare const HookConfigSchema: z.ZodObject<{
|
|
17
17
|
type: z.ZodEnum<{
|
|
18
18
|
context_size: "context_size";
|
|
19
|
+
tool_response: "tool_response";
|
|
19
20
|
}>;
|
|
20
|
-
setting: z.ZodOptional<z.ZodObject<{
|
|
21
|
+
setting: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
|
|
21
22
|
threshold: z.ZodNumber;
|
|
22
|
-
}, z.core.$strip
|
|
23
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
24
|
+
maxContextThreshold: z.ZodOptional<z.ZodNumber>;
|
|
25
|
+
responseTruncationThreshold: z.ZodOptional<z.ZodNumber>;
|
|
26
|
+
}, z.core.$strip>]>>;
|
|
23
27
|
callback: z.ZodString;
|
|
24
28
|
}, z.core.$strip>;
|
|
25
29
|
/** Agent definition schema. */
|
|
26
30
|
export declare const AgentDefinitionSchema: z.ZodObject<{
|
|
31
|
+
displayName: z.ZodOptional<z.ZodString>;
|
|
32
|
+
version: z.ZodOptional<z.ZodString>;
|
|
33
|
+
description: z.ZodOptional<z.ZodString>;
|
|
34
|
+
suggestedPrompts: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
27
35
|
systemPrompt: z.ZodNullable<z.ZodString>;
|
|
28
36
|
model: z.ZodString;
|
|
29
37
|
tools: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
@@ -56,10 +64,14 @@ export declare const AgentDefinitionSchema: z.ZodObject<{
|
|
|
56
64
|
hooks: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
57
65
|
type: z.ZodEnum<{
|
|
58
66
|
context_size: "context_size";
|
|
67
|
+
tool_response: "tool_response";
|
|
59
68
|
}>;
|
|
60
|
-
setting: z.ZodOptional<z.ZodObject<{
|
|
69
|
+
setting: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
|
|
61
70
|
threshold: z.ZodNumber;
|
|
62
|
-
}, z.core.$strip
|
|
71
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
72
|
+
maxContextThreshold: z.ZodOptional<z.ZodNumber>;
|
|
73
|
+
responseTruncationThreshold: z.ZodOptional<z.ZodNumber>;
|
|
74
|
+
}, z.core.$strip>]>>;
|
|
63
75
|
callback: z.ZodString;
|
|
64
76
|
}, z.core.$strip>>>;
|
|
65
77
|
}, z.core.$strip>;
|
package/dist/definition/index.js
CHANGED
|
@@ -54,16 +54,29 @@ const ToolSchema = z.union([
|
|
|
54
54
|
]);
|
|
55
55
|
/** Hook configuration schema. */
|
|
56
56
|
export const HookConfigSchema = z.object({
|
|
57
|
-
type: z.enum(["context_size"]),
|
|
57
|
+
type: z.enum(["context_size", "tool_response"]),
|
|
58
58
|
setting: z
|
|
59
|
-
.
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
.union([
|
|
60
|
+
// For context_size hooks
|
|
61
|
+
z.object({
|
|
62
|
+
threshold: z.number().min(0).max(100),
|
|
63
|
+
}),
|
|
64
|
+
// For tool_response hooks
|
|
65
|
+
z.object({
|
|
66
|
+
maxContextThreshold: z.number().min(0).max(100).optional(),
|
|
67
|
+
responseTruncationThreshold: z.number().min(0).max(100).optional(),
|
|
68
|
+
}),
|
|
69
|
+
])
|
|
62
70
|
.optional(),
|
|
63
71
|
callback: z.string(),
|
|
64
72
|
});
|
|
65
73
|
/** Agent definition schema. */
|
|
66
74
|
export const AgentDefinitionSchema = z.object({
|
|
75
|
+
/** Human-readable display name for the agent (shown in UI). */
|
|
76
|
+
displayName: z.string().optional(),
|
|
77
|
+
version: z.string().optional(),
|
|
78
|
+
description: z.string().optional(),
|
|
79
|
+
suggestedPrompts: z.array(z.string()).optional(),
|
|
67
80
|
systemPrompt: z.string().nullable(),
|
|
68
81
|
model: z.string(),
|
|
69
82
|
tools: z.array(ToolSchema).optional(),
|
package/dist/index.js
CHANGED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Helper script to test makeSubagentsTool
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* bun packages/agent/run-subagents.ts
|
|
7
|
+
* bun packages/agent/run-subagents.ts "your custom query here"
|
|
8
|
+
*/
|
|
9
|
+
import { makeSubagentsTool } from "./utils";
|
|
10
|
+
import { makeRunnerFromDefinition } from "./runner";
|
|
11
|
+
// Default query if none provided
|
|
12
|
+
const defaultQuery = "Can you search for news about artificial intelligence?";
|
|
13
|
+
const userQuery = process.argv[2] || defaultQuery;
|
|
14
|
+
console.log("š§Ŗ Testing makeSubagentsTool\n");
|
|
15
|
+
console.log("Query:", userQuery);
|
|
16
|
+
console.log("ā".repeat(60));
|
|
17
|
+
// Create a simple subagent definition
|
|
18
|
+
const simpleSubagent = {
|
|
19
|
+
model: "claude-sonnet-4-5-20250929",
|
|
20
|
+
systemPrompt: "You are a helpful research assistant. Provide concise, informative responses.",
|
|
21
|
+
tools: [
|
|
22
|
+
"web_search",
|
|
23
|
+
"todo_write",
|
|
24
|
+
],
|
|
25
|
+
mcps: [],
|
|
26
|
+
};
|
|
27
|
+
// Create the coordinator agent with subagent tool
|
|
28
|
+
const coordinatorAgent = {
|
|
29
|
+
model: "claude-sonnet-4-5-20250929",
|
|
30
|
+
systemPrompt: `You are a coordinator agent that delegates tasks to specialized subagents.
|
|
31
|
+
When you receive a query, evaluate if it needs to be delegated to a subagent.
|
|
32
|
+
If so, use the Task tool with the appropriate subagent.`,
|
|
33
|
+
tools: [
|
|
34
|
+
makeSubagentsTool([
|
|
35
|
+
{
|
|
36
|
+
agentName: "researcher",
|
|
37
|
+
description: "Use this agent to research topics, search the web, and gather information",
|
|
38
|
+
path: import.meta.filename, // Points to itself as a simple test
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
agentName: "simple",
|
|
42
|
+
description: "Use this for general tasks that don't require specialized tools",
|
|
43
|
+
path: import.meta.filename,
|
|
44
|
+
},
|
|
45
|
+
]),
|
|
46
|
+
],
|
|
47
|
+
mcps: [],
|
|
48
|
+
};
|
|
49
|
+
// Run the test
|
|
50
|
+
async function runTest() {
|
|
51
|
+
console.log("\nš Creating runner...");
|
|
52
|
+
const runner = makeRunnerFromDefinition(coordinatorAgent);
|
|
53
|
+
console.log("š Running query...\n");
|
|
54
|
+
try {
|
|
55
|
+
const stream = runner.invoke({
|
|
56
|
+
prompt: [
|
|
57
|
+
{
|
|
58
|
+
type: "text",
|
|
59
|
+
text: userQuery,
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
sessionId: "test-session",
|
|
63
|
+
messageId: "msg-1",
|
|
64
|
+
});
|
|
65
|
+
console.log("š Stream output:");
|
|
66
|
+
console.log("ā".repeat(60));
|
|
67
|
+
let messageCount = 0;
|
|
68
|
+
let toolCallCount = 0;
|
|
69
|
+
let lastTextContent = "";
|
|
70
|
+
for await (const chunk of stream) {
|
|
71
|
+
messageCount++;
|
|
72
|
+
// Pretty print different types of chunks
|
|
73
|
+
if (chunk.type === "agent_message_chunk") {
|
|
74
|
+
const content = chunk.content;
|
|
75
|
+
if (content.type === "text" && content.text) {
|
|
76
|
+
process.stdout.write(content.text);
|
|
77
|
+
lastTextContent += content.text;
|
|
78
|
+
}
|
|
79
|
+
else if (content.type === "tool_use") {
|
|
80
|
+
toolCallCount++;
|
|
81
|
+
console.log(`\n\nš§ Tool Call #${toolCallCount}: ${content.name}`);
|
|
82
|
+
console.log(" Input:", JSON.stringify(content.input, null, 2).split('\n').join('\n '));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else if (chunk.type === "tool_result") {
|
|
86
|
+
console.log("\n\nā
Tool Result:");
|
|
87
|
+
console.log(" ", JSON.stringify(chunk, null, 2).split('\n').join('\n '));
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
// Print other chunk types for debugging
|
|
91
|
+
console.log("\n\nš¦ Chunk:", JSON.stringify(chunk, null, 2));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
console.log("\n\n" + "ā".repeat(60));
|
|
95
|
+
console.log("⨠Test completed!");
|
|
96
|
+
console.log(` Total chunks: ${messageCount}`);
|
|
97
|
+
console.log(` Tool calls: ${toolCallCount}`);
|
|
98
|
+
console.log("ā".repeat(60));
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
console.error("\nā Error during test:");
|
|
102
|
+
console.error(error);
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Run the test
|
|
107
|
+
runTest().catch((error) => {
|
|
108
|
+
console.error("Fatal error:", error);
|
|
109
|
+
process.exit(1);
|
|
110
|
+
});
|
|
@@ -2,6 +2,10 @@ import type { PromptRequest, PromptResponse, SessionNotification } from "@agentc
|
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import type { ContentBlock } from "../acp-server/session-storage.js";
|
|
4
4
|
export declare const zAgentRunnerParams: z.ZodObject<{
|
|
5
|
+
displayName: z.ZodOptional<z.ZodString>;
|
|
6
|
+
version: z.ZodOptional<z.ZodString>;
|
|
7
|
+
description: z.ZodOptional<z.ZodString>;
|
|
8
|
+
suggestedPrompts: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
5
9
|
systemPrompt: z.ZodNullable<z.ZodString>;
|
|
6
10
|
model: z.ZodString;
|
|
7
11
|
tools: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodLiteral<"todo_write">, z.ZodLiteral<"get_weather">, z.ZodLiteral<"web_search">, z.ZodLiteral<"filesystem">]>, z.ZodObject<{
|
|
@@ -33,10 +37,14 @@ export declare const zAgentRunnerParams: z.ZodObject<{
|
|
|
33
37
|
hooks: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
34
38
|
type: z.ZodEnum<{
|
|
35
39
|
context_size: "context_size";
|
|
40
|
+
tool_response: "tool_response";
|
|
36
41
|
}>;
|
|
37
|
-
setting: z.ZodOptional<z.ZodObject<{
|
|
42
|
+
setting: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
|
|
38
43
|
threshold: z.ZodNumber;
|
|
39
|
-
}, z.core.$strip
|
|
44
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
45
|
+
maxContextThreshold: z.ZodOptional<z.ZodNumber>;
|
|
46
|
+
responseTruncationThreshold: z.ZodOptional<z.ZodNumber>;
|
|
47
|
+
}, z.core.$strip>]>>;
|
|
40
48
|
callback: z.ZodString;
|
|
41
49
|
}, z.core.$strip>>>;
|
|
42
50
|
}, z.core.$strip>;
|
|
@@ -2,6 +2,10 @@ import { z } from "zod";
|
|
|
2
2
|
import { HookConfigSchema, McpConfigSchema } from "../definition";
|
|
3
3
|
import { zToolType } from "./tools";
|
|
4
4
|
export const zAgentRunnerParams = z.object({
|
|
5
|
+
displayName: z.string().optional(),
|
|
6
|
+
version: z.string().optional(),
|
|
7
|
+
description: z.string().optional(),
|
|
8
|
+
suggestedPrompts: z.array(z.string()).optional(),
|
|
5
9
|
systemPrompt: z.string().nullable(),
|
|
6
10
|
model: z.string(),
|
|
7
11
|
tools: z.array(zToolType).optional(),
|
|
@@ -20,4 +20,21 @@ export declare class HookExecutor {
|
|
|
20
20
|
* Execute a context_size hook
|
|
21
21
|
*/
|
|
22
22
|
private executeContextSizeHook;
|
|
23
|
+
/**
|
|
24
|
+
* Execute tool_response hooks when a tool returns output
|
|
25
|
+
*/
|
|
26
|
+
executeToolResponseHooks(session: ReadonlySession, currentContextTokens: number, toolResponse: {
|
|
27
|
+
toolCallId: string;
|
|
28
|
+
toolName: string;
|
|
29
|
+
toolInput: Record<string, unknown>;
|
|
30
|
+
rawOutput: Record<string, unknown>;
|
|
31
|
+
outputTokens: number;
|
|
32
|
+
}): Promise<{
|
|
33
|
+
modifiedOutput?: Record<string, unknown>;
|
|
34
|
+
truncationWarning?: string;
|
|
35
|
+
}>;
|
|
36
|
+
/**
|
|
37
|
+
* Execute a single tool_response hook
|
|
38
|
+
*/
|
|
39
|
+
private executeToolResponseHook;
|
|
23
40
|
}
|
|
@@ -106,4 +106,70 @@ export class HookExecutor {
|
|
|
106
106
|
};
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* Execute tool_response hooks when a tool returns output
|
|
111
|
+
*/
|
|
112
|
+
async executeToolResponseHooks(session, currentContextTokens, toolResponse) {
|
|
113
|
+
logger.info(`Executing tool_response hooks - found ${this.hooks.length} hook(s)`, {
|
|
114
|
+
toolCallId: toolResponse.toolCallId,
|
|
115
|
+
toolName: toolResponse.toolName,
|
|
116
|
+
outputTokens: toolResponse.outputTokens,
|
|
117
|
+
});
|
|
118
|
+
for (const hook of this.hooks) {
|
|
119
|
+
if (hook.type === "tool_response") {
|
|
120
|
+
const result = await this.executeToolResponseHook(hook, session, currentContextTokens, toolResponse);
|
|
121
|
+
if (result) {
|
|
122
|
+
return result;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return {}; // No modifications
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Execute a single tool_response hook
|
|
130
|
+
*/
|
|
131
|
+
async executeToolResponseHook(hook, session, currentContextTokens, toolResponse) {
|
|
132
|
+
const maxTokens = getModelMaxTokens(this.model);
|
|
133
|
+
try {
|
|
134
|
+
// Load and execute callback
|
|
135
|
+
const callback = await this.loadCallback(hook.callback);
|
|
136
|
+
// Pass hook settings through requestParams
|
|
137
|
+
const sessionWithSettings = {
|
|
138
|
+
...session,
|
|
139
|
+
requestParams: {
|
|
140
|
+
...session.requestParams,
|
|
141
|
+
hookSettings: hook.setting,
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
const hookContext = {
|
|
145
|
+
session: sessionWithSettings,
|
|
146
|
+
currentTokens: currentContextTokens,
|
|
147
|
+
maxTokens,
|
|
148
|
+
percentage: (currentContextTokens / maxTokens) * 100,
|
|
149
|
+
model: this.model,
|
|
150
|
+
toolResponse,
|
|
151
|
+
};
|
|
152
|
+
const result = await callback(hookContext);
|
|
153
|
+
// Extract modified output and warnings from metadata
|
|
154
|
+
if (result.metadata) {
|
|
155
|
+
const response = {};
|
|
156
|
+
if (result.metadata.modifiedOutput) {
|
|
157
|
+
response.modifiedOutput = result.metadata.modifiedOutput;
|
|
158
|
+
}
|
|
159
|
+
if (result.metadata.truncationWarning) {
|
|
160
|
+
response.truncationWarning = result.metadata
|
|
161
|
+
.truncationWarning;
|
|
162
|
+
}
|
|
163
|
+
return response;
|
|
164
|
+
}
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
logger.error("Tool response hook execution failed", {
|
|
169
|
+
callback: hook.callback,
|
|
170
|
+
error: error instanceof Error ? error.message : String(error),
|
|
171
|
+
});
|
|
172
|
+
return null; // Return original output on error
|
|
173
|
+
}
|
|
174
|
+
}
|
|
109
175
|
}
|
|
@@ -99,7 +99,15 @@ Please provide your summary based on the conversation above, following this stru
|
|
|
99
99
|
const summaryEntry = createFullMessageEntry("user", `This session is being continued from a previous conversation that ran out of context. The conversation is summarized below:\n${summaryText}`);
|
|
100
100
|
// Set compactedUpTo to indicate all messages have been compacted into the summary
|
|
101
101
|
const lastMessageIndex = messagesToCompact.length - 1;
|
|
102
|
-
const newContextEntry = createContextEntry([summaryEntry], undefined, lastMessageIndex,
|
|
102
|
+
const newContextEntry = createContextEntry([summaryEntry], undefined, lastMessageIndex, {
|
|
103
|
+
// Store summary tokens in userMessagesTokens since the summary is a user message
|
|
104
|
+
systemPromptTokens: 0,
|
|
105
|
+
userMessagesTokens: summaryTokens,
|
|
106
|
+
assistantMessagesTokens: 0,
|
|
107
|
+
toolInputTokens: 0,
|
|
108
|
+
toolResultsTokens: 0,
|
|
109
|
+
totalEstimated: summaryTokens,
|
|
110
|
+
});
|
|
103
111
|
return {
|
|
104
112
|
newContextEntry,
|
|
105
113
|
metadata: {
|