@pouchy_ai/admin-sdk 0.15.1 → 0.16.1

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,57 @@
2
2
 
3
3
  All notable changes to `@pouchy_ai/admin-sdk` are documented here.
4
4
 
5
+ ## 0.16.1 — 2026-08-06
6
+
7
+ Documentation only — no type, signature or runtime change. Two doc comments
8
+ were describing a contract the server does not have.
9
+
10
+ - **`updateSkill` said the response echoes "the knob(s) you changed".** It is
11
+ one knob per call. `PATCH /skills/{slug}` disambiguates by payload, so a
12
+ patch naming two groups — `{ ratePerMin, maxCallsPerDay }` — used to perform
13
+ whichever the server checked first and silently drop the rest under a `200`.
14
+ The plural in this package's own doc invited exactly that call. The server
15
+ now refuses an ambiguous body with a `400` naming the groups it found, and
16
+ the doc states the rule. `{ freeHttp, grantedDomains }` remains ONE knob (a
17
+ single write), not two.
18
+
19
+ The typed conveniences (`setSkillRate`, `setSkillDailyCap`, `grantSkill`)
20
+ were never affected — each sends exactly one knob by construction. Only a
21
+ hand-built `updateSkill` patch could reach it.
22
+
23
+ - **`grantSkill` is a full REPLACE and did not say so.** `grantedDomains` is
24
+ optional in the signature, which reads as "leave it alone"; it is sent as
25
+ `[]` when omitted, clearing the extra allowlist. Pass the domains you want to
26
+ end up with on every call. (The manifest's own `allowed_domains` is a
27
+ separate list and is never touched by this call.)
28
+
29
+ ## 0.16.0 — 2026-08-06
30
+
31
+ - **Catches the package up to a server change that already shipped.**
32
+ `PATCH /skills/{slug}` with `{ ratePerMin }` used to be the only skill knob
33
+ that did not push the updated def to the project's running instances — and the
34
+ per-minute budget is read off each instance's provisioned def, not the record
35
+ the PATCH writes, so a rate you set persisted, echoed back on read, and reached
36
+ **no running agent** until an unrelated persona edit bumped the agent's
37
+ `templateRev`. That was fixed server-side, and every knob now also returns
38
+ `truncated`. This package still typed the old shapes — `setSkillRate` as
39
+ `Promise<{ ratePerMin }>`, the other two without `truncated` — so the typed
40
+ client was asserting a contract the server had already stopped honouring.
41
+
42
+ - **New `SkillKnobResult<T>` — every skill knob returns `reprovisioned` and
43
+ `truncated`.** `setSkillRate`, `setSkillDailyCap` and `grantSkill` now share
44
+ one result shape. `truncated: true` means the re-push swept its cap (100
45
+ agents / 200 instances) and the remainder were NOT refreshed — and they do not
46
+ catch up on their next session, they keep the OLD def until a persona edit
47
+ bumps `templateRev`. **A revoking call that returns `truncated: true` is a
48
+ PARTIAL revocation**; re-issue it or make a persona edit before treating it as
49
+ complete.
50
+
51
+ Additive and backward compatible: the previously-returned fields are all still
52
+ present with the same names and types, so existing destructuring keeps
53
+ compiling. Only widen your own annotations if you had hand-written the old
54
+ return types.
55
+
5
56
  ## 0.15.1 — 2026-08-03
6
57
 
7
58
  - **Docs fix: `MonthUsage.mauLimit` prescribed a call that does not compile.**
package/README.md CHANGED
@@ -58,6 +58,14 @@ console.log(`armed — ${armed.reprovisioned} running instance(s) updated`);
58
58
  // The agent can now drive the API from the skill's prose via http_request.
59
59
  ```
60
60
 
61
+ Every skill knob (`setSkillRate`, `setSkillDailyCap`, `grantSkill`) returns
62
+ `SkillKnobResult<T>` — the knob you set plus `reprovisioned` (instances the new
63
+ def reached) and `truncated`. A knob only binds a running agent once the def
64
+ reaches its instance, so `truncated: true` means the sweep hit its cap (100
65
+ agents / 200 instances) and the remainder still hold the **old** def; they do
66
+ not catch up on their next session. Treat a *revoking* call that returns
67
+ `truncated: true` as a partial revocation and re-issue it.
68
+
61
69
  ## Options
62
70
 
63
71
  ```ts
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export declare const ADMIN_SDK_VERSION = "0.15.1";
1
+ export declare const ADMIN_SDK_VERSION = "0.16.1";
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
@@ -421,6 +421,21 @@ export interface AdminRun {
421
421
  createdAt: string;
422
422
  updatedAt: string;
423
423
  }
