Repository navigation
Description
Describe the bug
When the CLI runs as an ACP server (copilot --acp), it exports no OpenTelemetry signals at all: no traces, no metrics, nothing. This happens even though OTel is enabled and server-managed settings force it on. The same machine, account, and policy export normally in copilot -p and interactive mode.
The CLI log shows OTel being configured in ACP mode, but the per-session tracker is never created:
| Mode | OpenTelemetry configured from managed settings |
OpenTelemetry tracker created for session <id> |
Spans/metrics received |
|---|---|---|---|
copilot -p "…" |
yes | yes | yes (2 traces + ~14 metrics within seconds) |
copilot --acp (session/new + session/prompt) |
yes | never | none, not even after a clean shutdown |
This means that any tool hosting Copilot through ACP (editor integrations, third-party ACP clients) is invisible to an organization's OTel monitoring, even when the enterprise telemetry policy is enforced. This is the same class of gap as #4169 (fixed for -p in v1.0.91), but ACP mode still isn't covered.
Affected version
GitHub Copilot CLI 1.0.107.
Steps to reproduce the behavior
-
Enable OTel. I used server-managed settings (
telemetry.enabled: true,exporter: otlp-http,capture_prompts: true), and I also triedCOPILOT_OTEL_ENABLED=true OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:14318andCOPILOT_OTEL_FILE_EXPORTER_PATH=/tmp/otel.jsonl. -
Start any OTLP/HTTP receiver, or watch the file exporter path.
-
Control:
copilot -p "Reply with just: hi". Traces and metrics arrive within seconds, and the log contains[rust:otel] OpenTelemetry tracker created for session <id>. -
Drive one ACP turn with this minimal client (Python 3, stdlib only):
import json, subprocess, threading, time p = subprocess.Popen(['copilot', '--acp'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, text=True, bufsize=1, cwd='/tmp') pending, nid = {}, [0] def send(m): p.stdin.write(json.dumps(m) + '\n'); p.stdin.flush() def reader(): for line in p.stdout: msg = json.loads(line) if 'method' in msg and 'id' in msg: # agent -> client request send({'jsonrpc': '2.0', 'id': msg['id'], 'result': {'outcome': {'outcome': 'cancelled'}}}) elif msg.get('id') in pending: pending[msg['id']]['r'] = msg; pending[msg['id']]['e'].set() threading.Thread(target=reader, daemon=True).start() def call(method, params): nid[0] += 1; i = nid[0]; pending[i] = {'e': threading.Event()} send({'jsonrpc': '2.0', 'id': i, 'method': method, 'params': params}) pending[i]['e'].wait(120); return pending[i]['r'] call('initialize', {'protocolVersion': 1, 'clientCapabilities': {}}) sid = call('session/new', {'cwd': '/tmp', 'mcpServers': []})['result']['sessionId'] print(call('session/prompt', {'sessionId': sid, 'prompt': [{'type': 'text', 'text': 'Reply with just: hi'}]})) time.sleep(20) # leave the process alive past the export interval p.stdin.close(); p.wait(15) # clean shutdown, which should flush
-
The turn completes normally (
stopReason: end_turn, usage reported), but the receiver or file gets nothing: no spans and no metrics, either during the 20-second idle or after the process exits. The process never opens a connection to the OTLP endpoint. -
The log (
~/.copilot/logs/process-*.log) showsStarting ACP server (stdio),OpenTelemetry configured from managed settings: exporter=otlp-http …andOTel session policy applied, but neverOpenTelemetry tracker created for session <id>.
Expected behavior
ACP sessions emit the same OTel signals as -p and interactive sessions (invoke_agent and chat spans, github.copilot.user.message, the GenAI metrics, and so on), following the same managed-settings telemetry policy. As #4169 put it: "OTEL telemetry gets emitted no matter how copilot is triggered when OTEL is forced on in managed settings."
Additional context
- OS: Fedora Linux 45, kernel 7.2.15, x86_64.
- ACP client in real use: a third-party desktop app that drives
copilot --acpover stdio. I reproduced it with the standalone client above, so it isn't specific to that host. - The ACP log also has
Failed to reload managed hooks … no hook session for session id …andevent was not delivered to its registered session host … no session host is registered for session …. Those warnings appear in-pmode too, so they probably aren't the cause. The one difference I found is the missingOpenTelemetry tracker createdline. - The session's local
events.jsonlis written normally in ACP mode (turns, tool calls,session.usage_record), so the session events exist; they just never reach the OTel tracker or exporter. - Related:
copilot -pdoes not emit OTEL telemetry even with server-managed settings overrides #4169 (same gap in-pmode, fixed in v1.0.91).
Activity