@pouchy_ai/companion-sdk 0.29.1 → 0.32.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 +117 -1
- package/README.md +65 -4
- package/dist/adapter-core.d.ts +58 -0
- package/dist/adapter-core.d.ts.map +1 -0
- package/dist/adapter-core.js +126 -0
- package/dist/adapter-core.js.map +1 -0
- package/dist/call.d.ts +1 -0
- package/dist/call.d.ts.map +1 -0
- package/dist/call.js +1 -0
- package/dist/call.js.map +1 -0
- package/dist/client.d.ts +91 -5
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +138 -14
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +15 -1
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +8 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +9 -5
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -0
- package/dist/protocol.d.ts +58 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +12 -0
- package/dist/protocol.js.map +1 -0
- package/dist/scopes.d.ts +1 -0
- package/dist/scopes.d.ts.map +1 -0
- package/dist/scopes.js +1 -0
- package/dist/scopes.js.map +1 -0
- package/dist/sse.d.ts +1 -0
- package/dist/sse.d.ts.map +1 -0
- package/dist/sse.js +1 -0
- package/dist/sse.js.map +1 -0
- package/dist/svelte.d.ts +16 -0
- package/dist/svelte.d.ts.map +1 -0
- package/dist/svelte.js +25 -0
- package/dist/svelte.js.map +1 -0
- package/dist/vue.d.ts +15 -0
- package/dist/vue.d.ts.map +1 -0
- package/dist/vue.js +27 -0
- package/dist/vue.js.map +1 -0
- package/dist/ws-transport.d.ts +1 -0
- package/dist/ws-transport.d.ts.map +1 -0
- package/dist/ws-transport.js +1 -0
- package/dist/ws-transport.js.map +1 -0
- package/package.json +24 -6
- package/src/adapter-core.ts +193 -0
- package/src/call.ts +699 -0
- package/src/client.ts +1959 -0
- package/src/errors.ts +77 -0
- package/src/index.ts +104 -0
- package/src/protocol.ts +316 -0
- package/src/scopes.ts +94 -0
- package/src/sse.ts +41 -0
- package/src/svelte.ts +47 -0
- package/src/vue.ts +46 -0
- package/src/ws-transport.ts +70 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { CompanionClient, type CompanionClientOptions } from './client.js';
|
|
2
2
|
export { CompanionClient, CompanionError, pouchyBrandIconUrl } from './client.js';
|
|
3
|
-
export type {
|
|
4
|
-
export type {
|
|
3
|
+
export type { CompanionDebugEvent } from './client.js';
|
|
4
|
+
export type { CompanionErrorCodeValue, ControlErrorCodeValue } from './errors.js';
|
|
5
|
+
export type { CompanionClientOptions, CompanionStreamState, HelloAck, RecalledMemory, CompanionTurn, CallCredentials, CompanionToolDecl, ToolCallEvent, WorldStateInput, CompanionAvatar, CompanionWallet, WalletBalance, BrandIconSize, EndSessionResult, SendTextReply } from './client.js';
|
|
5
6
|
export { openCompanionCall, HOST_CONTROL_TOOLS, HOST_CONTROL_TOOL_NAMES, AVATAR_VISUAL_TOOLS, AVATAR_VISUAL_TOOL_NAMES } from './call.js';
|
|
6
7
|
export type { CompanionCall, CompanionCallOptions, VoiceToolBridge } from './call.js';
|
|
7
8
|
export { COMPANION_SCOPES, COMPANION_MODALITIES, SENSITIVE_SCOPES, REPRESENT_SCOPES, DEFAULT_SCOPES, DEFAULT_MODALITIES, isSensitiveScope, isRepresentScope, hasScope } from './scopes.js';
|
|
8
9
|
export type { CompanionScope, CompanionModality } from './scopes.js';
|
|
9
|
-
export type { CompanionEnvelope, OutboundType, InboundType, WorldStateEvent, RenderInterfacePayload, InterfaceUpdatePayload, SocialMessagePayload, ConfirmRequestPayload, PendingConfirm, ToolCallPayload, AudioClipPayload, ExpressionPayload, TypingPayload, VoiceInjectPayload, UsagePayload, MessagePayload } from './protocol.js';
|
|
10
|
-
export { PROTOCOL_VERSION, INBOUND_TYPES, OUTBOUND_TYPES, COMPANION_ERROR_CODES } from './protocol.js';
|
|
11
|
-
export type { CompanionErrorCode } from './protocol.js';
|
|
10
|
+
export type { CompanionEnvelope, OutboundType, InboundType, WorldStateEvent, RenderInterfacePayload, InterfaceUpdatePayload, SocialMessagePayload, ConfirmRequestPayload, PendingConfirm, ToolCallPayload, AudioClipPayload, ExpressionPayload, TypingPayload, VoiceInjectPayload, UsagePayload, MessagePayload, ControlErrorPayload, HelloAckPayload, CallReadyPayload, OutboundPayloadMap } from './protocol.js';
|
|
11
|
+
export { PROTOCOL_VERSION, INBOUND_TYPES, OUTBOUND_TYPES, COMPANION_ERROR_CODES, CONTROL_ERROR_CODES } from './protocol.js';
|
|
12
|
+
export type { CompanionErrorCode, ControlErrorCode } from './protocol.js';
|
|
13
|
+
export { createCompanionView } from './adapter-core.js';
|
|
14
|
+
export type { CompanionView, CompanionViewOptions, CompanionViewSnapshot, CompanionTranscriptEntry } from './adapter-core.js';
|
|
12
15
|
/** Create a companion client. */
|
|
13
16
|
export declare function createCompanion(opts: CompanionClientOptions): CompanionClient;
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAExE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC/E,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpD,YAAY,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAC/E,YAAY,EACX,sBAAsB,EACtB,oBAAoB,EACpB,QAAQ,EACR,cAAc,EACd,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,eAAe,EACf,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,MAAM,UAAU,CAAC;AAClB,OAAO,EACN,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,wBAAwB,EACxB,MAAM,QAAQ,CAAC;AAChB,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACnF,OAAO,EACN,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,QAAQ,EACR,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAClE,YAAY,EACX,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,eAAe,EACf,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACrB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,MAAM,YAAY,CAAC;AAKpB,OAAO,EACN,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,qBAAqB,EACrB,mBAAmB,EACnB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAKvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,YAAY,EACX,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EACrB,wBAAwB,EACxB,MAAM,gBAAgB,CAAC;AAExB,iCAAiC;AACjC,wBAAgB,eAAe,CAAC,IAAI,EAAE,sBAAsB,GAAG,eAAe,CAE7E"}
|
package/dist/index.js
CHANGED
|
@@ -15,8 +15,15 @@ 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
|
-
|
|
18
|
+
// CONTROL_ERROR_CODES (0.30.0) is the stream-plane control.error vocabulary —
|
|
19
|
+
// a separate, smaller list than the HTTP COMPANION_ERROR_CODES.
|
|
20
|
+
export { PROTOCOL_VERSION, INBOUND_TYPES, OUTBOUND_TYPES, COMPANION_ERROR_CODES, CONTROL_ERROR_CODES } from './protocol.js';
|
|
21
|
+
// The framework-agnostic view controller behind the /react, /svelte and /vue
|
|
22
|
+
// subpath adapters — exported from the root too, so a host on any OTHER
|
|
23
|
+
// framework (or none) can reuse the same tested snapshot bookkeeping.
|
|
24
|
+
export { createCompanionView } from './adapter-core.js';
|
|
19
25
|
/** Create a companion client. */
|
|
20
26
|
export function createCompanion(opts) {
|
|
21
27
|
return new CompanionClient(opts);
|
|
22
28
|
}
|
|
29
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,yEAAyE;AACzE,sDAAsD;AACtD,EAAE;AACF,0DAA0D;AAC1D,6EAA6E;AAC7E,uBAAuB;AACvB,8CAA8C;AAC9C,eAAe;AACf,8EAA8E;AAC9E,2CAA2C;AAE3C,OAAO,EAAE,eAAe,EAA+B,MAAM,UAAU,CAAC;AAExE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAoB/E,OAAO,EACN,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,wBAAwB,EACxB,MAAM,QAAQ,CAAC;AAEhB,OAAO,EACN,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,QAAQ,EACR,MAAM,UAAU,CAAC;AAwBlB,wEAAwE;AACxE,2EAA2E;AAC3E,8EAA8E;AAC9E,gEAAgE;AAChE,OAAO,EACN,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,qBAAqB,EACrB,mBAAmB,EACnB,MAAM,YAAY,CAAC;AAGpB,6EAA6E;AAC7E,wEAAwE;AACxE,sEAAsE;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAQrD,iCAAiC;AACjC,MAAM,UAAU,eAAe,CAAC,IAA4B;IAC3D,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC"}
|
package/dist/protocol.d.ts
CHANGED
|
@@ -12,6 +12,15 @@ 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
|
+
/** `control.error` STREAM-plane code vocabulary (0.30.0) — a separate, smaller
|
|
16
|
+
* vocabulary from COMPANION_ERROR_CODES below (those tag HTTP `{ok:false}`
|
|
17
|
+
* response bodies; these tag `control.error` envelopes on the event stream,
|
|
18
|
+
* surfaced by `onError`). Self-contained mirror of the server list
|
|
19
|
+
* (drift-tested); APPEND-ONLY. The SDK itself synthesizes one more,
|
|
20
|
+
* `stream_unauthorized` (errors.ts) — the public union `ControlErrorCodeValue`
|
|
21
|
+
* covers both plus a forward-compat string arm. */
|
|
22
|
+
export declare const CONTROL_ERROR_CODES: readonly ["agent_error", "call_mint_failed"];
|
|
23
|
+
export type ControlErrorCode = (typeof CONTROL_ERROR_CODES)[number];
|
|
15
24
|
/** HTTP error `code` vocabulary — what `CompanionError.code` can hold. A
|
|
16
25
|
* self-contained mirror of the server's api-error.ts list (drift-tested);
|
|
17
26
|
* APPEND-ONLY: renaming or removing a code is a breaking SDK change.
|
|
@@ -187,3 +196,52 @@ export interface WorldStateEvent<D = unknown> {
|
|
|
187
196
|
salience?: number;
|
|
188
197
|
voiceRelevant?: boolean;
|
|
189
198
|
}
|
|
199
|
+
/** Payload of a `control.error` event — a typed error on the event stream
|
|
200
|
+
* (surfaced by `onError`). `code` is one of CONTROL_ERROR_CODES, the
|
|
201
|
+
* SDK-synthesized `stream_unauthorized`, or a code newer than this SDK build
|
|
202
|
+
* (the open arm keeps forward compat without losing autocomplete). */
|
|
203
|
+
export interface ControlErrorPayload {
|
|
204
|
+
code: ControlErrorCode | (string & {});
|
|
205
|
+
message: string;
|
|
206
|
+
}
|
|
207
|
+
/** Payload of a `hello.ack` — the handshake reply. On the REST plane this is
|
|
208
|
+
* the `/session` response body (what `connect()` normalizes into `HelloAck`);
|
|
209
|
+
* the event stream's greeting `open` frame carries a partial echo (just
|
|
210
|
+
* `{ resumeCursor }`), so every field is optional at the wire level. */
|
|
211
|
+
export interface HelloAckPayload {
|
|
212
|
+
session?: string;
|
|
213
|
+
grantedScopes?: string[];
|
|
214
|
+
modalities?: string[];
|
|
215
|
+
resumeCursor?: number;
|
|
216
|
+
representative?: boolean;
|
|
217
|
+
visitorPaired?: boolean;
|
|
218
|
+
}
|
|
219
|
+
/** Payload of a `control.call_ready` event — the stream echo of `start_call`'s
|
|
220
|
+
* accept. Deliberately SECRET-FREE (`provider` plus non-secret metadata such
|
|
221
|
+
* as `agentId` / `model` / `voice`); the actual WebRTC credentials only ride
|
|
222
|
+
* the `startCall` HTTP response. */
|
|
223
|
+
export interface CallReadyPayload {
|
|
224
|
+
provider: string;
|
|
225
|
+
[k: string]: unknown;
|
|
226
|
+
}
|
|
227
|
+
/** Per-event payload types, keyed by outbound event name — what `client.on()`
|
|
228
|
+
* narrows envelopes with (0.30.0). Type-only; extending the base Record keeps
|
|
229
|
+
* indexing valid for every OutboundType, so an event added to the vocabulary
|
|
230
|
+
* before it gets a dedicated payload type simply reads as `unknown`. */
|
|
231
|
+
export interface OutboundPayloadMap extends Record<OutboundType, unknown> {
|
|
232
|
+
'hello.ack': HelloAckPayload;
|
|
233
|
+
'companion.message': MessagePayload;
|
|
234
|
+
'companion.audio': AudioClipPayload;
|
|
235
|
+
'companion.tool_call': ToolCallPayload;
|
|
236
|
+
'companion.ui_action': RenderInterfacePayload;
|
|
237
|
+
'companion.ui_update': InterfaceUpdatePayload;
|
|
238
|
+
'companion.expression': ExpressionPayload;
|
|
239
|
+
'companion.voice_inject': VoiceInjectPayload;
|
|
240
|
+
'companion.confirm_request': ConfirmRequestPayload;
|
|
241
|
+
'companion.social_message': SocialMessagePayload;
|
|
242
|
+
'companion.typing': TypingPayload;
|
|
243
|
+
'control.call_ready': CallReadyPayload;
|
|
244
|
+
'control.error': ControlErrorPayload;
|
|
245
|
+
'control.usage': UsagePayload;
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,gBAAgB,EAAG,CAAU,CAAC;AAE3C,yCAAyC;AACzC,eAAO,MAAM,aAAa,0KAUhB,CAAC;AACX,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD;;;;;;qCAMqC;AACrC,eAAO,MAAM,cAAc,4TAejB,CAAC;AACX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,YAAY,CAAC;AAErD;;;;;;oDAMoD;AACpD,eAAO,MAAM,mBAAmB,8CAGtB,CAAC;AACX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE;;;4EAG4E;AAC5E,eAAO,MAAM,qBAAqB,0SAiBxB,CAAC;AACX,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE,mEAAmE;AACnE,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG,OAAO;IAC7C,CAAC,EAAE,OAAO,gBAAgB,CAAC;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,CAAC,CAAC;CACX;AAED;;;;;;;;2EAQ2E;AAC3E,MAAM,WAAW,sBAAsB;IACtC,SAAS,EAAE;QACV,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;SAAE,CAAC,CAAC;QACrD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;QAClD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnC,aAAa,CAAC,EAAE,OAAO,CAAC;KACxB,CAAC;CACF;AAED;;;;;;;;;6CAS6C;AAC7C,MAAM,WAAW,qBAAqB;IACrC,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB;;;sFAGkF;IAClF,MAAM,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;mEACmE;AACnE,MAAM,WAAW,cAAc;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,SAAS,EAAE,MAAM,CAAC;CAClB;AAED;;;uDAGuD;AACvD,MAAM,WAAW,eAAe;IAC/B,wDAAwD;IACxD,EAAE,EAAE,MAAM,CAAC;IACX,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;CACb;AAED;;;kFAGkF;AAClF,MAAM,WAAW,sBAAsB;IACtC,MAAM,EAAE;QACP,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,KAAK,CAAC;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;SAAE,CAAC,CAAC;KAClE,CAAC;CACF;AAED;;gBAEgB;AAChB,MAAM,WAAW,gBAAgB;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;uDAEuD;AACvD,MAAM,WAAW,iBAAiB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;uCACuC;AACvC,MAAM,WAAW,YAAY;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;gEAIgE;AAChE,MAAM,WAAW,oBAAoB;IACpC,+BAA+B;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;CAClB;AAED;;;;4EAI4E;AAC5E,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CACf;AAED;;;;;;iFAMiF;AACjF,MAAM,WAAW,aAAa;IAC7B,MAAM,EAAE,OAAO,CAAC;CAChB;AAED;;;+EAG+E;AAC/E,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;oCAEoC;AACpC,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,OAAO;IAC3C,WAAW,EAAE,KAAK,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,CAAC,CAAC;IACR,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;uEAGuE;AACvE,MAAM,WAAW,mBAAmB;IAEnC,IAAI,EAAE,gBAAgB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;CAChB;AAED;;;yEAGyE;AACzE,MAAM,WAAW,eAAe;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;qCAGqC;AACrC,MAAM,WAAW,gBAAgB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACrB;AAED;;;yEAGyE;AACzE,MAAM,WAAW,kBAAmB,SAAQ,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC;IACxE,WAAW,EAAE,eAAe,CAAC;IAC7B,mBAAmB,EAAE,cAAc,CAAC;IACpC,iBAAiB,EAAE,gBAAgB,CAAC;IACpC,qBAAqB,EAAE,eAAe,CAAC;IACvC,qBAAqB,EAAE,sBAAsB,CAAC;IAC9C,qBAAqB,EAAE,sBAAsB,CAAC;IAC9C,sBAAsB,EAAE,iBAAiB,CAAC;IAC1C,wBAAwB,EAAE,kBAAkB,CAAC;IAC7C,2BAA2B,EAAE,qBAAqB,CAAC;IACnD,0BAA0B,EAAE,oBAAoB,CAAC;IACjD,kBAAkB,EAAE,aAAa,CAAC;IAClC,oBAAoB,EAAE,gBAAgB,CAAC;IACvC,eAAe,EAAE,mBAAmB,CAAC;IACrC,eAAe,EAAE,YAAY,CAAC;CAC9B"}
|
package/dist/protocol.js
CHANGED
|
@@ -40,6 +40,17 @@ export const OUTBOUND_TYPES = [
|
|
|
40
40
|
'control.error',
|
|
41
41
|
'control.usage' // reserved — not emitted yet
|
|
42
42
|
];
|
|
43
|
+
/** `control.error` STREAM-plane code vocabulary (0.30.0) — a separate, smaller
|
|
44
|
+
* vocabulary from COMPANION_ERROR_CODES below (those tag HTTP `{ok:false}`
|
|
45
|
+
* response bodies; these tag `control.error` envelopes on the event stream,
|
|
46
|
+
* surfaced by `onError`). Self-contained mirror of the server list
|
|
47
|
+
* (drift-tested); APPEND-ONLY. The SDK itself synthesizes one more,
|
|
48
|
+
* `stream_unauthorized` (errors.ts) — the public union `ControlErrorCodeValue`
|
|
49
|
+
* covers both plus a forward-compat string arm. */
|
|
50
|
+
export const CONTROL_ERROR_CODES = [
|
|
51
|
+
'agent_error', // a server-side turn failed after the input was accepted — no reply was produced; safe to re-send
|
|
52
|
+
'call_mint_failed' // start_call couldn't mint the voice-provider credential — retry later or fall back to text
|
|
53
|
+
];
|
|
43
54
|
/** HTTP error `code` vocabulary — what `CompanionError.code` can hold. A
|
|
44
55
|
* self-contained mirror of the server's api-error.ts list (drift-tested);
|
|
45
56
|
* APPEND-ONLY: renaming or removing a code is a breaking SDK change.
|
|
@@ -62,3 +73,4 @@ export const COMPANION_ERROR_CODES = [
|
|
|
62
73
|
'step_up_required', // 401 — approval needs a passkey assertion (fetch confirm/stepup)
|
|
63
74
|
'step_up_failed' // 401 — the passkey assertion didn't verify; retry the step-up
|
|
64
75
|
];
|
|
76
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,+EAA+E;AAC/E,EAAE;AACF,mFAAmF;AACnF,iFAAiF;AACjF,gFAAgF;AAEhF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAU,CAAC;AAE3C,yCAAyC;AACzC,MAAM,CAAC,MAAM,aAAa,GAAG;IAC5B,OAAO;IACP,YAAY;IACZ,eAAe;IACf,kBAAkB;IAClB,aAAa;IACb,oBAAoB;IACpB,kBAAkB;IAClB,wBAAwB;IACxB,cAAc;CACL,CAAC;AAGX;;;;;;qCAMqC;AACrC,MAAM,CAAC,MAAM,cAAc,GAAG;IAC7B,WAAW;IACX,mBAAmB;IACnB,iBAAiB,EAAE,6BAA6B;IAChD,qBAAqB;IACrB,qBAAqB;IACrB,qBAAqB;IACrB,sBAAsB,EAAE,6BAA6B;IACrD,wBAAwB;IACxB,2BAA2B;IAC3B,0BAA0B;IAC1B,kBAAkB;IAClB,oBAAoB;IACpB,eAAe;IACf,eAAe,CAAC,6BAA6B;CACpC,CAAC;AAKX;;;;;;oDAMoD;AACpD,MAAM,CAAC,MAAM,mBAAmB,GAAG;IAClC,aAAa,EAAE,kGAAkG;IACjH,kBAAkB,CAAC,4FAA4F;CACtG,CAAC;AAGX;;;4EAG4E;AAC5E,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACpC,eAAe,EAAE,wCAAwC;IACzD,eAAe,EAAE,2CAA2C;IAC5D,eAAe,EAAE,qCAAqC;IACtD,iBAAiB,EAAE,mDAAmD;IACtE,mBAAmB,EAAE,2CAA2C;IAChE,cAAc,EAAE,+CAA+C;IAC/D,kBAAkB,EAAE,kDAAkD;IACtE,cAAc,EAAE,uDAAuD;IACvE,mBAAmB,EAAE,2CAA2C;IAChE,cAAc,EAAE,mFAAmF;IACnG,WAAW,EAAE,wDAAwD;IACrE,aAAa,EAAE,sDAAsD;IACrE,mBAAmB,EAAE,iDAAiD;IACtE,kBAAkB,EAAE,6DAA6D;IACjF,kBAAkB,EAAE,kEAAkE;IACtF,gBAAgB,CAAC,+DAA+D;CACvE,CAAC"}
|
package/dist/scopes.d.ts
CHANGED
|
@@ -22,3 +22,4 @@ export declare function isRepresentScope(s: CompanionScope): boolean;
|
|
|
22
22
|
/** Does a granted scope set (e.g. `hello.ack.grantedScopes`) satisfy a
|
|
23
23
|
* required scope? Exact-match for v1 (no hierarchical wildcards). */
|
|
24
24
|
export declare function hasScope(granted: readonly string[], required: CompanionScope): boolean;
|
|
25
|
+
//# sourceMappingURL=scopes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scopes.d.ts","sourceRoot":"","sources":["../src/scopes.ts"],"names":[],"mappings":"AAUA,8EAA8E;AAC9E,eAAO,MAAM,gBAAgB,8UAsBnB,CAAC;AACX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/D,2DAA2D;AAC3D,eAAO,MAAM,oBAAoB,6CAA8C,CAAC;AAChF,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE;;iDAEiD;AACjD,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,cAAc,CAWvD,CAAC;AAEH;;;6EAG6E;AAC7E,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,cAAc,CAMvD,CAAC;AAEH;oEACoE;AACpE,eAAO,MAAM,cAAc,EAAE,SAAS,cAAc,EASnD,CAAC;AACF,eAAO,MAAM,kBAAkB,EAAE,SAAS,iBAAiB,EAAsB,CAAC;AAElF,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,cAAc,GAAG,OAAO,CAE3D;AACD,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,cAAc,GAAG,OAAO,CAE3D;AAED;sEACsE;AACtE,wBAAgB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAEtF"}
|
package/dist/scopes.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scopes.js","sourceRoot":"","sources":["../src/scopes.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,0EAA0E;AAC1E,6EAA6E;AAC7E,kCAAkC;AAClC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,8EAA8E;AAC9E,0CAA0C;AAE1C,8EAA8E;AAC9E,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC/B,MAAM,EAAE,aAAa;IACrB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,gCAAgC;IACxC,OAAO,EAAE,0CAA0C;IACnD,kBAAkB,EAAE,8CAA8C;IAClE,kBAAkB,EAAE,iDAAiD;IACrE,WAAW,EAAE,4FAA4F;IACzG,iBAAiB,EAAE,uCAAuC;IAC1D,kBAAkB,EAAE,6CAA6C;IACjE,kBAAkB,EAAE,2CAA2C;IAC/D,mBAAmB,EAAE,iDAAiD;IACtE,gBAAgB,EAAE,8CAA8C;IAChE,aAAa,EAAE,4KAA4K;IAC3L,cAAc,EAAE,yCAAyC;IACzD,gBAAgB,EAAE,sCAAsC;IACxD,yEAAyE;IACzE,WAAW,EAAE,0DAA0D;IACvE,kBAAkB,EAAE,wEAAwE;IAC5F,cAAc,EAAE,qEAAqE;IACrF,gBAAgB,EAAE,mFAAmF;IACrG,oBAAoB,CAAC,gFAAgF;CAC5F,CAAC;AAGX,2DAA2D;AAC3D,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAGhF;;iDAEiD;AACjD,MAAM,CAAC,MAAM,gBAAgB,GAAgC,IAAI,GAAG,CAAiB;IACpF,kBAAkB;IAClB,mBAAmB;IACnB,gBAAgB;IAChB,cAAc;IACd,gBAAgB;IAChB,WAAW;IACX,kBAAkB;IAClB,cAAc;IACd,gBAAgB;IAChB,oBAAoB;CACpB,CAAC,CAAC;AAEH;;;6EAG6E;AAC7E,MAAM,CAAC,MAAM,gBAAgB,GAAgC,IAAI,GAAG,CAAiB;IACpF,WAAW;IACX,kBAAkB;IAClB,cAAc;IACd,gBAAgB;IAChB,oBAAoB;CACpB,CAAC,CAAC;AAEH;oEACoE;AACpE,MAAM,CAAC,MAAM,cAAc,GAA8B;IACxD,MAAM;IACN,OAAO;IACP,MAAM;IACN,OAAO;IACP,kBAAkB;IAClB,kBAAkB;IAClB,iBAAiB;IACjB,kBAAkB;CAClB,CAAC;AACF,MAAM,CAAC,MAAM,kBAAkB,GAAiC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAElF,MAAM,UAAU,gBAAgB,CAAC,CAAiB;IACjD,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAChC,CAAC;AACD,MAAM,UAAU,gBAAgB,CAAC,CAAiB;IACjD,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAChC,CAAC;AAED;sEACsE;AACtE,MAAM,UAAU,QAAQ,CAAC,OAA0B,EAAE,QAAwB;IAC5E,OAAO,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACnC,CAAC"}
|
package/dist/sse.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../src/sse.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,QAAQ;IACxB,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;CACb;AAED;yEACyE;AACzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAsB7E"}
|
package/dist/sse.js
CHANGED
package/dist/sse.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse.js","sourceRoot":"","sources":["../src/sse.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,gFAAgF;AAChF,iFAAiF;AACjF,iCAAiC;AACjC,EAAE;AACF,8EAA8E;AAC9E,iFAAiF;AACjF,2EAA2E;AAS3E;yEACyE;AACzE,MAAM,UAAU,QAAQ,CAAC,MAAc;IACtC,MAAM,MAAM,GAAe,EAAE,CAAC;IAC9B,IAAI,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC5C,IAAI,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,OAAO,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;QACnB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACpC,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QACjC,IAAI,KAAK,GAAG,SAAS,CAAC;QACtB,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACtC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS,CAAC,gCAAgC;YAC7E,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC7B,MAAM,KAAK,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACnD,IAAI,KAAK,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YAChD,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,gCAAgC;YACnF,IAAI,KAAK,KAAK,OAAO;gBAAE,KAAK,GAAG,KAAK,CAAC;iBAChC,IAAI,KAAK,KAAK,MAAM;gBAAE,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClD,CAAC;QACD,IAAI,SAAS,CAAC,MAAM;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAClC,CAAC"}
|
package/dist/svelte.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { CompanionClient } from './client.js';
|
|
2
|
+
import { type CompanionView, type CompanionViewOptions, type CompanionViewSnapshot } from './adapter-core.js';
|
|
3
|
+
/** Svelte-store-contract readable of the companion view snapshot. */
|
|
4
|
+
export interface CompanionStore {
|
|
5
|
+
/** Store contract: calls `run` with the current snapshot immediately and on
|
|
6
|
+
* every change. Returns unsubscribe. */
|
|
7
|
+
subscribe(run: (snapshot: CompanionViewSnapshot) => void): () => void;
|
|
8
|
+
sendText: CompanionView['sendText'];
|
|
9
|
+
confirmAction: CompanionView['confirmAction'];
|
|
10
|
+
/** Detach from the client (does not close it). */
|
|
11
|
+
dispose(): void;
|
|
12
|
+
client: CompanionClient;
|
|
13
|
+
}
|
|
14
|
+
/** Wrap a host-owned client as a Svelte-compatible readable store. */
|
|
15
|
+
export declare function companionStore(client: CompanionClient, opts?: CompanionViewOptions): CompanionStore;
|
|
16
|
+
//# sourceMappingURL=svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svelte.d.ts","sourceRoot":"","sources":["../src/svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAEN,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,MAAM,gBAAgB,CAAC;AAExB,qEAAqE;AACrE,MAAM,WAAW,cAAc;IAC9B;6CACyC;IACzC,SAAS,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,qBAAqB,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACtE,QAAQ,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IACpC,aAAa,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC9C,kDAAkD;IAClD,OAAO,IAAI,IAAI,CAAC;IAChB,MAAM,EAAE,eAAe,CAAC;CACxB;AAED,sEAAsE;AACtE,wBAAgB,cAAc,CAC7B,MAAM,EAAE,eAAe,EACvB,IAAI,CAAC,EAAE,oBAAoB,GACzB,cAAc,CAYhB"}
|
package/dist/svelte.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Svelte adapter (0.31.0) — `@pouchy_ai/companion-sdk/svelte`.
|
|
2
|
+
// Implements the Svelte STORE CONTRACT (subscribe(run) → unsubscribe) by hand,
|
|
3
|
+
// so it needs no `svelte` import and works from Svelte 3 through 5 (`$store`
|
|
4
|
+
// auto-subscription, or `fromStore()` in runes mode). Behavior lives in
|
|
5
|
+
// adapter-core.ts.
|
|
6
|
+
//
|
|
7
|
+
// const companion = companionStore(client);
|
|
8
|
+
// $companion.transcript / $companion.draft / $companion.streamState
|
|
9
|
+
// companion.sendText('hi');
|
|
10
|
+
import { createCompanionView } from './adapter-core.js';
|
|
11
|
+
/** Wrap a host-owned client as a Svelte-compatible readable store. */
|
|
12
|
+
export function companionStore(client, opts) {
|
|
13
|
+
const view = createCompanionView(client, opts);
|
|
14
|
+
return {
|
|
15
|
+
subscribe(run) {
|
|
16
|
+
run(view.getSnapshot());
|
|
17
|
+
return view.subscribe(() => run(view.getSnapshot()));
|
|
18
|
+
},
|
|
19
|
+
sendText: view.sendText,
|
|
20
|
+
confirmAction: view.confirmAction,
|
|
21
|
+
dispose: view.dispose,
|
|
22
|
+
client
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=svelte.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svelte.js","sourceRoot":"","sources":["../src/svelte.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+EAA+E;AAC/E,6EAA6E;AAC7E,wEAAwE;AACxE,mBAAmB;AACnB,EAAE;AACF,8CAA8C;AAC9C,sEAAsE;AACtE,8BAA8B;AAG9B,OAAO,EACN,mBAAmB,EAInB,MAAM,gBAAgB,CAAC;AAcxB,sEAAsE;AACtE,MAAM,UAAU,cAAc,CAC7B,MAAuB,EACvB,IAA2B;IAE3B,MAAM,IAAI,GAAG,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC/C,OAAO;QACN,SAAS,CAAC,GAAG;YACZ,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;YACxB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QACtD,CAAC;QACD,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,MAAM;KACN,CAAC;AACH,CAAC"}
|
package/dist/vue.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ShallowRef } from 'vue';
|
|
2
|
+
import type { CompanionClient } from './client.js';
|
|
3
|
+
import { type CompanionView, type CompanionViewOptions, type CompanionViewSnapshot } from './adapter-core.js';
|
|
4
|
+
export interface UseCompanionReturn {
|
|
5
|
+
/** Reactive, immutable view snapshot (replaced wholesale per change). */
|
|
6
|
+
snapshot: ShallowRef<CompanionViewSnapshot>;
|
|
7
|
+
sendText: CompanionView['sendText'];
|
|
8
|
+
confirmAction: CompanionView['confirmAction'];
|
|
9
|
+
/** Manual teardown for use outside an effect scope. */
|
|
10
|
+
dispose(): void;
|
|
11
|
+
client: CompanionClient;
|
|
12
|
+
}
|
|
13
|
+
/** Reactive companion view state for a host-owned client. */
|
|
14
|
+
export declare function useCompanion(client: CompanionClient, opts?: CompanionViewOptions): UseCompanionReturn;
|
|
15
|
+
//# sourceMappingURL=vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vue.d.ts","sourceRoot":"","sources":["../src/vue.ts"],"names":[],"mappings":"AAUA,OAAO,EAA+C,KAAK,UAAU,EAAE,MAAM,KAAK,CAAC;AACnF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAEN,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,kBAAkB;IAClC,yEAAyE;IACzE,QAAQ,EAAE,UAAU,CAAC,qBAAqB,CAAC,CAAC;IAC5C,QAAQ,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IACpC,aAAa,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC9C,uDAAuD;IACvD,OAAO,IAAI,IAAI,CAAC;IAChB,MAAM,EAAE,eAAe,CAAC;CACxB;AAED,6DAA6D;AAC7D,wBAAgB,YAAY,CAC3B,MAAM,EAAE,eAAe,EACvB,IAAI,CAAC,EAAE,oBAAoB,GACzB,kBAAkB,CAYpB"}
|
package/dist/vue.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Vue 3 adapter (0.31.0) — `@pouchy_ai/companion-sdk/vue`.
|
|
2
|
+
// Thin binding of adapter-core onto a shallowRef; behavior lives (and is
|
|
3
|
+
// tested) in adapter-core.ts.
|
|
4
|
+
//
|
|
5
|
+
// const { snapshot, sendText } = useCompanion(client);
|
|
6
|
+
// snapshot.value.transcript / snapshot.value.streamState
|
|
7
|
+
//
|
|
8
|
+
// Inside a component/effect scope the subscription is torn down automatically
|
|
9
|
+
// (onScopeDispose); outside any scope, call dispose() yourself.
|
|
10
|
+
import { getCurrentScope, onScopeDispose, shallowRef } from 'vue';
|
|
11
|
+
import { createCompanionView } from './adapter-core.js';
|
|
12
|
+
/** Reactive companion view state for a host-owned client. */
|
|
13
|
+
export function useCompanion(client, opts) {
|
|
14
|
+
const view = createCompanionView(client, opts);
|
|
15
|
+
const snapshot = shallowRef(view.getSnapshot());
|
|
16
|
+
const unsub = view.subscribe(() => {
|
|
17
|
+
snapshot.value = view.getSnapshot();
|
|
18
|
+
});
|
|
19
|
+
const dispose = () => {
|
|
20
|
+
unsub();
|
|
21
|
+
view.dispose();
|
|
22
|
+
};
|
|
23
|
+
if (getCurrentScope())
|
|
24
|
+
onScopeDispose(dispose);
|
|
25
|
+
return { snapshot, sendText: view.sendText, confirmAction: view.confirmAction, dispose, client };
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=vue.js.map
|
package/dist/vue.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vue.js","sourceRoot":"","sources":["../src/vue.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,yEAAyE;AACzE,8BAA8B;AAC9B,EAAE;AACF,yDAAyD;AACzD,2DAA2D;AAC3D,EAAE;AACF,8EAA8E;AAC9E,gEAAgE;AAEhE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,UAAU,EAAmB,MAAM,KAAK,CAAC;AAEnF,OAAO,EACN,mBAAmB,EAInB,MAAM,gBAAgB,CAAC;AAYxB,6DAA6D;AAC7D,MAAM,UAAU,YAAY,CAC3B,MAAuB,EACvB,IAA2B;IAE3B,MAAM,IAAI,GAAG,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE;QACjC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACrC,CAAC,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,GAAG,EAAE;QACpB,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,EAAE,CAAC;IAChB,CAAC,CAAC;IACF,IAAI,eAAe,EAAE;QAAE,cAAc,CAAC,OAAO,CAAC,CAAC;IAC/C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AAClG,CAAC"}
|
package/dist/ws-transport.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws-transport.d.ts","sourceRoot":"","sources":["../src/ws-transport.ts"],"names":[],"mappings":"AAeA;;;;+BAI+B;AAC/B,wBAAgB,iBAAiB,CAChC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,SAAI,GACR,MAAM,CAKR;AAED;;;;;mEAKmE;AACnE,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAuBnF;AAED;qEACqE;AACrE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAI7E"}
|
package/dist/ws-transport.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws-transport.js","sourceRoot":"","sources":["../src/ws-transport.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,EAAE;AACF,4EAA4E;AAC5E,6EAA6E;AAC7E,+EAA+E;AAC/E,8EAA8E;AAC9E,yEAAyE;AACzE,EAAE;AACF,sEAAsE;AACtE,0EAA0E;AAC1E,4EAA4E;AAC5E,8EAA8E;AAC9E,2EAA2E;AAC3E,8EAA8E;AAE9E;;;;+BAI+B;AAC/B,MAAM,UAAU,iBAAiB,CAChC,OAAe,EACf,SAAiB,EACjB,KAAa,EACb,MAAM,GAAG,CAAC;IAEV,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC9F,MAAM,EAAE,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACzC,MAAM,CAAC,GAAG,IAAI,eAAe,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IACjE,OAAO,GAAG,MAAM,0BAA0B,EAAE,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;AACnE,CAAC;AAED;;;;;mEAKmE;AACnE,MAAM,UAAU,eAAe,CAAC,GAAW;IAC1C,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACJ,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;IACD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACvD,MAAM,GAAG,GAAG,MAAiC,CAAC;IAE9C,2BAA2B;IAC3B,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QACtF,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;IACnC,CAAC;IAED,6EAA6E;IAC7E,yDAAyD;IACzD,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IACxC,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC;AAED;qEACqE;AACrE,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,IAAyB;IACpE,MAAM,OAAO,GAA4B,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACjE,IAAI,IAAI,EAAE,KAAK;QAAE,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IAC5C,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pouchy_ai/companion-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.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",
|
|
@@ -18,12 +18,23 @@
|
|
|
18
18
|
"types": "./dist/index.d.ts",
|
|
19
19
|
"import": "./dist/index.js",
|
|
20
20
|
"default": "./dist/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./svelte": {
|
|
23
|
+
"types": "./dist/svelte.d.ts",
|
|
24
|
+
"import": "./dist/svelte.js",
|
|
25
|
+
"default": "./dist/svelte.js"
|
|
26
|
+
},
|
|
27
|
+
"./vue": {
|
|
28
|
+
"types": "./dist/vue.d.ts",
|
|
29
|
+
"import": "./dist/vue.js",
|
|
30
|
+
"default": "./dist/vue.js"
|
|
21
31
|
}
|
|
22
32
|
},
|
|
23
33
|
"main": "./dist/index.js",
|
|
24
34
|
"types": "./dist/index.d.ts",
|
|
25
35
|
"files": [
|
|
26
36
|
"dist",
|
|
37
|
+
"src",
|
|
27
38
|
"README.md",
|
|
28
39
|
"CHANGELOG.md",
|
|
29
40
|
"LICENSE"
|
|
@@ -33,28 +44,35 @@
|
|
|
33
44
|
"node": ">=18"
|
|
34
45
|
},
|
|
35
46
|
"scripts": {
|
|
36
|
-
"build": "tsc -p tsconfig.json && node scripts/fix-esm-extensions.mjs",
|
|
37
|
-
"build:cdn": "esbuild ../../src/lib/companion-sdk/index.ts --bundle --format=esm --platform=browser --external:@elevenlabs/client --legal-comments=none --outfile=cdn/companion-sdk.js && node scripts/cdn-banner.mjs",
|
|
47
|
+
"build": "tsc -p tsconfig.json && node scripts/fix-esm-extensions.mjs && node scripts/package-src-maps.mjs",
|
|
48
|
+
"build:cdn": "esbuild ../../src/lib/companion-sdk/index.ts --bundle --format=esm --platform=browser --external:@elevenlabs/client --legal-comments=none --outfile=cdn/companion-sdk.js && esbuild ../../src/lib/companion-sdk/index.ts --bundle --minify --format=esm --platform=browser --external:@elevenlabs/client --legal-comments=none --outfile=cdn/companion-sdk.min.js && node scripts/cdn-banner.mjs",
|
|
38
49
|
"prepublishOnly": "npm run build"
|
|
39
50
|
},
|
|
40
51
|
"peerDependencies": {
|
|
41
|
-
"@elevenlabs/client": "^1.9.0"
|
|
52
|
+
"@elevenlabs/client": "^1.9.0",
|
|
53
|
+
"vue": "^3.0.0"
|
|
42
54
|
},
|
|
43
55
|
"peerDependenciesMeta": {
|
|
44
56
|
"@elevenlabs/client": {
|
|
45
57
|
"optional": true
|
|
58
|
+
},
|
|
59
|
+
"vue": {
|
|
60
|
+
"optional": true
|
|
46
61
|
}
|
|
47
62
|
},
|
|
48
63
|
"devDependencies": {
|
|
49
64
|
"esbuild": "^0.24.0",
|
|
50
|
-
"typescript": "^5.5.0"
|
|
65
|
+
"typescript": "^5.5.0",
|
|
66
|
+
"vue": "^3.5.0"
|
|
51
67
|
},
|
|
52
68
|
"keywords": [
|
|
53
69
|
"pouchy",
|
|
54
70
|
"ai-companion",
|
|
55
71
|
"voice",
|
|
56
72
|
"agent",
|
|
57
|
-
"sdk"
|
|
73
|
+
"sdk",
|
|
74
|
+
"svelte",
|
|
75
|
+
"vue"
|
|
58
76
|
],
|
|
59
77
|
"publishConfig": {
|
|
60
78
|
"access": "public"
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
// Framework-agnostic view controller behind the /svelte and /vue adapters
|
|
2
|
+
// (0.31.0). One place owns the subscription wiring + snapshot bookkeeping the
|
|
3
|
+
// adapters share, so each adapter stays a logic-free ~40-line binding to its
|
|
4
|
+
// framework's reactivity primitive — and THIS file is where the behavior gets
|
|
5
|
+
// unit-tested once instead of per-framework. (React hosts use the richer
|
|
6
|
+
// standalone `@pouchy_ai/react` package — Provider-owned lifecycle, voice-call
|
|
7
|
+
// hook — which predates this controller and keeps its own state wiring.)
|
|
8
|
+
//
|
|
9
|
+
// Contract (deliberately useSyncExternalStore-shaped, the strictest of the
|
|
10
|
+
// three): `getSnapshot()` returns the SAME object reference until something
|
|
11
|
+
// changes, and every change produces a new frozen snapshot + one listener
|
|
12
|
+
// sweep. Svelte's store contract and Vue's shallowRef both accept that shape
|
|
13
|
+
// as-is.
|
|
14
|
+
|
|
15
|
+
import type { CompanionClient } from './client';
|
|
16
|
+
import type { CompanionStreamState } from './client';
|
|
17
|
+
import type { ConfirmRequestPayload, TypingPayload } from './protocol';
|
|
18
|
+
|
|
19
|
+
/** One rendered line of the conversation, in arrival order. */
|
|
20
|
+
export interface CompanionTranscriptEntry {
|
|
21
|
+
role: 'user' | 'companion';
|
|
22
|
+
text: string;
|
|
23
|
+
/** Client wall-clock ms when the entry was appended. */
|
|
24
|
+
at: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Immutable view snapshot. A new object per change — safe to hand to
|
|
28
|
+
* useSyncExternalStore / $state / shallowRef without defensive copies. */
|
|
29
|
+
export interface CompanionViewSnapshot {
|
|
30
|
+
streamState: CompanionStreamState;
|
|
31
|
+
/** Rolling transcript, oldest first, capped at `transcriptCap`. */
|
|
32
|
+
transcript: readonly CompanionTranscriptEntry[];
|
|
33
|
+
/** The in-flight streamed reply (token deltas), '' when none. */
|
|
34
|
+
draft: string;
|
|
35
|
+
typing: boolean;
|
|
36
|
+
/** Confirm requests that arrived on the stream and haven't been resolved
|
|
37
|
+
* through this view yet. Rebuild after a reload via client.pendingConfirms()
|
|
38
|
+
* — confirm_request events are not replayed. */
|
|
39
|
+
pendingConfirms: readonly ConfirmRequestPayload[];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface CompanionViewOptions {
|
|
43
|
+
/** Max transcript entries kept (oldest dropped). Default 200. */
|
|
44
|
+
transcriptCap?: number;
|
|
45
|
+
/** Restore up to this many recent turns from `client.history()` on
|
|
46
|
+
* creation, so a reloaded tab isn't blank (same semantic as
|
|
47
|
+
* `@pouchy_ai/react`'s useMessages). Requires a connected client (a
|
|
48
|
+
* session must exist). Restored turns land ONLY while the live transcript
|
|
49
|
+
* is still empty — they never clobber messages that arrived first.
|
|
50
|
+
* Default 0 (off). */
|
|
51
|
+
restore?: number;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface CompanionView {
|
|
55
|
+
/** Stable-reference snapshot (useSyncExternalStore contract). */
|
|
56
|
+
getSnapshot(): CompanionViewSnapshot;
|
|
57
|
+
/** Subscribe to snapshot changes. Returns unsubscribe. */
|
|
58
|
+
subscribe(listener: () => void): () => void;
|
|
59
|
+
/** sendText that also appends the user turn to the transcript. */
|
|
60
|
+
sendText(
|
|
61
|
+
text: string,
|
|
62
|
+
opts?: Parameters<CompanionClient['sendText']>[1]
|
|
63
|
+
): ReturnType<CompanionClient['sendText']>;
|
|
64
|
+
/** confirmAction that also removes the confirm from `pendingConfirms`
|
|
65
|
+
* (on approve AND deny — both resolve the card server-side). */
|
|
66
|
+
confirmAction(
|
|
67
|
+
confirmId: string,
|
|
68
|
+
approve: boolean,
|
|
69
|
+
opts?: { signal?: AbortSignal }
|
|
70
|
+
): ReturnType<CompanionClient['confirmAction']>;
|
|
71
|
+
/** Detach every client subscription. The view goes inert (snapshot frozen,
|
|
72
|
+
* listeners dropped); the client itself is NOT closed — it belongs to the
|
|
73
|
+
* host. Idempotent. */
|
|
74
|
+
dispose(): void;
|
|
75
|
+
/** The underlying client, for everything the view doesn't wrap. */
|
|
76
|
+
readonly client: CompanionClient;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const DEFAULT_TRANSCRIPT_CAP = 200;
|
|
80
|
+
|
|
81
|
+
/** Wire a client into an immutable-snapshot view. Adapters bind this to their
|
|
82
|
+
* framework; hosts using none of the adapters can consume it directly. */
|
|
83
|
+
export function createCompanionView(
|
|
84
|
+
client: CompanionClient,
|
|
85
|
+
opts?: CompanionViewOptions
|
|
86
|
+
): CompanionView {
|
|
87
|
+
const cap = Math.max(1, opts?.transcriptCap ?? DEFAULT_TRANSCRIPT_CAP);
|
|
88
|
+
const listeners = new Set<() => void>();
|
|
89
|
+
let disposed = false;
|
|
90
|
+
|
|
91
|
+
let snapshot: CompanionViewSnapshot = Object.freeze({
|
|
92
|
+
streamState: client.streamState,
|
|
93
|
+
transcript: Object.freeze([]) as readonly CompanionTranscriptEntry[],
|
|
94
|
+
draft: '',
|
|
95
|
+
typing: false,
|
|
96
|
+
pendingConfirms: Object.freeze([]) as readonly ConfirmRequestPayload[]
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
function commit(patch: Partial<CompanionViewSnapshot>): void {
|
|
100
|
+
if (disposed) return;
|
|
101
|
+
snapshot = Object.freeze({ ...snapshot, ...patch });
|
|
102
|
+
// Snapshot-first, then notify: a listener that re-reads getSnapshot()
|
|
103
|
+
// synchronously must see the new value. Handler isolation matches the
|
|
104
|
+
// client's emit() doctrine — one throwing listener must not starve the rest.
|
|
105
|
+
for (const l of [...listeners]) {
|
|
106
|
+
try {
|
|
107
|
+
l();
|
|
108
|
+
} catch {
|
|
109
|
+
/* listener errors are the listener's problem */
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function appendTranscript(entry: CompanionTranscriptEntry): void {
|
|
115
|
+
const next = [...snapshot.transcript, entry];
|
|
116
|
+
commit({ transcript: Object.freeze(next.slice(-cap)) });
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const restore = opts?.restore ?? 0;
|
|
120
|
+
if (restore > 0) {
|
|
121
|
+
void client
|
|
122
|
+
.history({ limit: restore })
|
|
123
|
+
.then((turns) => {
|
|
124
|
+
// Only fill a still-empty transcript — live traffic wins.
|
|
125
|
+
if (disposed || snapshot.transcript.length) return;
|
|
126
|
+
const restored: CompanionTranscriptEntry[] = [];
|
|
127
|
+
for (const t of turns) {
|
|
128
|
+
if (t.user) restored.push({ role: 'user', text: t.user, at: t.ts });
|
|
129
|
+
if (t.assistant) restored.push({ role: 'companion', text: t.assistant, at: t.ts });
|
|
130
|
+
}
|
|
131
|
+
if (restored.length) commit({ transcript: Object.freeze(restored.slice(-cap)) });
|
|
132
|
+
})
|
|
133
|
+
.catch(() => {
|
|
134
|
+
/* a brand-new session has no history — fine */
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const unsubs: Array<() => void> = [
|
|
139
|
+
client.onStreamStateChange((next: CompanionStreamState) => commit({ streamState: next })),
|
|
140
|
+
client.onMessage((text: string) => {
|
|
141
|
+
// The authoritative full reply replaces any streamed draft; typing is
|
|
142
|
+
// definitionally over once the reply lands.
|
|
143
|
+
const next = [...snapshot.transcript, { role: 'companion' as const, text, at: Date.now() }];
|
|
144
|
+
commit({
|
|
145
|
+
transcript: Object.freeze(next.slice(-cap)),
|
|
146
|
+
draft: '',
|
|
147
|
+
typing: false
|
|
148
|
+
});
|
|
149
|
+
}),
|
|
150
|
+
client.onDelta((chunk: string, meta: { reset?: boolean }) => {
|
|
151
|
+
commit({ draft: meta.reset ? chunk : snapshot.draft + chunk });
|
|
152
|
+
}),
|
|
153
|
+
client.onTyping((payload: TypingPayload) => commit({ typing: !!payload.active })),
|
|
154
|
+
client.onConfirmRequest((payload: ConfirmRequestPayload) => {
|
|
155
|
+
// The stream can redeliver on reconnect replay — dedupe by confirmId.
|
|
156
|
+
if (snapshot.pendingConfirms.some((c) => c.confirmId === payload.confirmId)) return;
|
|
157
|
+
commit({ pendingConfirms: Object.freeze([...snapshot.pendingConfirms, payload]) });
|
|
158
|
+
})
|
|
159
|
+
];
|
|
160
|
+
|
|
161
|
+
return {
|
|
162
|
+
client,
|
|
163
|
+
getSnapshot: () => snapshot,
|
|
164
|
+
subscribe(listener: () => void) {
|
|
165
|
+
listeners.add(listener);
|
|
166
|
+
return () => listeners.delete(listener);
|
|
167
|
+
},
|
|
168
|
+
async sendText(text, sendOpts) {
|
|
169
|
+
appendTranscript({ role: 'user', text, at: Date.now() });
|
|
170
|
+
return client.sendText(text, sendOpts as never);
|
|
171
|
+
},
|
|
172
|
+
async confirmAction(confirmId, approve, confirmOpts) {
|
|
173
|
+
const res = await client.confirmAction(confirmId, approve, confirmOpts);
|
|
174
|
+
// Remove on any settled resolution; exec_failed with retryable keeps the
|
|
175
|
+
// card — the host may re-approve the SAME confirmId (documented server
|
|
176
|
+
// semantic), so dropping it would strand the retry affordance.
|
|
177
|
+
if (!(res.status === 'exec_failed' && res.retryable)) {
|
|
178
|
+
commit({
|
|
179
|
+
pendingConfirms: Object.freeze(
|
|
180
|
+
snapshot.pendingConfirms.filter((c) => c.confirmId !== confirmId)
|
|
181
|
+
)
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
return res;
|
|
185
|
+
},
|
|
186
|
+
dispose() {
|
|
187
|
+
if (disposed) return;
|
|
188
|
+
for (const u of unsubs) u();
|
|
189
|
+
listeners.clear();
|
|
190
|
+
disposed = true;
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
}
|