@alia.onl/sdk 15.8.0 → 19.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/CHANGELOG.md +242 -13
  2. package/README.md +223 -151
  3. package/package.json +15 -5
  4. package/src/animations.ts +0 -1
  5. package/src/components/AliaAskProvider.tsx +127 -0
  6. package/src/components/AliaChatContent.tsx +604 -392
  7. package/src/components/AliaChatHeader.tsx +14 -38
  8. package/src/components/AliaChatScreen.tsx +56 -31
  9. package/src/components/AliaChatSheet.tsx +110 -36
  10. package/src/components/AliaComposer.tsx +1 -1
  11. package/src/components/AliaParticipants.tsx +202 -0
  12. package/src/components/AliaParticipantsHeader.tsx +60 -0
  13. package/src/components/AliaSharedConversation.tsx +86 -0
  14. package/src/components/AliaWelcomeMessage.tsx +18 -5
  15. package/src/components/Image.tsx +12 -0
  16. package/src/components/Markdown.tsx +498 -14
  17. package/src/components/PlanPreviewCard.tsx +7 -49
  18. package/src/components/ReplyMarkdown.tsx +359 -0
  19. package/src/components/RichBlocks.tsx +195 -0
  20. package/src/components/canvas/CanvasComponent.tsx +59 -0
  21. package/src/components/canvas/ChartRenderer.tsx +73 -0
  22. package/src/components/canvas/CodeRenderer.tsx +24 -0
  23. package/src/components/canvas/FormRenderer.tsx +101 -0
  24. package/src/components/canvas/MarkdownRenderer.tsx +14 -0
  25. package/src/components/canvas/TableRenderer.tsx +47 -0
  26. package/src/components/thought/FilesAndSources.tsx +120 -0
  27. package/src/components/thought/ThoughtPanel.tsx +417 -0
  28. package/src/components/thought/ToolStep.tsx +141 -0
  29. package/src/components/thread/AgentResultCard.tsx +125 -0
  30. package/src/components/thread/AgentTaskCard.tsx +127 -0
  31. package/src/components/thread/AliaThread.tsx +401 -0
  32. package/src/components/thread/MessageBlockBoundary.tsx +78 -0
  33. package/src/components/thread/NewConversationOffer.tsx +54 -0
  34. package/src/components/thread/ThreadRow.tsx +458 -0
  35. package/src/components/thread/ThreadSearch.tsx +129 -0
  36. package/src/components/thread/ToolResultCard.tsx +254 -0
  37. package/src/components/thread/TurnMenu.tsx +54 -0
  38. package/src/components/thread/TurnStatusLine.tsx +34 -0
  39. package/src/components/voice/AliaVoiceCall.tsx +21 -0
  40. package/src/components/voice/VoiceControls.tsx +2 -28
  41. package/src/components/voice/VoiceSession.tsx +39 -11
  42. package/src/hooks/useAliaActivity.ts +2 -2
  43. package/src/hooks/useAtBottom.ts +51 -0
  44. package/src/hooks/useAttachMenu.ts +94 -0
  45. package/src/hooks/useChatComposer.ts +299 -0
  46. package/src/hooks/useChatVoice.ts +129 -0
  47. package/src/hooks/useDocumentPicker.ts +3 -29
  48. package/src/hooks/useFailedTurnToast.ts +43 -0
  49. package/src/hooks/useMessageVote.ts +50 -0
  50. package/src/hooks/useOpenThought.ts +79 -0
  51. package/src/hooks/usePendingQuestions.ts +2 -2
  52. package/src/hooks/useReadAloud.ts +92 -0
  53. package/src/hooks/useShareHandler.ts +24 -0
  54. package/src/hooks/useSoundEffects.ts +1 -1
  55. package/src/hooks/useThoughtScope.ts +59 -0
  56. package/src/hooks/useThreadRows.ts +145 -0
  57. package/src/hooks/useThreadView.ts +68 -0
  58. package/src/hooks/useTimelineWindow.ts +256 -0
  59. package/src/hooks/useVoiceLauncher.ts +180 -0
  60. package/src/hooks/useVoiceRoom.ts +0 -3
  61. package/src/index.ts +43 -29
  62. package/src/lib/activity-store.ts +1 -1
  63. package/src/lib/add-menu.ts +7 -0
  64. package/src/lib/call-thread.ts +33 -0
  65. package/src/lib/citations.ts +79 -2
  66. package/src/lib/clipboard.ts +23 -0
  67. package/src/lib/content-utils.ts +10 -0
  68. package/src/lib/copy-en.ts +284 -0
  69. package/src/lib/copy.ts +32 -0
  70. package/src/lib/document-picker.ts +31 -0
  71. package/src/lib/flights.ts +22 -13
  72. package/src/lib/focus-return.ts +66 -0
  73. package/src/lib/keyboard.native.tsx +19 -0
  74. package/src/lib/keyboard.tsx +9 -0
  75. package/src/lib/labels.tsx +69 -17
  76. package/src/lib/participants.ts +86 -0
  77. package/src/lib/power-level-options.ts +66 -0
  78. package/src/lib/questions.ts +2 -2
  79. package/src/lib/task-labels.ts +4 -4
  80. package/src/lib/tool-call-status.ts +1 -1
  81. package/src/lib/tool-icons.ts +36 -0
  82. package/src/lib/tool-renderers.tsx +48 -0
  83. package/src/lib/turn-state.ts +2 -2
  84. package/src/lib/voice-call-request.ts +49 -0
  85. package/src/lib/voice-call.ts +76 -34
  86. package/src/lib/voice-controls-labels.ts +31 -0
  87. package/src/lib/voice-protocol.ts +32 -14
  88. package/src/lib/work-log.ts +6 -6
  89. package/src/runtime/agents.ts +151 -0
  90. package/src/runtime/api.ts +123 -0
  91. package/src/runtime/attachment-utils.ts +96 -0
  92. package/src/runtime/composer-draft-store.ts +270 -0
  93. package/src/runtime/config.tsx +186 -0
  94. package/src/runtime/conversation-store.ts +49 -0
  95. package/src/runtime/conversations.ts +557 -0
  96. package/src/runtime/error-utils.ts +104 -0
  97. package/src/runtime/host-tools.ts +140 -0
  98. package/src/runtime/index.ts +113 -0
  99. package/src/runtime/message-history.ts +124 -0
  100. package/src/runtime/model.ts +39 -0
  101. package/src/runtime/oxy-files.ts +37 -0
  102. package/src/runtime/power-levels.ts +66 -0
  103. package/src/runtime/query-keys.ts +34 -0
  104. package/src/runtime/random-uuid.ts +25 -0
  105. package/src/runtime/routes.ts +51 -0
  106. package/src/runtime/sharing.ts +165 -0
  107. package/src/runtime/sse-frame-reader.ts +88 -0
  108. package/src/runtime/stream-events.ts +146 -0
  109. package/src/runtime/stream-outcome.ts +21 -0
  110. package/src/runtime/thought-store.ts +103 -0
  111. package/src/runtime/thread/agent-activity.ts +261 -0
  112. package/src/runtime/thread/automation-labels.ts +79 -0
  113. package/src/runtime/thread/conversation-export.ts +135 -0
  114. package/src/runtime/thread/message-days.ts +120 -0
  115. package/src/runtime/thread/message-processor.ts +93 -0
  116. package/src/runtime/thread/task-utils.ts +11 -0
  117. package/src/runtime/thread/thought-utils.ts +752 -0
  118. package/src/runtime/thread/thread-history.ts +139 -0
  119. package/src/runtime/thread/timeline.ts +202 -0
  120. package/src/runtime/thread/title-tags.ts +8 -0
  121. package/src/runtime/thread/tool-cards.ts +383 -0
  122. package/src/runtime/turn-failure.ts +108 -0
  123. package/src/runtime/types.ts +148 -0
  124. package/src/runtime/usage-limit-error.ts +44 -0
  125. package/src/runtime/use-agent-activity.ts +80 -0
  126. package/src/runtime/use-conversation-stream.ts +1427 -0
  127. package/src/runtime/use-conversation-thread.ts +556 -0
  128. package/src/runtime/use-start-conversation.ts +107 -0
  129. package/src/runtime/use-thread-history.ts +64 -0
  130. package/src/runtime/use-thread-search.ts +95 -0
  131. package/src/runtime/use-turn-edit.ts +99 -0
  132. package/src/tools.ts +2 -2
  133. package/src/types.ts +18 -47
  134. package/src/components/AliaChatMessageList.tsx +0 -532
  135. package/src/components/ThinkingBlock.tsx +0 -43
  136. package/src/hooks/useAliaChat.ts +0 -573
  137. package/src/lib/catalogue.ts +0 -236
  138. package/src/lib/chat-stream.ts +0 -655
  139. package/src/lib/chat-transport.ts +0 -98
  140. package/src/lib/delegation.ts +0 -34
  141. package/src/lib/work-log-copy.ts +0 -61
package/CHANGELOG.md CHANGED
@@ -1,6 +1,90 @@
1
1
  # @alia.onl/sdk
2
2
 
3
- ## 15.8.0
3
+ ## 19.0.0
4
+
5
+ Every agent is the same agent, and any app embeds any of them (ADR 0020; the wire contract is
6
+ [`docs/agent-embedding.md`](../../docs/agent-embedding.md), kept with the API). A clean cut: the retired frames and props are deleted, not deprecated,
7
+ and there is no compatibility path — a build on an older SDK cannot read the new stream.
8
+
9
+ ### Added
10
+
11
+ - **Any agent as lead.** `agent?: { id }` on `AliaChatSheet`, `AliaChatScreen` and
12
+ `AliaChatContent`. The chat reads `GET /v1/agents/:id/profile`, and that agent's greeting, name,
13
+ character and starters lead the conversation (`lib/participants.ts`: `lead = profile ?? ALIA_LEAD`);
14
+ the welcome waits for the profile rather than greeting as Alia. The composer's placeholder and
15
+ the welcome→header flight (`leadToProfile(lead)`) name the lead.
16
+ - **One participants header, with Bloom's join flight.** `AliaParticipants` draws Bloom's
17
+ `AgentProfile` with `[lead, ...joined]`. When the lead consults an agent, the agent's reply is
18
+ drawn under its own `AgentReplyIdentity` (anchor `reply:<agentId>`) and its avatar flies into
19
+ the header — `centeredLanding(14)`, merging, 950 ms, staggered by 120 ms when several join, one
20
+ batch at a time — and the header gains it when the flight lands (at once with reduced motion; an
21
+ agent already in a loaded conversation is simply there). `useParticipants`, `joinFlights`,
22
+ `AliaParticipantsHeader` (the participants between the AI chat shell's own buttons, for a host
23
+ whose header slot takes a string title) and `ANCHORS` are exported. `one-thread.test.tsx` fails if
24
+ any other file imports `AgentProfile` or builds a join flight.
25
+ - **Consult stream events.** `alia.agent_start | agent_delta | agent_tool | agent_end`, read
26
+ strictly (`parseConsultEvent`): a frame of another version or shape is dropped whole. Each
27
+ consultation is one message carrying `agentInfo`, named `<assistantMessageId>-agent-<n>` in the
28
+ order of its start, as the server stores it; its tool calls and results stream into it.
29
+ - **Host tools.** `hostTools?: { app, definitions, execute }` declares the app's UI effects with
30
+ every request (`host: { app, version: 1, tools, outcomes? }`). An `alia.host_action` is performed
31
+ once by `execute`; its outcome (`applied | inline | rejected | stale | failed`) rides the next
32
+ request, and stays queued when a request carrying it does not get through. Screen state is the
33
+ existing `clientContext`, built by the host per turn.
34
+ - **Tool-result renderers.** `toolRenderers?: Record<'<app>:<tool>', (result) => ReactNode>`, keyed
35
+ only from `oxy_<app>__<tool>` / `self_<app>__<tool>`, drawn before (and instead of) the generic
36
+ tool card, for consulted agents' results too.
37
+ - **Feature gates.** `GET /v1/agents/:id/features`; the default attach menu (photos and files)
38
+ offers a row only where the lead's feature is available or locked, and a locked row calls
39
+ `onFeatureLocked(key)` instead of a picker. A turn refused with `feature_entitlement_required`
40
+ (in the stream or before it) calls `onFeatureLocked(feature)` and hands the words back to the
41
+ composer. Documents are uploaded to the person's Oxy Files (`oxyServices.assets.upload`,
42
+ private) and sent as a `{ type: 'file', file: { file_id, filename, mime } }` part.
43
+ - **`AliaAskProvider` + `useAskAgent()`.** One mounted sheet; `ask(agentKey?, turn?)` opens it on an
44
+ agent of `agents: Record<string, { id?: string }>` (no id = Alia), or opens Oxy's sign-in when the
45
+ session cannot call Alia. It carries `hostTools`, `toolRenderers`, `labels`, `voice`,
46
+ `clientContext`, `onFeatureLocked` and `onShare` for every agent.
47
+ - **Sharing.** `useShareConversation()` (`POST`/`DELETE /v1/conversations/:id/share`),
48
+ `useSharedConversation(token)` and `<AliaSharedConversation token>` (`GET /v1/shared/:token`,
49
+ no session, read-only through the SDK's own thread). `useConversations({ agentId })` lists the
50
+ conversations with one agent.
51
+
52
+ ### Breaking
53
+
54
+ - `AliaChatContent`'s `agentId` prop is `agent: { id }`.
55
+ - `AliaChatState.agents` is `AliaChatState.participants` (`{ lead, joined }`); `AliaChatAgent` is
56
+ gone (`AliaChatAgentRef` names the `agent` prop). `AliaChatHeader` takes `participants`, not
57
+ `agents`.
58
+ - `AliaChatSheet` / `AliaChatScreen` `onShare` receives the minted share
59
+ (`{ conversationId, token, expiresAt }`) instead of nothing.
60
+ - `labels.placeholder` is `(leadName) => string`; `labels.addDocuments` is new.
61
+ - `ALIA_ANCHORS` and `ALIA_TO_PROFILE` are `ANCHORS` (`lead:welcome`, `participants`,
62
+ `reply:<id>`) and `leadToProfile(lead)`.
63
+ - The retired single `alia.agent` frame and the `delta.agent_message` chunk are no longer read.
64
+ - **No agent asks for approval.** Removed: `alia.approval_request` / `alia.approval_result` in the
65
+ chat stream and on the agent-session socket; `PendingApproval`, `PendingApprovalResult`,
66
+ `Message.pendingApproval`, `Message.pendingApprovalResult`; `ApprovalDecision`,
67
+ `AgentApprovalRequest`, the `approval_request` / `approval_result` activity events,
68
+ `AgentActivityState.approvalRequest` / `approvalResult`, `respondApproval` of `useAgentActivity`;
69
+ the `waiting_approval` turn lifecycle and the `waiting` thought step (copy
70
+ `thought.waitingApproval`); the voice protocol's `approval.requested` and
71
+ `onApprovalRequested`. A question the agent asks (`askUserQuestion`) stays.
72
+ - **A plan is shown, never approved.** `alia.plan_preview` still draws `PlanPreviewCard`, now the
73
+ steps alone: its Approve and Cancel are gone, and so are what they did. Removed:
74
+ `approvePlan` / `rejectPlan` of `useConversationStream` and `useConversationThread`,
75
+ `onApprovePlan` / `onRejectPlan` of `AliaThread`, `PendingPlan.approved` / `rejected`,
76
+ `PlanPreviewCard`'s `onApprove` / `onReject` / `approved` / `rejected`, and the labels
77
+ `planApprove`, `planCancel`, `planApproved`, `planCancelled`. The work log's `plan_approved`
78
+ entry is `plan` (copy `thought.audit.plan`, "Plan"), listed for every plan shown.
79
+ `Message.pendingPlan` is `Message.plan`, and its type `PendingPlan` is `MessagePlan`
80
+ (`{ planId, steps }`): nothing about it is pending.
81
+ - **No agent mode.** `AliaTurnRequest.agentMode` is gone and no `agentMode` is sent: Alia consults
82
+ agents with `consultAgent` whenever she needs to. The work-log copy of `askAgent` /
83
+ `delegateToAgent` is `consultAgent`'s.
84
+ - `usePhotosMenu` is gone (the default menu is `useAttachMenu`). `buildMessageContent` takes an
85
+ optional document `upload` as its third argument.
86
+
87
+ ## 18.1.0
4
88
 
5
89
  - **The SDK declares its CSP, and the voice call needs no `blob:` script.** In an app with a
6
90
  Content-Security-Policy (Mention) the call failed twice over: `connect-src` lacked
@@ -14,7 +98,7 @@
14
98
  `script-src https://alia.onl` the avatar already needs. The API's URL is defined once (the
15
99
  dictation, read-aloud and voice hooks each had their own copy).
