17 price?: number;
18 finish_reason?: string;
19 num_images?: number;
20 our_api_token: boolean;
21}
126 </div>
127 <div class="card-item">
128 <strong>Images:</strong> ${formatNumber(usage.num_images)}
129 </div>
130 <div class="card-item">
29 - [x] File write as a code embed
30 - [x] str_replace as a diff view
31- [x] make image drop area invisible and bigger
32- [x] Give it all the code (except maybe .txt files) as initial context (like cursor sonnet max)
33- [x] I seem to have lost the delete file tool and instructions, try to find them back in history or re-create?
55- [x] Create branch
56- [x] URL input + pathname
57- [x] Image upload controls
58- [x] Preview refresh button
59- [x] Audio controls
155
156- **Redirects:** Use `return new Response(null, { status: 302, headers: { Location: "/place/to/redirect" }})` instead of `Response.redirect` which is broken
157- **Images:** Avoid external images or base64 images. Use emojis, unicode symbols, or icon fonts/libraries instead
158- **AI Image:** To inline generate an AI image use: `<img src="https://maxm-imggenurl.web.val.run/the-description-of-your-image" />`
159- **Storage:** DO NOT use the Deno KV module for storage
160- **Browser APIs:** DO NOT use the `alert()`, `prompt()`, or `confirm()` methods
688 background-color: var(--highlight);
689}
690.card-image {
691 display: flex;
692 align-items: center;
720}
721
722.image-placeholder,
723.image-thumbnail {
724 flex-shrink: 0;
725 width: 40px;
728 object-fit: cover;
729}
730.image-placeholder {
731 background-color: var(--muted);
732}
739}
740
741.image-row {
742 display: flex;
743 gap: var(--space-1);
744}
745.input-image {
746 position: relative;
747 border: 1px solid var(--muted);
748 border-radius: 6px;
749}
750.remove-image-button {
751 position: absolute;
752 top: 0;
761 opacity: 0;
762}
763.input-image:hover .remove-image-button {
764 opacity: 1;
765}
766
767.image-drop-overlay {
768 position: fixed;
769 top: 0;
778 justify-content: center;
779}
780.image-drop-inner {
781 padding: var(--space-2);
782 background-color: var(--background);
858}
859
860.transition, .input-box, .icon-button, .button, .remove-image-button {
861 transition-property: color, background-color, border-color, opacity;
862 transition-duration: 200ms;
29 }
30
31 const { messages, project, branchId, anthropicApiKey, selectedFiles, images } = await c.req.json();
32
33 // do we want to allow user-provided tokens still
55 branch_id: branchId,
56 val_id: project.id,
57 num_images: images?.length || 0,
58 model,
59 });
87 townie_usage_id: rowid,
88 townie_our_api_token: our_api_token,
89 townie_num_images: images?.length || 0,
90 townie_selected_files_count: selectedFiles?.length || 0,
91 },
105 let coreMessages = convertToCoreMessages(messages);
106
107 // If there are images, we need to add them to the last user message
108 if (images && Array.isArray(images) && images.length > 0) {
109 // Find the last user message
110 const lastUserMessageIndex = coreMessages.findIndex(
128 };
129
130 // Add each image to the content array using the correct ImagePart format
131 for (const image of images) {
132 if (image && image.url) {
133 // Extract mime type from data URL if available
134 let mimeType = undefined;
135 if (image.url.startsWith("data:")) {
136 const matches = image.url.match(/^data:([^;]+);/);
137 if (matches && matches.length > 1) {
138 mimeType = matches[1];
141
142 newUserMessage.content.push({
143 type: "image",
144 image: image.url,
145 mimeType,
146 });
19 price?: number;
20 finish_reason?: string;
21 num_images?: number;
22 our_api_token: boolean;
23}
44 price REAL,
45 finish_reason TEXT,
46 num_images INTEGER,
47 our_api_token INTEGER NOT NULL,
48 finish_timestamp INTEGER
16 price: number | null;
17 finish_reason: string | null;
18 num_images: number | null;
19 our_api_token: number;
20}
68 <th>Price</th>
69 <th>Finish</th>
70 <th>Images</th>
71 <th>Our API</th>
72 </tr>
87 <td class="price">${formatPrice(row.price)}</td>
88 <td>${row.finish_reason || '-'}</td>
89 <td>${formatNumber(row.num_images)}</td>
90 <td>${formatBoolean(row.our_api_token)}</td>
91 </tr>
141 model,
142 our_api_token,
143 num_images,
144 tablePrefix = "",
145}: {
149 model: string;
150 our_api_token: boolean;
151 num_images: number;
152 tablePrefix: string;
153}) {
162 model,
163 our_api_token,
164 num_images
165 ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
166 `,
173 model,
174 our_api_token ? 1 : 0,
175 num_images,
176 ],
177 );
29 model,
30 our_api_token,
31 num_images
32 ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
33 `,
44 user: {
45 username: string;
46 profileImageUrl: string | null;
47 };
48 project: any;
50 return (
51 <div className="card">
52 {project.imageUrl ? (
53 <img src={project.imageUrl} className="card-image" />
54 ) : user.profileImageUrl ? (
55 <div className="card-image">
56 <img
57 src={user.profileImageUrl}
58 width="48"
59 height="48"
62 </div>
63 ) : (
64 <div className="card-image placeholder" />
65 )}
66 <div className="card-body">