@alia.onl/sdk 11.1.0 → 13.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.
- package/CHANGELOG.md +134 -0
- package/package.json +5 -4
- package/src/components/AliaAvatar.tsx +16 -20
- package/src/components/AliaChatContent.tsx +234 -96
- package/src/components/AliaChatHeader.tsx +102 -76
- package/src/components/AliaChatMessageList.tsx +174 -134
- package/src/components/AliaChatScreen.tsx +45 -23
- package/src/components/AliaChatSheet.tsx +151 -50
- package/src/components/AliaWelcomeMessage.tsx +26 -53
- package/src/components/AmbientField.tsx +19 -16
- package/src/components/ComposerSuggestions.tsx +45 -0
- package/src/components/IdentityMark.tsx +3 -1
- package/src/components/Markdown.tsx +18 -24
- package/src/components/QuestionCard.tsx +35 -33
- package/src/components/ThinkingBlock.tsx +9 -13
- package/src/components/VoiceModeIcon.tsx +15 -7
- package/src/components/voice/VoiceControls.tsx +17 -9
- package/src/hooks/useAliaChat.ts +124 -5
- package/src/hooks/useComposerSuggestions.ts +84 -0
- package/src/index.ts +10 -10
- package/src/lib/agent-character.ts +28 -0
- package/src/lib/chat-stream.ts +25 -3
- package/src/lib/citations.ts +62 -10
- package/src/lib/delegation.ts +34 -0
- package/src/lib/domain.ts +12 -0
- package/src/lib/flights.ts +24 -0
- package/src/lib/greeting.ts +15 -0
- package/src/lib/image-data-url.ts +26 -5
- package/src/lib/labels.tsx +10 -2
- package/src/lib/questions.ts +15 -1
- package/src/lib/suggestions.ts +53 -0
- package/src/lib/task-labels.ts +7 -39
- package/src/lib/use-after-delay.ts +19 -0
- package/src/lib/work-log.ts +3 -9
- package/src/tools.ts +8 -1
- package/src/types.ts +6 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,139 @@
|
|
|
1
1
|
# @alia.onl/sdk
|
|
2
2
|
|
|
3
|
+
## 13.0.0
|
|
4
|
+
|
|
5
|
+
Fixes found by driving the sheet end to end (the sheet shows plans, links citations, nests lists):
|
|
6
|
+
|
|
7
|
+
- **A plan is drawn.** `plan_preview` was parsed but the sheet passed no handlers, so the card
|
|
8
|
+
never showed. `useAliaChat` now returns `approvePlan` / `rejectPlan` (approve collapses the
|
|
9
|
+
card to "approved"; reject collapses it and stops the turn) and `AliaChatContent` uses them
|
|
10
|
+
unless the host passes its own.
|
|
11
|
+
- **Citations link.** `[n]` markers in a reply link to their sources (`linkifyCitations`,
|
|
12
|
+
`normalizeCitationMarkers`, `citationLabel` are exported from `@alia.onl/sdk/tools`; the app
|
|
13
|
+
re-exports them instead of keeping a copy).
|
|
14
|
+
- **Nested lists** draw under their parent instead of inline beside it.
|
|
15
|
+
- A finished research step reads "Researched", not "Researching".
|
|
16
|
+
- A turn that ends at a question card with no sentence before it counts as answered.
|
|
17
|
+
|
|
18
|
+
- **BREAKING: an agent is drawn with the look the server stores for it.** `agentCharacter(id)` (a
|
|
19
|
+
look hashed from the id) is removed; `readAgentCharacter(value)` parses a stored character
|
|
20
|
+
(Bloom's `parseAvatarCharacter`) and falls back on `DEFAULT_AGENT_CHARACTER`. The `alia.agent`
|
|
21
|
+
event carries `agentCharacter`, and `agentInfo` has `character`. `AliaChatAgent` has `character`;
|
|
22
|
+
`AliaChatSheet` / `AliaChatScreen` take `agents` (the host's directory) so a delegation's
|
|
23
|
+
thinking avatar is the agent's own before its answer arrives. Needs a server that sends
|
|
24
|
+
`agentCharacter`; release this SDK first, since the stream parser rejects unknown keys.
|
|
25
|
+
- **The one who answers thinks with its own avatar, and it is the same avatar that settles under
|
|
26
|
+
the reply** (Bloom's `AgentReplyIdentity`, as in the multi-agent chat). While Alia works, her
|
|
27
|
+
avatar is the indicator, large with "Thinking…", where the `AgentThinking` line was; when her
|
|
28
|
+
text starts it shrinks under it with her name. A call to an agent (`delegateToAgent` /
|
|
29
|
+
`askAgent`, its `agentId` and `agentName` or `agent` arguments) opens the agent's message at
|
|
30
|
+
once, empty and thinking, and its answer fills that same message, so the avatar never remounts;
|
|
31
|
+
an agent that never answers leaves no message. Alia's reply now carries her identity row, as the
|
|
32
|
+
agents' do.
|
|
33
|
+
The reasoning is part of that same component (`AgentReplyIdentity`'s `reasoning`): while the
|
|
34
|
+
turn thinks, "Thinking… ⌃" folds it under the avatar's row, and once the reply starts it is the
|
|
35
|
+
closed "Thought for N seconds" block above it (`ThinkingBlock` draws nothing while it streams, so
|
|
36
|
+
there is one thinking indicator, not two).
|
|
37
|
+
- **No jumps of height, and no flash of the wrong thinker.** A reply, a new row, the reasoning and
|
|
38
|
+
a thinking agent's avatar open and close with their height eased (Bloom's `Collapsible`, now
|
|
39
|
+
with `appear`) instead of popping. Alia is shown thinking only once she has for a moment, so a
|
|
40
|
+
turn she hands to an agent at once shows the agent thinking, not Alia for an instant first.
|
|
41
|
+
- **Bubbles are equal on every side as the eye reads them.** An agent's bubble sets its top and
|
|
42
|
+
bottom padding from the reply's text metrics (`AgentReplyBubble`'s `text`, 16 on 28 here), so
|
|
43
|
+
the gap from the edge to the text is the same above, below and at the sides. Nothing is cut:
|
|
44
|
+
an open `Collapsible` no longer clips.
|
|
45
|
+
- **The greeting's avatar flies up into the header's profile** as the conversation begins
|
|
46
|
+
(Bloom's `avatar-flight`: `useAvatarFlights`, `AvatarAnchor`, `AvatarFlightLayer`), across the
|
|
47
|
+
main and conversation sheets. `AgentProfile`'s new `avatarHidden` keeps the header's avatar
|
|
48
|
+
waiting for it. Needs a Bloom with `avatar-flight` (after 10.3).
|
|
49
|
+
- **`AliaChatSheet` opens the conversation in a second sheet stacked over the main one.** The
|
|
50
|
+
main sheet stays on the greeting, the suggestions and the composer; the first turn (typed or a
|
|
51
|
+
suggestion) opens a fresh conversation sheet on top, whose back button (and the menu's Clear)
|
|
52
|
+
closes just that sheet, back to the main screen. A phone gets sheets flush with the screen
|
|
53
|
+
edges, with the composer clearing the home indicator; from tablet width (768 px) they float.
|
|
54
|
+
`AliaChatContent` gains `onStart` (hand an empty chat's first turn to the host) and
|
|
55
|
+
`initialTurn` (a turn sent once on mount).
|
|
56
|
+
- **The empty chat looks and behaves like the Alia app's, from the same code.** The avatar sits
|
|
57
|
+
beside the greeting (`AliaWelcomeMessage`, now just the greeting: always side by side, no
|
|
58
|
+
`hideMark`, no suggestions) and the header shows Alia's profile only once there is a
|
|
59
|
+
conversation. The suggestions are one-line rows **over the composer** (`ComposerSuggestions`),
|
|
60
|
+
and from two typed characters they become matches with the typed part highlighted, arrows /
|
|
61
|
+
Enter / Escape through the composer's `onKeyPress`. The app now draws its greeting and its
|
|
62
|
+
suggestions with these same components and only supplies its API's data.
|
|
63
|
+
- **Several agents in one turn.** A delegated agent's answer (`alia.agent`) is now its own
|
|
64
|
+
message with its name and avatar, placed before Alia's reply as the app places it, so a turn
|
|
65
|
+
with Lumi, Atlas and Sol shows three speakers. Before, every answer was merged into one message
|
|
66
|
+
under the last agent's name. Alia's reply is dropped when she said nothing after handing over.
|
|
67
|
+
- **A delegated agent shows its 3D avatar.** The speaker line of an agent's message is Bloom's
|
|
68
|
+
`AgentAvatar`, not an image (an agent's account has none): the character comes from the agent's
|
|
69
|
+
id (`agentCharacter(id)`, exported), so the same agent looks the same everywhere and two agents
|
|
70
|
+
in a turn are told apart. The app draws its agents' messages with the same avatar.
|
|
71
|
+
- **Agents are bubbles, and the header holds the team.** As in Bloom's multi-agent chat, a
|
|
72
|
+
delegated agent's reply is a tinted bubble with its avatar and name beneath it. Once agents have
|
|
73
|
+
answered, the header profile stacks Alia with up to two of them and names them together
|
|
74
|
+
("Alia + Lumi + Atlas"). `headerLeading` / `actions` receive `agents` in their state
|
|
75
|
+
(`AliaChatState`, `AliaChatAgent`), and `AliaChatHeader` takes `agents`.
|
|
76
|
+
- **The row under every reply is Bloom's multi-agent one**: helpful, unhelpful and copy as 22px
|
|
77
|
+
tiles with 12px icons (read aloud is a fourth tile where the host reads), replacing the
|
|
78
|
+
`AiChatFeedbackRow`. New label keys `helpful` and `unhelpful`.
|
|
79
|
+
- **Built on Bloom's `agent-reply`** (peer `@oxy.so/bloom ^10.1.1`): replies, their identity line and
|
|
80
|
+
action tiles, and the header profile are Bloom's `AgentReply`, `AgentReplyBubble`,
|
|
81
|
+
`AgentReplyIdentity`, `AgentReplyActions` and `AgentProfile`, the pieces `MultiAgentChat` is made
|
|
82
|
+
of, not copies. Pressing the profile makes every avatar in it wave.
|
|
83
|
+
- **Questions are asked above the composer, not in the thread.** What Alia asks in her last turn
|
|
84
|
+
(`askUserQuestion`) docks above the composer as Bloom's `Questionnaire`, with a dismiss; typing a
|
|
85
|
+
reply answers just as well. The thread keeps the questions as plain lines (`AskedQuestions`).
|
|
86
|
+
**Breaking:** `QuestionCard` is now the docked questionnaire (`onSubmit` required, new
|
|
87
|
+
`onDismiss`) and no longer draws a read-only variant; the `onAnswerQuestions` prop of the message
|
|
88
|
+
list is gone. `pendingQuestions` joins `@alia.onl/sdk/tools`.
|
|
89
|
+
- **The voice bar is Bloom's voice controls.** `VoiceControls` draws Bloom's `@oxy.so/bloom/voice`
|
|
90
|
+
`VoiceControls` (microphone and end) under the status text, instead of `CallControls`, which is
|
|
91
|
+
made for a dark call stage and lost its captions on the chat's light surface.
|
|
92
|
+
- **The header is back, the profile, share and a menu.** Bloom's `PageHeader` with a back button at
|
|
93
|
+
its start, and at its end share and a three-dots menu (Bloom's `DropdownMenu`, aligned to its
|
|
94
|
+
button) holding Clear and the host's rows. Over the empty chat there is no bar: nothing to do
|
|
95
|
+
there. In the sheet, back returns to the main screen (a fresh chat) and the sheet stays open.
|
|
96
|
+
**Breaking:** `AliaChatHeader` / `AliaChatSheet` / `AliaChatScreen` lose `onClose`; they take
|
|
97
|
+
`onBack` (screen), `onShare` and `headerMenu`; the labels `close` becomes `back`, `share`,
|
|
98
|
+
`more`.
|
|
99
|
+
- **The chat follows Bloom's theme, not the system's scheme.** `AliaMarkdown` and the sheet read
|
|
100
|
+
the app's resolved mode: a person who chose light on a dark OS got white text on a light surface.
|
|
101
|
+
- **Every icon is Bloom's.** The voice button is `RiVolumeUpLine` (it was Entypo); the app's clock,
|
|
102
|
+
robot and connector glyphs are `RiTimeLine`, `RiRobot2Line`, `RiPlugLine` and the SVG generator
|
|
103
|
+
is gone; `@expo/vector-icons` is no longer a peer of the SDK.
|
|
104
|
+
- **Greeting.** The avatar (88px) above the text, both centred; `max-w-xs`, so it always sets in two lines; more room above than below. The Alia app draws the same.
|
|
105
|
+
- Peer `@oxy.so/bloom ^10.2.1` (scrollbar, pill groups, header scrim, voice controls).
|
|
106
|
+
- **Breaking:** `WelcomeSuggestion { id, title, description }` becomes `AliaSuggestion { id, text }`
|
|
107
|
+
(`text` is what is shown and what is sent). New optional props on the sheet, screen and content:
|
|
108
|
+
`suggestionMatches` and `onSuggestionQuery(query)`, so a host can search as the person types.
|
|
109
|
+
New exports: `ComposerSuggestions`, `useComposerSuggestions`, `useSuggestionQuery`,
|
|
110
|
+
`composerCompletions`, `Completion`, `AliaSuggestion`.
|
|
111
|
+
|
|
112
|
+
## 12.0.0
|
|
113
|
+
|
|
114
|
+
Breaking: Bloom 10 peer; the `header` render prop replaces the breadcrumb path (`title`, `actions`)
|
|
115
|
+
and the mark-state context. Hosts on Bloom 9 stay on 11.1.0.
|
|
116
|
+
|
|
117
|
+
- **The `@oxy.so` peers are open-ended** above their floors (`bloom >=10.0.0`, `core >=3.0.0`,
|
|
118
|
+
`services >=8.0.0`). The `^10.0.0`, `^4.0.0` and `^11.0.0` caps made each new Oxy major a peer
|
|
119
|
+
conflict in every app until this package republished; apps always run the latest Oxy SDK.
|
|
120
|
+
|
|
121
|
+
- **`AmbientField` takes `layout="sheet"`** for a short card (the chat's sheet): the blobs are
|
|
122
|
+
drawn at the size of a phone screen, spread wider and shifted back to the right, cropped by the
|
|
123
|
+
card's edges. It is asked for, not inferred from the field's height, so a short app screen is
|
|
124
|
+
never reinterpreted. `AmbientField`, `AliaAvatar` and `AliaChatHeader` are memoised and the
|
|
125
|
+
chat body no longer repaints them on every streamed token; read-aloud and starting a call no
|
|
126
|
+
longer change identity per flush. `AliaAvatar` takes `portrait` (a still thumbnail, used for
|
|
127
|
+
the sidebar's permanent mark).
|
|
128
|
+
- **One `header` render prop** on `AliaChatContent`, handed `hasMessages`, `clear` and the live
|
|
129
|
+
avatar `markState`; the breadcrumb path (`title`, `actions`) and the mark-state context are gone.
|
|
130
|
+
- The profile and the screen's background are NativeWind classes with Bloom tokens
|
|
131
|
+
(`bg-background-full`, `group-hover/profile:…`), not JS-computed colours.
|
|
132
|
+
- **Bloom is a peer at `^10.0.0`** (was `^9.0.0`). Bloom 10 makes an avatar one flat
|
|
133
|
+
`AvatarCharacter`; `AliaAvatar` is `{ preset: 'blue_beret', accessory: 'none', color: 'orchid' }`
|
|
134
|
+
and no longer builds a `config`. Hosts mount `AgentAvatarProvider` as before. Hosts on Bloom 9
|
|
135
|
+
stay on the previous release.
|
|
136
|
+
|
|
3
137
|
## 11.1.0
|
|
4
138
|
|
|
5
139
|
Alia can ask clarifying questions, as ChatGPT and Claude do.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alia.onl/sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "13.0.0",
|
|
4
4
|
"description": "Alia AI chat SDK — reusable chat UI, voice, and streaming components for Oxy apps",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"react-native": "src/index.ts",
|
|
@@ -39,9 +39,9 @@
|
|
|
39
39
|
"react": "^19.2.3",
|
|
40
40
|
"react-native": "^0.86.0",
|
|
41
41
|
"@expo/vector-icons": "^15.1.1",
|
|
42
|
-
"@oxy.so/bloom": "
|
|
43
|
-
"@oxy.so/core": "
|
|
44
|
-
"@oxy.so/services": "
|
|
42
|
+
"@oxy.so/bloom": ">=10.4.0",
|
|
43
|
+
"@oxy.so/core": ">=3.0.0",
|
|
44
|
+
"@oxy.so/services": ">=8.0.0",
|
|
45
45
|
"@react-native-async-storage/async-storage": "^2.2.0",
|
|
46
46
|
"expo-blur": "^57.0.0",
|
|
47
47
|
"react-native-reanimated": "^4.5.0",
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
"expo-haptics": "^57.0.0",
|
|
57
57
|
"nativewind": "^5.0.0-preview.3",
|
|
58
58
|
"expo-clipboard": "^57.0.0",
|
|
59
|
+
"expo-file-system": "^57.0.0",
|
|
59
60
|
"expo-speech-recognition": "^57.1.0"
|
|
60
61
|
},
|
|
61
62
|
"peerDependenciesMeta": {
|
|
@@ -1,26 +1,18 @@
|
|
|
1
|
-
import { AgentAvatar, type
|
|
2
|
-
import { useEffect, useState } from 'react';
|
|
1
|
+
import { AgentAvatar, type AvatarCharacter } from '@oxy.so/bloom/agent-avatar';
|
|
2
|
+
import { memo, useEffect, useState } from 'react';
|
|
3
3
|
|
|
4
4
|
/** What Alia is doing; the avatar plays a working turn each time it starts to think or work. */
|
|
5
5
|
export type AliaAvatarState = 'idle' | 'thinking' | 'working' | 'writing';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* Alia's likeness in Bloom's 3D character engine: the six-lobed flower in orchid,
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* Alia's likeness in Bloom's 3D character engine: the six-lobed flower in orchid, plain oval
|
|
9
|
+
* eyes, nothing on its head. It is `blue_beret` with the hat taken off and the paint changed,
|
|
10
|
+
* so Bloom retargets that preset's animation onto it; change it here and nowhere else.
|
|
11
11
|
*/
|
|
12
|
-
const ALIA_AVATAR:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
selections: {
|
|
17
|
-
shape: 'six_lobed_flower',
|
|
18
|
-
color: 'orchid',
|
|
19
|
-
eyes: 'oval',
|
|
20
|
-
eyewear: 'none',
|
|
21
|
-
accessory: 'none',
|
|
22
|
-
},
|
|
23
|
-
},
|
|
12
|
+
export const ALIA_AVATAR: AvatarCharacter = {
|
|
13
|
+
preset: 'blue_beret',
|
|
14
|
+
accessory: 'none',
|
|
15
|
+
color: 'orchid',
|
|
24
16
|
};
|
|
25
17
|
|
|
26
18
|
const BUSY: ReadonlySet<AliaAvatarState> = new Set(['thinking', 'working']);
|
|
@@ -34,6 +26,8 @@ export interface AliaAvatarProps {
|
|
|
34
26
|
interactive?: boolean;
|
|
35
27
|
/** Change it to replay the avatar's reaction (a wave) — for a button that wraps it. */
|
|
36
28
|
reactionKey?: number;
|
|
29
|
+
/** A still thumbnail instead of a live 3D avatar: for small, permanent spots like a sidebar. */
|
|
30
|
+
portrait?: boolean;
|
|
37
31
|
}
|
|
38
32
|
|
|
39
33
|
/**
|
|
@@ -41,11 +35,12 @@ export interface AliaAvatarProps {
|
|
|
41
35
|
* app must mount `AgentAvatarProvider` with the URL of the hosted `character-runtime`;
|
|
42
36
|
* without it Bloom shows its own "unavailable" state.
|
|
43
37
|
*/
|
|
44
|
-
export function AliaAvatar({
|
|
38
|
+
export const AliaAvatar = memo(function AliaAvatar({
|
|
45
39
|
size,
|
|
46
40
|
state = 'idle',
|
|
47
41
|
interactive = false,
|
|
48
42
|
reactionKey,
|
|
43
|
+
portrait = false,
|
|
49
44
|
}: AliaAvatarProps) {
|
|
50
45
|
const [workingKey, setWorkingKey] = useState(0);
|
|
51
46
|
const busy = BUSY.has(state);
|
|
@@ -55,12 +50,13 @@ export function AliaAvatar({
|
|
|
55
50
|
|
|
56
51
|
return (
|
|
57
52
|
<AgentAvatar
|
|
58
|
-
|
|
53
|
+
character={ALIA_AVATAR}
|
|
59
54
|
size={size}
|
|
60
55
|
label="Alia"
|
|
61
56
|
workingKey={workingKey}
|
|
62
57
|
interactive={interactive}
|
|
63
58
|
reactionKey={reactionKey}
|
|
59
|
+
portrait={portrait}
|
|
64
60
|
/>
|
|
65
61
|
);
|
|
66
|
-
}
|
|
62
|
+
});
|