func NewCore(opts CoreOptions) (*Core, error)
type CoreOptions struct {
// WorkRoot holds every session workspace: WorkRoot/<brain>/<session>.
WorkRoot string
// Workspace overrides the per-session directory (for example a machine
// executor whose sessions all share one directory, or a desktop app
// mapping a brain to a project folder). Tools are confined to it.
Workspace func(brain, sessionID string) string
// MaxSessions bounds active sessions across all attached brains;
// MaxSessionsPerBrain bounds one brain (defaults to MaxSessions). A full
// core answers session.assign with executor_busy (-32009, retryable).
MaxSessions int
MaxSessionsPerBrain int
// MaxMCPServersPerSession bounds session.assign.mcp_servers (default 4).
MaxMCPServersPerSession int
// BashTimeout applies when neither tool.call deadline_ms nor the bash
// timeout_ms is set (default 10 minutes).
BashTimeout time.Duration
// MaxOutputBytes caps each captured bash stream (default 1 MiB).
MaxOutputBytes int
// InlineResultBytes is the largest bash output returned inline (default
// 48 KiB, under the 64 KiB control frame). Larger output is uploaded as
// an artifact when UploadArtifacts is set, otherwise truncated.
InlineResultBytes int
// ComputerUse serves computer_observe and computer_action and advertises
// capabilities.computer_use (for example NewCuaDriver). Nil leaves
// computer use off: the harness then sends no computer_* tool.
ComputerUse ComputerUseBackend
// UploadArtifacts advertises the artifacts capability and offloads large
// bash results with Client.UploadArtifact. Only environment-scoped
// executors have an artifact store.
UploadArtifacts bool
// Env is set on every bash tool and process and cannot be overridden by
// a request (for example BMA_HOME).
Env map[string]string
// DenyEnv reports executor-private variables (credentials, state paths)
// that no bash tool, process or stdio MCP server may see: they are
// dropped from the inherited environment and a request setting one is
// rejected. NewCore rejects an Env entry it denies.
DenyEnv func(name string) bool
// RunAs, when set, is the OS identity every bash tool, process and stdio
// MCP server runs as, so a privileged executor (for example root) keeps
// its own credentials and state out of the workload's reach. HOME and
// USER in bash and process environments are the workload's. File tools
// (read/write/edit/glob/grep) run inside the executor and would bypass
// that boundary, so they are refused. Unix only.
RunAs *RunAs
// Launch runs before each bash tool command starts (tool.call and
// LocalToolRoute, so also ACPAgent's own tools), with the semantics of
// ProcessOptions.Launch: it may change the directory, argv and
// environment, or refuse the start; see LaunchFunc. File tools run inside
// the executor and do not call it (they stay within the session
// workspace). Nil starts commands as before.
Launch LaunchFunc
// FileAccess runs before every file tool (read, write, edit, glob, grep)
// of this machine: a tool.call and the tools of a LocalToolRoute (so also
// ACPAgent's). It gets the session, the tool, the operation (read or
// write) and the workspace-relative path, and refuses by returning an
// error: an *RPCError (NewReasonError) gives its data.reason as the
// refusal code, any other error permission_denied. A LocalToolRoute call
// is then not_forwarded with the code as Code, recorded like a result (the
// same call id is answered with it again); a tool.call fails with
// "<code>: <message>". Nothing is read or written when it refuses. A host
// uses it for read-only sessions, protected paths, revoked grants and
// stopped turns. The tools stay within the workspace with or without it.
// Nil allows every file tool call as before. See FileAccessRequest.
FileAccess FileAccessFunc
// ToolOutputDir, when set, holds the output files of the bash commands
// of a LocalToolRoute (so also ACPAgent's own tools):
// ToolOutputDir/<short hash of the session>/, created 0700 (owned by
// RunAs when set). Empty keeps them in .bma-bash/ under the turn's
// working directory. A host whose Launch sandboxes commands sets it to a
// directory outside every folder a session may write, so the executor
// writes nothing into the user's folders. The read tool of the session
// may read its own output files there. tool.call bash keeps its output
// in memory and does not use it.
ToolOutputDir string
// EndAfterToolCall marks sessions that carry exactly one tool call: the
// core ends them (session.ended "completed") after the result is
// delivered. BMA's durable selfhost queue assigns such sessions.
EndAfterToolCall func(SessionAssignParams) bool
OnLog func(LogEvent)
}