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

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.
Files changed (41) hide show
  1. package/README.md +46 -0
  2. package/dist/agent/index.cjs +2852 -0
  3. package/dist/agent/index.cjs.map +1 -0
  4. package/dist/agent/index.d.cts +57 -0
  5. package/dist/agent/index.d.ts +57 -0
  6. package/dist/agent/index.js +99 -0
  7. package/dist/agent/index.js.map +1 -0
  8. package/dist/chunk-3WR2SUG2.js +416 -0
  9. package/dist/chunk-3WR2SUG2.js.map +1 -0
  10. package/dist/{chunk-MKUNSAMT.js → chunk-GWLLUOFY.js} +3 -9
  11. package/dist/chunk-GWLLUOFY.js.map +1 -0
  12. package/dist/chunk-VSJDVLCP.js +9 -0
  13. package/dist/chunk-VSJDVLCP.js.map +1 -0
  14. package/dist/chunk-ZWG2TMUL.js +975 -0
  15. package/dist/chunk-ZWG2TMUL.js.map +1 -0
  16. package/dist/contract-_NMdPjgN.d.cts +6 -0
  17. package/dist/contract-_NMdPjgN.d.ts +6 -0
  18. package/dist/conversation/index.cjs +1 -1
  19. package/dist/conversation/index.cjs.map +1 -1
  20. package/dist/conversation/index.d.cts +6 -377
  21. package/dist/conversation/index.d.ts +6 -377
  22. package/dist/conversation/index.js +5 -973
  23. package/dist/conversation/index.js.map +1 -1
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.cts +2 -1
  26. package/dist/index.d.ts +2 -1
  27. package/dist/index.js +2 -1
  28. package/dist/runtime-B4nKwOTF.d.ts +232 -0
  29. package/dist/runtime-DDxwWBBr.d.cts +232 -0
  30. package/dist/{session-C3qZwGPG.d.cts → session-8W3fRNeb.d.cts} +1514 -253
  31. package/dist/{session-C3qZwGPG.d.ts → session-8W3fRNeb.d.ts} +1514 -253
  32. package/dist/store-C7FtS5AY.d.cts +384 -0
  33. package/dist/store-DFk0ayh8.d.ts +384 -0
  34. package/dist/testing/index.cjs +237 -0
  35. package/dist/testing/index.cjs.map +1 -0
  36. package/dist/testing/index.d.cts +49 -0
  37. package/dist/testing/index.d.ts +49 -0
  38. package/dist/testing/index.js +222 -0
  39. package/dist/testing/index.js.map +1 -0
  40. package/package.json +33 -1
  41. package/dist/chunk-MKUNSAMT.js.map +0 -1
@@ -1,248 +1,493 @@
1
- declare const CONTRACT: {
2
- readonly api: "v1-draft.20";
3
- readonly commit: "5f6f41bdbfbdd6eadf21180eed1ffddfa5310355";
4
- };
5
-
6
- /** A frame as received or sent: its `type`, and whatever else the contract gives it. */
7
- interface Frame {
8
- readonly type: string;
9
- readonly [field: string]: unknown;
10
- }
11
- /** A card as the app holds it. `locked` lists the question ids (the card's, or a `rate_each` row's) drawn locked. */
12
- interface HeldCard {
13
- readonly id: string;
14
- readonly kind: string;
15
- readonly card: Readonly<Record<string, unknown>>;
16
- readonly question?: HeldQuestion;
17
- readonly locked: readonly string[];
18
- /** The turn that drew the card, when known: `ui.action` names it with the card's `id`. */
19
- readonly turnId?: string;
20
- /** A proposal's first reported outcome (`confirmed`, `declined`, `failed`, `expired`); later ones change nothing. */
21
- readonly outcome?: string | null;
22
- /** Arrival order, shared with messages: a timeline sorts both by it. Moves when the card is drawn again. */
23
- readonly seq: number;
24
- }
25
- interface HeldQuestion {
26
- readonly question_id: string;
27
- readonly kind: string;
28
- readonly state: string;
29
- readonly answer?: unknown;
30
- readonly row_answers?: readonly {
31
- question_id: string;
32
- answer: unknown;
33
- }[];
34
- readonly rows?: readonly {
35
- question_id: string;
36
- }[];
37
- readonly [field: string]: unknown;
38
- }
39
- interface Message {
40
- readonly role: 'assistant' | 'person' | 'staff' | (string & {});
41
- readonly text: string;
42
- /**
43
- * Stable for the message's life, to key it in a list: a person's text by its `client_event_id`, an agent's reply by
44
- * its turn (`a:<turn_id>`), a staff reply by its `message_id` (`s:<id>`), a guardrail refusal by the input it answers
45
- * (`r:<client_event_id>`), a transcript item by its server `id` as the live key it matches, or by its time and role
46
- * (`t:<at>:<role>`) from a server that sends no `id`.
47
- */
48
- readonly key: string;
49
- /** Arrival order, shared with cards: a timeline sorts both by it. */
50
- readonly seq: number;
51
- /**
52
- * A reply cut off after some of it streamed; what streamed stands (§6): `blocked` (`output_blocked`), `interrupted`
53
- * (`cancelled`, as when a person from the business takes over, or the connection dropped), `failed` (any other code).
54
- */
55
- readonly partial?: 'blocked' | 'interrupted' | 'failed';
56
- /** A person's text recorded during a takeover (`input.received`): the business reads it; no agent turn runs. */
57
- readonly received?: true;
58
- /** The agent's reply is a guardrail refusal (`input.rejected` `guardrail`, its `message`). */
59
- readonly refusal?: true;
60
- }
61
- /** A person from the business is replying (`takeover.started`); `by` is their role as the person sees it. */
62
- interface Takeover {
63
- readonly by: string | null;
64
- readonly at: string;
65
- }
66
- /** The turn's text streamed so far (`message.delta`), until its `message.completed`. */
67
- interface Streaming {
68
- readonly turnId: string;
69
- readonly text: string;
70
- /** Taken at the turn's first delta, and kept by its message: a reply sorts before the cards its turn drew after it. */
71
- readonly seq: number;
72
- }
73
- interface Connection {
74
- readonly name: string;
75
- readonly state: 'open' | 'closed';
76
- readonly code?: number;
77
- readonly reason?: string;
78
- }
79
- interface ToolLine {
80
- readonly turn_id: string;
81
- readonly label: string;
82
- readonly state: string;
83
- }
84
1
  /**
85
- * Whether and how the conversation goes on after a connection ends:
86
- * - `allowed`: reconnect to the same session;
87
- * - `user_action_only`: the session was revoked or replaced (the conversation continued elsewhere): resume only when
88
- * the person asks;
89
- * - `new_session_on_next_action`: the session ended (idle, expired, limit_reached) but the conversation did not; its
90
- * secret is spent. On the person's next action, the app has its backend create a new session for the same
91
- * conversation and calls `resume()`.
2
+ * This file was auto-generated by openapi-typescript.
3
+ * Do not make direct changes to the file.
92
4
  */
