Skip to content

feat(cli): M4 observability + runtime — usage / logs / quota / chat + provider oauth (25 cmds)#13

Merged
quangdang46 merged 1 commit into
mainfrom
devin/1778563448-cli-m4-observability-runtime
May 12, 2026
Merged

feat(cli): M4 observability + runtime — usage / logs / quota / chat + provider oauth (25 cmds)#13
quangdang46 merged 1 commit into
mainfrom
devin/1778563448-cli-m4-observability-runtime

Conversation

@quangdang46
Copy link
Copy Markdown
Owner

Summary

Implements M4 — Observability & runtime from the PLAN v3: ~25 new CLI subcommands that wrap the running server's /api/usage/*, /api/observability/*, /api/oauth/*, /v1/models, and /api/dashboard/chat/completions endpoints. Single PR per user request — no M4a/M4b split.

New runtime plumbing (src/cli/runtime.rs)

  • Reqwest-based HTTP client that resolves the target server in priority order:
    1. --url / OPENPROXY_URL (remote mode)
    2. {data_dir}/openproxy.endpoint sidecar
    3. 127.0.0.1:4623 fallback
  • API key resolution: explicit flag → OPENPROXY_API_KEY env → first active key in local db.json.
  • ensure_alive() probes /api/health with a 1.5s timeout and maps connection failures to a stable exit code 6 + server_unreachable envelope.
  • stream_sse() / post_stream_sse() open SSE responses with no client-side timeout — streaming subcommands follow indefinitely until Ctrl+C, per spec.
  • SseFrames adapter extracts data: payloads from raw SSE bytes (handles both LF and CRLF, skips :-prefixed pings); unit-tested.

New CLI commands

Group Subcommands Source endpoint
usage summary, daily, chart, history, stats, providers, logs, request-logs, stream, pricing /api/usage/*
logs tail [--follow], export, clear, stats /api/observability/*
quota list, get, reset --yes, refresh /api/usage/providers + /api/observability/clear
chat models, tags, send, stream /v1/models, /api/tags, /api/dashboard/chat/completions
provider oauth start, poll, status, refresh, import-kiro [--auto], iflow-cookie, gitlab-pat /api/oauth/*

All commands honor the global --robot flag and emit stable openproxy.v1.* envelopes (NDJSON for streams). Streaming commands flush per chunk.

Server-side support

  • Re-introduces /api/observability/{logs,stream,stats,clear} (moved from inline /api/logs/list in mod.rs), backed by the existing console_logs broadcast channel + 25-second SSE keepalive pings. All four endpoints require API-key auth so CLI sessions can subscribe.
  • Relaxes auth on /api/usage/stats and /api/usage/stream from require_dashboard_sessionrequire_usage_access, so CLI API keys can read live counters without forging a dashboard session cookie.

Schema introspection

openproxy schema list/show/example now covers the new envelope shapes so agents can introspect without browsing the dashboard:

  • usage-event, log-event, chat-event — NDJSON event envelopes
  • quota — per-provider aggregate row
  • oauth-statusprovider oauth status return shape

Test infrastructure

  • New dev-deps: assert_cmd, predicates, insta (last reserved for future golden-snapshot tests).
  • tests/cli_m4_robot_envelopes.rs (10 cases, all green): launches the real openproxy binary via assert_cmd against a wiremock mock server, round-trips --robot stdout through serde_json, and asserts envelope shape. Covers happy paths for every M4 group plus the exit-6 / server_unreachable path.
  • src/cli/runtime.rs unit tests cover SSE frame extraction and RuntimeError → exit_code mapping.

Review & Testing Checklist for Human

  • Skim src/cli/runtime.rs — this is the dependency of every M4 command. Pay attention to how api_key is resolved (cfg → env → first active db.json key) and where streams disable the request timeout (stream_client()).
  • Spot-check one envelope: target/debug/openproxy --robot usage summary against a running server. Confirm shape is {schema, ok, data, error, meta}.
  • Confirm streaming UX: openproxy logs tail --follow and openproxy usage stream should run until Ctrl+C with no spurious disconnects. Server emits an SSE :keepalive ping every 25s.
  • Verify exit code: OPENPROXY_URL=http://127.0.0.1:1 openproxy --robot usage summary; echo $? → must print exit 6 with server_unreachable.
  • Run cargo test --test cli_m4_robot_envelopes locally — 10 tests should pass in <1s.

Notes

  • provider oauth is nested under provider (not top-level) because the M3 layout already groups everything provider-related under that namespace; the dispatcher in both main.rs and cli/mod.rs::Cli::run peels off the Oauth variant before falling through to run_provider (which still owns the DB-mode subcommands).
  • chat stream reads stdin via --prompt - (or accepts an inline --prompt "hello"); same for chat send.
  • quota reset is a thin alias over the observability clear endpoint — true per-key quota enforcement is a separate M6 task.
  • No DB schema changes. No web UI changes.
  • Insta is included but no golden snapshots are written yet — adding them is a friction-level cleanup item from the PLAN, deferred until the schema surface stabilizes after M5/M6.

…der oauth (25 cmds)

Adds an HTTP runtime client (src/cli/runtime.rs) that resolves the local
server endpoint from CLI flags, pid sidecar, or default port, probes
/api/health with exit code 6 on failure, and provides GET/POST/SSE
helpers (no client-side timeout for streams). All M4 subcommands speak
through it.

New top-level commands:
- usage: summary, daily, chart, history, stats, providers, logs,
  request-logs, stream (SSE → NDJSON), pricing
- logs: tail (--follow → SSE), export, clear, stats
- quota: list, get, reset, refresh (built atop /api/usage/providers)
- chat: models, tags, send, stream (POST SSE → NDJSON)

Nested under `provider`:
- provider oauth: start, poll, status, refresh, import-kiro,
  iflow-cookie, gitlab-pat

Server-side support:
- Re-introduces /api/observability/{logs,stream,stats,clear} backed by
  the existing console-log broadcast channel, requiring api-key auth
  so CLI sessions can subscribe.
- Relaxes /api/usage/stats and /api/usage/stream from dashboard-session
  to usage-access auth so CLI keys can read live counters.

Schema list / show / example now covers the new envelope shapes
(openproxy.v1.{usage,log,chat}.event, quota, oauth.status), so agents
can introspect without browsing the dashboard.

Test infra:
- assert_cmd + wiremock + serde_json round-trips through the real
  openproxy binary against a mocked server (tests/cli_m4_robot_envelopes.rs,
  10 cases, all green).
- Existing src/cli/runtime.rs unit tests cover SseFrames parsing and
  error-code → exit-code mapping.
- New dev-deps: assert_cmd, predicates, insta (for future golden snapshots).
@quangdang46 quangdang46 merged commit 74fa571 into main May 12, 2026
3 checks passed
@quangdang46 quangdang46 deleted the devin/1778563448-cli-m4-observability-runtime branch May 12, 2026 06:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant