@dvina/sdk 4.1.112 → 4.1.173

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 (38) hide show
  1. package/README.md +37 -134
  2. package/dist/_generated_documents-6WGCKLGZ.js +1 -0
  3. package/dist/_generated_sdk-7_X86mtI.d.ts +17341 -0
  4. package/dist/adapters/react/index.d.ts +36 -24
  5. package/dist/adapters/react/index.js +1 -1
  6. package/dist/ai/index.d.ts +570 -0
  7. package/dist/ai/index.js +3 -0
  8. package/dist/billing/index.d.ts +43 -15
  9. package/dist/billing/index.js +1 -1
  10. package/dist/chunk-32KGDH2Q.js +1 -0
  11. package/dist/chunk-37LLNIGO.js +1 -0
  12. package/dist/chunk-OCM5W3JH.js +1 -0
  13. package/dist/chunk-W764PDVJ.js +31 -0
  14. package/dist/chunk-Z2ADTQ64.js +1 -0
  15. package/dist/{sync-engine-DYHreGOv.d.ts → connection-ClMdDUce.d.ts} +223 -11
  16. package/dist/{error-CsVoUTY8.d.ts → error-Bk0Jmuzd.d.ts} +11 -3
  17. package/dist/index.d.ts +24 -3563
  18. package/dist/index.js +4 -1
  19. package/dist/package.json +8 -13
  20. package/dist/pagination/index.d.ts +18 -4
  21. package/dist/pagination/index.js +1 -1
  22. package/dist/{types-Chg8ASmf.d.ts → types-BfiQdtra.d.ts} +1 -9
  23. package/package.json +26 -21
  24. package/dist/_generated_documents-54JPKRBN.js +0 -1
  25. package/dist/adapters/angular/index.d.ts +0 -254
  26. package/dist/adapters/angular/index.js +0 -1
  27. package/dist/chunk-5E7LX4YQ.js +0 -1
  28. package/dist/chunk-G34ETQUN.js +0 -1
  29. package/dist/chunk-H3TI6B7T.js +0 -1
  30. package/dist/chunk-IFSDIGN6.js +0 -1
  31. package/dist/chunk-IIQ3WGOJ.js +0 -1
  32. package/dist/chunk-QNQ3WSMR.js +0 -5
  33. package/dist/chunk-YUQTEBYO.js +0 -31
  34. package/dist/client-Bb2gD6Iz.d.ts +0 -488
  35. package/dist/client-Bqi7gjM0.d.ts +0 -7987
  36. package/dist/index-DoGg4ya_.d.ts +0 -79
  37. package/dist/inference/index.d.ts +0 -80
  38. package/dist/inference/index.js +0 -1
@@ -1,10 +1,10 @@
1
- import { a as DvinaQueryRef } from '../../types-Chg8ASmf.js';
1
+ import { D as DvinaQueryRef } from '../../types-BfiQdtra.js';
2
2
  import 'graphql';
3
3
 
4
4
  /**
5
5
  * React adapter for @dvina/sdk.
6
6
  *
7
- * Converts DvinaQueryRef (AsyncIterable) into React state via hooks.
7
+ * Binds a DvinaQueryRef (AsyncIterable) to React through `useSyncExternalStore`.
8
8
  *
9
9
  * @example
10
10
  * ```tsx
@@ -23,33 +23,39 @@ import 'graphql';
23
23
  * @packageDocumentation
24
24
  */
25
25
 
26
+ /** The `useSyncExternalStore` contract over one query ref. */
27
+ interface LiveStore<T> {
28
+ subscribe(onChange: () => void): () => void;
29
+ getSnapshot(): T | undefined;
30
+ /** The value together with the error the query failed with, if it did; replaced on every change. */
31
+ getState(): LiveQueryState<T>;
32
+ }
33
+ /** A live query's latest value, and the error it failed with (e.g. a record that does not exist). */
34
+ type LiveQueryState<T> = {
35
+ data: T | undefined;
36
+ error: unknown;
37
+ };
26
38
  /**
27
- * React hook that subscribes to a `DvinaQueryRef` (AsyncIterable) and
28
- * returns its latest value as React state.
29
- *
30
- * Accepts a **factory function** that creates the query ref, along with a
31
- * dependency array. The factory is memoized internally — the ref is only
32
- * recreated when the dependencies change, preventing infinite
33
- * dispose-subscribe loops that would occur with inline `.watch()` calls.
39
+ * Exposes a query as an external store. Each subscriber consumes the query ref
40
+ * through its own iterator; the ref is disposed once the last subscriber has
41
+ * left and none came back within the same task. React may unsubscribe and
42
+ * subscribe again right away (Strict Mode, concurrent rendering), so disposal
43
+ * is deferred; a subscriber that returns after disposal (e.g. an `<Activity>`
44
+ * shown again) gets a fresh ref from the factory.
45
+ */
46
+ declare function createLiveStore<T>(factory: () => DvinaQueryRef<T>): LiveStore<T>;
47
+ /**
48
+ * Subscribes to a query ref and returns its latest value, or `undefined`
49
+ * until the first value arrives.
34
50
  *
35
- * The component re-renders whenever the query ref emits a new value.
36
- * Cleanup (disposal of the subscription) happens automatically when the
37
- * component unmounts or when dependencies change.
51
+ * The factory runs again only when `deps` change (same semantics as
52
+ * `useMemo`); the previous ref is disposed once React no longer uses it.
38
53
  *
39
- * @param factory - A function that returns a DvinaQueryRef (e.g. `() => sdk.reports().watch()`)
40
- * @param deps - Dependency array controlling when the ref is recreated (same semantics as `useMemo`)
41
- * @returns The latest value from the query ref, or `undefined` if not yet loaded
54
+ * @param factory - Returns the query ref, e.g. `() => sdk.reports().watch()`
55
+ * @param deps - Values the query depends on
42
56
  *
43
57
  * @example
44
58
  * ```tsx
45
- * // Static query — ref created once
46
- * function ReportsPage() {
47
- * const reports = useLiveQuery(() => sdk.reports({ first: 20 }).watch(), []);
48
- * if (!reports) return <div>Loading...</div>;
49
- * return <ul>{reports.nodes.map(r => <li key={r.id}>{r.name}</li>)}</ul>;
50
- * }
51
- *
52
- * // Reactive query — ref recreated when `id` changes
53
59
  * function ReportDetail({ id }: { id: string }) {
54
60
  * const report = useLiveQuery(() => sdk.report({ id }).watch(), [id]);
55
61
  * if (!report) return <div>Loading...</div>;
@@ -58,5 +64,11 @@ import 'graphql';
58
64
  * ```
59
65
  */
60
66
  declare function useLiveQuery<T>(factory: () => DvinaQueryRef<T>, deps: readonly unknown[]): T | undefined;
67
+ /**
68
+ * Like `useLiveQuery`, with the query's failure: `{ data, error }`. `data` is `undefined` while loading;
69
+ * `error` is set when the query failed (e.g. the record does not exist), so a panel can show "not found"
70
+ * instead of loading forever.
71
+ */
72
+ declare function useLiveQueryState<T>(factory: () => DvinaQueryRef<T>, deps: readonly unknown[]): LiveQueryState<T>;
61
73
 
