import type { query } from '@anthropic-ai/claude-agent-sdk'; import type { AgentRunner, OrgToolDef } from './agent-runner.js'; import type { OrgBus } from './bus.js'; import type { RoleFence } from './fence.js'; import { Mailbox } from './mailbox.js'; import type { Decision, PolicyEngine } from './policy.js'; import type { OrgDef, OrgRole } from './types.js'; /** Resolve the model string for a role: explicit adapter_config.model wins; * otherwise fall back to the vendor/runtime default. */ export declare function resolveModel(role: OrgRole, runtime?: string, vendor?: string): string; export type DeliverFn = (from: string, to: string, subject: string, body: string) => Promise; /** The SDK's `canUseTool` gate, composed from two independent layers: PolicyEngine's * static config checks (deny/allow lists, path scoping, git level, web allowlist, * budget), then — only for calls policy would allow — the human-approval guardrail * (`beforeTool`, i.e. daemon.checkApproval) for whatever action names it treats as * sensitive (Bash/WebFetch/WebSearch/org_complete). Exported standalone so this * composition is unit-testable without spinning up a real SDK session: previously * `beforeTool` was wired into SessionOpts but never actually called from here, so * none of those sensitive actions ever paused for a human. */ export declare function gatedCanUseTool(policy: PolicyEngine, beforeTool: SessionOpts['beforeTool'], roleId: string, fence?: RoleFence, /** Optional hook invoked whenever this gate denies a tool call — wired to * daemon.recordDecision() so denials show up in `org decisions` traces. */ onDeny?: (toolName: string, input: Record, decision: Extract) => void, /** ORG-9: reports whether this role has a pending (unresolved) decision gate. * org_gate is documented as creating a "hard-blocking" checkpoint, but until * this was wired in nothing actually stopped tool use while a gate sat * pending — only approvals did that. When set and true, ALL tool calls are * denied (not just the sensitive subset approvals gate) until the gate is * resolved, matching the "hard-blocking" description. */ hasPendingGate?: () => boolean): (toolName: string, input: Record) => Promise; export interface SessionOpts { org: string; role: OrgRole; bus: OrgBus; policy: PolicyEngine; mailbox: Mailbox; cwd: string; /** Org state directory (`.monomind/orgs/`). Used to pass * MONOMIND_ORG_DIR to runners that persist per-role state (VercelAgentRunner * stores session history under `/sessions/`). */ orgDir?: string; /** Project root for resolving `adapter_config.provider` named providers * (config search must start at the project root even when the role's * workspace cwd is an isolated scratch dir). Defaults to opts.cwd. */ orgRoot?: string; deliver: DeliverFn; askHuman?: (role: string, question: string) => Promise; /** Coordinator-only: records the run's outcome (daemon persists it to run history). */ onComplete?: (role: string, outcome: 'achieved' | 'partial' | 'failed', summary: string) => void; /** Search the org's accumulated cross-run memory (memory_namespace). */ recall?: (role: string, query: string) => Promise; /** Write a memory deliberately: scope 'org' (shared, default) or 'agent' (private to this role). */ remember?: (role: string, content: string, scope: 'org' | 'agent') => Promise; /** Persist extracted entities/relations/rules into the org's knowledge graph. */ learn?: (role: string, payload: { nodes?: { name: string; type?: string; description?: string; }[]; edges?: { source: string; target: string; relation: string; description?: string; }[]; rules?: { rule: string; context?: string; }[]; }) => Promise; /** Top existing KG entity names - injected into the coordinator prompt so * extraction reuses canonical names instead of minting near-duplicates. */ glossary?: string[]; /** Search the user's Second Brain (project documents + personal global brain). */ searchKnowledge?: (role: string, query: string) => Promise; /** Guardrail beforeTool hook: checks if a tool call requires approval before execution. */ beforeTool?: (role: string, toolName: string) => Promise; /** Called whenever gatedCanUseTool denies a tool call — wired to daemon.recordDecision() * so those denials show up in `org decisions` traces. */ onDecision?: (role: string, toolName: string, message: string) => void; /** ORG-9: reports whether this role currently has a pending decision gate — * wired to daemon.listGates(org, 'pending'). When true, gatedCanUseTool * denies every tool call until the gate is resolved. */ hasPendingGate?: () => boolean; def?: OrgDef; maxTurns?: number; queryFn?: typeof query; /** Provider-agnostic runner. Takes precedence over queryFn. When unset, * session.ts builds a ClaudeAgentRunner from queryFn (or the default), * preserving the previous Claude-only behaviour exactly. */ runner?: AgentRunner; /** ID of the last message received by this agent (for threading responses). Function to ensure live reading. */ lastMessageId?: () => string | undefined; /** Callback for each output line — feeds ScrollbackBuffer. */ onOutput?: (line: string) => void; /** Callback when the SDK assigns a session ID — enables checkpoint resume (P2-13). */ onSessionId?: (id: string) => void; /** SDK session ID persisted in a checkpoint from a prior run — when set, the * first query() call resumes it instead of starting a fresh conversation * (P2-13: this is what actually makes checkpoint resume resume). */ resumeSessionId?: string; /** Circuit breaker config for this role. */ circuitBreaker?: { threshold: number; state: { failures: number; tripped: boolean; }; }; /** Called when the coordinator's context window is exhausted. */ onContextLimit?: () => void; /** MonoFence guardrail instance for this role. */ fence?: RoleFence; /** Decision gate: creates a hard-blocking human-approval checkpoint. */ onGate?: (role: string, name: string, description: string) => Promise; /** Task DAG: create a task with dependencies. */ createTask?: (role: string, title: string, assignee: string, deps: string[]) => string; /** Task DAG: mark a task as completed. */ completeTask?: (role: string, taskId: string, result?: string) => string; /** Task DAG: list all tasks. */ listTasks?: () => string; splitTask?: (role: string, parentId: string, children: { title: string; assignee: string; }[]) => string; mergeTask?: (role: string, sourceId: string, targetId: string) => string; cancelTask?: (role: string, taskId: string, reason?: string) => string; /** Task DAG: mark a 'running' task as waiting on a real-world time (not a * dependency) — e.g. a scheduled soak test, a CI run, a human-set * deadline. The idle watchdog skips nudging while any task is actively * blocked, and auto-resumes (re-dispatches) it once the time passes. */ blockTask?: (role: string, taskId: string, untilIso: string, reason?: string) => string; planGraph?: (role: string, specs: { name: string; title: string; assignee: string; after?: string[]; }[]) => string; } /** Role briefing given to each agent session (SDK systemPrompt option). */ export declare function buildRolePrompt(role: OrgRole, def: Pick, roster: string[], glossary?: string[]): string; /** * Runs a role for the life of the org, transparently restarting the * underlying SDK session whenever it ends on its own (`maxTurns` reached) * while the mailbox is still open. `maxTurns` bounds a single SDK query() * call's TOTAL turns, not "turns per incoming message" - since one query() * call stays open across every mailbox message for as long as the mailbox * itself stays open, without a restart the role would go permanently silent * (no crash, no alert) once its lifetime turn count crossed the limit, while * deliver() kept queuing new messages into a mailbox nobody was reading. */ export declare function runAgentSession(opts: SessionOpts): Promise; /** Build the org tool surface as platform-agnostic OrgToolDef[]. The handlers * close over sessionOpts callbacks (deliver, recall, remember, …) — same * wiring as the previous inline createSdkMcpServer block, just decoupled from * the Claude SDK's tool() shape so any AgentRunner can host them. * * Behaviour is identical to the old inline definitions: conditional tools are * gated on their callback being present, org_send/ask_human are always added. */ export declare function buildOrgTools(opts: SessionOpts): OrgToolDef[]; //# sourceMappingURL=session.d.ts.map