mirror of
https://github.com/razzant/ouroboros.git
synced 2026-10-03 04:07:04 +00:00
fix(onboarding): do not latch Finish after a refused Main reviewer recovery
A refused "Use Main for reviewers" preview left skipSubscriptionPresets set, so the ordinary Finish path stayed blocked for the rest of the session and the packaged setup window has no reload to escape. Roll the flag back when the preview is refused, keep the recovery button offered, and pin the path with a browser test that refuses once, checks Finish is not latched, then retries successfully. Co-authored-by: Ouroboros <311266734+ouroboros-agent@users.noreply.github.com>
This commit is contained in:
parent
472f8c5cc7
commit
0a8bbdcce4
2 changed files with 47 additions and 1 deletions
|
|
@ -76,6 +76,11 @@ def subscription_ui():
|
|||
result = backend["preview_client"].post(path, json=payload)
|
||||
route.fulfill(status=result.status_code, content_type="application/json", body=result.text)
|
||||
return
|
||||
if backend.get("recovery_error") and payload.get("skipSubscriptionPresets"):
|
||||
route.fulfill(status=400, content_type="application/json", body=json.dumps({
|
||||
"ok": False, "error": "Reviewer recovery unavailable.", "detail": backend["recovery_error"], "saved": False,
|
||||
}))
|
||||
return
|
||||
if backend.get("preview_error") and not payload.get("skipSubscriptionPresets"):
|
||||
route.fulfill(status=503, content_type="application/json", body=json.dumps({
|
||||
"ok": False, "error": "Automatic assignments unavailable.", "code": "models_unavailable",
|
||||
|
|
@ -431,6 +436,39 @@ def test_failed_preview_allows_manual_main_and_visible_reviewer_recovery_before_
|
|||
assert row['route']['profile_id'] == 'personal'
|
||||
|
||||
|
||||
def test_failed_main_reviewer_recovery_does_not_latch_finish(subscription_ui):
|
||||
# A refused recovery preview must leave the wizard on its ordinary path:
|
||||
# the packaged setup window has no reload, so the owner needs both the
|
||||
# normal Finish and a working Use Main retry after the backend refuses once.
|
||||
ui, page = subscription_ui, subscription_ui['page']
|
||||
ui['backend'].update(preview_error='Agent model discovery unavailable.',
|
||||
recovery_error='A Main account pin requires a managed model source.')
|
||||
page.goto(ui['url'] + '/onboarding')
|
||||
page.wait_for_selector('#next-btn:not([disabled])')
|
||||
page.click('#next-btn')
|
||||
main = page.locator('[data-model-role="main"]')
|
||||
main.locator('[data-model-role-source]').select_option('subscription:codex')
|
||||
main.locator('[data-model-role-model]').fill('owner-main')
|
||||
for _ in range(3):
|
||||
page.click('#next-btn')
|
||||
page.wait_for_selector('#skip-presets-btn:not([hidden])')
|
||||
page.click('#skip-presets-btn')
|
||||
page.wait_for_function("() => document.querySelector('.wizard-error').textContent.includes('managed model source')")
|
||||
page.wait_for_selector('#skip-presets-btn:not([hidden])')
|
||||
page.click('#next-btn')
|
||||
page.wait_for_function("() => document.querySelector('.wizard-error').textContent")
|
||||
assert 'Use Main for reviewers to prepare' not in page.locator('.wizard-error').inner_text()
|
||||
assert not any(path == '/api/onboarding/complete' for path, _ in ui['posts'])
|
||||
ui['backend'].pop('recovery_error')
|
||||
page.click('#skip-presets-btn')
|
||||
page.wait_for_function("() => document.querySelector('.wizard-inline-note')?.textContent.includes('Reviewers were assigned to Main')")
|
||||
page.click('#next-btn')
|
||||
page.wait_for_url(ui['url'] + '/')
|
||||
bodies = [body for path, body in ui['posts'] if path == '/api/onboarding/complete']
|
||||
assert len(bodies) == 1 and bodies[0]['skipSubscriptionPresets'] is True
|
||||
assert bodies[0]['OUROBOROS_MODEL'] == 'claudexor::codex=owner-main'
|
||||
|
||||
|
||||
@pytest.mark.parametrize('http_status', [200, 500])
|
||||
def test_accounts_catalog_failure_is_visible_and_retry_keeps_the_draft(subscription_ui, http_status):
|
||||
ui, page = subscription_ui, subscription_ui['page']
|
||||
|
|
|
|||
|
|
@ -1492,8 +1492,16 @@ import { accountRowFacts } from './harness_accounts.js';
|
|||
if (disposed) return;
|
||||
state.preparingRecovery = false;
|
||||
state.recoveryPrepared = Boolean(ready);
|
||||
if (ready) state.recoveryMain = mainBinding();
|
||||
state.error = ready ? '' : agentsStep?.previewError || 'Reviewer assignments could not be prepared. Retry before saving.';
|
||||
if (ready) {
|
||||
state.recoveryMain = mainBinding();
|
||||
} else {
|
||||
// A failed recovery must not latch the wizard out of its ordinary
|
||||
// path: the desktop setup window has no reload, so the owner keeps
|
||||
// the normal Finish and the still-offered Use Main retry.
|
||||
state.skipSubscriptionPresets = false;
|
||||
void agentsStep?.setSkipPresets(false);
|
||||
}
|
||||
render(); // Show the recovered assignments; only the next explicit Start saves.
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue