feat: add resumable stream support for agent chat (#19107)
## Overview Add resumable stream support for agent chat to allow clients to reconnect and resume streaming responses if the connection is interrupted (e.g., during page refresh). ## Changes ### Backend (Twenty Server) - Add `activeStreamId` column to `AgentChatThreadEntity` to track ongoing streams - Create `AgentChatResumableStreamService` to manage Redis-backed resumable streams using the `resumable-stream` library with ioredis - Extend `AgentChatController` with: - `GET /:threadId/stream` endpoint to resume an existing stream - `DELETE /:threadId/stream` endpoint to stop an active stream - Update `AgentChatStreamingService` to store streams in Redis and track active stream IDs - Add `resumable-stream@^2.2.12` dependency to package.json ### Frontend (Twenty Front) - Update `useAgentChat` hook to: - Use a persistent transport with `prepareReconnectToStreamRequest` for resumable streams - Export `resumeStream` function from useChat - Add `handleStop` callback to clear active stream on DELETE endpoint - Use thread ID as stable message ID instead of including message count - Add stream resumption logic in `AgentChatAiSdkStreamEffect` component to automatically call `resumeStream()` when switching threads ## Database Migration New migration `1774003611071-add-active-stream-id-to-agent-chat-thread` adds the `activeStreamId` column to store the current resumable stream identifier. --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+19
@@ -0,0 +1,19 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
export class AddActiveStreamIdToAgentChatThread1774003611071
|
||||
implements MigrationInterface
|
||||
{
|
||||
name = 'AddActiveStreamIdToAgentChatThread1774003611071';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."agentChatThread" ADD "activeStreamId" character varying`,
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."agentChatThread" DROP COLUMN "activeStreamId"`,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user