@pouchy_ai/admin-sdk 0.28.0 → 0.30.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 +40 -0
- package/README.md +17 -12
- package/dist/index.d.ts +29 -8
- package/dist/index.js +6 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@pouchy_ai/admin-sdk` are documented here.
|
|
4
4
|
|
|
5
|
+
## 0.30.0 — 2026-09-04
|
|
6
|
+
|
|
7
|
+
- **`internal-a2a` leaves `ChannelTransportType`.** It was a placeholder the
|
|
8
|
+
platform's union and store knew and no adapter served — `createChannel`
|
|
9
|
+
answered 400 on it, which is why `CreatableChannelType` excluded it. The
|
|
10
|
+
platform retired the id (design #24 / F-04: the friend auto-reply is a
|
|
11
|
+
companion session SURFACE, not a transport), so the union no longer names it
|
|
12
|
+
and `CreatableChannelType` is now the whole union. A caller that referenced
|
|
13
|
+
the literal type gets a compile error, which is the point; nothing that ever
|
|
14
|
+
worked changes.
|
|
15
|
+
|
|
16
|
+
## 0.29.1 — 2026-09-04
|
|
17
|
+
|
|
18
|
+
- **`story_contract_v4_write_disabled`** joins `ADMIN_ERROR_CODES` — a Story
|
|
19
|
+
Package publish that declares a `public: true` flag (Story Contract v4,
|
|
20
|
+
design #23) answers 409 with this code in an environment that has not
|
|
21
|
+
enabled v4 writes, the field intact. Vocabulary only; no method changed.
|
|
22
|
+
|
|
23
|
+
## 0.29.0 — 2026-08-31
|
|
24
|
+
|
|
25
|
+
- **`setSkillAutoRunTools(slug, toolNames)` — the per-tool confirm exemptions
|
|
26
|
+
(免确认工具) the Admin API could not reach.** Admin API 1.12.0. The knob
|
|
27
|
+
existed on the owner plane and in the dashboard since 2026-08 and was never
|
|
28
|
+
added here, so a headless provisioning flow could install a skill, rate-limit
|
|
29
|
+
it, grant its domains and attach it to an agent — and then answer nothing.
|
|
30
|
+
For MCP skills that is not an edge case: `mcpRecord` hard-codes
|
|
31
|
+
`platformSafe: false`, so every `run_skill` raises a confirm, and a platform
|
|
32
|
+
instance has no human who could ever approve one. This was the only route out.
|
|
33
|
+
|
|
34
|
+
A full REPLACE, not a merge — pass the complete list each call. Names the
|
|
35
|
+
skill does not declare are dropped and echoed in `dropped`, so a typo is
|
|
36
|
+
visible rather than silently ungranted. Grant the READ tools (a storefront's
|
|
37
|
+
`search_catalog` / `get_product`); leave cart mutations and order placement
|
|
38
|
+
gated.
|
|
39
|
+
|
|
40
|
+
Opening this to a long-lived admin key was an explicit decision, not a
|
|
41
|
+
symmetry fix: the confirm being waived is not a human in the loop (on an
|
|
42
|
+
instance nobody can approve it), and the same key already grants the strictly
|
|
43
|
+
wider `freeHttp` + `grantedDomains`.
|
|
44
|
+
|
|
5
45
|
## 0.28.0 — 2026-08-29
|
|
6
46
|
|
|
7
47
|
- **`installSkill` / `importAgentPlugin` now type the re-push outcome.** Both
|
package/README.md
CHANGED
|
@@ -243,7 +243,8 @@ that voice, or the voice catalog is temporarily unreachable; retry),
|
|
|
243
243
|
like the other voice planes — there is no separate platform credit rate; it is
|
|
244
244
|
bounded by an input cap and the shared per-IP utility rate limit.
|
|
245
245
|
|
|
246
|
-
Every skill knob (`setSkillRate`, `setSkillDailyCap`, `grantSkill
|
|
246
|
+
Every skill knob (`setSkillRate`, `setSkillDailyCap`, `grantSkill`,
|
|
247
|
+
`setSkillAutoRunTools`) returns
|
|
247
248
|
`SkillKnobResult<T>` — the knob you set plus `reprovisioned` (instances the new
|
|
248
249
|
def reached) and `truncated`. A knob only binds a running agent once the def
|
|
249
250
|
reaches its instance, so `truncated: true` means the sweep hit its cap (100
|
|
@@ -307,15 +308,19 @@ createAdminClient({
|
|
|
307
308
|
});
|
|
308
309
|
```
|
|
309
310
|
|
|
310
|
-
`timeoutMs` defaults to **30s**, except for the
|
|
311
|
-
|
|
311
|
+
`timeoutMs` defaults to **30s**, except for the requests whose server handler
|
|
312
|
+
declares `maxDuration: 300` and therefore answers only when the work is
|
|
312
313
|
finished — `POST /knowledge`, `POST /knowledge/file`, `POST /knowledge/url`
|
|
313
|
-
(chunk + summarize + embed, after OCR / Whisper / vision or a page fetch)
|
|
314
|
-
`DELETE /users/{instanceId}` (recursive GDPR erasure)
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
314
|
+
(chunk + summarize + embed, after OCR / Whisper / vision or a page fetch),
|
|
315
|
+
`DELETE /users/{instanceId}` (recursive GDPR erasure) and
|
|
316
|
+
`POST /capabilities/{name}/test-action` (the Action protocol verifier makes
|
|
317
|
+
REAL deliveries to your endpoint, and an abort mid-test cannot undo the ones
|
|
318
|
+
already made). Those default to **310s** (`LONG_WORK_TIMEOUT_MS`), so a client
|
|
319
|
+
abort can only ever mean "the server really is hung", never "the server is
|
|
320
|
+
still working" — a shorter deadline there reports a failure for an ingest that
|
|
321
|
+
is succeeding, and the retry it invites races the still-running first one (or
|
|
322
|
+
re-runs a side-effecting test whose first verdict is never read). The list is
|
|
323
|
+
`LONG_WORK_REQUESTS`, exported, and a drift test binds it to the routes.
|
|
319
324
|
|
|
320
325
|
Setting `timeoutMs` explicitly always wins and applies to **every** request, long
|
|
321
326
|
or short. `requestDeadlineMs(method, path)` returns the default a given request
|
|
@@ -436,7 +441,7 @@ Reads (`GET`) are not covered by that bucket. `retryAfter` is available from
|
|
|
436
441
|
| Secret keys | `listKeys` · `createKey` · `revokeKey` · `rotateKey` (24 h grace) |
|
|
437
442
|
| 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` |
|
|
438
443
|
| Knowledge | `listKnowledge` · `ingestKnowledge` · `ingestKnowledgeFile` (PDF/audio/video/image) · `ingestKnowledgeUrl` (web page) · `searchKnowledge` (recall probe) · `deleteKnowledge` |
|
|
439
|
-
| Skills | `listSkills` · `installSkill` · `updateSkill` · `setSkillRate` · `setSkillDailyCap` · `grantSkill` (free-HTTP) · `compileSkill` (prose→tools) · `uninstallSkill` · `importAgentPlugin` / `exportAgentPlugin` (Agent Plugins 1.0.0 interop) |
|
|
444
|
+
| Skills | `listSkills` · `installSkill` · `updateSkill` · `setSkillRate` · `setSkillDailyCap` · `grantSkill` (free-HTTP) · `setSkillAutoRunTools` (免确认工具 — required to arm an MCP skill on an instance) · `compileSkill` (prose→tools) · `uninstallSkill` · `importAgentPlugin` / `exportAgentPlugin` (Agent Plugins 1.0.0 interop) |
|
|
440
445
|
| Credentials | `listCredentials` · `putCredentials` · `deleteCredentials` |
|
|
441
446
|
| Channels | `listChannels` · `createChannel` · `getChannel` · `updateChannel` · `deleteChannel` |
|
|
442
447
|
| Schedules | `listSchedules` · `createSchedule` · `getSchedule` · `updateSchedule` · `deleteSchedule` |
|
|
@@ -448,8 +453,8 @@ Reads (`GET`) are not covered by that bucket. `retryAfter` is available from
|
|
|
448
453
|
| Escape hatch | `request(method, path, body?)` — any endpoint not yet typed |
|
|
449
454
|
|
|
450
455
|
Channel types are checked at compile time: `createChannel` takes a
|
|
451
|
-
`CreatableChannelType` (the platform's
|
|
452
|
-
|
|
456
|
+
`CreatableChannelType` (the platform's 81-transport union — every member has an
|
|
457
|
+
adapter since 0.30.0), and `secret` is a named `ChannelSecretInput`. Per-transport
|
|
453
458
|
`secret.extra` fields are listed in <https://pouchy.ai/docs/channel-setup>.
|
|
454
459
|
|
|
455
460
|
**Telegram and Discord register themselves.** On create — and again on a
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const ADMIN_SDK_VERSION = "0.
|
|
1
|
+
export declare const ADMIN_SDK_VERSION = "0.30.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
|
|
@@ -38,7 +38,8 @@ export interface AdminClientOptions {
|
|
|
38
38
|
fetch?: typeof fetch;
|
|
39
39
|
/** Per-request timeout in ms. Default 30s, EXCEPT the requests whose server
|
|
40
40
|
* handler declares `maxDuration: 300` (knowledge ingest by text/file/url,
|
|
41
|
-
*
|
|
41
|
+
* the GDPR user delete, and the capability test-action verifier — the
|
|
42
|
+
* list is {@link LONG_WORK_REQUESTS}), which default to
|
|
42
43
|
* {@link LONG_WORK_TIMEOUT_MS}. Setting this explicitly always wins and
|
|
43
44
|
* applies to every request, long or short. A request that outlives its
|
|
44
45
|
* deadline rejects with an AdminApiError(status 0).
|
|
@@ -59,7 +60,7 @@ export interface AdminClientOptions {
|
|
|
59
60
|
* published: on this plane the status line never disambiguates, so two of the
|
|
60
61
|
* durable-run routes answer 409 for two entirely different reasons each, with
|
|
61
62
|
* different recoveries. `code` is the only thing that tells them apart. */
|
|
62
|
-
export declare const ADMIN_ERROR_CODES: readonly ["story_contract_v2_write_disabled", "story_contract_v3_write_disabled", "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"];
|
|
63
|
+
export declare const ADMIN_ERROR_CODES: readonly ["story_contract_v2_write_disabled", "story_contract_v3_write_disabled", "story_contract_v4_write_disabled", "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"];
|
|
63
64
|
/** `AdminApiError.code` values. The `(string & {})` arm keeps the type open for
|
|
64
65
|
* codes newer than this SDK build while preserving autocomplete — same
|
|
65
66
|
* doctrine as the companion SDK's `CompanionErrorCodeValue`. */
|
|
@@ -332,11 +333,12 @@ export interface DeliveryOutcome {
|
|
|
332
333
|
* (`channels/types.ts`) — this package is standalone and cannot import it, so
|
|
333
334
|
* `admin-sdk-channel-types.drift.test.ts` binds the two and fails CI if either
|
|
334
335
|
* side gains a transport the other lacks. */
|
|
335
|
-
export type ChannelTransportType = 'echo' | 'matrix' | 'telegram' | 'web' | 'activitypub' | '
|
|
336
|
-
/** Transports `createChannel` accepts
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
|
|
336
|
+
export type ChannelTransportType = 'echo' | 'matrix' | 'telegram' | 'web' | 'activitypub' | 'discord' | 'slack' | 'nostr' | 'atproto' | 'sms' | 'email' | 'whatsapp' | 'messenger' | 'instagram' | 'line' | 'teams' | 'wechat' | 'wecom' | 'feishu' | 'dingtalk' | 'twitter' | 'xmpp' | 'qq' | 'kakao' | 'viber' | 'signal' | 'weibo' | 'alexa' | 'google-assistant' | 'voice' | 'onlyfans' | 'fansly' | 'fanvue' | 'imessage' | 'rcs' | 'intercom' | 'twitch' | 'zalo' | 'douyin' | 'kick' | 'reddit' | 'xmtp' | 'guilded' | 'youtube-live' | 'bilibili-live' | 'minecraft' | 'steam' | 'vk' | 'ok' | 'threads' | 'groupme' | 'threema' | 'mattermost' | 'rocketchat' | 'zulip' | 'farcaster' | 'tiktok' | 'crisp' | 'freshchat' | 'front' | 'gorgias' | 'kustomer' | 'helpscout' | 'livechat' | 'zohodesk' | 'hubspot' | 'zendesk' | 'salesforce' | 'webex' | 'chatwork' | 'google-chat' | 'zohocliq' | 'zoom' | 'line-works' | 'ringcentral' | 'vonage' | 'github' | 'gitlab' | 'bitbucket' | 'jira' | 'linear' | 'discourse';
|
|
337
|
+
/** Transports `createChannel` accepts — the whole union, since 0.30.0: the
|
|
338
|
+
* adapterless `internal-a2a` placeholder this type used to exclude was
|
|
339
|
+
* retired from the platform's union (design #24 / F-04). Kept as a named
|
|
340
|
+
* alias so existing imports compile unchanged. */
|
|
341
|
+
export type CreatableChannelType = ChannelTransportType;
|
|
340
342
|
/** Credentials for a connector, sealed server-side as one AES-GCM blob.
|
|
341
343
|
*
|
|
342
344
|
* `extra` is where the transports needing more than a token live — Twitter
|
|
@@ -888,6 +890,25 @@ export interface AdminClient {
|
|
|
888
890
|
freeHttp: boolean;
|
|
889
891
|
grantedDomains: string[];
|
|
890
892
|
}>>;
|
|
893
|
+
/** Per-tool confirm exemptions (免确认工具) — the tools an INSTANCE may call
|
|
894
|
+
* without a confirm card.
|
|
895
|
+
*
|
|
896
|
+
* The one knob a headless flow could not reach before 0.29.0, and for MCP
|
|
897
|
+
* skills it is not optional: `mcpRecord` hard-codes `platformSafe: false`,
|
|
898
|
+
* so every `run_skill` raises a confirm — and a platform instance has no
|
|
899
|
+
* human who could ever approve one (a synthetic uid has no Firebase user).
|
|
900
|
+
* Without this the skill installs, rate-limits and attaches cleanly and then
|
|
901
|
+
* answers nothing. Grant the READ tools (a storefront's `search_catalog` /
|
|
902
|
+
* `get_product`) and leave anything that mutates a cart or places an order
|
|
903
|
+
* gated.
|
|
904
|
+
*
|
|
905
|
+
* A full REPLACE, not a merge — pass the complete list every call. Names the
|
|
906
|
+
* skill does not declare are dropped and echoed back in `dropped`, so a typo
|
|
907
|
+
* is visible rather than silently ungranted. */
|
|
908
|
+
setSkillAutoRunTools(slug: string, toolNames: string[]): Promise<SkillKnobResult<{
|
|
909
|
+
autoRunTools: string[];
|
|
910
|
+
dropped: string[];
|
|
911
|
+
}>>;
|
|
891
912
|
uninstallSkill(slug: string): Promise<{
|
|
892
913
|
deleted: boolean;
|
|
893
914
|
}>;
|
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.
|
|
11
|
+
export const ADMIN_SDK_VERSION = '0.30.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;
|
|
@@ -72,6 +72,7 @@ export function requestDeadlineMs(method, path) {
|
|
|
72
72
|
export const ADMIN_ERROR_CODES = [
|
|
73
73
|
'story_contract_v2_write_disabled',
|
|
74
74
|
'story_contract_v3_write_disabled',
|
|
75
|
+
'story_contract_v4_write_disabled',
|
|
75
76
|
'episode_history_incomplete',
|
|
76
77
|
'episode_ended',
|
|
77
78
|
'idempotency_key_reused',
|
|
@@ -194,8 +195,9 @@ export function createAdminClient(opts) {
|
|
|
194
195
|
throw new AdminApiError('no fetch available — pass opts.fetch on Node <18', 0);
|
|
195
196
|
async function request(method, path, body) {
|
|
196
197
|
// An explicit host `timeoutMs` always wins (JS SDK contract); otherwise
|
|
197
|
-
// the deadline is sized to the ROUTE, so the
|
|
198
|
-
// `maxDuration: 300` are not cut at 30s while they
|
|
198
|
+
// the deadline is sized to the ROUTE, so the handlers that declare
|
|
199
|
+
// `maxDuration: 300` (LONG_WORK_REQUESTS) are not cut at 30s while they
|
|
200
|
+
// are still working.
|
|
199
201
|
// `??` (not `||`) is deliberate: 0 is a SET value meaning "no deadline",
|
|
200
202
|
// and it must not fall through to the route default.
|
|
201
203
|
const timeoutMs = opts.timeoutMs ?? requestDeadlineMs(method, path);
|
|
@@ -266,6 +268,7 @@ export function createAdminClient(opts) {
|
|
|
266
268
|
listSkills: () => request('GET', '/skills'),
|
|
267
269
|
installSkill: (input) => request('POST', '/skills', input),
|
|
268
270
|
updateSkill: (slug, patch) => request('PATCH', `/skills/${encodeURIComponent(slug)}`, patch),
|
|
271
|
+
setSkillAutoRunTools: (slug, toolNames) => request('PATCH', `/skills/${encodeURIComponent(slug)}`, { autoRunTools: toolNames }),
|
|
269
272
|
setSkillRate: (slug, ratePerMin) => request('PATCH', `/skills/${encodeURIComponent(slug)}`, { ratePerMin }),
|
|
270
273
|
setSkillDailyCap: (slug, maxCallsPerDay) => request('PATCH', `/skills/${encodeURIComponent(slug)}`, { maxCallsPerDay }),
|
|
271
274
|
compileSkill: (slug) => request('POST', `/skills/${encodeURIComponent(slug)}/compile`, {}),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pouchy_ai/admin-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.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",
|