@lumavox/client 0.4.0 → 0.5.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/README.md +5 -1
- package/dist/conversation.d.ts +8 -0
- package/dist/conversation.js +12 -2
- package/dist/events.d.ts +38 -0
- package/dist/gen/index.d.ts +1 -1
- package/dist/gen/types.gen.d.ts +38 -0
- package/dist/protocol.gen.d.ts +2 -2
- package/dist/protocol.gen.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -89,7 +89,7 @@ key, dials, authenticates, and from then on:
|
|
|
89
89
|
|
|
90
90
|
| Handler | Frame |
|
|
91
91
|
|---|---|
|
|
92
|
-
| `onReady` `onTurnStart` `onHeard` `onHeardPartial` `onKnowledge` `onMood` `onThought` `onText` `onChunk` `onToolStart` `onToolEnd` `onUsage` `onMuted` `onAudioStart` `onAudioEnd` `onTranscript` `onDone` `onInterrupted` `onError` | the wire's frame, as it is |
|
|
92
|
+
| `onReady` `onTurnStart` `onHeard` `onHeardPartial` `onKnowledge` `onMood` `onThought` `onText` `onChunk` `onToolStart` `onToolEnd` `onToolConfirm` `onUsage` `onMuted` `onAudioStart` `onAudioEnd` `onTranscript` `onDone` `onInterrupted` `onError` | the wire's frame, as it is |
|
|
93
93
|
| `onAudio` | `{ pcm, chunk, turn, sample_rate, channels }`: raw 16-bit PCM, never copied |
|
|
94
94
|
| `onRelation` | the relationship, each change once |
|
|
95
95
|
| `onState` | `connecting` `ready` `busy` `reconnecting` `dormant` `closed` |
|
|
@@ -101,6 +101,10 @@ key, dials, authenticates, and from then on:
|
|
|
101
101
|
With no `onAudio` handler every turn asks for no speech, so nothing pays
|
|
102
102
|
for audio nobody hears; `connect`'s `{ speech }` overrides that.
|
|
103
103
|
|
|
104
|
+
A tool marked "ask first" sends `tool.confirm` and does not run:
|
|
105
|
+
`confirmTool(callId, yes)` answers with the person's tap — a turn of
|
|
106
|
+
theirs, queued as `send` is, which runs the tool first on a yes.
|
|
107
|
+
|
|
104
108
|
### Speaking
|
|
105
109
|
|
|
106
110
|
```ts
|
package/dist/conversation.d.ts
CHANGED
|
@@ -142,6 +142,8 @@ export interface ConversationHandlers {
|
|
|
142
142
|
onChunk?: On<"text.chunk">;
|
|
143
143
|
onToolStart?: On<"tool.start">;
|
|
144
144
|
onToolEnd?: On<"tool.end">;
|
|
145
|
+
/** A tool that asks first waits for the person: answer with `confirmTool`. */
|
|
146
|
+
onToolConfirm?: On<"tool.confirm">;
|
|
145
147
|
onUsage?: On<"usage">;
|
|
146
148
|
onMuted?: On<"muted">;
|
|
147
149
|
onAudioStart?: On<"audio.start">;
|
|
@@ -250,6 +252,12 @@ export declare class Conversation {
|
|
|
250
252
|
* 1 to 32,000 characters, or it is `dropped: refused` here.
|
|
251
253
|
*/
|
|
252
254
|
send(text: string, options?: TurnOptions): Promise<TurnOutcome>;
|
|
255
|
+
/**
|
|
256
|
+
* Answer a `tool.confirm` with the person's tap: a turn of theirs — "Yes."
|
|
257
|
+
* or "No." in the transcript — which runs the tool first on a yes.
|
|
258
|
+
* Queued as `send` is; never rejects.
|
|
259
|
+
*/
|
|
260
|
+
confirmTool(callId: string, yes: boolean, options?: TurnOptions): Promise<TurnOutcome>;
|
|
253
261
|
/**
|
|
254
262
|
* Open a recording at `rate`, which must be one of `RECORDING_RATES`.
|
|
255
263
|
* Answers its id. A recording already open is abandoned, as the edge
|
package/dist/conversation.js
CHANGED
|
@@ -26,6 +26,7 @@ const HANDLER = {
|
|
|
26
26
|
"text.chunk": "onChunk",
|
|
27
27
|
"tool.start": "onToolStart",
|
|
28
28
|
"tool.end": "onToolEnd",
|
|
29
|
+
"tool.confirm": "onToolConfirm",
|
|
29
30
|
usage: "onUsage",
|
|
30
31
|
muted: "onMuted",
|
|
31
32
|
"audio.start": "onAudioStart",
|
|
@@ -138,6 +139,14 @@ export class Conversation {
|
|
|
138
139
|
}
|
|
139
140
|
return this.enqueue({ type: "user_message", text }, options);
|
|
140
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* Answer a `tool.confirm` with the person's tap: a turn of theirs — "Yes."
|
|
144
|
+
* or "No." in the transcript — which runs the tool first on a yes.
|
|
145
|
+
* Queued as `send` is; never rejects.
|
|
146
|
+
*/
|
|
147
|
+
confirmTool(callId, yes, options = {}) {
|
|
148
|
+
return this.enqueue({ type: "tool.confirmed", call_id: callId, yes }, options);
|
|
149
|
+
}
|
|
141
150
|
/**
|
|
142
151
|
* Open a recording at `rate`, which must be one of `RECORDING_RATES`.
|
|
143
152
|
* Answers its id. A recording already open is abandoned, as the edge
|
|
@@ -686,8 +695,9 @@ export class Conversation {
|
|
|
686
695
|
next.resolve(dropped(recording.dropped ?? "closed"));
|
|
687
696
|
continue;
|
|
688
697
|
}
|
|
689
|
-
// A message
|
|
690
|
-
|
|
698
|
+
// A message or a tap — a turn with no recording of its own — abandons
|
|
699
|
+
// an open recording, at the edge and here.
|
|
700
|
+
if (!recording && this.open) {
|
|
691
701
|
this.abandon("cancelled");
|
|
692
702
|
}
|
|
693
703
|
this.inFlight = next;
|
package/dist/events.d.ts
CHANGED
|
@@ -85,11 +85,46 @@ export interface TextChunkFrame extends Frame<"text.chunk">, InTurn {
|
|
|
85
85
|
export interface ThoughtDeltaFrame extends Frame<"thought.delta">, InTurn {
|
|
86
86
|
text: string;
|
|
87
87
|
}
|
|
88
|
+
/** Who runs a tool: the platform's own, your server's, or your app's. */
|
|
89
|
+
export type ToolKind = "platform" | "webhook" | "app";
|
|
90
|
+
/** The model called a tool; its `tool.end` follows. */
|
|
88
91
|
export interface ToolStartFrame extends Frame<"tool.start">, InTurn {
|
|
89
92
|
name: string;
|
|
93
|
+
kind: ToolKind;
|
|
94
|
+
/** Your tool's call, `call_…`; `null` for the platform's own. */
|
|
95
|
+
call_id: string | null;
|
|
90
96
|
}
|
|
97
|
+
/** A tool's call is over: whether it answered, and how long it took. */
|
|
91
98
|
export interface ToolEndFrame extends Frame<"tool.end">, InTurn {
|
|
92
99
|
name: string;
|
|
100
|
+
kind: ToolKind;
|
|
101
|
+
call_id: string | null;
|
|
102
|
+
ok: boolean;
|
|
103
|
+
ms: number;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* A tool marked "ask first" waits for the person's yes: the agent asks in
|
|
107
|
+
* its own words, and `confirmTool(call_id, yes)` answers with a tap.
|
|
108
|
+
*/
|
|
109
|
+
export interface ToolConfirmFrame extends Frame<"tool.confirm">, InTurn {
|
|
110
|
+
call_id: string;
|
|
111
|
+
name: string;
|
|
112
|
+
arguments: Record<string, unknown>;
|
|
113
|
+
}
|
|
114
|
+
/** One call of your tool in a turn, as `turn.done` and the transcript keep it. */
|
|
115
|
+
export interface ToolCall {
|
|
116
|
+
call_id: string;
|
|
117
|
+
name: string;
|
|
118
|
+
kind: "webhook" | "app";
|
|
119
|
+
arguments: Record<string, unknown>;
|
|
120
|
+
/** What it answered, as the model read it (16 KB at most); `null` for none. */
|
|
121
|
+
result: unknown;
|
|
122
|
+
ok: boolean;
|
|
123
|
+
/** What failed, as the model was told; `null` when nothing did. */
|
|
124
|
+
error: string | null;
|
|
125
|
+
ms: number;
|
|
126
|
+
/** Which of the reply's rounds, 1 to 3; 0 for a call the person confirmed with a tap. */
|
|
127
|
+
round: number;
|
|
93
128
|
}
|
|
94
129
|
export interface KnowledgeEntry {
|
|
95
130
|
entry_id: string;
|
|
@@ -157,6 +192,8 @@ export interface TurnDoneFrame extends Frame<"turn.done">, InTurn {
|
|
|
157
192
|
chunks_spoken: number;
|
|
158
193
|
heard: string | null;
|
|
159
194
|
heard_seconds: number | null;
|
|
195
|
+
/** Your tools it called, in order. */
|
|
196
|
+
tool_calls: ToolCall[];
|
|
160
197
|
timings: TurnTimings;
|
|
161
198
|
}
|
|
162
199
|
/** The turn ended early; what was written before it stopped still stands. */
|
|
@@ -207,6 +244,7 @@ export type ServerFrames = Exhaustive<{
|
|
|
207
244
|
"thought.delta": ThoughtDeltaFrame;
|
|
208
245
|
"tool.start": ToolStartFrame;
|
|
209
246
|
"tool.end": ToolEndFrame;
|
|
247
|
+
"tool.confirm": ToolConfirmFrame;
|
|
210
248
|
knowledge: KnowledgeFrame;
|
|
211
249
|
"audio.start": AudioStartFrame;
|
|
212
250
|
"audio.end": AudioEndFrame;
|
package/dist/gen/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export type { ClientOptions, CompactionInfo, CompactRequest, CompactSessionData, CompactSessionError, CompactSessionErrors, CompactSessionResponse, CompactSessionResponses, CreateSessionData, CreateSessionError, CreateSessionErrors, CreateSessionResponse, CreateSessionResponses, DeleteAllFactsData, DeleteAllFactsError, DeleteAllFactsErrors, DeleteAllFactsResponse, DeleteAllFactsResponses, DeleteFactData, DeleteFactError, DeleteFactErrors, DeleteFactResponse, DeleteFactResponses, DeleteSessionData, DeleteSessionError, DeleteSessionErrors, DeleteSessionResponse, DeleteSessionResponses, ErrorCode, ErrorInfo, ErrorResponse, ExtractSessionFactsData, ExtractSessionFactsError, ExtractSessionFactsErrors, ExtractSessionFactsResponse, ExtractSessionFactsResponses, FactInfo, FactPage, FactsDeleted, GetSessionData, GetSessionError, GetSessionErrors, GetSessionResponse, GetSessionResponses, KnowledgeCitation, KnowledgeLookupInfo, ListFactsData, ListFactsError, ListFactsErrors, ListFactsResponse, ListFactsResponses, ListRelationsData, ListRelationsError, ListRelationsErrors, ListRelationsResponse, ListRelationsResponses, ListSessionsData, ListSessionsError, ListSessionsErrors, ListSessionsResponse, ListSessionsResponses, MessageInfo, MessageKnowledge, MessagePage, RelationInfo, RelationPage, SessionCreateRequest, SessionDetail, SessionInfo, SessionPage, ValidationIssue } from './types.gen.js';
|
|
1
|
+
export type { ClientOptions, CompactionInfo, CompactRequest, CompactSessionData, CompactSessionError, CompactSessionErrors, CompactSessionResponse, CompactSessionResponses, CreateSessionData, CreateSessionError, CreateSessionErrors, CreateSessionResponse, CreateSessionResponses, DeleteAllFactsData, DeleteAllFactsError, DeleteAllFactsErrors, DeleteAllFactsResponse, DeleteAllFactsResponses, DeleteFactData, DeleteFactError, DeleteFactErrors, DeleteFactResponse, DeleteFactResponses, DeleteSessionData, DeleteSessionError, DeleteSessionErrors, DeleteSessionResponse, DeleteSessionResponses, ErrorCode, ErrorInfo, ErrorResponse, ExtractSessionFactsData, ExtractSessionFactsError, ExtractSessionFactsErrors, ExtractSessionFactsResponse, ExtractSessionFactsResponses, FactInfo, FactPage, FactsDeleted, GetSessionData, GetSessionError, GetSessionErrors, GetSessionResponse, GetSessionResponses, KnowledgeCitation, KnowledgeLookupInfo, ListFactsData, ListFactsError, ListFactsErrors, ListFactsResponse, ListFactsResponses, ListRelationsData, ListRelationsError, ListRelationsErrors, ListRelationsResponse, ListRelationsResponses, ListSessionsData, ListSessionsError, ListSessionsErrors, ListSessionsResponse, ListSessionsResponses, MessageInfo, MessageKnowledge, MessagePage, MessageToolCall, RelationInfo, RelationPage, SessionCreateRequest, SessionDetail, SessionInfo, SessionPage, ValidationIssue } from './types.gen.js';
|
package/dist/gen/types.gen.d.ts
CHANGED
|
@@ -89,6 +89,10 @@ export type MessageInfo = {
|
|
|
89
89
|
*/
|
|
90
90
|
mood_intensity: number | null;
|
|
91
91
|
role: 'user' | 'assistant';
|
|
92
|
+
/**
|
|
93
|
+
* On a reply: the calls of your tools it made, in order, each with its arguments and what it answered. Empty when it called none, and on the person's messages.
|
|
94
|
+
*/
|
|
95
|
+
tool_calls: Array<MessageToolCall>;
|
|
92
96
|
};
|
|
93
97
|
export type MessageKnowledge = {
|
|
94
98
|
lookups: Array<KnowledgeLookupInfo>;
|
|
@@ -114,6 +118,40 @@ export type KnowledgeCitation = {
|
|
|
114
118
|
score: number;
|
|
115
119
|
title: string;
|
|
116
120
|
};
|
|
121
|
+
export type MessageToolCall = {
|
|
122
|
+
/**
|
|
123
|
+
* The call's id, `call_…`: what your server or app was sent.
|
|
124
|
+
*/
|
|
125
|
+
call_id: string;
|
|
126
|
+
name: string;
|
|
127
|
+
kind: 'webhook' | 'app';
|
|
128
|
+
/**
|
|
129
|
+
* What the model called it with.
|
|
130
|
+
*/
|
|
131
|
+
arguments: {
|
|
132
|
+
[key: string]: unknown;
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* What it answered, as the model read it — its JSON, or its text, cut at 16 KB. Null when it answered nothing.
|
|
136
|
+
*/
|
|
137
|
+
result?: unknown;
|
|
138
|
+
/**
|
|
139
|
+
* It answered in time, with a 2xx or a result.
|
|
140
|
+
*/
|
|
141
|
+
ok: boolean;
|
|
142
|
+
/**
|
|
143
|
+
* What failed, as the model was told — or, for a tool that asks first, that it waited for the person's yes. Null when nothing did.
|
|
144
|
+
*/
|
|
145
|
+
error: string | null;
|
|
146
|
+
/**
|
|
147
|
+
* How long it took.
|
|
148
|
+
*/
|
|
149
|
+
ms: number;
|
|
150
|
+
/**
|
|
151
|
+
* Which of the reply's rounds of calls, 1 to 3; 0 for a call the person confirmed with a tap.
|
|
152
|
+
*/
|
|
153
|
+
round: number;
|
|
154
|
+
};
|
|
117
155
|
export type RelationInfo = {
|
|
118
156
|
agent_id: string;
|
|
119
157
|
/**
|
package/dist/protocol.gen.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/** The protocol, sent as the WebSocket subprotocol and echoed on `ready`. */
|
|
2
2
|
export declare const PROTOCOL = "ino.v2";
|
|
3
3
|
/** Every frame a client may send; the edge closes on any other (4009). */
|
|
4
|
-
export declare const CLIENT_VERBS: readonly ["auth", "user_message", "user_audio.start", "user_audio.end", "cancel", "mute", "ping"];
|
|
4
|
+
export declare const CLIENT_VERBS: readonly ["auth", "user_message", "user_audio.start", "user_audio.end", "cancel", "mute", "ping", "tool.confirmed"];
|
|
5
5
|
export type ClientVerb = (typeof CLIENT_VERBS)[number];
|
|
6
6
|
/** Every event the edge sends. */
|
|
7
|
-
export declare const SERVER_EVENTS: readonly ["ready", "turn.start", "heard", "heard.partial", "transcript", "mood", "text.delta", "text.chunk", "thought.delta", "tool.start", "tool.end", "knowledge", "audio.start", "audio.end", "muted", "relation", "usage", "turn.done", "interrupted", "error", "pong"];
|
|
7
|
+
export declare const SERVER_EVENTS: readonly ["ready", "turn.start", "heard", "heard.partial", "transcript", "mood", "text.delta", "text.chunk", "thought.delta", "tool.start", "tool.end", "tool.confirm", "knowledge", "audio.start", "audio.end", "muted", "relation", "usage", "turn.done", "interrupted", "error", "pong"];
|
|
8
8
|
export type ServerEventName = (typeof SERVER_EVENTS)[number];
|
|
9
9
|
/** The events that end a turn: exactly one of them ends every turn. */
|
|
10
10
|
export declare const TERMINAL_EVENTS: readonly ["turn.done", "interrupted"];
|
package/dist/protocol.gen.js
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
/** The protocol, sent as the WebSocket subprotocol and echoed on `ready`. */
|
|
6
6
|
export const PROTOCOL = "ino.v2";
|
|
7
7
|
/** Every frame a client may send; the edge closes on any other (4009). */
|
|
8
|
-
export const CLIENT_VERBS = ["auth", "user_message", "user_audio.start", "user_audio.end", "cancel", "mute", "ping"];
|
|
8
|
+
export const CLIENT_VERBS = ["auth", "user_message", "user_audio.start", "user_audio.end", "cancel", "mute", "ping", "tool.confirmed"];
|
|
9
9
|
/** Every event the edge sends. */
|
|
10
|
-
export const SERVER_EVENTS = ["ready", "turn.start", "heard", "heard.partial", "transcript", "mood", "text.delta", "text.chunk", "thought.delta", "tool.start", "tool.end", "knowledge", "audio.start", "audio.end", "muted", "relation", "usage", "turn.done", "interrupted", "error", "pong"];
|
|
10
|
+
export const SERVER_EVENTS = ["ready", "turn.start", "heard", "heard.partial", "transcript", "mood", "text.delta", "text.chunk", "thought.delta", "tool.start", "tool.end", "tool.confirm", "knowledge", "audio.start", "audio.end", "muted", "relation", "usage", "turn.done", "interrupted", "error", "pong"];
|
|
11
11
|
/** The events that end a turn: exactly one of them ends every turn. */
|
|
12
12
|
export const TERMINAL_EVENTS = ["turn.done", "interrupted"];
|
|
13
13
|
/** A `ping` of exactly this text is answered by the edge's runtime with `KEEPALIVE_PONG`, which has no `seq`. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lumavox/client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Talk to Lumavox agents from a browser, a React Native app or Node, with an end user's ephemeral key: conversations on the agent's socket, sessions, memory and relations. Zero dependencies.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|