reference

@kestrel-agents/next

Next.js route helpers for exposing Kestrel through typed server routes while keeping context, credentials, and correlation on the server.

Next.jsintermediate0.7.0 Stable
Verified 2026-07-20View sourceReport a docs issue

@kestrel-agents/next handles request parsing, authenticated context, correlation headers, and SSE formatting inside Next.js route handlers.

Install

Bash
pnpm add @kestrel-agents/next@0.7.0 @kestrel-agents/sdk@0.7.0

Route helpers

HelperBest forKey responsibility
createJsonRunRouteHandler()request-response routesparse body, resolve context, return JSON terminal event
createStreamRunRouteHandler()live browser progressparse body, resolve context, stream SSE, propagate cancellation
createWebhookRunRouteHandler()external or background payloadsmap arbitrary payload into a Kestrel turn

Two integration shapes

You usually choose between two patterns:

PatternBest fitWhy choose it
route-helper integrationNext.js app wants typed Kestrel turnsclean server-only route code, built-in correlation handling, easy transition into SDK features
OpenAI-compatible proxyingapp already speaks OpenAI chat or responsespreserves the existing client request format while routing through Kestrel

Use compatibility mode to preserve an existing client. Move to route helpers when the application needs typed sessions, memory, and operator behavior.

Route example

TypeScript
export const POST = createStreamRunRouteHandler({
  agent,
  resolveContext,
});

OpenAI-compatible proxy example

For chat-first products, keep the browser pointed at your Next.js route and forward to /v1/chat/completions or /v1/responses from the server:

TypeScript
export async function POST(request: Request) {
  const body = await request.text();
  const user = await requireAuthenticatedUser(request);
 
  const upstream = await fetch(
    `${process.env.KESTREL_RUNNER_SERVICE_URL}/v1/chat/completions`,
    {
      method: "POST",
      headers: {
        "content-type": "application/json",
        authorization: `Bearer ${process.env.KESTREL_RUNNER_SERVICE_TOKEN}`,
        "x-kestrel-actor-id": user.id,
        "x-kestrel-actor-type": "end_user",
        "x-kestrel-actor-name": user.name,
        "x-kestrel-tenant-id": user.tenantId,
      },
      body,
    },
  );
 
  return new Response(upstream.body, {
    status: upstream.status,
    headers: upstream.headers,
  });
}

Correlation headers

The route helpers read:

  • x-request-id
  • x-correlation-id
  • user-agent
  • x-forwarded-for

If those values are missing, the helper generates request and correlation IDs and returns them as x-kestrel-request-id and x-kestrel-correlation-id.

Those two headers connect the application request to later inspection. When you proxy the OpenAI-compatible runner endpoints instead, preserve their separate upstream session, run, thread, and model headers as well.

Common failure cases

FailureUsually means
route body missing sessionIdthe caller sent an incomplete request
stream closes immediatelyupstream cancellation or runner outage
actor context missingserver route did not resolve context correctly
webhook payload maps badlymapPayload() does not match the incoming payload
OpenAI-compatible request works but control-plane routes do not existyou stayed on compat mode too long for the product needs

When to choose this package

Use it when your product is already in Next.js and you want to keep:

  • browser traffic pointed at your app
  • runner credentials on the server
  • Kestrel request correlation explicit
  • route code small and repeatable

Move deeper into the SDK and custom protocol when the app needs operator inbox/thread/control, task graph, project snapshot, or filtered /events/stream subscriptions. That is the line between "proxying Kestrel" and "building directly on Kestrel."

Put the helpers to work