import { type Principal } from "../auth.js"; export interface Dispatcher { dispatchTool(name: string, args: Record): Promise; getToolNames(): string[]; } export declare function createToolListHandler(opts: { dispatcher: Dispatcher; toolCosts?: Record; /** * Names to withhold from a caller who is not a platform operator. * * The dispatcher keeps them — an operator calls them through this same surface — so this * is what a caller is TOLD exists, not what exists. `createBilling` passes * `OPERATOR_TOOL_NAMES`. */ operatorTools?: readonly string[]; /** How this deployment decides. Defaults to the env-configured operator check. */ isOperator?: (request: Request) => boolean | Promise; }): (request: Request) => Promise; export declare function createToolDispatchHandler(opts: { dispatcher: Dispatcher; realm?: string; /** Advertise the auth.md PRM discovery doc in the 401 WWW-Authenticate header * (`resource_metadata="…"`) so agents can bootstrap. String or per-request. */ resourceMetadata?: string | ((request: Request) => string); /** * WHO is calling, when this surface knows — a session cookie, an OAuth token carrying * a user id. Return null for a request that carries only an org API key. * * Without it the admin-only tools cannot be enforced through this route AT ALL, which * was true until now: `runWithAuth` installs a fresh AsyncLocalStorage store, so an * outer `runWithPrincipal` was discarded, `currentPrincipal()` read null, and * `enforceAdmin` took its org-key branch and allowed everything. An app whose own UI * calls these endpoints was relying on gating it did itself, or on nothing. * * Only pass `isAdmin` if you have already resolved the role and want to skip the * adapter lookup — otherwise leave it off and let `adapter.isAdmin` answer, which is * the path that reads the real role. */ principal?: (request: Request) => Principal | null | Promise; /** * The MPP gate, when the app accepts machine payments. Turns the empty-wallet 402 * below into an OFFER: the same refusal comes back carrying a `WWW-Authenticate: * Payment` challenge, and a caller that settles it has its call dispatched. * * This lives here because the 402 is written here. Both consumers had wrapped this * handler to do it — clone the request, dispatch, look for a 402, call * `requirePayment`, dispatch again — which is the same ten lines twice, in the one * place where getting the retry wrong means either charging twice or serving for * free. `createBilling` wires it automatically whenever `machinePayment` is * configured. * * Only the money 402. A 429 is a rate or spend limit and no payment lifts either. */ payment?: { requirePayment(request: Request): Promise; }; }): (request: Request, ctx: { params: Promise<{ tool: string; }>; }) => Promise; //# sourceMappingURL=rest.d.ts.map