Copilot agents
What copilot-scuba bridges, its audited SDK prompt and event support, and the types and features it does not expose.
On this page
Native GitHub Copilot session adapter for Octostaff, with durable sessions, shared conversation projection, streamed replies, local and provider tools, and interactive permissions, user questions and session controls. Smart drain, in-flight steering and hosted GitHub login are not currently supported.
Requires Node 22.13 or newer (including node:sqlite). The dependency pins Copilot
SDK 1.0.14 and its bundled runtime 1.0.85 / protocol 3; arbitrary CLI overrides,
TCP and the experimental in-process runtime are not supported.
See Running a Copilot bot for configuration, credentials, durable state and embedding.
Prompt and event support (SDK 1.0.14)
This inventory covers the installed SDK's public entrypoints (index, client,
session, types, factory, canvas, extension, tools, request handlers and
filesystem providers), all 138 generated SessionEvent variants and their
payload declarations, and the generated RPC attachment/send/control surfaces.
It is an API/type and relevant send/disconnect implementation audit, not a claim
that every SDK feature was exercised against a live provider. Native runtime
1.0.85 / protocol 3 is pinned alongside it.
Public MessageOptions
| Field | Adapter treatment |
|---|---|
prompt | Shared BrokerPromptProjector renders ordered authors, mentions, supplied system-context text, text attachments and artifact/enclosure annotations. |
source | Always user. Mixed Octostaff authors stay attributed in the text; they are not promoted to SDK system or agent-${string} authority. |
attachments | Image bytes become named blob attachments. Text bytes are inlined with attachment delimiters. |
mode | Always enqueue; immediate steering is unsupported; new input queues for the next turn. |
agentMode | Always interactive; plan, autopilot and shell are not exposed. |
requestHeaders | Not exposed. Arbitrary per-turn provider headers are not part of Octostaff message content. |
displayPrompt | Not set: there is one projected prompt, rather than a second display-only representation. |
The four public attachment shapes are file, directory, selection and
blob. Only image blob delivery is implemented. Octostaff attachments do not
confer permission to read arbitrary native filesystem paths, so file.path,
directory.path, and selection filePath/range/text are not manufactured from
untrusted input. PNG, JPEG, WebP and GIF are accepted; the selected model must
itself support vision. PDFs, audio, video, other binary types and remote file
URLs are omitted with a content-free diagnosis. Legacy data URLs must have
matching MIME types, canonical base64, and valid UTF-8 for text, within a
cumulative 10 MiB limit. Image byte validity beyond base64 is the provider's
responsibility. Images are a separate ordered attachment list with numbered
markers in the text; the SDK does not offer arbitrary interleaved content blocks.
broker.prompt uses the shared schema (groupChat defaults true; artifacts are
opt-in with artifacts.enabled and artifacts.maxTotalBytes). Shared artifact
resolution enforces scope/hash/byte limits and never forwards signed transfer
URLs or headers. An undelivered artifact gets both the shared text annotation
and an omission diagnosis; the annotation's generic reference to artifact tools
does not mean this package hosts those tools yet. Enclosures use the same
policy in the conversation and projector: only text-like user-input enclosures,
up to 1 MiB per turn; diagnostic/agent/system enclosures are ignored and binary
user enclosures are reported as dropped. Internal file/artifact provenance lets provider
decoding errors identify the originating message without changing the wire.
Peer reasoning/tool activity follows the shared projection policy.
The experimental generated RPC send also has prepend, billable,
requiredTool, responseFormat, traceparent, tracestate and wait, and
sendMessages provides batching. None is called/exposed by this adapter.
The RPC attachment union additionally has GitHub reference, commit, release,
actions-job, repository, file-diff, tree-comparison, URL, file and snippet forms,
plus extension-context attachments. These are not implemented: they require
native GitHub/extension resolution and have no authorized Octostaff input mapping.
Session events
The exhaustive disposition table names all 138
events and is checked by TypeScript against SessionEventType; a new SDK type
requires review. The runtime treatment is:
| Event(s) | Treatment |
|---|---|
assistant.message_start, assistant.message_delta, assistant.message | Stable message-ID text blocks; final snapshots append only a missing suffix and close once. Final-only replies and refusals are text. Divergent snapshots cannot replace already streamed text; the streamed version wins. |
assistant.reasoning_delta, assistant.reasoning | Stable reasoning-ID blocks with the same final/delta deduplication. |
assistant.tool_call_delta | Starts a dynamic tool when its name arrives. Partial JSON arguments are deliberately omitted: credential/media fields cannot be safely redacted fragment by fragment. Complete input comes from the final request/start event. |
assistant.message.toolRequests, tool.execution_start | One typed tool input per call ID. |
tool.execution_complete | Typed output or safe error for a known call; an orphan result remains an agent event, without inventing a tool name. |
assistant.usage | Native agent_event with supplied model/token/cache/reasoning/cost/timing fields after redaction. No fabricated counts or conversion of native cost into USD. |
session.title_changed | Shared title initializer; never overwrites an existing user/peer title. |
session.idle | Turn completion (autopilot intermediate idle is not terminal). An aborted idle is an interruption. |
session.error, session.shutdown, abort | Terminate the stream; shared HarnessBroker emits the safe error and closes the run. Raw provider messages/stacks are not exposed. |
user.message, pending_messages.modified, assistant.streaming_delta, assistant.turn_start, assistant.turn_end, assistant.idle | No transcript output: input echoes, queue/byte counters, or intermediate model-loop boundaries, not a completed Octostaff turn. |
Every event marked metadata in the table | Opaque agent_event preserving event name, ID, predecessor and agent ID, not the arbitrary payload. No interactive behavior is implied. |
| Unknown future events | Same metadata-only escape hatch, marked nonconforming for shared turn diagnosis. |
Subagent content carrying agentId or parentToolCallId stays metadata-only;
it is not rendered as the root assistant's reply. There is no child Octostaff
thread/run mapping yet. subagent.*, fusion, factories, background tasks,
hooks, skill execution, model-call telemetry, context/compaction, permissions,
schedules, remote/handoff/workspace changes, plan/todo changes, system messages,
MCP, commands, elicitation, sampling, canvases, extensions and custom notifications
are deliberately not typed Octostaff features. Their exact event names remain
in the disposition table. In particular, session.todos_changed has no todo
list payload; we do not infer a plan without a separate RPC read.
Additional payload limitations are deliberate:
assistant.message.reasoningTextis not replayed alongside dedicated reasoning events. Provider-specificreasoningBlocks,reasoningOpaque, encrypted content, server-tool payloads and citations are not rendered as typed Octostaff content. With no dedicated reasoning event, final-only embedded reasoning is omitted.- Tool progress/partial results are metadata-only until a final result. Tool
result text/structured content is retained, with media/credential fields
redacted; binary results,
session.binary_asset, citable sources and canvas/MCP resources do not become uploaded Octostaff artifacts or interactive source cards. - Permission and
ask_usercallbacks use Octostaff approval and answer requests. Elicitation, MCP OAuth/header-refresh, sampling, exit-plan, auto-mode and limits-exhausted interactions have no Octostaff mapping.
The shared harness alone brackets runs, settles cursors, coalesces deltas and
applies diagnostics.turns/diagnostics.bodies. Known content is sanitized before
diagnosis capture; inline media data, typed credential fields and media URLs are
omitted. Diagnostic bodies omit partial delta strings (which cannot be safely
redacted independently), retaining sanitized final snapshots instead. Unknown/interactive events never capture arbitrary payloads, even when
bodies are enabled. Text data URIs are redacted across delta boundaries; tool input is forwarded
only as a complete, sanitized object. As with ordinary chat, free prose is not a general secret detector.
The stream subscribes before sending and unsubscribes at completion. Empty, tool-only, failed and cancelled turns close; frames after the terminal event are dropped. A five-second health probe detects transport loss, with a ten-minute absolute turn deadline for a silent backend. Cancellation also covers a stalled send RPC. An unacknowledged abort after two seconds, or cancellation before send acceptance, disables prompting on that broker until restart, preventing overlap with possibly still-running work. These fixed limits are not configurable yet. Interrupt is supported through the shared cancellation path, including pending approvals and user input. In-flight steering is not advertised; the shared drain queues new input for the next turn.
Tools, permissions and questions
Copilot receives the shared browse_thread, open_subthread, search_principals
and invite_to_thread tools. They run using the bot's Octostaff credentials and
current thread; Octostaff still enforces grants and visibility. The native coding
tools bash, view, edit, create, grep, glob and ask_user are enabled
explicitly. Tools that require permission pause for approval in Octostaff. Approval
is for one request only; rejection feedback is returned to Copilot. An unanswered
request is never treated as approval.
Provider-advertised tools retain their schemas and provider target. Native names include a provider/name digest to prevent namespace collisions; Octostaff receives the original advertised name. Existing catalogs are loaded on start and resume. Catalog changes take effect in the native runtime through disconnect/resume before the next turn, preserving history. A call using a withdrawn or changed catalog fails explicitly; pending calls and approvals for that provider are cancelled. Live, mid-turn tool registration is not supported.
ask_user questions use Octostaff's existing question/answer interaction. Replies
must match the active run and request; provider replies must also come from the
intended provider. Invalid answers, cancellation, shutdown and publication
failures complete the callback with an error. Pending interactions time out
after 60 seconds. Late and duplicate replies cannot reopen them.
Other audited SDK options/APIs not exposed
clientName is not exposed. Only model, working directory, state directory and the explicit OpenAI-compatible
HTTP provider (type, baseUrl, apiKey, wireApi) are configurable here.
Streaming, empty runtime mode, the tool catalog and transport/lifecycle ownership are
set by the adapter. All other options below retain SDK defaults or remain unset;
listing them does not claim the runtime has disabled every internal feature.
Unknown adapter configuration keys are rejected.
| SDK surface | Not exposed / reason |
|---|---|
| Model controls | reasoningEffort, reasoningSummary, contextTier, modelCapabilities, enableExperimentalMode; setModel is used by /model; setAutoTier, model discovery and auto-tier changes are not exposed. |
| System prompt | systemMessage append/replace/customize, all section overrides/transforms; no trusted runtime system-prompt configuration in C3. |
| Tool/interaction configuration | tools, canvases, commands, toolSearch, excludedTools, excludedBuiltinAgents, includedBuiltinSkills, onMcpAuthRequest, askUserVariant, onElicitationRequest, onExitPlanModeRequest, onAutoModeSwitchRequest, enableMcpApps, githubMcpToolConfig; The adapter supplies tools, onPermissionRequest and onUserInputRequest; arbitrary caller callbacks and broader interactions are not configuration options. |
| Hooks | onPreToolUse, onPreMcpToolCall, onPostToolUse, onPostToolUseFailure, onUserPromptSubmitted, onUserPromptTransformed, onSessionStart, onSessionEnd, onErrorOccurred, onAgentStop: no adapter hook pipeline. |
| Agent/discovery configuration | configDirectory, enableConfigDiscovery, additionalDirectories, mcpServers, customAgents, defaultAgent, agent, skillDirectories, pluginDirectories, instructionDirectories, disabledSkills, disabledMcpServers, customAgentsLocalOnly, skipCustomInstructions, enableSkills, enableFileHooks, enableOnDemandInstructionDiscovery, organizationCustomInstructions; no host discovery controls exposed. |
| Session policy/state | largeOutput, infiniteSessions, memory, sessionLimits, enableSessionTelemetry, enableCitations, enableFileChangeTracking, coauthorEnabled, manageScheduleEnabled, includeSubAgentStreamingEvents, enableHostGitOperations, enableSessionStore, skipEmbeddingRetrieval, embeddingCacheStorage, featureFlags, onEvent; native defaults, no Octostaff policy/control mapping. |
| Authentication/providers | capi, named providers/models, gitHubToken, gitHubTokenProvider, mcpOAuthTokenStorage, authClientIdMetadataUrl, enableManagedSettings, managedSettings; also Azure/Anthropic provider types, websocket transport, bearer-token callbacks, arbitrary headers, wire/model overrides and token limits. Only the previously probed BYOK HTTP path is exposed. |
| Extensions/cloud/FS | requestCanvasRenderer, requestExtensions, extensionSdkPath, extensionInfo, canvasProvider, remoteSession, createSessionFsProvider, cloud; extension joinSession, factories, canvas handlers and virtual filesystem/SQLite providers have no Octostaff host implementation. |
| Resume | suppressResumeEvent, continuePendingWork, openCanvases are not exposed. Shared durable session identity supplies the resume ID; caller-controlled creation sessionId is not exposed. |
| Client plumbing | Alternative runtime connections/modes, client-info/telemetry/trace callbacks, model-list callback, request/WebSocket handlers/forwarders, session FS, plugin loading, token callbacks, GitHub telemetry, remote sessions and idle timeout are not adapter options. |
| Client lifecycle APIs | Created/deleted/updated/foreground/background lifecycle notifications are not turn content. Listing/deleting sessions, foreground selection and account/model discovery are not Octostaff controls. |
| Experimental RPC | Direct sandbox/auth/debug, canvas/factory/fleet, plan/workspace/autopilot, completion/instruction, task/agent/skill/plugin/MCP, provider/options/LSP, tool/command/UI/permission, metadata/content-exclusion/shell, history/queue/event-log, usage/limit-prediction/remote/visibility/schedule operations are not invoked. Shared Octostaff owners retain conversation, draining, persistence and run lifecycle. |