feat(quantum): add sidebar dashboard with credits, jobs, and compute status#7
Open
Kenny-Heitritter wants to merge 12 commits intofeat/codeq-telemetryfrom
Open
feat(quantum): add sidebar dashboard with credits, jobs, and compute status#7Kenny-Heitritter wants to merge 12 commits intofeat/codeq-telemetryfrom
Kenny-Heitritter wants to merge 12 commits intofeat/codeq-telemetryfrom
Conversation
…status Add quantum resource dashboard to the TUI sidebar and footer: - QuantumState: centralized reactive store tracking credits balance, active jobs, and compute instance status via Bus events - QuantumPoller: Scheduler-based adaptive polling (credits/compute 60s, jobs 30s when active) with auto-detection of API key mid-session - QuantumSidebarSection: collapsible sidebar panel showing credit balance, active job rows with status dots and elapsed time, compute status - QuantumFooterIndicator: compact footer indicator (active QPU count) - Extended client.ts with getCredits (billing/credits/balance endpoint), getComputeStatus, listActiveJobs, and Zod schemas for validation - Fixed getCredits return type mismatch in estimate_cost tool - Tools (submit, cancel, get_result) trigger state refresh for immediate sidebar updates after quantum operations - Wired poller and initial refresh into InstanceBootstrap
- Move CreditsBalanceSchema and ComputeStatusSchema to the schema section at the top of client.ts, alongside QuantumDeviceSchema, QuantumJobSchema, and JobResultSchema - Remove redundant formatCredits branch (n >= 10 and default were identical)
…endency - submitJob: send deviceQrn+program instead of device+openQasm (API v1 schema) - state: use module-level singleton instead of Instance.state() so it works inside SolidJS reactive computations (no AsyncLocalStorage context there) - getDevice: unwrap data envelope for single-device API response - build: fallback to 'dev' channel when git is not available in PATH
…, and interference spinner - Add qBraid API key startup dialog (dialog-qbraid-auth.tsx) shown after telemetry consent on first launch, with sequence: consent → auth → provider connect - Fix quantum client wire format: correct auth header (X-API-Key), endpoint paths (/devices, /jobs, /billing/credits/balance), response unwrapping (.data), and Zod schemas with transforms for API normalization - Fix event timing race: register RPC listener during init() instead of onMount() to prevent lost events; add sdk.latest Map for event caching - Fix quantum sidebar: credits displayed as 'X credits' not dollars, updatedAt guard prevents stale events, cached event read on mount - Add interference/diffraction animation engine for quantum-themed spinner - Simplify telemetry consent dialog text and auth resolution - Add QBRAID_DEFAULT_API_URL constant with QBRAID_API_URL env var override - Add includeUsage flag for qBraid provider - Fix branding apply.ts URL replacement ordering - Normalize CodeQ → Codeq capitalization in comments - Add fork rationale documentation and build/smoke-test scripts
… tools Add 8 new tools for deep qBraid platform integration: - quantum_environments: list/search software environments (Qiskit, Cirq, CUDA-Q, etc.) - quantum_environment_packages: get full package list for an environment - quantum_compute_profiles: list available server configs (free to GPU) - quantum_compute_status: check if compute server is running - quantum_compute_start: launch a compute server (with permission prompt) - quantum_compute_stop: stop running server (with permission prompt) - quantum_account: show credits, AI chat quota, disk usage, org/subscription info - quantum_job_circuit: get ASCII circuit diagram for a submitted job Also adds queue depth, description, and modality to device schema for richer device listing output. All endpoints verified against live qBraid API v1.
Add quantum/jupyter.ts — new module for JupyterHub integration: - Session token resolution from qBraid API - Contents API: list, read, write files on remote server - Kernel WebSocket execution: start kernel, send execute_request, collect stdout/stderr, clean up kernel New tools (5): - quantum_remote_exec: execute Python code on cloud server - quantum_remote_files: list files on remote workspace - quantum_remote_read: read a file from remote server - quantum_remote_write: write a file to remote server - quantum_remote_kernels: list available Jupyter kernels The demo flow: start a compute server, write a quantum circuit, execute it remotely, get measurement results — all from the agent. Verified against live staging: session tokens, Contents API (201), and WebSocket kernel execution all working on lab-v2-staging.
Production (account.qbraid.com) requires Authorization: Bearer, while staging (pr-441 Cloud Run) requires X-API-Key. Send both headers so the provider works against either environment.
The AI provider was only reading the API key from the auth store (~/.local/share/codeq/auth.json), ignoring QBRAID_API_KEY env var. This meant staging couldn't override the key. Now QBRAID_API_KEY takes priority over the stored key, matching the quantum client.
Redesign compute state from single-instance to array of ComputeInstance, preparing for multi-server support via JupyterHub named servers. State changes: - State.compute (single object) -> State.instances (ComputeInstance[]) - ComputeInstance tracks: name, profile, status, clusterId, startedAt, rate, kernels count, and executing snippet Sidebar changes: - InstancesSection replaces ComputeSection, shows all live instances - Each instance row: colored status dot, profile name, uptime, cost rate, kernel count, and current execution snippet - Footer indicator shows both QPU job count and compute instance count Client changes: - listServers() calls new GET /compute/servers endpoint - startServer/stopServer accept optional serverName for named servers - refreshCompute tries listServers first, falls back to legacy status Tool changes: - compute_start optimistically shows instance in sidebar immediately - remote_exec tracks execution in sidebar (snippet + kernel count)
- compute_start: add optional name param for named instances - compute_stop: add optional name param to target specific instance - compute_status: use listServers to show all instances - remote_exec/files/read/write/kernels: add optional instance param - client.getSessionToken: pass serverName for named instances - All tool descriptions updated to reflect multi-instance capability
getDevice, submitJob, getJob, getResult were passing the full
{ success, data } envelope to Zod schemas instead of unwrapping
the inner data field first. This caused validation errors like
'expected string, received undefined' for fields like name/vendor/status.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
quantum/state.ts) usingInstance.state()for per-instance isolation, with Bus events for TUI reactivityDesign
Progressive disclosure — minimal when idle (just
⚛ qBraid $42.50in footer), expands when resources are active (shows job rows, compute status in sidebar section).Three pillars mirroring the qBraid account page:
/billing/credits/balance/jobs/compute/servers/status(management is future work)New Files
quantum/state.ts— Centralized state store withInstance.state(), Bus eventquantum.state.updated, refresh functions for credits/jobs/computequantum/poller.ts— Scheduler-based adaptive background polling withInstance.state()for per-instance timestamp trackingcli/cmd/tui/component/quantum-status.tsx—QuantumSidebarSection(collapsible),QuantumFooterIndicator(compact),useQuantumState()hookModified Files
quantum/client.ts— AddedgetCredits(),getComputeStatus(),listActiveJobs(),isConfigured(),CreditsBalanceSchema,ComputeStatusSchemaquantum/tools.ts— Added state refresh triggers after submit/cancel/get_result, fixedgetCreditsreturn typequantum/index.ts— AddedQuantumStateandQuantumPollerexportsproject/bootstrap.ts— AddedQuantumPoller.init()+QuantumState.refreshAll()callscli/cmd/tui/routes/session/sidebar.tsx— Added qBraid section between Context and MCPcli/cmd/tui/routes/session/footer.tsx— AddedQuantumFooterIndicatorbetween permissions and LSPArchitecture Patterns
Instance.state()for all per-instance state (matches all 25+ existing modules)BusEvent.define()with explicit Zod schemaz.object({})for signal eventsuseTheme()for typed RGBA color access (no type-erasing helper functions)Commits (2)
Stats
9 files changed, 546 insertions(+), 7 deletions(-)
Depends On