Progress Tracking
How get_plan_status computes progress percentage, surfaces stall warnings, returns derived status, and breaks down step states.
Progress tracking gives the AI platform and administrators visibility into where a research plan stands. The primary tool is get_plan_status, which combines stored plan state, derived status from step states, stall detection, and step-level breakdowns into a single response.
get_plan_status Response
The tool returns a JSON object with these fields:
| Field | Type | Description |
|---|---|---|
planId | string | The plan identifier |
name | string | Human-readable plan name |
status | string | Stored plan status from the database |
derivedStatus | string | Computed status from derivePlanStatus based on current step states |
stalled | boolean | Whether any step exceeds the stall threshold (see Stall Detection) |
progress | number | Percentage of steps completed or skipped (0-100, rounded) |
totalSteps | number | Total number of steps in the plan |
currentStep | object | null | The step currently in_progress or awaiting_input, if any |
completedSteps | array | Steps with completed or skipped status, including result summaries |
pendingSteps | array | Steps still in pending status |
Stored vs. Derived Status
The response includes both status (the value stored in research_plan.status) and derivedStatus (computed by derivePlanStatus from current step states). These can diverge temporarily -- for example, if a plan is marked stalled in the database but all its steps have since been completed. The derived status is the more accurate representation of the plan's actual state.
Progress Calculation
Progress is computed as the ratio of terminal steps to total steps:
const completedSteps = steps.filter((s) => s.status === "completed" || s.status === "skipped");
const progress = steps.length > 0 ? completedSteps.length / steps.length : 0;
// Response: Math.round(progress * 100)
Note that only completed and skipped steps count toward progress. Steps with failed status do not contribute to the progress percentage, even though they are terminal states for the purpose of derivePlanStatus. This means a plan where every step has failed shows 0% progress but a derived status of completed.
Step Breakdowns
The response partitions steps into three categories:
completedSteps includes both completed and skipped steps, ordered by step_order:
{
"stepId": "...",
"stepOrder": 2,
"stepType": "analyze",
"status": "completed",
"resultSummary": { "key findings": "..." },
"confidence": 0.85
}
currentStep is the single step in in_progress or awaiting_input, or null:
{
"stepId": "...",
"stepOrder": 3,
"stepType": "synthesize",
"status": "in_progress"
}
pendingSteps are steps not yet started:
{
"stepId": "...",
"stepOrder": 4,
"stepType": "checkpoint"
}
list_active_plans
The list_active_plans tool returns all non-terminal plans (status not completed or failed) for the user's organization. Each entry includes a progress percentage, computed the same way as get_plan_status. This gives the AI platform a quick overview of ongoing work when starting a new session.
Admin Dashboard Integration
The research plans view in the admin dashboard uses the same progress calculation and stall detection logic. It displays:
- All plans with their status and progress bars
- Stall warnings for plans with stuck steps
- Step-by-step breakdowns with timing information
- Audit log entries for each plan
Related Pages
- Stall Detection -- how the
stalledboolean is computed - State Machines -- how
derivePlanStatusworks and why it may differ from stored status - Execution Loop -- the lifecycle events that drive progress changes
Execution Loop
The end-to-end flow from plan creation through step execution to completion, including human-in-the-loop review and cross-session resume.
ADR-010: MCP-First Architecture + Plan Engine
Decision record for the MCP-first research architecture with a custom PostgreSQL-backed plan engine over server-side LLM orchestration or off-the-shelf workflow frameworks.