Handler Factories¶
Handler factories create platform-agnostic request handlers that accept a generic HttpEvent and return a JsonResponse (or SseResponse for streaming). Customers provide agent resolution, authentication, and stores; the framework handles request parsing, error handling, and response formatting.
Import¶
import {
createAgentExecuteHandler,
createAgentExecuteStreamHandler,
createConversationHandler,
createTraceHandler,
createKnowledgeBaseAdminHandlers,
HttpEvent,
AgentResolver,
CorsOptions,
} from "@modernpath/agent-framework";
Common Types¶
HttpEvent¶
interface HttpEvent {
pathParameters?: Record<string, string | undefined>;
queryStringParameters?: Record<string, string | undefined>;
headers?: Record<string, string | undefined>;
body?: string | null;
method?: string;
}
JsonResponse¶
CorsOptions¶
interface CorsOptions {
origin?: string; // Default: "*"
allowHeaders?: string; // Default: "content-type, authorization"
allowMethods?: string; // Default: "POST, OPTIONS"
maxAgeSeconds?: number; // Default: 600
}
AgentResolver¶
createAgentExecuteHandler¶
function createAgentExecuteHandler(opts: {
resolveAgent: AgentResolver;
getUserId: (event: HttpEvent) => Promise<number> | number;
cors?: CorsOptions;
}): (event: HttpEvent) => Promise<JsonResponse>
Creates a handler for synchronous agent execution. Accepts POST requests with an AgentExecuteRequestBody:
interface AgentExecuteRequestBody {
agentType: string;
prompt: string;
parameters?: Record<string, any>;
history?: AgentContext["history"];
metadata?: AgentContext["metadata"];
}
Expected path parameters: auditingId
Response: AgentResult on success (200), error on failure (400/500).
createAgentExecuteStreamHandler¶
function createAgentExecuteStreamHandler(opts: {
resolveAgent: AgentResolver;
getUserId: (event: HttpEvent) => Promise<number> | number;
cors?: CorsOptions;
}): (event: HttpEvent) => Promise<SseResponse>
Creates a streaming (SSE) handler for agent execution. Returns a SseResponse:
interface SseResponse {
statusCode: number;
headers: Record<string, string>;
stream: AsyncIterable<string>;
}
SSE Event Types:
| Event | Description |
|---|---|
{ type: "delta", text: "" } | Initial empty delta so UIs can show progress immediately. |
{ type: "final", response: AgentResult } | The complete agent result. |
{ type: "error", error: string } | Error message if execution fails. |
[DONE] | Signals the end of the stream. |
createConversationHandler¶
function createConversationHandler(opts: {
resolveAgent: (agentName: string) => BaseAgent;
getUserId: (event: HttpEvent) => Promise<number> | number;
conversationStore: ConversationStore;
defaultAgentName?: string;
defaultParameters?: Record<string, any>;
maxHistoryMessages?: number; // Default: 50
cors?: CorsOptions;
}): (event: HttpEvent) => Promise<JsonResponse>
Creates a handler for multi-turn conversation endpoints:
| Method | Path Parameters | Description |
|---|---|---|
POST | -- | Create conversation. Body: { agentName?, title?, metadata? } |
GET | -- | List conversations. Query: agentName, limit, offset |
GET | conversationId | Get conversation + messages |
POST | conversationId, subResource: "messages" | Send message. Body: { prompt, parameters?, metadata? } |
DELETE | conversationId | Delete conversation |
The send-message endpoint loads conversation history, executes the agent, and saves both user and assistant messages.
createTraceHandler¶
function createTraceHandler(opts: {
traceStore: TraceStore;
cors?: CorsOptions;
}): (event: HttpEvent) => Promise<JsonResponse>
Creates a read-only handler for trace/session/config-snapshot endpoints:
| Method | Path Parameters | Description |
|---|---|---|
GET | resource: "traces" | List traces. Query: agentName, sessionId, userId, status, tags, after, before, limit, offset |
GET | resource: "traces", resourceId | Get trace + spans |
GET | resource: "sessions" | List sessions. Query: userId, tags, limit, offset |
GET | resource: "sessions", resourceId | Get session + its traces |
GET | resource: "config-snapshots", resourceId | Get config snapshot |
createKnowledgeBaseAdminHandlers¶
function createKnowledgeBaseAdminHandlers(opts: {
gemini: GeminiClient;
cfg?: KnowledgeBaseAdminServiceConfig;
cors?: CorsOptions;
}): {
listStores: (event: HttpEvent) => Promise<JsonResponse>;
createStore: (event: HttpEvent) => Promise<JsonResponse>;
deleteStore: (event: HttpEvent) => Promise<JsonResponse>;
listDocuments: (event: HttpEvent) => Promise<JsonResponse>;
uploadJson: (event: HttpEvent) => Promise<JsonResponse>;
deleteDocument: (event: HttpEvent) => Promise<JsonResponse>;
groundTruthRedirect: (event: HttpEvent) => Promise<JsonResponse>;
}
Returns an object of individual handlers for knowledge base administration. Each handler is a separate function, allowing flexible routing.
| Handler | Method | Path Params | Description |
|---|---|---|---|
listStores | GET | -- | List all knowledge base stores |
createStore | POST | -- | Create a store. Body: { displayName } |
deleteStore | DELETE | storeName | Delete a store |
listDocuments | GET | storeName | List documents in a store |
uploadJson | POST | storeName | Upload document. Body: { filename, mimeType, contentBase64 } |
deleteDocument | DELETE | storeName, docName | Delete a document. Query: deleteGroundTruth |
groundTruthRedirect | GET | storeName, docName | Redirect to ground truth download URL |
Code Example¶
import {
createAgentExecuteHandler,
createTraceHandler,
createConversationHandler,
} from "@modernpath/agent-framework";
// Agent execution
const agentHandler = createAgentExecuteHandler({
resolveAgent: (type) => {
if (type === "incident-resolver") return incidentResolverAgent;
if (type === "qa-chat") return qaChatAgent;
throw new Error(`Unknown agent: ${type}`);
},
getUserId: async (event) => {
const token = event.headers?.authorization?.replace("Bearer ", "");
return await verifyToken(token);
},
cors: { origin: "https://app.example.com" },
});
// Trace queries
const traceHandler = createTraceHandler({
traceStore: firestoreTraceStore,
});
// Conversations
const conversationHandler = createConversationHandler({
resolveAgent: (name) => agentFactory.resolve(name),
getUserId: (event) => parseInt(event.headers?.["x-user-id"] ?? "0"),
conversationStore: firestoreConversationStore,
defaultAgentName: "qa-chat",
maxHistoryMessages: 50,
});
Related Pages¶
- Platform Adapters -- wiring handlers to cloud platforms
- Convenience Entrypoints -- one-liner deployment functions
- Core / BaseAgent -- agents executed by handlers