Skip to main content

SessionConfig

You can configure many behaviors with the SessionConfig class. Use it with Copilot::run(prompt: '...', config: $config) or Copilot::start(function (CopilotSession $session) { ... }, config: $config). If you only need simple options like a model ID, you can pass an array instead of using SessionConfig: Copilot::run(prompt: '...', config: ['model' => 'auto']).

Discovery roots

skillDirectories, agentDirectories, hookDirectories, and instructionDirectories are discovery-only roots for skills, custom agents, file hooks, and custom instructions. They do not grant the agent general file access. To add regular file access locations, use additionalDirectories. You can set discovery roots whether or not enableConfigDiscovery is enabled. The SDK resolves relative paths once, against the effective workingDirectory at the time you set them. The roots do not move if the working directory changes later. Omitting a key or passing null leaves the default discovery sources unchanged. Passing [] clears only the roots the SDK set explicitly. Per-source disable settings and Managed Settings for skills, agents, hooks, and instructions still apply. When resuming a session, use ResumeSessionConfig. It is almost the same as SessionConfig, but has small differences. In ResumeSessionConfig, specify only the options you want to change. All other settings are inherited from the original session start. The SDK sends the same session options in both the create and resume RPC payloads. This includes BYOK providers and models, memory, enableMcpApps, interactiveUser, enableGitHubCacheStore, discovery roots, and handlers such as onMcpAuthRequest, onExitPlanModeRequest, and onAutoModeSwitchRequest. When resuming, pass them in ResumeSessionConfig or in an array with the same keys. Closures and provider objects are not persisted, so supply them again on every resume.

Canvas providers

Canvas support is experimental.
Declare canvases with canvases and handle open and action requests with a canvasHandler. The runtime calls your handler over reverse RPC when the agent opens a canvas or invokes one of its actions. Set requestCanvasRenderer: true to opt in as a renderer, so the runtime exposes canvas agent tools to the model for this connection. It is off by default so SDK callers that cannot display canvases stay clean.
Related options:
  • requestExtensions: true opts in to the extension surface. The runtime then wires extension management tools into sessions on this connection. Off by default.
  • extensionInfo: new ExtensionInfo(source: 'github-app', name: 'my-extension') sets a stable extension ID for canvas providers on this connection. The runtime uses ${source}:${name} instead of the per-connection ID. You can also pass an array.
When resuming, pass canvases and canvasHandler again. The canvasHandler runs only inside the PHP process. The SDK sends only the declaration metadata in the RPC payload. ResumeSessionConfig also accepts openCanvases, a snapshot of the canvases that were open when the session stopped. The runtime uses it to rehydrate canvas state, so you do not need to reopen them. Get the current open canvases with $session->openCanvases(). The SDK keeps this list in sync with session.canvas.opened and session.canvas.closed events.

Session filesystem providers

Skill and filesystem callbacks

Use skillProvider to load skills from an application-owned source. The callbacks belong to that session and are not serialized to the Copilot runtime. Cloud sessions do not support custom skill providers.
SkillProviderCallOptions::$signal exposes the callback’s cancellation token. Cancellation is cooperative. Your callbacks should observe the signal and cancel pending work themselves. You can implement Revolution\Copilot\Contracts\SkillProvider instead of using the callback array. sessionFsProvider uses the same session-scoped configuration. The text callbacks are readFile(path) and writeFile(path, content, mode). To support binary files, provide both readFileBytes(path) and writeFileBytes(path, bytes, mode), or implement SessionFsBinaryProvider. These callbacks receive and return the original bytes. The SDK handles base64 encoding on the JSON-RPC wire. Keep filesystem access scoped to the paths your application intends to expose.

Delegate all session state with sessionFs

Set the client option sessionFs (alias session_fs) to move the whole Copilot CLI session state, including session-state files and the per-session SQLite database, into your own storage. When you set it, every session config must provide a createSessionFsProvider factory. The SDK calls the factory for both createSession() and resumeSession(), after the session ID is known and before the request is sent to the runtime.
With the Copilot facade, set session_fs in config/copilot.php. initialCwd, sessionStatePath, and conventions (posix or windows) are required. Missing fields or an invalid conventions value throw an InvalidArgumentException. createSessionFsProvider is a Closure. It also works with arrays, fromArray(), and toArray() on SessionConfig and ResumeSessionConfig. The provider it returns can be an object or an array of callables. Each optional capability has its own interface: If the provider does not meet the declared capabilities, the SDK throws an InvalidArgumentException. Calling an operation the provider does not support returns an UNKNOWN error. Providers signal failures by throwing. An exception whose code is ENOENT (or errno 2) becomes ENOENT. Anything else becomes UNKNOWN. Throw SessionFsSqliteTransactionFailure from transaction() to report an errorClass (busyOrLocked, fatal, or postCommitAmbiguous). Without the client sessionFs option, the SDK never calls createSessionFsProvider, and the existing sessionFsProvider (readFile and writeFile) keeps working.

Empty mode for multi-tenant apps

Set the client mode to empty to disable, by default, features that depend on the Copilot CLI host environment or on cross-session state. The default is copilot-cli, which keeps the existing behavior. In empty mode, you must set one persistence target: base_directory, session_fs, or an external server url.
Every session in empty mode must set availableTools. Use ToolSet to build source-qualified tool filters (builtin:, custom:, mcp:). BuiltInTools::Isolated allows only built-in tools confined to a single session, with no host filesystem, environment, network, or cross-session access.
Tool names must match /^[a-zA-Z0-9_-]+$/ or be the wildcard *. Otherwise ToolSet throws an InvalidArgumentException. Empty mode applies safe defaults to session telemetry, persistent MCP OAuth token storage, embedding retrieval and cache, instruction discovery, file hooks, host git operations, the session store, the GitHub cache store, skills, memory, and experimental mode. Session options you set explicitly take precedence over these defaults. systemMessage in replace mode is used as is. Other modes remove the environment_context section. The SDK also sets COPILOT_DISABLE_KEYTAR=1 for the CLI process.

GitHub cache store

Set enableGitHubCacheStore: true to request the read-only GitHub cache store. The CLI registers the github_sql tool only when its GITHUB_CACHE_STORE feature flag is enabled.
For cloud execution, see Cloud Sessions; for plugin directories, see Plugin Directories.
For the latest updates, see the GitHub repository.
Last modified on October 19, 2026