All posts
releaseannouncement

FlowDrop 1.10.0: PlaygroundStudio and Reliable Polling

FlowDrop 1.10.0 ships PlaygroundStudio as a first-class embeddable component, sequence-number polling, automatic message pagination, and a deep set of state machine fixes.

FlowDrop 1.10.0 makes the split-pane playground layout embeddable without custom scaffolding, switches message polling to use sequence numbers, and fixes a cluster of state machine edge cases that were causing desync in production.

PlaygroundStudio

PlaygroundStudio is a drop-in split-pane component combining PipelinePanel and Playground side by side. It’s the same layout as the demo app, available as a single import. A minChatWidth prop (default 760 px, backed by a CSS var) controls the minimum chat panel width.

For non-Svelte hosts, mountPlaygroundStudio() is the vanilla JS equivalent — same options shape as mountPlayground, works in any framework or plain HTML page.

Sequence-number polling

Message polling now uses ?since=<sequenceNumber> instead of a timestamp. Sequence numbers are monotonic and server-assigned, so incremental fetches are exact: no missed messages, no duplicates from clock skew. getLastSequenceNumber() is exposed from playgroundService; getLatestSequenceNumber() and getLastPollSequenceNumber() from playgroundStore. startPolling accepts an optional initialSequenceNumber seed to avoid a full re-fetch on restart.

Automatic message pagination

playgroundService.getMessages now follows pagination automatically — it fetches pages of 100 until pagination.has_more is false, then returns all messages merged. Previously only the first page was returned for sessions with many messages. The PlaygroundMessagesPagination type is exported from both entry points.

Pipeline panel auto-refresh

When following the latest run (not pinned to a specific execution), the pipeline panel re-fetches from the server on every incoming message batch. Pinned historical runs are not affected. The panel also clears its pin automatically when a new execution is detected in incoming messages, or when the user sends a new message.

Refresh button

A Refresh button in the playground header triggers an immediate fetch and resumes polling if it had stopped. Host applications can also dispatch flowdrop:refresh-status on the mount container to trigger the same action programmatically.

State machine fixes

This release resolves a set of concurrency and lifecycle bugs:

  • loadSession seeds the polling timestamp and uses applyServerResponse
  • handleSelectSession resets status to idle before loading the next session
  • handleSendMessage guards with getIsExecuting() and resets to idle on error
  • handleStopExecution resets status in the catch block
  • handleInterruptResolved restarts polling and sets executing if the server resumed
  • loadedInitialSessionId is assigned before the first await in loadInitialSession, making the guard visible synchronously and preventing concurrent loads
  • isExecuting() now reads from the store’s _currentSession.status rather than playgroundService.isPolling(), eliminating desync between the stop button and send button guards
  • A visibilitychange listener triggers an immediate catch-up fetch when the user returns to the tab
  • addMessages deduplicates against the incoming batch itself, preventing each_key_duplicate errors when the server returns the same message ID twice in one response

Upgrading

npm install @flowdrop/flowdrop@1.10.0

No breaking changes.