---
title: "createChatTransport"
description: "把内部 LLM 网关的 SSE 接成 AI SDK 传输层，直接喂给 @nuxt/ui 的 Chat 组件。"
seo_title: "createChatTransport"
seo_description: "Bridge an internal LLM gateway's SSE protocol to the AI SDK chat transport so Nuxt UI chat components work unchanged."
canonical_url: "https://nuxt.mhaibaraai.cn/docs/api/chat-transport"
---
# createChatTransport

> 把内部 LLM 网关的 SSE 接成 AI SDK 传输层，直接喂给 @nuxt/ui 的 Chat 组件。

## 用法

`@nuxt/ui` 的 `UChat*` 组件渲染的是 AI SDK 的 `UIMessage`，协议解析全在 `ai` 包里，且只认 AI SDK 自己的 UI Message Stream 格式。内部网关（MaxKB、Dify、FastGPT、自研）的分片结构各不相同，`createChatTransport` 补的就是中间这一段：**领域侧只写一个无状态的 `select`，其余全部继承 AI SDK 的 `HttpChatTransport`。**

> \[\!NOTE\]
> 
> 需要额外安装 
> 
> ai
> 
> （
> 
> @movk/nuxt
> 
>  的可选 peer）与 
> 
> @ai-sdk/vue
> 
> ，并从 
> 
> @movk/nuxt/ai
> 
>  子路径导入——主包不引入 AI SDK。

```vue
<script setup lang="ts">
import { createChatTransport } from '@movk/nuxt/ai'
import { useChat } from '@ai-sdk/vue'

interface GatewayChunk {
  content: string
  node_id: string
  runtime_node_id: string
  node_is_end: boolean
  is_end: boolean
}

const transport = createChatTransport<GatewayChunk>({
  api: '/chat/completions',
  select: raw => ({
    id: raw.runtime_node_id,
    delta: raw.content,
    end: raw.node_is_end,
    finished: raw.is_end
  })
})

const { messages, status, error, sendMessage, stop } = useChat({ transport })
</script>
```

`createChatTransport` 内部取 `$api`，须在 setup 作用域内调用。

## select 映射

`select` 是纯函数：拿一条后端分片，说明它对应哪些 UI 片段，返回 `undefined` 表示这条什么都不产出。生命周期由传输层兜住——`start` 只发一次、按 `id` 开合文本块、流结束时补齐所有未关闭的块与 `finish`，因此后端漏发结束信号或中途断流，消息也不会永远停在 streaming。

**id** (`string`): 文本块 id，同 id 的增量并入同一块。省略则并入默认块 'text-1'。

**delta** (`string`): 本片增量文本，为空则不产出 text-delta。

**end** (`boolean`): 该文本块到此结束。

**data** (`{ type: string, value: unknown, transient?: boolean }`): 附带的自定义数据片，产出 data-${type}。transient: true 时只走 useChat 的 onData 回调、不写入消息历史。

**finished** (`boolean`): 整条流到此结束，其后的分片被忽略。

工作流类网关常在正文之外带节点信息，用 `data` 片把它送到 `onData`，就能在不污染消息历史的前提下驱动进度：

```ts
const transport = createChatTransport<GatewayChunk>({
  api: '/chat/completions',
  select: raw => ({
    id: raw.runtime_node_id,
    delta: raw.content,
    end: raw.node_is_end,
    finished: raw.is_end,
    data: { type: 'node', value: { nodeId: raw.node_id, nodeIsEnd: raw.node_is_end }, transient: true }
  })
})

const { messages } = useChat({
  transport,
  onData: (part) => {
    if (part.type === 'data-node') advanceStage(part.data)
  }
})
```

## 请求编排

`api`、`headers`、`body`、`credentials`、`prepareSendMessagesRequest`、`prepareReconnectToStreamRequest` 全部是 AI SDK `HttpChatTransport` 的原生选项，行为一致。私有握手（先开会话再拼流地址）放在 `prepareSendMessagesRequest` 里即可，它允许异步、允许覆盖 `api`：

```ts
const transport = createChatTransport<GatewayChunk>({
  prepareSendMessagesRequest: async ({ messages }) => {
    const chatId = await $api<string>('/chat/open')

    return {
      api: `/chat_message/${chatId}`,
      body: { message: getTextFromMessage(messages.at(-1)!) }
    }
  },
  select
})
```

## 为什么默认 fetch 走 $api

默认注入的 `fetch` 基于 `$api`，端点 baseURL、鉴权头、业务码校验、错误 toast 与 `movk:api:*` hook 全部复用。这不只是省事：**有些网关的错误响应是 HTTP 200 + `{ code: 500 }` 信封**，只看 `response.ok` 的实现会放行，然后拿 JSON 当流读、静默空转。走 `$api` 时这类响应在业务码校验处就抛出，最终落到 `useChat` 的 `onError`。

它还顺手处理了 Accept：ofetch 见到 JSON body 会自动塞 `Accept: application/json`，对要当流读的请求是错误声明，因此默认改发通配符；调用方在 `headers` 里指定则以调用方为准。细节见 [`useApiStream`](/docs/composables/use-api-stream#accept-%E4%B8%8E-responsetype-%E7%9A%84%E5%A4%84%E7%90%86)。

传入自己的 `fetch` 会覆盖该默认值，Accept 也要自己管。

## API

### createChatTransport()

#### Type Parameters

**Raw** (`unknown`): 后端单条分片的类型。

**UI\_MESSAGE** (`UIMessage`): 消息类型，默认 AI SDK 的 UIMessage。

#### Parameters

**options** (`MovkChatTransportOptions<Raw, UI_MESSAGE>`) *required*: 后端分片 → UI 片段的纯映射。使用的端点名称，默认走 defaultEndpoint。单条 SSE 事件的 data 解析方式，返回 undefined 丢弃该条。默认容错的 JSON.parse。api、headers、body、credentials、fetch、prepareSendMessagesRequest、prepareReconnectToStreamRequest，语义与 AI SDK 一致。

#### Returns

`ChatTransport<UI_MESSAGE>`，直接传给 `useChat({ transport })`。

## Changelog

See commit history for [src/runtime/domains/ai/create-chat-transport.ts](https://github.com/mhaibaraai/movk-nuxt/commits/main/src/runtime/domains/ai/create-chat-transport.ts).


## Sitemap

See the full [sitemap](/sitemap.md) for all pages.
