research: wire start_topic to actually run the pipeline
ci / gates (push) Successful in 7s
ci / frontend (push) Successful in 25s
ci / rust (push) Successful in 3m4s
ci / e2e (push) Has been skipped
ci / publish (push) Successful in 2m34s

The prior start_topic only flipped the status column — no work was
enqueued. Now clicking "Start research" actually launches the
assigned agents through the orchestrator.

- start_topic loads the topic + its research_topic_agents, picks a
  coordinator (first slot with role_slot containing "coordinator";
  else the first slot), and swaps it to index 0.
- Builds a hub_spoke topology graph via cm_topology::build with
  roles = [coordinator, spoke1, spoke2, …]. hub_spoke wires edges
  from the hub to every spoke and back, so the coordinator can
  address any specialist per turn.
- Assembles a coordinator prompt from the topic's title,
  description, outcome_kind, and a roster line for each teammate —
  so the coordinator knows who's on the team and what each does.
- Enqueues via a new topology_runs helper
  enqueue_run_for_research_topic that stores research_topic_id on
  the run row. `topology_worker::maybe_transition_research_topic`
  → `notify_run_completed` already picks up on that back-ref and
  flips the topic processing → reviewing when the last run
  terminates — that path was dead code until now.
- Per-agent activity streams into each claw's card for free:
  the orchestrator journals turn events into run_events; the
  existing /api/world/live SSE normalizer emits
  agent.reasoning.delta / agent.tool.call / agent.task.update
  keyed by agent id, which ClawCommandCenter is already
  subscribed to.

The `published` terminal state is still unreached (that's the
"publishing → published + artifact" step from the earlier
walkthrough — separate follow-up).
This commit is contained in:
Omar Sobh
2026-07-08 16:25:24 -07:00
parent 81a436d221
commit 7e2b02d8bb
2 changed files with 130 additions and 3 deletions
+27
View File
@@ -147,6 +147,33 @@ pub async fn enqueue_run_for_team(
Ok(())
}
/// Enqueue a durable run bound to a research topic. `research_topic_id` is
/// stored so `notify_run_completed` can flip the owning topic
/// `processing → reviewing` when its last run terminates (see
/// `topology_worker::maybe_transition_research_topic`).
pub async fn enqueue_run_for_research_topic(
pool: &PgPool,
id: Uuid,
workspace_id: WorkspaceId,
task: &str,
graph: &Value,
research_topic_id: Uuid,
) -> Result<(), DbError> {
sqlx::query!(
"INSERT INTO topology_runs
(id, workspace_id, task, kind, status, graph, tier, research_topic_id)
VALUES ($1, $2, $3, 'run', 'queued', $4, 'team', $5)",
id,
workspace_id.as_uuid(),
task,
graph,
research_topic_id,
)
.execute(pool)
.await?;
Ok(())
}
/// Result of `check_ephemeral_teardown` when this run's terminal completion
/// should tear down its team.
pub struct EphemeralTeardown {