01What it is
my-orchestra is a local web app for building and testing code with Copilot's agent, designed around one principle: you should always know what a turn costs. It borrows Copilot CLI's calm, tool-centric chrome and Claude CLI's conversational warmth, and adds first-class pages for context engineering and live credit telemetry — all server-rendered and streamed over SSE.
Chat
Streaming agent conversation with a tool timeline, a separate reasoning block, and a live credit footer.
Telemetry
Per-model token & credit breakdown vs. your monthly budget, plus GitHub's authoritative AIU cost.
Forge
Toggle skills and instructions and pick the active agent — compiled into the session's system message.
Permissions
Inline approve/reject prompts for the agent's shell/file/tool actions when auto-approve is off.
htmx + SSE
One long-lived event stream renders tokens, tools, and cost live — no JS build chain.
Settings
The effective configuration — model, effort, budget, price overrides, OTLP endpoint.
02Architecture
A small, testable core in pure Go, a thin SDK adapter at the edge, and an
htmx web UI streamed over SSE on top. The copilot.Client
interface is the seam that keeps the UI hermetically testable with an
in-memory mock.
handlers · SSE hub · html/template"] CONVO["convo
Turn · ToolView · transcript reducer"] FORGE["ctxforge
skills · instructions · agents · MCP"] TEL["telemetry
price book · Meter · budget"] CFG["config
settings · key bindings"] IFACE{{"copilot.Client
(interface)"}} WEB --> CONVO WEB --> FORGE WEB --> TEL WEB --> CFG WEB --> IFACE FORGE -->|Compile → SessionSpec| IFACE end IFACE -->|production| SDKC["SDKClient
wraps github/copilot-sdk/go
+ permBridge (sync↔async perms)"] IFACE -.->|tests / offline| MOCK["MockClient"] SDKC --> CLI["copilot CLI runtime"] CLI --> CAPI["GitHub Copilot API
(models · billing)"] CLI -->|assistant.usage events| TEL
Why an interface, not a direct call?
The web layer never imports the SDK. It depends only on
copilot.Client, so the handlers and the event→fragment reducer
are unit-tested against MockClient with deterministic events —
no network, no auth, no flake. SDKClient is the one place that
touches the runtime, and it is covered by a gated end-to-end test.
Interactive permissions: bridging sync ↔ async
The SDK's OnPermissionRequest callback is synchronous — it
must return a decision inline — but a browser answers later. A small
permBridge reconciles the two: the callback registers a
one-shot channel, emits an EvPermission, and blocks; the server
streams an inline approve/reject form over SSE, and a
POST /perm/{id} routes the decision back through
Client.Respond. On shutdown the callback returns
user-not-available so it never hangs.
03Credit telemetry
GitHub moved Copilot to usage-based billing on 2026-06-01:
spend is metered on tokens and converted to AI Credits at a
fixed 1 credit = $0.01. my-orchestra meters two ways:
- Estimate — a configurable price book multiplies each token category by its per-model rate. Deterministic, offline, testable.
- Authoritative — the SDK's
assistant.usageevent carries GitHub's ownTotalNanoAiucost, shown next to the estimate so you can trust and calibrate it.
| Token category | Source field | Billed as |
|---|---|---|
| Input | inputTokens | input rate |
| Cached input | cacheReadTokens | cached rate |
| Output | outputTokens | output rate |
| Reasoning | reasoningTokens | output rate |
| Authoritative | copilotUsage.totalNanoAiu | GitHub AIU |
04The my-ctx forge
The forge is a file-backed registry (forge.json) of reusable
context. Selected pieces compile into one SessionSpec:
the agent persona's system message, then enabled instructions (by priority),
then active skill prompts, plus enabled MCP servers. Reproducible, diffable,
shareable.
forge.json ──▶ Forge.Compile(agentID) ──▶ SessionSpec
├─ Model / ReasoningEffort (from agent)
├─ SystemMessage (agent + instructions + skills)
├─ EnabledSkillIDs / SlashCommands
└─ MCPServers (enabled only)
05Engineering & infrastructure
Test-driven, SDET-hardened
- Every package was written test-first; tests run under the race detector.
- Table-driven edge cases, a fuzz target for the pricing engine, and concurrency tests for the meter.
- CI enforces a coverage floor and gofmt/vet/golangci-lint cleanliness.
CI/CD
- CI — lint, race tests + coverage gate, fuzz smoke, and a 6-target cross-compile matrix (linux/darwin/windows × amd64/arm64).
- Release — tagged builds publish stripped binaries + checksums.
- Pages — this site deploys from
docs/on every push tomain.
cmd/my-orchestra entrypoint & wiring internal/web net/http server · SSE hub · html/template · vendored htmx internal/convo transcript model · Turn · ToolView · reducer (pure) internal/copilot Client interface · SDKClient · MockClient internal/ctxforge skills · instructions · agents · MCP → SessionSpec internal/telemetry price book · Meter · budget · AIU internal/config settings · key bindings (JSON)
06Quickstart
# build go build -o bin/my-orchestra ./cmd/my-orchestra # seed a starter forge + config, then run (opens http://127.0.0.1:8765) ./bin/my-orchestra --seed ./bin/my-orchestra # or explore offline with a scripted mock ./bin/my-orchestra -demo
By default my-orchestra authenticates with the already-logged-in
copilot CLI session. Without it (or with -demo) it
runs an offline mock so you can explore every page. Install the
Copilot CLI and log in
to drive a real agent.