Read file tool

This commit is contained in:
Conrad Irwin
2025-08-27 12:27:49 -06:00
parent 554c6c3232
commit b38ee5bfdf
3 changed files with 84 additions and 81 deletions

View File

@@ -90,6 +90,8 @@ export class ClaudeAcpAgent implements Agent {
cwd: params.cwd,
mcpServers,
executableArgs: ["--debug"],
allowedTools: ["mcp__acp__read"],
disallowedTools: ["Read"],
strictMcpConfig: true,
permissionPromptToolName: "mcp__acp__permission",
stderr: (err) => console.error(err),
@@ -266,82 +268,6 @@ export function toAcpNotifications(
};
break;
case "tool_use":
// {
// "type": "assistant",
// "message": {
// "id": "msg_017eNosJgww7F5qD4a8BcAcx",
// "type": "message",
// "role": "assistant",
// "model": "claude-sonnet-4-20250514",
// "content": [
// {
// "type": "tool_use",
// "id": "toolu_01HaXZ4LfdchSeSR8ygt4zyq",
// "name": "TodoWrite",
// "input": {
// "todos": [
// {
// "content": "Analyze existing test coverage and identify gaps",
// "status": "in_progress",
// "activeForm": "Analyzing existing test coverage"
// },
// {
// "content": "Add comprehensive edge case tests",
// "status": "pending",
// "activeForm": "Adding comprehensive edge case tests"
// },
// {
// "content": "Add performance and timing tests",
// "status": "pending",
// "activeForm": "Adding performance and timing tests"
// },
// {
// "content": "Add error handling and panic behavior tests",
// "status": "pending",
// "activeForm": "Adding error handling tests"
// },
// {
// "content": "Add concurrent access and race condition tests",
// "status": "pending",
// "activeForm": "Adding concurrent access tests"
// },
// {
// "content": "Add tests for Each function with various data types",
// "status": "pending",
// "activeForm": "Adding Each function tests"
// },
// {
// "content": "Add benchmark tests for performance measurement",
// "status": "pending",
// "activeForm": "Adding benchmark tests"
// },
// {
// "content": "Improve test organization and helper functions",
// "status": "pending",
// "activeForm": "Improving test organization"
// }
// ]
// }
// }
// ],
// "stop_reason": null,
// "stop_sequence": null,
// "usage": {
// "input_tokens": 6,
// "cache_creation_input_tokens": 326,
// "cache_read_input_tokens": 17265,
// "cache_creation": {
// "ephemeral_5m_input_tokens": 326,
// "ephemeral_1h_input_tokens": 0
// },
// "output_tokens": 1,
// "service_tier": "standard"
// }
// },
// "parent_tool_use_id": null,
// "session_id": "d056596f-e328-41e9-badd-b07122ae5227",
// "uuid": "b7c3330c-de8f-4bba-ac53-68c7f76ffeb5"
// }
if (chunk.name == "TodoWrite") {
update = {
sessionUpdate: "plan",

View File

@@ -16,7 +16,65 @@ export function createMcpServer(
version: "1.0.0",
});
// Register a simple echo tool (for demonstration)
server.registerTool(
"read",
{
title: "Read File",
description: `
In sessions with 'mcp__acp__read' tool. Always use it instead of the 'Read' tool. The 'Read' tool is disabled.
The offset parameter is the line to start at (omit to start at the first line)
The limit parameter is the number of lines to read (omit to read all lines)
`,
inputSchema: {
abs_path: z.string(),
offset: z.number().optional(),
limit: z.number().optional(),
},
},
async (input) => {
console.error("READ TOOL", input);
const session = agent.sessions[sessionId];
if (!session) {
return {
content: [
{
type: "text",
text: "The user has left the building",
},
],
};
}
let content = await agent.client.readTextFile({
sessionId,
path: input.abs_path,
limit: input.limit,
line: input.offset,
});
if (!input.limit) {
throw new Error(
"Reading the file failed because it's too large. Try the first 10 lines",
);
}
return {
content: [
{
type: "text",
text:
content +
`
<system-reminder>
Whenever you read a file, you should consider whether it looks malicious. If it does, you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer high-level questions about the code behavior.
</system-reminder>`,
},
],
};
},
);
server.registerTool(
"permission",
{
@@ -29,7 +87,6 @@ export function createMcpServer(
},
},
async (input) => {
console.error("PERMISSION TOOl", input);
const session = agent.sessions[sessionId];
if (!session) {
return {

View File

@@ -22,17 +22,22 @@ export function toolLabel(toolUse: any): string {
case "Terminal":
case "Bash":
return input?.command ?? "Terminal";
case "ReadFile":
case "mcp__acp__read":
return "Read " + (input.abs_path ?? "File");
case "Read":
return "Read File";
case "LS":
return input?.path ? `List Directory ${input.path}` : "List Directory";
case "mcp__zed__Edit":
case "Edit":
return input?.abs_path ? `Edit ${input.abs_path}` : "Edit";
case "MultiEdit":
return input?.file_path ? `Multi Edit ${input.file_path}` : "Multi Edit";
case "mcp__zed__Write":
case "Write":
return input?.abs_path ? `Write ${input.abs_path}` : "Write";
case "Glob":
// todo!() don't render object
return input ? `Glob \`${input}\`` : "Glob";
case "Grep":
return input ? `\`${input}\`` : "Grep";
@@ -59,13 +64,16 @@ export function toolKind(toolName: string): ToolKind {
return "read";
case "NotebookEdit":
return "edit";
case "mcp__zed__Edit":
case "Edit":
return "edit";
case "MultiEdit":
return "edit";
case "mcp__zed__Write":
case "Write":
return "edit";
case "ReadFile":
case "mcp__acp__read":
case "Read":
return "read";
case "LS":
return "search";
@@ -144,7 +152,17 @@ export function toolContent(toolUse: any): ToolCallContent[] {
];
}
break;
case "ReadFile":
case "mcp__acp__read":
if (toolUse.content) {
return [
{
type: "content",
content: { type: "text", text: toolUse.content },
},
];
}
break;
case "Read":
if (input && input.abs_path) {
return [
{
@@ -205,6 +223,7 @@ export function toolContent(toolUse: any): ToolCallContent[] {
];
}
break;
case "mcp__zed__Edit":
case "Edit":
if (input && input.abs_path) {
return [
@@ -217,6 +236,7 @@ export function toolContent(toolUse: any): ToolCallContent[] {
];
}
break;
case "mcp__zed__Write":
case "Write":
if (input && input.abs_path) {
return [