Skip to content

Commit c5daeaf

Browse files
committed
clean up
1 parent 2f67908 commit c5daeaf

File tree

4 files changed

+40
-32
lines changed

4 files changed

+40
-32
lines changed

apps/web/client/src/app/project/[id]/_components/right-panel/chat-tab/chat-messages/message-content/tool-call-display.tsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import {
1010
TYPECHECK_TOOL_NAME,
1111
UPLOAD_IMAGE_TOOL_NAME,
1212
type UPLOAD_IMAGE_TOOL_PARAMETERS,
13+
VIEW_IMAGE_TOOL_NAME,
14+
type VIEW_IMAGE_TOOL_PARAMETERS,
1315
WEB_SEARCH_TOOL_NAME,
1416
type WEB_SEARCH_TOOL_PARAMETERS,
1517
WRITE_FILE_TOOL_NAME,
@@ -91,6 +93,29 @@ export const ToolCallDisplay = ({
9193
}
9294
}
9395

96+
if (toolName === VIEW_IMAGE_TOOL_NAME) {
97+
const args = toolPart.input as z.infer<typeof VIEW_IMAGE_TOOL_PARAMETERS> | null;
98+
const result = toolPart.output as { message: string } | null;
99+
return (
100+
<div className="flex flex-col gap-2 p-3 border rounded-lg bg-background-secondary">
101+
<div className="flex items-center gap-2">
102+
<Icons.Image className="w-4 h-4" />
103+
<span className="text-sm font-medium">View Image</span>
104+
</div>
105+
{args?.image_reference && (
106+
<div className="text-xs text-foreground-secondary">
107+
Image: {args.image_reference}
108+
</div>
109+
)}
110+
{result?.message && (
111+
<div className="text-xs text-green-600 mt-1">
112+
{result.message}
113+
</div>
114+
)}
115+
</div>
116+
);
117+
}
118+
94119
if (toolName === UPLOAD_IMAGE_TOOL_NAME) {
95120
const args = toolPart.input as z.infer<typeof UPLOAD_IMAGE_TOOL_PARAMETERS> | null;
96121
const result = toolPart.output as string | null;

apps/web/client/src/app/project/[id]/_components/right-panel/chat-tab/chat-messages/message-content/tool-call-simple.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import {
3030
TYPECHECK_TOOL_NAME,
3131
UPLOAD_IMAGE_TOOL_NAME,
3232
type UPLOAD_IMAGE_TOOL_PARAMETERS,
33+
VIEW_IMAGE_TOOL_NAME,
34+
type VIEW_IMAGE_TOOL_PARAMETERS,
3335
WEB_SEARCH_TOOL_NAME,
3436
type WEB_SEARCH_TOOL_PARAMETERS,
3537
WRITE_FILE_TOOL_NAME,
@@ -62,6 +64,7 @@ const TOOL_ICONS: Record<string, any> = {
6264
[TYPECHECK_TOOL_NAME]: Icons.MagnifyingGlass,
6365
[LIST_BRANCHES_TOOL_NAME]: Icons.Branch,
6466
[GLOB_TOOL_NAME]: Icons.MagnifyingGlass,
67+
[VIEW_IMAGE_TOOL_NAME]: Icons.Image,
6568
[UPLOAD_IMAGE_TOOL_NAME]: Icons.Image,
6669
} as const;
6770

@@ -220,6 +223,14 @@ const getLabel = (toolName: string, toolPart: ToolUIPart) => {
220223
return 'Reading Onlook instructions';
221224
case TYPECHECK_TOOL_NAME:
222225
return 'Checking types';
226+
case VIEW_IMAGE_TOOL_NAME: {
227+
const params = toolPart.input as z.infer<typeof VIEW_IMAGE_TOOL_PARAMETERS>;
228+
if (params?.image_reference) {
229+
return 'Viewing image ' + truncateString(params.image_reference);
230+
} else {
231+
return 'Viewing image';
232+
}
233+
}
223234
case UPLOAD_IMAGE_TOOL_NAME: {
224235
const params = toolPart.input as z.infer<typeof UPLOAD_IMAGE_TOOL_PARAMETERS>;
225236
if (params?.image_reference) {

apps/web/client/src/components/tools/handlers/edit.ts

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
WRITE_FILE_TOOL_PARAMETERS
1010
} from '@onlook/ai';
1111
import { MessageContextType } from '@onlook/models';
12+
import { v4 as uuidv4 } from 'uuid';
1213
import { z } from 'zod';
1314

1415
export async function handleSearchReplaceEditFileTool(args: z.infer<typeof SEARCH_REPLACE_EDIT_FILE_TOOL_PARAMETERS>, editorEngine: EditorEngine): Promise<string> {
@@ -187,7 +188,6 @@ export async function handleViewImageTool(args: z.infer<typeof VIEW_IMAGE_TOOL_P
187188
});
188189

189190
if (!imageContext || imageContext.type !== MessageContextType.IMAGE) {
190-
// Try to find by index number
191191
const imageContexts = context.filter(ctx => ctx.type === MessageContextType.IMAGE);
192192
const indexMatch = args.image_reference.match(/^\d+$/);
193193
if (indexMatch) {
@@ -228,75 +228,55 @@ export async function handleUploadImageTool(args: z.infer<typeof UPLOAD_IMAGE_TO
228228
throw new Error(`Sandbox not found for branch ID: ${args.branchId}`);
229229
}
230230

231-
// Find the image in the chat context by reference
232231
const context = editorEngine.chat.context.context;
233232
const imageContext = context.find((ctx) => {
234233
if (ctx.type !== MessageContextType.IMAGE) {
235234
return false;
236235
}
237-
// Try to match by display name or description
238236
return ctx.displayName.toLowerCase().includes(args.image_reference.toLowerCase()) ||
239237
args.image_reference.toLowerCase().includes(ctx.displayName.toLowerCase());
240238
});
241239

242240
if (!imageContext || imageContext.type !== MessageContextType.IMAGE) {
243-
// Try to find the most recent image if no specific match
244241
const recentImages = context.filter(ctx => ctx.type === MessageContextType.IMAGE);
245242
if (recentImages.length === 0) {
246243
throw new Error(`No image found matching reference: ${args.image_reference}`);
247244
}
248245

249-
// Use the most recent image if no specific match
250246
const mostRecentImage = recentImages[recentImages.length - 1];
251247
if (!mostRecentImage || mostRecentImage.type !== MessageContextType.IMAGE) {
252248
throw new Error(`No image found matching reference: ${args.image_reference}`);
253249
}
254250

255251
console.warn(`No exact match for "${args.image_reference}", using most recent image: ${mostRecentImage.displayName}`);
256252

257-
// Extract MIME type and file extension
258253
const mimeType = mostRecentImage.mimeType;
259254
const extension = getExtensionFromMimeType(mimeType);
260255

261-
// Generate filename
262-
const filename = args.filename ? `${args.filename}.${extension}` : `${generateUUID()}.${extension}`;
263-
264-
// Determine destination path
256+
const filename = args.filename ? `${args.filename}.${extension}` : `${uuidv4()}.${extension}`;
265257
const destinationPath = args.destination_path || 'public/assets/images';
266258
const fullPath = `${destinationPath}/${filename}`;
267259

268-
// Convert base64 to binary data
269260
const base64Data = mostRecentImage.content.replace(/^data:image\/[a-z]+;base64,/, '');
270261
const binaryData = base64ToUint8Array(base64Data);
271262

272-
// Upload to sandbox
273263
await sandbox.writeBinaryFile(fullPath, binaryData);
274-
275-
// Refresh image scanning to update the UI
276264
await editorEngine.image.scanImages();
277265

278266
return `Image "${mostRecentImage.displayName}" uploaded successfully to ${fullPath}`;
279267
}
280268

281-
// Extract MIME type and file extension
282269
const mimeType = imageContext.mimeType;
283270
const extension = getExtensionFromMimeType(mimeType);
284271

285-
// Generate filename
286-
const filename = args.filename ? `${args.filename}.${extension}` : `${generateUUID()}.${extension}`;
287-
288-
// Determine destination path
272+
const filename = args.filename ? `${args.filename}.${extension}` : `${uuidv4()}.${extension}`;
289273
const destinationPath = args.destination_path || 'public/assets/images';
290274
const fullPath = `${destinationPath}/${filename}`;
291275

292-
// Convert base64 to binary data
293276
const base64Data = imageContext.content.replace(/^data:image\/[a-z]+;base64,/, '');
294277
const binaryData = base64ToUint8Array(base64Data);
295278

296-
// Upload to sandbox
297279
await sandbox.writeBinaryFile(fullPath, binaryData);
298-
299-
// Refresh image scanning to update the UI
300280
await editorEngine.image.scanImages();
301281

302282
return `Image "${imageContext.displayName}" uploaded successfully to ${fullPath}`;
@@ -327,11 +307,3 @@ function base64ToUint8Array(base64: string): Uint8Array {
327307
}
328308
return bytes;
329309
}
330-
331-
function generateUUID(): string {
332-
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
333-
const r = Math.random() * 16 | 0;
334-
const v = c === 'x' ? r : (r & 0x3 | 0x8);
335-
return v.toString(16);
336-
});
337-
}

packages/ai/src/prompt/provider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ export function getHydratedUserMessage(
110110
.join('\n');
111111
prompt += wrapXml('instruction', textContent);
112112

113-
// Add image references to prompt (but don't send image data yet)
113+
// Add image references to prompt (but doesnt send image data yet)
114114
// AI will decide whether to view or upload them using tools
115115
if (images.length > 0) {
116116
const imageList = images

0 commit comments

Comments
 (0)