Sessions and runs
The SR&ED workspace is built on top of projects, sessions, persisted message history, and explicit run execution.
Endpoint map
| Endpoint | Purpose |
|---|---|
POST /api/v1/projects | Create a project |
GET /api/v1/projects | List current user projects |
GET /api/v1/projects/{projectId} | Fetch one project |
PATCH /api/v1/projects/{projectId} | Update project fields such as name, description, or status |
DELETE /api/v1/projects/{projectId} | Delete a project |
POST /api/v1/projects/{projectId}/sessions | Create a session |
GET /api/v1/projects/{projectId}/sessions | List sessions in a project |
GET /api/v1/projects/{projectId}/sessions/{sessionId} | Fetch one session |
PATCH /api/v1/projects/{projectId}/sessions/{sessionId}/status | Update session status |
PATCH /api/v1/projects/{projectId}/sessions/{sessionId}/title | Rename a session |
DELETE /api/v1/projects/{projectId}/sessions/{sessionId} | Delete a session |
GET /api/v1/sessions/{sessionId}/history | Fetch chronological session history |
POST /api/v1/sessions/{sessionId}/runs | Execute an AI run for a session |
Typical flow
- Create or select a project
- Create a session for that project
- Upload and wait for files to become
READYif file context is needed - Submit a run for the session
- Read the latest assistant output from the returned message IDs or reload history
Project creation and updates
Project creation accepts:
json
{
"name": "Project name",
"fiscalYear": "2025",
"description": "Optional description"
}Project patch requests are partial and can update:
namefiscalYeardescriptionstatus
Session creation
Session creation accepts:
json
{
"type": "PRECHECK",
"title": "Optional title"
}The backend session types are currently:
PRECHECKT661T661_GENT661_DRAFTT661_ANALYSISLOGBOOK
The frontend may present broader UI types and map them into the supported run set before calling the backend.
History retrieval
History is available at:
GET /api/v1/sessions/{sessionId}/history?limit=50
Important behavior:
- the backend clamps
limitinto0..200 - messages are returned in chronological order
- only
USERandASSISTANTmessages are included in the returned DTO
Run request
Run execution accepts a request with these fields:
json
{
"type": "T661",
"input": "User prompt or guided intake output",
"selected_file_ids": ["uuid-1", "uuid-2"],
"history_limit": 10
}Important behavior:
typeandinputare requiredhistory_limitdefaults to10history_limitis clamped to0..50- file attachment is strict: if
selected_file_idsis empty or omitted, no files are attached implicitly - every selected file must belong to the project and be in
READYindex state
What happens during a run
AgentRunService currently does this:
- verifies session ownership
- reserves AI-run quota
- loads bounded session history
- validates selected files
- persists the new user message
- attaches signed R2 download URLs for selected files
- attaches project-scoped GitHub runtime access when available
- sends the task envelope to the Python worker
- persists the assistant result as a message
- confirms or cancels quota reservation
If the Python call fails, the backend returns a structured failed result and rolls the quota reservation back.
Run response
The run response contains:
| Field | Meaning |
|---|---|
runId | Backend-generated run UUID |
python | Raw Python worker result payload |
messages.userMessageId | Persisted user message UUID |
messages.assistantMessageId | Persisted assistant message UUID |
selectedFileIds | File IDs attached to the run |
Use the history endpoint or the stored message IDs to reconcile chat state after a run.