import type { ActionEntry } from "../../agent/production-agent.js"; /** * The agent loop a request runs on: interactive chat (production or dev), an * A2A task, or an MCP `ask_app` call. */ export type AgentChatAdditionalActionsSurface = "chat" | "a2a" | "mcp"; /** Surfaces an app must opt into before its additional actions reach them. */ export type AgentChatAdditionalActionsExternalSurface = Exclude; export interface AgentChatAdditionalActionsDetails { surface: AgentChatAdditionalActionsSurface; /** The H3 event. Absent for `mcp`, which runs outside a chat handler. */ event?: any; ownerEmail: string; orgId: string | null; /** * The chat thread and the turn the client asked to continue, and whether * this request continues a turn already in progress. Chat only. An app that * wants one tool set for a whole turn can key its own snapshot on these. */ threadId?: string; requestedTurnId?: string; internalContinuation?: boolean; } export type ResolveAgentChatAdditionalActions = (details: AgentChatAdditionalActionsDetails) => Record | Promise>; export interface AppAdditionalActionsConfig { resolver: ResolveAgentChatAdditionalActions | undefined; /** Surfaces besides chat the app opted into. */ externalSurfaces: readonly AgentChatAdditionalActionsExternalSurface[]; /** * True for every name any surface can dispatch to a framework, template, or * dev implementation, including names the current surface leaves out. */ isReservedName: (name: string) => boolean; } export declare function normalizeAdditionalActionSurfaces(surfaces: readonly string[] | undefined): AgentChatAdditionalActionsExternalSurface[]; /** * Runs the app's `resolveAdditionalActions` once for one request and returns * the entries that may join that request's registry. * * Everything the app returns is untrusted: it may carry names, descriptions, * and schemas a user registered. An entry is dropped (and reported once) when * its name is malformed or reserved, when it is an `mcp__` name this caller * cannot see, or when its tool definition is unusable. Each kept entry is bound * to the caller it was resolved for and its `run` is wrapped so every call, * from any dispatcher, rechecks that caller, enforces the entry's `access` * policy, and validates the arguments against its schema without coercion. */ export declare function resolveAppAdditionalActions(config: AppAdditionalActionsConfig, details: { surface: AgentChatAdditionalActionsSurface; event?: any; ownerEmail: string | null | undefined; orgId: string | null | undefined; threadId?: string; requestedTurnId?: string; internalContinuation?: boolean; }, registered: Record): Promise>;