Skip to main content

Server Setup

How to configure the flow-state.dev server runtime in your application.

Basic Setup

The server package provides three main exports: a flow registry, an API router, and store adapters.

import {
createFlowRegistry,
createFlowApiRouter,
} from "@flow-state-dev/server";
import chatFlow from "./flows/hello-chat/flow";
import agentFlow from "./flows/agent/flow";

const registry = createFlowRegistry();
registry.register(chatFlow);
registry.register(agentFlow);

const router = createFlowApiRouter({ registry });

Next.js App Router Integration

Create a catch-all route:

app/api/flows/[...path]/route.ts
import { createFlowRegistry, createFlowApiRouter } from "@flow-state-dev/server";
import chatFlow from "@/flows/hello-chat/flow";

const registry = createFlowRegistry();
registry.register(chatFlow);

const router = createFlowApiRouter({ registry });

export const GET = router.GET;
export const POST = router.POST;
export const DELETE = router.DELETE;

This exposes all framework endpoints under /api/flows/.

API Endpoints

MethodPathPurpose
GET/api/flowsList registered flows
GET/api/flows/capabilitiesFeature flags
POST/api/flows/:kind/actions/:actionExecute action (new session)
POST/api/flows/:kind/:sessionId/actions/:actionExecute action (existing session)
GET/api/flows/:kind/requests/:requestId/streamSSE request stream
GET/api/flows/sessionsList sessions
GET/api/flows/sessions/:sessionIdSession detail
GET/api/flows/sessions/:sessionId/stateState snapshot (clientData)
POST/api/flows/:kind/sessionsCreate session
DELETE/api/flows/sessions/:sessionIdDelete session

Store Configuration

Filesystem Store (Default)

const router = createFlowApiRouter({ registry });
// Uses filesystem stores by default

In-Memory Store (Testing)

import { createInMemoryStores } from "@flow-state-dev/server";

const router = createFlowApiRouter({
registry,
stores: createInMemoryStores(),
});

Model Resolution

Generators need models resolved at runtime. The framework provides a unified model resolver.

Zero-Config Resolver

Auto-detects providers from environment variables (OPENAI_API_KEY, ANTHROPIC_API_KEY, etc.):

import { createModelResolver } from "@flow-state-dev/core/models";

const router = createFlowApiRouter({
registry,
modelResolver: createModelResolver(),
});

Resolver with Options

import { createModelResolver } from "@flow-state-dev/core/models";

const router = createFlowApiRouter({
registry,
modelResolver: createModelResolver({
keys: { openai: process.env.MY_OPENAI_KEY },
presets: { fast: { models: ["openai/gpt-5.4-mini"] } },
}),
});

Request Lifecycle

When an action is invoked:

  1. The server validates the input against the action's inputSchema
  2. Resolves or creates a session
  3. Creates a request scope and stream
  4. Returns 202 Accepted with a requestId
  5. Executes the block asynchronously
  6. Streams events (items, deltas, status) via SSE
  7. Persists state on completion

The client connects to the SSE stream using the requestId to receive real-time results.