Skip to content

Convenience Entrypoints

Convenience entrypoints compose a handler factory with a platform adapter in a single function call. They are the fastest way to deploy an agent endpoint to a specific cloud platform.

Import

import {
  createGcpAgentExecuteEndpoint,
  createAzureAgentExecuteEndpoint,
} from "@modernpath/agent-framework";

createGcpAgentExecuteEndpoint

function createGcpAgentExecuteEndpoint(opts: {
  resolveAgent: AgentResolver;
  getUserId: (event: HttpEvent) => Promise<number> | number;
  cors?: CorsOptions;
}): (req: ExpressRequestLike, res: ExpressResponseLike) => Promise<any>

Composes createAgentExecuteHandler with gcpHttp. Returns a function compatible with the GCP Functions Framework (Express-style request/response).

Parameter Type Description
opts.resolveAgent AgentResolver Maps agentType strings to BaseAgent instances.
opts.getUserId function Extracts user ID from the request event.
opts.cors CorsOptions CORS configuration.

createAzureAgentExecuteEndpoint

function createAzureAgentExecuteEndpoint(opts: {
  resolveAgent: AgentResolver;
  getUserId: (event: HttpEvent) => Promise<number> | number;
  cors?: CorsOptions;
}): (request: AzureHttpRequestLike, context: AzureInvocationContextLike) => Promise<AzureHttpResponseInitLike>

Composes createAgentExecuteHandler with azureHttp. Returns a function compatible with Azure Functions v4 app.http().

Equivalent Manual Composition

The convenience entrypoints are equivalent to manually composing a handler and adapter:

// This convenience call:
const endpoint = createGcpAgentExecuteEndpoint({
  resolveAgent,
  getUserId,
  cors,
});

// Is equivalent to:
const handler = createAgentExecuteHandler({ resolveAgent, getUserId, cors });
const endpoint = gcpHttp(handler);

Use the manual approach when you need to:

  • Apply middleware before or after the handler
  • Use the same handler with multiple adapters
  • Compose handlers for non-standard platforms

Code Examples

GCP Cloud Function

src/functions/agent-execute.ts
import { createGcpAgentExecuteEndpoint } from "@modernpath/agent-framework";

export const agentExecute = createGcpAgentExecuteEndpoint({
  resolveAgent: (agentType) => {
    switch (agentType) {
      case "incident-resolver":
        return new IncidentResolverAgent(toolRegistry, geminiClient);
      case "qa-chat":
        return new QAChatAgent(toolRegistry, geminiClient, retrievalService);
      default:
        throw new Error(`Unknown agent type: ${agentType}`);
    }
  },
  getUserId: async (event) => {
    const token = event.headers?.authorization?.replace("Bearer ", "");
    if (!token) throw new Error("Missing authorization header");
    const decoded = await verifyFirebaseToken(token);
    return decoded.uid;
  },
  cors: {
    origin: process.env.CORS_ORIGIN ?? "*",
  },
});

Azure Function

src/functions/agent-execute.ts
import { createAzureAgentExecuteEndpoint } from "@modernpath/agent-framework";
import { app } from "@azure/functions";

const endpoint = createAzureAgentExecuteEndpoint({
  resolveAgent: (agentType) => agentFactory.resolve(agentType),
  getUserId: (event) => parseInt(event.headers?.["x-user-id"] ?? "0", 10),
});

app.http("agentExecute", {
  methods: ["POST", "OPTIONS"],
  authLevel: "function",
  route: "agent/{auditingId}/execute",
  handler: endpoint,
});

Multiple Endpoints

For a complete deployment with agent execution, streaming, traces, conversations, and KB admin:

src/functions/index.ts
import {
  createGcpAgentExecuteEndpoint,
  createAgentExecuteStreamHandler,
  createTraceHandler,
  createConversationHandler,
  createKnowledgeBaseAdminHandlers,
  gcpHttp,
} from "@modernpath/agent-framework";

// Synchronous agent execution
export const agentExecute = createGcpAgentExecuteEndpoint({
  resolveAgent,
  getUserId,
});

// Streaming agent execution (manual composition needed for SSE)
const streamHandler = createAgentExecuteStreamHandler({
  resolveAgent,
  getUserId,
});

export const agentStream = async (req: any, res: any) => {
  const event = toHttpEvent(req);
  const sseResponse = await streamHandler(event);
  res.status(sseResponse.statusCode);
  for (const [k, v] of Object.entries(sseResponse.headers)) {
    res.set(k, v);
  }
  for await (const chunk of sseResponse.stream) {
    res.write(chunk);
  }
  res.end();
};

// Trace queries
export const traces = gcpHttp(createTraceHandler({ traceStore }));

// Conversations
export const conversations = gcpHttp(
  createConversationHandler({
    resolveAgent,
    getUserId,
    conversationStore,
  }),
);

// KB Admin
const kbHandlers = createKnowledgeBaseAdminHandlers({ gemini: geminiClient });
export const kbListStores = gcpHttp(kbHandlers.listStores);
export const kbListDocs = gcpHttp(kbHandlers.listDocuments);
export const kbUpload = gcpHttp(kbHandlers.uploadJson);
export const kbDelete = gcpHttp(kbHandlers.deleteDocument);