spec.md 2.0 KB

ADDED Requirements

Requirement: Streaming chat response

服务层 SHALL 使用 fetch + ReadableStream 实现流式对话,通过 AsyncGenerator<SSEEvent> 供上层消费。

Scenario: Successful streaming

  • WHEN 调用 speak(sessionId, audioBlob) 发起请求
  • THEN 依次 yield transcripttoken(多次)、done 事件

Scenario: Empty response

  • WHEN 后端返回空的 stream(0 tokens)
  • THEN generator 正常结束,不抛异常

Requirement: Request cancellation

每个流式请求 SHALL 支持通过 AbortController 取消。

Scenario: User cancels during streaming

  • WHEN 流式输出进行中调用 signal.abort()
  • THEN fetch 请求被取消,generator 抛出 AbortError,上层保留已接收内容

Requirement: Error handling

请求失败时 SHALL 统一抛出错误,不区分错误类型(v1 简化版)。

Scenario: Request fails

  • WHEN 网络断开、超时、或后端返回错误
  • THEN 抛出 Error,上层将消息状态设为 error,显示重试按钮

Requirement: Adapter interface

服务层 SHALL 通过 DialogueAPI 接口抽象后端通信,支持 mock 和真实 API 切换。

interface DialogueAPI {
  createSession(config: SessionConfig): Promise<SessionInfo>
  speak(sessionId: string, audioBlob: Blob, signal: AbortSignal): AsyncGenerator<SSEEvent>
  getReport(sessionId: string): Promise<Report>
}

Scenario: Using mock adapter

  • WHEN modepreview
  • THEN 使用 MockDialogueAPI,模拟 transcript + 逐 token 输出

Scenario: Using real adapter

  • WHEN modereal
  • THEN 使用 RealDialogueAPI,对接后端 3 个接口

Requirement: SSE response parsing

服务层 SHALL 解析后端返回的 SSE 格式流。

Scenario: Parse SSE events

  • WHEN 后端返回 event: transcript\ndata: {...}\n\n 格式
  • THEN 根据 event type 解析为对应的 SSEEvent 对象(transcript / token / done)