import type { RuntimeEventDomain } from '../runtime/events/index.js'; export type GatewayMethodTransport = 'http' | 'ws' | 'internal'; export type GatewayMethodSource = 'builtin' | 'plugin'; export type GatewayMethodAccess = 'public' | 'authenticated' | 'admin' | 'remote-peer'; export type GatewayEventTransport = 'sse' | 'ws' | 'internal'; export interface GatewayHttpBinding { readonly method: 'GET' | 'POST' | 'PATCH' | 'DELETE'; readonly path: string; } export interface GatewayMethodDescriptor { readonly id: string; readonly title: string; readonly description: string; readonly category: string; readonly source: GatewayMethodSource; readonly access: GatewayMethodAccess; readonly transport: readonly GatewayMethodTransport[]; readonly scopes: readonly string[]; readonly http?: GatewayHttpBinding | undefined; readonly events?: readonly string[] | undefined; readonly inputSchema?: Record | undefined; readonly outputSchema?: Record | undefined; readonly pluginId?: string | undefined; readonly dangerous?: boolean | undefined; /** * Defaults to `true`. When explicitly `false`, this method is NOT dispatchable * through the generic HTTP/WS method-invocation surface * (`invokeGatewayMethodCall`/`invokeWebSocketControlPlaneCall` in * `../daemon/control-plane.ts`, guarded by `validateGatewayInvocation`, which * rejects it with an honest 400 `NOT_INVOKABLE` before any handler or route is * even considered), nothing more, nothing less. * * This is a statement about ONE dispatch path, not a claim that the method can * never run anywhere. Two independent reasons a descriptor carries * `invokable: false`: * - No route or internal handler exists at all for this build (e.g. `email.*`, * `calendar.*`, cataloged so the contract is honest about the capability's * shape, but genuinely unavailable everywhere). * - A real route DOES exist and IS served (e.g. `voice.tts.stream`, * `control.events.stream`, `artifacts.content.get`), just not through the * generic JSON-envelope invoke path, the response is binary/streaming/HTML * (see `metadata.responseKind`) and callers must use the direct HTTP path * instead. * * A runtime that registers a real in-process handler for this method id (via * `GatewayMethodCatalog.register(descriptor, handler)`) and calls * `GatewayMethodCatalog.invoke()` DIRECTLY (bypassing `validateGatewayInvocation`) * still serves it, `invoke()` itself does not consult this flag, by design: a * consuming runtime that has wired up a genuine handler is authoritative over * whether the method actually works, this descriptor is not. `invoke()` only * refuses when BOTH `invokable === false` AND no handler is registered, see * `method-catalog.ts`'s `invoke()`. */ readonly invokable?: boolean | undefined; readonly metadata?: Record | undefined; } export interface GatewayEventDescriptor { readonly id: string; readonly title: string; readonly description: string; readonly category: string; readonly source: GatewayMethodSource; readonly transport: readonly GatewayEventTransport[]; readonly scopes: readonly string[]; readonly domains?: readonly RuntimeEventDomain[] | undefined; readonly wireEvents?: readonly string[] | undefined; readonly outputSchema?: Record | undefined; readonly pluginId?: string | undefined; readonly metadata?: Record | undefined; } export interface GatewayMethodInvocationContext { readonly principalId?: string | undefined; readonly principalKind?: 'user' | 'bot' | 'service' | 'token' | 'remote-peer' | undefined; readonly admin?: boolean | undefined; readonly scopes?: readonly string[] | undefined; readonly clientKind?: string | undefined; readonly authToken?: string | undefined; readonly metadata?: Record | undefined; } export interface GatewayMethodInvocation { readonly body?: unknown | undefined; readonly query?: Record | undefined; readonly context: GatewayMethodInvocationContext; } export type GatewayMethodHandler = (input: GatewayMethodInvocation) => unknown | Promise; export interface GatewayMethodListOptions { readonly category?: string | undefined; readonly source?: GatewayMethodSource | undefined; readonly pluginId?: string | undefined; } export interface GatewayEventListOptions { readonly category?: string | undefined; readonly source?: GatewayMethodSource | undefined; readonly pluginId?: string | undefined; readonly domain?: RuntimeEventDomain | undefined; } export declare const EMPTY_OBJECT_SCHEMA: { readonly type: "object"; readonly properties: {}; readonly additionalProperties: false; }; export declare const STRING_SCHEMA: { readonly type: "string"; }; export declare const BOOLEAN_SCHEMA: { readonly type: "boolean"; }; export declare const NUMBER_SCHEMA: { readonly type: "number"; }; export declare const JSON_VALUE_SCHEMA: Record; export declare const JSON_OBJECT_SCHEMA: Record; export declare const JSON_ARRAY_SCHEMA: Record; export declare function arraySchema(itemSchema: Record): Record; export declare function objectSchema(properties: Record>, required?: readonly string[], options?: { readonly additionalProperties?: boolean; }): Record; export declare const GATEWAY_HTTP_BINDING_SCHEMA: Record; export declare const METHOD_DESCRIPTOR_SCHEMA: Record; export declare const EVENT_DESCRIPTOR_SCHEMA: Record; export declare function listOutputSchema(key: string, itemSchema: Record): Record; export declare function entityOutputSchema(key: string, entitySchema: Record): Record; export declare function actionResultOutputSchema(key: string, entitySchema: Record): Record; export declare function bodyEnvelopeSchema(properties?: Record>, required?: readonly string[], options?: { readonly dependentRequired?: Readonly>; }): Record; /** * An input schema for a verb whose required set is CONDITIONAL, "id when kind * names a specific item", "one of dataBase64/text/path/uri", "cron when the * schedule is a cron". * * Handlers like these refuse a call that a flat `required` array calls valid, * and the flat array cannot be repaired by adding the field: `id` is genuinely * not required for `kind: 'overview'`, so declaring it required would refuse * calls that work today. * * The encoding is a BASE schema, every property, plus whatever is required * unconditionally, carrying an `anyOf` of small requirement branches. Both * consumers read it that way: * - `invoke-input-validation.ts` checks the base first and then requires one * branch to match (proper JSON Schema conjunction). * - `scripts/check-foundation-io-types.ts` renders it as `Base & (B1 | B2)`. * * Why factored rather than a union of whole objects, which reads more directly: * repeating a thirty-property object four times, twice (automation's job and * schedule create verbs), made the operator client's method map exceed * TypeScript's union-complexity limit outright, `client-core.ts` stopped * compiling with TS2590. Intersecting one base with small branches says the * same thing at a fraction of the type size. * * Each branch must still be a real object schema naming its own required * fields as properties, with `additionalProperties: true` so it constrains * only what it names, `requirementBranch` builds that shape. A bare * `{ required: [...] }` fragment would render as `unknown`, which is how * `knowledge.ingest.connector` ended up with no consumer type at all. */ export declare function branchedSchema(base: Record, requirementBranches: readonly Record[]): Record; /** * One requirement branch: the fields this alternative makes mandatory, and * nothing else. Anything the branch does not name is left to the base schema, * which is where the full property list and the open-ended body envelope live. * * The branch is `additionalProperties: true`, and that is not incidental. These * schemas are PUBLISHED, they become the operator contract artifact and the * OpenAPI document that third-party validators read. A branch saying * `{ required: ['text'], additionalProperties: false }` inside an `anyOf` * rejects `{ text: 'hello', kind: 'note' }`, because the only branch that * accepts `text` forbids `kind`. Our own invoke gate never enforces * `additionalProperties` so nothing would break here, and the published * contract would be quietly wrong for everyone else, the worst kind of wrong, * since it reads as more precise. * * `scripts/check-foundation-io-types.ts` drops the resulting index signature * when it renders a branch, because the base it is intersected with already * carries one. Stating it once rather than once per branch is what keeps the * client's method map inside TypeScript's union-complexity limit. */ export declare function requirementBranch(properties: Record>, required: readonly string[]): Record; /** A string constrained to a fixed set of values. */ export declare function stringEnumSchema(values: readonly string[]): Record; export declare function methodDescriptor(input: Omit & Partial>): GatewayMethodDescriptor; export declare function eventDescriptor(input: Omit & Partial>): GatewayEventDescriptor; export declare function runtimeEventId(domain: RuntimeEventDomain): string; export declare function runtimeDomainEvent(domain: RuntimeEventDomain, description: string): GatewayEventDescriptor; //# sourceMappingURL=method-catalog-shared.d.ts.map