Repository navigation
fix: treat a repository model as an own model for quota - #733
Conversation
HugoXK-bot
left a comment
There was a problem hiding this comment.
Verdict: PASS at e488223
Written-by: HugoXK-bot
Author: Fledge Platform Reviewer
Posted-by: HugoXK-bot
T3 quota change: a repository model selection counts as the user's own model, so a job that will run on that selection is no longer treated as platform-funded (and is no longer refused for an exhausted platform quota).
Reviewed at the tip: src/app.ts, src/jobs/service.ts, src/views/checklist.ts, src/views/pages.ts, test/jobs.test.ts, test/nextAction.test.ts, test/nextScheduledRun.test.ts, test/setupChecklist.test.ts, docs/quota.md, docs/architecture.md, changelog. 11 files, +146/−21.
What I checked:
- one predicate, two call sites:
platformFundedFor()(src/jobs/service.ts:58-68) is!legacyOwnModel && listRepoModelSelection(repoId).length === 0, and both the enqueue check (:1008-1011) and the run-time check (:3144-3147) now use it. That is the same row set the gateway resolves (src/gateway/gateway.ts:165,:222) and the bridge patches from (src/flybot/instances.ts:374,:416), so the three cannot disagree about who pays. legacyOwnModelis the exact negation of the old condition (own_llm_base_urlnon-empty andown_llm_key_encnon-null), so the pre-existing user-level model keeps its old behaviour.- the checklist separates
providerConfigured(a provider has a model) frommodelConfigured(a repository can actually run on an own model) (src/views/checklist.ts:11-30,:73-98). A provider that no repository selected now names the missing action "Choose a model for the repository" and links to the repository, instead of claiming the step is done; the instance blocker names the same missing action. src/views/pages.ts:837-845only shows the platform-quota card when the setup has no own model, which is the same distinction; a user with an own model is not told to add one.- the route-level test creates a provider, asserts
data-setup-next="model", then sets the selection and assertsdata-setup-next="instance"— it tests the wiring, not only the pure function.
Ran (this turn, at this tip):
npx tsx --test test/jobs.test.ts test/nextAction.test.ts test/nextScheduledRun.test.ts test/setupChecklist.test.ts— pass 135/135
Red half (same four suites against base b0adcc5f): 130 pass / 5 fail, first failure not ok 9 - a repository model bypasses the platform quota check in enqueue and dispatch, plus 107, 123, 125, 131.
Merge-order note (not a finding against this tip): #731 edits the same setupChecklist model step, app.ts setup block and nextAction.test.ts at base b0adcc5f. Whichever lands second will conflict; merge one, then have the other rebased and re-judged at the new tip rather than resolving the conflict by hand. The two intents are compatible (platform funding vs own model are two ways to satisfy the same step) but the combined predicate must keep both.
Not run: a real own-provider call; the suite drives the gateway with fakes.
Conclusion: PASS — the paying party is decided by one predicate shared with the gateway and bridge, the checklist names the real missing action, and the quota card follows the same rule.
e488223 to
219ee3f
Compare
HugoXK-bot
left a comment
There was a problem hiding this comment.
Verdict: PASS at 219ee3f
Written-by: HugoXK-bot
Author: Fledge Platform Reviewer
Posted-by: HugoXK-bot
Re-judged at the forward-merged tip. My earlier PASS 5908787902 bound e48822384ea4 and is void at this tip; this review reads the merge resolution, not the old conclusion.
T3 quota change (#732): a repository model selection is an own model for quota purposes. The merge brought main up to d1a91cd2 and had to combine this change with #731's platform-quota model step.
Reviewed at the tip: 11 files, +155/−26 against live fc6825c6; the change itself is src/app.ts, src/jobs/service.ts, src/views/checklist.ts, src/views/pages.ts, four test files, docs/quota.md, docs/architecture.md, changelog.
What I checked in the merged result:
- the two ways to satisfy the model step now compose instead of fighting:
done: state.modelConfigured || state.platformAvailable,optionalonly when the platform funds and no own model exists, and the "Choose a model for the repository" title only when a provider exists, no repository selected it, and the platform cannot fund (src/views/checklist.ts:78-113). The instance blocker is!modelConfigured && !platformAvailable, so neither half is dropped by the resolution. - the quota path is unchanged by the merge:
platformFundedFor()(src/jobs/service.ts:58-68) is still shared by enqueue and dispatch, andsrc/views/pages.tsstill shows the quota action only when no own model exists. jobs: jobsTotalremains main's value at this base (#735 is a separate, unmerged PR; this branch does not anticipate it). No setup field is duplicated by the merge.- the unrelated main changes the merge carried in (memory audience, recent-auth, asset versioning) are main's own and are not modified by this PR.
Ran (this turn, at this tip):
npx tsx --test test/jobs.test.ts test/nextAction.test.ts test/nextScheduledRun.test.ts test/setupChecklist.test.ts— pass 139/139 (the extra four over the old tip are #731's platform-quota tests, now running together with #732's)
Not run: a real own-provider call; the suites drive the gateway with fakes.
Sequencing note: this tip is behind live main by #736, #737 and #741; two of them touch src/views/pages.ts, the same file this PR edits. The tip's ci-ok therefore did not exercise the combined tree. If a forward-merge lands to catch up, this PASS dies at the new tip and I re-judge it; if the merge queue runs the checks on the merge result, the current tip is green and this PASS stands.
Conclusion: PASS — the merge resolution keeps both the own-model and platform-quota paths intact, and the combined suites pass.
219ee3f to
930e2e3
Compare
930e2e3 to
09cbad8
Compare
HugoXK-bot
left a comment
There was a problem hiding this comment.
Verdict: PASS at 09cbad8
Written-by: HugoXK-bot
Author: Fledge Platform Reviewer
Posted-by: HugoXK-bot
Re-judged at the current tip. My earlier PASSes bound e48822384ea4 (5908787902) and 219ee3f8b559 (5908828974); both are void at this head, and this review reads the rebased tree.
T3 quota change (#732): a repository model selection counts as an own model, and the platform-satisfied model step shows the remaining balance.
Reviewed at the tip (against ada57f6): 17 files, +311/−39 — src/app.ts, src/config.ts, src/jobs/service.ts, src/views/checklist.ts, src/views/pages.ts, public/app.css, five test files, docs, changelog.
What I checked:
- the rebase kept #735's fix:
jobs: setupJobsTotal(the unfiltered account count) is still whatsetup.jobsreceives (src/app.ts:1244,:1265), so the filteredjobsTotaldid not come back with the merge. - the two ways to satisfy the model step compose:
done: modelConfigured || platformAvailable,optionalonly when the platform funds and no own model exists, and the "Choose a model for the repository" title only when a provider exists, no selection, and the platform cannot fund (src/views/checklist.ts:78-113). The instance blocker checks both halves. - the quota decision is one predicate shared by enqueue and dispatch (
platformFundedFor,src/jobs/service.ts:58-68), and the dashboard quota card is suppressed only when an own model exists (src/views/pages.ts:837-845). - the new comfort threshold is a config value, not a second default:
quota.comfortCnyfromPLATFORM_QUOTA_COMFORT_CNY(default 50,src/config.ts:321-324), read by the checklist asstate.platformQuotaComfortCny;docs/quota.md,docs/deploy.mdand.env.exampleall name it. - the tip is now
mergeable: trueagainst livemainand no longer dirty; the merge that moved it kept both #735's count and this change.
Ran (this turn, at this tip):
npx tsx --test test/jobs.test.ts test/nextAction.test.ts test/nextScheduledRun.test.ts test/setupChecklist.test.ts— pass 145/145
Not run: a real own-provider call; the suites drive the gateway with fakes.
One non-blocking product question, worth confirming rather than blocking: the default initial platform quota is 1 CNY (INITIAL_QUOTA_CNY default 1) while the comfort threshold defaults to 50 CNY, so a brand-new account — whose first run the platform is supposed to fund — always lands in the "balance may not cover the first run" warning on a step that is marked done. If that is deliberate (a first run really can cost more than 1 CNY), fine; otherwise the default threshold should sit below the initial quota, or the sentence should state the remaining balance without predicting what it covers. The note itself is only advisory and does not block the run or the step.
Conclusion: PASS — the rebase preserves the platform and own-model paths and #735's unfiltered count, the threshold is one config knob, and the combined suites pass.
Written-by: HugoXK
What changed
A provider model selected for a repository now counts as an own model everywhere Fledge decides whether a job is platform-funded. The first-run model step is completed by a repository selection rather than by a provider row; when a provider exists but no repository has selected it, the step links to the repository picker. The dashboard no longer shows the exhausted-quota action to a user who has a usable own model, and both the enqueue and dispatch quota checks treat a repository selection as non-platform-funded.
The platform-satisfied model step now also shows the remaining platform balance. Below
PLATFORM_QUOTA_COMFORT_CNY(default 50, configurable in.env) it warns that the balance may not cover the first run and offers an immediate "add your own model" or "choose a repository model" action. At the threshold or above (or when unlimited) it only names the remaining balance and points at Settings → Model for later configuration. The threshold changes the advice only, never quota accounting.Fixes #732
Why
src/gateway/gateway.tsand the bridge already resolve the repository's selected model, butsrc/app.tscounted any provider row as a configured model, andsrc/jobs/service.tsdecidedplatformFundedfrom the legacyusers.own_llm_*fields only. A repository with a selected model was therefore refused withQUOTA_EXHAUSTEDbefore the gateway was called, the dashboard kept asking for a model that existed, and adding a provider in Settings could mark the model step done without the repository ever using it.The default 1 CNY platform quota also looked like a comfortable default. A first run can spend that quickly, so the checklist now says how much is left and, below the configured threshold, recommends the own-model path instead of silently skipping the step.
Verification
Ran:
npm run check— pass (1842 tests, typecheck, build)node scripts/version.mjs check— 0.3.6 oknode scripts/changelog.mjs check— passNot run:
Security notes
The quota pre-check now reads
repo_model_selection; a repository-selected model is no longer refused as platform-funded. The gateway still applies the repository's provider policy, SSRF guard and metering for that model. No token, secret or quota accounting format changed.PLATFORM_QUOTA_COMFORT_CNYchanges the checklist advice only.Note
Rebased onto the current
main. #735 and #745 have since merged; this branch includes both tips. No further overlap is expected.