16
100
 
17
- ## 15.7.0
101
+ ## 17.1.0
18
102
 
19
103
  - **`AliaAvatarIcon` is her still until she moves.** At icon size it drew Alia through the live 3D
20
104
  runtime, so a header button cost every cold load of the app around it the whole runtime from
@@ -26,23 +110,70 @@
26
110
  installed Bloom's runtime; a test fails if `ALIA_AVATAR` changes without it. Peer
27
111
  `@oxy.so/bloom` is `>=10.9.0`.
28
112
 
29
- ## 15.6.0
113
+ ## 17.0.2
30
114
 
31
115
  - **The composer has its loader again.** While a turn runs, the pill is wrapped in Bloom's
32
116
  `ComposerLoader` (the light that laps its rim) with `surface={false}` and `frosted`, as the
33
117
  composer had before it became `ComposerPill` (15.1.0) and lost it. A question Alia asks sits
34
118
  beside the loader instead of inside the pill's `question` slot, so the light does not ring it.
35
119
 
36
- ## 15.5.0
37
-
38
- - **Replies are set by Bloom's `Markdown`.** `AliaMarkdown` is a thin wrapper over
39
- `@oxy.so/bloom/markdown` at its chat reading size (`lg`, 16/28): the parser, the streaming
40
- behaviour and the colours are Bloom's. `react-native-markdown-display` — and with it
41
- `markdown-it` and the `linkify-it` ReDoS advisory — is no longer a dependency, so apps stop
42
- installing it. `AliaMarkdown` loses its `colors` and `fontFamily` props (nothing used them: the
43
- text follows the app's Bloom theme) and gains `streaming`. Peer `@oxy.so/bloom` is `>=10.7.0`.
44
-
45
- ## 15.4.0
120
+ ## 18.0.0
121
+
122
+ One thread, one conversation screen. The Alia app's thread — its turns, cards, work log, thought
123
+ panel, history, search and scroll window — moves into the SDK, and `AliaChatContent` becomes the
124
+ whole conversation: the bottom sheet, `AliaChatScreen` and the app are frames around it. What the
125
+ app keeps is what is its own: the sidebar, the right panel, the column layout that mounts them,
126
+ its routes and its callbacks.
127
+
128
+ - **Breaking: the sheet and the screen draw the app's thread.** `AliaChatMessageList` and
129
+ `ThinkingBlock` are gone, with the avatar-identity reply they drew. The turns are Bloom's AI Chat
130
+ turns (`AliaThread`, `ThreadRow`), with copy, like/dislike, read aloud, regenerate, edit, the
131
+ long-press menu, day lines, tool cards, the "Worked for…" line and the failed turn's toast with
132
+ Retry. `renderMarkdown`, `onEditMessage`, `onThumbsUp`, `onThumbsDown`, `onApprovePlan` and
133
+ `onRejectPlan` are removed from `AliaChatContent`: the thread edits in the composer, votes through
134
+ the API (`PATCH /v1/conversations/:id/messages/:id/vote`) and answers plans itself.
135
+ - **Breaking: `AliaChatContent`'s `header` is `chrome`.** `chrome(state)` returns
136
+ `{ header, title, project, actions }`, the whole of what the container draws around the thread
137
+ (the breadcrumb included). `AliaChatState.clear` is `startOver`; it also carries `conversationId`,
138
+ `clearMessages`, `openSearch` and `getMessages`. `AliaVoiceOptions` loses `isFocused` (the chat
139
+ has one, for the ambient field too) and gains `sounds`.
140
+ - **New: what a host brings to `AliaChatContent`.** `threadHandle` (an agent's permanent thread:
141
+ history above, search, jump), `ephemeral` (ghost mode), `model` + `onModelChange` +
142
+ `deviceModels` (the power-level selector: the seven levels from `buildPowerLevelOptions`, then
143
+ the person's own devices), `addMenu` (the host's rows; photos by default), `composerStatus`,
144
+ `surface`, `layout`, `isFocused`, `bottomInset` (now gives way to the keyboard,
145
+ `KeyboardSafeAreaFloor`), `onSignInRequired`, `renderUsageLimit`, `onSuggestionPicked`.
146
+ `AliaSuggestion.template` marks a line with blanks to fill.
147
+ - **New: where the work of a turn is read.** `ThoughtPanel` draws the selection of
148
+ `useThoughtStore` (`open`, `setTab`, `sync`, `close`); the host places it. `AliaRuntimeHost`
149
+ gains `showThought(opening)` (return `false` to decline an automatic opening), `openAutomation`
150
+ (a scheduled-task card is a link only where the host says where it goes) and `faviconUrl`.
151
+ `AliaChatSheet` opens it in a sheet over the conversation. `FilesAndSources` takes
152
+ `outputActions` (`canOpen`/`open`): asking whether a file opens no longer opens it.
153
+ - **New: the weather, market and FairCoin cards are the SDK's.** Their tools are in the pipeline
154
+ every Alia surface calls and the numbers travel in the message, so any surface that draws Alia's
155
+ reply draws them.
156
+ - **New: `AliaRuntimeProvider speech`** (`voice`, `tone`, `language`) for read-aloud, dictation and
157
+ calls; `useTTS` takes its `apiUrl` and preferences from it.
158
+ - **New: the thread's data layer, in `@alia.onl/sdk/runtime`.** `useThreadHistory`,
159
+ `useThreadSearch`, `useThreadWindow`, `useAgentActivity` (and `applyActivityEvent` /
160
+ `hydrateActivity` in `/model`), `useThoughtStore`, `aliaQueryKeys.threads`,
161
+ `AliaApi.patch`, `ConversationThread`, `AgentRun` (`useConversationThread` now
162
+ returns `agentRun`), and `useConversation(undefined)`. The agent routes are Alia's own clients'
163
+ (outside `/v1`).
164
+ - **New: `@alia.onl/sdk/model`** also carries the power levels (`POWER_LEVELS`,
165
+ `resolveModeSelection`…) and `triggerLabel` / `cronLabel`.
166
+ - **Changed: `AliaChatScreen`'s ambient field takes the whole screen's shape** (`layout="screen"`, the default); the sheet keeps its smaller one (`layout="sheet"`).
167
+ - **Changed: `labels.locale`** (the language `labels.t` speaks, for dates, days and prices). The
168
+ chat's English covers every key the thread asks for (`tests/lib/copy-keys.test.ts` reads the
169
+ source and fails on one it lacks).
170
+ - **Changed: `AliaMarkdown` defaults its body face to Bloom's** (`MARKDOWN_BODY` is gone), and
171
+ `ReplyMarkdown` — rich blocks, references list, code card — is the reply's renderer.
172
+ - **New peers:** `expo-web-browser`, `react-native-css`; `expo-clipboard` is no longer optional.
173
+ - **Fixed:** the thought panel asked "can this file open?" by opening it, once per output, while
174
+ rendering.
175
+
176
+ ## 17.1.0
46
177
 
