14 calculatePartialUsageFromInferenceCalls,
15} from "../database/queries.tsx";
16import { makeChangeValTypeTool, makeFetchTool, makeTextEditorTool, makeTracesTool } from "../tools/index.ts";
17import fileWithLinesNumbers from "../utils/fileWithLinesNumbers.ts";
18
153 }
154
155 // If there are selected files, fetch their content and add them to the messages
156 if (selectedFiles && selectedFiles.length > 0) {
157 const vt = new ValTown({ bearerToken });
173 fileContents += `## File: ${filePath}\n\`\`\`\n${fileWithLinesNumbers(content)}\n\`\`\`\n\n`;
174 } catch (error) {
175 console.error(`Error fetching file ${filePath}:`, error);
176 fileContents += `## File: ${filePath}\nError: Could not fetch file content\n\n`;
177 }
178 }
218 // think: thinkTool,
219 change_val_type: makeChangeValTypeTool({ bearerToken, project, branch_id: branchId }),
220 fetch: makeFetchTool({ bearerToken, project, branch_id: branchId }),
221 requests: makeTracesTool({ bearerToken, project, branch_id: branchId }),
222 },
8
9- **AI-Assisted Editing**: Chat with Claude 4 Sonnet about your code and let it make changes directly to your project files
10- **Fetch tool**: Townie is able to make HTTP calls to your HTTP services to test them and continue iterating
11- **Branch Management**: View, select, and create branches without leaving the app
12- **Sound Notifications**: Get alerted when Claude finishes responding
73 });
74
75 const response = await fetch("https://api.stripe.com/v1/payment_intents", {
76 method: "POST",
77 headers: {
10
11 useEffect(() => {
12 fetchBalance();
13 }, []);
14
15 const fetchBalance = async () => {
16 try {
17 const response = await fetch("/api/credit-balance");
18 if (response.ok) {
19 const data = await response.json();
21 }
22 } catch (err) {
23 console.error("Failed to fetch balance:", err);
24 }
25 };
35
36 try {
37 const response = await fetch("/api/purchase-credits", {
38 method: "POST",
39 headers: { "Content-Type": "application/json" },
30 return c.json({ files: files.data });
31 } catch (error) {
32 console.error("Error fetching project files:", error);
33 return Response.json({ error: "Failed to fetch project files" }, { status: 500 });
34 }
35});
21 return c.json({ branches: branches.data });
22 } catch (error) {
23 console.error("Error fetching branches:", error);
24 return Response.json({ error: "Failed to fetch branches" }, { status: 500 });
25 }
26});
19solution that changes as little code as possible.
20
21Use your 'fetch' tool to debug HTTP vals making requests to them and examining the responses.
22
23Use your 'requests' tool to debug all kinds of vals. It'll show you the logs made during the file execution and the attributes associated it, including headers, http status, run time, error messages and error stack traces.
256 </>
257 );
258 case "fetch":
259 return (
260 <Details
269 summary={(
270 <>
271 <div>fetch:</div>
272 <div>{args?.valPath}</div>
273 <div>{args?.urlPath || "/"}</div>
275 )}>
276 {result?.type === "success" ? (
277 <div className="fetch-result">
278 <div className="fetch-header">
279 <span className={`status-badge ${result.data.status >= 200 && result.data.status < 300 ? 'success' :
280 result.data.status >= 300 && result.data.status < 400 ? 'redirect' :
284 <span className="response-time">{result.data.responseTime}ms</span>
285 </div>
286 <div className="fetch-section">
287 <h4>Headers</h4>
288 <pre className="fetch-headers">{JSON.stringify(result.data.headers, null, 2)}</pre>
289 </div>
290 <div className="fetch-section">
291 <h4>Response Body</h4>
292 <pre className="fetch-body">
293 {typeof result.data.body === 'object'
294 ? JSON.stringify(result.data.body, null, 2)
298 </div>
299 ) : (
300 <div className="fetch-error">
301 <h4>Error</h4>
302 <pre>{result?.message || "Unknown error"}</pre>
215});
216
217export default app.fetch;
218
27
28// This is the entry point for HTTP vals
29export default app.fetch;
30