@pouchy_ai/admin-sdk 0.40.0 → 0.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,32 @@
2
2
 
3
3
  All notable changes to `@pouchy_ai/admin-sdk` are documented here.
4
4
 
5
+ ## 0.41.0 — 2026-10-02
6
+
7
+ - **Three world session-mint codes join `ADMIN_ERROR_CODES`.** `POST
8
+ /v1/sessions` with a `world` block used to answer all three membership
9
+ conflicts with one sentence and no `code`, telling the caller to start a
10
+ fresh `world_instance`. Each now carries its own 409 code:
11
+ `world_actor_conflict` (the role in this world instance is bound to a
12
+ different agent, registry instance or key environment — mint with the ones
13
+ that first entered it), `world_revision_mismatch` and
14
+ `world_provider_mismatch` (both a race between two concurrent first mints of
15
+ one world instance — retry the mint). A worldline whose project merely
16
+ edited or promoted the role's agent, or republished one of its
17
+ capabilities, is no longer refused at all. Additive; no method changed.
18
+
19
+ ## 0.40.1 — 2026-09-30
20
+
21
+ - **A 2xx whose body cannot be read now rejects with `AdminApiError`.** It
22
+ used to resolve as `{}` typed as the method's result: an HTML 200 from a
23
+ proxy or captive portal, a truncated body, or a deadline that fired
24
+ mid-body read as a success with every field `undefined`. For a one-shot
25
+ secret (`createKey`, `rotateKey`, `createWebhook`, `rotateWebhookSecret`)
26
+ the server had already minted it, and the caller lost it silently. The
27
+ error's `status` is the server's 2xx, because the request did land: do not
28
+ blindly retry a mint. A 204 / 205 still resolves `{}`; non-2xx errors are
29
+ unchanged.
30
+
5
31
  ## 0.40.0 — 2026-09-29
6
32
 
7
33
  - **`recording` on agents.** Turning it on grants `call.record` on the agent's
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export declare const ADMIN_SDK_VERSION = "0.40.0";
1
+ export declare const ADMIN_SDK_VERSION = "0.41.0";
2
2
  export declare const DEFAULT_BASE_URL = "https://pouchy.ai/v1/admin";
3
3
  /** Deadline for the routes whose server handler declares `maxDuration: 300` —
4
4
  * the server's own ceiling plus headroom, so a client abort can only ever mean
@@ -60,7 +60,7 @@ export interface AdminClientOptions {
60
60
  * published: on this plane the status line never disambiguates, so two of the
61
61
  * durable-run routes answer 409 for two entirely different reasons each, with
62
62
  * different recoveries. `code` is the only thing that tells them apart. */
63
- export declare const ADMIN_ERROR_CODES: readonly ["story_contract_v2_write_disabled", "story_contract_v3_write_disabled", "story_contract_v4_write_disabled", "has_pins", "pins_unknown", "story_package_limit", "story_package_documents_limit", "episode_history_incomplete", "episode_ended", "idempotency_key_reused", "stale_deliberation", "deliberation_disabled", "deliberation_uncalibrated", "deliberation_not_enabled", "deliberation_candidates_exceeded", "schedule_limit_reached", "one_shot_spent", "ghost_row", "channel_limit_reached", "webhook_limit_reached", "run_limit_reached", "reembed_required", "run_terminal", "run_not_parked", "stale_token", "run_not_waiting", "event_mismatch", "subscription_exists"];
63
+ export declare const ADMIN_ERROR_CODES: readonly ["story_contract_v2_write_disabled", "story_contract_v3_write_disabled", "story_contract_v4_write_disabled", "has_pins", "pins_unknown", "story_package_limit", "story_package_documents_limit", "episode_history_incomplete", "episode_ended", "idempotency_key_reused", "stale_deliberation", "deliberation_disabled", "deliberation_uncalibrated", "deliberation_not_enabled", "deliberation_candidates_exceeded", "schedule_limit_reached", "one_shot_spent", "ghost_row", "channel_limit_reached", "webhook_limit_reached", "run_limit_reached", "reembed_required", "run_terminal", "run_not_parked", "stale_token", "run_not_waiting", "event_mismatch", "subscription_exists", "world_actor_conflict", "world_revision_mismatch", "world_provider_mismatch"];
64
64
  /** `AdminApiError.code` values. The `(string & {})` arm keeps the type open for
65
65
  * codes newer than this SDK build while preserving autocomplete — same
66
66
  * doctrine as the companion SDK's `CompanionErrorCodeValue`. */
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@
8
8
  // import { createAdminClient } from '@pouchy_ai/admin-sdk';
