Skip to content

fix(onboarding): the dashboard stays empty for 30s after the first-run overlay closes #3109

Closed

Description

@obasilakis

What happens

On a fresh marketplace install: claim the admin at /setup, complete every step of the first-run overlay, and the dashboard Timeline shows no agents. They appear about 30 seconds later, or immediately on a manual refresh.

Reproduced on a clean Vultr one-click install (image sha-128a0f6). Four agents existed server-side the whole time — the acme trio plus Cornelius — seeded by the backend during /setup completion.

Why

Four separate gaps, each of which alone would be enough:

  1. The dashboard store has no agent_created handler. stores/network.js:672-712 dispatches on agent_collaboration, agent_status, agent_started, agent_tags_changed, agent_label_changed, agent_deleted and agent_activity. Nothing for a created agent.

  2. The broadcast could not be caught even if it were. services/agent_service/crud.py:2277 emits {"event": "agent_created", "data": {...}} with no type key, and that dispatcher keys on data.type. The agent_deleted branch at network.js:706 is already dead for the same reason (routers/agents.py:702, :800). Events that do work — agent_started, agent_stopped, agent_label_changed — deliberately send both keys.

  3. Two stores, two websocket connections, one listener on the wrong one. utils/websocket.js:124-130 does handle agent_created, and writes to stores/agents.js. The dashboard and Timeline read stores/network.js.

  4. The overlay refetches three stores and no agent list. FirstRunOverlay.vue:375-382 forces loadFeatureFlags, fetchUserProfile and firstRun.fetchState after every step; close() at :303-316 refetches nothing. Dashboard.vue:510 mounts it with no close handler — unlike the create modal two hundred lines below at :683-686, which does exactly the missing thing:

function onCreateModalClose() {
  showCreateModal.value = false
  networkStore.fetchAgents()
}

The only thing that recovers is the 30-second poll at stores/network.js:1367-1403, which correctly detects additions. That is why the wait works and why it takes half a minute.

Related

ActivationChecklist.vue:146-155 fixed the sibling surface — the getting-started checklist not updating without a reload. It works because it watches agentsStore.agents.length, and agentsStore is the store the websocket actually feeds. stores/network.js has no such feed to watch.

Suggested scope

  • Refetch agents when the overlay closes, matching onCreateModalClose.
  • Add an agent_created handler to stores/network.js.
  • Make the backend broadcast carry type alongside event, which also revives the dead agent_deleted branch.

The last two are worth doing together; a fix to only the overlay leaves any server-side agent creation invisible to an open dashboard.

Activity

  1. dolho commented on Oct 1, 2026

    @dolho
    Contributor

    /claim

  2. github-actions commented on Oct 1, 2026

    @github-actions

    Claimed by @dolho. Label status-in-progress added.

    Next steps:

    1. Create branch: feature/3109-<short-slug>
    2. Implement the feature
    3. Open a PR with Fixes #3109
  3. dolho commented on Oct 1, 2026

    @dolho
    Contributor

    Fixed in #3158. Today's Workspace fixes, tested together on a local dev stack and reviewed

    This issue: PR #3158.

    • Closing the first-run overlay now refetches the agents.
    • stores/network.js handles agent_created by refetching through the REST list.
    • agent_created / agent_deleted now carry type, which also revives the dead agent_deleted branch.

    Live, with the dashboard open: a new agent appeared after 0.53 s instead of up to 30 s.

    Local verification, 2026-10-01

    The frontend was built from dev + all five PRs; they merge together cleanly. It ran against a local backend carrying the two backend fixes. All checks were in light and dark, with 0 page errors.

    PR Fixes Result
    #3158 #3109 dashboard empty after first-run ✅ created agent visible after 0.53 s, deleted one gone after 0.52 s
    #3148 #3001 "doesn't report steps" ✅ real turn: 42 samples, live line in 4, 0 containing the sentence
    #3155 #3139 client sees others' runs ✅ two portal clients on one agent: each sees only their own turn (1 and 2 rows, the 2nd being a seat brief); the platform sees all 18. Stats totals match the rows
    #3156 #3140 composer under a URL you can't open ✅ foreign chat → "This chat isn't available"; off-roster agent → "You don't have access"; no composer on either; own agent and chat still open
    #3157 #3135 [object Object] tooltip ✅ badge reads "Shadowed by: Team catalog, Vendor pack" (library response stubbed in the browser, since the instance's library isn't synced)

    The test clients, runs and agents were removed afterwards.

    Review (/review, posted on each PR)

    0 critical findings across the five. Informational notes are on each PR. The most useful:

    Every PR carries a regression test that fails with its fix reverted. CI: no failures; #3157 and #3158 were still running when this was posted.

    Separate observation (not from these PRs)

    On every backend reload the default system seed retries and logs Default system seed FAILED … Agent already exists for the acme trio. It has done so since at least 10:07 today, before any of these changes. It's harmless, but it's noise worth its own issue if it reproduces on a clean install.

  4. added
    status-in-devMerged to dev, awaiting release cut to main
    and removed on Oct 1, 2026
  5. removed
    status-in-devMerged to dev, awaiting release cut to main
    on Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions