import { type ActivityRoutingContract } from "./activity-routing.js"; import { type SessionManager } from "./session-manager.js"; import type { SessionStateStore } from "./session-store.js"; import { type SessionCatalog } from "./cms.js"; import type { StorageConfig } from "./storage-config.js"; import { type SerializableSessionConfig } from "./types.js"; import type { ArtifactStore } from "./session-store.js"; import type { AgentConfig } from "./agent-loader.js"; import { type CronAtSchedule } from "./cron-at.js"; /** The trimmed agent definition both resolution paths hand to their callers. */ export interface ResolvedAgentDefinition { name: string; prompt: string; tools?: string[]; initialPrompt?: string; initialRequiredTool?: string; title?: string; system?: boolean; id?: string; parent?: string; splash?: string; splashMobile?: string; namespace?: string; promptLayerKind?: "app-agent" | "app-system-agent" | "pilotswarm-system-agent"; creatable?: boolean; /** Present when the definition came from an agent package. */ packageId?: string; packageScope?: "shared" | "user"; } export type RequiredToolAgentResolution = { status: "resolved"; agent: ResolvedAgentDefinition; candidates: string[]; } | { status: "not_found"; candidates: string[]; } | { status: "ambiguous"; candidates: string[]; }; /** * THE agent-name resolver: FQN parsing, fuzzy matching, package privacy, and * owner shadowing in one place. * * This used to exist twice — the resolveAgentConfig activity had the full * rule set while the control bridge's inline copy had none of it, so * `spawn_agent`/`create_agent_session` could bind another user's private * agent, could not address `__shared:`, and ignored the caller's own * shadowing copy. A security rule with two implementations has one that is * wrong; this is now the only one. * * `getCallerOwnerKey` is awaited lazily — only when a user-scope package * agent is actually in play — and must resolve to the caller's owner key * (`provider\u0001subject`) or null. Fail closed: null means no private * agents match. */ export declare function resolveAgentDefinitionForCaller(opts: { agentName: string; userAgents?: any[]; systemAgents?: any[]; getCallerOwnerKey: () => Promise; }): Promise; /** Legacy activity compatibility for frozen orchestrations. Not a spawn_agent selector. */ export declare function resolveAgentDefinitionForRequiredToolForCaller(opts: { requiredTool: string; userAgents?: any[]; systemAgents?: any[]; getCallerOwnerKey: () => Promise; }): Promise; export { CANVAS_ARTIFACT_FILENAME, canvasArtifactFilename } from "./canvas-support.js"; /** @internal Exported for contract normalization tests. */ export declare function collectContractViolations(contractJson: Record | null, result: Record | null, missingResultCode?: string): Array>; import type { ContextTier, ReasoningEffort } from "./model-providers.js"; export declare function createSessionProxy(ctx: any, sessionId: string, affinityKey: string, config: SerializableSessionConfig, routingContract?: ActivityRoutingContract): { runTurn(prompt: string, bootstrap?: boolean, turnIndex?: number, turnMeta?: { parentSessionId?: string; nestingLevel?: number; requiredTool?: string; cycleOrigin?: "cron" | "cron_at"; retryCount?: number; clientMessageIds?: string[]; sender?: unknown; snapshot?: { expectedVersion?: number; turnKey: string; }; attachments?: Array<{ filename: string; contentType: string; sizeBytes: number; }>; transcriptEpoch?: number; epochStart?: boolean; stashedPrompts?: string[]; }): any; dehydrate(reason: string, eventData?: Record): any; hydrate(): any; needsHydration(): any; destroy(): any; checkpoint(): any; /** * Stop-turn fast-path interrupt: lands on the worker owning the warm * session and aborts the in-flight turn CONCURRENTLY with the still * running `runTurn` activity (requires stable workerNodeId + a free * worker slot; otherwise the dropped-future backstop still stops it). */ abortTurn(reason: string, expectedTurnIndex?: number): any; }; export declare function buildRunTurnConfig(inputConfig: SerializableSessionConfig, hostname: string, fallbackAgentIdentity?: string): SerializableSessionConfig; /** * Derive the app-assigned CRAWLER role from the bound agent definition. * * The crawler role is a property of the AGENT, not of a session: it is resolved * from the worker's static, loaded agent definitions every turn by matching the * session's resolved identity (agentIdentity / boundAgentName) against each * agent's CANONICAL identifier (id / name). Because the agent list is static * worker configuration, this is deterministic and replay-safe. * * Deriving it here (rather than trusting a persisted `isCrawler` / legacy * `isHarvester`) means the role can NEVER be inherited from a parent session or * smuggled in via a stale serialized config — a child only becomes a crawler if * its OWN bound agent declares `crawler: true` (or legacy `harvester: true`). * System agents (e.g. facts-manager) that should be crawler-capable get the * tools through the SessionManager gating, not here. * * SECURITY (P5 review BLOCKER#2): `title` is display metadata, NOT an * authorization key — matching on it would let a non-crawler whose title * normalizes to a crawler's identity receive the privileged crawl queue * (`facts_read_uncrawled` / `facts_set_crawled`, which read facts across ALL * scopes). We match only `id` / `name`, and we FAIL CLOSED on ambiguity: when * more than one loaded agent resolves to the same normalized identity, the * privileged role is granted only if EVERY one declares the crawler role. */ export declare function resolveCrawlerRole(identity: string | undefined, boundAgentName: string | undefined, userAgents?: Array<{ name?: string; id?: string; title?: string; crawler?: boolean; harvester?: boolean; }>, systemAgents?: Array<{ name?: string; id?: string; title?: string; crawler?: boolean; harvester?: boolean; }>): boolean; /** * Backfill a session's bound agent from the CMS catalog row. * * WHY THIS EXISTS: a top-level session's creation config lives in an * IN-MEMORY map on the API server that created it (`client.ts` * `sessionConfigs`). The orchestration is started lazily by whichever server * process handles the FIRST MESSAGE — and with more than one portal replica * behind a load balancer, that is routinely a different process. The lookup * misses, and the orchestration input is started with an empty config: no * `boundAgentName`, no model, nothing. The model already self-heals from the * catalog row (catalog-authoritative adoption in runTurn) and so does * `agentIdentity` — but the PROMPT layer and per-agent MCP grants key off * `boundAgentName`, so an API-created agent session ran with its agent's * title and tools-ish surface but NONE of its instructions. Measured on a * live fleet 2026-08-31: every MCP-created agent session composed only the * base + app-default layers. * * The CMS row's `agentId` is written by createSessionForAgent at create time * and is authoritative, exactly like the model. Backfill from it, guarded: * * - only when the input carried no boundAgentName (never override); * - only when the id matches a loaded USER agent by canonical name/id — * a system agent must never be backfilled into the app-agent layering, * which would hand it the app default prompt it deliberately does not * get (and service identities like regen-distiller are not user agents, * so they fall out here too); * - never when the input explicitly declared a non-app prompt layering. * * Exact-name result: the prompt lookup is keyed by the agent's exact name, * so the matched agent's own `name` is returned, not the raw row value. * * @internal exported for tests */ export declare function resolveBoundAgentBackfill(runConfig: SerializableSessionConfig, catalogAgentId: string | null | undefined, userAgents?: Array<{ name?: string; id?: string; }>): string | undefined; /** @deprecated Use `resolveCrawlerRole`; retained for compatibility. */ export declare const resolveHarvesterRole: typeof resolveCrawlerRole; /** @internal Child model options shared by inline and activity spawn paths. */ export declare function childModelCreationOptions(config: SerializableSessionConfig): { model: string | undefined; reasoningEffort: ReasoningEffort | null | undefined; contextTier: ContextTier | null | undefined; childContract: Record | undefined; }; /** @internal Initial turn options shared by every named-agent creation path. */ export declare function bootstrapTurnOptions(requiredTool?: string): { requiredTool?: string | undefined; bootstrap: true; }; export declare function createSessionManagerProxy(ctx: any, routingContract?: ActivityRoutingContract, options?: { childResultProvenance?: boolean; }): { listModels(): any; summarizeSession(sessionId: string): any; /** Spawn a child session via the PilotSwarmClient SDK. Returns the generated child session ID. */ spawnChildSession(parentSessionId: string, config: any, task: string, nestingLevel?: number, isSystem?: boolean, title?: string, agentId?: string, splash?: string, titleIsExplicit?: boolean, requiredTool?: string): any; /** * Resolve a loaded agent config by name. Returns null if not found. * * `callerSessionId` comes from the orchestration INSTANCE, never from the * model: it is what lets the activity refuse to hand a private package's * agent to somebody else's session. Threading it here rather than through * the orchestration generator keeps the yield sequence byte-identical, so * this is not an orchestration version change. */ resolveAgentConfig(agentName: string, callerSessionId?: string, binding?: { packageId?: string; source?: "deployment"; }): any; resolveAgentForRequiredTool(requiredTool: string, callerSessionId?: string): any; /** Send a message to a session via the PilotSwarmClient SDK. */ sendToSession(sessionId: string, message: string): any; /** Send a raw command (JSON) directly to a session's event queue. */ sendCommandToSession(sessionId: string, command: any): any; /** Get the status of a session via the PilotSwarmClient SDK. */ getSessionStatus(sessionId: string): any; /** Get orchestration runtime stats for a session. */ getOrchestrationStats(sessionId: string): any; /** List all sessions via the PilotSwarmClient SDK. */ listSessions(filters?: { includeSystem?: boolean; ownerQuery?: string; ownerKind?: string; includeTimestamps?: boolean; }): any; /** List direct child sessions of a session. */ listChildSessions(parentSessionId: string): any; /** @deprecated Send a child_updates event to a parent orchestration. Use sendToSession instead. */ notifyParent(parentOrchId: string, childOrchId: string, childSessionId: string, update: any): any; /** Get all descendant session IDs of a session (children, grandchildren, etc.). */ getDescendantSessionIds(sessionId: string): any; /** Cancel a session's orchestration (terminates immediately). */ cancelSession(sessionId: string, reason?: string): any; /** Cancel a session's orchestration and delete it from CMS. */ deleteSession(sessionId: string, reason?: string): any; /** Update a session's CMS state (e.g. "rejected" for policy violations). */ updateCmsState(sessionId: string, state: string, lastError?: string | null, waitReason?: string | null): any; /** Persist this session's model metadata in CMS. */ updateSessionModel(sessionId: string, model: string, reasoningEffort?: string | null, contextTier?: string | null, source?: string | null): any; /** Get the worker's authoritative session policy + allowed agent names. */ getWorkerSessionPolicy(): any; /** Load curated skills and open asks from the knowledge pipeline. */ loadKnowledgeIndex(cap?: number): any; /** Record CMS lifecycle events from the orchestration (waits, spawns, cron, commands). */ recordSessionEvent(sessionId: string, events: { eventType: string; data: unknown; }[]): any; /** Compute the next wall-clock cron fire in an activity so tzdata-dependent results are recorded in history. */ computeCronAtNextFire(schedule: CronAtSchedule, afterUtcMs: number, lastOccurrenceKey?: string): any; /** ARCHIVE stage: transcript slice → attempt-scoped artifact. Idempotent per attempt. */ runRegenArchive(sessionId: string, epoch: number, attemptId: string): any; /** DISTILL (deterministic): closure package in-activity → ResumePackage artifact + bootstrap. */ runRegenDistill(sessionId: string, epoch: number, attemptId: string, opts?: { handoff?: string; instructions?: string; sessionModel?: string; distillerModel?: string; archiveArtifactId?: string; }): any; /** Post-flip boundary: epoch_committed event + transcript_epoch + regen_count, one CMS transaction. */ commitEpochBoundary(sessionId: string, commit: Record): any; /** Proven rebirth: session.regenerated event + last_regen_stats. */ recordRegenerated(sessionId: string, payload: Record): any; /** Spawn the regen-distiller service session under the tree root (idempotent per attempt). */ runRegenSpawnDistiller(sessionId: string, epoch: number, attemptId: string, opts?: { archiveArtifactId?: string; archiveChunkIds?: string[]; handoff?: string; instructions?: string; distillerModel?: string; distillerReasoningEffort?: string; distillerContextTier?: string; }): any; /** Poll the distiller service session: running | completed (with response) | failed. */ runRegenCheckDistiller(distillerSessionId: string): any; /** Parse/validate the distiller's final message into the package (+dumps); deterministic fallback on junk. */ runRegenCollectDistiller(sessionId: string, epoch: number, attemptId: string, distillerSessionId: string, opts?: { archiveArtifactId?: string; archiveChunkIds?: string[]; handoff?: string; instructions?: string; distillerModel?: string; distillerReasoningEffort?: string; distillerContextTier?: string; }): any; /** Best-effort cancel of a timed-out/failed distiller service session. */ runRegenCancelDistiller(distillerSessionId: string): any; }; export declare function registerActivities(runtime: any, sessionManager: SessionManager, sessionStore: SessionStateStore | null, githubToken?: string, catalog?: SessionCatalog | null, provider?: any, storeUrl?: string, cmsSchema?: string, clientConfig?: { storageConfig?: StorageConfig; duroxideSchema?: string; factsSchema?: string; cmsFactsDatabaseUrl?: string; enhancedFactsDatabaseUrl?: string; factsProvider?: "pg" | "horizon"; enhancedFactsSchema?: string; useManagedIdentity?: boolean; aadDbUser?: string; }, /** Loaded system agents — used by resolveAgentConfig activity. */ systemAgents?: AgentConfig[], /** Worker-level session policy — used by getWorkerSessionPolicy activity. */ workerSessionPolicy?: import("./types.js").SessionPolicy | null, /** Names of loaded non-system agents — used by getWorkerSessionPolicy activity. */ workerAllowedAgentNames?: string[], /** Loaded user-creatable agents — used by resolveAgentConfig activity. */ userAgents?: Array<{ name: string; description?: string; prompt: string; tools?: string[] | null; namespace?: string; id?: string; title?: string; initialPrompt?: string; splash?: string; splashMobile?: string; parent?: string; crawler?: boolean; harvester?: boolean; promptLayerKind?: "app-agent" | "app-system-agent" | "pilotswarm-system-agent"; }>, /** Fact store instance for the loadKnowledgeIndex activity. */ factStore?: import("./facts-store.js").FactStore | null, /** Worker node identifier — written on every CMS event for worker tracking. */ workerNodeId?: string, /** Artifact store — resolves image attachment refs to bytes inside runTurn. */ artifactStore?: ArtifactStore | null): void; //# sourceMappingURL=session-proxy.d.ts.map