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; authorizeThread keeps 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 zod
EnvironmentGOOGLE_API_KEY
run · bash
GOOGLE_API_KEY=your-key bun tetsu-server.ts

Or run the full example from a clone of the repository (keys in .env):

repository · bash
bun examples/integrations/08-tetsu-server.ts

Try 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"}'

Learn more