feat: DeepSeek as a first-class provider pool - #44
Open
atyrode wants to merge 7 commits into
Open
Conversation
Restructure the two-pool (OpenAI/Anthropic) assumptions into a provider registry so DeepSeek joins routing, usage, and account management as data, not code surgery. - providers.go: single registry table (pools, lanes, labels, colors, buckets, metered/required, special tiers); ordered fallback and advisor pool lists replace every otherPool() flip. - Catalog: __models__ grows a provider column (5/6/7-token rows all parse); the lane facet is catalog-driven, ds-led/ds-only lanes appear only when the catalog carries a D pool. - Generator: N-pool genCombo with pool-set validity, optional-pool ladder fill (one verified D rung is enough), relief tails on heavyweight led/mixed chains, vision purity exception, per-pool advisor tables; generate init scaffolds and bench-probes DeepSeek. - Usage: DeepSeek prepaid balance fetched concurrently with the broker snapshot, rendered as its own group (no bar/reset), cached by value only; api_key never serialized, account pool stays OAuth-only; manager shows display-only API-key rows. - omp catch-up: security-reviewer routed like reviewer everywhere; omp --version probe gates task.agentAdvisor emission (>= 17.3). Two-pool output stays byte-identical outside the __models__ provider column and the security-reviewer rows; goldens pin both.
The account manager's DeepSeek box showed only the display-only API-key row; the prepaid balance - its single usage datum - lived in the Usage panel alone. Mirror deepseekBalanceRow under the credential, including the unavailable/stale degrade, so v answers 'how much is left' too.
…ricing, thinking gauge Design round 2 with the operator (2026-08-14): - relief dial: catalogs with an optional pool double their metered-led blends into _rel/_norel variants; off strips exactly the pay-as-you-go tail. The segment (and dial) exist only in such catalogs, so two-pool output stays byte-identical and old ids keep resolving. - quota-aware lane suggestion: deriveToggles moves a proposal off a lane whose lead pool is maxed/unauthed to the first sibling led lane with headroom (fallbackPoolOrder), gated for DeepSeek by the prepaid balance. Manual dials are never rewritten. - balance guard: under $2 the balance row warns 'low', suggestions stop proposing ds lanes and turn relief off. Unknown balance counts as dry. - off-peak pricing: DeepSeek rungs cost 50% in the meter during UTC 16:30-00:30 and the balance row carries the live discount tag. The classifier deliberately does not chase the discount: spending money while metered quota is free stays an operator decision. - thinking gauge: the six-word dial renders as a level meter with the selected word beside it; arrow behavior and persistence unchanged.
…l/thinking Operator feedback on round 2: - The 7-value lane row overflowed the pane and read as too many choices. It now renders as a lead dial (gpt / mixed / claude / ds - one entry per pool the catalog carries) with a led|only blend child, hidden for mixed. sel["lane"] stays the canonical persisted value: lead/blend are derived in visibleFacets, recomposed in cycleFacet, and filtered from persistence by the facet list. - The half-height bar gauge clashed with the pane's text height. Both the thinking and model dials now draw a notched meter (one segment per step) with the selected word beside it. Arrow behavior, facet values, ids, and persistence are all unchanged.
- Both notched dials now share a fixed 6-cell track (model spans two cells per step), so the meters and the words after them sit in one column; a leading space matches the word dials' cell padding. - mixed anchors the lead dial's left edge: it is the default and the only lead without a blend child.
- The relief row now carries a dim state-specific note ('drained chains
spill into DeepSeek' / 'drained chains wait for quota reset') - it was
the one dial whose effect was unreadable from the pane.
- audit is the advisor's heavyweight setting, so it now follows the same
metered logic as the heavyweight roles: with relief on, a metered-led
blend's audit chain ends on each optional pool's audit rung (glance and
review stay short; optional-led and pure lanes are untouched). The tail
flows into both the preview and the launch overlay via applyAdvisor.
- Every gauge now has exactly as many cells as it has selectable options: model ▰▰▰ (3), thinking ▰▰▰▱▱▱ (6), advisor ▰▱▱ (3) - the shared 6-cell track width is gone. - advisor's leading 'off' is the dial's zero: it takes no cell, so off renders an empty track and each level lights exactly one.
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.
Restructures the hard two-pool (OpenAI/Anthropic) assumptions into a provider registry so DeepSeek becomes a first-class pool across routing, usage, and account management — and catches up with omp 17.3 (security-reviewer role,
task.agentAdvisor).What changed
providers.go(new) — single registry table: pool letters, lane names, product/account labels, brand + paint colors, model prefixes, bucket bases,Metered/Required, skeleton windows, special tiers (spark@O0, fable@A4), service tiers. OrderedfallbackPoolOrder(O→A→D) andadvisorPoolOrder(A→O→D) replace everyotherPool()binary flip. Provider-id literals now live only here and in tests.__models__grows a trailingprovidercolumn; the parser accepts 5/6/7-token rows, so old catalogs keep working. The lane facet is catalog-driven:ds-led/ds-onlyappear only when the catalog carries a D pool; pre-catalog runs keep the classic five lanes.genCombo: pool-set validity (spark/fable gated on the lane hosting their pool), optional-pool ladder fill (one verified DeepSeek rung is enough; missing tiers borrow the nearest), relief tails (D tier-2 appended to heavyweight led/mixed chains), vision purity exception (ds-only crosses for images since DeepSeek is text-only), per-pool advisor tables.generate initscaffolds the D pool when candidates exist and bench-probes deepseek; the "need 3 rungs" error applies to Required pools only.GET api.deepseek.com/user/balance) fetched concurrently with the broker snapshot; rendered as its own group (balance $X USD · pay-as-you-go, no bar/reset — absent key is the normal state, not an error); stale values retained visibly on refresh failure; cache stores value+timestamp, never the key.api_keycredentials stay in memory only — never serialized to usage cache or account state; the account pool remains OAuth-only. Manager shows display-onlyAPI key · credential #Nrows (cursor-skipped).security-reviewerrouted exactly likereviewer(deliberative, cross-led, mirrored intotask.agentModelOverrides, meter-weighted). Asyncomp --versionprobe gatestask.agentAdvisor: {task: "on"}emission (advisor=audit AND omp ≥ 17.3); lagging wrappers never see the key.Compatibility
__models__provider column and the security-reviewer rows — pinned byTestGoldenCatalogTwoPoolagainsttestdata/two-pool-golden.plain.CODE_*env contract unchanged.Verification
gofmt/go vet/go test ./...green (30 new tests: three-pool goldens, one-rung optional pool, balance fetch contract + degrade paths, key-secrecy, ds-lane overlay YAML, lane-dial growth, usage-group rendering).omp auth-broker login deepseek→generate init --refresh→ ds-led session) — no DeepSeek credential on the dev machine.