@pouchy_ai/companion-sdk 0.10.0 → 0.11.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 +38 -1
- package/dist/call.js +44 -6
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +14 -3
package/CHANGELOG.md
CHANGED
|
@@ -12,6 +12,40 @@ a protocol bump is always called out explicitly here.
|
|
|
12
12
|
|
|
13
13
|
## [Unreleased]
|
|
14
14
|
|
|
15
|
+
## [0.11.0] - 2026-07-02
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- **`AVATAR_VISUAL_TOOLS` / `AVATAR_VISUAL_TOOL_NAMES` are now exported from the
|
|
20
|
+
package entry point.** `docs/companion-host-control.md` has documented these
|
|
21
|
+
since the avatar-emote work, but the public `index.ts` never re-exported them —
|
|
22
|
+
hosts that wanted to filter or inspect the avatar visual tool set had to
|
|
23
|
+
reach into internal module paths. Additive; no behavior change.
|
|
24
|
+
|
|
25
|
+
### Docs
|
|
26
|
+
|
|
27
|
+
- The protocol document now reflects the shipped transport reality: REST + SSE
|
|
28
|
+
is the live control/data plane, `stream: 'websocket'` is a client-side option
|
|
29
|
+
that automatically falls back to SSE (the server WebSocket endpoint is not
|
|
30
|
+
yet available), and the server agent loop is live. The voice and poker
|
|
31
|
+
integration guides now install the SDK from npm instead of a local build /
|
|
32
|
+
bundled tarball.
|
|
33
|
+
|
|
34
|
+
## [0.10.1] - 2026-06-29
|
|
35
|
+
|
|
36
|
+
### Fixed
|
|
37
|
+
|
|
38
|
+
- **Voice calls no longer drop on a transient network blip.** A WebRTC
|
|
39
|
+
`connectionState` of `disconnected` is transient per spec — a brief Wi-Fi
|
|
40
|
+
hiccup or cell handoff routinely hits it and recovers to `connected` on its
|
|
41
|
+
own. `connectCall()` previously tore the call down the instant `disconnected`
|
|
42
|
+
appeared, killing calls that would have healed. It now holds a short grace
|
|
43
|
+
window (6s) and only tears down if the connection is still `disconnected` when
|
|
44
|
+
it elapses; recovery to `connected` cancels the teardown. `failed` / `closed`
|
|
45
|
+
remain immediately fatal, and a genuine silent drop still tears down (so the
|
|
46
|
+
mic can't keep recording). No surface change — `connectCall` signature,
|
|
47
|
+
events, payloads, and scopes are unchanged.
|
|
48
|
+
|
|
15
49
|
## [0.10.0] - 2026-06-28
|
|
16
50
|
|
|
17
51
|
Completes the SDK surface for all six companion capabilities, with Instant UI and
|
|
@@ -82,5 +116,8 @@ self-hosted/CDN build; this entry captures the surface that ships publicly.
|
|
|
82
116
|
- **Versioned wire protocol.** `PROTOCOL_VERSION = 1`, kept in lockstep with the
|
|
83
117
|
server by `protocol.drift.test.ts` (fails CI on divergence).
|
|
84
118
|
|
|
85
|
-
[Unreleased]: https://github.com/oviswang/Pouchy/compare/companion-sdk-v0.
|
|
119
|
+
[Unreleased]: https://github.com/oviswang/Pouchy/compare/companion-sdk-v0.11.0...HEAD
|
|
120
|
+
[0.11.0]: https://github.com/oviswang/Pouchy/compare/companion-sdk-v0.10.1...companion-sdk-v0.11.0
|
|
121
|
+
[0.10.1]: https://github.com/oviswang/Pouchy/compare/companion-sdk-v0.10.0...companion-sdk-v0.10.1
|
|
122
|
+
[0.10.0]: https://github.com/oviswang/Pouchy/compare/companion-sdk-v0.9.0...companion-sdk-v0.10.0
|
|
86
123
|
[0.9.0]: https://github.com/oviswang/Pouchy/releases/tag/companion-sdk-v0.9.0
|
package/dist/call.js
CHANGED
|
@@ -302,10 +302,26 @@ async function openOpenAICall(creds, opts, bridge) {
|
|
|
302
302
|
}
|
|
303
303
|
await pc.setRemoteDescription({ type: 'answer', sdp: await res.text() });
|
|
304
304
|
let closed = false;
|
|
305
|
+
// `disconnected` is TRANSIENT per the WebRTC spec — a brief Wi-Fi hiccup or a
|
|
306
|
+
// cell handoff routinely drops to `disconnected` and recovers to `connected`
|
|
307
|
+
// on its own. Tearing down the instant it appears killed calls that would have
|
|
308
|
+
// healed (field report: SDK voice "动不动就掉线"). Give it a grace window to
|
|
309
|
+
// come back; only if it's STILL disconnected when the timer fires do we tear
|
|
310
|
+
// down — so the mic still can't record forever on a genuine silent drop (the
|
|
311
|
+
// original concern). `failed` / `closed` stay immediately fatal.
|
|
312
|
+
const DISCONNECT_GRACE_MS = 6000;
|
|
313
|
+
let disconnectTimer = null;
|
|
314
|
+
const clearDisconnectTimer = () => {
|
|
315
|
+
if (disconnectTimer) {
|
|
316
|
+
clearTimeout(disconnectTimer);
|
|
317
|
+
disconnectTimer = null;
|
|
318
|
+
}
|
|
319
|
+
};
|
|
305
320
|
const teardown = () => {
|
|
306
321
|
if (closed)
|
|
307
322
|
return;
|
|
308
323
|
closed = true;
|
|
324
|
+
clearDisconnectTimer();
|
|
309
325
|
if (micUnmuteTimer) {
|
|
310
326
|
clearTimeout(micUnmuteTimer);
|
|
311
327
|
micUnmuteTimer = null;
|
|
@@ -320,13 +336,35 @@ async function openOpenAICall(creds, opts, bridge) {
|
|
|
320
336
|
mic.getTracks().forEach((t) => t.stop());
|
|
321
337
|
};
|
|
322
338
|
pc.onconnectionstatechange = () => {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
// (
|
|
326
|
-
|
|
327
|
-
|
|
339
|
+
const st = pc.connectionState;
|
|
340
|
+
if (st === 'connected') {
|
|
341
|
+
// (Re)connected — cancel any pending disconnect teardown.
|
|
342
|
+
clearDisconnectTimer();
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
if (st === 'failed' || st === 'closed') {
|
|
346
|
+
// Genuinely dead — tear down immediately, BEFORE surfacing the error, so a
|
|
347
|
+
// silent transport drop can't leave the mic recording (mirrors the
|
|
348
|
+
// first-party realtime/connection.ts fail() ordering).
|
|
349
|
+
clearDisconnectTimer();
|
|
328
350
|
teardown();
|
|
329
|
-
opts.onError?.(new Error(`call ${
|
|
351
|
+
opts.onError?.(new Error(`call ${st}`));
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
if (st === 'disconnected') {
|
|
355
|
+
// Hold a grace window; a recovery to `connected` (handled above) cancels
|
|
356
|
+
// the timer. Still disconnected when it fires → tear down.
|
|
357
|
+
if (disconnectTimer || closed)
|
|
358
|
+
return;
|
|
359
|
+
disconnectTimer = setTimeout(() => {
|
|
360
|
+
disconnectTimer = null;
|
|
361
|
+
if (closed)
|
|
362
|
+
return;
|
|
363
|
+
if (pc.connectionState === 'disconnected') {
|
|
364
|
+
teardown();
|
|
365
|
+
opts.onError?.(new Error('call disconnected'));
|
|
366
|
+
}
|
|
367
|
+
}, DISCONNECT_GRACE_MS);
|
|
330
368
|
}
|
|
331
369
|
};
|
|
332
370
|
return {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CompanionClient, type CompanionClientOptions } from './client.js';
|
|
2
2
|
export { CompanionClient, CompanionError, pouchyBrandIconUrl } from './client.js';
|
|
3
3
|
export type { CompanionClientOptions, HelloAck, RecalledMemory, CallCredentials, CompanionToolDecl, WorldStateInput, CompanionAvatar, BrandIconSize } from './client.js';
|
|
4
|
-
export { openCompanionCall, HOST_CONTROL_TOOLS, HOST_CONTROL_TOOL_NAMES } from './call.js';
|
|
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 type { CompanionEnvelope, OutboundType, InboundType, WorldStateEvent, RenderInterfacePayload, InterfaceUpdatePayload, SocialMessagePayload, ConfirmRequestPayload, AudioClipPayload, ExpressionPayload, UsagePayload } from './protocol.js';
|
|
7
7
|
/** Create a companion client. */
|
package/dist/index.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// await c.sendText('what should I do?');
|
|
11
11
|
import { CompanionClient } from './client.js';
|
|
12
12
|
export { CompanionClient, CompanionError, pouchyBrandIconUrl } from './client.js';
|
|
13
|
-
export { openCompanionCall, HOST_CONTROL_TOOLS, HOST_CONTROL_TOOL_NAMES } from './call.js';
|
|
13
|
+
export { openCompanionCall, HOST_CONTROL_TOOLS, HOST_CONTROL_TOOL_NAMES, AVATAR_VISUAL_TOOLS, AVATAR_VISUAL_TOOL_NAMES } from './call.js';
|
|
14
14
|
/** Create a companion client. */
|
|
15
15
|
export function createCompanion(opts) {
|
|
16
16
|
return new CompanionClient(opts);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pouchy_ai/companion-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "Embed the Pouchy companion — chat, voice, tools, memory, live world-state, instant UI, and agent-to-agent messaging — in any app, game, or site.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -21,7 +21,12 @@
|
|
|
21
21
|
},
|
|
22
22
|
"main": "./dist/index.js",
|
|
23
23
|
"types": "./dist/index.d.ts",
|
|
24
|
-
"files": [
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"README.md",
|
|
27
|
+
"CHANGELOG.md",
|
|
28
|
+
"LICENSE"
|
|
29
|
+
],
|
|
25
30
|
"sideEffects": false,
|
|
26
31
|
"scripts": {
|
|
27
32
|
"build": "tsc -p tsconfig.json && node scripts/fix-esm-extensions.mjs",
|
|
@@ -40,7 +45,13 @@
|
|
|
40
45
|
"esbuild": "^0.24.0",
|
|
41
46
|
"typescript": "^5.5.0"
|
|
42
47
|
},
|
|
43
|
-
"keywords": [
|
|
48
|
+
"keywords": [
|
|
49
|
+
"pouchy",
|
|
50
|
+
"ai-companion",
|
|
51
|
+
"voice",
|
|
52
|
+
"agent",
|
|
53
|
+
"sdk"
|
|
54
|
+
],
|
|
44
55
|
"publishConfig": {
|
|
45
56
|
"access": "public"
|
|
46
57
|
}
|