import { type Logger } from "./log.js"; import type { WorkspaceScanMeasurement } from "./file-candidates.js"; import { type RuntimeSkillProviderFactory } from "./runtime-skills.js"; import { type PersistentSessionExecution, type PreparedPersistentTurn, type RunReportingClient } from "./run-dispatcher.js"; import type { CourseRuntime, RunEvent, RunEventReceipt, RunFileCandidate, RunFileRecord, RunStartPayload } from "./types.js"; import type { StartupTimer } from "./startup-timings.js"; /** Task-scoped CourseRuns route each run to its own native thread (course-agent-session-scope.md). */ export declare const NATIVE_SESSION_KEY_CAPABILITY = "native_session_key_v1"; export declare function workspaceDurabilityCapabilities(): string[]; export interface AgentServiceSandboxOptions { wsUrl: string; sandboxId: string; sandboxToken: string; runtimes: Map; daemonVersion: string; deepseekTuiVersion?: string; log?: Logger; random?: () => number; sleep?: (ms: number) => Promise; /** Test/provider injection; production uses the bounded HTTP Runtime Skill Provider. */ prepareSkillProvider?: RuntimeSkillProviderFactory; /** Cold-start stage timer; its payload is sent once with the first `sandbox.ready`. */ startupTimer?: StartupTimer; } /** * Long-running daemon client for one user-scoped managed sandbox (ADR-015). * * 一个 sandbox 内可承载多个 runtime session(CourseRun Session)。server 通过显式命令帧 * (session.open/activate/close、turn.start/cancel、sandbox.drain/shutdown/sync)驱动; * daemon 同时只允许一个 active session,且整个 sandbox 同时只有一个 active turn。 */ export declare class AgentServiceSandboxClient implements RunReportingClient, PersistentSessionExecution { private readonly options; private readonly log; private readonly random; private readonly sleep; private readonly prepareSkillProvider; private readonly state; private readonly dispatcher; /** agent_run_id → TURN scope(session/attempt/activation),事件与文件帧路由用。 */ private readonly turnScopes; /** activation-scoped 模型短凭据;只保存在内存中,绝不进入 state.json。 */ private readonly activationContexts; private readonly activationCleanupTasks; private readonly pendingAcks; private readonly pendingFileReports; private readonly inflightCommands; private socket; private sandboxGeneration; private connectionEpoch; private currentLifecycleOperationId; private outboundSeq; private inboundSeq; private activeSessionId; /** 全局串行下当前正在执行 turn 的 session(persistNativeSession 路由用)。 */ private currentTurnSessionId; /** Native session key of the current turn; persistNativeSession writes only this slot. */ private currentTurnNativeKey; private heartbeatMs; private staleMs; /** Server-advertised bounded pipeline; legacy peers remain stop-and-wait. */ private maxUnackedEvents; private stopped; private permanentFailure; private lifecycleChain; private runtimeLogPolicy; private runtimeLogHandshakeReady; private runtimeLogWindowStartedAt; private runtimeLogWindowEvents; private runtimeLogWindowBytes; private runtimeLogSuppressedEvents; private runtimeLogSuppressedBytes; private runtimeLogSendChain; private workspaceFileReadInFlight; private readonly removeOperationalLogSink; constructor(options: AgentServiceSandboxOptions); prepareTurn(payload: RunStartPayload): PreparedPersistentTurn; persistNativeSession(nativeSessionId: string): void; finishTurn(payload: RunStartPayload): Promise; private completePendingActivationCleanup; private runPendingActivationCleanup; private recoverPendingActivationCleanups; run(): Promise; stop(): void; stopGracefully(): Promise; private drainWorkspace; postEvent(agentRunId: string, event: RunEvent): Promise; postFiles(agentRunId: string, files: RunFileCandidate[], truncated?: boolean, signal?: AbortSignal): Promise; recordWorkspaceScanMeasurement(agentRunId: string, measurement: WorkspaceScanMeasurement): Promise; private connectOnce; private handleHello; /** * The server is the durable authority after a reconnect. Reconcile only the * fields that are explicitly present so an older server cannot erase local * recovery state during a rolling upgrade. */ private reconcileHelloState; private forwardOperationalLog; private queueRuntimeLog; private assertServerFrame; private handleServerFrame; /** sandbox.sync 只做对账:重放 spool、关闭待关 session、应用 shutdown。 */ private applySync; private handleSessionOpen; private handleSessionActivate; private handleTurnStart; private handleTurnCancel; /** * 幂等关闭一个 runtime session:终止其 runtime 子进程并清空 session-local state。 * Durable Workspace 由独立身份拥有,关闭执行上下文不会删除学员文件。 */ private closeSession; private reconcileInterruptedCommand; private turnContextRevision; private validTurnPayload; private scheduleLifecycle; private currentLifecycleFence; private isCurrentLifecycleFence; private isCurrentDrainFence; private runIdsForSession; private deactivateSession; private terminateSessionWriters; private sameTurnScope; private matchesTurnScope; private assertTurnScope; private ackEventOrFile; private discardSpooledTurnEvents; private resolvePendingEventAck; private resolvePendingEventAcksForSession; private rejectPendingFilesForSession; private replaySpool; private sendHeartbeat; private sendCommandAck; private handleWorkspaceFilesList; private handleWorkspaceFileRead; private sendWorkspaceFileResult; private sendControlFrame; private sendSessionFrame; private sendFrame; private sendBinaryFrame; private nextOutboundSeq; private waitForEventCapacity; private waitForPendingEventAcks; private spoolFrameCount; private spoolBytes; private enforceSpoolLimit; private rejectPending; private rejectPendingFiles; private persist; }