Skip to content

Commit f1ec7b1

Browse files
committed
fix(demo/ctx): handle pause_turn stop reason and add path traversal guard in research agent
Made-with: Cursor
1 parent dd2ebb7 commit f1ec7b1

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

demo/ctx/src/research.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Anthropic from "@anthropic-ai/sdk";
2+
import path from "path";
23
import { selectMenu, textPrompt } from "./cli.ts";
34
import { readFile, listFiles } from "./files.ts";
45
import { phase, toolCall, dim } from "./ui.ts";
@@ -93,6 +94,11 @@ export async function runResearchAgent(
9394
}
9495
}
9596

97+
if (response.stop_reason === "pause_turn") {
98+
messages.push({ role: "assistant", content: response.content });
99+
continue;
100+
}
101+
96102
if (response.stop_reason !== "tool_use") break;
97103

98104
const toolUses = response.content.filter((b): b is Anthropic.ToolUseBlock => b.type === "tool_use");
@@ -105,11 +111,25 @@ export async function runResearchAgent(
105111
toolCall("web_search", { query: input.query });
106112
toolResults.push({ type: "tool_result", tool_use_id: tool.id, content: "" });
107113
} else if (tool.name === "list_files") {
108-
toolCall("list_files", input);
109-
toolResults.push({ type: "tool_result", tool_use_id: tool.id, content: JSON.stringify(listFiles(input.directory)) });
114+
const resolvedDir = path.resolve(targetDir, input.directory);
115+
const relDir = path.relative(targetDir, resolvedDir);
116+
if (relDir.startsWith("..") || path.isAbsolute(relDir)) {
117+
toolCall("list_files", { directory: input.directory });
118+
toolResults.push({ type: "tool_result", tool_use_id: tool.id, content: "Error: Path outside project root" });
119+
} else {
120+
toolCall("list_files", { directory: resolvedDir });
121+
toolResults.push({ type: "tool_result", tool_use_id: tool.id, content: JSON.stringify(listFiles(resolvedDir)) });
122+
}
110123
} else if (tool.name === "read_file") {
111-
toolCall("read_file", input);
112-
toolResults.push({ type: "tool_result", tool_use_id: tool.id, content: readFile(input.file_path) });
124+
const resolvedFile = path.resolve(targetDir, input.file_path);
125+
const relFile = path.relative(targetDir, resolvedFile);
126+
if (relFile.startsWith("..") || path.isAbsolute(relFile)) {
127+
toolCall("read_file", { file_path: input.file_path });
128+
toolResults.push({ type: "tool_result", tool_use_id: tool.id, content: "Error: Path outside project root" });
129+
} else {
130+
toolCall("read_file", { file_path: resolvedFile });
131+
toolResults.push({ type: "tool_result", tool_use_id: tool.id, content: readFile(resolvedFile) });
132+
}
113133
}
114134
}
115135

0 commit comments

Comments
 (0)