47
178
  - **New leaf entry `@alia.onl/sdk/avatar`.** `AliaAvatarIcon`, `AliaAvatar`, `ALIA_AVATAR` and
48
179
  `useAliaActivity` without the chat: an app draws Alia's live avatar on a header button and keeps
@@ -50,6 +181,104 @@
50
181
  `check:entries` holds the leaf free of the sheet, the composer, the markdown renderer and the
51
182
  voice call. The root entry still exports the same four.
52
183
 
184
+ ## 17.0.1
185
+
186
+ - The task labels follow the API's tool loader: `loadTools` ("Loading tools" / "Loaded tools")
187
+ replaces `useApps`, which the API no longer has. A conversation stored with `useApps` calls
188
+ still replays; the call just shows its raw name.
189
+
190
+ ## 17.0.0
191
+
192
+ One conversation runtime. The sheet, `AliaChatScreen` and the Alia app are frames around the
193
+ same data layer and the same conversation screen: conversations are persisted, listed, opened,
194
+ renamed, deleted and cleared through the same hooks, a turn is the same stream, and a
195
+ conversation started in one surface is the same conversation in the others. The runtime is the
196
+ app's, moved and generalised (`src/runtime`).
197
+
198
+ - **Breaking: the sheet and the screen have conversations.** Turns are stored, and the SDK
199
+ speaks only to `/v1` (`POST /v1/chat/completions`, `/v1/conversations`): bearer, no cookies,
200
+ public CORS, so it works from every Oxy app's web origin with no backend in between. The API
201
+ gained `/v1/conversations` (the same router as `/conversations`, behind a person's session
202
+ only) for this. The consumer-backend relay the README used to document is no longer needed.
203
+ - **Breaking: `useAliaChat`, `UseAliaChatOptions`, `UseAliaChatReturn`, `AliaChatStreamError`,
204
+ `AliaChatFailure` are removed.** Use `useConversationThread`.
205
+ - **Breaking: the `agents` prop is gone** from the sheet, the screen and `AliaChatContent`
206
+ (the pre-opened agent message of a delegation is the thread's agent run now).
207
+ - **Breaking: `model`** is sent as given (a power level — `auto`, `instant`, `medium`, `high`,
208
+ `xhigh`, `pro`, `ultra` — or an exact `publisher/model`) instead of being checked against
209
+ `GET /catalogue` first. The catalogue helpers (`fetchCatalogue`, `parseCatalogue`,
210
+ `resolveSelection`, `resolveModelId`, `clearCatalogueCache` and their types) are removed: the
211
+ SDK itself no longer reads the catalogue, and people choose power levels, not model names.
212
+ - **Changed: the header's Clear starts a new conversation** in the sheet and the screen (the
213
+ thread empties and the next turn opens a fresh conversation); nothing is deleted, the old one
214
+ stays in the list. Deleting or emptying a stored conversation is `useDeleteConversation` /
215
+ `useClearConversation`.
216
+ - **Breaking: `ChatMessage` is the runtime `Message`:** `createdAt` is an ISO string, and a
217
+ `ToolInvocation` always has a `toolCallId`. Agent answers use the server's ids
218
+ (`<reply id>-agent-<n>`).
219
+ - **Breaking: voice.** `openElsewhere` and `owner` are gone from `useVoiceLauncher` and
220
+ `AliaVoiceOptions`; `conversationId` and `agentId` belong to the chat. A call always lives in a
221
+ conversation: the open one, or — on a new-chat screen — one created when the call starts (after
222
+ the gate) and shown, and it opens on the screen that shows that conversation — in place in the
223
+ sheet, on the destination route in a navigating host (`useVoiceCallRequests`). `start()` is
224
+ async. New options `resolveConversation` and `accountId`; a live call now ends when the screen
225
+ shows another conversation, loses focus or changes account.
226
+ - **Who owns the open conversation:** a host that navigates (`runtime.openConversation`, or one
227
+ from an outer `AliaRuntimeProvider`) decides; with none, `AliaChatContent` keeps its own.
228
+ - **Breaking: `labels.workLog` is `labels.t`, and `englishWorkLog` is `englishCopy`.** One translator
229
+ keyed like the Alia app's catalogue asks for every string that is not a fixed `labels` field
230
+ (the work log, the thread, the thought panel…); the app hands its own `t` in, a host without one
231
+ reads English (`src/lib/copy-en.ts`).
232
+ - **Breaking: `ChatMessage` is `Message`** (and `ToolInvocation` always has a `toolCallId`).
233
+ - **New leaf entries.** `@alia.onl/sdk/model` is the conversation as pure data — the records and
234
+ what a list of messages becomes before anything draws it (`timelinePositions`, `buildSteps`,
235
+ `extractSources`, `cardOf`, `daySeparators`, `buildConversationMarkdown`…), no React, no Oxy
236
+ client. `@alia.onl/sdk/runtime` is the data layer (hooks, cache, stores) and re-exports the model.
237
+ `check:entries` holds both leaves free of the UI and the call.
238
+ - **New peer: `@tanstack/react-query`** (the runtime's cache; `OxyProvider` already mounts it).
239
+ - **New:** `AliaRuntimeProvider` / `useAliaRuntime` (`apiUrl`, `chatUrl`, `offline`, `streamFetch`,
240
+ and `host: AliaRuntimeHost`: navigation, `onUsage`, `onArtifact`, `onToolResult`, `onContext`,
241
+ `onAgentTurn`, `onTurnPreview`, `turnRequest`, `deviceInfo`, `subscribeConversationMessages`),
242
+ `useConversations`, `useConversation`, `usePrefetchConversation`, `useCreateConversation`,
243
+ `useRenameConversation`, `useDeleteConversation`, `useClearConversation`, `useSaveConversation`,
244
+ `useConversationThread`, `useTurnEdit`, `useComposerDraftStore` (+ `useComposerDraft`,
245
+ `useDraftAddress`), `useConversationStore`, `aliaQueryKeys`, `useAliaApi`, `AliaApiError`,
246
+ `buildMessageContent`, `UsageLimitError`, `FailedTurn`; `AliaChatContent` takes
247
+ `conversationId`, `onConversationChange`, `agentId` and `runtime`.
248
+ - **New labels:** `newChat`, `sendFailed`, `signInRequired`, `conversationSaveFailed`,
249
+ `conversationDeleteFailed`, `conversationCreateFailed`, `conversationClearFailed`,
250
+ `attachmentNotSent`, `attachmentUnreadable`.
251
+ - The composer's text and photos are the shared per-conversation draft (they survive closing the
252
+ sheet and failed sends restore them).
253
+
254
+ ## 16.0.0
255
+
256
+ Voice is part of the conversation screen. The sheet, `AliaChatScreen` and the Alia app now run
257
+ the same call, with the same words and the same behaviour, instead of each orchestrating it.
258
+
259
+ - **Breaking: the `voiceSession` prop is gone** from `AliaChatContent`, `AliaChatScreen` and
260
+ `AliaChatSheet`, together with the `VoiceSessionComponent` type. Voice is on by default; pass
261
+ `voice={false}` for a text-only chat. `voice={{ ... }}` (`AliaVoiceOptions`) brings the host's
262
+ part: `canStartVoice` (answers `'sign-in' | 'plan-required' | 'credits-exhausted' | null`;
263
+ the SDK tells the person, `onVoiceBlocked` adds navigation or sign-in), `onCallEnded` (refresh
264
+ credits and the thread), `onNotice` (default: Bloom's toast), `conversationId`, `agentId`,
265
+ `locale`, `voice` (`'male' | 'female'`), `onMessagesSaved`, `owner` and `isFocused` (a live
266
+ call ends when the screen is no longer on show or the account/conversation changes) and
267
+ `openElsewhere` (a screen with no conversation to hold the call opens one and hands over).
268
+ - **Breaking: `VoiceSessionProps.onEnd` takes no argument.** `VoiceSession` itself says why a
269
+ call failed (`labels.voiceError(code)`), that it ended without failing
270
+ (`labels.voiceEnded(reason)`: moved to another device, time limit, silence, credits, server
271
+ shutdown; a hang-up says nothing) and, once, that it is about to end
272
+ (`labels.voiceEndingSoon`, also shown in the bar), through `onNotice`. New `onMessagesSaved`
273
+ and `onNotice` props.
274
+ - **Breaking: labels.** `voiceFailed` is replaced by `voiceControls`, `voiceEnded`,
275
+ `voiceEndingSoon` and `voiceBlocked`. `AliaChatLabelsProvider` and `useLabels` are exported.
276
+ - **New:** `useVoiceLauncher` (the host side of a call: gate, state, ownership), `AliaVoiceCall`
277
+ (the call bar, loaded on its first use), `toastNotice`, `VoiceNotice`, `VoiceBlockReason`.
278
+ - **Breaking: `react-native-audio-api` is a required peer** (it was optional): the conversation
279
+ screen includes the call. It is still only evaluated on the first call (one lazy `import()`),
280
+ and `check:entries` now holds that, not the old isolation.
281
+
53
282
  ## 15.3.0
54
283
 
55
284
  - **The composer is Bloom's `ComposerPill`.** `AliaComposer` (the sheet's, the screen's and the