Skip to content

Add annotation tool to highlight changed elements in preview#565

Open
abi wants to merge 2 commits intomainfrom
claude/add-annotate-tool-sX5PE
Open

Add annotation tool to highlight changed elements in preview#565
abi wants to merge 2 commits intomainfrom
claude/add-annotate-tool-sX5PE

Conversation

@abi
Copy link
Owner

@abi abi commented Feb 27, 2026

Summary

This PR adds a new annotate tool that allows the agent to highlight and describe changed elements in the preview pane. When the agent completes code edits, it can call the annotate tool to visually mark which elements were modified and provide descriptions of the changes.

Key Changes

  • Backend - Tool Definition & Runtime

    • Added annotate tool definition in backend/agent/tools/definitions.py with schema for CSS selectors and change descriptions
    • Implemented _annotate() method in backend/agent/tools/runtime.py to validate and process annotation data
    • Added annotation summarization in backend/agent/tools/summaries.py to display annotations in activity logs
    • Updated system prompt to document the new annotate tool
  • Frontend - Preview Component

    • Added Annotation interface to PreviewComponent.tsx with selector and description fields
    • Implemented annotation highlighting logic that:
      • Injects CSS with a pulsing amber outline animation
      • Applies highlights to elements matching the provided CSS selectors
      • Adds tooltip descriptions via title attributes
      • Handles iframe load timing and cleanup
    • Integrated annotations into PreviewPane.tsx to extract and pass them from completed agent events
  • Frontend - Activity Display

    • Added annotation event rendering in AgentActivity.tsx with:
      • Tag icon (BsTag) for visual identification
      • Display of CSS selectors and descriptions in amber-themed cards
      • Proper event title handling for running/complete states

Implementation Details

  • Annotations are applied inside the iframe with a 2-second pulsing animation (3 iterations) using amber color (rgba(245, 158, 11))
  • Invalid CSS selectors are silently skipped to prevent errors
  • The annotation effect is cleaned up when the component unmounts or annotations change
  • Annotations are extracted from the most recent completed annotate tool event in the current variant

https://claude.ai/code/session_01S3R2LH589n6nrSAJkfeDg8

Adds a new `annotate` tool that the model calls after completing all code
edits to highlight what was changed. Each annotation includes a label and
a one-sentence description. The system prompt instructs the model to call
it exactly once before returning its final response.

Backend: tool schema, runtime handler, and input summarizer.
Frontend: amber-themed display in AgentActivity with BsTag icon.

https://claude.ai/code/session_01S3R2LH589n6nrSAJkfeDg8
Replace the label field with a CSS selector so annotations can target
actual DOM elements. The PreviewComponent now injects a pulsing amber
outline into the iframe for each matched selector after the iframe
loads. PreviewPane extracts annotations from completed annotate tool
events and passes them down. System prompt and tool description updated
to instruct the model to provide CSS selectors.

https://claude.ai/code/session_01S3R2LH589n6nrSAJkfeDg8
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b0f6f61705

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +373 to +374
selector = ensure_str(annotation.get("selector"))
description = ensure_str(annotation.get("description"))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Guard non-object annotations before reading selector

The new annotate runtime only validates that annotations is a non-empty list, then immediately calls annotation.get(...) on each item. If the model emits malformed JSON like annotations: ["#hero"] or [null], this throws an AttributeError instead of returning a structured tool error, which can abort the tool-execution turn rather than producing a recoverable failure result.

Useful? React with 👍 / 👎.

if (!currentCommit) return [];
const variant = currentCommit.variants[currentCommit.selectedVariantIndex];
const events = variant?.agentEvents || [];
for (const event of events) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Select the latest completed annotate event

This extraction returns as soon as it sees the first completed annotate event, but agent events are appended in chronological order (newest at the end), so multiple annotate calls in one variant (e.g., retries) will display stale highlights from the oldest event. The preview should read the most recent completed annotation payload instead.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants