feat: add WorkersResource + UsageResource (parity with /v1/workers + /v1/usage)#26
Merged
govindkavaturi-art merged 1 commit intomainfrom May 4, 2026
Merged
Conversation
…/v1/usage) Closes 2 entries from cueapi-python #24's `endpoints_missing` parity manifest: - GET /v1/workers → client.workers.list() - DELETE /v1/workers/{id} → client.workers.delete(worker_id) - GET /v1/usage → client.usage.get() (`DELETE /v1/workers/{id}` wasn't in the manifest but is part of the same hosted surface — added for completeness.) New resource classes: - `cueapi/resources/workers.py`: WorkersResource — `.list()` + `.delete()` - `cueapi/resources/usage.py`: UsageResource — `.get()` Both registered on the CueAPI client and exported from cueapi.__init__. Skipped from manifest: POST /v1/worker/heartbeat (worker registration). The hosted endpoint is meant for cueapi-worker (which already wraps it correctly with heartbeat-loop semantics); direct SDK-driven registration is redundant. Documented in WorkersResource's class docstring. Tests: 5 new (12 → 17 unit tests). Mock-based, mirrors the existing ExecutionsResource test pattern. The 14 pre-existing staging-cred test_cues.py failures (`ValueError: api_key is required`) are unrelated to this PR — same flake captured in the Backlog row added when surveying cueapi-python earlier this session. No hosted-PR dependency. All 3 endpoints already shipped on prod. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This was referenced May 4, 2026
govindkavaturi-art
approved these changes
May 4, 2026
Member
govindkavaturi-art
left a comment
There was a problem hiding this comment.
Clean parity port — WorkersResource + UsageResource just wrap GET endpoints. Approve.
govindkavaturi-art
pushed a commit
that referenced
this pull request
May 4, 2026
Wraps the entire `/v1/agents` surface from the messaging primitive (Phase 12.1.5). Closes the agents portion of the `Messaging primitive` endpoints_missing entry in cueapi-python #24's parity manifest. The companion `MessagesResource` (send/get/read/ack lifecycle) ships in a follow-up PR. New resource: - `cueapi/resources/agents.py`: AgentsResource - .create(display_name, slug=None, webhook_url=None, metadata=None) - .list(status=None, include_deleted=False, limit=50, offset=0) - .get(ref, include_deleted=False) - .update(ref, display_name=None, webhook_url=None, clear_webhook_url=False, status=None, metadata=None) - .delete(ref) - .webhook_secret_get(ref) - .webhook_secret_regenerate(ref) # sends X-Confirm-Destructive: true - .inbox(ref, state=None, limit=50, offset=0) - .sent(ref, limit=50, offset=0) Client extension: - `client._request` now accepts an optional `headers` kwarg, which extends (does not replace) the client's default Authorization + Content-Type + User-Agent headers. Used here for the destructive X-Confirm-Destructive guard; will also be used by the upcoming MessagesResource for X-Cueapi-From-Agent + Idempotency-Key. Design notes pinned by tests: - `--include-deleted` mirror: `include_deleted=True` sends `"true"`, `False` (default) omits. Same omit-when-default pattern as PR #26's `executions list --has-evidence`. - `clear_webhook_url=True` sends literal JSON `null` (key present, value None), NOT field omission. Server uses `model_fields_set` to disambiguate "omitted = no change" from "explicit null = clear", so the SDK MUST send the key with explicit None. Pinned by test_clear_webhook_url_sends_explicit_null. - `webhook_url` and `clear_webhook_url` mutex enforced with a clear ValueError before any HTTP call. - `webhook_secret_regenerate` sends X-Confirm-Destructive: true in the header. The server requires it; the SDK adds it automatically so callers don't have to know about the header. Pinned by test_regenerate_sends_destructive_header. Tests: 18 new across 9 test classes (12 → ~30 unit tests; total 46 passing across all unit-test files). No hosted-PR dependency. All 9 endpoints already shipped on prod. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
govindkavaturi-art
pushed a commit
that referenced
this pull request
May 4, 2026
Wraps the entire `/v1/agents` surface from the messaging primitive (Phase 12.1.5). Closes the agents portion of the `Messaging primitive` endpoints_missing entry in cueapi-python #24's parity manifest. The companion `MessagesResource` (send/get/read/ack lifecycle) ships in a follow-up PR. New resource: - `cueapi/resources/agents.py`: AgentsResource - .create(display_name, slug=None, webhook_url=None, metadata=None) - .list(status=None, include_deleted=False, limit=50, offset=0) - .get(ref, include_deleted=False) - .update(ref, display_name=None, webhook_url=None, clear_webhook_url=False, status=None, metadata=None) - .delete(ref) - .webhook_secret_get(ref) - .webhook_secret_regenerate(ref) # sends X-Confirm-Destructive: true - .inbox(ref, state=None, limit=50, offset=0) - .sent(ref, limit=50, offset=0) Client extension: - `client._request` now accepts an optional `headers` kwarg, which extends (does not replace) the client's default Authorization + Content-Type + User-Agent headers. Used here for the destructive X-Confirm-Destructive guard; will also be used by the upcoming MessagesResource for X-Cueapi-From-Agent + Idempotency-Key. Design notes pinned by tests: - `--include-deleted` mirror: `include_deleted=True` sends `"true"`, `False` (default) omits. Same omit-when-default pattern as PR #26's `executions list --has-evidence`. - `clear_webhook_url=True` sends literal JSON `null` (key present, value None), NOT field omission. Server uses `model_fields_set` to disambiguate "omitted = no change" from "explicit null = clear", so the SDK MUST send the key with explicit None. Pinned by test_clear_webhook_url_sends_explicit_null. - `webhook_url` and `clear_webhook_url` mutex enforced with a clear ValueError before any HTTP call. - `webhook_secret_regenerate` sends X-Confirm-Destructive: true in the header. The server requires it; the SDK adds it automatically so callers don't have to know about the header. Pinned by test_regenerate_sends_destructive_header. Tests: 18 new across 9 test classes (12 → ~30 unit tests; total 46 passing across all unit-test files). No hosted-PR dependency. All 9 endpoints already shipped on prod. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes 2 entries from cueapi-python #24's
endpoints_missingparity manifest plus a bonusDELETEthat wasn't listed:client.workers.list()client.workers.delete(worker_id)client.usage.get()New resource classes
cueapi/resources/workers.py—WorkersResourcecueapi/resources/usage.py—UsageResourceBoth registered on the
CueAPIclient (client.workers,client.usage) and exported fromcueapi.__init__so callers canfrom cueapi import WorkersResource, UsageResourceif they want to mock them in tests.Skipped from manifest
POST /v1/worker/heartbeat(worker registration). The hosted endpoint is meant for cueapi-worker (which already wraps it correctly with heartbeat-loop semantics); direct SDK-driven registration would be redundant. Documented inWorkersResource's class docstring so future readers don't wonder why it's missing.Tests
5 new (12 → 17 unit tests). Mock-based, mirrors the existing
ExecutionsResourcetest pattern:test_list_calls_get_workers— verifies pathtest_list_passes_no_params— pinned bare-call shape (no params kwarg leakage)test_delete_calls_delete_workers_id— verifies path + 204→None handlingtest_get_calls_get_usage— verifies path + a representative response shapetest_get_returns_server_dict_unchanged— pinned no-transform behavior so a future refactor can't silently start coercing into a typed objectPre-existing CI flake
The 14 errors on
test_cues.py(ValueError: api_key is required) are pre-existing and unrelated to this PR. Captured in the Backlog row added when surveying cueapi-python earlier today (cueapi-python staging-cred test flake, tier-5-maintenance).No hosted-PR dependency
All 3 endpoints already shipped on prod. Pure SDK catch-up.
Companion PR
#25 —
mark_verifiedbug fix +replay()(sibling executions-resource changes from the same survey pass).Test plan
python3 -m pytest tests/test_workers_resource.py tests/test_usage_resource.py -q→ 5 passedpython3 -m pytest tests/test_executions_resource.py -q→ 12 passed (unchanged)client.workers.list()→ returns dict with workers + totalclient.usage.get()→ returns plan + cues + executions + rate_limitParity Impact
Closes 2 entries from
endpoints_missingin cueapi-python #24'sparity-manifest.json:GET /v1/workersGET /v1/usagePlus the bonus
DELETE /v1/workers/{id}. After this and #25 merge, remainingendpoints_missingis the messaging primitive (Phase 12.1.5 — large surface, separate PR) plus the deliberately-skipped destructive operations andPOST /v1/worker/heartbeat.🤖 Generated with Claude Code