Skip to content

feat: add listAgents and make ensureAgent idempotent at the agent cap#41

Merged
guyb1 merged 1 commit into
mainfrom
fix/ensure-agent-idempotent-at-cap
Jun 14, 2026
Merged

feat: add listAgents and make ensureAgent idempotent at the agent cap#41
guyb1 merged 1 commit into
mainfrom
fix/ensure-agent-idempotent-at-cap

Conversation

@guyb1

@guyb1 guyb1 commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Summary

ensureAgent is documented as idempotent — "Creates it if missing, returns normally if it already exists." It broke once a project hit its agent cap, even when the target agent already existed and the call should have been a no-op.

Root cause: the server evaluates the agent-count quota before the identifier-uniqueness check, so re-creating an existing identifier while at the cap returns 403 (quota) instead of the 409 (conflict) that ensureAgent treats as success. ensureAgent only handled 409, so the 403 propagated. The root cause is fixed server-side in the companion onecli-cloud PR; this change hardens the SDK so the documented contract holds regardless of server version.

What this does

  • ensureAgent — on a 403, confirms whether the agent already exists and, if so, resolves with created: false; a genuine quota error (agent doesn't exist) still throws. The happy path is unchanged — the extra lookup only runs on a 403.
  • listAgents() — new public method (GET /v1/agents) + Agent type. The fallback needs it, and it's a useful primitive the SDK was missing.

Testing

  • pnpm typecheck, pnpm build, pnpm test — all green (74 tests).
  • +7 tests: listAgents (happy / 4xx / network) and the ensureAgent 403 branches (exists → created: false; absent → throws 403; existence-check itself fails → throws the original 403).

Fixes #40

🤖 Generated with Claude Code

ensureAgent is documented as idempotent ("returns normally if it already exists"), but it broke at the project's agent cap. The server evaluates the agent quota before the identifier-uniqueness check, so re-creating an existing identifier while at the cap returned 403 (quota) instead of the 409 (conflict) that ensureAgent treats as success -- so ensureAgent threw even though the agent already existed.

On a 403, ensureAgent now confirms whether the agent already exists (via a new listAgents() call) and, if so, resolves with created: false; a genuine quota error (agent does not exist) still surfaces. The happy path is unchanged -- the extra lookup only runs on a 403.

Also adds a public listAgents() method and Agent type.

Fixes #40

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@guyb1

guyb1 commented Jun 14, 2026

Copy link
Copy Markdown
Contributor Author

Companion server-side root-cause fix: onecli/onecli-cloud#550. That PR makes the API return the canonical 409 at the cap; this PR hardens the SDK so ensureAgent stays idempotent regardless of server version.

@guyb1 guyb1 merged commit 74dbae8 into main Jun 14, 2026
3 checks passed
@guyb1 guyb1 deleted the fix/ensure-agent-idempotent-at-cap branch June 14, 2026 16:20
@guyb1 guyb1 mentioned this pull request Jun 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ensureAgent not idempotent at agent quota cap — server returns 403 (not documented 409) for an existing identifier

1 participant