Repository navigation
FEAT GUI: Import dataset prompts and conversations into chat #2751
Description
Is your feature request related to a problem? Please describe.
After inspecting a dataset example, users should be able to use it in chat without copying text, reattaching media, or rebuilding a conversation turn by turn. This includes prepending an entire stored conversation, not just importing a single prompt. The destination must be explicit, and importing must not make a model call.
Work item 7 of 17 in #2744. Ready for contribution: prompt table/details (#2745/#3163), shared media previews (#2749/#3251), and draft preservation (#2750/#3334) are merged. This is the current main-sequence item, marked help wanted. Coordinate here before starting; later items remain not ready yet.
Current work, October 31, 2026: assigned to Nimit3418 and covered by open #3670. Continue the existing implementation rather than start another import/editor/handoff path. Its changes-requested review has seven unresolved threads covering real seed-group turn ordering, saved/new-conversation destinations, dirty and untouched imported drafts, retained destination history, and editor target/temperature preservation. The acceptance criteria below remain applicable; this audit does not credit the open PR as delivered.
Describe the solution you'd like
For exactly one selected logical example, support a single prompt, a linked multimodal message, or an entire stored multi-turn conversation, including conversations with media in individual turns. Keep these three destinations:
- Import to new attack.
- Import to current conversation within the current attack.
- Import to new conversation within the current attack.
Reuse the existing composer and conversation editor. A simple outgoing prompt goes into the editable composer. A stored conversation opens in the existing conversation/prepend editor, with its messages and message pieces intact. Do not concatenate turns into one prompt, turn each media piece into a separate message, or require users to copy turns individually. Group prompt members by their stored sequence and compatible role, retaining their within-turn order. Ambiguous multi-turn roles/order need an explanation, not guessed dialogue. Objective/condition records remain associated metadata, not extra conversation turns.
Match the existing chat convention: if the conversation ends in a user turn, earlier turns become prepended history and the final user turn remains editable and unsent in the composer. If it ends in an assistant/tool turn, retain the whole selected history and leave the next prompt empty. All selected content must survive this split. For example, user -> assistant -> user becomes two history turns plus one unsent user prompt, not one flattened string. Imported assistant/tool turns use the existing simulated-history roles; they must never masquerade as fresh target output or execute tools. A materialized conversation is different from a stored SeedSimulatedConversation configuration that would need generation.
Make destination and replacement behavior explicit. New attacks/conversations start from the selected example, not an unexpected copy of the previously viewed transcript. For the current conversation, single-message imports replace only the composer after dirty-draft confirmation. Whole-conversation imports enter an editable prepend/history draft and show the resulting history before it is saved; do not silently discard existing setup/history. Reuse an existing unsent conversation only through the current guarded save path. If sent evidence prevents in-place prepending, explain that and offer an explicit new-conversation/new-attack destination instead of silently rewriting or redirecting it. Cancellation leaves the original composer, history, and selection untouched.
Keep the destination's objective, system prompt, target, scorer, and configured converter pipeline unless the user explicitly changes them. Resolve a conflicting imported system/developer prompt visibly rather than overwriting the existing one. Do not reuse stale applied conversions for newly imported content. Target-free drafting is already supported: do not require a target merely to inspect/import/edit. When a target is bound or selected, preserve its identity and respect modality, multi-turn/history-replay capabilities, operator ownership, read-only automated results, and mutation locks. Explain unavailable destinations and retain the selection while the user resolves them.
Build on the shipped contracts. Use #2750's navigation-safe, single-use handoff. Its current PendingImportPayload only carries text/attachments; extend that shared typed contract and consumer for ordered conversation drafts instead of encoding a transcript in content.text or introducing a second state store. Preserve exact destination ownership, dirty-draft confirmation, stale-request/runtime invalidation, attachment URL ownership, and one-time consumption. Include conversation-editor drafts in the same protection when they participate in this journey.
Use the existing ConversationEditor, useConversationDraft, useConversationSave, and attack/conversation APIs. POST /api/attacks/save-conversation already saves ordered history without sending, supports target-free drafts, and provides retry identity and guarded unsent-history reuse. Keep persistence behind the existing explicit save/confirmation flow, not on catalog browsing or selection. Do not implement imports by issuing one send request per turn. Add only a narrow service adapter or shared typed field if the current APIs cannot carry verified seed provenance or media; no memory schema change or new import persistence service.
Retain selection_key together with example_id and original member IDs. Fetch the complete dataset-scoped detail, not the table preview or all seeds with the same group ID. Detail members are raw stored SeedRecord projections, not execution-ready seeds. Preserve full values, IDs/hashes, nullable source roles/order, typed objective conditions, and provenance. Seed IDs are not saved chat message-piece IDs: do not put them into source_piece_id, which the save API validates against a source conversation. Keep stable stored media references separate from expiring value_url display URLs and use the existing safe attachment/media path.
Validate importability only on explicit import/save. Do not reconstruct executable seeds, open template files, render templates, generate simulated conversations, apply converters, or call a target to prepare an import. Missing template flags/parameters do not prove a record is executable. Unsupported or unfilled configuration, invalid role/tool pairing, missing media, and API size limits must produce a clear explanation without dropping members, truncating a conversation, or importing a partial example. Multiple independent selected examples still belong to the later scenario workflow.
Acceptance criteria:
- All three destinations support a single prompt, a multimodal message, and a stored conversation where the destination permits it; disabled cases explain why and offer a deliberate alternative.
- Whole-conversation imports preserve turn order, roles, within-turn pieces/media, and source metadata in the existing editor. The final-user-turn split retains all content and never sends it automatically.
- Importing and saving do not call a target, run converters, execute tools, render templates, or generate conversations. Imported assistant/tool turns remain visibly simulated history.
- Dataset-scoped membership and full stored content are retained. Preview text, signed display URLs, objective/configuration records, and seed IDs are not mistaken for executable prompts, durable content, history turns, or chat piece IDs.
- Target-free drafts work. Bound targets, existing settings, ownership/read-only/mutation restrictions, and history-replay/modality capabilities are respected. Sent evidence is not rewritten in place.
- Dirty composer or conversation-editor content and system-prompt conflicts have explicit confirmation/cancellation behavior, with no silent data loss. Going to Datasets and back preserves draft/context.
- Failure, navigation/runtime changes, late responses, double clicks, remounts, and retries do not misroute an import, apply it twice, duplicate saved history, or revive a cancelled import. Failed creation/save preserves the draft and reports an error.
- Unit/component and real-component routing tests cover all three destinations, no attack/target, text and media, multi-turn conversations ending in user and assistant/tool turns, grouping/role errors, dirty drafts, sent-history restrictions, and stale/failing requests. Mocked or seeded browser coverage demonstrates a whole-conversation import, edit, save/return, and an unsent final prompt using local fixtures without paid target calls.
Describe alternatives you've considered, if relevant
Do not add bulk chat sending, a new executor, a second conversation editor, a separate import persistence service, or new scenario/scan launch actions. Whole stored conversations are in scope; generating a conversation from a configuration is not. Reuse the current editor/prepend and save flows rather than flattening a conversation or treating multiple unrelated examples as one transcript.
Additional context
Scope refreshed against main 21fce4492cee464d759c28cad14097bbf81a6eca on 2026-10-27 UTC. Conversation editing/prepending is already implemented, including the branching/technique-reuse and chat-usability changes in #3187/#3276. #3334 supplies the dataset round-trip handoff, not dataset import execution.
Starting points: SeedExampleBrowser, SeedExampleDetail, seedExampleSelection, datasetsApi.getSeedExample, useChatDraftHandoff, PendingImportPayload, ChatWindow, ConversationEditor, useConversationDraft, useConversationSave, utils/conversationDraft.ts, attacksApi.saveConversation, and the backend attack models/service. Preserve existing SeedGroup turn-grouping semantics without invoking its template/generation paths. Follow doc/code/framework.md and the applicable frontend/backend test instructions. Update the dataset/chat guide for the supported shapes and no-send behavior. Inspiration entry points remain #2752; provider loading and multi-example scenarios remain later items.
Activity
[-]FEAT GUI: Import a dataset example into a chat draft[/-][+]FEAT GUI: Import dataset prompts and conversations into chat[/+]github-actions commentedon Oct 27, 2026
Thanks for the feedback! A maintainer will take a look soon.
Nimit3418 commentedon Oct 28, 2026
Hi Roman Lutz (@romanlutz),
I would love to pick this up!
I have reviewed the requirements, acceptance criteria, and the precedent handoff contract in #3334. Here is my high-level approach:
PendingImportPayload:useChatDraftHandoffto carry structured, ordered conversation turns (roles, message pieces, and media references) rather than only flat text/attachments.SeedExampleDetail,useChatDraftHandoff, andConversationEditorcovering multimodal attachments, turn splitting, destination routing, and target-free drafting.Could you please assign this issue to me?
Nimit3418 commentedon Oct 30, 2026
Hi Roman Lutz (@romanlutz),
I have completed the implementation for this issue and opened PR #3670.
Here is a summary of how the requirements and edge cases were addressed:
Shared Contract Extension:
PendingImportPayloadwithconversation?: PendingImportConversationcarrying ordered turns, objective metadata, and system prompt, building directly on the FEAT GUI: Preserve chat drafts when exploring datasets #2750 / FEAT GUI: Preserve chat drafts when exploring datasets (#2750) #3334 draft handoff without introducing a second state store.ChatDraftContentso in-progressConversationEditordrafts participate in round-trip preservation when switching between Chat and Datasets.Turn Grouping, Role Mapping & Invariants:
buildSeedImport(members)insrc/utils/seedImport.ts:prompt_group_idandsequence.simulated_assistant,simulated_tool) and never execute tools or call a model.simulated_conversationconfigurations are rejected with a clear message explaining they require generation via Scenarios.seed_type === 'objective'records are extracted as objective metadata, not extra turns.valueremains the durable reference;value_urlis preview-only.source_piece_id.Turn Splitting Convention:
Destination UI & Guards:
SeedExampleDetailcovering all three destinations:Testing & Docs:
src/utils/seedImport.test.ts).useChatDraftHandoff.test.tsx,SeedExampleDetail.test.tsx, andApp.drafts.test.tsxfor round-trip integration across all destinations.doc/gui/0_gui.md.Looking forward to your review!