Tetsu on Bun
medium15 mintetsu-server.ts
Your API runs on Bun with Tetsu. Signed-in users talk to an agent that can only touch their own tasks and threads.
What it shows
- Mount
cogitatorController()with an auth hook shared with your routes - Tools read the caller from
context.userId;authorizeThreadkeeps threads private - Get OpenAPI docs for free at
/docs
The code
tetsu-server.ts
import { Agent, Cogitator, tool } from '@cogitator-ai/core';
import { callerHook, cogitatorController, type AuthContext } from '@cogitator-ai/tetsu';
import { createApp, group, type BaseCtx } from '@tetsujs/core';
import { docs, secured } from '@tetsujs/openapi';
import { z } from 'zod';
const apiKey = process.env.GOOGLE_API_KEY;
if (!apiKey) throw new Error('Set GOOGLE_API_KEY');
const users = new Map([
['token-ada', { id: 'ada', name: 'Ada' }],
['token-grace', { id: 'grace', name: 'Grace' }],
]);
const tasks = [
{ id: 1, owner: 'ada', title: 'Review the analytical engine notes', done: false },
{ id: 2, owner: 'grace', title: 'Find the moth in relay 70', done: true },
];
function ownerOf(userId: string | undefined): string {
if (!userId) throw new Error('Tasks are only available to a signed-in user');
return userId;
}
const listMyTasks = tool({
name: 'list_my_tasks',
description: "List the signed-in user's tasks",
parameters: z.object({}),
execute: async (_args, context) => tasks.filter((task) => task.owner === ownerOf(context.userId)),
});
const addMyTask = tool({
name: 'add_my_task',
description: 'Add a task for the signed-in user',
parameters: z.object({ title: z.string().min(1) }),
execute: async ({ title }, context) => {
const task = { id: tasks.length + 1, owner: ownerOf(context.userId), title, done: false };
tasks.push(task);
return task;
},
});
function authenticate(ctx: BaseCtx): AuthContext | undefined {
const token = ctx.req.headers.get('authorization')?.replace(/^Bearer /, '');
const user = token ? users.get(token) : undefined;
return user && { userId: user.id, metadata: { name: user.name } };
}
const signedIn = secured(callerHook(authenticate), {
name: 'bearerAuth',
scheme: { type: 'http', scheme: 'bearer' },
error: 'UNAUTHORIZED',
});
const assistant = new Agent({
name: 'assistant',
description: 'Manages the tasks of the signed-in user',
model: 'google/gemini-3.5-flash-lite',
instructions: 'You help the user with their tasks. Use the tools to read and add tasks. Be concise.',
tools: [listMyTasks, addMyTask],
temperature: 0.2,
});
const app = createApp({
routes: [
group('/api/agent', {
children: [
cogitatorController({
cogitator: new Cogitator({
llm: { providers: { google: { apiKey } } },
memory: { adapter: 'memory' },
}),
agents: { assistant },
auth: signedIn,
authorizeThread: (auth, threadId) => threadId.startsWith(`${auth?.userId}:`),
websocket: true,
}),
],
}),
docs({ info: { title: 'Tasks app', version: '1.0.0' } }),
],
});
Bun.serve({ ...app, port: 3104 });
console.log('Listening on http://localhost:3104 (API docs at /docs)');Run it
install · bash
pnpm add @cogitator-ai/core @cogitator-ai/tetsu @tetsujs/core @tetsujs/openapi zodEnvironment
GOOGLE_API_KEYrun · bash
GOOGLE_API_KEY=your-key bun tetsu-server.tsOr run the full example from a clone of the repository (keys in .env):
repository · bash
bun examples/integrations/08-tetsu-server.tsTry it
Try it · bash
curl -X POST http://localhost:3104/api/agent/agents/assistant/run \
-H 'Authorization: Bearer token-ada' -H 'Content-Type: application/json' \
-d '{"input": "What is on my list? Add: call Charles.", "threadId": "ada:1"}'