Hono
Example of using the AI TOOLKIT in a Hono server.
You can use the AI TOOLKIT in a Hono server to generate and stream text and objects to the client.
Run it locally
$ npm install aiExamples
The examples start a simple HTTP server that listens on port 8080. You can e.g. test it using curl:
curl -X POST http://localhost:8080
<Note>
The examples use the Vercel AI Gateway. Ensure that your AI Gateway API key is
set in the AI_GATEWAY_API_KEY environment variable.
</Note>
Full example: github.com/khulnasoft/ai-toolkit/examples/hono
### UI Message Stream
You can use the toUIMessageStreamResponse method to create a properly formatted streaming response.
import { serve } from '@hono/node-server';
import { streamText } from 'ai-toolkit';
import { Hono } from 'hono';
const app = new Hono();
app.post('/', async c => {
const result = streamText({
model: 'openai/gpt-4o',
prompt: 'Invent a new holiday and describe its traditions.',
});
return result.toUIMessageStreamResponse();
});
serve({ fetch: app.fetch, port: 8080 });
### Text Stream
You can use the toTextStreamResponse method to return a text stream response.
import { serve } from '@hono/node-server';
import { streamText } from 'ai-toolkit';
import { Hono } from 'hono';
const app = new Hono();
app.post('/text', async c => {
const result = streamText({
model: 'openai/gpt-4o',
prompt: 'Write a short poem about coding.',
});
return result.toTextStreamResponse();
});
serve({ fetch: app.fetch, port: 8080 });
### Sending Custom Data
You can use createUIMessageStream and createUIMessageStreamResponse to send custom data to the client.
import { serve } from '@hono/node-server';
import {
createUIMessageStream,
createUIMessageStreamResponse,
streamText,
} from 'ai-toolkit';
import { Hono } from 'hono';
const app = new Hono();
app.post('/stream-data', async c => {
// immediately start streaming the response
const stream = createUIMessageStream({
execute: ({ writer }) => {
writer.write({ type: 'start' });
writer.write({
type: 'data-custom',
data: {
custom: 'Hello, world!',
},
});
const result = streamText({
model: 'openai/gpt-4o',
prompt: 'Invent a new holiday and describe its traditions.',
});
writer.merge(
result.toUIMessageStream({
sendStart: false,
onError: error => {
// Error messages are masked by default for security reasons.
// If you want to expose the error message to the client, you can do so here:
return error instanceof Error ? error.message : String(error);
},
}),
);
},
});
return createUIMessageStreamResponse({ stream });
});
serve({ fetch: app.fetch, port: 8080 });
- 1curl -X POST http://localhost:8080
- 1import { serve } from '@hono/node-server';
- 2import { streamText } from 'ai-toolkit';
- 3import { Hono } from 'hono';
- 4const app = new Hono();
- 5app.post('/', async c => {
- 6 const result = streamText({
- 7 model: 'openai/gpt-4o',
- 8 prompt: 'Invent a new holiday and describe its traditions.',
- 9 });
- 10 return result.toUIMessageStreamResponse();
- 11});
- 12serve({ fetch: app.fetch, port: 8080 });
- 1import { serve } from '@hono/node-server';
- 2import { streamText } from 'ai-toolkit';
- 3import { Hono } from 'hono';
- 4const app = new Hono();
- 5app.post('/text', async c => {
- 6 const result = streamText({
- 7 model: 'openai/gpt-4o',
- 8 prompt: 'Write a short poem about coding.',
- 9 });
- 10 return result.toTextStreamResponse();
- 11});
- 12serve({ fetch: app.fetch, port: 8080 });
- 1import { serve } from '@hono/node-server';
- 2import {
- 3 createUIMessageStream,
- 4 createUIMessageStreamResponse,
- 5 streamText,
- 6} from 'ai-toolkit';
- 7import { Hono } from 'hono';
- 8const app = new Hono();
- 9app.post('/stream-data', async c => {
- 10 // immediately start streaming the response
- 11 const stream = createUIMessageStream({
- 12 execute: ({ writer }) => {
- 13 writer.write({ type: 'start' });
- 14 writer.write({
- 15 type: 'data-custom',
- 16 data: {
- 17 custom: 'Hello, world!',
- 18 },
- 19 });
- 20 const result = streamText({
- 21 model: 'openai/gpt-4o',
- 22 prompt: 'Invent a new holiday and describe its traditions.',
- 23 });
- 24 writer.merge(
- 25 result.toUIMessageStream({
- 26 sendStart: false,
- 27 onError: error => {
- 28 // Error messages are masked by default for security reasons.
- 29 // If you want to expose the error message to the client, you can do so here:
- 30 return error instanceof Error ? error.message : String(error);
- 31 },
- 32 }),
- 33 );
- 34 },
- 35 });
- 36 return createUIMessageStreamResponse({ stream });
- 37});
- 38serve({ fetch: app.fetch, port: 8080 });
Troubleshooting
- Streaming not working when proxied