townie-126Messages.tsx9 matches
256</>
257);
258case "fetch":
259return (
260<Details
269summary={(
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' :
280result.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>
townie-126index.ts1 match
215});
216217export default app.fetch;
218
townie-126index.ts1 match
2728// This is the entry point for HTTP vals
29export default app.fetch;
30
townie-126index.ts2 matches
1import { makeChangeValTypeTool } from "./change-val-type.ts";
2import { makeFetchTool } from "./fetch.ts";
3import { makeTextEditorTool } from "./text-editor.ts";
4import { makeTracesTool } from "./traces.ts";
8makeTextEditorTool,
9makeChangeValTypeTool,
10makeFetchTool,
11makeTracesTool,
12thinkTool,
townie-126fetch.ts5 matches
11* Creates a tool for making HTTP requests to vals in a Val Town project
12*/
13export const makeFetchTool = (
14{ bearerToken, project, branch_id }: { bearerToken?: string; project?: any; branch_id?: string } = {},
15) =>
16tool({
17name: "fetch",
18description: "Make an HTTP request to a Val Town val and return the response. Useful for testing HTTP vals. The HTTP response body will be truncated to 5000 characters.",
19parameters: z.object({
68return {
69type: "error",
70message: `Error fetching val at path '${valPath}': ${error.message}`,
71};
72}
83return {
84type: "error",
85message: `The val at path '${valPath}' is not an HTTP val. Only HTTP vals can be called with fetch.`,
86};
87}
111let response;
112try {
113response = await fetch(valEndpoint + urlPath, options);
114} catch (error: any) {
115// Return error information
townie-126.cursorrules3 matches
239
240// Inject data to avoid extra round-trips
241const initialData = await fetchInitialData();
242const dataScript = `<script>
243window.__INITIAL_DATA__ = ${JSON.stringify(initialData)};
2862875. **API Design:**
288- `fetch` handler is the entry point for HTTP vals
289- Run the Hono app with `export default app.fetch // This is the entry point for HTTP vals`
290291
townie-126CreditBalance.tsx5 matches
7const [loading, setLoading] = useState(true);
89const fetchBalance = async () => {
10try {
11const response = await fetch("/api/credit-balance");
12if (response.ok) {
13const data = await response.json();
15setBalance(data.balance);
16} else {
17console.error("Failed to fetch balance");
18}
19} catch (err) {
20console.error("Error fetching balance:", err);
21} finally {
22setLoading(false);
2526useEffect(() => {
27fetchBalance();
28}, []);
29
townie-126ChatRouteSingleColumn.tsx13 matches
51files={project.data?.files}
52branchId={branchId}
53refetch={project.refetch}
54/>
55</ProjectContext.Provider>
61files,
62branchId,
63refetch,
64}: {
65project: any;
66files: any[];
67branchId: string;
68refetch: () => void;
69}) {
70const [images, setImages] = useState<(string|null)[]>([]);
71const [selectedFiles, setSelectedFiles] = useState<string[]>([]);
72const { audio, user } = useContext(AppContext);
73const { balance, loading: balanceLoading, refetch: refetchBalance } = useCreditBalance();
7475const {
94useLoadingFavicon(running);
9596// Track when requests end and refetch balance
97const prevRunning = useRef(running);
98useEffect(() => {
99// If running changed from true to false, request just ended
100if (prevRunning.current === true && running === false) {
101refetchBalance();
102}
103prevRunning.current = running;
104}, [running, refetchBalance]);
105106// Auto-poll balance every 4 seconds when credits are insufficient
110if (hasInsufficientCredits) {
111const intervalId = setInterval(() => {
112refetchBalance();
113}, 4000); // 4 seconds
114
115return () => clearInterval(intervalId);
116}
117}, [balanceLoading, balance, refetchBalance]);
118119useEffect(() => {
120if (!messages?.length) return;
121let last = messages.at(-1);
122if (shouldRefetch(last)) {
123refetch();
124}
125}, [messages]);
196<button
197onClick={() => {
198refetchBalance();
199}}
200className="icon-button"
227}
228229function shouldRefetch (message) {
230for (let i = 0; i < message?.parts?.length; i++) {
231let part = message.parts[i];
townie-126BranchSelect.tsx1 match
32return;
33}
34branches.refetch();
35if (res?.branch?.id) {
36navigate(`/chat/${projectId}/branch/${res.branch.id}`);
Louoauth_handler.tsx2 matches
62});
6364const response = await fetch(tokenUrl, {
65method: "POST",
66headers: {
96});
9798const response = await fetch(tokenUrl, {
99method: "POST",
100headers: {