@vinaverse/client 0.1.0-alpha.2 → 0.1.0-alpha.4

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.
@@ -1,5 +1,5 @@
1
- import { Q as Question, A as AnswerInput, H as HeldCard, T as ToolLine, S as SessionInfo, C as ClientSecret, a as SessionOptions, P as ProposalOutcome } from '../session--W6JXfwo.cjs';
2
- export { b as CONTRACT, c as Card, d as CardKind, e as ClientErrorCode, f as HeldQuestion, g as Proposal, V as VinaverseClientError, i as isKnownCard } from '../session--W6JXfwo.cjs';
1
+ import { Q as Question, A as AnswerInput, H as HeldCard, W as Welcome, T as ToolLine, S as SessionInfo, C as ClientSecret, a as SessionOptions, P as ProposalOutcome } from '../session-C3qZwGPG.cjs';
2
+ export { b as CONTRACT, c as Card, d as CardGroup, e as CardImage, f as CardKind, g as CardLink, h as ClientErrorCode, i as HeldQuestion, j as Proposal, V as VinaverseClientError, k as isKnownCard } from '../session-C3qZwGPG.cjs';
3
3
 
4
4
  type AnswerProblem =
5
5
  /** Nothing chosen or typed, and the question is required (or skipped while required). */
@@ -47,7 +47,10 @@ type ConversationStatus =
47
47
  | 'sse'
48
48
  /** The session ended; `next` says how the conversation goes on. */
49
49
  | 'ended'
50
- /** The client secret was refused and no fresh one could be had. */
50
+ /**
51
+ * The client secret was refused, and the new session the store then asked for was refused as well: `start()` (the
52
+ * person's "Try again") asks for another.
53
+ */
51
54
  | 'unauthorized'
52
55
  /** `dispose()` or `clear()` closed it. */
53
56
  | 'closed';
@@ -102,13 +105,17 @@ interface SystemItem {
102
105
  readonly event: SystemEvent;
103
106
  /**
104
107
  * `takeover_started`: `by`; `handoff_created`: `expected_response`; `flow_completed`: `result`, `code`;
105
- * `turn_failed` (a turn that failed before any of its reply streamed): `code`, `message`, `retryable`.
108
+ * `turn_failed` (a turn that failed before any of its reply streamed): `code`, `message`, `retryable`, `turn` (its `turn_id`), and `retry`:
109
+ * the server allows a retry and the person's text that started the turn is known, so `retryTurn(key)` sends it
110
+ * again (false once it did).
106
111
  */
107
112
  readonly data: Readonly<Record<string, string | boolean | null>>;
108
113
  }
109
114
  type TimelineItem = MessageItem | CardItem | SystemItem;
110
115
  interface ConversationView {
111
116
  readonly status: ConversationStatus;
117
+ /** The conversation the sessions belong to, once a session named it; for the tenant's own records and support. */
118
+ readonly conversationId: string | null;
112
119
  readonly banner: ConversationBanner;
113
120
  /**
114
121
  * How the conversation goes on after the session ended: `continue` on the person's next action (it resumes on its
@@ -119,6 +126,11 @@ interface ConversationView {
119
126
  readonly name: string | null;
120
127
  readonly avatarUrl: string | null;
121
128
  };
129
+ /**
130
+ * The tenant's greeting and chips for the session's mode (v1-draft.20, `Session.welcome`), or null. A UI shows it on
131
+ * an empty conversation; a chip sends its `message` as the person's own text (`send`).
132
+ */
133
+ readonly welcome: Welcome | null;
122
134
  /** The server's AI disclosure; null until the first one, when the UI shows its own line. Never hidden. */
123
135
  readonly disclosure: string | null;
124
136
  /** While a person from the business replies: their role (`by`, never a name). */
@@ -179,6 +191,13 @@ type ConversationSession = SessionInfo & {
179
191
  readonly avatar_url?: string;
180
192
  };
181
193
  readonly disclosure?: string;
194
+ /**
195
+ * When the session ends (`Session.expires_at`: the earliest of its own limit and the tenant's tool token). Past it,
196
+ * the conversation goes on in a new session from `getSession`, never with a fresh secret for this one.
197
+ */
198
+ readonly expires_at?: string;
199
+ /** v1-draft.20: the tenant's greeting and chips for the session's mode (`Session.welcome`); no model call. */
200
+ readonly welcome?: Welcome;
182
201
  };
