feat: add AgentsResource (messaging primitive identity surface)#27
Merged
govindkavaturi-art merged 1 commit intomainfrom May 4, 2026
Merged
feat: add AgentsResource (messaging primitive identity surface)#27govindkavaturi-art merged 1 commit intomainfrom
govindkavaturi-art merged 1 commit intomainfrom
Conversation
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.
AgentsResource wraps the messaging-primitive identity surface. The headers param plumbed through _request() is the right place to add support for X-Cueapi-From-Agent / X-Idempotency-Key passthrough. Approve.
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)
a967e4e to
fb4088c
Compare
govindkavaturi-art
pushed a commit
that referenced
this pull request
May 4, 2026
Wraps the `/v1/messages` surface (Phase 12.1.5). Closes the messages portion of the `Messaging primitive` `endpoints_missing` entry in cueapi-python #24's parity manifest. New resource: - `cueapi/resources/messages.py`: MessagesResource - .send(from_agent, to, body, subject=, reply_to=, priority=, expects_reply=, reply_to_agent=, metadata=, idempotency_key=) - .get(msg_id) - .mark_read(msg_id) # idempotent on already-read - .ack(msg_id) # terminal Client extension: - Same `_request(headers=...)` extension as PR #27 (AgentsResource). Independent commit on this branch since the two resources can land in either order; minor merge conflict on client.py is auto-resolvable (both PRs add the same kwarg in the same way). Design notes pinned by tests: - `from_agent` goes via `X-Cueapi-From-Agent` HEADER, NOT in body. The server's MessageCreate schema is extra="forbid" — putting `from` in the body would 400, but we want this caught at unit-test time. Pinned by test_minimal_body_and_from_header. - `expects_reply=False` (default) NOT sent in body. Server default is False; sending `expects_reply: false` is no-op + adds noise. Pinned by test_omits_expects_reply_when_default. - `idempotency_key` >255 chars raises ValueError client-side BEFORE any HTTP call. Matches server's hard limit. Pinned that no HTTP request is made when the validation fails. - `idempotency_key=None` omits the header entirely (no `Idempotency-Key: None` leakage). Pinned. Tests: 9 new (12 → 21 in this resource family; 38 total across all unit-test files). Server-side dedup-hit (200 response) and priority-downgrade signals (`X-CueAPI-Priority-Downgraded` header) are surfaced through the underlying httpx response — the SDK's `_handle_response` returns the data dict on 2xx, so callers see status_code 200 vs 201 only via the underlying client. A future enhancement could expose these signals explicitly via a richer return type; documented for follow-up. No hosted-PR dependency. All 4 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 `/v1/messages` surface (Phase 12.1.5). Closes the messages portion of the `Messaging primitive` `endpoints_missing` entry in cueapi-python #24's parity manifest. New resource: - `cueapi/resources/messages.py`: MessagesResource - .send(from_agent, to, body, subject=, reply_to=, priority=, expects_reply=, reply_to_agent=, metadata=, idempotency_key=) - .get(msg_id) - .mark_read(msg_id) # idempotent on already-read - .ack(msg_id) # terminal Client extension: - Same `_request(headers=...)` extension as PR #27 (AgentsResource). Independent commit on this branch since the two resources can land in either order; minor merge conflict on client.py is auto-resolvable (both PRs add the same kwarg in the same way). Design notes pinned by tests: - `from_agent` goes via `X-Cueapi-From-Agent` HEADER, NOT in body. The server's MessageCreate schema is extra="forbid" — putting `from` in the body would 400, but we want this caught at unit-test time. Pinned by test_minimal_body_and_from_header. - `expects_reply=False` (default) NOT sent in body. Server default is False; sending `expects_reply: false` is no-op + adds noise. Pinned by test_omits_expects_reply_when_default. - `idempotency_key` >255 chars raises ValueError client-side BEFORE any HTTP call. Matches server's hard limit. Pinned that no HTTP request is made when the validation fails. - `idempotency_key=None` omits the header entirely (no `Idempotency-Key: None` leakage). Pinned. Tests: 9 new (12 → 21 in this resource family; 38 total across all unit-test files). Server-side dedup-hit (200 response) and priority-downgrade signals (`X-CueAPI-Priority-Downgraded` header) are surfaced through the underlying httpx response — the SDK's `_handle_response` returns the data dict on 2xx, so callers see status_code 200 vs 201 only via the underlying client. A future enhancement could expose these signals explicitly via a richer return type; documented for follow-up. No hosted-PR dependency. All 4 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
Wraps the entire
/v1/agentssurface from the messaging primitive (Phase 12.1.5). Closes the agents portion of theMessaging primitiveendpoints_missingentry in cueapi-python #24's parity manifest.The companion
MessagesResource(send/get/read/ack lifecycle) ships in a follow-up PR for review-burden reasons. Both PRs are independent (different files, different test classes) and can land in either order.Surface
client.agentsexposes:.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, ...).delete(ref).webhook_secret_get(ref).webhook_secret_regenerate(ref).inbox(ref, state=None, ...).sent(ref, ...)Client extension
client._requestnow accepts an optionalheaderskwarg. Extends (doesn't replace) the client's defaultAuthorization+Content-Type+User-Agent. Used here for theX-Confirm-Destructiveguard; will also be used by the upcomingMessagesResourceforX-Cueapi-From-Agent+Idempotency-Key. Backwards-compatible (existing callers don't change).Design notes pinned by tests
include_deleted=Truesends\"true\",False(default) omits. Same omit-when-default pattern as the executions-list filters and cueapi-cli's similar flags. Pinned bytest_include_deleted_only_sent_when_true.clear_webhook_url=Truesends literal JSONnull, not field omission. Server usesmodel_fields_setto disambiguate "omitted = no change" from "explicit null = clear," so the SDK MUST send the key with explicitNone. Pinned bytest_clear_webhook_url_sends_explicit_null. Mirror of cueapi-cli feat: add MessagesResource (messaging primitive lifecycle) #28's--clear-webhook-url.webhook_url+clear_webhook_urlmutex enforced with a clearValueErrorbefore any HTTP call.webhook_secret_regenerateaddsX-Confirm-Destructive: trueautomatically. The server requires it; the SDK handles it so callers don't have to know about the header. Pinned bytest_regenerate_sends_destructive_header.Tests
18 new across 9 test classes. Mock-based, mirrors the existing
ExecutionsResourcetest pattern. All 46 unit tests pass (excluding the pre-existingtest_cues.pystaging-cred flake which is captured in a separate Backlog item).No hosted-PR dependency
All 9 endpoints already shipped on prod via Phase 12.1 messaging primitive (per MEMORY.md / CLAUDE.md).
Companion PRs from this session
mark_verifiedbug fix +replay()WorkersResource+UsageResourceMessagesResource— message lifecycle, separate PR🤖 Generated with Claude Code