424
+ /** What every skill-knob PATCH reports about the re-push, on top of the knob it
425
+ * echoes. A knob only takes effect on a running agent once the def reaches its
426
+ * instance, so these two fields are the outcome, not decoration.
427
+ *
428
+ * `reprovisioned` — instances refreshed by this call.
429
+ * `truncated` — the sweep hit a cap (100 agents / 200 instances) and the
430
+ * remainder were NOT refreshed. They do not catch up on their next session:
431
+ * they keep the OLD def until a persona edit bumps the agent's templateRev. So
432
+ * a revoking call (e.g. clearing a grant) that returns `truncated: true` is a
433
+ * PARTIAL revocation — re-issue it, or make a persona edit, before treating it
434
+ * as complete. */
435
+ export type SkillKnobResult<T> = T & {
436
+ reprovisioned: number;
437
+ truncated: boolean;
438
+ };
424
439
  export interface AdminClient {
425
440
  listAgents(): Promise<{
426
441
  agents: Agent[];
@@ -656,23 +671,30 @@ export interface AdminClient {
656
671
  version: number;
657
672
  };
658
673
  }>;
659
- /** Generic PATCH of a skill's knobs. The response echoes only the knob(s)
660
- * you changed (e.g. `{ ratePerMin }`, `{ maxCallsPerDay, reprovisioned }`,
661
- * `{ freeHttp, grantedDomains, reprovisioned }`) prefer the typed
662
- * conveniences (setSkillRate / setSkillDailyCap / grantSkill) for a precise
674
+ /** Generic PATCH of a skill's knobs. **Exactly ONE knob per call** — the
675
+ * endpoint disambiguates by payload, so a patch naming two (say
676
+ * `{ ratePerMin, maxCallsPerDay }`) is refused with 400 rather than
677
+ * half-applied. `{ freeHttp, grantedDomains }` is one knob, not two: the
678
+ * grant is a single write. The response echoes the knob you changed plus
679
+ * the re-push outcome every knob carries (`reprovisioned`, `truncated`).
680
+ * Prefer the typed conveniences (setSkillRate / setSkillDailyCap /
681
+ * grantSkill) — they are one knob each by construction and give a precise
663
682
  * return type. */
664
683
  updateSkill(slug: string, patch: Record<string, unknown>): Promise<Record<string, unknown>>;
665
- /** Set a skill's per-minute call budget (1..120; null restores the default). */
666
- setSkillRate(slug: string, ratePerMin: number | null): Promise<{
684
+ /** Set a skill's per-minute call budget (1..120; null restores the default).
685
+ * Re-pushes the def to running instances — the limiter reads the budget off
686
+ * each instance's provisioned def, so a saved rate that was not re-pushed
687
+ * reached no running agent (server-side fix; this signature now carries the
688
+ * outcome the other knobs already returned). */
689
+ setSkillRate(slug: string, ratePerMin: number | null): Promise<SkillKnobResult<{
667
690
  ratePerMin: number | null;
668
- }>;
691
+ }>>;
669
692
  /** Set a skill's opt-in daily call ceiling — max HTTP calls per rolling 24h
670
693
  * (1..20000; null clears it, leaving only the per-minute cap). A runaway
671
694
  * guard for autonomous outbound. Re-pushes the def to running instances. */
672
- setSkillDailyCap(slug: string, maxCallsPerDay: number | null): Promise<{
695
+ setSkillDailyCap(slug: string, maxCallsPerDay: number | null): Promise<SkillKnobResult<{
673
696
  maxCallsPerDay: number | null;
674
- reprovisioned: number;
675
- }>;
697
+ }>>;
676
698
  /** Compile a docs-only skill's prose (curl snippets / endpoint tables) into
677
699
  * declared `http` tools via a one-shot LLM, then re-install the result
678
700
  * (safety gate + version archive → reversible via rollback). Each tool is
@@ -690,15 +712,19 @@ export interface AdminClient {
690
712
  * `allowed_domains` ∪ `grantedDomains`. This is how a docs-only skill
691
713
  * (no `tools:` block) becomes runnable — install it, attach it to an agent
692
714
  * (`updateAgent(id, { skills: [...] })`), then grant it here. The new def is
693
- * re-pushed to running instances; `reprovisioned` is how many were updated. */
715
+ * re-pushed to running instances; `reprovisioned` is how many were updated.
716
+ *
717
+ * This is a full REPLACE of the grant, not a merge: omitting
718
+ * `grantedDomains` sends `[]` and clears the extra allowlist (the manifest's
719
+ * own `allowed_domains` is unaffected). Pass the domains you want to end up
720
+ * with on every call. */
694
721
  grantSkill(slug: string, grant: {
695
722
  freeHttp: boolean;
696
723
  grantedDomains?: string[];
697
- }): Promise<{
724
+ }): Promise<SkillKnobResult<{
698
725
  freeHttp: boolean;
699
726
  grantedDomains: string[];
700
- reprovisioned: number;
701
- }>;
727
+ }>>;
702
728
  uninstallSkill(slug: string): Promise<{
703
729
  deleted: boolean;
704
730
  }>;
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.15.1';
11
+ export const ADMIN_SDK_VERSION = '0.16.1';
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pouchy_ai/admin-sdk",
3
- "version": "0.15.1",
3
+ "version": "0.16.1",
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",