import type { McpServerDefinition } from "../connectors/mcp/McpClient.js"; import type { HttpConnectorDefinition } from "../connectors/http/HttpToolDefinition.js"; /** * The one seam through which Codali learns what a request is allowed to touch. * * Codali is meant to serve many products, and a multi-tenant product like * okacam has a different tool set, different credentials, and different limits * for every tenant. So the tool configuration is never read from a file at run * time — it is *resolved* per request. * * A config file is simply one implementation of this interface, used by the * local CLI and single-tenant deployments. An embedded product implements its * own, or passes a `RunContext` directly on the request; either way the host * supplies the context, and Codali never calls back into the product to fetch * it. That callback would create a circular dependency * (product -> codali -> product) plus the caching, invalidation, and * failure-mode machinery that comes with it, and the authenticated host already * holds this data. */ export interface RunContextRepo { root?: string; repoId?: string; } export interface RunContextDocdex { baseUrl?: string; apiKey?: string; repoRoot?: string; repoId?: string; allowedOperations?: string[]; } export interface RunContextTenant { id?: string; slug?: string; realm?: string; /** * The product this tenant belongs to, sent to mswarm alongside the per-tenant * identity so a self-hosted node can grant every tenant of a product at once. * Hosts that set `MSWARM_CLIENT_PRODUCT` in their deployment can leave this unset. */ product?: string; } export interface RunContextLimits { maxRounds?: number; maxToolCalls?: number; maxModelCalls?: number; deadlineMs?: number; } export interface RunContextAgentRoles { /** Routes, plans, assesses completeness, repairs. Runs on every question. */ orchestrator?: string; /** Makes the tool calls. Defaults to the orchestrator when unset. */ worker?: string; /** Produces multi-source answers. */ synthesizer?: string; /** Generates images and other media. */ media?: string; } export interface RunContext { tenant?: RunContextTenant; repo?: RunContextRepo; docdex?: RunContextDocdex; agentRoles?: RunContextAgentRoles; limits?: RunContextLimits; /** * MCP servers this run may connect to. * * Only ever populated from user/host config or a host-supplied context — * never from repository config. See {@link scrubRepoConfig}. */ mcpServers?: McpServerDefinition[]; /** * Hand-declared HTTP connectors. Same trust rules as MCP servers: trusted * layers only, never repository config. */ httpConnectors?: HttpConnectorDefinition[]; /** Tool names permitted for this run. Absent means "registry default". */ allowedTools?: string[]; deniedTools?: string[]; /** Non-fatal problems encountered while resolving, surfaced in the trace. */ warnings?: string[]; } export interface RunContextResolveInput { workspaceRoot: string; tenant?: RunContextTenant; /** Context supplied directly by an embedding host, taking precedence. */ provided?: RunContext; } export interface RunContextResolver { readonly id: string; resolve(input: RunContextResolveInput): Promise; } export interface RepoConfigScrubResult { value: Record; rejectedKeys: string[]; } /** * Strips forbidden keys from a repository config, recording what was dropped. * Rejection is loud rather than silent: the keys land in run warnings so a * repository that tries to widen its own permissions is visible. */ export declare const scrubRepoConfig: (config: Record, pathPrefix?: string) => RepoConfigScrubResult; /** * Merges a narrower context over a broader one. Allow-lists intersect and * deny-lists union, so a later layer can only ever restrict what an earlier one * permitted — never widen it. */ export declare const mergeRunContexts: (base: RunContext, override: RunContext) => RunContext; export interface LocalConfigResolverOptions { /** Overridden in tests; defaults to `~/.codali`. */ userConfigDir?: string; } /** * Resolves run context from trusted user config, then applies the repository's * narrowing config on top. Used by the CLI and any single-tenant deployment. */ export declare class LocalConfigRunContextResolver implements RunContextResolver { private readonly options; readonly id = "local_config"; constructor(options?: LocalConfigResolverOptions); resolve(input: RunContextResolveInput): Promise; } /** * Uses context handed over by an embedding host. This is the okacam path: the * product resolves the tenant's tools and credentials from its own database and * passes them on the request. */ export declare class ProvidedRunContextResolver implements RunContextResolver { readonly id = "provided"; resolve(input: RunContextResolveInput): Promise; } export declare const resolveRunContext: (input: RunContextResolveInput, resolver?: RunContextResolver) => Promise; //# sourceMappingURL=RunContextResolver.d.ts.map