@pouchy_ai/companion-sdk 0.22.0 → 0.24.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 +63 -0
- package/README.md +14 -5
- package/dist/client.d.ts +12 -2
- package/dist/client.js +26 -11
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/protocol.d.ts +6 -0
- package/dist/protocol.js +17 -0
- package/dist/scopes.js +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -12,6 +12,69 @@ a protocol bump is always called out explicitly here.
|
|
|
12
12
|
|
|
13
13
|
## [Unreleased]
|
|
14
14
|
|
|
15
|
+
## [0.24.0] - 2026-07-11
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- **`CompanionError.code` is now populated on EVERY helper, and the vocabulary
|
|
20
|
+
ships in the package.** `COMPANION_ERROR_CODES` (+ the `CompanionErrorCode`
|
|
21
|
+
type) is exported — the append-only HTTP `code` list the server emits
|
|
22
|
+
(`missing_scope`, `session_not_found`, `turn_pending`, …), drift-tested
|
|
23
|
+
against the server source. Previously only `postJson`-backed calls carried
|
|
24
|
+
`code`; the GET/stream helpers (`recall`, `history`, `setModalities`,
|
|
25
|
+
`ping`, `getAvatar`, `getWallet`, `pendingConfirms`, and `sendText`'s
|
|
26
|
+
streaming fallback) constructed `CompanionError` without it, so a
|
|
27
|
+
`missing_scope` 403 from `getWallet()` had `code === undefined`. All of them
|
|
28
|
+
now thread the server's `code` through — switch on it instead of matching
|
|
29
|
+
error prose.
|
|
30
|
+
|
|
31
|
+
### Changed (server-side, shipped with the platform)
|
|
32
|
+
|
|
33
|
+
- `GET …/history` now enforces the `chat` scope the API reference always
|
|
34
|
+
documented (a token without `chat` gets a 403 `missing_scope` instead of the
|
|
35
|
+
transcript).
|
|
36
|
+
- The `control.error` stream code `call_mint_failed` (voice-credential mint
|
|
37
|
+
failure) is now documented everywhere the other stream codes are.
|
|
38
|
+
|
|
39
|
+
### Docs
|
|
40
|
+
|
|
41
|
+
- `/sdk` REST quickstart now shows the REAL session → input flow (the previous
|
|
42
|
+
snippet showed a `POST /api/companion/message` endpoint that never existed)
|
|
43
|
+
and the 0.23.0 `argsJson` tool-handler form.
|
|
44
|
+
- OpenAPI: `history` response shape corrected to `{ ok, count, history }`;
|
|
45
|
+
`confirm` documents instance-token auth + the full
|
|
46
|
+
`{ status, outcome?, retryable? }` response; `end` summary reflects memory
|
|
47
|
+
consolidation.
|
|
48
|
+
- `wallet.read` scope comment no longer claims there is no standalone REST
|
|
49
|
+
endpoint (`GET /api/companion/wallet` shipped in 0.20.0).
|
|
50
|
+
|
|
51
|
+
## [0.23.0] - 2026-07-11
|
|
52
|
+
|
|
53
|
+
### Added
|
|
54
|
+
|
|
55
|
+
- **`onToolCall` hands you pre-parsed arguments.** The callback now receives a
|
|
56
|
+
`ToolCallEvent` — the `companion.tool_call` wire payload plus `argsJson`:
|
|
57
|
+
`args` pre-parsed as JSON (`undefined` when empty or malformed). Every tool
|
|
58
|
+
handler was re-implementing the same `try { JSON.parse(args) } catch {}`
|
|
59
|
+
boilerplate; now `const { item } = call.argsJson as {...}` just works, and the
|
|
60
|
+
raw `args` string is still there when you need the exact model output.
|
|
61
|
+
`ToolCallEvent` is exported. Backwards-compatible (the type extends
|
|
62
|
+
`ToolCallPayload`).
|
|
63
|
+
|
|
64
|
+
### Docs
|
|
65
|
+
|
|
66
|
+
- The `control.error` stream-plane code vocabulary (`agent_error`,
|
|
67
|
+
`stream_unauthorized`) is now documented in the protocol/API references, the
|
|
68
|
+
README event tables, and pouchy.ai/sdk — previously the codes were emitted
|
|
69
|
+
but listed nowhere.
|
|
70
|
+
- The pouchy.ai/sdk CDN snippet now uses the canonical self-hosted bundle URL
|
|
71
|
+
(`https://pouchy.ai/sdk/companion-sdk.js`) and includes the
|
|
72
|
+
`@elevenlabs/client` import-map entry voice needs.
|
|
73
|
+
- `openCompanionCall` / `VoiceToolBridge` (the advanced voice primitive
|
|
74
|
+
`connectCall`/`startCall` wrap) get a pointer in the package README.
|
|
75
|
+
|
|
76
|
+
No wire-protocol change (`PROTOCOL_VERSION` stays `1`).
|
|
77
|
+
|
|
15
78
|
## [0.22.0] - 2026-07-11
|
|
16
79
|
|
|
17
80
|
### Added
|
package/README.md
CHANGED
|
@@ -67,7 +67,7 @@ Subscribe with `on(type, fn)` (or `'*'`), or these typed convenience helpers:
|
|
|
67
67
|
| --- | --- | --- |
|
|
68
68
|
| `onMessage(fn)` | `companion.message` | the assistant reply (fires exactly once per turn, streaming or not) |
|
|
69
69
|
| `onDelta(fn)` | *(POST-response SSE)* | **token streaming** — registering makes `sendText` stream the reply as it is generated: `fn(chunk, {reset?})` fires per text chunk (`reset` = clear the partial — that text was tool-call deliberation); `onMessage` then fires once with the authoritative final text (replay-deduplicated). Force per call with `sendText(text, { stream: true \| false })` |
|
|
70
|
-
| `onToolCall(fn)` | `companion.tool_call` | the companion asks your app to run a declared tool → `sendToolResult` |
|
|
70
|
+
| `onToolCall(fn)` | `companion.tool_call` | the companion asks your app to run a declared tool → `sendToolResult`. The call carries `argsJson` — `args` pre-parsed as JSON (undefined on empty/malformed args) |
|
|
71
71
|
| `onRender(fn)` | `companion.ui_action` | **Instant UI** — draw `payload.interface` (platform-neutral genui schema) with your own renderer (web / iOS / Android / CLI). Needs `ui.render` |
|
|
72
72
|
| `onInterfaceUpdate(fn)` | `companion.ui_update` | live `{key,value}` update to an already-rendered panel (no rebuild) |
|
|
73
73
|
| `onSocialMessage(fn)` | `companion.social_message` | inbound A2A friend message, delivered cross-app. Needs `social.message` |
|
|
@@ -77,7 +77,7 @@ Subscribe with `on(type, fn)` (or `'*'`), or these typed convenience helpers:
|
|
|
77
77
|
| `onVoiceInject(fn)` | `companion.voice_inject` | `fn({text, speak})` — a `voiceRelevant` world-state line to say aloud during a live call; route `text` to your voice session when `speak` |
|
|
78
78
|
| `onTyping(fn)` | `companion.typing` | activity indicator — `fn({active})` fires `true` when a turn starts working and `false` when it finishes / pauses, spanning the tool-loop / thinking phase before the first text delta. Drive a "typing…" state |
|
|
79
79
|
| `onUsage(fn)` | `control.usage` | per-token metering echo. _(reserved — not emitted yet)_ |
|
|
80
|
-
| `onError(fn)` | `control.error` | agent / stream errors |
|
|
80
|
+
| `onError(fn)` | `control.error` | agent / stream errors — `agent_error` (server-side turn failed after accept; safe to re-send), `call_mint_failed` (voice-credential mint failed — retry later or fall back to text) or the SDK-synthesized `stream_unauthorized` (stream 401 exhausted reconnects — refresh the token, `start()` again) |
|
|
81
81
|
|
|
82
82
|
### Instant UI
|
|
83
83
|
|
|
@@ -141,10 +141,19 @@ exported: `COMPANION_MODALITIES`, `REPRESENT_SCOPES`, `DEFAULT_MODALITIES`,
|
|
|
141
141
|
the SDK's drift test.
|
|
142
142
|
|
|
143
143
|
The wire-protocol runtime constants are exported too — `PROTOCOL_VERSION`,
|
|
144
|
-
`INBOUND_TYPES`, and `
|
|
145
|
-
|
|
144
|
+
`INBOUND_TYPES`, `OUTBOUND_TYPES`, and `COMPANION_ERROR_CODES` (the append-only
|
|
145
|
+
HTTP `code` vocabulary behind `CompanionError.code`, e.g. `missing_scope` /
|
|
146
|
+
`session_not_found` / `turn_pending`) — so you can assert the version, validate
|
|
147
|
+
the event vocabulary, or switch on error codes without hard-coding strings.
|
|
148
|
+
Every helper populates `CompanionError.code` when the server names a cause
|
|
149
|
+
(0.24.0 — previously only the POST-backed calls did). Every
|
|
146
150
|
outbound payload has a named type; `ToolCallPayload` (`{ id, name, args }`) types
|
|
147
|
-
the `companion.tool_call` event and `onToolCall`'s callback
|
|
151
|
+
the `companion.tool_call` event, and `onToolCall`'s callback receives
|
|
152
|
+
`ToolCallEvent` — the payload plus `argsJson` (pre-parsed args).
|
|
153
|
+
|
|
154
|
+
For advanced voice hosts, the lower-level `openCompanionCall(client, options)`
|
|
155
|
+
primitive that `connectCall`/`startCall` wrap is exported too (bring-your-own
|
|
156
|
+
call lifecycle; see `docs/companion-integration-faq.md`).
|
|
148
157
|
|
|
149
158
|
## Representative mode (代聊)
|
|
150
159
|
|
package/dist/client.d.ts
CHANGED
|
@@ -75,6 +75,13 @@ export interface CompanionToolDecl {
|
|
|
75
75
|
description?: string;
|
|
76
76
|
parameters?: Record<string, unknown>;
|
|
77
77
|
}
|
|
78
|
+
/** What `onToolCall` hands your handler: the `companion.tool_call` wire payload
|
|
79
|
+
* plus `argsJson` — `args` pre-parsed as JSON. `undefined` when `args` is
|
|
80
|
+
* empty or not valid JSON; keep reading the raw `args` string when you need
|
|
81
|
+
* the exact model output. */
|
|
82
|
+
export interface ToolCallEvent extends ToolCallPayload {
|
|
83
|
+
argsJson?: unknown;
|
|
84
|
+
}
|
|
78
85
|
/** Voice-plane credentials, discriminated by provider (see startCall). */
|
|
79
86
|
export type CallCredentials = {
|
|
80
87
|
provider: 'elevenlabs-convai';
|
|
@@ -332,8 +339,11 @@ export declare class CompanionClient {
|
|
|
332
339
|
* string fed back to the voice model. Times out so a missing result can't
|
|
333
340
|
* hang the call. */
|
|
334
341
|
private invokeVoiceTool;
|
|
335
|
-
/** Convenience: subscribe to tool-call requests from the companion.
|
|
336
|
-
|
|
342
|
+
/** Convenience: subscribe to tool-call requests from the companion. The call
|
|
343
|
+
* carries the wire payload plus `argsJson` — `args` pre-parsed as JSON
|
|
344
|
+
* (undefined when empty or malformed), so handlers don't each re-implement
|
|
345
|
+
* the same try/catch around `JSON.parse(args)`. */
|
|
346
|
+
onToolCall(handler: (call: ToolCallEvent, envelope: CompanionEnvelope) => void): () => void;
|
|
337
347
|
/** Convenience: subscribe to errors the companion surfaces — server-side agent
|
|
338
348
|
* errors and stream failures (e.g. a permanent `stream_unauthorized`) both
|
|
339
349
|
* arrive as `control.error`. Returns an unsubscribe fn. */
|
package/dist/client.js
CHANGED
|
@@ -15,6 +15,17 @@
|
|
|
15
15
|
import { PROTOCOL_VERSION } from './protocol.js';
|
|
16
16
|
import { parseSse } from './sse.js';
|
|
17
17
|
import { openCompanionCall, HOST_CONTROL_TOOLS, HOST_CONTROL_TOOL_NAMES, AVATAR_VISUAL_TOOLS, AVATAR_VISUAL_TOOL_NAMES } from './call.js';
|
|
18
|
+
/** Model tool arguments are model output — tolerate junk without throwing. */
|
|
19
|
+
function parseArgsJson(args) {
|
|
20
|
+
if (!args.trim())
|
|
21
|
+
return undefined;
|
|
22
|
+
try {
|
|
23
|
+
return JSON.parse(args);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
18
29
|
/** Canonical URL of the official Pouchy brand icon at `size` px, derived from a
|
|
19
30
|
* deployment origin. Standalone (no client/token needed) so a surface can show
|
|
20
31
|
* the Pouchy mark before/without connecting. */
|
|
@@ -202,7 +213,7 @@ export class CompanionClient {
|
|
|
202
213
|
// Old server / error before the stream opened — behave like postJson.
|
|
203
214
|
const json = (await res.json().catch(() => null));
|
|
204
215
|
if (!res.ok || !json || json.ok === false) {
|
|
205
|
-
throw new CompanionError(json?.error || `request failed (${res.status})`, res.status);
|
|
216
|
+
throw new CompanionError(json?.error || `request failed (${res.status})`, res.status, json?.code);
|
|
206
217
|
}
|
|
207
218
|
return { seq: json.seq ?? null };
|
|
208
219
|
}
|
|
@@ -239,7 +250,7 @@ export class CompanionClient {
|
|
|
239
250
|
/* stream already finished */
|
|
240
251
|
}
|
|
241
252
|
if (d.ok === false) {
|
|
242
|
-
throw new CompanionError(d.error || 'turn failed', d.status ?? 500);
|
|
253
|
+
throw new CompanionError(d.error || 'turn failed', d.status ?? 500, d.code);
|
|
243
254
|
}
|
|
244
255
|
// Emit the final envelope NOW so onMessage fires with zero poll
|
|
245
256
|
// latency; the event-stream replay of the same id is deduped.
|
|
@@ -501,12 +512,16 @@ export class CompanionClient {
|
|
|
501
512
|
});
|
|
502
513
|
});
|
|
503
514
|
}
|
|
504
|
-
/** Convenience: subscribe to tool-call requests from the companion.
|
|
515
|
+
/** Convenience: subscribe to tool-call requests from the companion. The call
|
|
516
|
+
* carries the wire payload plus `argsJson` — `args` pre-parsed as JSON
|
|
517
|
+
* (undefined when empty or malformed), so handlers don't each re-implement
|
|
518
|
+
* the same try/catch around `JSON.parse(args)`. */
|
|
505
519
|
onToolCall(handler) {
|
|
506
520
|
return this.on('companion.tool_call', (env) => {
|
|
507
521
|
const p = env.payload;
|
|
508
522
|
if (typeof p?.id === 'string' && typeof p?.name === 'string') {
|
|
509
|
-
|
|
523
|
+
const args = typeof p.args === 'string' ? p.args : '';
|
|
524
|
+
handler({ id: p.id, name: p.name, args, argsJson: parseArgsJson(args) }, env);
|
|
510
525
|
}
|
|
511
526
|
});
|
|
512
527
|
}
|
|
@@ -540,7 +555,7 @@ export class CompanionClient {
|
|
|
540
555
|
});
|
|
541
556
|
const json = (await res.json().catch(() => null));
|
|
542
557
|
if (!res.ok || !json || json.ok === false) {
|
|
543
|
-
throw new CompanionError(json?.error || `recall failed (${res.status})`, res.status);
|
|
558
|
+
throw new CompanionError(json?.error || `recall failed (${res.status})`, res.status, json?.code);
|
|
544
559
|
}
|
|
545
560
|
return json.memories ?? [];
|
|
546
561
|
}
|
|
@@ -555,7 +570,7 @@ export class CompanionClient {
|
|
|
555
570
|
const res = await this.fetchAuthed(this.url(`/api/companion/session/${encodeURIComponent(id)}/history${qs}`), { headers: { Authorization: `Bearer ${this.opts.token}` } });
|
|
556
571
|
const json = (await res.json().catch(() => null));
|
|
557
572
|
if (!res.ok || !json || json.ok === false) {
|
|
558
|
-
throw new CompanionError(json?.error || `history failed (${res.status})`, res.status);
|
|
573
|
+
throw new CompanionError(json?.error || `history failed (${res.status})`, res.status, json?.code);
|
|
559
574
|
}
|
|
560
575
|
return json.history ?? [];
|
|
561
576
|
}
|
|
@@ -575,7 +590,7 @@ export class CompanionClient {
|
|
|
575
590
|
});
|
|
576
591
|
const json = (await res.json().catch(() => null));
|
|
577
592
|
if (!res.ok || !json || json.ok === false) {
|
|
578
|
-
throw new CompanionError(json?.error || `setModalities failed (${res.status})`, res.status);
|
|
593
|
+
throw new CompanionError(json?.error || `setModalities failed (${res.status})`, res.status, json?.code);
|
|
579
594
|
}
|
|
580
595
|
return { modalities: json.modalities ?? modalities };
|
|
581
596
|
}
|
|
@@ -587,7 +602,7 @@ export class CompanionClient {
|
|
|
587
602
|
const res = await this.fetchAuthed(this.url(`/api/companion/session/${encodeURIComponent(id)}/ping`), { method: 'POST', headers: { Authorization: `Bearer ${this.opts.token}` } });
|
|
588
603
|
if (!res.ok) {
|
|
589
604
|
const json = (await res.json().catch(() => null));
|
|
590
|
-
throw new CompanionError(json?.error || `ping failed (${res.status})`, res.status);
|
|
605
|
+
throw new CompanionError(json?.error || `ping failed (${res.status})`, res.status, json?.code);
|
|
591
606
|
}
|
|
592
607
|
}
|
|
593
608
|
/** Remember a fact (into this app's namespace unless `namespace` is given and
|
|
@@ -634,7 +649,7 @@ export class CompanionClient {
|
|
|
634
649
|
});
|
|
635
650
|
const json = (await res.json().catch(() => null));
|
|
636
651
|
if (!res.ok || !json || json.ok === false) {
|
|
637
|
-
throw new CompanionError(json?.error || `avatar fetch failed (${res.status})`, res.status);
|
|
652
|
+
throw new CompanionError(json?.error || `avatar fetch failed (${res.status})`, res.status, json?.code);
|
|
638
653
|
}
|
|
639
654
|
return {
|
|
640
655
|
name: json.name ?? null,
|
|
@@ -655,7 +670,7 @@ export class CompanionClient {
|
|
|
655
670
|
});
|
|
656
671
|
const json = (await res.json().catch(() => null));
|
|
657
672
|
if (!res.ok || !json || json.ok === false) {
|
|
658
|
-
throw new CompanionError(json?.error || `wallet fetch failed (${res.status})`, res.status);
|
|
673
|
+
throw new CompanionError(json?.error || `wallet fetch failed (${res.status})`, res.status, json?.code);
|
|
659
674
|
}
|
|
660
675
|
return {
|
|
661
676
|
balances: json.balances ?? [],
|
|
@@ -769,7 +784,7 @@ export class CompanionClient {
|
|
|
769
784
|
const res = await this.fetchAuthed(this.url(`/api/companion/session/${encodeURIComponent(sessionId)}/confirm`), { headers: { Authorization: `Bearer ${this.opts.token}` } });
|
|
770
785
|
const json = (await res.json().catch(() => null));
|
|
771
786
|
if (!res.ok || !json || json.ok === false) {
|
|
772
|
-
throw new CompanionError(json?.error || `pending confirms failed (${res.status})`, res.status);
|
|
787
|
+
throw new CompanionError(json?.error || `pending confirms failed (${res.status})`, res.status, json?.code);
|
|
773
788
|
}
|
|
774
789
|
return json.pending ?? [];
|
|
775
790
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { CompanionClient, type CompanionClientOptions } from './client.js';
|
|
2
2
|
export { CompanionClient, CompanionError, pouchyBrandIconUrl } from './client.js';
|
|
3
|
-
export type { CompanionClientOptions, HelloAck, RecalledMemory, CompanionTurn, CallCredentials, CompanionToolDecl, WorldStateInput, CompanionAvatar, CompanionWallet, WalletBalance, BrandIconSize, EndSessionResult } from './client.js';
|
|
3
|
+
export type { CompanionClientOptions, HelloAck, RecalledMemory, CompanionTurn, CallCredentials, CompanionToolDecl, ToolCallEvent, WorldStateInput, CompanionAvatar, CompanionWallet, WalletBalance, BrandIconSize, EndSessionResult } from './client.js';
|
|
4
4
|
export { openCompanionCall, HOST_CONTROL_TOOLS, HOST_CONTROL_TOOL_NAMES, AVATAR_VISUAL_TOOLS, AVATAR_VISUAL_TOOL_NAMES } from './call.js';
|
|
5
5
|
export type { CompanionCall, CompanionCallOptions, VoiceToolBridge } from './call.js';
|
|
6
6
|
export { COMPANION_SCOPES, COMPANION_MODALITIES, SENSITIVE_SCOPES, REPRESENT_SCOPES, DEFAULT_SCOPES, DEFAULT_MODALITIES, isSensitiveScope, isRepresentScope, hasScope } from './scopes.js';
|
|
7
7
|
export type { CompanionScope, CompanionModality } from './scopes.js';
|
|
8
8
|
export type { CompanionEnvelope, OutboundType, InboundType, WorldStateEvent, RenderInterfacePayload, InterfaceUpdatePayload, SocialMessagePayload, ConfirmRequestPayload, PendingConfirm, ToolCallPayload, AudioClipPayload, ExpressionPayload, TypingPayload, VoiceInjectPayload, UsagePayload } from './protocol.js';
|
|
9
|
-
export { PROTOCOL_VERSION, INBOUND_TYPES, OUTBOUND_TYPES } from './protocol.js';
|
|
9
|
+
export { PROTOCOL_VERSION, INBOUND_TYPES, OUTBOUND_TYPES, COMPANION_ERROR_CODES } from './protocol.js';
|
|
10
|
+
export type { CompanionErrorCode } from './protocol.js';
|
|
10
11
|
/** Create a companion client. */
|
|
11
12
|
export declare function createCompanion(opts: CompanionClientOptions): CompanionClient;
|
package/dist/index.js
CHANGED
|
@@ -15,7 +15,7 @@ export { openCompanionCall, HOST_CONTROL_TOOLS, HOST_CONTROL_TOOL_NAMES, AVATAR_
|
|
|
15
15
|
export { COMPANION_SCOPES, COMPANION_MODALITIES, SENSITIVE_SCOPES, REPRESENT_SCOPES, DEFAULT_SCOPES, DEFAULT_MODALITIES, isSensitiveScope, isRepresentScope, hasScope } from './scopes.js';
|
|
16
16
|
// Runtime protocol constants — so a host can assert PROTOCOL_VERSION or
|
|
17
17
|
// enumerate/validate the event vocabulary without hard-coding the strings.
|
|
18
|
-
export { PROTOCOL_VERSION, INBOUND_TYPES, OUTBOUND_TYPES } from './protocol.js';
|
|
18
|
+
export { PROTOCOL_VERSION, INBOUND_TYPES, OUTBOUND_TYPES, COMPANION_ERROR_CODES } from './protocol.js';
|
|
19
19
|
/** Create a companion client. */
|
|
20
20
|
export function createCompanion(opts) {
|
|
21
21
|
return new CompanionClient(opts);
|
package/dist/protocol.d.ts
CHANGED
|
@@ -12,6 +12,12 @@ export type InboundType = (typeof INBOUND_TYPES)[number];
|
|
|
12
12
|
export declare const OUTBOUND_TYPES: readonly ["hello.ack", "companion.message", "companion.audio", "companion.tool_call", "companion.ui_action", "companion.ui_update", "companion.expression", "companion.voice_inject", "companion.confirm_request", "companion.social_message", "companion.typing", "control.call_ready", "control.error", "control.usage"];
|
|
13
13
|
export type OutboundType = (typeof OUTBOUND_TYPES)[number];
|
|
14
14
|
export type MessageType = InboundType | OutboundType;
|
|
15
|
+
/** HTTP error `code` vocabulary — what `CompanionError.code` can hold. A
|
|
16
|
+
* self-contained mirror of the server's api-error.ts list (drift-tested);
|
|
17
|
+
* APPEND-ONLY: renaming or removing a code is a breaking SDK change.
|
|
18
|
+
* Consumers can switch on these instead of string-matching error prose. */
|
|
19
|
+
export declare const COMPANION_ERROR_CODES: readonly ["missing_token", "invalid_token", "missing_scope", "invalid_request", "session_not_found", "turn_pending", "no_pending_tools", "unknown_call", "payload_too_large", "forbidden", "unavailable"];
|
|
20
|
+
export type CompanionErrorCode = (typeof COMPANION_ERROR_CODES)[number];
|
|
15
21
|
/** The single envelope every control/data-plane message shares. */
|
|
16
22
|
export interface CompanionEnvelope<T = unknown> {
|
|
17
23
|
v: typeof PROTOCOL_VERSION;
|
package/dist/protocol.js
CHANGED
|
@@ -40,3 +40,20 @@ export const OUTBOUND_TYPES = [
|
|
|
40
40
|
'control.error',
|
|
41
41
|
'control.usage' // reserved — not emitted yet
|
|
42
42
|
];
|
|
43
|
+
/** HTTP error `code` vocabulary — what `CompanionError.code` can hold. A
|
|
44
|
+
* self-contained mirror of the server's api-error.ts list (drift-tested);
|
|
45
|
+
* APPEND-ONLY: renaming or removing a code is a breaking SDK change.
|
|
46
|
+
* Consumers can switch on these instead of string-matching error prose. */
|
|
47
|
+
export const COMPANION_ERROR_CODES = [
|
|
48
|
+
'missing_token', // 401 — no Authorization: Bearer header
|
|
49
|
+
'invalid_token', // 401 — token unknown, revoked, or expired
|
|
50
|
+
'missing_scope', // 403 — token lacks a required grant
|
|
51
|
+
'invalid_request', // 400 — malformed JSON / missing or invalid fields
|
|
52
|
+
'session_not_found', // 404 — sessionId expired or never started
|
|
53
|
+
'turn_pending', // 409 — a turn is paused awaiting tool results
|
|
54
|
+
'no_pending_tools', // 409 — tool result posted but nothing is pending
|
|
55
|
+
'unknown_call', // 404 — tool result for a callId the turn didn't issue
|
|
56
|
+
'payload_too_large', // 413 — body/image over the documented cap
|
|
57
|
+
'forbidden', // 403 — authorization denial other than a missing scope
|
|
58
|
+
'unavailable' // 503 — backing store/provider not configured or down
|
|
59
|
+
];
|
package/dist/scopes.js
CHANGED
|
@@ -21,7 +21,7 @@ export const COMPANION_SCOPES = [
|
|
|
21
21
|
'memory.read:core', // read the shared global brain (SENSITIVE)
|
|
22
22
|
'memory.write:core', // write into the shared global brain (SENSITIVE)
|
|
23
23
|
'skills.execute', // run the user's installed skills (SENSITIVE)
|
|
24
|
-
'wallet.read', // READ-ONLY wallet: balance + own deposit address (receive-only; not sensitive).
|
|
24
|
+
'wallet.read', // READ-ONLY wallet: balance + own deposit address (receive-only; not sensitive). GET /api/companion/wallet (SDK: getWallet(), 0.20.0+) or ask the companion's wallet tools.
|
|
25
25
|
'wallet.spend', // spend from the Care Wallet (SENSITIVE)
|
|
26
26
|
'social.message', // message friends via A2A (SENSITIVE)
|
|
27
27
|
// ── Representative ("on-behalf-of") plane ─────────────────────────────
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pouchy_ai/companion-sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Embed the Pouchy companion
|
|
3
|
+
"version": "0.24.0",
|
|
4
|
+
"description": "Embed the Pouchy companion \u2014 chat, voice, tools, memory, live world-state, instant UI, and agent-to-agent messaging \u2014 in any app, game, or site.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
7
7
|
"homepage": "https://pouchy.ai",
|