@pouchy_ai/admin-sdk 0.4.3 → 0.5.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,35 @@
2
2
 
3
3
  All notable changes to `@pouchy_ai/admin-sdk` are documented here.
4
4
 
5
+ ## 0.5.0 — 2026-07-17
6
+
7
+ Additive: end-user listing pagination.
8
+
9
+ - **`listUsers` gains cursor pagination**: pass `limit` (clamped 1..100
10
+ server-side, default 100) and `cursor` (opaque — the previous response's
11
+ `nextCursor`); the response now carries `nextCursor` while more rows exist.
12
+ Previously the unfiltered listing was hard-capped at the 100 most recently
13
+ active instances with no way to reach the tail. The filtered variants
14
+ (`external_user_id` / `external_user_prefix`) are unchanged and don't
15
+ paginate. Requires a server deployment serving Admin API >= 1.2.0; older
16
+ servers ignore the new params and never return `nextCursor` (you just get
17
+ the old first-100 behavior).
18
+
19
+ ## 0.4.4 — 2026-07-17
20
+
21
+ Transport-error parity with the JS/python/unity siblings (they got this in
22
+ their last release; admin-sdk was only touched for packaging).
23
+
24
+ - **Every failure now throws `AdminApiError`.** A network/DNS failure
25
+ previously escaped as a raw `TypeError: fetch failed`, contradicting the
26
+ documented "failures throw AdminApiError" contract. Transport errors are
27
+ wrapped as `AdminApiError(status: 0)`.
28
+ - **Per-request timeout** (`timeoutMs`, default 30s): a hung upstream now
29
+ rejects with `AdminApiError('request timed out after …', 0)` instead of
30
+ hanging forever. Uses `AbortSignal.timeout`.
31
+ - **`ADMIN_SDK_VERSION` corrected to match `package.json`** (it had drifted to
32
+ `0.4.2`, the second time this constant fell behind — now pinned by a test).
33
+
5
34
  ## 0.4.3 — 2026-07-17
6
35
 
7
36
  - Packaging only: added the `default` export condition beside `import` in the
package/README.md CHANGED
@@ -61,13 +61,16 @@ console.log(`armed — ${armed.reprovisioned} running instance(s) updated`);
61
61
  createAdminClient({
62
62
  adminKey: 'pchy_admin_…', // required
63
63
  baseUrl: 'https://pouchy.ai/v1/admin', // optional (self-host / staging)
64
- fetch: myFetch // optional (Node <18, or tests)
64
+ fetch: myFetch, // optional (Node <18, or tests)
65
+ timeoutMs: 30_000 // optional per-request timeout (default 30s)
65
66
  });
66
67
  ```
67
68
 
68
69
  ## Errors
69
70
 
70
- Every method throws `AdminApiError` on a non-2xx response:
71
+ Every method throws `AdminApiError` on failure — a non-2xx response, a network
72
+ error, or a timeout. Transport failures (network/DNS/timeout) carry
73
+ `status: 0`; HTTP errors carry the real status and the server's `error` string:
71
74
 
72
75
  ```ts
73
76
  import { AdminApiError } from '@pouchy_ai/admin-sdk';
