Summary
GET /api/v1/projects/<id>/results (SDK: get_project_results) signals extraction state implicitly, by the shape of the row. There is no status field, which makes correct polling harder than it should be and produces a silent, hard-to-debug failure mode for clients.
Observed shapes:
Why this bites
The natural poll is while result.get("paper") != done: sleep(). On success "paper" is absent, so .get("paper") returns None — identical to what a client sees for an in-flight job. I polled a finished extraction for 14 minutes believing it was still running, and earlier reported the service as broken partly on that basis. The values were sitting in the response the whole time.
It is also awkward that a feature identifier could collide with a reserved key (a feature named paper would be indistinguishable from the failure marker).
Suggested fix
Add an explicit, always-present status and nest the extracted values, e.g.:
Even just adding "status" alongside the current shape (keeping the rest for backwards compatibility) would remove the ambiguity entirely.
Related
check_task_status(task_id) returns None for the UUID task ids that upload_paper() hands back, so it can't be used to poll either — status is only observable via get_project_results. Aligning those two would make the async flow much easier to consume from the SDK/MCP.
Happy to send a PR for the SDK side if you decide on a shape.
Summary
GET /api/v1/projects/<id>/results(SDK:get_project_results) signals extraction state implicitly, by the shape of the row. There is nostatusfield, which makes correct polling harder than it should be and produces a silent, hard-to-debug failure mode for clients.Observed shapes:
Why this bites
The natural poll is
while result.get("paper") != done: sleep(). On success"paper"is absent, so.get("paper")returnsNone— identical to what a client sees for an in-flight job. I polled a finished extraction for 14 minutes believing it was still running, and earlier reported the service as broken partly on that basis. The values were sitting in the response the whole time.It is also awkward that a feature identifier could collide with a reserved key (a feature named
paperwould be indistinguishable from the failure marker).Suggested fix
Add an explicit, always-present status and nest the extracted values, e.g.:
{"status": "completed" | "failed" | "processing", "error": "<message when failed>", "features": {"paper_title": "...", "n_params": 213000000}, "_result_id": "...", "_paper_id": "..."}Even just adding
"status"alongside the current shape (keeping the rest for backwards compatibility) would remove the ambiguity entirely.Related
check_task_status(task_id)returnsNonefor the UUID task ids thatupload_paper()hands back, so it can't be used to poll either — status is only observable viaget_project_results. Aligning those two would make the async flow much easier to consume from the SDK/MCP.Happy to send a PR for the SDK side if you decide on a shape.