Skip to content

feat(desktop): opt-in aggregate agent-metrics aggregator + flush#4033

Merged
esengine merged 1 commit into
main-v2from
feat/desktop-metrics-aggregator
Jun 11, 2026
Merged

feat(desktop): opt-in aggregate agent-metrics aggregator + flush#4033
esengine merged 1 commit into
main-v2from
feat/desktop-metrics-aggregator

Conversation

@esengine

Copy link
Copy Markdown
Owner

Desktop side of the opt-in agent-metrics telemetry. The worker /v1/metrics endpoint is already merged (#4030) and deployed live (schema applied, smoke-tested 202/400/405), so once this ships and a user opts in, counts start flowing.

How it works

  • metricsAggregator taps the existing tabEventSink.Emit event stream — internal/agent is untouched, so the CLI stays zero-egress (desktop-only, per the telemetry-scope decision).
  • observe(e) counts enumerated facts only: finish_reason, empty_final, provider_error (class), cache_hit (bucket), tool_error (class), compaction, turns. Error classes come from a status (\d{3}) regex + keyword match — never the message body, which can echo request content.
  • Counts persist per turn (merge into a pending file) and flush once at the next launch, mirroring the ping. A failed POST folds back to retry.

Privacy / opt-in

  • New desktop.metrics flag, default off, separate from the default-on launch ping. Dev builds skip it.
  • No install id, no content, no keys, no prompts, no paths — only enumerated integer counters. Worker rejects any non-enum signal / bad bucket (zod), so the table can't be polluted.

Test

  • go test ./ (desktop) — aggregator classification, error/cache bucketing, cross-session merge; verified each mapping
  • go test ./internal/config/..., go build ./... (desktop), go vet ./... — pass

Not in this PR (follow-up)

Settings toggle + first-run disclosure (the user-facing opt-in switch). Until then the flag is set via [desktop] metrics = true in config.toml. No new bound App method here, so no bridge.ts AppBindings change.

Desktop side of the opt-in metrics telemetry (worker /v1/metrics already
live). A metricsAggregator taps the existing tabEventSink event stream —
internal/agent is untouched, so the CLI stays zero-egress — and counts
enumerated facts only: finish_reason, empty_final, provider error class,
cache-hit bucket, tool error class, compaction, and turns. Never message
text, keys, prompts, or paths; error classes are derived from a status-code
regex, not the message body.

Gated on a new desktop.metrics flag (default off, separate from the
default-on launch ping) and skipped in dev. Counts persist per turn and
flush once at the next launch, mirroring the ping; a failed POST folds back
to retry. The settings toggle and first-run disclosure land in a follow-up;
until then the flag is set via config.toml.
@esengine esengine requested a review from SivanCola as a code owner June 11, 2026 11:54
@github-actions github-actions Bot added v2 Go rewrite (1.x) — main-v2 branch, active development desktop Wails desktop app (desktop/**) config Configuration & setup (internal/config) labels Jun 11, 2026
@esengine esengine merged commit 6b9d367 into main-v2 Jun 11, 2026
14 checks passed
@esengine esengine deleted the feat/desktop-metrics-aggregator branch June 11, 2026 11:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

config Configuration & setup (internal/config) desktop Wails desktop app (desktop/**) v2 Go rewrite (1.x) — main-v2 branch, active development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant