TheDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/aipoch/open-science/llms.txt
Use this file to discover all available pages before exploring further.
AcpRuntime class in src/main/acp/runtime.ts is the heart of Open Science. It owns the agent subprocess, manages one or more concurrent ACP sessions, streams typed events to the renderer as the agent works, intercepts tool-call permission requests, and coordinates the artifact and notebook MCP servers injected into every session. Everything the researcher sees in the chat transcript — messages, tool calls, plans, permission prompts, generated files — originates as an AcpRuntimeEvent emitted by this class.
Connection Lifecycle
connect()
Spawns the agent subprocess via
spawnClaudeAgentAcp() and wraps its stdin/stdout in an acp.ndJsonStream. Sends an agent.initialize request advertising client capabilities (filesystem read/write, session config options, plans). Sets status to connecting, then connected on success or error on failure. A connectInFlight guard prevents duplicate concurrent connect calls.createSession()
Calls
ensureConnected(), then builds a protocol session via connection.agent.buildSession(). At creation time it injects both MCP servers — the artifact server scoped to a freshly generated artifactSessionId, and the notebook server scoped to a notebookSessionId — using createMcpServers(). Also appends artifact and notebook guidance to the session’s system prompt via _meta.systemPrompt.append without touching user prompts.sendPrompt()
Activates a new artifact run with
activateArtifactRun(), which writes a current-run.json handoff file so the artifact MCP server knows which runId to attribute writes to. Streams updates via activeSession.nextUpdate() in a loop, converting each SessionNotification to a typed AcpRuntimeEvent. On stop, calls emitArtifactRunEvent() to publish any pending artifact files before emitting the final stop event.ACP Connection States
Thestatus field of AcpStateSnapshot is typed as AcpConnectionStatus (defined in src/shared/acp.ts). The renderer uses this to drive connection UI and gate prompt input.
| State | Description |
|---|---|
idle | Runtime is initialized but no agent subprocess has been started yet. |
connecting | Subprocess is being spawned and the agent.initialize handshake is in progress. |
connected | The protocol connection is live and the runtime is ready to create sessions and accept prompts. |
error | The connection attempt failed or the subprocess exited unexpectedly. AcpStateSnapshot.error carries the message. |
closed | The connection was cleanly torn down by a disconnect() call or by the remote end closing the stream. |
Runtime Event Kinds
Every activity the agent performs — or that the runtime itself generates — is published as anAcpRuntimeEvent with a kind field typed as AcpRuntimeEventKind. The renderer maps each kind to a distinct visual treatment in the transcript.
| Kind | Description |
|---|---|
system | Internal runtime notifications: agent initialized, session created/resumed/deleted, process stderr output. Not produced by the agent model itself. |
message | A text message from the agent (role: 'assistant') or the researcher (role: 'user'). |
thought | The agent’s internal reasoning text, shown collapsed in the transcript. |
tool | A tool call made by the agent, carrying toolKind, toolCallId, toolContent, and toolLocations for typed activity rendering. |
plan | A structured plan the agent emits before beginning multi-step work. |
permission | A permission request surfaced by the AcpPermissionBroker; the renderer renders an approval UI until the researcher responds. |
artifact | Emitted just before stop when the run produced files. Carries runId, artifactSessionId, artifactClaimId, and the list of ArtifactFile objects so the renderer can attach them to the finishing message. |
error | A prompt failure, connection error, or artifact cleanup error. |
stop | The final event of a prompt turn, carrying the stopReason and raw PromptResponse. |
raw | A pass-through for low-level protocol notifications that don’t map to a typed kind. |
The in-memory event log is bounded to the most recent 500 events (
MAX_EVENTS = 500). Older events are evicted as new ones arrive, keeping the renderer payload from growing unboundedly across long sessions.State Snapshot
getSnapshot() returns an AcpStateSnapshot — the complete, serializable view of runtime state that is broadcast to the renderer on every meaningful change.
| Field | Type | Description |
|---|---|---|
status | AcpConnectionStatus | Current connection state (idle, connecting, connected, error, closed). |
cwd | string | The resolved working directory of the most recently active session. |
sessionId | string? | The session most recently targeted by a prompt or session switch. |
sessionIds | string[] | All session IDs currently tracked by the runtime. |
error | string? | Human-readable error message when status is error. |
events | AcpRuntimeEvent[] | Bounded event log (last 500 events). |
pendingPermissions | AcpPermissionRequest[] | All permission requests awaiting a renderer response. |
promptInFlight | boolean | true when any session has a prompt in progress. |
promptInFlightSessionIds | string[] | IDs of sessions that currently have a prompt in flight. |
Permission Broker
TheAcpPermissionBroker (in src/main/acp/permission-broker.ts) sits between the ACP protocol’s client.session.requestPermission handler and the renderer’s approval UI. When the agent requests permission for a higher-risk tool call, the broker:
- Generates a unique
requestIdand wraps the raw ACP permission request into anAcpPermissionRequest. - Stores the request in a
pendingRequestsmap and emits it as apermissionevent so the renderer renders an approval card. - Holds the underlying promise open until
respondToPermission()is called from the renderer with anAcpPermissionResponse. - Resolves the promise with
outcome: 'selected'(approved) oroutcome: 'cancelled'(denied/cancelled).
disconnect(), cancelAll() cancels every pending request so the agent subprocess is never left waiting for a response that will never arrive. cancelForSession() targets only one session’s pending permissions, used when a single session is deleted while others remain active.
Attachment Handling
When a prompt includes file attachments (images, text, data files),createPromptContent() converts each UploadedAttachment into an appropriate ACP ContentBlock type:
- Images (
image/*MIME type) — read from disk and embedded as base64{ type: 'image', data, mimeType, uri }blocks so vision-capable agents receive actual pixel data. - Small text and JSON files (up to
MAX_EMBEDDED_TEXT_UPLOAD_BYTES = 1 MiB) — embedded as{ type: 'resource', resource: { uri, mimeType, text } }blocks for direct reading. - Large or binary files — passed as
{ type: 'resource_link', uri, name, mimeType, size }so the agent can decide how to fetch or reference them without inflating the prompt payload.