Skip to content

feat: streaming ai assistant messages#4517

Open
elias-ba wants to merge 4 commits intomainfrom
3585-ai-assistant-streaming
Open

feat: streaming ai assistant messages#4517
elias-ba wants to merge 4 commits intomainfrom
3585-ai-assistant-streaming

Conversation

@elias-ba
Copy link
Contributor

@elias-ba elias-ba commented Mar 10, 2026

Description

This PR adds real-time streaming support for AI assistant responses. Instead of waiting for the full response to complete, users now see text stream in word-by-word. Structured changes (workflow YAML, job code diffs) are applied to the canvas/editor before the text explanation finishes streaming.

Previously, the AI would generate text first and code/YAML second, so users would read "I've updated your workflow..." and only see the changes seconds later. With a companion Apollo PR (OpenFn/apollo#407) that reverses the generation order, Lightning now receives a changes SSE event early in the stream containing the resolved code or YAML, applies it immediately, and then streams the text explanation.

The backend handles SSE streaming events from Apollo (text chunks, status updates, structured changes), broadcasts them via PubSub, and forwards them through Phoenix Channels to WebSocket clients. It also fixes a Mint transport error crash during SSE streaming and a message_processor crash on non-map error tuples.

The frontend adds streaming state to the AI assistant store, registers event handlers in AIChannelRegistry, renders streaming content in the message list, and auto-applies workflow YAML / auto-previews job code diffs as soon as streaming changes arrive, with deduplication to prevent double-application when the final message lands.

Closes #3585

Validation steps

  1. Send a message to the AI assistant. The response text should stream in word-by-word instead of appearing all at once after completion
  2. While streaming, verify that a status indicator (e.g. "Thinking...") appears before text starts arriving
  3. After the stream completes, verify the final message renders correctly with proper markdown formatting, code block, and Apply button
  4. In workflow mode, ask the AI to create or modify a workflow. The canvas should update before the text explanation finishes streaming
  5. In job code mode, ask the AI to modify code. The diff preview should appear in Monaco before the text finishes
  6. Send a message without code context (e.g. "how does this adaptor work?"). Text should stream normally without any code preview
  7. With a collaborator viewing the same session, verify that only the message author gets auto-apply/preview
  8. Disconnect the network mid-stream or trigger an error. Verify graceful handling without crashes

Additional notes for the reviewer

This PR depends on a companion Apollo PR (OpenFn/apollo#407) which reverses the generation order and introduces the new changes SSE event. To validate this work, you'll need Apollo running locally on the tweaks-for-streaming branch (or a deployed version with that branch merged). Without the Apollo changes, streaming will still work but structured changes won't arrive early. They'll only appear when the final message completes, as before.

AI Usage

  • I have used Claude Code
  • I have used another model
  • I have not used AI

Pre-submission checklist

  • I have performed an AI review of my code (we recommend using /review
    with Claude Code)
  • I have implemented and tested all related authorization policies.
    (e.g., :owner, :admin, :editor, :viewer)
  • I have updated the changelog.
  • I have ticked a box in "AI usage" in this PR

@github-project-automation github-project-automation bot moved this to New Issues in Core Mar 10, 2026
@elias-ba elias-ba changed the title feat: AI assistant streaming with early change application feat: streaming ai assistant responses Mar 10, 2026
@elias-ba elias-ba changed the title feat: streaming ai assistant responses feat: streaming ai assistant messages Mar 10, 2026
@codecov
Copy link

codecov bot commented Mar 10, 2026

Codecov Report

❌ Patch coverage is 98.88889% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 89.60%. Comparing base (5d4762c) to head (fac55b9).

Files with missing lines Patch % Lines
lib/lightning/apollo_client.ex 94.44% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4517      +/-   ##
==========================================
+ Coverage   89.55%   89.60%   +0.05%     
==========================================
  Files         425      425              
  Lines       20307    20391      +84     
==========================================
+ Hits        18185    18271      +86     
+ Misses       2122     2120       -2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Add real-time streaming support for AI assistant responses and apply
structured changes (workflow YAML, job code) before text finishes streaming.

Backend:
- Handle SSE streaming events from Apollo (text chunks, status, changes)
- Broadcast streaming events via PubSub to ai_session topics
- Forward streaming events through Phoenix Channel to WebSocket clients
- Handle Mint transport errors gracefully during SSE streaming
- Fix message_processor crash on non-map error tuples

Frontend:
- Add streaming state (content, status, changes) to AI assistant store
- Register streaming event handlers in AIChannelRegistry
- Render streaming content in MessageList during AI response
- Auto-apply workflow YAML and auto-preview job code when streaming
  changes arrive, before text finishes streaming
- Deduplicate auto-apply to prevent double-application when final
  message arrives
@elias-ba elias-ba force-pushed the 3585-ai-assistant-streaming branch from 4f51faa to c9e2e5a Compare March 10, 2026 00:46
Cover SSE event handling, PubSub broadcasting, channel forwarding,
Apollo client streaming endpoints, catch :exit path, and edge cases
for invalid JSON in complete and changes events.
@elias-ba elias-ba force-pushed the 3585-ai-assistant-streaming branch from 47f1dbf to 4fd08ac Compare March 10, 2026 01:40
Wire up the streaming_error channel event in AIChannelRegistry so
errors during SSE streaming clear the UI state instead of being
silently dropped. Extract shared test helpers (streaming_or_sync_response,
stub_ai_with_health_check) to reduce mock duplication across 5 test files.
@elias-ba elias-ba requested a review from josephjclark March 10, 2026 02:14
@josephjclark
Copy link
Collaborator

@elias-ba this is looking pretty good (and I agree that it works better with your apollo changes, even if I have some concerns about the changes themselves).

The big thing I have here is that the streaming text comes in really really fast, and in really big chunks. It's stressful and kinda hard to read.

Do we need to buffer the response from the model, tokenise it, and then render token by token on a throttle? The worry with that of course is that the markdown will render all weird. It's difficult that we have to both render text smoothly, but also incrementally render markdown. Ideally we'd background-generate a markdown block, then incrementally render the html output.

Very happy to cut cloth - maybe the current rendering is the most appropriate place to release. Just want to thoroughly discuss options and costs before moving forward.

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

Labels

None yet

Projects

Status: New Issues

Development

Successfully merging this pull request may close these issues.

Add support for streaming text and status updates from Apollo AI service

2 participants