Skip to content

feat: carry selected excerpt through composer integration references - #1024

Draft
adriandemian wants to merge 6 commits into
mainfrom
ralphx/ralphx/agent-392587e7
Draft

feat: carry selected excerpt through composer integration references#1024
adriandemian wants to merge 6 commits into
mainfrom
ralphx/ralphx/agent-392587e7

Conversation

@adriandemian

@adriandemian adriandemian commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

Added support for carrying user-selected excerpt text from artifact surfaces (tickets, PRs, Granola notes) through the chat composer into agent prompt expansion. Three new optional fields on ComposerIntegrationReference: selectedExcerpt, selectedSourcePath, and selectedRangeLabel.

Excerpt text is appended to the expanded prompt even when no full-expansion service is available for that provider (e.g., ClickUp), and is rendered as a clearly labeled <selected_context> fence with fully escaped content to prevent injection.

User Impact

Agents can now see relevant context the user highlights from artifact surfaces without relying on provider expansion services to be wired. The selected text is marked as untrusted external context and never treated as instructions.

Technical Context

Frontend (frontend/src/api/chat.ts, frontend/src/components/agents/composer/agentComposerCore.ts):

  • Three optional fields on ComposerIntegrationReference
  • Normalization with bounds (COMPOSER_SELECTED_EXCERPT_MAX_LENGTH = 4000) and safety checks in normalizeComposerIntegrationReferences

Backend (src-tauri/src/domain/services/message_queue.rs):

  • Struct fields with Default derive added; all existing literals updated

Expansion (src-tauri/src/application/integration_reference_expansion.rs):

  • New append_selected_excerpts_for_prompt() appends excerpts after standard provider expansions, remaining within MAX_TOTAL_INTEGRATION_REFERENCE_BYTES budget
  • format_selected_excerpt_block() renders <selected_context provider="..." kind="..." id="..." source="..." range="..."> fence with every value escaped via escape_attr() (body and attributes both escaped)
  • safe_selected_attribute_value() validates selected_source_path and selected_range_label, dropping values with null bytes or newlines
  • clamp_selected_excerpt() truncates on a UTF-8 character boundary (server-side max 16 KiB, matching MAX_SELECTED_EXCERPT_BYTES)
  • Fold-in: excerpts skip attachment for references already marked BudgetExceeded during the expansion phase

Tests: Comprehensive coverage added to integration_reference_expansion_tests.rs (body injection, attribute breakout, newline filtering, character-boundary clamping, budget interaction); mechanical struct-literal updates across ~23 test files.

Risks / Follow-Ups

  • Frontend and backend excerpt limits differ (4 KB vs 16 KB) intentionally: frontend clamps input, backend clamps render. No truncation surprise, but worth awareness.
  • Excerpt body is marked untrusted external context in the prompt; agents should not execute or treat as instructions.
  • User-facing UI surfaces for selecting and attaching excerpts (from tickets, PRs, Granola) are follow-up work per the original goal statement.

Generated by RalphX


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Resolve conflicts from the selected-excerpt composer work against upstream:
- keep both provider_unavailable_skips (main) and the selected-excerpt
  prompt helpers (workspace)
- drop the inline chat_service_queue test module in favour of main's
  extracted chat_service_queue_tests.rs
- update ComposerIntegrationReference literals added upstream for the
  three new selected_* fields
…rences

Escape every interpolated value in format_selected_excerpt_block via the
shared chat_service::escape_attr helper so an excerpt containing a literal
</selected_context> cannot close the untrusted-context fence and a quote in
selected_source_path cannot break out of its attribute. Drop structurally
unsafe attribute values (empty/NUL/CR/LF) and clamp the excerpt server-side
at 16 KiB on a UTF-8 character boundary.

Also pass expandable_references to append_selected_excerpts_for_prompt so
references already recorded as BudgetExceeded skips no longer bypass the
reference count cap.
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.

1 participant