@@ -85,7 +88,7 @@ try {
85
88
  | Agents | `listAgents` · `createAgent` · `getAgent` · `updateAgent` · `deleteAgent` |
86
89
  | Voices | `listVoices({ gender?, age?, locale? })` — catalog for programmatic voice selection (each `CatalogVoice` carries `age`) |
87
90
  | Secret keys | `listKeys` · `createKey` · `revokeKey` · `rotateKey` (24 h grace) |
88
- | End users | `listUsers` · `setUserSuspended` · `deleteUser` · `getUserWallet` · `getUserTraces` · `importUsers` · `exportUser` · `getUserSessions` · `getUserTurns` |
91
+ | End users | `listUsers({ limit?, cursor? })` (cursor-paginated — the response's `nextCursor` feeds the next page; filter variants: `external_user_id` / `external_user_prefix`) · `setUserSuspended` · `deleteUser` · `getUserWallet` · `getUserTraces` · `importUsers` · `exportUser` · `getUserSessions` · `getUserTurns` |
89
92
  | Knowledge | `listKnowledge` · `ingestKnowledge` · `deleteKnowledge` |
90
93
  | Skills | `listSkills` · `installSkill` · `updateSkill` · `setSkillRate` · `setSkillDailyCap` · `grantSkill` (free-HTTP) · `compileSkill` (prose→tools) · `uninstallSkill` |
91
94
  | Credentials | `listCredentials` · `putCredentials` · `deleteCredentials` |
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export declare const ADMIN_SDK_VERSION = "0.4.2";
1
+ export declare const ADMIN_SDK_VERSION = "0.5.0";
2
2
  export declare const DEFAULT_BASE_URL = "https://pouchy.ai/v1/admin";
3
3
  export interface AdminClientOptions {
4
4
  /** A project Admin key (`pchy_admin_…`) from the dashboard Admin Keys page. */
@@ -7,6 +7,9 @@ export interface AdminClientOptions {
7
7
  baseUrl?: string;
8
8
  /** Inject a fetch impl (Node <18, or for tests). Default global fetch. */
9
9
  fetch?: typeof fetch;
10
+ /** Per-request timeout in ms (default 30s). A request that outlives it
11
+ * rejects with an AdminApiError(status 0). */
12
+ timeoutMs?: number;
10
13
  }
11
14
  /** Thrown on any non-2xx response. `status` is the HTTP status; `message` is the
12
15
  * server's `error` string when present. */
@@ -156,13 +159,19 @@ export interface AdminClient {
156
159
  graceUntil: string | null;
157
160
  };
158
161
  }>;
159
- /** List end-user instances. Filter by exact external id or by prefix (the
160
- * server ignores any other query param and hard-caps the page at 100). */
162
+ /** List end-user instances. Filter by exact external id or by prefix, or
163
+ * page the full listing: `limit` (clamped 1..100 server-side, default 100)
164
+ * + `cursor` (opaque — pass back the previous response's `nextCursor`).
165
+ * `nextCursor` is present while more rows exist; the filtered variants
166
+ * don't paginate. */
161
167
  listUsers(params?: {
162
168
  external_user_id?: string;
163
169
  external_user_prefix?: string;
170
+ limit?: number;
171
+ cursor?: string;
164
172
  }): Promise<{
165
173
  users: Instance[];
174
+ nextCursor?: string;
166
175
  }>;
167
176
  setUserSuspended(instanceId: string, suspended: boolean): Promise<{
168
177
  suspended: boolean;
package/dist/index.js CHANGED
@@ -8,8 +8,10 @@
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.4.2';
11
+ export const ADMIN_SDK_VERSION = '0.5.0';
12
12
  export const DEFAULT_BASE_URL = 'https://pouchy.ai/v1/admin';
13
+ /** Default per-request timeout (ms). A hung upstream otherwise never rejects. */
14
+ const DEFAULT_TIMEOUT_MS = 30_000;
13
15
  /** Thrown on any non-2xx response. `status` is the HTTP status; `message` is the
14
16
  * server's `error` string when present. */
15
17
  export class AdminApiError extends Error {
@@ -35,15 +37,28 @@ export function createAdminClient(opts) {
35
37
  const f = opts.fetch ?? globalThis.fetch;
36
38
  if (!f)
37
39
  throw new AdminApiError('no fetch available — pass opts.fetch on Node <18', 0);
40
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
38
41
  async function request(method, path, body) {
39
- const res = await f(base + path, {
40
- method,
41
- headers: {
42
- authorization: `Bearer ${opts.adminKey}`,
43
- ...(body !== undefined ? { 'content-type': 'application/json' } : {})
44
- },
45
- body: body !== undefined ? JSON.stringify(body) : undefined
46
- });
42
+ // Every failure surfaces as an AdminApiError (the doc contract): a
43
+ // network/DNS error or a timeout would otherwise escape as a raw
44
+ // `TypeError: fetch failed` / AbortError. Status 0 = never reached the
45
+ // server (parity with the JS/python SDKs' transport-error wrapping).
46
+ let res;
47
+ try {
48
+ res = await f(base + path, {
49
+ method,
50
+ headers: {
51
+ authorization: `Bearer ${opts.adminKey}`,
52
+ ...(body !== undefined ? { 'content-type': 'application/json' } : {})
53
+ },
54
+ body: body !== undefined ? JSON.stringify(body) : undefined,
55
+ signal: AbortSignal.timeout(timeoutMs)
56
+ });
57
+ }
58
+ catch (e) {
59
+ const isTimeout = e instanceof Error && (e.name === 'TimeoutError' || e.name === 'AbortError');
60
+ throw new AdminApiError(isTimeout ? `request timed out after ${timeoutMs}ms` : `network error: ${e instanceof Error ? e.message : String(e)}`, 0);
61
+ }
47
62
  const data = (await res.json().catch(() => ({})));
48
63
  if (!res.ok)
49
64
  throw new AdminApiError(data?.error ?? `HTTP ${res.status}`, res.status);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pouchy_ai/admin-sdk",
3
- "version": "0.4.3",
4
- "description": "Typed TypeScript client for the Pouchy Admin API manage agents, keys, end users, knowledge, skills, channels, schedules, webhooks and credentials headlessly, with a project Admin key.",
3
+ "version": "0.5.0",
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",
7
7
  "homepage": "https://pouchy.ai/sdk",
@@ -10,7 +10,9 @@
10
10
  "url": "https://github.com/oviswang/Pouchy.git",
11
11
  "directory": "packages/admin-sdk"
12
12
  },
13
- "bugs": { "email": "support@pouchy.ai" },
13
+ "bugs": {
14
+ "email": "support@pouchy.ai"
15
+ },
14
16
  "exports": {
15
17
  ".": {
16
18
  "types": "./dist/index.d.ts",
@@ -20,13 +22,28 @@
20
22
  },
21
23
  "main": "./dist/index.js",
22
24
  "types": "./dist/index.d.ts",
23
- "files": ["dist", "README.md", "CHANGELOG.md", "LICENSE"],
25
+ "files": [
26
+ "dist",
27
+ "README.md",
28
+ "CHANGELOG.md",
29
+ "LICENSE"
30
+ ],
24
31
  "sideEffects": false,
25
32
  "scripts": {
26
33
  "build": "tsc -p tsconfig.json",
27
34
  "prepublishOnly": "npm run build"
28
35
  },
29
- "devDependencies": { "typescript": "^5.5.0" },
30
- "keywords": ["pouchy", "admin", "api", "sdk", "agent-platform"],
31
- "publishConfig": { "access": "public" }
36
+ "devDependencies": {
37
+ "typescript": "^5.5.0"
38
+ },
39
+ "keywords": [
40
+ "pouchy",
41
+ "admin",
42
+ "api",
43
+ "sdk",
44
+ "agent-platform"
45
+ ],
46
+ "publishConfig": {
47
+ "access": "public"
48
+ }
32
49
  }