mirror of
https://github.com/microsoft/vscode.git
synced 2026-08-20 16:23:02 +01:00
* Remove extension-host Claude implementation Make Agent Host the sole Claude sessions implementation and remove the obsolete provider preference settings, extension runtime, SDK dependency, commands, tests, and integration glue.\n\n(Written by Copilot)\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove extension-host Claude smoke tests Delete smoke cases and commands that target the removed extension-host Claude implementation.\n\n(Written by Copilot)\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix Agent Host Claude permissions link Keep the Claude-specific permission documentation link for Agent Host Claude after removing the extension-host implementation.\n\n(Written by Copilot)\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
549 lines
31 KiB
HTML
549 lines
31 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>OTel Data Flow — All Agents</title>
|
|
<style>
|
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, monospace; background: #0d1117; color: #c9d1d9; padding: 24px; }
|
|
h1 { color: #58a6ff; margin-bottom: 8px; font-size: 20px; }
|
|
h2 { color: #8b949e; font-size: 14px; margin-bottom: 24px; font-weight: normal; }
|
|
.legend { display: flex; gap: 20px; flex-wrap: wrap; margin-bottom: 20px; font-size: 12px; }
|
|
.legend-item { display: flex; align-items: center; gap: 6px; }
|
|
.legend-swatch { width: 14px; height: 14px; border-radius: 3px; }
|
|
|
|
svg { width: 100%; height: auto; }
|
|
.node { cursor: default; }
|
|
.node rect { rx: 6; ry: 6; stroke-width: 1.5; }
|
|
.node text { font-family: inherit; font-size: 11px; fill: #c9d1d9; }
|
|
.node .label { font-weight: 600; font-size: 12px; }
|
|
.node .sub { font-size: 10px; fill: #8b949e; }
|
|
|
|
/* Provider colors */
|
|
.provider-a rect { fill: #1a2332; stroke: #58a6ff; }
|
|
.provider-b rect { fill: #1a2a1a; stroke: #3fb950; }
|
|
.provider-none rect { fill: #2a1a2a; stroke: #bc8cff; }
|
|
.debug-panel rect { fill: #2a2218; stroke: #d29922; }
|
|
.exporter rect { fill: #2a1a1a; stroke: #f85149; }
|
|
.process rect { fill: #1a1a2a; stroke: #8b949e; }
|
|
.bridge rect { fill: #1a2a2a; stroke: #39d353; }
|
|
|
|
.arrow { stroke-width: 1.5; fill: none; marker-end: url(#arrowhead); }
|
|
.arrow-data { stroke: #58a6ff; }
|
|
.arrow-bridge { stroke: #39d353; stroke-dasharray: 6,3; }
|
|
.arrow-export { stroke: #f85149; }
|
|
.arrow-env { stroke: #d29922; stroke-dasharray: 3,3; }
|
|
.arrow-context { stroke: #bc8cff; stroke-dasharray: 8,4; }
|
|
|
|
.section { margin-top: 32px; }
|
|
.section h3 { color: #58a6ff; font-size: 16px; margin-bottom: 12px; border-bottom: 1px solid #21262d; padding-bottom: 8px; }
|
|
|
|
.info-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 16px; margin-top: 16px; }
|
|
.info-card { background: #161b22; border: 1px solid #30363d; border-radius: 8px; padding: 16px; }
|
|
.info-card h4 { color: #58a6ff; margin-bottom: 8px; font-size: 13px; }
|
|
.info-card p, .info-card li { font-size: 12px; line-height: 1.6; color: #8b949e; }
|
|
.info-card ul { padding-left: 16px; }
|
|
.info-card code { background: #21262d; padding: 1px 5px; border-radius: 3px; color: #c9d1d9; font-size: 11px; }
|
|
|
|
.tab-bar { display: flex; gap: 2px; margin-bottom: 0; }
|
|
.tab { padding: 8px 16px; background: #161b22; border: 1px solid #30363d; border-bottom: none; border-radius: 6px 6px 0 0; cursor: pointer; font-size: 12px; color: #8b949e; }
|
|
.tab.active { background: #0d1117; color: #58a6ff; border-color: #58a6ff; border-bottom: 1px solid #0d1117; position: relative; z-index: 1; }
|
|
.tab-content { border: 1px solid #30363d; border-radius: 0 6px 6px 6px; padding: 0; background: #0d1117; }
|
|
.tab-pane { display: none; }
|
|
.tab-pane.active { display: block; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<h1>OTel Data Flow — VS Code Copilot Chat Extension</h1>
|
|
<h2>Complete tracing architecture for foreground agent, CLI background agent, and CLI terminal</h2>
|
|
|
|
<div class="legend">
|
|
<div class="legend-item"><div class="legend-swatch" style="background:#1a2332;border:1.5px solid #58a6ff"></div> Provider A (Extension NodeOTelService)</div>
|
|
<div class="legend-item"><div class="legend-swatch" style="background:#1a2a1a;border:1.5px solid #3fb950"></div> Provider B (SDK BasicTracerProvider)</div>
|
|
<div class="legend-item"><div class="legend-swatch" style="background:#1a2a2a;border:1.5px solid #39d353"></div> Bridge SpanProcessor</div>
|
|
<div class="legend-item"><div class="legend-swatch" style="background:#2a2218;border:1.5px solid #d29922"></div> Debug Panel Consumer</div>
|
|
<div class="legend-item"><div class="legend-swatch" style="background:#2a1a1a;border:1.5px solid #f85149"></div> External Exporter</div>
|
|
<div class="legend-item"><div class="legend-swatch" style="background:#2a1a2a;border:1.5px solid #bc8cff"></div> Synthetic Spans (ext-created)</div>
|
|
</div>
|
|
|
|
<div class="tab-bar">
|
|
<div class="tab active" onclick="switchTab('overview')">Overview (All Agents)</div>
|
|
<div class="tab" onclick="switchTab('foreground')">Foreground Agent</div>
|
|
<div class="tab" onclick="switchTab('cli-bg')">CLI Background</div>
|
|
<div class="tab" onclick="switchTab('cli-term')">CLI Terminal</div>
|
|
</div>
|
|
|
|
<div class="tab-content">
|
|
|
|
<!-- OVERVIEW -->
|
|
<div class="tab-pane active" id="tab-overview">
|
|
<svg viewBox="0 0 1100 720" xmlns="http://www.w3.org/2000/svg">
|
|
<defs>
|
|
<marker id="arrowhead" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#8b949e"/></marker>
|
|
<marker id="ah-blue" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#58a6ff"/></marker>
|
|
<marker id="ah-green" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#39d353"/></marker>
|
|
<marker id="ah-red" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#f85149"/></marker>
|
|
<marker id="ah-yellow" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#d29922"/></marker>
|
|
<marker id="ah-purple" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#bc8cff"/></marker>
|
|
</defs>
|
|
|
|
<!-- Extension Host Process boundary -->
|
|
<rect x="10" y="10" width="850" height="700" rx="10" fill="none" stroke="#30363d" stroke-dasharray="8,4"/>
|
|
<text x="24" y="32" fill="#8b949e" font-size="11" font-family="monospace">VS Code Extension Host Process</text>
|
|
|
|
<!-- Provider A: NodeOTelService -->
|
|
<g class="node provider-a" transform="translate(30,50)">
|
|
<rect width="260" height="90"/>
|
|
<text x="12" y="20" class="label" fill="#58a6ff">Provider A: NodeOTelService</text>
|
|
<text x="12" y="36" class="sub">Registered at extension activation</text>
|
|
<text x="12" y="52" class="sub">tracer A (stored ref, survives override)</text>
|
|
<text x="12" y="66" class="sub">service.name = "copilot-chat"</text>
|
|
<text x="12" y="80" class="sub">Emitters: onDidCompleteSpan, onDidEmitSpanEvent</text>
|
|
</g>
|
|
|
|
<!-- Provider B: SDK BasicTracerProvider -->
|
|
<g class="node provider-b" transform="translate(30,170)">
|
|
<rect width="260" height="90"/>
|
|
<text x="12" y="20" class="label" fill="#3fb950">Provider B: SDK BasicTracerProvider</text>
|
|
<text x="12" y="36" class="sub">Created by OtelLifecycle.initializeOtelSdk()</text>
|
|
<text x="12" y="52" class="sub">Replaces Provider A as global</text>
|
|
<text x="12" y="66" class="sub">service.name = "github-copilot"</text>
|
|
<text x="12" y="80" class="sub">SpanProcessors: BatchSP + BridgeSP</text>
|
|
</g>
|
|
|
|
<!-- Bridge SpanProcessor -->
|
|
<g class="node bridge" transform="translate(30,290)">
|
|
<rect width="260" height="70"/>
|
|
<text x="12" y="20" class="label" fill="#39d353">CopilotCliBridgeSpanProcessor</text>
|
|
<text x="12" y="36" class="sub">Added to Provider B after trackSession()</text>
|
|
<text x="12" y="52" class="sub">Maps traceId → sessionId, injects CHAT_SESSION_ID</text>
|
|
<text x="12" y="66" class="sub">Filters: only forwards registered traceIds</text>
|
|
</g>
|
|
|
|
<!-- Foreground Agent -->
|
|
<g class="node provider-a" transform="translate(340,50)">
|
|
<rect width="220" height="70"/>
|
|
<text x="12" y="20" class="label">Foreground Agent</text>
|
|
<text x="12" y="36" class="sub">toolCallingLoop.ts → chatMLFetcher.ts</text>
|
|
<text x="12" y="52" class="sub">Uses tracer A (Provider A)</text>
|
|
<text x="12" y="66" class="sub">invoke_agent → chat → execute_tool</text>
|
|
</g>
|
|
|
|
<!-- CLI Background Agent -->
|
|
<g class="node provider-b" transform="translate(340,150)">
|
|
<rect width="220" height="90"/>
|
|
<text x="12" y="20" class="label">CLI Background Agent</text>
|
|
<text x="12" y="36" class="sub">OtelSessionTracker (SDK native)</text>
|
|
<text x="12" y="52" class="sub">Uses tracer B (Provider B / global)</text>
|
|
<text x="12" y="66" class="sub">invoke_agent → chat → execute_tool</text>
|
|
<text x="12" y="80" class="sub">+ subagents, permissions, hooks</text>
|
|
</g>
|
|
|
|
<!-- CLI Background Extension Wrapper -->
|
|
<g class="node provider-a" transform="translate(340,270)">
|
|
<rect width="220" height="55"/>
|
|
<text x="12" y="20" class="label">CLI Extension Wrapper</text>
|
|
<text x="12" y="36" class="sub">copilotcliSession.ts</text>
|
|
<text x="12" y="50" class="sub">invoke_agent copilotcli (tracer A)</text>
|
|
</g>
|
|
|
|
<!-- CLI Terminal -->
|
|
<g class="node process" transform="translate(340,540)">
|
|
<rect width="220" height="55"/>
|
|
<text x="12" y="20" class="label">CLI Terminal Process</text>
|
|
<text x="12" y="36" class="sub">Separate terminal process</text>
|
|
<text x="12" y="50" class="sub">Full SDK OTel (independent traces)</text>
|
|
</g>
|
|
|
|
<!-- Debug Panel: Trajectory Provider -->
|
|
<g class="node debug-panel" transform="translate(620,50)">
|
|
<rect width="230" height="70"/>
|
|
<text x="12" y="20" class="label" fill="#d29922">OTelChatDebugLogProvider</text>
|
|
<text x="12" y="36" class="sub">Listens: onDidCompleteSpan</text>
|
|
<text x="12" y="52" class="sub">Buckets by copilot_chat.chat_session_id</text>
|
|
<text x="12" y="66" class="sub">Feeds: Agent Debug Log panel UI</text>
|
|
</g>
|
|
|
|
<!-- Debug Panel: File Logger -->
|
|
<g class="node debug-panel" transform="translate(620,150)">
|
|
<rect width="230" height="55"/>
|
|
<text x="12" y="20" class="label" fill="#d29922">ChatDebugFileLoggerService</text>
|
|
<text x="12" y="36" class="sub">Listens: onDidCompleteSpan</text>
|
|
<text x="12" y="50" class="sub">Writes: debug-logs/<sessionId>/main.jsonl</text>
|
|
</g>
|
|
|
|
<!-- OTLP Exporter (Provider A) -->
|
|
<g class="node exporter" transform="translate(620,240)">
|
|
<rect width="230" height="55"/>
|
|
<text x="12" y="20" class="label" fill="#f85149">OTLP Exporter (Provider A)</text>
|
|
<text x="12" y="36" class="sub">BatchSpanProcessor → HTTP/gRPC endpoint</text>
|
|
<text x="12" y="50" class="sub">Exports foreground + CLI wrapper spans</text>
|
|
</g>
|
|
|
|
<!-- OTLP Exporter (Provider B) -->
|
|
<g class="node exporter" transform="translate(620,325)">
|
|
<rect width="230" height="55"/>
|
|
<text x="12" y="20" class="label" fill="#f85149">OTLP Exporter (Provider B)</text>
|
|
<text x="12" y="36" class="sub">BatchSpanProcessor → same HTTP endpoint</text>
|
|
<text x="12" y="50" class="sub">Exports SDK native spans</text>
|
|
</g>
|
|
|
|
<!-- Grafana / External -->
|
|
<g class="node exporter" transform="translate(620,420)">
|
|
<rect width="230" height="55"/>
|
|
<text x="12" y="20" class="label" fill="#f85149">Grafana / Jaeger / Collector</text>
|
|
<text x="12" y="36" class="sub">Receives all spans from all exporters</text>
|
|
<text x="12" y="50" class="sub">Shows full trace hierarchy</text>
|
|
</g>
|
|
|
|
<!-- === ARROWS === -->
|
|
|
|
<!-- Provider A → Debug Panel (onDidCompleteSpan) -->
|
|
<path d="M 290,95 L 310,85 Q 615,55 620,85" class="arrow arrow-data" marker-end="url(#ah-blue)"/>
|
|
<text x="390" y="48" fill="#58a6ff" font-size="9">onDidCompleteSpan</text>
|
|
|
|
<!-- Provider A → File Logger -->
|
|
<path d="M 290,110 L 615,175" class="arrow arrow-data" marker-end="url(#ah-blue)"/>
|
|
|
|
<!-- Provider A → OTLP A -->
|
|
<path d="M 290,130 Q 450,260 620,267" class="arrow arrow-export" marker-end="url(#ah-red)"/>
|
|
<text x="420" y="228" fill="#f85149" font-size="9">BatchSpanProcessor</text>
|
|
|
|
<!-- Bridge → Provider A (injectCompletedSpan → onDidCompleteSpan) -->
|
|
<path d="M 290,325 Q 600,290 620,85" class="arrow arrow-bridge" marker-end="url(#ah-green)"/>
|
|
<text x="470" y="160" fill="#39d353" font-size="9">injectCompletedSpan()</text>
|
|
|
|
<!-- Provider B → OTLP B -->
|
|
<path d="M 290,215 Q 450,330 620,350" class="arrow arrow-export" marker-end="url(#ah-red)"/>
|
|
|
|
<!-- Provider B → Bridge -->
|
|
<path d="M 160,260 L 160,290" class="arrow arrow-bridge" marker-end="url(#ah-green)"/>
|
|
<text x="165" y="278" fill="#39d353" font-size="9">onEnd()</text>
|
|
|
|
<!-- OTLP A → Grafana -->
|
|
<path d="M 735,295 L 735,420" class="arrow arrow-export" marker-end="url(#ah-red)"/>
|
|
<!-- OTLP B → Grafana -->
|
|
<path d="M 755,380 L 755,420" class="arrow arrow-export" marker-end="url(#ah-red)"/>
|
|
|
|
<!-- CLI wrapper → traceparent → SDK -->
|
|
<path d="M 450,325 L 450,240" class="arrow arrow-context" marker-end="url(#ah-purple)"/>
|
|
<text x="455" y="285" fill="#bc8cff" font-size="9">traceparent</text>
|
|
|
|
<!-- Env vars → CLI Terminal -->
|
|
<path d="M 290,355 Q 320,540 340,565" class="arrow arrow-env" marker-end="url(#ah-yellow)"/>
|
|
<text x="265" y="480" fill="#d29922" font-size="9">env vars</text>
|
|
|
|
<!-- CLI Terminal → Grafana (independent) -->
|
|
<path d="M 560,565 Q 750,540 750,475" class="arrow arrow-export" marker-end="url(#ah-red)"/>
|
|
<text x="630" y="530" fill="#f85149" font-size="9">independent traces</text>
|
|
|
|
<!-- Config source -->
|
|
<g class="node" transform="translate(30,630)">
|
|
<rect width="260" height="70" fill="#161b22" stroke="#30363d" rx="6"/>
|
|
<text x="12" y="20" class="label" fill="#8b949e">resolveOTelConfig()</text>
|
|
<text x="12" y="38" class="sub">Settings: github.copilot.chat.otel.*</text>
|
|
<text x="12" y="52" class="sub">Env: COPILOT_OTEL_*, OTEL_EXPORTER_*</text>
|
|
<text x="12" y="66" class="sub">Kill switch: telemetry.telemetryLevel=off</text>
|
|
</g>
|
|
|
|
<!-- Config → Providers -->
|
|
<path d="M 160,630 L 160,360" class="arrow arrow-env" marker-end="url(#ah-yellow)"/>
|
|
<text x="85" y="500" fill="#d29922" font-size="9">OTelConfig</text>
|
|
<path d="M 200,630 Q 310,600 350,540" class="arrow arrow-env" marker-end="url(#ah-yellow)"/>
|
|
<path d="M 220,630 Q 320,580 350,510" class="arrow arrow-env" marker-end="url(#ah-yellow)"/>
|
|
</svg>
|
|
</div>
|
|
|
|
<!-- FOREGROUND AGENT -->
|
|
<div class="tab-pane" id="tab-foreground">
|
|
<svg viewBox="0 0 900 380" xmlns="http://www.w3.org/2000/svg">
|
|
<defs>
|
|
<marker id="ah2-blue" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#58a6ff"/></marker>
|
|
<marker id="ah2-red" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#f85149"/></marker>
|
|
</defs>
|
|
|
|
<text x="20" y="24" fill="#58a6ff" font-size="14" font-weight="600">Foreground Agent — Provider A Only</text>
|
|
<text x="20" y="42" fill="#8b949e" font-size="11">All spans created by tracer A (extension's NodeOTelService)</text>
|
|
|
|
<!-- Span hierarchy -->
|
|
<g transform="translate(30,60)">
|
|
<rect x="0" y="0" width="400" height="280" rx="8" fill="#161b22" stroke="#30363d"/>
|
|
<text x="12" y="20" fill="#58a6ff" font-size="12" font-weight="600">Span Hierarchy (tracer A)</text>
|
|
|
|
<rect x="16" y="34" width="370" height="24" rx="4" fill="#1a2332" stroke="#58a6ff" stroke-width="1"/>
|
|
<text x="24" y="50" fill="#c9d1d9" font-size="10">invoke_agent copilot (INTERNAL) — toolCallingLoop.ts</text>
|
|
|
|
<rect x="32" y="66" width="345" height="24" rx="4" fill="#1a2332" stroke="#58a6ff" stroke-width="1"/>
|
|
<text x="40" y="82" fill="#c9d1d9" font-size="10">chat gpt-4o (CLIENT) — chatMLFetcher.ts</text>
|
|
|
|
<rect x="48" y="98" width="320" height="22" rx="4" fill="#1a2332" stroke="#58a6ff" stroke-width="1"/>
|
|
<text x="56" y="113" fill="#c9d1d9" font-size="10">execute_tool readFile (INTERNAL) — toolsService.ts</text>
|
|
|
|
<rect x="48" y="128" width="320" height="22" rx="4" fill="#1a2332" stroke="#58a6ff" stroke-width="1"/>
|
|
<text x="56" y="143" fill="#c9d1d9" font-size="10">execute_tool runCommand (INTERNAL) — toolsService.ts</text>
|
|
|
|
<rect x="32" y="160" width="345" height="24" rx="4" fill="#1a2332" stroke="#58a6ff" stroke-width="1"/>
|
|
<text x="40" y="176" fill="#c9d1d9" font-size="10">chat gpt-4o (CLIENT) — chatMLFetcher.ts</text>
|
|
|
|
<rect x="48" y="192" width="320" height="22" rx="4" fill="#1a2332" stroke="#58a6ff" stroke-width="1"/>
|
|
<text x="56" y="207" fill="#c9d1d9" font-size="10">execute_tool runSubagent (INTERNAL) — toolsService.ts</text>
|
|
|
|
<rect x="64" y="222" width="305" height="24" rx="4" fill="#1a2332" stroke="#58a6ff" stroke-width="1"/>
|
|
<text x="72" y="238" fill="#c9d1d9" font-size="10">invoke_agent Explore (INTERNAL) — toolCallingLoop.ts</text>
|
|
|
|
<text x="16" y="270" fill="#8b949e" font-size="10">All spans have copilot_chat.chat_session_id</text>
|
|
</g>
|
|
|
|
<!-- Flow -->
|
|
<g transform="translate(460,60)">
|
|
<rect x="0" y="0" width="200" height="50" rx="6" fill="#1a2332" stroke="#58a6ff"/>
|
|
<text x="12" y="20" fill="#58a6ff" font-size="11" font-weight="600">NodeOTelService</text>
|
|
<text x="12" y="38" fill="#8b949e" font-size="10">Provider A tracer</text>
|
|
|
|
<path d="M 100,50 L 100,90" stroke="#58a6ff" stroke-width="1.5" marker-end="url(#ah2-blue)"/>
|
|
<text x="110" y="75" fill="#58a6ff" font-size="9">onDidCompleteSpan</text>
|
|
|
|
<rect x="0" y="90" width="200" height="40" rx="6" fill="#2a2218" stroke="#d29922"/>
|
|
<text x="12" y="115" fill="#d29922" font-size="11">Debug Panel ✅</text>
|
|
|
|
<path d="M 100,50 L 250,90" stroke="#f85149" stroke-width="1.5" marker-end="url(#ah2-red)"/>
|
|
<rect x="210" y="90" width="200" height="40" rx="6" fill="#2a1a1a" stroke="#f85149"/>
|
|
<text x="222" y="115" fill="#f85149" font-size="11">OTLP → Grafana ✅</text>
|
|
|
|
<text x="0" y="170" fill="#3fb950" font-size="12" font-weight="600">✅ Fully working</text>
|
|
<text x="0" y="188" fill="#8b949e" font-size="10">Same spans in debug panel and Grafana</text>
|
|
</g>
|
|
</svg>
|
|
</div>
|
|
|
|
<!-- CLI BACKGROUND -->
|
|
<div class="tab-pane" id="tab-cli-bg">
|
|
<svg viewBox="0 0 1000 620" xmlns="http://www.w3.org/2000/svg">
|
|
<defs>
|
|
<marker id="ah3-blue" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#58a6ff"/></marker>
|
|
<marker id="ah3-green" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#39d353"/></marker>
|
|
<marker id="ah3-red" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#f85149"/></marker>
|
|
<marker id="ah3-purple" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#bc8cff"/></marker>
|
|
</defs>
|
|
|
|
<text x="20" y="24" fill="#3fb950" font-size="14" font-weight="600">CLI Background Agent — Two Providers (Bridge Architecture)</text>
|
|
<text x="20" y="42" fill="#8b949e" font-size="11">Extension root span (tracer A) + SDK native spans (tracer B) + Bridge for debug panel</text>
|
|
|
|
<!-- Extension root span -->
|
|
<g transform="translate(30,60)">
|
|
<rect width="380" height="130" rx="8" fill="#161b22" stroke="#30363d"/>
|
|
<text x="12" y="20" fill="#58a6ff" font-size="12" font-weight="600">Extension Root (tracer A)</text>
|
|
|
|
<rect x="16" y="34" width="350" height="24" rx="4" fill="#1a2332" stroke="#58a6ff" stroke-width="1"/>
|
|
<text x="24" y="50" fill="#c9d1d9" font-size="10">invoke_agent copilotcli — copilotcliSession.ts</text>
|
|
<text x="24" y="68" fill="#8b949e" font-size="9">CHAT_SESSION_ID ✅ | CONVERSATION_ID ✅ | SESSION_ID ✅</text>
|
|
|
|
<text x="16" y="92" fill="#bc8cff" font-size="10">↓ traceparent = 00-{traceId}-{spanId}-01</text>
|
|
<text x="16" y="106" fill="#bc8cff" font-size="10">↓ via otelLifecycle.updateParentTraceContext()</text>
|
|
<text x="16" y="120" fill="#8b949e" font-size="9">SDK spans inherit this traceId → same trace in Grafana ✅</text>
|
|
</g>
|
|
|
|
<!-- SDK native spans -->
|
|
<g transform="translate(30,210)">
|
|
<rect width="380" height="280" rx="8" fill="#161b22" stroke="#30363d"/>
|
|
<text x="12" y="20" fill="#3fb950" font-size="12" font-weight="600">SDK Native Spans (tracer B, same traceId)</text>
|
|
|
|
<rect x="16" y="34" width="350" height="24" rx="4" fill="#1a2a1a" stroke="#3fb950" stroke-width="1"/>
|
|
<text x="24" y="50" fill="#c9d1d9" font-size="10">invoke_agent (CLIENT) — OtelSessionTracker</text>
|
|
|
|
<rect x="32" y="66" width="330" height="22" rx="4" fill="#1a2a1a" stroke="#3fb950" stroke-width="1"/>
|
|
<text x="40" y="81" fill="#c9d1d9" font-size="10">chat claude-opus-4.6-1m (CLIENT)</text>
|
|
|
|
<rect x="48" y="96" width="310" height="22" rx="4" fill="#1a2a1a" stroke="#3fb950" stroke-width="1"/>
|
|
<text x="56" y="111" fill="#c9d1d9" font-size="10">execute_tool report_intent</text>
|
|
|
|
<rect x="48" y="126" width="310" height="22" rx="4" fill="#1a2a1a" stroke="#3fb950" stroke-width="1"/>
|
|
<text x="56" y="141" fill="#c9d1d9" font-size="10">execute_tool task</text>
|
|
|
|
<rect x="64" y="156" width="290" height="22" rx="4" fill="#1a2a1a" stroke="#3fb950" stroke-width="1"/>
|
|
<text x="72" y="171" fill="#c9d1d9" font-size="10">invoke_agent explore (SUBAGENT!)</text>
|
|
|
|
<rect x="80" y="186" width="270" height="22" rx="4" fill="#1a2a1a" stroke="#3fb950" stroke-width="1"/>
|
|
<text x="88" y="201" fill="#c9d1d9" font-size="10">execute_tool grep + permission</text>
|
|
|
|
<rect x="32" y="216" width="330" height="22" rx="4" fill="#1a2a1a" stroke="#3fb950" stroke-width="1"/>
|
|
<text x="40" y="231" fill="#c9d1d9" font-size="10">chat claude-opus-4.6-1m (final response)</text>
|
|
|
|
<text x="16" y="260" fill="#8b949e" font-size="9">Bridge injects copilot_chat.chat_session_id on each span</text>
|
|
<text x="16" y="274" fill="#3fb950" font-size="9" font-weight="600">✅ All spans reach debug panel via bridge</text>
|
|
</g>
|
|
|
|
<!-- Data flow -->
|
|
<g transform="translate(450,60)">
|
|
<!-- Provider B box -->
|
|
<rect width="210" height="60" rx="6" fill="#1a2a1a" stroke="#3fb950"/>
|
|
<text x="12" y="20" fill="#3fb950" font-size="11" font-weight="600">Provider B (SDK)</text>
|
|
<text x="12" y="38" fill="#8b949e" font-size="10">BatchSpanProcessor → OTLP</text>
|
|
<text x="12" y="52" fill="#8b949e" font-size="10">BridgeSpanProcessor → ext (injected)</text>
|
|
|
|
<!-- Bridge box -->
|
|
<rect x="0" y="80" width="210" height="65" rx="6" fill="#1a2a2a" stroke="#39d353"/>
|
|
<text x="12" y="98" fill="#39d353" font-size="11" font-weight="600">BridgeSpanProcessor ✅</text>
|
|
<text x="12" y="114" fill="#8b949e" font-size="10">Injected via internal _spanProcessors</text>
|
|
<text x="12" y="128" fill="#8b949e" font-size="9">ProxyTP._delegate._activeSpanProcessor._spanProcessors.push()</text>
|
|
|
|
<path d="M 105,60 L 105,80" stroke="#39d353" stroke-width="1.5" stroke-dasharray="4,2" marker-end="url(#ah3-green)"/>
|
|
|
|
<!-- Provider A for injection -->
|
|
<rect x="0" y="165" width="210" height="50" rx="6" fill="#1a2332" stroke="#58a6ff"/>
|
|
<text x="12" y="185" fill="#58a6ff" font-size="11" font-weight="600">NodeOTelService (Provider A)</text>
|
|
<text x="12" y="201" fill="#8b949e" font-size="10">injectCompletedSpan → fire event</text>
|
|
|
|
<path d="M 105,145 L 105,165" stroke="#39d353" stroke-width="1.5" stroke-dasharray="4,2" marker-end="url(#ah3-green)"/>
|
|
|
|
<!-- Debug panel -->
|
|
<rect x="0" y="235" width="210" height="40" rx="6" fill="#2a2218" stroke="#d29922"/>
|
|
<text x="12" y="260" fill="#d29922" font-size="11" font-weight="600">Debug Panel ✅ (full hierarchy)</text>
|
|
|
|
<path d="M 105,215 L 105,235" stroke="#58a6ff" stroke-width="1.5" marker-end="url(#ah3-blue)"/>
|
|
<text x="110" y="228" fill="#58a6ff" font-size="9">onDidCompleteSpan</text>
|
|
|
|
<!-- OTLP — this works fine -->
|
|
<rect x="240" y="0" width="200" height="40" rx="6" fill="#2a1a1a" stroke="#f85149"/>
|
|
<text x="252" y="25" fill="#f85149" font-size="11">OTLP → Grafana ✅</text>
|
|
|
|
<path d="M 210,30 L 240,20" stroke="#f85149" stroke-width="1.5" marker-end="url(#ah3-red)"/>
|
|
|
|
<!-- Key insight -->
|
|
<rect x="0" y="300" width="440" height="100" rx="8" fill="#161b22" stroke="#39d353"/>
|
|
<text x="16" y="320" fill="#39d353" font-size="12" font-weight="600">HOW: Bridge injection via OTel v2 internals</text>
|
|
<text x="16" y="340" fill="#8b949e" font-size="10">1. api.trace.getTracerProvider() → ProxyTracerProvider</text>
|
|
<text x="16" y="356" fill="#8b949e" font-size="10">2. ._delegate → BasicTracerProvider</text>
|
|
<text x="16" y="372" fill="#8b949e" font-size="10">3. ._activeSpanProcessor → MultiSpanProcessor</text>
|
|
<text x="16" y="388" fill="#8b949e" font-size="10">4. ._spanProcessors.push(bridge) — same pattern SDK uses in forceFlush()</text>
|
|
</g>
|
|
|
|
<!-- Working path annotation -->
|
|
<g transform="translate(30,510)">
|
|
<rect width="920" height="80" rx="8" fill="#161b22" stroke="#3fb950"/>
|
|
<text x="16" y="20" fill="#3fb950" font-size="12" font-weight="600">✅ Full data flow working</text>
|
|
<text x="16" y="40" fill="#8b949e" font-size="10">• Grafana: full hierarchy via Provider B → BatchSpanProcessor → OTLP</text>
|
|
<text x="16" y="56" fill="#8b949e" font-size="10">• Debug Panel: full hierarchy via Provider B → Bridge → injectCompletedSpan → onDidCompleteSpan</text>
|
|
<text x="16" y="72" fill="#8b949e" font-size="10">• Trace context: SDK spans are children of extension root span (traceparent propagation)</text>
|
|
</g>
|
|
</svg>
|
|
</div>
|
|
|
|
<!-- CLI TERMINAL -->
|
|
<div class="tab-pane" id="tab-cli-term">
|
|
<svg viewBox="0 0 800 300" xmlns="http://www.w3.org/2000/svg">
|
|
<defs>
|
|
<marker id="ah4-red" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#f85149"/></marker>
|
|
<marker id="ah4-yellow" markerWidth="8" markerHeight="6" refX="8" refY="3" orient="auto"><polygon points="0 0, 8 3, 0 6" fill="#d29922"/></marker>
|
|
</defs>
|
|
|
|
<text x="20" y="24" fill="#8b949e" font-size="14" font-weight="600">CLI Terminal — Separate Process, Independent Traces</text>
|
|
<text x="20" y="42" fill="#8b949e" font-size="11">Extension only forwards env vars. No bridge. No debug panel visibility.</text>
|
|
|
|
<g transform="translate(30,60)">
|
|
<!-- Extension -->
|
|
<rect width="250" height="70" rx="6" fill="#161b22" stroke="#30363d"/>
|
|
<text x="12" y="20" fill="#58a6ff" font-size="11" font-weight="600">Extension (at terminal creation)</text>
|
|
<text x="12" y="40" fill="#8b949e" font-size="10">deriveCopilotCliOTelEnv(config, {})</text>
|
|
<text x="12" y="56" fill="#8b949e" font-size="10">→ TerminalOptions.env</text>
|
|
|
|
<path d="M 250,50 L 310,50" stroke="#d29922" stroke-width="1.5" stroke-dasharray="4,2" marker-end="url(#ah4-yellow)"/>
|
|
<text x="255" y="42" fill="#d29922" font-size="9">env vars</text>
|
|
|
|
<!-- Terminal process -->
|
|
<rect x="310" y="0" width="250" height="130" rx="6" fill="#161b22" stroke="#8b949e"/>
|
|
<text x="322" y="20" fill="#8b949e" font-size="11" font-weight="600">Terminal Process (copilot binary)</text>
|
|
<text x="322" y="40" fill="#8b949e" font-size="10">Own OtelLifecycle + BasicTracerProvider</text>
|
|
<text x="322" y="56" fill="#8b949e" font-size="10">service.name = "github-copilot"</text>
|
|
<text x="322" y="76" fill="#8b949e" font-size="10">invoke_agent → chat → execute_tool</text>
|
|
<text x="322" y="96" fill="#8b949e" font-size="10">Independent root traceId</text>
|
|
<text x="322" y="116" fill="#8b949e" font-size="10">No CHAT_SESSION_ID (not needed)</text>
|
|
|
|
<path d="M 560,65 L 620,65" stroke="#f85149" stroke-width="1.5" marker-end="url(#ah4-red)"/>
|
|
|
|
<!-- Grafana -->
|
|
<rect x="620" y="30" width="150" height="40" rx="6" fill="#2a1a1a" stroke="#f85149"/>
|
|
<text x="632" y="55" fill="#f85149" font-size="11">Grafana ✅</text>
|
|
|
|
<!-- No debug panel -->
|
|
<rect x="620" y="90" width="150" height="40" rx="6" fill="#21262d" stroke="#484f58"/>
|
|
<text x="632" y="115" fill="#484f58" font-size="11">Debug Panel ❌</text>
|
|
<text x="622" y="148" fill="#484f58" font-size="9">Separate process — spans</text>
|
|
<text x="622" y="162" fill="#484f58" font-size="9">never reach extension</text>
|
|
</g>
|
|
</svg>
|
|
</div>
|
|
|
|
</div><!-- tab-content -->
|
|
|
|
<!-- Info cards -->
|
|
<div class="section">
|
|
<h3>Key Design Facts</h3>
|
|
<div class="info-grid">
|
|
<div class="info-card">
|
|
<h4>Two TracerProviders in the Same Process</h4>
|
|
<ul>
|
|
<li><b>Provider A</b> (<code>NodeOTelService</code>): Created at extension activation. Stores tracer ref. Serves foreground agent and the CLI wrapper span.</li>
|
|
<li><b>Provider B</b> (<code>BasicTracerProvider</code>): Created by SDK's <code>OtelLifecycle.initializeOtelSdk()</code>. Replaces A as global. Serves all SDK-native spans.</li>
|
|
<li>Provider A's stored <code>this._tracer</code> still works after override — OTel tracers are bound to their provider at creation time.</li>
|
|
</ul>
|
|
</div>
|
|
<div class="info-card">
|
|
<h4>Bridge SpanProcessor</h4>
|
|
<ul>
|
|
<li>Injected into Provider B via internal <code>_spanProcessors.push()</code></li>
|
|
<li>Converts <code>ReadableSpan</code> → <code>ICompletedSpanData</code></li>
|
|
<li>Injects <code>copilot_chat.chat_session_id</code> from <code>traceId → sessionId</code> map</li>
|
|
<li><b>Filters</b>: only forwards spans whose traceId is registered (CLI sessions)</li>
|
|
<li>Fires <code>IOTelService.injectCompletedSpan()</code> → <code>onDidCompleteSpan</code></li>
|
|
</ul>
|
|
</div>
|
|
<div class="info-card">
|
|
<h4>Trace Context Propagation</h4>
|
|
<ul>
|
|
<li>Extension root span → <code>traceparent = 00-{traceId}-{spanId}-01</code></li>
|
|
<li>Passed to SDK via <code>otelLifecycle.updateParentTraceContext(sessionId, traceparent)</code></li>
|
|
<li>SDK spans inherit the extension's traceId → same trace in Grafana</li>
|
|
<li>Bridge matches traceId → injects CHAT_SESSION_ID → debug panel buckets correctly</li>
|
|
</ul>
|
|
</div>
|
|
<div class="info-card">
|
|
<h4>Debug Panel Data Path</h4>
|
|
<ul>
|
|
<li><b>Foreground</b>: tracer A → TrackedSpanHandle.end() → <code>_onDidCompleteSpan.fire()</code></li>
|
|
<li><b>CLI background</b>: tracer B → Bridge.onEnd() → <code>injectCompletedSpan()</code> → <code>_onDidCompleteSpan.fire()</code></li>
|
|
<li><b>CLI terminal</b>: N/A (separate process, no debug panel visibility)</li>
|
|
<li>Both consumers: <code>OTelChatDebugLogProvider</code> (trajectory) and <code>ChatDebugFileLoggerService</code> (file)</li>
|
|
</ul>
|
|
</div>
|
|
<div class="info-card">
|
|
<h4>service.name Values</h4>
|
|
<ul>
|
|
<li><code>copilot-chat</code> — Extension Provider A spans (foreground and CLI wrapper)</li>
|
|
<li><code>github-copilot</code> — SDK Provider B spans (CLI native), CLI terminal</li>
|
|
</ul>
|
|
</div>
|
|
<div class="info-card">
|
|
<h4>What Goes Where</h4>
|
|
<ul>
|
|
<li><b>Grafana</b>: Everything from all OTLP exporters (Provider A + B + terminal)</li>
|
|
<li><b>Debug Panel</b>: Only spans that fire <code>onDidCompleteSpan</code> with <code>copilot_chat.chat_session_id</code></li>
|
|
<li><b>File Logger</b>: Same as debug panel (listens to same event)</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function switchTab(id) {
|
|
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
|
|
document.querySelectorAll('.tab-pane').forEach(p => p.classList.remove('active'));
|
|
document.getElementById('tab-' + id).classList.add('active');
|
|
event.target.classList.add('active');
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|