@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.
- package/CHANGELOG.md +242 -13
- package/README.md +223 -151
- package/package.json +15 -5
- package/src/animations.ts +0 -1
- package/src/components/AliaAskProvider.tsx +127 -0
- package/src/components/AliaChatContent.tsx +604 -392
- package/src/components/AliaChatHeader.tsx +14 -38
- package/src/components/AliaChatScreen.tsx +56 -31
- package/src/components/AliaChatSheet.tsx +110 -36
- package/src/components/AliaComposer.tsx +1 -1
- package/src/components/AliaParticipants.tsx +202 -0
- package/src/components/AliaParticipantsHeader.tsx +60 -0
- package/src/components/AliaSharedConversation.tsx +86 -0
- package/src/components/AliaWelcomeMessage.tsx +18 -5
- package/src/components/Image.tsx +12 -0
- package/src/components/Markdown.tsx +498 -14
- package/src/components/PlanPreviewCard.tsx +7 -49
- package/src/components/ReplyMarkdown.tsx +359 -0
- package/src/components/RichBlocks.tsx +195 -0
- package/src/components/canvas/CanvasComponent.tsx +59 -0
- package/src/components/canvas/ChartRenderer.tsx +73 -0
- package/src/components/canvas/CodeRenderer.tsx +24 -0
- package/src/components/canvas/FormRenderer.tsx +101 -0
- package/src/components/canvas/MarkdownRenderer.tsx +14 -0
- package/src/components/canvas/TableRenderer.tsx +47 -0
- package/src/components/thought/FilesAndSources.tsx +120 -0
- package/src/components/thought/ThoughtPanel.tsx +417 -0
- package/src/components/thought/ToolStep.tsx +141 -0
- package/src/components/thread/AgentResultCard.tsx +125 -0
- package/src/components/thread/AgentTaskCard.tsx +127 -0
- package/src/components/thread/AliaThread.tsx +401 -0
- package/src/components/thread/MessageBlockBoundary.tsx +78 -0
- package/src/components/thread/NewConversationOffer.tsx +54 -0
- package/src/components/thread/ThreadRow.tsx +458 -0
- package/src/components/thread/ThreadSearch.tsx +129 -0
- package/src/components/thread/ToolResultCard.tsx +254 -0
- package/src/components/thread/TurnMenu.tsx +54 -0
- package/src/components/thread/TurnStatusLine.tsx +34 -0
- package/src/components/voice/AliaVoiceCall.tsx +21 -0
- package/src/components/voice/VoiceControls.tsx +2 -28
- package/src/components/voice/VoiceSession.tsx +39 -11
- package/src/hooks/useAliaActivity.ts +2 -2
- package/src/hooks/useAtBottom.ts +51 -0
- package/src/hooks/useAttachMenu.ts +94 -0
- package/src/hooks/useChatComposer.ts +299 -0
- package/src/hooks/useChatVoice.ts +129 -0
- package/src/hooks/useDocumentPicker.ts +3 -29
- package/src/hooks/useFailedTurnToast.ts +43 -0
- package/src/hooks/useMessageVote.ts +50 -0
- package/src/hooks/useOpenThought.ts +79 -0
- package/src/hooks/usePendingQuestions.ts +2 -2
- package/src/hooks/useReadAloud.ts +92 -0
- package/src/hooks/useShareHandler.ts +24 -0
- package/src/hooks/useSoundEffects.ts +1 -1
- package/src/hooks/useThoughtScope.ts +59 -0
- package/src/hooks/useThreadRows.ts +145 -0
- package/src/hooks/useThreadView.ts +68 -0
- package/src/hooks/useTimelineWindow.ts +256 -0
- package/src/hooks/useVoiceLauncher.ts +180 -0
- package/src/hooks/useVoiceRoom.ts +0 -3
- package/src/index.ts +43 -29
- package/src/lib/activity-store.ts +1 -1
- package/src/lib/add-menu.ts +7 -0
- package/src/lib/call-thread.ts +33 -0
- package/src/lib/citations.ts +79 -2
- package/src/lib/clipboard.ts +23 -0
- package/src/lib/content-utils.ts +10 -0
- package/src/lib/copy-en.ts +284 -0
- package/src/lib/copy.ts +32 -0
- package/src/lib/document-picker.ts +31 -0
- package/src/lib/flights.ts +22 -13
- package/src/lib/focus-return.ts +66 -0
- package/src/lib/keyboard.native.tsx +19 -0
- package/src/lib/keyboard.tsx +9 -0
- package/src/lib/labels.tsx +69 -17
- package/src/lib/participants.ts +86 -0
- package/src/lib/power-level-options.ts +66 -0
- package/src/lib/questions.ts +2 -2
- package/src/lib/task-labels.ts +4 -4
- package/src/lib/tool-call-status.ts +1 -1
- package/src/lib/tool-icons.ts +36 -0
- package/src/lib/tool-renderers.tsx +48 -0
- package/src/lib/turn-state.ts +2 -2
- package/src/lib/voice-call-request.ts +49 -0
- package/src/lib/voice-call.ts +76 -34
- package/src/lib/voice-controls-labels.ts +31 -0
- package/src/lib/voice-protocol.ts +32 -14
- package/src/lib/work-log.ts +6 -6
- package/src/runtime/agents.ts +151 -0
- package/src/runtime/api.ts +123 -0
- package/src/runtime/attachment-utils.ts +96 -0
- package/src/runtime/composer-draft-store.ts +270 -0
- package/src/runtime/config.tsx +186 -0
- package/src/runtime/conversation-store.ts +49 -0
- package/src/runtime/conversations.ts +557 -0
- package/src/runtime/error-utils.ts +104 -0
- package/src/runtime/host-tools.ts +140 -0
- package/src/runtime/index.ts +113 -0
- package/src/runtime/message-history.ts +124 -0
- package/src/runtime/model.ts +39 -0
- package/src/runtime/oxy-files.ts +37 -0
- package/src/runtime/power-levels.ts +66 -0
- package/src/runtime/query-keys.ts +34 -0
- package/src/runtime/random-uuid.ts +25 -0
- package/src/runtime/routes.ts +51 -0
- package/src/runtime/sharing.ts +165 -0
- package/src/runtime/sse-frame-reader.ts +88 -0
- package/src/runtime/stream-events.ts +146 -0
- package/src/runtime/stream-outcome.ts +21 -0
- package/src/runtime/thought-store.ts +103 -0
- package/src/runtime/thread/agent-activity.ts +261 -0
- package/src/runtime/thread/automation-labels.ts +79 -0
- package/src/runtime/thread/conversation-export.ts +135 -0
- package/src/runtime/thread/message-days.ts +120 -0
- package/src/runtime/thread/message-processor.ts +93 -0
- package/src/runtime/thread/task-utils.ts +11 -0
- package/src/runtime/thread/thought-utils.ts +752 -0
- package/src/runtime/thread/thread-history.ts +139 -0
- package/src/runtime/thread/timeline.ts +202 -0
- package/src/runtime/thread/title-tags.ts +8 -0
- package/src/runtime/thread/tool-cards.ts +383 -0
- package/src/runtime/turn-failure.ts +108 -0
- package/src/runtime/types.ts +148 -0
- package/src/runtime/usage-limit-error.ts +44 -0
- package/src/runtime/use-agent-activity.ts +80 -0
- package/src/runtime/use-conversation-stream.ts +1427 -0
- package/src/runtime/use-conversation-thread.ts +556 -0
- package/src/runtime/use-start-conversation.ts +107 -0
- package/src/runtime/use-thread-history.ts +64 -0
- package/src/runtime/use-thread-search.ts +95 -0
- package/src/runtime/use-turn-edit.ts +99 -0
- package/src/tools.ts +2 -2
- package/src/types.ts +18 -47
- package/src/components/AliaChatMessageList.tsx +0 -532
- package/src/components/ThinkingBlock.tsx +0 -43
- package/src/hooks/useAliaChat.ts +0 -573
- package/src/lib/catalogue.ts +0 -236
- package/src/lib/chat-stream.ts +0 -655
- package/src/lib/chat-transport.ts +0 -98
- package/src/lib/delegation.ts +0 -34
- package/src/lib/work-log-copy.ts +0 -61
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { createContext, type ReactNode, useContext, useMemo } from 'react';
|
|
2
|
+
import { ALIA_API_URL } from '../lib/origins';
|
|
3
|
+
import type { AgentRun, Message } from './types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Where a signed-out session keeps its conversations, per account. The host
|
|
7
|
+
* binds it to the signed-in account; unbound it reads nothing and writes
|
|
8
|
+
* nothing. `AccountScopedKey` in the Alia app is one.
|
|
9
|
+
*/
|
|
10
|
+
export interface OfflineConversationStore {
|
|
11
|
+
getItem(): Promise<string | null>;
|
|
12
|
+
setItem(value: string): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** An artifact a tool produced (a generated file, a canvas), for the host to show beside the thread. */
|
|
16
|
+
export interface AliaArtifact {
|
|
17
|
+
id: string;
|
|
18
|
+
type: string;
|
|
19
|
+
content: unknown;
|
|
20
|
+
title: string;
|
|
21
|
+
timestamp: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** The usage frame a stream ends with: the balance left and, sometimes, a spending warning. */
|
|
25
|
+
export interface AliaUsageFrame {
|
|
26
|
+
credits_remaining?: number;
|
|
27
|
+
credit_warning?: {
|
|
28
|
+
level?: string;
|
|
29
|
+
daysRemaining?: unknown;
|
|
30
|
+
todaySpend?: unknown;
|
|
31
|
+
avgDailySpend?: unknown;
|
|
32
|
+
currentModelMultiplier?: unknown;
|
|
33
|
+
};
|
|
34
|
+
[key: string]: unknown;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** What the request carries that the host's own controls decide, read at send time. */
|
|
38
|
+
export interface AliaTurnRequest {
|
|
39
|
+
/** Only `false` is sent: `true` is the server's default. */
|
|
40
|
+
webSearch?: boolean;
|
|
41
|
+
deepResearch?: boolean;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Why the thread asks its host to show the thought panel. */
|
|
45
|
+
export type ThoughtOpening =
|
|
46
|
+
/** The reader pressed a turn's "worked for" line or a sources row. */
|
|
47
|
+
| 'pressed'
|
|
48
|
+
/** A running turn began using tools; offered only while the host has nothing else open. */
|
|
49
|
+
| 'automatic';
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* How the person speaks and likes to be spoken to: read-aloud, dictation and calls all use it.
|
|
53
|
+
* Each is the server's or the platform's own default when absent.
|
|
54
|
+
*/
|
|
55
|
+
export interface SpeechPreferences {
|
|
56
|
+
voice?: 'male' | 'female';
|
|
57
|
+
tone?: 'brief' | 'chill' | 'default';
|
|
58
|
+
/** The language spoken and dictated, a BCP 47 tag; the platform's own when absent. */
|
|
59
|
+
language?: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Everything the conversation runtime needs from the app around it, as typed
|
|
64
|
+
* callbacks. Every member is optional: a host that omits one gets the plain
|
|
65
|
+
* behaviour (no navigation, no artifacts panel, no credits). The Alia app and
|
|
66
|
+
* the sheet mount the SAME runtime and differ only in what they put here.
|
|
67
|
+
*/
|
|
68
|
+
export interface AliaRuntimeHost {
|
|
69
|
+
/** Device facts sent as `X-Device-Info`, so the model's `getDeviceInfo` tool can answer. */
|
|
70
|
+
deviceInfo?: () => Promise<unknown>;
|
|
71
|
+
/** The modes the host's composer controls own; read when the turn is sent, not when it is built. */
|
|
72
|
+
turnRequest?: () => AliaTurnRequest;
|
|
73
|
+
/** A turn is about to be sent from the composer or a retry. */
|
|
74
|
+
onTurnStart?: () => void;
|
|
75
|
+
/** Real answer text just arrived (throttled): a haptic tick. */
|
|
76
|
+
onOutput?: () => void;
|
|
77
|
+
/** The stream's usage frame: credits left and the spending warning. */
|
|
78
|
+
onUsage?: (usage: AliaUsageFrame) => void;
|
|
79
|
+
/** A tool finished; `name` is the tool, `output` its structural result. */
|
|
80
|
+
onToolResult?: (result: {
|
|
81
|
+
toolCallId: string;
|
|
82
|
+
name: string | undefined;
|
|
83
|
+
output: unknown;
|
|
84
|
+
}) => void;
|
|
85
|
+
/** A tool produced something worth its own panel. */
|
|
86
|
+
onArtifact?: (artifact: AliaArtifact) => void;
|
|
87
|
+
/** What this turn put in the context window (`alia.context`), raw. */
|
|
88
|
+
onContext?: (conversationId: string | null, payload: unknown) => void;
|
|
89
|
+
/**
|
|
90
|
+
* An agent's feature gate refused what the person tried (`feature_entitlement_required`, or a
|
|
91
|
+
* locked row of the attach menu): `key` is the feature, e.g. `attachments.documents`. The host
|
|
92
|
+
* shows its own upsell; the person's words stay in the composer.
|
|
93
|
+
*/
|
|
94
|
+
onFeatureLocked?: (key: string) => void;
|
|
95
|
+
/** A delegated agent started a run of its own for this turn. */
|
|
96
|
+
onAgentTurn?: (turn: AgentRun & { conversationId: string | null }) => void;
|
|
97
|
+
/** The agent's row in the host's list, ahead of the server: your line, then her answer. */
|
|
98
|
+
onTurnPreview?: (agentId: string | null | undefined, text: string) => void;
|
|
99
|
+
/**
|
|
100
|
+
* Messages an agent writes into the open conversation by itself (a result, a check-in).
|
|
101
|
+
* Returns the unsubscribe.
|
|
102
|
+
*/
|
|
103
|
+
subscribeConversationMessages?: (
|
|
104
|
+
conversationId: string,
|
|
105
|
+
listener: (message: Message) => void,
|
|
106
|
+
) => () => void;
|
|
107
|
+
/**
|
|
108
|
+
* Show where the work of a turn is read — the host's right panel — now that the thread selected
|
|
109
|
+
* one (`useThoughtStore`; the panel is `ThoughtPanel`). Return `false` to decline an
|
|
110
|
+
* `automatic` opening because something else is open. A host without it has no thought panel:
|
|
111
|
+
* the thread draws the "worked for" line as text and never opens one.
|
|
112
|
+
*/
|
|
113
|
+
showThought?: (opening: ThoughtOpening) => boolean;
|
|
114
|
+
/** A scheduled-task card in the thread was pressed: show that task. Omitted, the card is not pressable. */
|
|
115
|
+
openAutomation?: (automationId: string) => void;
|
|
116
|
+
/** The URL of a site's cached icon for the work log's sources, or nothing for Bloom's quiet dot. */
|
|
117
|
+
faviconUrl?: (url: string) => string | null | undefined;
|
|
118
|
+
/** The runtime created or chose a conversation: show it. Omitted, the host shows nothing new. */
|
|
119
|
+
openConversation?: (conversationId: string) => void;
|
|
120
|
+
/** The open conversation is gone (deleted elsewhere, or a first send failed): leave it. */
|
|
121
|
+
closeConversation?: () => void;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface AliaRuntimeConfig {
|
|
125
|
+
/** Alia's API origin. Every route the SDK calls hangs off it, under `/v1` (`routes.ts`). */
|
|
126
|
+
apiUrl: string;
|
|
127
|
+
/** The offline copy of the conversations, when the host keeps one. */
|
|
128
|
+
offline: OfflineConversationStore | null;
|
|
129
|
+
/**
|
|
130
|
+
* The `fetch` a turn is streamed with. React Native's own cannot stream a
|
|
131
|
+
* body; Expo's (`expo/fetch`) can. Omitted, the platform's.
|
|
132
|
+
*/
|
|
133
|
+
streamFetch: typeof fetch | undefined;
|
|
134
|
+
/** How read-aloud, dictation and calls speak; omitted, the server's and the platform's defaults. */
|
|
135
|
+
speech: SpeechPreferences;
|
|
136
|
+
host: AliaRuntimeHost;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export interface AliaRuntimeProviderProps extends Partial<Omit<AliaRuntimeConfig, 'host'>> {
|
|
140
|
+
host?: AliaRuntimeHost;
|
|
141
|
+
children: ReactNode;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const DEFAULT_CONFIG: AliaRuntimeConfig = {
|
|
145
|
+
apiUrl: ALIA_API_URL,
|
|
146
|
+
offline: null,
|
|
147
|
+
streamFetch: undefined,
|
|
148
|
+
speech: {},
|
|
149
|
+
host: {},
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const AliaRuntimeContext = createContext<AliaRuntimeConfig>(DEFAULT_CONFIG);
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Configure the conversation runtime for everything below. Providers nest and
|
|
156
|
+
* merge: what a nearer one leaves out, the outer one (or the default) answers.
|
|
157
|
+
* The sheet and the screen mount one from their own props; the Alia app mounts
|
|
158
|
+
* one above its routes, so its sidebar and its conversation read the same
|
|
159
|
+
* conversations through the same hooks.
|
|
160
|
+
*/
|
|
161
|
+
export function AliaRuntimeProvider({
|
|
162
|
+
apiUrl,
|
|
163
|
+
offline,
|
|
164
|
+
streamFetch,
|
|
165
|
+
speech,
|
|
166
|
+
host,
|
|
167
|
+
children,
|
|
168
|
+
}: AliaRuntimeProviderProps) {
|
|
169
|
+
const parent = useContext(AliaRuntimeContext);
|
|
170
|
+
const value = useMemo<AliaRuntimeConfig>(() => {
|
|
171
|
+
const nextApiUrl = apiUrl ?? parent.apiUrl;
|
|
172
|
+
return {
|
|
173
|
+
apiUrl: nextApiUrl,
|
|
174
|
+
offline: offline === undefined ? parent.offline : offline,
|
|
175
|
+
streamFetch: streamFetch ?? parent.streamFetch,
|
|
176
|
+
speech: speech ?? parent.speech,
|
|
177
|
+
host: host === undefined ? parent.host : { ...parent.host, ...host },
|
|
178
|
+
};
|
|
179
|
+
}, [apiUrl, offline, streamFetch, speech, host, parent]);
|
|
180
|
+
return <AliaRuntimeContext.Provider value={value}>{children}</AliaRuntimeContext.Provider>;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** The runtime's configuration: the nearest provider's, or the defaults. */
|
|
184
|
+
export function useAliaRuntime(): AliaRuntimeConfig {
|
|
185
|
+
return useContext(AliaRuntimeContext);
|
|
186
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { create } from 'zustand';
|
|
2
|
+
import type { AliaAttachment } from '../types';
|
|
3
|
+
import type { MessageContent } from './types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A first message queued for a conversation that was just created. `content` is
|
|
7
|
+
* what gets sent; `text` and `attachments` are the raw composer state, kept so a
|
|
8
|
+
* failed send can hand them back to the input.
|
|
9
|
+
*/
|
|
10
|
+
export interface PendingInitialMessage {
|
|
11
|
+
/** The conversation the message was queued for; only its thread sends it. */
|
|
12
|
+
conversationId: string;
|
|
13
|
+
content: MessageContent;
|
|
14
|
+
text: string;
|
|
15
|
+
attachments: AliaAttachment[];
|
|
16
|
+
mcpServerId: string | null;
|
|
17
|
+
/** The skills chosen for that message, carried across the screen hand-off. */
|
|
18
|
+
skillNames: string[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface ConversationStoreState {
|
|
22
|
+
/**
|
|
23
|
+
* The first message of a conversation that was created a moment ago. The
|
|
24
|
+
* conversation opens (a route, a sheet) and the message is sent from there,
|
|
25
|
+
* so the thread the person lands on is the one being answered.
|
|
26
|
+
*/
|
|
27
|
+
pendingInitialMessage: PendingInitialMessage | null;
|
|
28
|
+
setPendingInitialMessage: (message: PendingInitialMessage) => void;
|
|
29
|
+
clearPendingInitialMessage: () => void;
|
|
30
|
+
|
|
31
|
+
/** The conversation a turn is streaming into right now, for a list to show a spinner on its row. */
|
|
32
|
+
streamingConversationId: string | null;
|
|
33
|
+
setStreamingConversationId: (id: string | null) => void;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Conversation state that outlives one open screen and is read from several:
|
|
38
|
+
* the hand-off of a first message, and which row is streaming. Shared by every
|
|
39
|
+
* surface that mounts the runtime, so a sidebar beside a thread reads what the
|
|
40
|
+
* thread is doing.
|
|
41
|
+
*/
|
|
42
|
+
export const useConversationStore = create<ConversationStoreState>((set) => ({
|
|
43
|
+
pendingInitialMessage: null,
|
|
44
|
+
setPendingInitialMessage: (message) => set({ pendingInitialMessage: message }),
|
|
45
|
+
clearPendingInitialMessage: () => set({ pendingInitialMessage: null }),
|
|
46
|
+
|
|
47
|
+
streamingConversationId: null,
|
|
48
|
+
setStreamingConversationId: (id) => set({ streamingConversationId: id }),
|
|
49
|
+
}));
|