/** * `@ai-matrx/agents/runtime` — the RUN TIER's row types (agent core B2). * * The run tier is everything a client needs to RUN an agent and nothing it needs to BUILD one: * name, description, variables, context rules, the kill switches, the default model, UI gates, * tool ids, access level and the run-control counts. JSON columns are typed `unknown` here — the * core never interprets variable, context-policy or gate shapes; a host narrows them at its seam * (chat's `AgentRunTier` does). */ /** One `agx_get_run_tier(p_agent_id)` row. */ interface AgentRunTierRow { id: string; is_version: boolean; version_id: string | null; name: string; description: string | null; variable_definitions: unknown[] | null; context_policies: unknown[] | null; auto_context_disabled: boolean; model_id: string | null; ui_gates: Record | null; tool_ids: string[] | null; access_level: string; custom_tool_count: number; skill_count: number; connection_count: number; /** The agent's model settings (a small object): the override-diff base and what "Model and overrides" shows. */ settings?: Record | null; } /** The run tier's plain counts (P24b). */ interface AgentRunCounts { customTools: number; skills: number; connections: number; } /** One `agx_get_run_controls(p_agent_id)` row — what the run-control pickers show (P25). */ interface AgentRunControlsRow { id: string; tool_ids: string[] | null; custom_tool_names: string[] | null; auto_tools_disabled: boolean | null; skill_config: unknown; /** Catalog server IDS (uuid) — never names. Read `mcp_server_slugs` to name or resolve a connector. */ mcp_servers: string[] | null; /** The same servers as catalog slugs, in the same order (a server the caller cannot see has none). */ mcp_server_slugs?: string[] | null; /** The agent's forbidden tool names (`tool_config.excluded_tools`); the composer shows them off. */ excluded_tools?: string[] | null; } /** One `agx_get_access_level(p_agent_id)` row. */ interface AgentAccessLevelRow { agent_id: string; agent_name: string; owner_id: string; owner_email: string; access_level: "owner" | "admin" | "editor" | "viewer" | "public" | "none"; is_owner: boolean; } /** One `agx_get_shared_with_me()` row. */ interface SharedAgentItem { id: string; name: string; description: string | null; agent_type: "user" | "builtin"; category: string | null; tags: string[]; owner_id: string | null; owner_email: string | null; permission_level: string; created_at: string; updated_at: string; } /** One `agx_get_shared_for_chat()` row. */ interface SharedAgentForChat { id: string; name: string; permission_level: string; owner_email: string | null; } type RunTierStatus = "idle" | "loading" | "ready" | "failed"; /** One cached read. `data` is the last good answer; a failed refresh keeps it and sets `error`. */ interface RunTierEntry { status: RunTierStatus; data: T | null; error: string | null; } declare function runCountsOf(row: Pick): AgentRunCounts; /** * `@ai-matrx/agents/runtime` — `createRunTierStore`: the headless RUN TIER store (agent core B2). * * The ONE place a client reads what it needs to RUN an agent: the run tier (`agx_get_run_tier`), * the run controls (`agx_get_run_controls`), the caller's access level (`agx_get_access_level`) and * the shared lists (`agx_get_shared_with_me`, `agx_get_shared_for_chat`). Built like * `createAgentCatalog` / `createSkillCatalog`: framework-free, `getState` / `subscribe`, no Redux. * A host binds it (chat's run thunks read it; extend/local/vscode call it directly). * * It READS only (guard G1). Every read is deduped in flight and cached per agent; `force` re-reads. * A read failure rejects with `RunTierReadError` AND lands in the entry's `error` + the * `errorSink` — never silent. An empty answer is a refusal (`RunTierNotReadableError`), never a * quiet success: the RPCs answer `[]` when the caller cannot read the agent. */ interface RunTierPgError { message: string; code?: string; details?: string | null; hint?: string | null; } interface RunTierRpcResult { data: unknown; error: RunTierPgError | null; } /** REQUIRED. A structural subset of `SupabaseClient` — only `rpc`. */ interface RunTierClient { rpc(fn: string, args?: Record): PromiseLike; } type RunTierErrorSink = (event: { code: string; message: string; context?: object; }) => void; interface RunTierStoreConfig { client: RunTierClient; /** OPTIONAL — DEFAULT: a tagged `console.error`. */ errorSink?: RunTierErrorSink; /** OPTIONAL — per-attempt timeout for the run tier read. DEFAULT 15 000 ms. */ timeoutMs?: number; /** OPTIONAL — attempts for the run tier read (a dropped connection retries once). DEFAULT 2. */ attempts?: number; } /** A read failed. `operation` is the plain-English action for the host's error door. */ declare class RunTierReadError extends Error { readonly operation: string; readonly pgError: RunTierPgError | null; constructor(operation: string, message: string, pgError: RunTierPgError | null); } /** The RPC answered no row: the caller cannot read this agent. */ declare class RunTierNotReadableError extends Error { readonly agentId: string; constructor(agentId: string); } /** The run tier read did not answer in time. */ declare class RunTierTimeoutError extends Error { readonly timeoutMs: number; constructor(timeoutMs: number); } interface RunTierState { runTier: Record>; runControls: Record>; accessLevel: Record>; sharedWithMe: RunTierEntry; sharedForChat: RunTierEntry; } interface RunTierStore { getState(): RunTierState; subscribe(listener: () => void): () => void; /** The run tier for one agent. Cached; `force` re-reads. Rejects on refusal or failure. */ loadRunTier(agentId: string, options?: { force?: boolean; }): Promise; /** The run controls for one agent (fetched when a run-control picker opens). */ loadRunControls(agentId: string, options?: { force?: boolean; }): Promise; /** The caller's access level on one agent. */ loadAccessLevel(agentId: string, options?: { force?: boolean; }): Promise; loadSharedWithMe(options?: { force?: boolean; }): Promise; loadSharedForChat(options?: { force?: boolean; }): Promise; /** * Hold a GENERATED run tier answer (`@ai-matrx/agents/mandates` `MANDATE_DISPLAY_SEEDS`) as if * it had been read — only when nothing for that agent is held or reading. Returns whether it * seeded. Once per agent: after `invalidate` the next ask is a real read. */ seedRunTier(row: AgentRunTierRow): boolean; getRunTier(agentId: string): AgentRunTierRow | undefined; getRunControls(agentId: string): AgentRunControlsRow | undefined; getAccessLevel(agentId: string): AgentAccessLevelRow | undefined; /** Drop every cached read for one agent (a save landed; the next read is fresh). */ invalidate(agentId: string): void; } declare function createRunTierStore(config: RunTierStoreConfig): RunTierStore; /** * The run-control counts (agent core B5): the at-a-glance numbers for the attach menu's * "This run" rows (Tools / Skills). Pure — the instance-bound hook lives in chat. * * The numbers mirror exactly what ships with the request: * Tools — the agent's configured tools (built-in + custom) plus the per-run `addedTools`. * Skills — the agent's visible tiers (included + listed) plus `addedSkills`, deduped. A disabled * skill config counts only the explicit per-run adds, which re-enable it. * Counts are withheld (absent) until the agent's run tier has loaded, so the menu never shows a * confident "0" that jumps to "12" a moment later. Once the real lists are known, they win. */ interface RunControlCounts { tools?: number; skills?: number; } interface RunControlCountsInput { /** The run has an agent at all (none → the per-run adds are the whole story). */ hasAgent: boolean; /** The agent's run tier has answered. */ runTierReady: boolean; /** The run tier's plain counts, when answered. */ runCounts: AgentRunCounts | null | undefined; builtInToolIds: readonly string[] | null | undefined; /** The agent's custom tools, when the record has READ them (else the run tier's count is used). */ customTools: readonly unknown[] | null | undefined; customToolsKnown: boolean; /** The agent's skill config, when the record has READ it (else the run tier's count is used). */ skillConfig: { disabled?: boolean; included: readonly string[]; listed: readonly string[]; } | null | undefined; skillConfigKnown: boolean; addedTools: readonly string[]; addedSkills: readonly string[]; } declare function computeRunControlCounts(input: RunControlCountsInput): RunControlCounts; export { RunTierNotReadableError, RunTierReadError, RunTierTimeoutError, computeRunControlCounts, createRunTierStore, runCountsOf }; export type { AgentAccessLevelRow, AgentRunControlsRow, AgentRunCounts, AgentRunTierRow, RunControlCounts, RunControlCountsInput, RunTierClient, RunTierEntry, RunTierErrorSink, RunTierPgError, RunTierRpcResult, RunTierState, RunTierStatus, RunTierStore, RunTierStoreConfig, SharedAgentForChat, SharedAgentItem };