93
- type Reconnect = 'allowed' | 'user_action_only' | 'new_session_on_next_action';
94
- /** The engine's whole state, for an app to draw. */
95
- interface ConversationState {
96
- readonly sessionId: string | null;
97
- readonly conversationId: string | null;
98
- readonly connection: Connection | null;
99
- /** How the conversation goes on after the connection ends (`Reconnect`). */
100
- readonly reconnect: Reconnect;
101
- readonly messages: readonly Message[];
102
- /** Every card held, oldest first. */
103
- readonly cards: readonly HeldCard[];
104
- /** The newest question card still open: the one to answer. */
105
- readonly openQuestion: string | null;
106
- /** Events sent and neither acknowledged nor refused, by `client_event_id`: resend them, same id, after a reconnect. */
107
- readonly unacknowledged: readonly Frame[];
108
- /** Ids refused for now (`turn_in_progress`, `screen_unavailable`): send again with the same id. */
109
- readonly resend: readonly string[];
110
- /**
111
- * Texts and answers refused with `limit_reached`: never resent in this session (it would get the same refusal);
112
- * resent, same id, on the next session's `session.ready`. Kept apart from `resend` (conformance README, `held`). A
113
- * refused action is dropped: a new session cannot act on an earlier session's card.
114
- */
115
- readonly held: readonly string[];
116
- /** Typed messages whose refusal stands, by `client_event_id`: shown as not sent, never resent. */
117
- readonly refused: Readonly<Record<string, string>>;
118
- /** The last `flow.completed`: `ok`, `refused` or `failed` (an unknown result reads as `failed`). */
119
- readonly flow: {
120
- readonly flow: unknown;
121
- readonly result: 'ok' | 'refused' | 'failed';
122
- } | null;
123
- /** The turn in progress. */
124
- readonly turn: string | null;
125
- /** The last state of each tool line (the last 100). */
126
- readonly tools: readonly ToolLine[];
127
- readonly handoffs: readonly unknown[];
128
- /** The codes of `error` and `turn.failed` events (the last 100). */
129
- readonly errors: readonly string[];
130
- /**
131
- * While `reconnect` is `new_session_on_next_action`: the `client_event_id`s held for the next session (unacknowledged,
132
- * or refused for this session's turn limit). Draw them as "sends when you continue", not as failed. Empty otherwise.
133
- */
134
- readonly heldForNextSession: readonly string[];
135
- /** Seconds left when `session.expiring` arrived (WebSocket only, about a minute before the end); null otherwise. */
136
- readonly expiring: number | null;
137
- /** The turn's text streamed so far, until its `message.completed` (or its end, which keeps it as a message). */
138
- readonly streaming: Streaming | null;
139
- /** While a person from the business replies (§8): from `takeover.started` to `takeover.ended`. */
140
- readonly takeover: Takeover | null;
141
- /** Every refusal's code and `message` (`input.rejected`), by `client_event_id`; `refused` lists those that stand. */
142
- readonly rejections: Readonly<Record<string, {
143
- code: string;
144
- message: string;
145
- }>>;
146
- /** The AI disclosure `session.ready` carries: always shown, never removed. Null until the first one. */
147
- readonly disclosure: string | null;
148
- /** `session.ready`'s `limits.turns_left`, when given. */
149
- readonly turnsLeft: number | null;
150
- }
151
- declare class ConversationEngine {
152
- private sessionId;
153
- private conversationId;
154
- private connection;
155
- private reconnect;
156
- private messages;
157
- private cards;
158
- private unacknowledged;
159
- private resend;
160
- private held;
161
- private refused;
162
- private flow;
163
- private turn;
164
- private tools;
165
- private handoffs;
166
- private errors;
167
- private expiring;
168
- private streaming;
169
- private takeover;
170
- private rejections;
171
- private disclosure;
172
- private turnsLeft;
173
- /** The next arrival number for a message or a card. */
174
- private seq;
175
- /** The cards drawn before a resumed flow's transcript replaced them: proposal outcomes carry over. */
176
- private replaced;
177
- /** client_event_id → the first event the app sent under it, until it is settled. */
178
- private readonly inputs;
179
- /** The tenant's backend created a session (and named its conversation). */
180
- sessionCreated(sessionId: string, conversationId?: string | null): void;
181
- /** A connection opened: the user's own action, or an allowed reconnect, so it lifts a hold on reconnecting. */
182
- connected(name: string): void;
183
- /** A connection closed with its code. `4403` (revoked) and `4409` (replaced) hold reconnecting for a user action. */
184
- closed(name: string, code: number): void;
185
- /** The app was killed: what it drew is gone; what it sent and never saw acknowledged it kept, to resend. */
186
- killed(): void;
187
- sent(event: Frame): void;
188
- received(event: Frame): void;
189
- private ready;
190
- /**
191
- * A transcript merged by key: an item the app holds keeps its place, with the text the server recorded; one it does
192
- * not hold goes just after the nearest earlier item it does (just before the first later one when none came before,
193
- * at the end when it holds none of them). Nothing the app holds is dropped.
194
- */
195
- private mergeTranscript;
196
- private hold;
197
- private recorded;
198
- private rejected;
199
- private inputRejected;
200
- /** No longer to resend, nor held for the next session (sent again, or settled). */
201
- private unqueue;
202
- /** An input acknowledged or refused for good: nothing more is resent under its id. */
203
- private settle;
204
- /** Adds a message once: a key already held (a frame seen twice) changes nothing. */
205
- private say;
206
- /** The turn's streamed text, kept as the agent's message when the turn ends without its `message.completed`. */
207
- private cutOff;
208
- private error;
209
- /**
210
- * An input that could not be delivered, or whose retries are spent (`screen_unavailable` after the last try): it is
211
- * no longer resent. A typed message is shown as not sent, with `code`; an answer's question unlocks so the person
212
- * can answer again; a proposal outcome it reported is taken back, so it can be reported again.
213
- */
214
- giveUp(clientEventId: string, code: string): void;
215
- /** A turn the app stopped where no event will say so (an SSE turn cancelled): none is in progress. */
216
- turnEnded(): void;
217
- /** The event first sent under a `client_event_id`, to resend it unchanged. */
218
- input(clientEventId: string): Frame | undefined;
219
- state(): ConversationState;
220
- }
221
5
 