183
202
  /**
184
203
  * Runs a callback before the next frame; `requestAnimationFrame` where there is one. Every listener, of the view and
@@ -249,6 +268,8 @@ declare class ConversationStore {
249
268
  /** Proposals whose tenant decision threw: shown as recoverable, the person may decide again. */
250
269
  private readonly decisionErrors;
251
270
  private system;
271
+ /** The person's text that started each recent turn, by `turn_id` (`turn.started` echoes its `client_event_id`). */
272
+ private readonly turnInputs;
252
273
  /** Numbers system rows that carry no id of their own. */
253
274
  private systemSeq;
254
275
  private history;
@@ -259,6 +280,8 @@ declare class ConversationStore {
259
280
  private readySession;
260
281
  private cardOrder;
261
282
  private kept;
283
+ /** Cards an earlier session drew, kept by a merged transcript: drawn as restored, taking no tap. */
284
+ private readonly inert;
262
285
  private locale;
263
286
  /** The request for a session in flight, to abort when it is no longer wanted. */
264
287
  private fetching;
@@ -297,7 +320,12 @@ declare class ConversationStore {
297
320
  /** In the background (`closeInBackground`): the connection is closed; the engine keeps what was sent, to resend. */
298
321
  private suspended;
299
322
  private suspend;
300
- /** Back in the foreground: a new connection to the same session, with a fresh secret when the backend gives one. */
323
+ /**
324
+ * Back in the foreground, or the person acted while away: a new connection to the same session, with a fresh secret
325
+ * when the backend gives one. A session that passed its end meanwhile is never reopened (a fresh secret cannot bring
326
+ * back an expired tool token): the person's action continues the conversation in a new session from `getSession`,
327
+ * and until then nothing connects.
328
+ */
301
329
  private wake;
302
330
  /** The network as the app sees it; null when unknown. Back online reconnects a connection that gave up. */
303
331
  setOnline(online: boolean | null): void;
@@ -321,6 +349,12 @@ declare class ConversationStore {
321
349
  decideProposal(cardId: string, decide: () => Promise<ProposalOutcome>): Promise<ProposalOutcome | null>;
322
350
  /** Send a "not sent" message again, as a new message (the person's action). Returns the new id. */
323
351
  retry(key: string): string | null;
352
+ /**
353
+ * Send again the person's text whose turn failed before any reply (a `turn_failed` row with `data.retry`), as a new
354
+ * message (the person's action). Once per row: its `retry` turns false. Returns the new id, or null when the row
355
+ * allows no retry.
356
+ */
357
+ retryTurn(key: string): string | null;
324
358
  /** After the conversation continued on another device: continue it here (the person's choice). */
325
359
  continueHere(): Promise<void>;
326
360
  /** Stop the turn in progress. */
@@ -336,8 +370,12 @@ declare class ConversationStore {
336
370
  /** The person acted after the session ended idle, expired or at its limit: the next session takes what they sent. */
337
371
  private continueIfEnded;
338
372
  private reconnectIfDown;
373
+ /** A refusal already led to a new session, and none has been ready since: another refusal is no cue. */
374
+ private rolled;
339
375
  private statusChanged;
340
376
  private event;
377
+ /** The person's text that started a turn, while its message is on screen. */
378
+ private turnText;
341
379
  /**
342
380
  * A resumed session's transcript replaced the messages, and a chat transcript carries text only: the engine drops
343
381
  * the cards it drew, and draws the pending ones again at the end. Each card on screen is anchored just after the
@@ -362,10 +400,37 @@ declare class ConversationStore {
362
400
  private key;
363
401
  private restore;
364
402
  private schedulePersist;
403
+ /** Past the session's end (`expires_at`), when the backend passed it on. */
404
+ private sessionOver;
365
405
  private live;
366
406
  private required;
367
407
  }
368
408
  /** One conversation with an agent, for any UI: see `ConversationStore`. */
369
409
  declare function createConversation(options: ConversationOptions): ConversationStore;
370
410
 
371
- export { AnswerInput, type AnswerProblem, type CardItem, type ConversationBanner, type ConversationOptions, type ConversationPersistence, type ConversationSession, type ConversationStatus, ConversationStore, type ConversationView, type FrameScheduler, HeldCard, MAX_TEXT, type MessageItem, type MessageState, ProposalOutcome, Question, type SessionReason, type SessionRequest, type StreamingText, type SystemEvent, type SystemItem, type TimelineItem, ToolLine, answerProblem, codePoints, createConversation, isAllowedLink, isValidLinkPrefix };
411
+ /** A session request, with the mode it is for. */
412
+ interface ModeSessionRequest extends SessionRequest {
413
+ readonly mode: string;
414
+ }
415
+ interface ConversationsByModeOptions extends Omit<ConversationOptions, 'getSession'> {
416
+ /** Your backend creates the session for the mode's agent (its `subject.type`, its agent), with its service key. */
417
+ readonly getSession: (request: ModeSessionRequest) => Promise<ConversationSession>;
418
+ /** Every mode the app has, so `clear()` forgets each one's kept history, even one not opened since launch. */
419
+ readonly modes?: readonly string[];
420
+ }
421
+ interface ConversationsByMode {
422
+ /** The mode's store, made the first time it is asked for; the same store after that. */
423
+ get(mode: string): ConversationStore;
424
+ /**
425
+ * The mode the person switched to: its store, with every other mode's sent to the background (no pings; closed
426
+ * with `closeInBackground`). The kit then drives the selected one with the app's foreground and background.
427
+ */
428
+ select(mode: string): ConversationStore;
429
+ /** Close every mode's store. */
430
+ dispose(): void;
431
+ /** Close every mode's store and forget what each kept on the device (sign-out). */
432
+ clear(): void;
433
+ }
434
+ declare function createConversationsByMode(options: ConversationsByModeOptions): ConversationsByMode;
435
+
436
+ export { AnswerInput, type AnswerProblem, type CardItem, type ConversationBanner, type ConversationOptions, type ConversationPersistence, type ConversationSession, type ConversationStatus, ConversationStore, type ConversationView, type ConversationsByMode, type ConversationsByModeOptions, type FrameScheduler, HeldCard, MAX_TEXT, type MessageItem, type MessageState, type ModeSessionRequest, ProposalOutcome, Question, type SessionReason, type SessionRequest, type StreamingText, type SystemEvent, type SystemItem, type TimelineItem, ToolLine, Welcome, answerProblem, codePoints, createConversation, createConversationsByMode, isAllowedLink, isValidLinkPrefix };
@@ -1,5 +1,5 @@
1
- import { Q as Question, A as AnswerInput, H as HeldCard, T as ToolLine, S as SessionInfo, C as ClientSecret, a as SessionOptions, P as ProposalOutcome } from '../session--W6JXfwo.js';
2
- export { b as CONTRACT, c as Card, d as CardKind, e as ClientErrorCode, f as HeldQuestion, g as Proposal, V as VinaverseClientError, i as isKnownCard } from '../session--W6JXfwo.js';
1
+ import { Q as Question, A as AnswerInput, H as HeldCard, W as Welcome, T as ToolLine, S as SessionInfo, C as ClientSecret, a as SessionOptions, P as ProposalOutcome } from '../session-C3qZwGPG.js';
2
+ export { b as CONTRACT, c as Card, d as CardGroup, e as CardImage, f as CardKind, g as CardLink, h as ClientErrorCode, i as HeldQuestion, j as Proposal, V as VinaverseClientError, k as isKnownCard } from '../session-C3qZwGPG.js';
3
3
 
4
4
  type AnswerProblem =
5
5
  /** Nothing chosen or typed, and the question is required (or skipped while required). */
@@ -47,7 +47,10 @@ type ConversationStatus =
47
47
  | 'sse'
48
48
  /** The session ended; `next` says how the conversation goes on. */
49
49
  | 'ended'
50
- /** The client secret was refused and no fresh one could be had. */
50
+ /**
51
+ * The client secret was refused, and the new session the store then asked for was refused as well: `start()` (the
52
+ * person's "Try again") asks for another.
53
+ */
51
54
  | 'unauthorized'
52
55
  /** `dispose()` or `clear()` closed it. */
53
56
  | 'closed';
@@ -102,13 +105,17 @@ interface SystemItem {
102
105
  readonly event: SystemEvent;
103
106
  /**
104
107
  * `takeover_started`: `by`; `handoff_created`: `expected_response`; `flow_completed`: `result`, `code`;
105
- * `turn_failed` (a turn that failed before any of its reply streamed): `code`, `message`, `retryable`.
108
+ * `turn_failed` (a turn that failed before any of its reply streamed): `code`, `message`, `retryable`, `turn` (its `turn_id`), and `retry`:
109
+ * the server allows a retry and the person's text that started the turn is known, so `retryTurn(key)` sends it
110
+ * again (false once it did).
106
111
  */
107
112
  readonly data: Readonly<Record<string, string | boolean | null>>;
108
113
  }
109
114
  type TimelineItem = MessageItem | CardItem | SystemItem;
110
115
  interface ConversationView {
111
116
  readonly status: ConversationStatus;
117
+ /** The conversation the sessions belong to, once a session named it; for the tenant's own records and support. */
118
+ readonly conversationId: string | null;
112
119
  readonly banner: ConversationBanner;
113
120
  /**
114
121
  * How the conversation goes on after the session ended: `continue` on the person's next action (it resumes on its
@@ -119,6 +126,11 @@ interface ConversationView {
119
126
  readonly name: string | null;
120
127
  readonly avatarUrl: string | null;
121
128
  };
129
+ /**
130
+ * The tenant's greeting and chips for the session's mode (v1-draft.20, `Session.welcome`), or null. A UI shows it on
131
+ * an empty conversation; a chip sends its `message` as the person's own text (`send`).
132
+ */
133
+ readonly welcome: Welcome | null;
122
134
  /** The server's AI disclosure; null until the first one, when the UI shows its own line. Never hidden. */
123
135
  readonly disclosure: string | null;
124
136
  /** While a person from the business replies: their role (`by`, never a name). */
@@ -179,6 +191,13 @@ type ConversationSession = SessionInfo & {
179
191
  readonly avatar_url?: string;
180
192
  };
181
193
  readonly disclosure?: string;
194
+ /**
195
+ * When the session ends (`Session.expires_at`: the earliest of its own limit and the tenant's tool token). Past it,
196
+ * the conversation goes on in a new session from `getSession`, never with a fresh secret for this one.
197
+ */
198
+ readonly expires_at?: string;
199
+ /** v1-draft.20: the tenant's greeting and chips for the session's mode (`Session.welcome`); no model call. */
200
+ readonly welcome?: Welcome;
182
201
  };
183
202
  /**
184
203
  * Runs a callback before the next frame; `requestAnimationFrame` where there is one. Every listener, of the view and
@@ -249,6 +268,8 @@ declare class ConversationStore {
249
268
  /** Proposals whose tenant decision threw: shown as recoverable, the person may decide again. */
250
269
  private readonly decisionErrors;
251
270
  private system;
271
+ /** The person's text that started each recent turn, by `turn_id` (`turn.started` echoes its `client_event_id`). */
272
+ private readonly turnInputs;
252
273
  /** Numbers system rows that carry no id of their own. */
253
274
  private systemSeq;
254
275
  private history;
@@ -259,6 +280,8 @@ declare class ConversationStore {
259
280
  private readySession;
260
281
  private cardOrder;
261
282
  private kept;
283
+ /** Cards an earlier session drew, kept by a merged transcript: drawn as restored, taking no tap. */
284
+ private readonly inert;
262
285
  private locale;
263
286
  /** The request for a session in flight, to abort when it is no longer wanted. */
264
287
  private fetching;
@@ -297,7 +320,12 @@ declare class ConversationStore {
297
320
  /** In the background (`closeInBackground`): the connection is closed; the engine keeps what was sent, to resend. */
298
321
  private suspended;
299
322
  private suspend;
300
- /** Back in the foreground: a new connection to the same session, with a fresh secret when the backend gives one. */
323
+ /**
324
+ * Back in the foreground, or the person acted while away: a new connection to the same session, with a fresh secret
325
+ * when the backend gives one. A session that passed its end meanwhile is never reopened (a fresh secret cannot bring
326
+ * back an expired tool token): the person's action continues the conversation in a new session from `getSession`,
327
+ * and until then nothing connects.
328
+ */
301
329
  private wake;
302
330
  /** The network as the app sees it; null when unknown. Back online reconnects a connection that gave up. */
303
331
  setOnline(online: boolean | null): void;
@@ -321,6 +349,12 @@ declare class ConversationStore {
321
349
  decideProposal(cardId: string, decide: () => Promise<ProposalOutcome>): Promise<ProposalOutcome | null>;
322
350
  /** Send a "not sent" message again, as a new message (the person's action). Returns the new id. */
323
351
  retry(key: string): string | null;
352
+ /**
353
+ * Send again the person's text whose turn failed before any reply (a `turn_failed` row with `data.retry`), as a new
354
+ * message (the person's action). Once per row: its `retry` turns false. Returns the new id, or null when the row
355
+ * allows no retry.
356
+ */
357
+ retryTurn(key: string): string | null;
324
358
  /** After the conversation continued on another device: continue it here (the person's choice). */
325
359
  continueHere(): Promise<void>;
326
360
  /** Stop the turn in progress. */
@@ -336,8 +370,12 @@ declare class ConversationStore {
336
370
  /** The person acted after the session ended idle, expired or at its limit: the next session takes what they sent. */
337
371
  private continueIfEnded;
338
372
  private reconnectIfDown;
373
+ /** A refusal already led to a new session, and none has been ready since: another refusal is no cue. */
374
+ private rolled;
339
375
  private statusChanged;
340
376
  private event;
377
+ /** The person's text that started a turn, while its message is on screen. */
378
+ private turnText;
341
379
  /**
342
380
  * A resumed session's transcript replaced the messages, and a chat transcript carries text only: the engine drops
343
381
  * the cards it drew, and draws the pending ones again at the end. Each card on screen is anchored just after the
@@ -362,10 +400,37 @@ declare class ConversationStore {
362
400
  private key;
363
401
  private restore;
364
402
  private schedulePersist;
403
+ /** Past the session's end (`expires_at`), when the backend passed it on. */
404
+ private sessionOver;
365
405
  private live;
366
406
  private required;
367
407
  }
368
408
  /** One conversation with an agent, for any UI: see `ConversationStore`. */
369
409
  declare function createConversation(options: ConversationOptions): ConversationStore;
370
410
 
371
- export { AnswerInput, type AnswerProblem, type CardItem, type ConversationBanner, type ConversationOptions, type ConversationPersistence, type ConversationSession, type ConversationStatus, ConversationStore, type ConversationView, type FrameScheduler, HeldCard, MAX_TEXT, type MessageItem, type MessageState, ProposalOutcome, Question, type SessionReason, type SessionRequest, type StreamingText, type SystemEvent, type SystemItem, type TimelineItem, ToolLine, answerProblem, codePoints, createConversation, isAllowedLink, isValidLinkPrefix };
411
+ /** A session request, with the mode it is for. */
412
+ interface ModeSessionRequest extends SessionRequest {
413
+ readonly mode: string;
414
+ }
415
+ interface ConversationsByModeOptions extends Omit<ConversationOptions, 'getSession'> {
416
+ /** Your backend creates the session for the mode's agent (its `subject.type`, its agent), with its service key. */
417
+ readonly getSession: (request: ModeSessionRequest) => Promise<ConversationSession>;
418
+ /** Every mode the app has, so `clear()` forgets each one's kept history, even one not opened since launch. */
419
+ readonly modes?: readonly string[];
420
+ }
421
+ interface ConversationsByMode {
422
+ /** The mode's store, made the first time it is asked for; the same store after that. */
423
+ get(mode: string): ConversationStore;
424
+ /**
425
+ * The mode the person switched to: its store, with every other mode's sent to the background (no pings; closed
426
+ * with `closeInBackground`). The kit then drives the selected one with the app's foreground and background.
427
+ */
428
+ select(mode: string): ConversationStore;
429
+ /** Close every mode's store. */
430
+ dispose(): void;
431
+ /** Close every mode's store and forget what each kept on the device (sign-out). */
432
+ clear(): void;
433
+ }
434
+ declare function createConversationsByMode(options: ConversationsByModeOptions): ConversationsByMode;
435
+
436
+ export { AnswerInput, type AnswerProblem, type CardItem, type ConversationBanner, type ConversationOptions, type ConversationPersistence, type ConversationSession, type ConversationStatus, ConversationStore, type ConversationView, type ConversationsByMode, type ConversationsByModeOptions, type FrameScheduler, HeldCard, MAX_TEXT, type MessageItem, type MessageState, type ModeSessionRequest, ProposalOutcome, Question, type SessionReason, type SessionRequest, type StreamingText, type SystemEvent, type SystemItem, type TimelineItem, ToolLine, Welcome, answerProblem, codePoints, createConversation, createConversationsByMode, isAllowedLink, isValidLinkPrefix };