@durable-streams/aisdk-transport

中文文档
0.0.8发布于 2026/09/11Apache-2.0TypeScriptESM + CJS构建来源已验证近 30 天下载 5.3万

Vercel AI SDK transport adapters for Durable Streams

原始使用文档
文档目录15 节
  1. Goal
  2. 0) Starting point (no Durable Streams)
  3. 1) Basic Durable Streams integration
  4. Client
  5. Server
  6. 2) Optimal setup: resumable generations
  7. A. Persist active stream id per chat
  8. B. Add reconnect endpoint
  9. C. Enable resume on useChat
  10. API reference
  11. createDurableChatTransport({ api, reconnectApi?, headers?, …
  12. toDurableStreamResponse({ source, ...options })
  13. Response contract
  14. mode: "immediate"
  15. mode: "await"

@durable-streams/aisdk-transport

Vercel AI SDK transport adapters for Durable Streams.

Goal

Use Durable Streams with AI SDK useChat so generations can survive refreshes and reconnect cleanly.

This guide moves from:

  1. No integration (regular AI SDK chat)
  2. Basic Durable Streams integration
  3. Optimal resumable generations (recommended)

0) Starting point (no Durable Streams)

Client:

import { useChat } from "@ai-sdk/react"
import { DefaultChatTransport } from "ai"

const transport = new DefaultChatTransport({ api: "/api/chat" })
const chat = useChat({ transport })

Server:

return result.toUIMessageStreamResponse()

This works, but refreshing during generation can lose the in-flight stream.

1) Basic Durable Streams integration

Client

Swap to createDurableChatTransport:

import { useChat } from "@ai-sdk/react"
import { createDurableChatTransport } from "@durable-streams/aisdk-transport"

const transport = createDurableChatTransport({ api: "/api/chat" })
const chat = useChat({ transport })

Server

Wrap your UI message stream with toDurableStreamResponse:

import { toDurableStreamResponse } from "@durable-streams/aisdk-transport"

return toDurableStreamResponse({
  source: result.toUIMessageStream(),
  stream: {
    writeUrl: buildWriteStreamUrl(streamPath),
    readUrl: buildReadProxyUrl(request, streamPath),
    headers: DURABLE_STREAMS_WRITE_HEADERS,
  },
})

At this point you get durable writes + durable reads, but no automatic resume after refresh yet.

2) Optimal setup: resumable generations

This is the recommended production flow.

A. Persist active stream id per chat

When a generation starts, save activeStreamId = streamPath. When it finishes, save final messages and clear activeStreamId.

await saveChat({ id, activeStreamId: streamPath })

return toDurableStreamResponse({
  source: result.toUIMessageStream({
    originalMessages: messages,
    onFinish: ({ messages: finalMessages }) => {
      void saveChat({ id, messages: finalMessages, activeStreamId: null })
    },
  }),
  stream: { writeUrl, readUrl, headers },
})

B. Add reconnect endpoint

Implement GET /api/chat/:id/stream:

  • Return 204 when there is no active generation.
  • Return 200 with Location and { streamUrl } when there is one.
if (!chat.activeStreamId) return new Response(null, { status: 204 })

const streamUrl = buildReadProxyUrl(request, chat.activeStreamId)
return Response.json(
  { streamUrl },
  { status: 200, headers: { Location: streamUrl } }
)

C. Enable resume on useChat

const transport = createDurableChatTransport({ api: "/api/chat" })
const chat = useChat({ id, transport, resume: true })

On page load, AI SDK will call reconnectToStream automatically. This transport resolves the stream URL from Location first (or { streamUrl } fallback), then reconnects to the durable stream.

API reference

createDurableChatTransport({ api, reconnectApi?, headers?, fetchClient? })

Creates an AI SDK ChatTransport that:

  1. POSTs messages to api
  2. Resolves read URL from:
    • Location header (preferred)
    • JSON body { streamUrl } fallback
  3. Reads the durable stream as JSON+SSE and returns ReadableStream<UIMessageChunk>
  4. Supports reconnect via GET reconnectApi (or default ${api}/${chatId}/stream)

toDurableStreamResponse({ source, ...options })

Writes AI SDK UI message chunks into Durable Streams and returns a pointer response.

Options:

  • source: required async iterable of AI SDK UI message chunks
  • stream.writeUrl: required durable write URL
  • stream.readUrl: optional URL exposed to clients (Location + JSON body)
  • stream.headers: optional write headers
  • mode:
    • immediate (default): return once stream is prepared
    • await: return after generation/write completes
  • waitUntil: optional runtime keep-alive hook (useful in worker runtimes)

Response contract

mode: "immediate"

The initial response returns only stream location metadata, not generated content:

  • Location: <read-url>
  • { "streamUrl": "<read-url>" }

The client then connects to that read URL to consume generated chunks, while generation continues in the background. Use waitUntil when your runtime needs an explicit keep-alive signal so the worker stays alive until streaming work is complete.

  • Status: 201
  • Header: Location: <read-url>
  • Body: { "streamUrl": "<read-url>" }

mode: "await"

Headers are still sent immediately, so clients can read Location and start consuming the stream early, but the HTTP connection stays open until generation/write completes. This is useful on runtimes that only allow long-running work while an inbound request remains active.

  • Status: 200
  • Header: Location: <read-url>
  • Body: { "streamUrl": "<read-url>", "finalOffset": "<offset>" }

版本与发布记录

@durable-streams/aisdk-transport 共发布 8 个版本,首次发布于 2026/03/24;过去 12 个月发布了 8 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.0.8latest2026/09/112 个月前
0.0.72026/06/015 个月前
0.0.62026/05/285 个月前
0.0.52026/05/205 个月前
0.0.42026/05/195 个月前
0.0.32026/04/137 个月前

关于 @durable-streams/aisdk-transport 的常见问题

@durable-streams/aisdk-transport 是什么?

Vercel AI SDK transport adapters for Durable Streams

如何安装 @durable-streams/aisdk-transport?

在项目目录运行 npm install @durable-streams/aisdk-transport,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:ai(^6.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。它还提供命令行工具 intent,可以用 npx intent 直接运行。

@durable-streams/aisdk-transport 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@durable-streams/aisdk-transport 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@durable-streams/aisdk-transport 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@durable-streams/aisdk-transport 可以商用吗?

@durable-streams/aisdk-transport 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@durable-streams/aisdk-transport 的下载量有多少?

根据 npm 官方下载统计,@durable-streams/aisdk-transport 在 2026/10/13 – 2026/11/11 这 30 天内被下载 53,038 次,日均约 1,768 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@durable-streams/aisdk-transport 还在维护吗?

最新版本 0.0.8 发布于 2026/09/11(2 个月前);至今共发布 8 个版本,其中过去 12 个月发布了 8 个;首次发布于 2026/03/24。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。