222
- /** Why the client refused to do something; `code` is stable, `message` is for people. */
223
- type ClientErrorCode =
224
- /** A service key (`vv_sk_`) was given: it belongs on the tenant's backend, never in an app. */
225
- 'service_key'
226
- /** The value is not a client secret (`vv_cs_` and at least 16 base64url characters). */
227
- | 'invalid_secret'
228
- /** The action needs the WebSocket (answers to question cards); the session runs over SSE. */
229
- | 'needs_websocket'
230
- /** The session was closed by the app, or ended for good (replaced, revoked, expired). */
231
- | 'session_ended'
232
- /** An SSE request failed: `status` holds the HTTP status. */
233
- | 'http_error'
234
- /**
235
- * The session ended but the conversation did not (idle, expired, its turn limit): its secret is spent. Have your
236
- * backend create a new session for the conversation and call `resume()` with it.
237
- */
238
- | 'needs_new_session';
239
- declare class VinaverseClientError extends Error {
240
- readonly name = "VinaverseClientError";
241
- readonly code: ClientErrorCode;
242
- readonly status: number | undefined;
243
- constructor(code: ClientErrorCode, message: string, status?: number);
6
+ interface paths {
7
+ "/v1/sessions": {
8
+ parameters: {
9
+ query?: never;
10
+ header?: never;
11
+ path?: never;
12
+ cookie?: never;
13
+ };
14
+ get?: never;
15
+ put?: never;
16
+ /**
17
+ * Create an agent session for one subject
18
+ * @description A session belongs to a conversation when it names one (`conversation_key`, `conversation_id`, or both) or when its agent runs a guided flow; a flow session that names none starts a new conversation. `Session` then returns its `conversation_id`, and a conversation started without a key can later be resumed by that id. A conversation is scoped to the tenant, the environment, the `subject.id` and the `agent`, and (v1-draft.20) the mode and business scope it started with; `subject.type` itself is not part of it, so a guest who signs in keeps the conversation.
19
+ * **`business_setup`.** The `business_setup` capability is only for a business's own people: a `subject.type` of `professional`, `host` or `staff`. Asked for any other subject, it is `400 invalid_request` with the pointer `/tool_access/capabilities`.
20
+ * **`booking_proposals`.** The `booking_proposals` capability is only for a `client`: not a guest, who has no account in the tenant's app to confirm with. Asked for any other subject, it is `400 invalid_request` with the pointer `/tool_access/capabilities`.
21
+ * **Audience** (v1-draft.20). An agent talks only to the subject types of its template (admin-v1 `AgentProfile.audience`): the customer agent to a `client` or `guest`, a business agent to a `professional`, `host` or `staff`, a guided flow to anyone its tenant names. Any other `subject.type` is `400 invalid_request` with the pointer `/subject/type`. The tenant's backend sets the type by the side of its app the person is on, never by the account's roles: a professional booking for themselves is a `client`.
22
+ * **Mode and business scope** (v1-draft.20). `experience_mode` is the agent's side: `customer` for the customer agent, `business` for a business agent. Left out, it follows the agent's template; given, it must match it (`400 invalid_request`, `/experience_mode`). `business_scope_id` names the business the person acts for (a professional's business, a host's place): only with `business` (`400`, `/business_scope_id`), and the tenant's backend derives it from its own records, never from the app. A conversation is bound, when it starts, to the subject, the agent, the mode and the business scope. The mode stands for the side of the app, so a guest who signs in as a client keeps their conversation, while a professional never resumes a customer conversation (the audience rule keeps each side's types apart). Resuming with any of them different is `404 not_found` (step 1 below), never a switch: a person acting for business A never resumes business B's conversation.
23
+ * **The checks, in this order:** 1. `conversation_id` is given, and is unknown, erased, or belongs to another tenant, environment, `agent` or
24
+ * `subject.id`, or (v1-draft.20) was started with another `experience_mode` or `business_scope_id`: `404
25
+ * not_found`. A `conversation_key` names a conversation within the same binding,
26
+ * so the same key under another binding names another conversation.
27
+ * 2. Both are given, and the key names a different conversation, or none: `409 conversation_mismatch`. 3. The conversation expired: `410 conversation_expired`. With `conversation_key` alone, an expired
28
+ * conversation instead lets a new one start under the key; the id never starts one silently.
29
+ * 4. The conversation is completed (its flow was accepted): `409 conversation_completed`. This holds by key too,
30
+ * so a finished survey is never started twice.
31
+ *
32
+ * **Resuming** is the same however the conversation is named. The new session continues the conversation, and `conversation_id` stays the same. The agent gets the answers recorded so far and a short summary, and re-emits the pending question card under its original `id`. A question card keeps its `id` across the sessions of a conversation, so an answer resent on a later session still names it. `client_event_id`s are deduplicated across all the sessions of the conversation. The older open session of the conversation is replaced (`session.closed replaced`, close `4409`). Each session still has its own short-lived client secret.
33
+ */
34
+ post: operations["createSession"];
35
+ delete?: never;
36
+ options?: never;
37
+ head?: never;
38
+ patch?: never;
39
+ trace?: never;
40
+ };
41
+ "/v1/suggestions": {
42
+ parameters: {
43
+ query?: never;
44
+ header?: never;
45
+ path?: never;
46
+ cookie?: never;
47
+ };
48
+ get?: never;
49
+ put?: never;
50
+ /**
51
+ * Pick, rank and word a few explore suggestions from the candidates the tenant sends
52
+ * @description Synchronous, with a service key that has `sessions:write` (a key without scopes has every scope). Feature `suggestions`, for caps and switches: when it is off or capped, the answer is `feature_unavailable`, as everywhere else.
53
+ * **Time.** The tenant waits at most 1.5 seconds. The runtime answers within 1.2 seconds, with what it has by then, or an empty list. A request whose caller disconnected before the answer is not charged and does not count toward the `suggestions` cap, so the tenant's ledger, which records the `usage` it receives, stays exact.
54
+ * **The split.** The tenant supplies the facts: `candidates` from its own live data, each with a `ref`, a `kind`, a `title` and open `facts`. The agent picks between `min` and `max` of them, ranks them, and writes a short `title` and `why` for each. It may also turn one into a question for the agent (`action: ask`). - **Never an invented target.** `ref` is always one of the request's candidates, and `null` only for `ask`. - **Never a claim beyond the facts.** `why` uses only the facts sent. An unknown `facts` key is ignored. - **No filler.** With fewer than `min` good suggestions, the list is empty. `min` greater than `max` is
55
+ * `400 invalid_request` with the pointer `/max`.
56
+ * - **Language and length.** `title`, `why` and `question` are in `subject.locale`, falling back to the
57
+ * tenant's default locale and then English. Their lengths are counted in Unicode code points; a check in a
58
+ * language whose strings are UTF-16 (.NET, JavaScript) must count code points, not UTF-16 units.
59
+ *
60
+ * **Candidates are untrusted data.** Candidate `title`s and `facts` often come from other people (a host's listing title, a professional's name). They enter the model as quoted data in a delimited block, never as instructions, and the platform floor applies: every `title`, `why` and `question` passes the leak check and the blocked-topic filter before it is returned.
61
+ * **Tool mode.** Only when `candidates` is omitted and `tool_access` is given does the agent read the tenant's `read` tools for candidates. With `candidates` present, the tools are not read, and every `ref` is a candidate's. In tool mode: - `why` uses only the tool results; - a `ref` is `<kind>:<id>`, with the `id` exactly as the tenant's read tool returned it: `professional` from
62
+ * `get_professional` and the search tools, `space` from `get_workspace`, `service` from the catalogue's
63
+ * `service_type`, `class` from a tool that returns classes;
64
+ * - the tenant validates a `ref` by fetching that object again before it shows the suggestion.
65
+ * **The agent's guardrails apply.** The suggestions follow the `scope` and `blocked_topics` of the request's `agent` (default `customer_assistant`). An `agent` the tenant does not have is `400 invalid_request` with the pointer `/agent`. `business_setup` or `booking_proposals` in `tool_access` is refused (`400 invalid_request`, `/tool_access/capabilities`): suggestions never propose, and the subject is a `client` or a `guest`.
66
+ * **Privacy and caching.** `personalized` says whether any suggestion used the subject's own history, from a `facts` key such as `booked_by_subject` or from the tools. It is always `false` for a `guest`. A personalised answer never crosses subjects: its cache key includes the tenant, environment and `subject.id`, and the rest of the key (place, filters, a cell size) is the tenant's choice. A response with `personalized: false` may also be cached across subjects. The decision records are kept for the tenant's `transcript_retention` (at most 30 days; with `none`, not after the answer), and are erased with the subject (`eraseSubject`).
67
+ * **An `ask` suggestion** opens the agent with `question` already typed in the composer. It becomes the person's message only when they send it, and they may edit it first. No session field carries the suggestion.
68
+ */
69
+ post: operations["createSuggestions"];
70
+ delete?: never;
71
+ options?: never;
72
+ head?: never;
73
+ patch?: never;
74
+ trace?: never;
75
+ };
76
+ "/v1/conversations/{conversation_id}": {
77
+ parameters: {
78
+ query?: never;
79
+ header?: never;
80
+ path?: never;
81
+ cookie?: never;
82
+ };
83
+ /**
84
+ * The state of one conversation, with all its answers
85
+ * @description The same `ConversationState` the conversation webhooks carry, always complete: `answers` and `remarks` are never omitted here, and `sequence` is the same counter the webhooks carry. Use it when a webhook arrives with `answers_omitted: true`, or to check where a person is.
86
+ * **Access.** A service key only, never a client secret, and only for the key's own tenant and environment. The key needs the `conversations:read` scope (a key without scopes has every scope); otherwise `403 forbidden`.
87
+ * **How long the state can be read.** - While the conversation lives. - **72 hours after it ends without acceptance** (`expired`, including one whose last submission
88
+ * `failed`): the final state, answers included, stays readable, so a backend that missed an omitted
89
+ * webhook can still fetch the answers.
90
+ * - **Under `transcript_retention: none`,** the state is deleted on acceptance, and the tenant already holds
91
+ * the accepted submission. The read then answers `410` at once.
92
+ *
93
+ * After that window the read answers `410 conversation_expired`, from a tombstone that keeps no answers (see `docs/conversation-state.md`). An unknown or erased conversation, or one of another tenant or environment, is `404 not_found`.
94
+ */
95
+ get: operations["getConversation"];
96
+ put?: never;
97
+ post?: never;
98
+ delete?: never;
99
+ options?: never;
100
+ head?: never;
101
+ patch?: never;
102
+ trace?: never;
103
+ };
104
+ "/v1/sessions/{session_id}": {
105
+ parameters: {
106
+ query?: never;
107
+ header?: never;
108
+ path?: never;
109
+ cookie?: never;
110
+ };
111
+ get: operations["getSession"];
112
+ put?: never;
113
+ post?: never;
114
+ delete?: never;
115
+ options?: never;
116
+ head?: never;
117
+ patch?: never;
118
+ trace?: never;
119
+ };
120
+ "/v1/sessions/{session_id}/revoke": {
121
+ parameters: {
122
+ query?: never;
123
+ header?: never;
124
+ path?: never;
125
+ cookie?: never;
126
+ };
127
+ get?: never;
128
+ put?: never;
129
+ post: operations["revokeSession"];
130
+ delete?: never;
131
+ options?: never;
132
+ head?: never;
133
+ patch?: never;
134
+ trace?: never;
135
+ };
136
+ "/v1/sessions/{session_id}/client_secret": {
137
+ parameters: {
138
+ query?: never;
139
+ header?: never;
140
+ path?: never;
141
+ cookie?: never;
142
+ };
143
+ get?: never;
144
+ put?: never;
145
+ /**
146
+ * A fresh client secret for an open session
147
+ * @description A service key with the `sessions:write` scope gets a new connect secret for an open session, for an app that missed the connect window or connects from another device (whose connection then replaces the open one, with close code 4409). The previous secret no longer authenticates a new connection or an SSE turn. A socket already open stays open and keeps its session: refreshing never drops the person's live connection. To cut it off, revoke the session (`revokeSession`). An ended session is `409 session_closed`.
148
+ */
149
+ post: operations["refreshClientSecret"];
150
+ delete?: never;
151
+ options?: never;
152
+ head?: never;
153
+ patch?: never;
154
+ trace?: never;
155
+ };
156
+ "/v1/sessions/{session_id}/turns": {
157
+ parameters: {
158
+ query?: never;
159
+ header?: never;
160
+ path?: never;
161
+ cookie?: never;
162
+ };
163
+ get?: never;
164
+ put?: never;
165
+ /**
166
+ * Run one turn and stream its events as SSE (alternative to the WebSocket)
167
+ * @description Browsers and WebViews (v1-draft.18): the preflight (`OPTIONS`) is answered for the tenant's client origins of the session's environment only (admin-v1 `ClientOrigins.effective`), with `Access-Control-Allow-Origin` the request's origin (never `*`), `Vary: Origin`, `Access-Control-Allow-Methods: POST`, `Access-Control-Allow-Headers: Authorization, Content-Type` and `Access-Control-Max-Age: 600`; no credentials mode is needed (the client secret is a header). Any other origin, or a session that does not exist, gets no CORS headers. A request whose `Origin` is not one of them is refused with `403` `forbidden` and runs nothing; a request with no `Origin` (a native app, a server) is not checked.
168
+ */
169
+ post: operations["createTurnSse"];
170
+ delete?: never;
171
+ options?: never;
172
+ head?: never;
173
+ patch?: never;
174
+ trace?: never;
175
+ };
176
+ "/v1/sessions/{session_id}/turns/{turn_id}/actions": {
177
+ parameters: {
178
+ query?: never;
179
+ header?: never;
180
+ path?: never;
181
+ cookie?: never;
182
+ };
183
+ get?: never;
184
+ put?: never;
185
+ /**
186
+ * Send a card action and stream the resulting turn as SSE
187
+ * @description Browsers and WebViews (v1-draft.18), as for `createTurnSse`: the preflight (`OPTIONS`) is answered for the tenant's client origins of the session's environment only (admin-v1 `ClientOrigins.effective`), with `Access-Control-Allow-Origin` the request's origin (never `*`), `Vary: Origin`, `Access-Control-Allow-Methods: POST`, `Access-Control-Allow-Headers: Authorization, Content-Type` and `Access-Control-Max-Age: 600`; no credentials mode is needed (the client secret is a header). Any other origin, or a session that does not exist, gets no CORS headers. A request whose `Origin` is not one of them is refused with `403` `forbidden` and runs nothing; a request with no `Origin` (a native app, a server) is not checked.
188
+ */
189
+ post: operations["createCardActionSse"];
190
+ delete?: never;
191
+ options?: never;
192
+ head?: never;
193
+ patch?: never;
194
+ trace?: never;
195
+ };
196
+ "/v1/moderation/jobs": {
197
+ parameters: {
198
+ query?: never;
199
+ header?: never;
200
+ path?: never;
201
+ cookie?: never;
202
+ };
203
+ get?: never;
204
+ put?: never;
205
+ post: operations["createModerationJob"];
206
+ delete?: never;
207
+ options?: never;
208
+ head?: never;
209
+ patch?: never;
210
+ trace?: never;
211
+ };
212
+ "/v1/moderation/jobs/{job_id}": {
213
+ parameters: {
214
+ query?: never;
215
+ header?: never;
216
+ path?: never;
217
+ cookie?: never;
218
+ };
219
+ get: operations["getModerationJob"];
220
+ put?: never;
221
+ post?: never;
222
+ delete?: never;
223
+ options?: never;
224
+ head?: never;
225
+ patch?: never;
226
+ trace?: never;
227
+ };
228
+ "/v1/moderation/items/{item_id}": {
229
+ parameters: {
230
+ query?: never;
231
+ header?: never;
232
+ path?: never;
233
+ cookie?: never;
234
+ };
235
+ get: operations["getModerationItem"];
236
+ put?: never;
237
+ post?: never;
238
+ delete?: never;
239
+ options?: never;
240
+ head?: never;
241
+ patch?: never;
242
+ trace?: never;
243
+ };
244
+ "/v1/media/avatars/{avatar_file}": {
245
+ parameters: {
246
+ query?: never;
247
+ header?: never;
248
+ path?: never;
249
+ cookie?: never;
250
+ };
251
+ /**
252
+ * An agent's avatar image (v1-draft.19), as `Session.agent.avatar_url` names it
253
+ * @description Public: no credential, since an app draws it in an image view. Only an avatar that passed the screen is served, and only while it is an agent's current or previous avatar of the last 30 days; anything else is `404`. The bytes never change under a name (`Cache-Control: public, max-age=31536000, immutable`), and the response is `image/webp` with `X-Content-Type-Options: nosniff` and a sandboxing `Content-Security-Policy`.
254
+ */
255
+ get: operations["getAgentAvatarImage"];
256
+ put?: never;
257
+ post?: never;
258
+ delete?: never;
259
+ options?: never;
260
+ head?: never;
261
+ patch?: never;
262
+ trace?: never;
263
+ };
264
+ "/v1/media/jobs": {
265
+ parameters: {
266
+ query?: never;
267
+ header?: never;
268
+ path?: never;
269
+ cookie?: never;
270
+ };
271
+ get: operations["listMediaJobs"];
272
+ put?: never;
273
+ /**
274
+ * @description Queue a media job. `moderate` is required; `transcode`, `poster` and `captions` are optional (video only)
275
+ * and write to the tenant's destination under `<prefix>/<job id>/`. Same tenant, same `media.sha256`, same
276
+ * steps and same policy version within 30 days returns the earlier completed job with `200` and
277
+ * `deduplicated: true`, not charged; `force: true` reprocesses. When the expected wait exceeds the tenant's
278
+ * soft limit the job is accepted with `delayed: true` and a later `estimated_completion_at`; past the hard
279
+ * limit the request is refused with `429` and `Retry-After`.
280
+ */
281
+ post: operations["createMediaJob"];
282
+ delete?: never;
283
+ options?: never;
284
+ head?: never;
285
+ patch?: never;
286
+ trace?: never;
287
+ };
288
+ "/v1/media/jobs/{job_id}": {
289
+ parameters: {
290
+ query?: never;
291
+ header?: never;
292
+ path?: never;
293
+ cookie?: never;
294
+ };
295
+ get: operations["getMediaJob"];
296
+ put?: never;
297
+ post?: never;
298
+ delete?: never;
299
+ options?: never;
300
+ head?: never;
301
+ patch?: never;
302
+ trace?: never;
303
+ };
304
+ "/v1/media/jobs/{job_id}/cancel": {
305
+ parameters: {
306
+ query?: never;
307
+ header?: never;
308
+ path?: never;
309
+ cookie?: never;
310
+ };
311
+ get?: never;
312
+ put?: never;
313
+ /**
314
+ * @description Stops the job at the next step boundary (within seconds) and deletes outputs already written. Idempotent:
315
+ * cancelling an ended job returns it unchanged.
316
+ */
317
+ post: operations["cancelMediaJob"];
318
+ delete?: never;
319
+ options?: never;
320
+ head?: never;
321
+ patch?: never;
322
+ trace?: never;
323
+ };
324
+ "/v1/media/profiles": {
325
+ parameters: {
326
+ query?: never;
327
+ header?: never;
328
+ path?: never;
329
+ cookie?: never;
330
+ };
331
+ get: operations["listMediaProfiles"];
332
+ put?: never;
333
+ post?: never;
334
+ delete?: never;
335
+ options?: never;
336
+ head?: never;
337
+ patch?: never;
338
+ trace?: never;
339
+ };
340
+ "/v1/screening/text": {
341
+ parameters: {
342
+ query?: never;
343
+ header?: never;
344
+ path?: never;
345
+ cookie?: never;
346
+ };
347
+ get?: never;
348
+ put?: never;
349
+ post: operations["screenText"];
350
+ delete?: never;
351
+ options?: never;
352
+ head?: never;
353
+ patch?: never;
354
+ trace?: never;
355
+ };
356
+ "/v1/document-checks": {
357
+ parameters: {
358
+ query?: never;
359
+ header?: never;
360
+ path?: never;
361
+ cookie?: never;
362
+ };
363
+ get?: never;
364
+ put?: never;
365
+ post: operations["createDocumentCheck"];
366
+ delete?: never;
367
+ options?: never;
368
+ head?: never;
369
+ patch?: never;
370
+ trace?: never;
371
+ };
372
+ "/v1/document-checks/{check_id}": {
373
+ parameters: {
374
+ query?: never;
375
+ header?: never;
376
+ path?: never;
377
+ cookie?: never;
378
+ };
379
+ /** @description Fields are present only within 24 hours of completion; afterwards only flags remain. */
380
+ get: operations["getDocumentCheck"];
381
+ put?: never;
382
+ post?: never;
383
+ delete?: never;
384
+ options?: never;
385
+ head?: never;
386
+ patch?: never;
387
+ trace?: never;
388
+ };
389
+ "/v1/feedback": {
390
+ parameters: {
391
+ query?: never;
392
+ header?: never;
393
+ path?: never;
394
+ cookie?: never;
395
+ };
396
+ get?: never;
397
+ put?: never;
398
+ post: operations["sendFeedback"];
399
+ delete?: never;
400
+ options?: never;
401
+ head?: never;
402
+ patch?: never;
403
+ trace?: never;
404
+ };
405
+ "/v1/subjects/{subject_id}/erase": {
406
+ parameters: {
407
+ query?: never;
408
+ header?: never;
409
+ path?: never;
410
+ cookie?: never;
411
+ };
412
+ get?: never;
413
+ put?: never;
414
+ /**
415
+ * @description Erases the subject's data: transcripts, screening texts, memory, indexes, the conversation state of its guided flows (recorded answers, remarks, transcript), and the explore suggestion decisions made for it, and revokes its open sessions. `subject.erased` follows.
416
+ * **A subject Vinaverse holds nothing for** (never seen, or already erased) is `404` with `code: not_found` and `type: https://docs.vinaverse.com/problems/subject-not-found`; a client matches on the `type` ending in `/problems/subject-not-found`. Only that answer means nothing is held, and nothing needs erasing. Vinaverse keeps no record of erased subjects to tell the two apart. Any other `404` (a wrong base URL, say) is not that answer, and the caller retries.
417
+ */
418
+ post: operations["eraseSubject"];
419
+ delete?: never;
420
+ options?: never;
421
+ head?: never;
422
+ patch?: never;
423
+ trace?: never;
424
+ };
425
+ "/v1/events": {
426
+ parameters: {
427
+ query?: never;
428
+ header?: never;
429
+ path?: never;
430
+ cookie?: never;
431
+ };
432
+ get?: never;
433
+ put?: never;
434
+ /** @description Contract §13.1. Each event must validate against its type's JSON Schema in the event catalogue (`contracts/events/beauty_marketplace@1/`); one invalid event rejects the call. */
435
+ post: operations["sendEvents"];
436
+ delete?: never;
437
+ options?: never;
438
+ head?: never;
439
+ patch?: never;
440
+ trace?: never;
441
+ };
442
+ "/v1/knowledge/documents": {
443
+ parameters: {
444
+ query?: never;
445
+ header?: never;
446
+ path?: never;
447
+ cookie?: never;
448
+ };
449
+ get?: never;
450
+ put?: never;
451
+ post: operations["sendKnowledgeDocument"];
452
+ delete?: never;
453
+ options?: never;
454
+ head?: never;
455
+ patch?: never;
456
+ trace?: never;
457
+ };
458
+ "/v1/catalog/{type}/{id}": {
459
+ parameters: {
460
+ query?: never;
461
+ header?: never;
462
+ path?: never;
463
+ cookie?: never;
464
+ };
465
+ get?: never;
466
+ put: operations["putCatalogEntity"];
467
+ post?: never;
468
+ delete?: never;
469
+ options?: never;
470
+ head?: never;
471
+ patch?: never;
472
+ trace?: never;
473
+ };
474
+ "/v1/usage": {
475
+ parameters: {
476
+ query?: never;
477
+ header?: never;
478
+ path?: never;
479
+ cookie?: never;
480
+ };
481
+ get: operations["getUsage"];
482
+ put?: never;
483
+ post?: never;
484
+ delete?: never;
485
+ options?: never;
486
+ head?: never;
487
+ patch?: never;
488
+ trace?: never;
489
+ };
244
490
  }
245
-
246
491
  interface components {
247
492
  schemas: {
248
493
  Problem: {
@@ -1874,20 +2119,796 @@ interface components {
1874
2119
  };
1875
2120
  };
1876
2121
  };
1877
- parameters: {
1878
- IdempotencyKey: string;
1879
- MediaJobId: string;
1880
- ConversationId: components["schemas"]["ConversationId"];
1881
- SessionId: string;
1882
- };
1883
- requestBodies: never;
1884
- headers: {
1885
- /** @description Vinaverse-Request-Id */
1886
- RequestId: string;
2122
+ parameters: {
2123
+ IdempotencyKey: string;
2124
+ MediaJobId: string;
2125
+ ConversationId: components["schemas"]["ConversationId"];
2126
+ SessionId: string;
2127
+ };
2128
+ requestBodies: never;
2129
+ headers: {
2130
+ /** @description Vinaverse-Request-Id */
2131
+ RequestId: string;
2132
+ };
2133
+ pathItems: never;
2134
+ }
2135
+ interface operations {
2136
+ createSession: {
2137
+ parameters: {
2138
+ query?: never;
2139
+ header: {
2140
+ "Idempotency-Key": components["parameters"]["IdempotencyKey"];
2141
+ };
2142
+ path?: never;
2143
+ cookie?: never;
2144
+ };
2145
+ requestBody: {
2146
+ content: {
2147
+ "application/json": components["schemas"]["SessionCreate"];
2148
+ };
2149
+ };
2150
+ responses: {
2151
+ /** @description Created */
2152
+ 201: {
2153
+ headers: {
2154
+ [name: string]: unknown;
2155
+ };
2156
+ content: {
2157
+ "application/json": components["schemas"]["Session"];
2158
+ };
2159
+ };
2160
+ 400: components["responses"]["Problem"];
2161
+ 401: components["responses"]["Problem"];
2162
+ 403: components["responses"]["Problem"];
2163
+ 404: components["responses"]["Problem"];
2164
+ 409: components["responses"]["Problem"];
2165
+ 410: components["responses"]["Problem"];
2166
+ 429: components["responses"]["RateLimited"];
2167
+ 503: components["responses"]["Problem"];
2168
+ };
2169
+ };
2170
+ createSuggestions: {
2171
+ parameters: {
2172
+ query?: never;
2173
+ header?: never;
2174
+ path?: never;
2175
+ cookie?: never;
2176
+ };
2177
+ requestBody: {
2178
+ content: {
2179
+ "application/json": components["schemas"]["SuggestionsRequest"];
2180
+ };
2181
+ };
2182
+ responses: {
2183
+ /** @description OK */
2184
+ 200: {
2185
+ headers: {
2186
+ [name: string]: unknown;
2187
+ };
2188
+ content: {
2189
+ "application/json": components["schemas"]["SuggestionsResponse"];
2190
+ };
2191
+ };
2192
+ 400: components["responses"]["Problem"];
2193
+ 401: components["responses"]["Problem"];
2194
+ 403: components["responses"]["Problem"];
2195
+ 429: components["responses"]["RateLimited"];
2196
+ 503: components["responses"]["Problem"];
2197
+ };
2198
+ };
2199
+ getConversation: {
2200
+ parameters: {
2201
+ query?: never;
2202
+ header?: never;
2203
+ path: {
2204
+ conversation_id: components["parameters"]["ConversationId"];
2205
+ };
2206
+ cookie?: never;
2207
+ };
2208
+ requestBody?: never;
2209
+ responses: {
2210
+ /** @description OK */
2211
+ 200: {
2212
+ headers: {
2213
+ [name: string]: unknown;
2214
+ };
2215
+ content: {
2216
+ "application/json": components["schemas"]["ConversationState"] & unknown;
2217
+ };
2218
+ };
2219
+ 401: components["responses"]["Problem"];
2220
+ 403: components["responses"]["Problem"];
2221
+ 404: components["responses"]["Problem"];
2222
+ 410: components["responses"]["Problem"];
2223
+ };
2224
+ };
2225
+ getSession: {
2226
+ parameters: {
2227
+ query?: never;
2228
+ header?: never;
2229
+ path: {
2230
+ session_id: components["parameters"]["SessionId"];
2231
+ };
2232
+ cookie?: never;
2233
+ };
2234
+ requestBody?: never;
2235
+ responses: {
2236
+ /** @description OK */
2237
+ 200: {
2238
+ headers: {
2239
+ [name: string]: unknown;
2240
+ };
2241
+ content: {
2242
+ "application/json": components["schemas"]["SessionStatus"];
2243
+ };
2244
+ };
2245
+ 404: components["responses"]["Problem"];
2246
+ };
2247
+ };
2248
+ revokeSession: {
2249
+ parameters: {
2250
+ query?: never;
2251
+ header?: never;
2252
+ path: {
2253
+ session_id: components["parameters"]["SessionId"];
2254
+ };
2255
+ cookie?: never;
2256
+ };
2257
+ requestBody?: never;
2258
+ responses: {
2259
+ /** @description Revoked (idempotent) */
2260
+ 200: {
2261
+ headers: {
2262
+ [name: string]: unknown;
2263
+ };
2264
+ content: {
2265
+ "application/json": components["schemas"]["SessionStatus"];
2266
+ };
2267
+ };
2268
+ 404: components["responses"]["Problem"];
2269
+ };
2270
+ };
2271
+ refreshClientSecret: {
2272
+ parameters: {
2273
+ query?: never;
2274
+ header?: never;
2275
+ path: {
2276
+ session_id: components["parameters"]["SessionId"];
2277
+ };
2278
+ cookie?: never;
2279
+ };
2280
+ requestBody?: never;
2281
+ responses: {
2282
+ /** @description OK */
2283
+ 200: {
2284
+ headers: {
2285
+ [name: string]: unknown;
2286
+ };
2287
+ content: {
2288
+ "application/json": components["schemas"]["ClientSecret"];
2289
+ };
2290
+ };
2291
+ 409: components["responses"]["Problem"];
2292
+ };
2293
+ };
2294
+ createTurnSse: {
2295
+ parameters: {
2296
+ query?: never;
2297
+ header?: never;
2298
+ path: {
2299
+ session_id: components["parameters"]["SessionId"];
2300
+ };
2301
+ cookie?: never;
2302
+ };
2303
+ requestBody: {
2304
+ content: {
2305
+ "application/json": components["schemas"]["TurnInput"];
2306
+ };
2307
+ };
2308
+ responses: {
2309
+ /** @description `text/event-stream`. Each event's `event:` is a ServerEvent `type`; `data:` is the ServerEvent JSON. */
2310
+ 200: {
2311
+ headers: {
2312
+ [name: string]: unknown;
2313
+ };
2314
+ content: {
2315
+ "text/event-stream": string;
2316
+ };
2317
+ };
2318
+ 401: components["responses"]["Problem"];
2319
+ 403: components["responses"]["Problem"];
2320
+ 409: components["responses"]["Problem"];
2321
+ 429: components["responses"]["RateLimited"];
2322
+ };
2323
+ };
2324
+ createCardActionSse: {
2325
+ parameters: {
2326
+ query?: never;
2327
+ header?: never;
2328
+ path: {
2329
+ session_id: components["parameters"]["SessionId"];
2330
+ turn_id: string;
2331
+ };
2332
+ cookie?: never;
2333
+ };
2334
+ requestBody: {
2335
+ content: {
2336
+ "application/json": {
2337
+ card_id: string;
2338
+ action: string;
2339
+ /** @description as on the WebSocket `ui.action`; required for a proposal outcome and for `select_slot` (the server refuses either without it) */
2340
+ client_event_id?: string;
2341
+ /** @description `select_slot` only (v1-draft.17): the slot picked, as on the WebSocket `ui.action` */
2342
+ slot?: components["schemas"]["SlotSelection"];
2343
+ };
2344
+ };
2345
+ };
2346
+ responses: {
2347
+ /** @description `text/event-stream` as for createTurnSse */
2348
+ 200: {
2349
+ headers: {
2350
+ [name: string]: unknown;
2351
+ };
2352
+ content: {
2353
+ "text/event-stream": string;
2354
+ };
2355
+ };
2356
+ 403: components["responses"]["Problem"];
2357
+ };
2358
+ };
2359
+ createModerationJob: {
2360
+ parameters: {
2361
+ query?: never;
2362
+ header: {
2363
+ "Idempotency-Key": components["parameters"]["IdempotencyKey"];
2364
+ };
2365
+ path?: never;
2366
+ cookie?: never;
2367
+ };
2368
+ requestBody: {
2369
+ content: {
2370
+ "application/json": components["schemas"]["ModerationJobCreate"];
2371
+ };
2372
+ };
2373
+ responses: {
2374
+ /** @description Accepted */
2375
+ 202: {
2376
+ headers: {
2377
+ [name: string]: unknown;
2378
+ };
2379
+ content: {
2380
+ "application/json": components["schemas"]["ModerationJob"];
2381
+ };
2382
+ };
2383
+ 400: components["responses"]["Problem"];
2384
+ 403: components["responses"]["Problem"];
2385
+ 413: components["responses"]["Problem"];
2386
+ 429: components["responses"]["RateLimited"];
2387
+ };
2388
+ };
2389
+ getModerationJob: {
2390
+ parameters: {
2391
+ query?: never;
2392
+ header?: never;
2393
+ path: {
2394
+ job_id: string;
2395
+ };
2396
+ cookie?: never;
2397
+ };
2398
+ requestBody?: never;
2399
+ responses: {
2400
+ /** @description OK */
2401
+ 200: {
2402
+ headers: {
2403
+ [name: string]: unknown;
2404
+ };
2405
+ content: {
2406
+ "application/json": components["schemas"]["ModerationJob"];
2407
+ };
2408
+ };
2409
+ 404: components["responses"]["Problem"];
2410
+ };
2411
+ };
2412
+ getModerationItem: {
2413
+ parameters: {
2414
+ query?: never;
2415
+ header?: never;
2416
+ path: {
2417
+ item_id: string;
2418
+ };
2419
+ cookie?: never;
2420
+ };
2421
+ requestBody?: never;
2422
+ responses: {
2423
+ /** @description OK */
2424
+ 200: {
2425
+ headers: {
2426
+ [name: string]: unknown;
2427
+ };
2428
+ content: {
2429
+ "application/json": components["schemas"]["ModerationItem"];
2430
+ };
2431
+ };
2432
+ 404: components["responses"]["Problem"];
2433
+ };
2434
+ };
2435
+ getAgentAvatarImage: {
2436
+ parameters: {
2437
+ query?: never;
2438
+ header?: never;
2439
+ path: {
2440
+ /** @description the SHA-256 of the image's bytes, its first 32 hex digits, then `.webp` */
2441
+ avatar_file: string;
2442
+ };
2443
+ cookie?: never;
2444
+ };
2445
+ requestBody?: never;
2446
+ responses: {
2447
+ /** @description the image */
2448
+ 200: {
2449
+ headers: {
2450
+ [name: string]: unknown;
2451
+ };
2452
+ content: {
2453
+ "image/webp": string;
2454
+ };
2455
+ };
2456
+ 404: components["responses"]["Problem"];
2457
+ };
2458
+ };
2459
+ listMediaJobs: {
2460
+ parameters: {
2461
+ query?: {
2462
+ ref?: string;
2463
+ status?: "queued" | "processing" | "completed" | "failed" | "cancelled";
2464
+ limit?: number;
2465
+ cursor?: string;
2466
+ };
2467
+ header?: never;
2468
+ path?: never;
2469
+ cookie?: never;
2470
+ };
2471
+ requestBody?: never;
2472
+ responses: {
2473
+ /** @description Newest first. */
2474
+ 200: {
2475
+ headers: {
2476
+ [name: string]: unknown;
2477
+ };
2478
+ content: {
2479
+ "application/json": {
2480
+ data: components["schemas"]["MediaJob"][];
2481
+ next_cursor: string | null;
2482
+ };
2483
+ };
2484
+ };
2485
+ };
2486
+ };
2487
+ createMediaJob: {
2488
+ parameters: {
2489
+ query?: never;
2490
+ header: {
2491
+ "Idempotency-Key": components["parameters"]["IdempotencyKey"];
2492
+ };
2493
+ path?: never;
2494
+ cookie?: never;
2495
+ };
2496
+ requestBody: {
2497
+ content: {
2498
+ "application/json": components["schemas"]["MediaJobCreate"];
2499
+ };
2500
+ };
2501
+ responses: {
2502
+ /** @description The same content was processed with the same steps and policy in the last 30 days. */
2503
+ 200: {
2504
+ headers: {
2505
+ [name: string]: unknown;
2506
+ };
2507
+ content: {
2508
+ "application/json": components["schemas"]["MediaJobCreated"];
2509
+ };
2510
+ };
2511
+ /** @description Accepted */
2512
+ 202: {
2513
+ headers: {
2514
+ [name: string]: unknown;
2515
+ };
2516
+ content: {
2517
+ "application/json": components["schemas"]["MediaJobCreated"];
2518
+ };
2519
+ };
2520
+ 400: components["responses"]["Problem"];
2521
+ 403: components["responses"]["Problem"];
2522
+ 409: components["responses"]["Problem"];
2523
+ 413: components["responses"]["Problem"];
2524
+ 429: components["responses"]["RateLimited"];
2525
+ };
2526
+ };
2527
+ getMediaJob: {
2528
+ parameters: {
2529
+ query?: never;
2530
+ header?: never;
2531
+ path: {
2532
+ job_id: components["parameters"]["MediaJobId"];
2533
+ };
2534
+ cookie?: never;
2535
+ };
2536
+ requestBody?: never;
2537
+ responses: {
2538
+ /** @description OK */
2539
+ 200: {
2540
+ headers: {
2541
+ [name: string]: unknown;
2542
+ };
2543
+ content: {
2544
+ "application/json": components["schemas"]["MediaJob"];
2545
+ };
2546
+ };
2547
+ 404: components["responses"]["Problem"];
2548
+ };
2549
+ };
2550
+ cancelMediaJob: {
2551
+ parameters: {
2552
+ query?: never;
2553
+ header?: never;
2554
+ path: {
2555
+ job_id: components["parameters"]["MediaJobId"];
2556
+ };
2557
+ cookie?: never;
2558
+ };
2559
+ requestBody?: never;
2560
+ responses: {
2561
+ /** @description The job, `cancelled` (or as it ended). */
2562
+ 200: {
2563
+ headers: {
2564
+ [name: string]: unknown;
2565
+ };
2566
+ content: {
2567
+ "application/json": components["schemas"]["MediaJob"];
2568
+ };
2569
+ };
2570
+ 404: components["responses"]["Problem"];
2571
+ };
2572
+ };
2573
+ listMediaProfiles: {
2574
+ parameters: {
2575
+ query?: never;
2576
+ header?: never;
2577
+ path?: never;
2578
+ cookie?: never;
2579
+ };
2580
+ requestBody?: never;
2581
+ responses: {
2582
+ /** @description The transcoding profiles, named and versioned. */
2583
+ 200: {
2584
+ headers: {
2585
+ [name: string]: unknown;
2586
+ };
2587
+ content: {
2588
+ "application/json": {
2589
+ data: components["schemas"]["MediaProfile"][];
2590
+ };
2591
+ };
2592
+ };
2593
+ };
2594
+ };
2595
+ screenText: {
2596
+ parameters: {
2597
+ query?: never;
2598
+ header?: never;
2599
+ path?: never;
2600
+ cookie?: never;
2601
+ };
2602
+ requestBody: {
2603
+ content: {
2604
+ "application/json": components["schemas"]["ScreeningRequest"];
2605
+ };
2606
+ };
2607
+ responses: {
2608
+ /** @description OK */
2609
+ 200: {
2610
+ headers: {
2611
+ [name: string]: unknown;
2612
+ };
2613
+ content: {
2614
+ "application/json": components["schemas"]["ScreeningResponse"];
2615
+ };
2616
+ };
2617
+ 400: components["responses"]["Problem"];
2618
+ 403: components["responses"]["Problem"];
2619
+ 429: components["responses"]["RateLimited"];
2620
+ 503: components["responses"]["Problem"];
2621
+ };
2622
+ };
2623
+ createDocumentCheck: {
2624
+ parameters: {
2625
+ query?: never;
2626
+ header: {
2627
+ "Idempotency-Key": components["parameters"]["IdempotencyKey"];
2628
+ };
2629
+ path?: never;
2630
+ cookie?: never;
2631
+ };
2632
+ requestBody: {
2633
+ content: {
2634
+ "application/json": components["schemas"]["DocumentCheckCreate"];
2635
+ };
2636
+ };
2637
+ responses: {
2638
+ /** @description Accepted */
2639
+ 202: {
2640
+ headers: {
2641
+ [name: string]: unknown;
2642
+ };
2643
+ content: {
2644
+ "application/json": {
2645
+ id: string;
2646
+ /** @enum {string} */
2647
+ status: "queued";
2648
+ estimated_completion_seconds?: number;
2649
+ };
2650
+ };
2651
+ };
2652
+ 400: components["responses"]["Problem"];
2653
+ 403: components["responses"]["Problem"];
2654
+ 429: components["responses"]["RateLimited"];
2655
+ };
2656
+ };
2657
+ getDocumentCheck: {
2658
+ parameters: {
2659
+ query?: never;
2660
+ header?: never;
2661
+ path: {
2662
+ check_id: string;
2663
+ };
2664
+ cookie?: never;
2665
+ };
2666
+ requestBody?: never;
2667
+ responses: {
2668
+ /** @description OK */
2669
+ 200: {
2670
+ headers: {
2671
+ [name: string]: unknown;
2672
+ };
2673
+ content: {
2674
+ "application/json": components["schemas"]["DocumentCheck"];
2675
+ };
2676
+ };
2677
+ 404: components["responses"]["Problem"];
2678
+ };
2679
+ };
2680
+ sendFeedback: {
2681
+ parameters: {
2682
+ query?: never;
2683
+ header?: never;
2684
+ path?: never;
2685
+ cookie?: never;
2686
+ };
2687
+ requestBody: {
2688
+ content: {
2689
+ "application/json": components["schemas"]["FeedbackBatch"];
2690
+ };
2691
+ };
2692
+ responses: {
2693
+ /** @description Accepted */
2694
+ 202: {
2695
+ headers: {
2696
+ [name: string]: unknown;
2697
+ };
2698
+ content: {
2699
+ "application/json": {
2700
+ accepted: number;
2701
+ rejected: {
2702
+ index: number;
2703
+ code: string;
2704
+ detail?: string;
2705
+ }[];
2706
+ };
2707
+ };
2708
+ };
2709
+ 400: components["responses"]["Problem"];
2710
+ };
2711
+ };
2712
+ eraseSubject: {
2713
+ parameters: {
2714
+ query?: never;
2715
+ header: {
2716
+ "Idempotency-Key": components["parameters"]["IdempotencyKey"];
2717
+ };
2718
+ path: {
2719
+ subject_id: components["schemas"]["SubjectId"];
2720
+ };
2721
+ cookie?: never;
2722
+ };
2723
+ requestBody?: never;
2724
+ responses: {
2725
+ /** @description Accepted; `subject.erased` follows */
2726
+ 202: {
2727
+ headers: {
2728
+ [name: string]: unknown;
2729
+ };
2730
+ content: {
2731
+ "application/json": {
2732
+ subject_id: components["schemas"]["SubjectId"];
2733
+ /** @enum {string} */
2734
+ status: "accepted" | "completed";
2735
+ sessions_revoked: number;
2736
+ /** Format: date-time */
2737
+ deadline: string;
2738
+ };
2739
+ };
2740
+ };
2741
+ /** @description Nothing held for the subject (never seen, or already erased); the problem's `type` ends in `/problems/subject-not-found` */
2742
+ 404: {
2743
+ headers: {
2744
+ "Vinaverse-Request-Id": components["headers"]["RequestId"];
2745
+ [name: string]: unknown;
2746
+ };
2747
+ content: {
2748
+ "application/problem+json": components["schemas"]["Problem"] & {
2749
+ /** @constant */
2750
+ code?: "not_found";
2751
+ type?: unknown;
2752
+ };
2753
+ };
2754
+ };
2755
+ };
2756
+ };
2757
+ sendEvents: {
2758
+ parameters: {
2759
+ query?: never;
2760
+ header?: never;
2761
+ path?: never;
2762
+ cookie?: never;
2763
+ };
2764
+ requestBody: {
2765
+ content: {
2766
+ "application/json": {
2767
+ events: components["schemas"]["Event"][];
2768
+ };
2769
+ };
2770
+ };
2771
+ responses: {
2772
+ /** @description Accepted */
2773
+ 202: {
2774
+ headers: {
2775
+ [name: string]: unknown;
2776
+ };
2777
+ content: {
2778
+ "application/json": {
2779
+ accepted: number;
2780
+ duplicates: number;
2781
+ batch_id: string;
2782
+ batch_cid: string;
2783
+ };
2784
+ };
2785
+ };
2786
+ 400: components["responses"]["Problem"];
2787
+ 403: components["responses"]["Problem"];
2788
+ 429: components["responses"]["RateLimited"];
2789
+ };
2790
+ };
2791
+ sendKnowledgeDocument: {
2792
+ parameters: {
2793
+ query?: never;
2794
+ header?: never;
2795
+ path?: never;
2796
+ cookie?: never;
2797
+ };
2798
+ requestBody: {
2799
+ content: {
2800
+ "application/json": {
2801
+ doc_id: string;
2802
+ version: string;
2803
+ title: string;
2804
+ /** @description Markdown */
2805
+ body: string;
2806
+ /** @enum {string} */
2807
+ audience: "public" | "staff";
2808
+ /** @default en */
2809
+ language?: string;
2810
+ /** Format: uri */
2811
+ url?: string;
2812
+ };
2813
+ };
2814
+ };
2815
+ responses: {
2816
+ /** @description Same version and body already stored (no change) */
2817
+ 200: {
2818
+ headers: {
2819
+ [name: string]: unknown;
2820
+ };
2821
+ content?: never;
2822
+ };
2823
+ /** @description Stored */
2824
+ 201: {
2825
+ headers: {
2826
+ [name: string]: unknown;
2827
+ };
2828
+ content: {
2829
+ "application/json": {
2830
+ doc_id: string;
2831
+ version: string;
2832
+ audience: string;
2833
+ artifact_cid: string;
2834
+ chunks: number;
2835
+ };
2836
+ };
2837
+ };
2838
+ 400: components["responses"]["Problem"];
2839
+ 403: components["responses"]["Problem"];
2840
+ };
2841
+ };
2842
+ putCatalogEntity: {
2843
+ parameters: {
2844
+ query?: never;
2845
+ header?: never;
2846
+ path: {
2847
+ type: "professional" | "workspace" | "service_type" | "area";
2848
+ id: string;
2849
+ };
2850
+ cookie?: never;
2851
+ };
2852
+ requestBody: {
2853
+ content: {
2854
+ "application/json": {
2855
+ name?: string;
2856
+ display_name?: string;
2857
+ title?: string;
2858
+ service_type_ids?: string[];
2859
+ area?: {
2860
+ city?: string;
2861
+ neighborhood?: string;
2862
+ };
2863
+ /** @default true */
2864
+ active?: boolean;
2865
+ };
2866
+ };
2867
+ };
2868
+ responses: {
2869
+ /** @description Stored or unchanged */
2870
+ 200: {
2871
+ headers: {
2872
+ [name: string]: unknown;
2873
+ };
2874
+ content: {
2875
+ "application/json": {
2876
+ type: string;
2877
+ id: string;
2878
+ changed: boolean;
2879
+ snapshot_cid: string | null;
2880
+ };
2881
+ };
2882
+ };
2883
+ 400: components["responses"]["Problem"];
2884
+ 403: components["responses"]["Problem"];
2885
+ };
2886
+ };
2887
+ getUsage: {
2888
+ parameters: {
2889
+ query?: {
2890
+ period?: string;
2891
+ };
2892
+ header?: never;
2893
+ path?: never;
2894
+ cookie?: never;
2895
+ };
2896
+ requestBody?: never;
2897
+ responses: {
2898
+ /** @description OK */
2899
+ 200: {
2900
+ headers: {
2901
+ [name: string]: unknown;
2902
+ };
2903
+ content: {
2904
+ "application/json": components["schemas"]["UsageReport"];
2905
+ };
2906
+ };
2907
+ };
1887
2908
  };
1888
- pathItems: never;
1889
2909
  }
1890
2910
 
2911
+ /** Every schema of the pinned public contract (vinaverse-v1), by name: `Schemas['Session']`, `Schemas['Card']`, … */
1891
2912
  type Schemas = components['schemas'];
1892
2913
  type ClientEvent = Schemas['ClientEvent'];
1893
2914
  type ServerEvent = Schemas['ServerEvent'];
@@ -1919,6 +2940,246 @@ declare function isKnownCard(card: {
1919
2940
  kind: string;
1920
2941
  }): card is Card;
1921
2942
 
2943
+ /** A frame as received or sent: its `type`, and whatever else the contract gives it. */
2944
+ interface Frame {
2945
+ readonly type: string;
2946
+ readonly [field: string]: unknown;
2947
+ }
2948
+ /** A card as the app holds it. `locked` lists the question ids (the card's, or a `rate_each` row's) drawn locked. */
2949
+ interface HeldCard {
2950
+ readonly id: string;
2951
+ readonly kind: string;
2952
+ readonly card: Readonly<Record<string, unknown>>;
2953
+ readonly question?: HeldQuestion;
2954
+ readonly locked: readonly string[];
2955
+ /** The turn that drew the card, when known: `ui.action` names it with the card's `id`. */
2956
+ readonly turnId?: string;
2957
+ /** A proposal's first reported outcome (`confirmed`, `declined`, `failed`, `expired`); later ones change nothing. */
2958
+ readonly outcome?: string | null;
2959
+ /** Arrival order, shared with messages: a timeline sorts both by it. Moves when the card is drawn again. */
2960
+ readonly seq: number;
2961
+ }
2962
+ interface HeldQuestion {
2963
+ readonly question_id: string;
2964
+ readonly kind: string;
2965
+ readonly state: string;
2966
+ readonly answer?: unknown;
2967
+ readonly row_answers?: readonly {
2968
+ question_id: string;
2969
+ answer: unknown;
2970
+ }[];
2971
+ readonly rows?: readonly {
2972
+ question_id: string;
2973
+ }[];
2974
+ readonly [field: string]: unknown;
2975
+ }
2976
+ interface Message {
2977
+ readonly role: 'assistant' | 'person' | 'staff' | (string & {});
2978
+ readonly text: string;
2979
+ /**
2980
+ * Stable for the message's life, to key it in a list: a person's text by its `client_event_id`, an agent's reply by
2981
+ * its turn (`a:<turn_id>`), a staff reply by its `message_id` (`s:<id>`), a guardrail refusal by the input it answers
2982
+ * (`r:<client_event_id>`), a transcript item by its server `id` as the live key it matches, or by its time and role
2983
+ * (`t:<at>:<role>`) from a server that sends no `id`.
2984
+ */
2985
+ readonly key: string;
2986
+ /** Arrival order, shared with cards: a timeline sorts both by it. */
2987
+ readonly seq: number;
2988
+ /**
2989
+ * A reply cut off after some of it streamed; what streamed stands (§6): `blocked` (`output_blocked`), `interrupted`
2990
+ * (`cancelled`, as when a person from the business takes over, or the connection dropped), `failed` (any other code).
2991
+ */
2992
+ readonly partial?: 'blocked' | 'interrupted' | 'failed';
2993
+ /** A person's text recorded during a takeover (`input.received`): the business reads it; no agent turn runs. */
2994
+ readonly received?: true;
2995
+ /** The agent's reply is a guardrail refusal (`input.rejected` `guardrail`, its `message`). */
2996
+ readonly refusal?: true;
2997
+ }
2998
+ /** A person from the business is replying (`takeover.started`); `by` is their role as the person sees it. */
2999
+ interface Takeover {
3000
+ readonly by: string | null;
3001
+ readonly at: string;
3002
+ }
3003
+ /** The turn's text streamed so far (`message.delta`), until its `message.completed`. */
3004
+ interface Streaming {
3005
+ readonly turnId: string;
3006
+ readonly text: string;
3007
+ /** Taken at the turn's first delta, and kept by its message: a reply sorts before the cards its turn drew after it. */
3008
+ readonly seq: number;
3009
+ }
3010
+ interface Connection {
3011
+ readonly name: string;
3012
+ readonly state: 'open' | 'closed';
3013
+ readonly code?: number;
3014
+ readonly reason?: string;
3015
+ }
3016
+ interface ToolLine {
3017
+ readonly turn_id: string;
3018
+ readonly label: string;
3019
+ readonly state: string;
3020
+ }
3021
+ /**
3022
+ * Whether and how the conversation goes on after a connection ends:
3023
+ * - `allowed`: reconnect to the same session;
3024
+ * - `user_action_only`: the session was revoked or replaced (the conversation continued elsewhere): resume only when
3025
+ * the person asks;
3026
+ * - `new_session_on_next_action`: the session ended (idle, expired, limit_reached) but the conversation did not; its
3027
+ * secret is spent. On the person's next action, the app has its backend create a new session for the same
3028
+ * conversation and calls `resume()`.
3029
+ */
3030
+ type Reconnect = 'allowed' | 'user_action_only' | 'new_session_on_next_action';
3031
+ /** The engine's whole state, for an app to draw. */
3032
+ interface ConversationState {
3033
+ readonly sessionId: string | null;
3034
+ readonly conversationId: string | null;
3035
+ readonly connection: Connection | null;
3036
+ /** How the conversation goes on after the connection ends (`Reconnect`). */
3037
+ readonly reconnect: Reconnect;
3038
+ readonly messages: readonly Message[];
3039
+ /** Every card held, oldest first. */
3040
+ readonly cards: readonly HeldCard[];
3041
+ /** The newest question card still open: the one to answer. */
3042
+ readonly openQuestion: string | null;
3043
+ /** Events sent and neither acknowledged nor refused, by `client_event_id`: resend them, same id, after a reconnect. */
3044
+ readonly unacknowledged: readonly Frame[];
3045
+ /** Ids refused for now (`turn_in_progress`, `screen_unavailable`): send again with the same id. */
3046
+ readonly resend: readonly string[];
3047
+ /**
3048
+ * Texts and answers refused with `limit_reached`: never resent in this session (it would get the same refusal);
3049
+ * resent, same id, on the next session's `session.ready`. Kept apart from `resend` (conformance README, `held`). A
3050
+ * refused action is dropped: a new session cannot act on an earlier session's card.
3051
+ */
3052
+ readonly held: readonly string[];
3053
+ /** Typed messages whose refusal stands, by `client_event_id`: shown as not sent, never resent. */
3054
+ readonly refused: Readonly<Record<string, string>>;
3055
+ /** The last `flow.completed`: `ok`, `refused` or `failed` (an unknown result reads as `failed`). */
3056
+ readonly flow: {
3057
+ readonly flow: unknown;
3058
+ readonly result: 'ok' | 'refused' | 'failed';
3059
+ } | null;
3060
+ /** The turn in progress. */
3061
+ readonly turn: string | null;
3062
+ /** The last state of each tool line (the last 100). */
3063
+ readonly tools: readonly ToolLine[];
3064
+ readonly handoffs: readonly unknown[];
3065
+ /** The codes of `error` and `turn.failed` events (the last 100). */
3066
+ readonly errors: readonly string[];
3067
+ /**
3068
+ * While `reconnect` is `new_session_on_next_action`: the `client_event_id`s held for the next session (unacknowledged,
3069
+ * or refused for this session's turn limit). Draw them as "sends when you continue", not as failed. Empty otherwise.
3070
+ */
3071
+ readonly heldForNextSession: readonly string[];
3072
+ /** Seconds left when `session.expiring` arrived (WebSocket only, about a minute before the end); null otherwise. */
3073
+ readonly expiring: number | null;
3074
+ /** The turn's text streamed so far, until its `message.completed` (or its end, which keeps it as a message). */
3075
+ readonly streaming: Streaming | null;
3076
+ /** While a person from the business replies (§8): from `takeover.started` to `takeover.ended`. */
3077
+ readonly takeover: Takeover | null;
3078
+ /** Every refusal's code and `message` (`input.rejected`), by `client_event_id`; `refused` lists those that stand. */
3079
+ readonly rejections: Readonly<Record<string, {
3080
+ code: string;
3081
+ message: string;
3082
+ }>>;
3083
+ /** The AI disclosure `session.ready` carries: always shown, never removed. Null until the first one. */
3084
+ readonly disclosure: string | null;
3085
+ /** `session.ready`'s `limits.turns_left`, when given. */
3086
+ readonly turnsLeft: number | null;
3087
+ }
3088
+ declare class ConversationEngine {
3089
+ private sessionId;
3090
+ private conversationId;
3091
+ private connection;
3092
+ private reconnect;
3093
+ private messages;
3094
+ private cards;
3095
+ private unacknowledged;
3096
+ private resend;
3097
+ private held;
3098
+ private refused;
3099
+ private flow;
3100
+ private turn;
3101
+ private tools;
3102
+ private handoffs;
3103
+ private errors;
3104
+ private expiring;
3105
+ private streaming;
3106
+ private takeover;
3107
+ private rejections;
3108
+ private disclosure;
3109
+ private turnsLeft;
3110
+ /** The next arrival number for a message or a card. */
3111
+ private seq;
3112
+ /** The cards drawn before a resumed flow's transcript replaced them: proposal outcomes carry over. */
3113
+ private replaced;
3114
+ /** client_event_id → the first event the app sent under it, until it is settled. */
3115
+ private readonly inputs;
3116
+ /** The tenant's backend created a session (and named its conversation). */
3117
+ sessionCreated(sessionId: string, conversationId?: string | null): void;
3118
+ /** A connection opened: the user's own action, or an allowed reconnect, so it lifts a hold on reconnecting. */
3119
+ connected(name: string): void;
3120
+ /** A connection closed with its code. `4403` (revoked) and `4409` (replaced) hold reconnecting for a user action. */
3121
+ closed(name: string, code: number): void;
3122
+ /** The app was killed: what it drew is gone; what it sent and never saw acknowledged it kept, to resend. */
3123
+ killed(): void;
3124
+ sent(event: Frame): void;
3125
+ received(event: Frame): void;
3126
+ private ready;
3127
+ /**
3128
+ * A transcript merged by key: an item the app holds keeps its place, with the text the server recorded; one it does
3129
+ * not hold goes just after the nearest earlier item it does (just before the first later one when none came before,
3130
+ * at the end when it holds none of them). Nothing the app holds is dropped.
3131
+ */
3132
+ private mergeTranscript;
3133
+ private hold;
3134
+ private recorded;
3135
+ private rejected;
3136
+ private inputRejected;
3137
+ /** No longer to resend, nor held for the next session (sent again, or settled). */
3138
+ private unqueue;
3139
+ /** An input acknowledged or refused for good: nothing more is resent under its id. */
3140
+ private settle;
3141
+ /** Adds a message once: a key already held (a frame seen twice) changes nothing. */
3142
+ private say;
3143
+ /** The turn's streamed text, kept as the agent's message when the turn ends without its `message.completed`. */
3144
+ private cutOff;
3145
+ private error;
3146
+ /**
3147
+ * An input that could not be delivered, or whose retries are spent (`screen_unavailable` after the last try): it is
3148
+ * no longer resent. A typed message is shown as not sent, with `code`; an answer's question unlocks so the person
3149
+ * can answer again; a proposal outcome it reported is taken back, so it can be reported again.
3150
+ */
3151
+ giveUp(clientEventId: string, code: string): void;
3152
+ /** A turn the app stopped where no event will say so (an SSE turn cancelled): none is in progress. */
3153
+ turnEnded(): void;
3154
+ /** The event first sent under a `client_event_id`, to resend it unchanged. */
3155
+ input(clientEventId: string): Frame | undefined;
3156
+ state(): ConversationState;
3157
+ }
3158
+
3159
+ /** Why the client refused to do something; `code` is stable, `message` is for people. */
3160
+ type ClientErrorCode =
3161
+ /** A service key (`vv_sk_`) was given: it belongs on the tenant's backend, never in an app. */
3162
+ 'service_key'
3163
+ /** The value is not a client secret (`vv_cs_` and at least 16 base64url characters). */
3164
+ | 'invalid_secret'
3165
+ /** The action needs the WebSocket (answers to question cards); the session runs over SSE. */
3166
+ | 'needs_websocket'
3167
+ /** The session was closed by the app, or ended for good (replaced, revoked, expired). */
3168
+ | 'session_ended'
3169
+ /** An SSE request failed: `status` holds the HTTP status. */
3170
+ | 'http_error'
3171
+ /**
3172
+ * The session ended but the conversation did not (idle, expired, its turn limit): its secret is spent. Have your
3173
+ * backend create a new session for the conversation and call `resume()` with it.
3174
+ */
3175
+ | 'needs_new_session';
3176
+ declare class VinaverseClientError extends Error {
3177
+ readonly name = "VinaverseClientError";
3178
+ readonly code: ClientErrorCode;
3179
+ readonly status: number | undefined;
3180
+ constructor(code: ClientErrorCode, message: string, status?: number);
3181
+ }
3182
+
1922
3183
  type FetchLike = (input: string, init: RequestInit) => Promise<Response>;
1923
3184
  /** One SSE request: where and with which secret, and the `fetch` to use. */
1924
3185
  interface SseTarget {
@@ -2148,4 +3409,4 @@ declare class VinaverseSession {
2148
3409
  private emit;
2149
3410
  }
2150
3411
 
2151
- export { type AnswerInput as A, type WebSocketFactory as B, type ClientSecret as C, type WebSocketLike as D, cardActionSse as E, type FetchLike as F, sseFrames as G, type HeldCard as H, turnSse as I, type Message as M, type ProposalOutcome as P, type Question as Q, type Reconnect as R, type SessionInfo as S, type ToolLine as T, VinaverseClientError as V, type Welcome as W, type SessionOptions as a, CONTRACT as b, type Card as c, type CardGroup as d, type CardImage as e, type CardKind as f, type CardLink as g, type ClientErrorCode as h, type HeldQuestion as i, type Proposal as j, isKnownCard as k, type AuthMode as l, type ClientEvent as m, type Connection as n, ConversationEngine as o, type ConversationState as p, type Frame as q, type ServerEvent as r, type ServerEventOf as s, type ServerEventType as t, type SessionEvents as u, type SessionStatus as v, type SseTarget as w, type TranscriptItem as x, type TurnInput as y, VinaverseSession as z };
3412
+ export { type AnswerInput as A, type WebSocketFactory as B, type CardLink as C, type WebSocketLike as D, cardActionSse as E, type FetchLike as F, type components as G, type HeldCard as H, type operations as I, type paths as J, sseFrames as K, turnSse as L, type Message as M, type Proposal as P, type Question as Q, type Reconnect as R, type Schemas as S, type ToolLine as T, VinaverseClientError as V, type Welcome as W, type Card as a, type CardGroup as b, type CardImage as c, type CardKind as d, type ClientErrorCode as e, type HeldQuestion as f, type ProposalOutcome as g, type AuthMode as h, isKnownCard as i, type ClientEvent as j, type ClientSecret as k, type Connection as l, ConversationEngine as m, type ConversationState as n, type Frame as o, type ServerEvent as p, type ServerEventOf as q, type ServerEventType as r, type SessionEvents as s, type SessionInfo as t, type SessionOptions as u, type SessionStatus as v, type SseTarget as w, type TranscriptItem as x, type TurnInput as y, VinaverseSession as z };