Skip to content

PRD: AI Radio — Host-driven Channel experience with chat timeline #39

Description

@zeevenn

This was generated by AI during triage.

Problem

Listening to a local music library still requires active playlist and queue management. Flow should offer a passive, coherent radio experience: the listener tunes into a Channel, music continues in Programmes, and a Host adds short spoken Interludes and responds to typed requests without taking over low-level Player controls.

V1 product

Flow keeps two playback modes:

  1. Radio Mode — Programme-driven playback from a selected Channel.
  2. Classic Mode — existing user-controlled queue playback.

Only one mode is active. Playing a Library Track enters Classic Mode; tuning into a Channel enters Radio Mode.

Radio uses the domain terms Channel, Host, CandidateSet, Programme, Segment, Interlude, Intervention, and Session Context. “Agent” is only the Host implementation style. V1 has no tool loop, Player-control tools, long-term memory, or model-owned chat history.

Primary flow

  1. The listener configures a DeepSeek API key and TTS API key in secure device storage. Both are required before provider-backed Radio is enabled.
  2. The listener enters a Channel. Library returns a CandidateSet matching its structured Channel Style.
  3. Programme Manager supplies CandidateSet, bounded Session Context, generation reason, optional Intervention, Generation ID, and AbortSignal to Host.
  4. Host makes one structured DeepSeek planning call, validates the result in deterministic code, synthesises Interludes through an injected TTS provider, materialises local playable URIs, and atomically returns a complete Programme.
  5. The same expo-audio player plays Track and Interlude Segments. During an Interlude, lock-screen text identifies the Host/Channel while preserving the previous Track artwork.
  6. Programme Manager prepares a background refill near Programme end so playback can continue.

Host and Programme rules

  • Direct DeepSeek API through AI SDK Core, model deepseek-v4-flash, Thinking disabled.
  • V1 supports one model provider and BYOK; no Flow-hosted proxy, key custody, billing, or quotas.
  • Host Policy is versioned and application-owned. Model/user text cannot override it.
  • Programme music targets 30–45 minutes, usually 7–12 Tracks, subject to available CandidateSet duration.
  • A Programme may select only CandidateSet Tracks and cannot repeat a Track within that Programme.
  • Programme Manager deterministically withholds recent/current Programme Tracks, then reintroduces least-recent Tracks only when required.
  • Channel entry and Intervention may contain one opening/acknowledgement Interlude. Background refill may not.
  • Transition Interludes occur after 2–3 Tracks. A Programme cannot end with an Interlude.
  • Host returns a complete playable Programme; Player never receives partially synthesised Segments.

Interventions

V1 input is text only:

  • Track Request — current Segment finishes; optional acknowledgement Interlude; requested Track is first in the replacement Programme.
  • Mood Change — current Segment finishes; replacement Programme responds to the requested style shift.
  • Free Instruction — current Segment finishes; replacement Programme follows the bounded instruction where compatible with Host Policy.

Timeline records user turns, Host acknowledgements/Interludes, and Track-start events in memory for the current session. Persistent history and speech-to-text are later work.

Failure and lifecycle behavior

  • Invalid/empty model output: bounded retry, then deterministic music-only Programme.
  • Individual TTS failure: bounded retry, then omit only that Interlude.
  • Latest Generation ID wins. New Channel or Intervention aborts stale work; cancellation propagates through model, TTS, and cache and must not trigger fallback.
  • Generated TTS returns bytes plus media type. Mobile cache materialises a native file URI; Web will use a Blob URL.
  • Network/offline product behavior remains tracked separately in Offline Host fallback #51.

V1 UI

  • Radio Screen shows current Track, playback state, session timeline, and a text Intervention field.
  • Upcoming Programme remains opaque.
  • Classic Library/queue experience remains available.
  • No microphone/STT, persistent timeline, Radio UI redesign, or user-visible model selector in this slice.

Architecture ownership

  • Library: filters Tracks into CandidateSet; never ranks or sequences.
  • Programme Manager: lifecycle, recency, generation reason, Intervention timing, cancellation, latest-wins commit.
  • Host: model plan plus deterministic validation/assembly; no Library query or Player control.
  • TTS provider: provider-specific synthesis behind a bytes/media-type contract.
  • Audio cache: converts generated bytes into a playable URI and removes stale artifacts.
  • Player: consumes Programme or classic Queue and reports Segment lifecycle events.
  • Chat timeline: in-memory current-session presentation state.

Success criteria

  • Radio and Classic modes coexist without competing playback state.
  • Provider-backed Radio cannot start until both BYOK credentials exist.
  • Entering a Channel yields an atomic playable Programme and background refill.
  • Track Request, Mood Change, and Free Instruction switch after the current Segment.
  • No intra-Programme repeats; cross-Programme recency is deterministic.
  • Failure degrades to continuous music instead of breaking playback.
  • Lock-screen/notification playback remains one media session across Tracks and Interludes.
  • Core Host/Programme Manager behavior is covered by deterministic contract tests.

Child work and references

Out of scope

  • Multiple AI providers or user-selectable models
  • Final TTS provider selection and final voice IDs before Mandarin blind testing
  • Speech input/STT
  • Host volume, pause, skip, or arbitrary Player tools
  • Long-term listener memory
  • Server-side proxy/API
  • Persistent chat history

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestready-for-agentReady for an AI agent to implement

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions