Transports
How AI components send requests to your server and get answers back.
A transport is how an AI component sends a request and gets the answer
back. Most apps use the fetch transport, which sends requests to a URL on your
server. You create one and pass it to your component as the transport prop.
The transport does not care which AI provider you use. It only moves requests and answers.
Which one to use
| Option | Use it for | Network |
|---|---|---|
createFetchTransport | Your real app. Sends requests to your server route | Yes |
createMockTransport | Demos and building UI without a server or API key | No |
mockGenerate + createFetchTransport | Testing your server route without calling a model | Yes |
| Your own transport | Sending requests some other way, such as WebSockets | Depends |
Fetch transport (most apps)
import { createFetchTransport } from "@emend/ai/transport"
const transport = createFetchTransport({
url: "/api/editor-ai",
})It sends each request to your URL as a POST, and reads the answer as it
streams back. If the server returns an error, such as 401 or 429, it turns
it into an emend error your UI can show.
To add headers or change other options, see
createFetchTransport.
Mock transport (no server needed)
import { createMockTransport } from "@emend/ai/transport"
const transport = createMockTransport({
delayMs: 30,
})It returns fake answers that match the action, so you can build and test your
UI without a server or API key. Set failAfterDeltas to fake an error partway
through an answer.
The demos on this site use a real model
The editors on this site use createFetchTransport with /api/editor-ai,
which runs the Vercel AI Gateway recipe on OpenRouter's free models.
Build your own transport
If you do not want to send requests with fetch, you can write your own
transport. It is an object with a run function that takes the request and
returns the answer's events one at a time. emend does not include any other
transports, so you write this part yourself. Its type is EmendTransport.
import type { EmendTransport } from "@emend/ai"
const transport: EmendTransport = {
async *run(request, signal) {
signal.throwIfAborted()
for await (const event of readEvents(request, signal)) {
yield event
}
},
}Your transport must:
- Stop when
signalis aborted (for example, when the user clicks Stop), so you do not keep paying for an answer nobody will see. - Send back events with the same protocol version and request ID as the request. Events that do not match are ignored.
Next, read Supported Markdown and Compatibility to see which content the AI can edit and which versions emend supports.