| 430 | * ``` |
| 431 | */ |
| 432 | export async function analyzeScreenshot( |
| 433 | anthropic: Anthropic, |
| 434 | image: ExtractedImage, |
| 435 | options: ScreenshotAnalysisOptions, |
| 436 | config: { model: string } |
| 437 | ): Promise<{ usage: TokenUsage; responseText: string }> { |
| 438 | const stream = anthropic.messages.stream({ |
| 439 | model: config.model, |
| 440 | max_tokens: 64000, |
| 441 | messages: [ |
| 442 | { |
| 443 | role: "user", |
| 444 | content: [ |
| 445 | { |
| 446 | type: "image", |
| 447 | source: { |
| 448 | type: "base64", |
| 449 | media_type: image.mimeType, |
| 450 | data: image.data, |
| 451 | }, |
| 452 | }, |
| 453 | { |
| 454 | type: "text", |
| 455 | text: options.prompt, |
| 456 | }, |
| 457 | ], |
| 458 | }, |
| 459 | ], |
| 460 | }); |
| 461 | |
| 462 | let responseText = ""; |
| 463 | for await (const event of stream) { |
| 464 | if (event.type === "content_block_delta" && event.delta.type === "text_delta") { |
| 465 | responseText += event.delta.text; |
| 466 | } |
| 467 | } |
| 468 | |
| 469 | const finalMessage = await stream.finalMessage(); |
| 470 | |
| 471 | return { |
| 472 | usage: { |
| 473 | inputTokens: finalMessage.usage.input_tokens, |
| 474 | outputTokens: finalMessage.usage.output_tokens, |
| 475 | }, |
| 476 | responseText, |
| 477 | }; |
| 478 | } |
| 479 | |
| 480 | /** |
| 481 | * Sends a text-only prompt to Claude and returns token usage. |