9
9
  // const admin = createAdminClient({ adminKey: process.env.POUCHY_ADMIN_KEY! });
10
10
  // const { agents } = await admin.listAgents();
11
- export const ADMIN_SDK_VERSION = '0.40.0';
11
+ export const ADMIN_SDK_VERSION = '0.41.0';
12
12
  export const DEFAULT_BASE_URL = 'https://pouchy.ai/v1/admin';
13
13
  /** Default per-request timeout (ms). A hung upstream otherwise never rejects. */
14
14
  const DEFAULT_TIMEOUT_MS = 30_000;
@@ -100,7 +100,14 @@ export const ADMIN_ERROR_CODES = [
100
100
  // 0.38.0 — checkout on an account that already pays through a live
101
101
  // subscription. Recovery: POST /v1/projects/{id}/billing/upgrade, which moves
102
102
  // that subscription to the new price instead of opening a second one.
103
- 'subscription_exists'
103
+ 'subscription_exists',
104
+ // 0.41.0 — the three world session-mint conflicts (`POST /v1/sessions` with
105
+ // `world`). `world_actor_conflict`: the role is bound to a different agent,
106
+ // registry instance or key environment. The other two are races between
107
+ // two concurrent FIRST mints of one world instance; retry the mint.
108
+ 'world_actor_conflict',
109
+ 'world_revision_mismatch',
110
+ 'world_provider_mismatch'
104
111
  ];
105
112
  /** Thrown on any non-2xx response AND on a transport failure that never reached
106
113
  * the server (network / DNS / timeout), which carries `status: 0`. `status` is
@@ -270,7 +277,25 @@ export function createAdminClient(opts) {
270
277
  ? `${method} ${path} — request timed out after ${timeoutMs}ms`
271
278
  : `${method} ${path} — network error: ${e instanceof Error ? e.message : String(e)}`, 0);
272
279
  }
273
- const data = (await res.json().catch(() => ({})));
280
+ // 0.40.1: a 2xx whose body cannot be read is an error, not `{}`. It used
281
+ // to resolve as a success with every field undefined — an HTML 200 from a
282
+ // proxy, a truncated body, a deadline that fired mid-body — and a secret
283
+ // the server had already minted (`createKey`, `rotateKey`,
284
+ // `createWebhook`) was lost with no signal. `status` stays the server's
285
+ // 2xx: the request DID land, so a blind retry of a mint is not safe. A
286
+ // 204 / 205 (no body by definition) still resolves `{}`, and the non-2xx
287
+ // arm keeps its fallback. Still `res.json()`, not `text()`: an injected
288
+ // `fetch` may hand back a minimal response that only implements `json`.
289
+ let readError = null;
290
+ const data = (await res.json().catch((e) => {
291
+ readError = e;
292
+ return {};
293
+ }));
294
+ if (res.ok && readError !== null && res.status !== 204 && res.status !== 205) {
295
+ const why = readError instanceof Error ? readError.message : String(readError);
296
+ const msg = `${method} ${path} — unreadable ${res.status} body: ${why}`;
297
+ throw new AdminApiError(msg, res.status, retryAfterFrom(res, null));
298
+ }
274
299
  if (!res.ok)
275
300
  throw new AdminApiError(
276
301
  // The server's own `error` string is passed through UNCHANGED — it is
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pouchy_ai/admin-sdk",
3
- "version": "0.40.0",
3
+ "version": "0.41.0",
4
4
  "description": "Typed TypeScript client for the Pouchy Admin API \u2014 manage agents, keys, end users, knowledge, skills, channels, schedules, webhooks and credentials headlessly, with a project Admin key.",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN LICENSE",