Aviary
Packages

@dudousxd/nestjs-agent-codegen

A @dudousxd/nestjs-codegen extension that injects a typed api.agent.* client for the agent's JSON REST routes into your generated api.ts.

The agent's controllers live in node_modules, where @dudousxd/nestjs-codegen's static AST discovery can't see them. This extension injects the JSON REST routes directly — the agents catalog, threads (incl. rename/promote/fork/truncate), tool-call approve/reject/answer/skip, skills, tools, memories, staged attachments, message feedback, the model catalog, quota, client config, the message queue and cancel — so they show up in your unified generated client. A spec in the package (covers-every-json-route.spec.ts) reads the library's controllers off disk and fails when a JSON route there is missing from the injected list.

pnpm add -D @dudousxd/nestjs-agent-codegen @dudousxd/nestjs-codegen

Minimal example

// codegen.config.ts
import { defineConfig } from '@dudousxd/nestjs-codegen';
import { nestjsAgentCodegen } from '@dudousxd/nestjs-agent-codegen';

export default defineConfig({
  extensions: [nestjsAgentCodegen({ basePath: '/api' })],
});
// generated client usage — plain fetch always works:
import { api } from '../lib/api';

const threads = await api.agent.threads.list();
await api.agent.toolCall.approve({ body: { toolCallId } });

With the @dudousxd/nestjs-codegen-tanstack extension registered, each call also returns a handle with .queryOptions() / .mutationOptions():

import { useQuery, useMutation } from '@tanstack/react-query';

const threads = useQuery(api.agent.threads.list().queryOptions());
const approve = useMutation(api.agent.toolCall.approve().mutationOptions());

Routes deliberately omitted

POST /agent/chat and GET /agent/chat/:runId/stream are SSE, not JSON, so they're excluded from the generated client. Use @dudousxd/nestjs-agent-react's useAgentChat (a Vercel AI SDK transport) for those — see Frontend. POST /agent/attachments is a multipart upload and is also left out.

The resumable-upload routes under /agent/attachments/uploads and the AG-UI route are also left out (the first follow the tus protocol, the second answers a stream). Call those with your own client.

Exports

ExportKindPurpose
nestjsAgentCodegen(options?)function → AgentCodegenExtensionInjects the agent's JSON REST routes (table below) into the codegen route set. The extension's name is 'nestjs-agent'; transformRoutes appends the fixed list synchronously
AgentCodegenExtensiontypeCodegenExtension with a required transformRoutes(routes)
AgentCodegenOptionstype{ basePath?: string; name?: string } — the mount prefix (default '') and the client namespace (default 'agent', i.e. api.agent.*)

Routes it injects

Method & pathGenerated name
GET /agent/agentsagent.agents.list
GET /agent/modelsagent.models.list
GET /agent/threadsagent.threads.list
GET /agent/threads/:idagent.threads.get
DELETE /agent/threads/:idagent.threads.remove
POST /agent/threads/:id/fork-from/:messageIdagent.threads.fork
PATCH /agent/threads/:idagent.threads.rename (body: title, defaultAgent, model, persona)
POST /agent/threads/:id/promoteagent.threads.promote
DELETE /agent/threads/:id/from/:messageIdagent.threads.truncate
POST /agent/tool-call/approveagent.toolCall.approve
POST /agent/tool-call/rejectagent.toolCall.reject
POST /agent/tool-call/answeragent.toolCall.answer
POST /agent/tool-call/skipagent.toolCall.skip
GET /agent/skillsagent.skills.list
GET /agent/toolsagent.tools.list
GET /agent/memoriesagent.memories.list
DELETE /agent/memories/:idagent.memories.forget
GET /agent/attachmentsagent.attachments.list
POST /agent/messages/:id/feedbackagent.messages.feedback
GET /agent/quotaagent.quota.report
GET /agent/configagent.config
GET /agent/threads/:id/queueagent.queue.get
DELETE /agent/threads/:id/queueagent.queue.clear
POST /agent/threads/:id/queue/resumeagent.queue.resume
PATCH /agent/queue/:messageIdagent.queue.update
POST /agent/queue/:messageId/interruptagent.queue.interrupt
DELETE /agent/queue/:messageIdagent.queue.remove
POST /agent/chat/:runId/cancelagent.chat.cancel
GET /agent/threads/:threadId/action-proposalsagent.actionProposals.list
POST /agent/threads/:threadId/action-proposals/:proposalId/approveagent.actionProposals.approve (body: remember?)
POST /agent/threads/:threadId/action-proposals/:proposalId/rejectagent.actionProposals.reject (body: reason?)

Response and body types are hand-mirrored from @dudousxd/nestjs-agent-core (dates are ISO strings); deeply nested tool-call payloads are typed loosely as Record<string, unknown>[].

Peer dependencies

@dudousxd/nestjs-codegen (>=0.2.0).

When to use it

Add this extension once your frontend already consumes a @dudousxd/nestjs-codegen-generated client and you want the agent's thread/quota/approval surface typed the same way as the rest of your API — rather than hand-writing a client against those routes.

  • Frontend — useAgentChat, the streaming transport, and where the generated client fits alongside it
  • Codegen docs — the extension mechanism and the unified api.ts output

On this page