62
- export { useLiveQuery };
74
+ export { type LiveQueryState, type LiveStore, createLiveStore, useLiveQuery, useLiveQueryState };
@@ -1 +1 @@
1
- import'../../chunk-EK7ODJWE.js';import {useMemo,useState,useRef,useEffect}from'react';function p(u,o){let n=useMemo(u,o),[c,t]=useState(n.current);if(process.env.NODE_ENV!=="production"){let e=useRef(0),r=useRef(Date.now()),s=Date.now();n!==void 0&&(s-r.current<1e3?e.current++:e.current=1,r.current=s,e.current>10&&(console.warn("useLiveQuery: query ref was recreated more than 10 times within 1 second. This usually means the dependency array is unstable (e.g. a new object/array created every render). Ensure deps contain only primitive values or stable references."),e.current=0));}return useEffect(()=>{let e=true;return t(n.current),(async()=>{try{for await(let r of n){if(!e)break;t(r);}}catch{}})(),()=>{e=false,n.dispose();}},[n]),c}export{p as useLiveQuery};
1
+ import'../../chunk-EK7ODJWE.js';import {useMemo,useSyncExternalStore}from'react';var S=1e3;function T(r){let t=r(),e=t.current,o={data:e,error:void 0},s=(i,n)=>{o={...o,...n},e=o.data,i();},d=0,c,f=()=>{t?.dispose(),t=void 0;};return c=setTimeout(f,S),{getSnapshot:()=>e,getState:()=>o,subscribe(i){clearTimeout(c),d++;let n=t??=r(),y=n[Symbol.asyncIterator](),u=true;return (async()=>{try{for(;u;){let a=await y.next();if(a.done||!u)break;s(i,{data:a.value,error:void 0});}}catch(a){u&&s(i,{error:a});}})(),n.current!==void 0&&n.current!==e&&s(i,{data:n.current}),()=>{u=false,y.return?.(),d--,d===0&&(c=setTimeout(f,0));}}}}function b(r,t){let e=useMemo(()=>T(r),t);return useSyncExternalStore(e.subscribe,e.getSnapshot,e.getSnapshot)}function Q(r,t){let e=useMemo(()=>T(r),t);return useSyncExternalStore(e.subscribe,e.getState,e.getState)}export{T as createLiveStore,b as useLiveQuery,Q as useLiveQueryState};
@@ -0,0 +1,570 @@
1
+ import { UIMessage, DefaultChatTransport } from 'ai';
2
+ import { D as DvinaSdk, C as ChatMessage, a as ChatMessageConnection } from '../_generated_sdk-7_X86mtI.js';
3
+ import '../types-BfiQdtra.js';
4
+ import 'graphql';
5
+ import '../connection-ClMdDUce.js';
6
+ import 'dexie';
7
+ import '../error-Bk0Jmuzd.js';
8
+ import '../billing/index.js';
9
+
10
+ /** How a turn ended: `waiting` for the user's approval or answer, `incomplete` when it ended before finishing. */
11
+ type DvinaTurnOutcome = 'done' | 'waiting' | 'incomplete' | 'failed' | 'stopped';
12
+ /** Where the supervisor sent a user message: answered itself, relayed it to a task, or started a new task. */
13
+ type DvinaMessageRoute = {
14
+ to: 'supervisor' | 'task' | 'new-task';
15
+ /** The task chat, for `task` and `new-task`. */
16
+ chatId?: string;
17
+ /** The supervisor's one-line reason for a relay or a new task. */
18
+ reason?: string;
19
+ };
20
+ /** A task's state as a badge shows it: running (also while queued or resuming), or how its latest turn ended. */
21
+ type DvinaTaskStatus = 'running' | DvinaTurnOutcome;
22
+ /** Metadata attached to every Dvina chat message. */
23
+ type DvinaMessageMetadata = {
24
+ createdAt?: string;
25
+ /** When an assistant message finished streaming. */
26
+ finishedAt?: string;
27
+ /** The reply was stopped by the user before it finished. */
28
+ stopped?: boolean;
29
+ /** Why the model ended the reply's last step, as the AI SDK reports it (`stop`, `length`, `tool-calls`, …). */
30
+ finishReason?: string;
31
+ /**
32
+ * How the turn that wrote this reply ended, decided by the server. `done` only when the model ended on
33
+ * its own; absent on replies saved before outcomes were recorded.
34
+ */
35
+ outcome?: DvinaTurnOutcome;
36
+ /** Why an `incomplete` or `failed` turn ended: `budget` (step or token limit), `error`, or a finish reason. */
37
+ outcomeReason?: string;
38
+ /** Model that produced an assistant message. */
39
+ model?: string;
40
+ usage?: {
41
+ inputTokens: number;
42
+ cachedInputTokens: number;
43
+ outputTokens: number;
44
+ reasoningTokens: number;
45
+ };
46
+ threadId?: string | null;
47
+ inResponseToId?: string | null;
48
+ /** The user inputs this reply consumes together; durable wake-ups use this to avoid answering a batch twice. */
49
+ answeredUserMessageIds?: string[];
50
+ /** The part of the replied-to message the user answered, as the reply's quote shows it. */
51
+ inResponseToExcerpt?: string;
52
+ /** Task chat a supervisor message refers to. */
53
+ referencedChatId?: string | null;
54
+ /**
55
+ * The reply thread the message is in, from the whole chat (not what is loaded): its first message (`rootId`, the
56
+ * message's own id on a root) and how many replies it holds, as the app counts them (a reply of the reader's, and
57
+ * whatever answers a reply, at any depth). Absent when the message is in no thread.
58
+ */
59
+ replyThread?: {
60
+ rootId: string;
61
+ replyCount: number;
62
+ };
63
+ /**
64
+ * This message owns its task's live code card: the first of Dvina's shown replies to a hidden prompt that refers to
65
+ * the task chat (`referencedChatId`), in the whole chat's order.
66
+ */
67
+ ownsTaskCode?: true;
68
+ /** A single task's report: the message that handed exactly this one task to the task chat it reports on. */
69
+ handOffId?: string;
70
+ /**
71
+ * A single task's report drawn in its hand-off's thread: false when only plain replies stand between the hand-off and
72
+ * the report (the hand-off's own line says how the task ended), true otherwise. Decided when the report is written.
73
+ */
74
+ threadedUnderHandOff?: boolean;
75
+ /** An internal message (a task's result, an agent's note): the user's role, never shown as theirs. */
76
+ hidden?: boolean;
77
+ /** A message of a legacy chat moved into this one: it is read in its thread, as text. */
78
+ legacyChatId?: string | null;
79
+ /**
80
+ * Said in a voice call and answered by the voice itself (its user line and its answer), kept in the call's thread
81
+ * outside any turn: a turn's continuation or recovery looks past it.
82
+ */
83
+ spoken?: boolean;
84
+ /** A voice message from an older app; its text is the server's transcript. The reply is text. */
85
+ voiceInput?: boolean;
86
+ /** On a user message: sent from Dvina's bar (desktop), over whatever app the user was working in. */
87
+ surface?: 'bar';
88
+ /** On a message sent from the bar: the user let Dvina look at their screen (the bar's screen context, off by default). */
89
+ screenContext?: boolean;
90
+ /**
91
+ * On a user message sent while a reply was showing: how much of that reply was on screen then, so the message reads
92
+ * after it and the rest of the reply after the message, as written. `parts` whole parts, then `text` characters of
93
+ * the text part being written; without `id` the reply showed nothing yet and the message reads before it.
94
+ */
95
+ afterReply?: {
96
+ id?: string;
97
+ parts: number;
98
+ text?: number;
99
+ };
100
+ /** The scheduled message that sent this user message when it was due. */
101
+ scheduledMessageId?: string;
102
+ /** On a main chat user message: where the supervisor routed it (stored when its turn ends). */
103
+ route?: DvinaMessageRoute;
104
+ /**
105
+ * On a reply to a section of a report: the task that section is about (its badge's `chatId`). The supervisor
106
+ * reads it as the task the reply is for.
107
+ */
108
+ inResponseToTaskChatId?: string;
109
+ /**
110
+ * On a message a task chat received from the supervisor: the main chat user message that led to it. The task
111
+ * panel shows that message's own words; a message the supervisor added on its own has none.
112
+ */
113
+ triggeredBy?: string;
114
+ /**
115
+ * On an assistant reply: the user's predicted next message, shown in an empty composer (ghost text), and when
116
+ * it was predicted; `null` when none fits. Absent until the client asks for it.
117
+ */
118
+ nextPrompt?: {
119
+ text: string;
120
+ at: string;
121
+ } | null;
122
+ /** On a user message: it began as the predicted next message (accepted with Tab or a tap). */
123
+ nextPromptUsed?: boolean;
124
+ };
125
+ /** Custom data parts streamed alongside text and tool parts. */
126
+ type DvinaDataParts = {
127
+ /** Files presented to the user; persisted with the message. */
128
+ artifact: {
129
+ id: string;
130
+ name: string;
131
+ size: number;
132
+ path?: string;
133
+ toolCallId?: string;
134
+ /** The artifact's file at this presentation; absent on parts saved before versioning. */
135
+ fileId?: string;
136
+ /** Version this presentation saved; presenting the same path again in a chat adds one. */
137
+ version?: number;
138
+ versionCount?: number;
139
+ /** `draft` while the agent is still changing the file. */
140
+ status?: 'ready' | 'draft';
141
+ /** File extension, lower case. */
142
+ format?: string;
143
+ };
144
+ /** An office file a script is building before it is presented; streamed only (transient), never saved. */
145
+ 'file-draft': {
146
+ path: string;
147
+ name: string;
148
+ fileId: string;
149
+ size: number;
150
+ };
151
+ /** PII protection applied to the latest turn. */
152
+ privacy: {
153
+ maskedValueCount: number;
154
+ matchedTypes: string[];
155
+ };
156
+ /** Context the model reads with the user's message but the UI does not show; persisted with the message. */
157
+ context: {
158
+ text: string;
159
+ };
160
+ /** Conversations imported from another assistant into the library; written to the main chat by the server. */
161
+ 'chat-import': {
162
+ /** The export's archive hash. */
163
+ id: string;
164
+ provider: 'ChatGpt' | 'Claude' | 'Grok';
165
+ importedCount: number;
166
+ skippedCount: number;
167
+ messageCount: number;
168
+ /** Library folder holding the imported documents; their `isReady` tells the indexing progress. */
169
+ folderPath: string;
170
+ firstConversationAt?: string;
171
+ lastConversationAt?: string;
172
+ /** Titles of the newest imported conversations, newest first. */
173
+ sampleTitles: string[];
174
+ importedAt: string;
175
+ };
176
+ /** One task chat messaged another; shown in the supervisor chat so the user can follow the team. */
177
+ 'agent-message': {
178
+ fromChatId: string;
179
+ fromTitle: string;
180
+ toChatId: string;
181
+ toTitle: string;
182
+ /** The start of the message. */
183
+ gist: string;
184
+ };
185
+ /** A legacy generative UI block (StreamableUi), kept as stored: `content` is its original payload. */
186
+ 'legacy-streamable-ui': {
187
+ content: string;
188
+ agentId?: string;
189
+ agentName?: string;
190
+ };
191
+ /** A legacy chat moved into the main chat: its card on the timeline, opening its thread (the message's `threadId`). */
192
+ 'legacy-chat': {
193
+ chatId: string;
194
+ name: string;
195
+ messageCount: number;
196
+ };
197
+ /**
198
+ * A voice call (conversation mode): its card on the main chat's timeline, opening its thread (the message's
199
+ * `threadId`), which holds what was said in the call. Written when the call opens; the end and the counts are
200
+ * added when it ends. A call whose end never arrived reads as ended once it is older than the longest call.
201
+ */
202
+ 'voice-call': {
203
+ /** When the call opened (ISO). */
204
+ startedAt: string;
205
+ /** When it ended (ISO); absent while it goes on. */
206
+ endedAt?: string;
207
+ /** Why it ended, as the server's session says (`ended`, `idle`, `expired`, `limit`…). */
208
+ endReason?: string;
209
+ durationMs?: number;
210
+ /** The user's and Dvina's messages in the call's thread. */
211
+ messageCount?: number;
212
+ /** Files presented in the call's thread. */
213
+ artifactCount?: number;
214
+ /** Tasks Dvina started in the call. */
215
+ taskCount?: number;
216
+ };
217
+ /**
218
+ * A chat, task or thread someone shared with the reader: its card in their main chat, at the moment it was
219
+ * shared, opening it read-only or as the reader's role allows. `title` and the sharer are as they were when the
220
+ * card was written; the item opens under its current title. `revokedAt` once the share was taken away.
221
+ */
222
+ 'shared-chat': {
223
+ kind: 'chat' | 'task' | 'thread';
224
+ id: string;
225
+ /** The owner's chat it is read from (a thread's is the chat it is in). */
226
+ chatId: string;
227
+ title: string;
228
+ sharedById: string;
229
+ sharedByName: string;
230
+ revokedAt?: string | null;
231
+ };
232
+ /** A legacy content block with no other form (e.g. a tool call whose record is unreadable), kept as stored. */
233
+ 'legacy-block': {
234
+ blockType: string;
235
+ content: string;
236
+ agentId?: string;
237
+ agentName?: string;
238
+ };
239
+ /**
240
+ * A task's one-line badge on a supervisor message: the message that started it (`delegate`), relayed a user
241
+ * message to it (`relay`), presents its result (`result`), or offers it as an answer to "which one?"
242
+ * (`candidate`). In a chat, a task's latest delegate/relay badge is live and follows the task. An earlier one
243
+ * is frozen: it shows the `previous` state of the task's next badge, or its own `state` at `at`.
244
+ */
245
+ /**
246
+ * "While you were away": the tasks that finished while the user was away, one row each (failures too),
247
+ * written when they come back. A row opens that task's result (`messageId`, in the task chat).
248
+ */
249
+ 'away-summary': {
250
+ /** When the first of them finished (ISO). */
251
+ since: string;
252
+ items: {
253
+ chatId: string;
254
+ title: string;
255
+ state: DvinaTaskStatus;
256
+ /** One line of its result, or of what stopped it. */
257
+ gist: string;
258
+ /** When it finished (ISO). */
259
+ at: string;
260
+ messageId?: string;
261
+ }[];
262
+ };
263
+ 'task-badge': {
264
+ chatId: string;
265
+ /** The task's name when the badge was written. */
266
+ title: string;
267
+ via: 'delegate' | 'relay' | 'result' | 'candidate';
268
+ /** The task's state when the badge was written. */
269
+ state: DvinaTaskStatus;
270
+ /** When the badge was written (ISO). */
271
+ at: string;
272
+ /** The task input message for this run. Shared by delegate/relay and result badges; not the reply's ID. */
273
+ messageId?: string;
274
+ /**
275
+ * On a relay: the task's state just before it, which the previous badge of the task shows once this one is
276
+ * live. A badge with no later badge for its task shows its own `state`.
277
+ */
278
+ previous?: {
279
+ state: DvinaTaskStatus;
280
+ at: string;
281
+ };
282
+ /** The task's current step, when known. */
283
+ step?: string;
284
+ progress?: {
285
+ done: number;
286
+ total: number;
287
+ };
288
+ };
289
+ /** Older replies: a user reply the supervisor passed to a task chat (now `task-badge`). */
290
+ 'task-follow-up': {
291
+ chatId: string;
292
+ /** The task chat message the reply was passed as; the task's reply answers it (`metadata.inResponseToId`). */
293
+ messageId?: string;
294
+ };
295
+ /** A task chat's live progress line in the user's language, updated in place after each step. */
296
+ narration: {
297
+ text: string;
298
+ };
299
+ /**
300
+ * Something Dvina noticed on its own (proactive), in its own message, never inside a reply. The card reads the
301
+ * finding's live state (body, sources, status) by `itemId`; a `superseded` one folds to a line.
302
+ */
303
+ 'proactive-item': {
304
+ itemId: string;
305
+ /** `meeting-prep`, `deadline`, ... */
306
+ detector: string;
307
+ title: string;
308
+ /** The time phrase in the user's language, e.g. "before your 2 PM". */
309
+ whenLabel?: string;
310
+ /** When it was written (ISO). */
311
+ at: string;
312
+ /** The finding this one replaces (the meeting moved). */
313
+ previousItemId?: string;
314
+ };
315
+ /**
316
+ * A weekly or monthly report that became ready, in its own message in the main chat: the card shows this snapshot
317
+ * and opens the report (`?aside=digest:<period>:<key>`). Everything past the digest's identity is optional, so a
318
+ * card written before a field existed still draws.
319
+ */
320
+ 'digest-report': {
321
+ digestId: string;
322
+ period: 'week' | 'month';
323
+ /** The digest's period key, `2026-W41` or `2026-10`. */
324
+ key: string;
325
+ /** What mattered most, in the user's language. */
326
+ headline?: string;
327
+ /** Up to three of the report's top points. */
328
+ points?: string[];
329
+ /** How many of each the report holds, counted from its content. */
330
+ counts?: {
331
+ tasks?: number;
332
+ decisions?: number;
333
+ openEnds?: number;
334
+ risks?: number;
335
+ };
336
+ /** When it was written (ISO). */
337
+ at?: string;
338
+ };
339
+ /** A message the user scheduled; the card reads the schedule's live state by `id`. */
340
+ 'scheduled-message': {
341
+ id: string;
342
+ title: string;
343
+ };
344
+ /** New chat title; transient. */
345
+ 'chat-title': {
346
+ title: string;
347
+ };
348
+ /**
349
+ * A goal Dvina proposes for a task, on the task's waiting reply next to the `question` that asks to start it
350
+ * (`toolCallId`): an app that knows goals draws the proposal card, an older one the plain question.
351
+ */
352
+ 'goal-proposal': DvinaGoal & {
353
+ /** The `question` call this proposal is answered through. */
354
+ toolCallId: string;
355
+ };
356
+ /**
357
+ * A round of a goal, graded: on the round's reply in the task chat. The last one says where the goal stands.
358
+ * Unknown to older apps, which show the task as before.
359
+ */
360
+ 'goal-evaluation': DvinaGoalEvaluation;
361
+ };
362
+ /** What a goal's run is doing. */
363
+ type DvinaGoalStatus = 'proposed' | 'pursuing'
364
+ /** Waiting on the user's decision: accept the best version, adjust, one more round or stop. */
365
+ | 'checkpoint' | 'achieved'
366
+ /** A limit (rounds, time, usage) ended it; the best round is the result. */
367
+ | 'limit'
368
+ /** The user accepted a version that did not meet it. */
369
+ | 'accepted' | 'stopped'
370
+ /** The user chose to do the work once, without the goal. */
371
+ | 'declined';
372
+ type DvinaGoalCriterion = {
373
+ id: string;
374
+ title: string;
375
+ description?: string;
376
+ weight: number;
377
+ mustPass: boolean;
378
+ /** judge: a reviewer reads the result; check: a deterministic check over files and tool results; human: the user confirms. */
379
+ kind: 'judge' | 'check' | 'human';
380
+ /** A `check` criterion's deterministic check over the round's files, tool results and answer. */
381
+ check?: {
382
+ type: 'artifact' | 'tool-succeeded' | 'no-tool-errors' | 'answer-includes';
383
+ value?: string;
384
+ min?: number;
385
+ };
386
+ };
387
+ /** A task's goal: what to achieve, when it is done, how that is judged (its rubric) and the run's limits. */
388
+ type DvinaGoal = {
389
+ objective: string;
390
+ doneWhen: string;
391
+ criteria: DvinaGoalCriterion[];
392
+ /** Weighted score needed, 0 to 1. */
393
+ threshold: number;
394
+ limits: {
395
+ maxRounds: number;
396
+ maxMinutes: number;
397
+ maxUsagePercent: number;
398
+ };
399
+ /** The rubric template (a skill) it follows. */
400
+ template?: {
401
+ id: string;
402
+ name: string;
403
+ } | null;
404
+ };
405
+ type DvinaGoalEvaluation = {
406
+ round: number;
407
+ maxRounds: number;
408
+ /** Weighted score, 0 to 1. */
409
+ score: number;
410
+ threshold: number;
411
+ verdict: 'pass' | 'revise' | 'stuck' | 'needs_human';
412
+ /** Where the goal stands after this round. */
413
+ status: DvinaGoalStatus;
414
+ criteria: {
415
+ id: string;
416
+ title: string;
417
+ /** null: waiting for the user. */
418
+ passed: boolean | null;
419
+ score: number;
420
+ /** One line: what in the result shows it. */
421
+ evidence: string;
422
+ fix?: string;
423
+ }[];
424
+ /** One or two sentences from the reviewer. */
425
+ summary: string;
426
+ /** The best round so far and the reply that holds it. */
427
+ best: {
428
+ round: number;
429
+ score: number;
430
+ messageId: string;
431
+ };
432
+ /** Every round's score so far, this one last. */
433
+ scores: number[];
434
+ /** When it was graded (ISO). */
435
+ at: string;
436
+ };
437
+ type DvinaUIMessage = UIMessage<DvinaMessageMetadata, DvinaDataParts>;
438
+ /** Tool metadata carried on tool parts; set by the server for every tool. */
439
+ type DvinaToolMetadata = {
440
+ toolKit?: string;
441
+ };
442
+
443
+ type DvinaChatTransportOptions = {
444
+ /** API origin including protocol, e.g. `https://api.dvina.ai`. */
445
+ apiUrl: string;
446
+ getToken: (options?: {
447
+ forceRefresh?: boolean;
448
+ }) => Promise<string>;
449
+ /** Custom fetch, e.g. the Tauri HTTP plugin. */
450
+ fetch?: typeof fetch;
451
+ /** The app's language (BCP 47, e.g. `tr`, `pt-BR`), sent as `x-preferred-language` like the GraphQL client's. */
452
+ getLanguage?: () => string | undefined;
453
+ };
454
+ /**
455
+ * Chat transport for `useChat` / `Chat`.
456
+ *
457
+ * - Sends only the newest message; the server owns the history.
458
+ * - Resumes an active stream with `GET /api/chat/:id/stream`.
459
+ * - Retries once with a refreshed token when the API answers 401.
460
+ * - Retries with backoff while the API answers 503 during a restart.
461
+ *
462
+ * A resumed stream of a continued reply starts by replaying the reply as stored. `keepsReply` says the chat already
463
+ * holds that reply and continues it in place (AI SDK keeps a reply whose tool waits on an approval answer or on its
464
+ * input); its replay is then skipped, as the legacy stream skips it, or the reply's parts would be added twice.
465
+ */
466
+ declare function createDvinaChatTransport(options: DvinaChatTransportOptions, { keepsReply }?: {
467
+ keepsReply?: () => boolean;
468
+ }): DefaultChatTransport<DvinaUIMessage>;
469
+ /**
470
+ * Chat transport for a temporary chat (`POST /api/temporary-chat`): AI SDK's default, without persistence. The
471
+ * client holds the conversation and sends all of it with each turn; the server answers and stores nothing, so there
472
+ * is no stream to resume and stopping aborts the request.
473
+ */
474
+ declare function createDvinaTemporaryChatTransport(options: DvinaChatTransportOptions): DefaultChatTransport<DvinaUIMessage>;
475
+
476
+ /** The chat actions of the SDK, as the functions below call them. */
477
+ type DvinaChatActionsSdk = Pick<DvinaSdk, 'sendChatMessageWhileRunning' | 'chatNextPrompt' | 'stopChat' | 'grantChatApproval' | 'respondChatApproval' | 'answerChatQuestion' | 'returnToMainChat' | 'startChatDay'>;
478
+ /**
479
+ * Sends a user message while the chat's turn runs: the server stores it at once (every device shows it) and answers it
480
+ * with the chat's next turn, without cutting the running reply off. Sending it again under the same id changes nothing,
481
+ * so it is sent again while the API restarts. Aborting stops the waiting; a request already sent may still land.
482
+ */
483
+ declare function postDvinaChatMessage(sdk: DvinaChatActionsSdk, chatId: string, message: DvinaUIMessage, signal?: AbortSignal): Promise<void>;
484
+ /**
485
+ * The user's predicted next message after the chat's latest reply, for an empty composer; `null` when none fits.
486
+ * Ask only when it can be shown (the reply finished, the composer is empty and on screen): the server predicts it
487
+ * once per reply and keeps it as the reply's `metadata.nextPrompt`.
488
+ */
489
+ declare function fetchDvinaNextPrompt(sdk: DvinaChatActionsSdk, chatId: string): Promise<string | null>;
490
+ /** Stops the chat's running turn on the server; streaming clients then finish normally. */
491
+ declare function stopDvinaChat(sdk: DvinaChatActionsSdk, chatId: string): Promise<void>;
492
+ /**
493
+ * Lets a task do this tool from now on without asking (its later approvals for the tool pass on the server); the
494
+ * approval waiting now is still answered as usual. Only the caller's own task chats, only tools that ask.
495
+ */
496
+ declare function grantDvinaTaskApproval(sdk: DvinaChatActionsSdk, taskChatId: string, toolName: string): Promise<void>;
497
+ /** What became of an answer given outside the chat: sent, or the chat no longer waited for it (answered elsewhere). */
498
+ type DvinaAnswerOutcome = 'sent' | 'answered-elsewhere';
499
+ /**
500
+ * Answers a chat's waiting approval from outside the chat (a notification), as the chat's own card does; `always`
501
+ * also allows the tool for the chat from now on. The turn continues on the server.
502
+ */
503
+ declare function respondDvinaApproval(sdk: DvinaChatActionsSdk, chatId: string, toolCallId: string, answer: {
504
+ approved: boolean;
505
+ always?: boolean;
506
+ }): Promise<DvinaAnswerOutcome>;
507
+ /** Answers a chat's waiting question from outside the chat (a notification's reply): one answer list per question. */
508
+ declare function answerDvinaQuestion(sdk: DvinaChatActionsSdk, chatId: string, toolCallId: string, answers: string[][]): Promise<DvinaAnswerOutcome>;
509
+ /**
510
+ * Tells the server the user is back (the app opened or came to the foreground): the results that finished while
511
+ * they were away arrive as one summary in the main chat. Idempotent within one absence.
512
+ */
513
+ declare function returnToDvinaMainChat(sdk: DvinaChatActionsSdk): Promise<void>;
514
+ /**
515
+ * Starts the reader's day (their local day, from `x-user-timezone`) as the app opens or comes to the foreground: the
516
+ * day's first call queues its work (pending day digests, the cards kept for the morning, the night's ideas); later
517
+ * calls are cheap. `started` is whether this call queued it.
518
+ */
519
+ declare function startDvinaDay(sdk: DvinaChatActionsSdk): Promise<{
520
+ started: boolean;
521
+ }>;
522
+
523
+ /** What a ChatMessage node needs to be read as an AI SDK message. */
524
+ type DvinaChatMessageNode = Pick<ChatMessage, 'id' | 'role' | 'parts' | 'metadata'>;
525
+ /**
526
+ * A ChatMessage node as the AI SDK's message: a plain object of its id, role, parts and metadata, which the API
527
+ * already gives in the AI SDK's shape (`metadata.hidden` on an internal message).
528
+ */
529
+ declare function dvinaUIMessageOf(node: DvinaChatMessageNode): DvinaUIMessage;
530
+ /**
531
+ * A page of a chat, oldest to newest: its messages, whether the chat goes on before and after it, and the ids that
532
+ * page on (`before: startCursor` for the page before, `after: endCursor` for the one after). Pages hold whole turns,
533
+ * so a page may hold a few more messages than asked for.
534
+ */
535
+ type DvinaMessagePage = {
536
+ messages: DvinaUIMessage[];
537
+ hasOlder: boolean;
538
+ hasNewer: boolean;
539
+ startCursor?: string;
540
+ endCursor?: string;
541
+ };
542
+ /** A `chatMessages` or `chatMessagesAround` connection, oldest first, as a page of AI SDK messages. */
543
+ declare function dvinaMessagePageOf(connection: Pick<ChatMessageConnection, 'nodes' | 'pageInfo'>): DvinaMessagePage;
544
+ /** The most the API gives in one page (`first` and `last` are capped there). */
545
+ declare const MAX_MESSAGE_PAGE = 200;
546
+ /**
547
+ * A whole chat, or one thread of it with the message it started from, oldest first: `chatMessages` read forward
548
+ * (`first` + `after`) page by page to the end. For short reads such as a thread or a task chat; long chats load by
549
+ * page. Each page is a one-off fetch, never a watch. A chat the caller may not read, or one not created yet, has none.
550
+ */
551
+ declare function fetchAllDvinaChatMessages(sdk: Pick<DvinaSdk, 'chatMessages'>, scope: {
552
+ chatId: string;
553
+ threadId?: string;
554
+ }, { pageSize }?: {
555
+ pageSize?: number;
556
+ }): Promise<DvinaUIMessage[]>;
557
+
558
+ /**
559
+ * A tool's output the server held back from a chat message: its size, its first 500 characters and the links in it.
560
+ * The whole output loads with the SDK's `chatMessageToolOutput` query when the reader opens the call.
561
+ */
562
+ type DvinaLazyToolOutput = {
563
+ bytes: number;
564
+ preview: string;
565
+ urls: string[];
566
+ };
567
+ /** The held-back output a tool part carries instead of its output, or `null` for a whole output. */
568
+ declare function lazyToolOutputOf(output: unknown): DvinaLazyToolOutput | null;
569
+
570
+ export { type DvinaAnswerOutcome, type DvinaChatActionsSdk, type DvinaChatMessageNode, type DvinaChatTransportOptions, type DvinaDataParts, type DvinaGoal, type DvinaGoalCriterion, type DvinaGoalEvaluation, type DvinaGoalStatus, type DvinaLazyToolOutput, type DvinaMessageMetadata, type DvinaMessagePage, type DvinaMessageRoute, type DvinaTaskStatus, type DvinaToolMetadata, type DvinaTurnOutcome, type DvinaUIMessage, MAX_MESSAGE_PAGE, answerDvinaQuestion, createDvinaChatTransport, createDvinaTemporaryChatTransport, dvinaMessagePageOf, dvinaUIMessageOf, fetchAllDvinaChatMessages, fetchDvinaNextPrompt, grantDvinaTaskApproval, lazyToolOutputOf, postDvinaChatMessage, respondDvinaApproval, returnToDvinaMainChat, startDvinaDay, stopDvinaChat };