/** * Gateway Types */ import type { App } from "@agentick/core"; import type { SendInput, StreamEvent, ToolConfirmationResponse } from "@agentick/shared"; import type { KernelContext, UserContext } from "@agentick/kernel"; import type { AuthConfig } from "@agentick/server"; import type { ConfigStore } from "./config.js"; export type { AuthConfig, AuthResult } from "@agentick/server"; /** * Schema type that works with both Zod 3 and Zod 4. * Infers output type from parse() return type — no reliance on internal * Zod properties (_output in v3, _zod.output in v4). */ export interface ZodLikeSchema { parse(data: unknown): any; } /** Extract the output type from a schema's parse() method. */ export type SchemaOutput = ReturnType; export type { UserContext } from "@agentick/kernel"; export interface GatewayConfig { /** * Port to listen on (ignored in embedded mode) * @default 18789 */ port?: number; /** * Host to bind to (ignored in embedded mode) * @default "127.0.0.1" */ host?: string; /** * Gateway ID (auto-generated if not provided) */ id?: string; /** * App definitions */ apps: Record; /** * Default app to use when session key doesn't specify one */ defaultApp: string; /** * Authentication configuration */ auth?: AuthConfig; /** * Run in embedded mode (no standalone server). * Use handleRequest() to process requests from your framework. * @default false */ embedded?: boolean; /** * Persistence configuration */ storage?: StorageConfig; /** * Plugins — connectors, integrations, outbound capabilities. * Also addable at runtime via `gateway.use()`. */ plugins?: GatewayPlugin[]; /** * Unix socket path. When set, gateway also listens on this socket. * Orthogonal to `transport` — a gateway can serve WebSocket, HTTP, and * Unix socket clients simultaneously. */ socketPath?: string; /** * Transport mode (ignored in embedded mode) * - "websocket": WebSocket only (default, good for CLI/native clients) * - "http": HTTP/SSE only (good for web browsers) * - "both": Both transports on different ports * @default "websocket" */ transport?: "websocket" | "http" | "both"; /** * HTTP path prefix (e.g., "/api") * @default "" */ httpPathPrefix?: string; /** * CORS origin for HTTP transport * @default "*" */ httpCorsOrigin?: string; /** * HTTP port when using "both" mode * @default port + 1 */ httpPort?: number; /** * Custom methods - runs within Agentick ALS context. * * Supports: * - Simple handlers: `async (params) => result` * - Streaming: `async function* (params) { yield value }` * - With config: `method({ schema, handler, roles, guard })` * - Namespaces: `{ tasks: { list, create, admin: { ... } } }` (recursive) * * Use method() wrapper for schema validation, roles, guards, etc. * ctx param is optional - use Context.get() for idiomatic access. */ methods?: MethodsConfig; /** * Pre-loaded config store. If provided, gateway skips file loading. */ configStore?: ConfigStore; /** * Path to config file (used when configStore not provided). * @default "./agentick.config.json" */ configPath?: string; } export interface StorageConfig { /** * Base directory for storage * @default "~/.agentick" */ directory?: string; /** * Enable session persistence * @default true */ sessions?: boolean; /** * Enable memory persistence * @default true */ memory?: boolean; } /** * Handle available to tool handlers via `Context.get().metadata.gateway`. * Injected when a session is created through the gateway. */ export interface GatewayHandle { /** Invoke any registered gateway method */ invoke(method: string, params: unknown): Promise; /** Register a plugin at runtime */ use(plugin: GatewayPlugin): Promise; /** Remove a plugin at runtime */ remove(pluginId: string): Promise; } export interface GatewayPlugin { /** Unique identifier for this plugin */ id: string; /** Called when the plugin is registered via gateway.use() */ initialize(ctx: PluginContext): Promise; /** Called when the plugin is removed or the gateway stops */ destroy?(): Promise; } export interface PluginContext { /** Route inbound messages to a session (creates if needed). * Returns the execution's event stream — iterate to observe responses, * tool confirmations, etc. The gateway also broadcasts events to * transport subscribers independently, so ignoring the return is safe. */ sendToSession(sessionKey: string, input: SendInput): Promise>; /** Respond to a tool confirmation request within a session */ respondToConfirmation(sessionKey: string, callId: string, response: ToolConfirmationResponse): Promise; /** Register a callable method (for outbound capabilities) */ registerMethod(path: string, handler: SimpleMethodHandler | MethodDefinition): void; /** Unregister a method this plugin registered */ unregisterMethod(path: string): void; /** Invoke any gateway method (including other plugins') */ invoke(method: string, params: unknown): Promise; /** Subscribe to gateway lifecycle events */ on(event: K, handler: (payload: GatewayEvents[K]) => void): void; /** Unsubscribe from gateway events */ off(event: K, handler: (payload: GatewayEvents[K]) => void): void; /** Broadcast an event to all clients subscribed to this plugin */ broadcast(event: string, data: unknown): void; /** Mount an HTTP route handler on the gateway's HTTP server. * Path is relative to the gateway's httpPathPrefix by default (e.g., "mcp" → "{prefix}/mcp"). * Pass `{ absolute: true }` for paths that must be at the domain root regardless of prefix * (e.g., `/.well-known/oauth-authorization-server`). * Routes enforce gateway auth by default. Pass `{ auth: false }` to skip. */ registerRoute(path: string, handler: (req: import("http").IncomingMessage, res: import("http").ServerResponse) => void | Promise, options?: { auth?: boolean; absolute?: boolean; }): void; /** Unmount a route this plugin registered */ unregisterRoute(path: string): void; /** Validate an auth token against the gateway's auth config. * Plugins can use this to enforce auth on their custom routes. */ validateAuth(token: string | undefined): Promise; /** List all registered plugins with their methods */ listPlugins(): Array<{ id: string; methods: string[]; }>; /** Gateway configuration store */ config: ConfigStore; /** Gateway ID for logging */ gatewayId: string; } export interface ClientState { id: string; connectedAt: Date; authenticated: boolean; /** Full user context from auth */ user?: UserContext; subscriptions: Set; metadata?: Record; } export interface SessionState { id: string; appId: string; createdAt: Date; lastActivityAt: Date; messageCount: number; isActive: boolean; subscribers: Set; } export interface GatewayEvents { started: { port: number; host: string; }; stopped: Record; "client:connected": { clientId: string; ip?: string; }; "client:disconnected": { clientId: string; reason?: string; }; "client:authenticated": { clientId: string; user?: UserContext; }; "session:created": { sessionId: string; appId: string; }; "session:closed": { sessionId: string; }; "session:message": { sessionId: string; role: "user" | "assistant"; content: string; }; "app:message": { appId: string; sessionId: string; message: string; }; "plugin:registered": { pluginId: string; }; "plugin:removed": { pluginId: string; }; error: Error; } /** Symbol for detecting method definitions vs namespaces */ export declare const METHOD_DEFINITION: unique symbol; /** * Simple method handler - ctx param is optional since Context.get() works */ export type SimpleMethodHandler, TResult = unknown> = (params: TParams, ctx?: KernelContext) => Promise | TResult; /** * Streaming method handler - yields values to client */ export type StreamingMethodHandler, TYield = unknown> = (params: TParams, ctx?: KernelContext) => AsyncGenerator; /** * Method definition input (what you pass to method()) */ export interface MethodDefinitionInput { /** Zod schema for params validation + TypeScript inference */ schema?: TSchema; /** Zod schema for response (used by schema discovery only) */ response?: ZodLikeSchema; /** Handler function - receives validated & typed params */ handler: SimpleMethodHandler> | StreamingMethodHandler>; /** Required roles - checked before handler */ roles?: string[]; /** Custom guard function */ guard?: (ctx: KernelContext) => boolean | Promise; /** Method description for discovery */ description?: string; } /** * Method definition with symbol marker (returned by method()) */ export interface MethodDefinition extends MethodDefinitionInput { [METHOD_DEFINITION]: true; } /** * Factory function to create a method definition. * Stores config (schema, roles, guards) - the gateway creates the * actual procedure during initialization with the full inferred path name. * * @example * methods: { * tasks: { * list: async (params) => { ... }, // Simple - auto-wrapped * create: method({ // With config * schema: z.object({ title: z.string() }), * handler: async (params) => { ... } * }), * } * } */ /** Schema-less method definition — handler receives Record */ interface MethodDefinitionInputNoSchema { handler: SimpleMethodHandler | StreamingMethodHandler; roles?: string[]; guard?: (ctx: KernelContext) => boolean | Promise; description?: string; response?: ZodLikeSchema; } export declare function method(definition: Omit, "schema"> & { schema: TSchema; }): MethodDefinition; export declare function method(definition: MethodDefinitionInputNoSchema): MethodDefinition; /** * Check if a value is a method definition (vs a namespace) */ export declare function isMethodDefinition(value: unknown): value is MethodDefinition; /** * Method can be: * - Simple function: async (params) => result * - Streaming function: async function* (params) { yield } * - Method definition: method({ schema, handler, roles, ... }) */ export type Method = SimpleMethodHandler | StreamingMethodHandler | MethodDefinition; /** * Method namespace - recursively nested, arbitrary depth */ export type MethodNamespace = { [key: string]: Method | MethodNamespace; }; /** * Methods config - supports flat or nested namespaces */ export type MethodsConfig = MethodNamespace; //# sourceMappingURL=types.d.ts.map