@fromsko/chat-ui 0.0.0-stage → 0.1.6

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 (248) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +100 -2
  3. package/lib/adapters/event-bus.d.ts +80 -0
  4. package/lib/adapters/event-bus.js +73 -0
  5. package/lib/adapters/index.d.ts +3 -0
  6. package/lib/adapters/index.js +3 -0
  7. package/lib/adapters/labels.d.ts +6 -0
  8. package/lib/adapters/labels.js +17 -0
  9. package/lib/adapters/stream-bridge.d.ts +9 -0
  10. package/lib/adapters/stream-bridge.js +7 -0
  11. package/lib/blocks/cards/AskCard.d.ts +8 -0
  12. package/lib/blocks/cards/AskCard.js +97 -0
  13. package/lib/blocks/cards/CompactionCard.d.ts +5 -0
  14. package/lib/blocks/cards/CompactionCard.js +5 -0
  15. package/lib/blocks/cards/ContextUsage.d.ts +14 -0
  16. package/lib/blocks/cards/ContextUsage.js +136 -0
  17. package/lib/blocks/cards/DisplayCard.d.ts +7 -0
  18. package/lib/blocks/cards/DisplayCard.js +27 -0
  19. package/lib/blocks/cards/MemoryPill.d.ts +5 -0
  20. package/lib/blocks/cards/MemoryPill.js +5 -0
  21. package/lib/blocks/cards/OutputCard.d.ts +5 -0
  22. package/lib/blocks/cards/OutputCard.js +13 -0
  23. package/lib/blocks/cards/PermissionCard.d.ts +21 -0
  24. package/lib/blocks/cards/PermissionCard.js +26 -0
  25. package/lib/blocks/cards/SpringCheck.d.ts +9 -0
  26. package/lib/blocks/cards/SpringCheck.js +17 -0
  27. package/lib/blocks/cards/TodoCard.d.ts +19 -0
  28. package/lib/blocks/cards/TodoCard.js +28 -0
  29. package/lib/blocks/cards/index.d.ts +10 -0
  30. package/lib/blocks/cards/index.js +10 -0
  31. package/lib/blocks/composer/Composer.d.ts +66 -0
  32. package/lib/blocks/composer/Composer.js +73 -0
  33. package/lib/blocks/composer/ComposerAttachments.d.ts +17 -0
  34. package/lib/blocks/composer/ComposerAttachments.js +10 -0
  35. package/lib/blocks/composer/ComposerGrip.d.ts +1 -0
  36. package/lib/blocks/composer/ComposerGrip.js +39 -0
  37. package/lib/blocks/composer/ComposerInput.d.ts +18 -0
  38. package/lib/blocks/composer/ComposerInput.js +60 -0
  39. package/lib/blocks/composer/ComposerMenus.d.ts +10 -0
  40. package/lib/blocks/composer/ComposerMenus.js +78 -0
  41. package/lib/blocks/composer/ComposerToolbar.d.ts +27 -0
  42. package/lib/blocks/composer/ComposerToolbar.js +16 -0
  43. package/lib/blocks/composer/MentionPicker.d.ts +13 -0
  44. package/lib/blocks/composer/MentionPicker.js +71 -0
  45. package/lib/blocks/composer/PromptPop.d.ts +7 -0
  46. package/lib/blocks/composer/PromptPop.js +40 -0
  47. package/lib/blocks/composer/QueuedPrompts.d.ts +14 -0
  48. package/lib/blocks/composer/QueuedPrompts.js +21 -0
  49. package/lib/blocks/composer/SlingButton.d.ts +10 -0
  50. package/lib/blocks/composer/SlingButton.js +112 -0
  51. package/lib/blocks/composer/index.d.ts +7 -0
  52. package/lib/blocks/composer/index.js +1 -0
  53. package/lib/blocks/conversation/ChatEmptyScene.d.ts +4 -0
  54. package/lib/blocks/conversation/ChatEmptyScene.js +21 -0
  55. package/lib/blocks/conversation/ChatHeader.d.ts +13 -0
  56. package/lib/blocks/conversation/ChatHeader.js +20 -0
  57. package/lib/blocks/conversation/ChatPane.d.ts +90 -0
  58. package/lib/blocks/conversation/ChatPane.js +60 -0
  59. package/lib/blocks/conversation/Conversation.d.ts +11 -0
  60. package/lib/blocks/conversation/Conversation.js +41 -0
  61. package/lib/blocks/conversation/LineSidebar.d.ts +14 -0
  62. package/lib/blocks/conversation/LineSidebar.js +42 -0
  63. package/lib/blocks/conversation/index.d.ts +5 -0
  64. package/lib/blocks/conversation/index.js +5 -0
  65. package/lib/blocks/index.d.ts +9 -0
  66. package/lib/blocks/index.js +9 -0
  67. package/lib/blocks/message/DayDivider.d.ts +10 -0
  68. package/lib/blocks/message/DayDivider.js +29 -0
  69. package/lib/blocks/message/DiffView.d.ts +5 -0
  70. package/lib/blocks/message/DiffView.js +18 -0
  71. package/lib/blocks/message/MermaidDiagram.d.ts +4 -0
  72. package/lib/blocks/message/MermaidDiagram.js +43 -0
  73. package/lib/blocks/message/Message.d.ts +17 -0
  74. package/lib/blocks/message/Message.js +45 -0
  75. package/lib/blocks/message/MessageActionBar.d.ts +18 -0
  76. package/lib/blocks/message/MessageActionBar.js +15 -0
  77. package/lib/blocks/message/MessageArtifacts.d.ts +13 -0
  78. package/lib/blocks/message/MessageArtifacts.js +9 -0
  79. package/lib/blocks/message/MessageAttachments.d.ts +5 -0
  80. package/lib/blocks/message/MessageAttachments.js +28 -0
  81. package/lib/blocks/message/MessageBubble.d.ts +11 -0
  82. package/lib/blocks/message/MessageBubble.js +31 -0
  83. package/lib/blocks/message/MessageRow.d.ts +20 -0
  84. package/lib/blocks/message/MessageRow.js +49 -0
  85. package/lib/blocks/message/MessageStream.d.ts +23 -0
  86. package/lib/blocks/message/MessageStream.js +80 -0
  87. package/lib/blocks/message/MessageTrace.d.ts +16 -0
  88. package/lib/blocks/message/MessageTrace.js +39 -0
  89. package/lib/blocks/message/PartView.d.ts +10 -0
  90. package/lib/blocks/message/PartView.js +29 -0
  91. package/lib/blocks/message/code-text.d.ts +15 -0
  92. package/lib/blocks/message/code-text.js +17 -0
  93. package/lib/blocks/message/index.d.ts +12 -0
  94. package/lib/blocks/message/index.js +12 -0
  95. package/lib/blocks/reasoning/Reasoning.d.ts +7 -0
  96. package/lib/blocks/reasoning/Reasoning.js +26 -0
  97. package/lib/blocks/reasoning/ReasoningBlock.d.ts +6 -0
  98. package/lib/blocks/reasoning/ReasoningBlock.js +5 -0
  99. package/lib/blocks/reasoning/index.d.ts +2 -0
  100. package/lib/blocks/reasoning/index.js +2 -0
  101. package/lib/blocks/selection/SelectionActions.d.ts +12 -0
  102. package/lib/blocks/selection/SelectionActions.js +29 -0
  103. package/lib/blocks/selection/SelectionBar.d.ts +10 -0
  104. package/lib/blocks/selection/SelectionBar.js +6 -0
  105. package/lib/blocks/selection/index.d.ts +2 -0
  106. package/lib/blocks/selection/index.js +2 -0
  107. package/lib/blocks/settings/DisplaySettingsPanel.d.ts +5 -0
  108. package/lib/blocks/settings/DisplaySettingsPanel.js +33 -0
  109. package/lib/blocks/settings/SquishSwitch.d.ts +8 -0
  110. package/lib/blocks/settings/SquishSwitch.js +21 -0
  111. package/lib/blocks/settings/index.d.ts +2 -0
  112. package/lib/blocks/settings/index.js +2 -0
  113. package/lib/blocks/status/LatticeLoader.d.ts +12 -0
  114. package/lib/blocks/status/LatticeLoader.js +22 -0
  115. package/lib/blocks/status/TypingIndicator.d.ts +5 -0
  116. package/lib/blocks/status/TypingIndicator.js +5 -0
  117. package/lib/blocks/status/index.d.ts +2 -0
  118. package/lib/blocks/status/index.js +2 -0
  119. package/lib/blocks/tool/SandboxCard.d.ts +5 -0
  120. package/lib/blocks/tool/SandboxCard.js +10 -0
  121. package/lib/blocks/tool/ToolCard.d.ts +10 -0
  122. package/lib/blocks/tool/ToolCard.js +32 -0
  123. package/lib/blocks/tool/ToolGroup.d.ts +6 -0
  124. package/lib/blocks/tool/ToolGroup.js +23 -0
  125. package/lib/blocks/tool/exec-envelope.d.ts +7 -0
  126. package/lib/blocks/tool/exec-envelope.js +43 -0
  127. package/lib/blocks/tool/index.d.ts +4 -0
  128. package/lib/blocks/tool/index.js +4 -0
  129. package/lib/domain/ask.d.ts +14 -0
  130. package/lib/domain/ask.js +50 -0
  131. package/lib/domain/attachments.d.ts +16 -0
  132. package/lib/domain/attachments.js +126 -0
  133. package/lib/domain/attribution.d.ts +4 -0
  134. package/lib/domain/attribution.js +11 -0
  135. package/lib/domain/composer-palette.d.ts +15 -0
  136. package/lib/domain/composer-palette.js +131 -0
  137. package/lib/domain/index.d.ts +12 -0
  138. package/lib/domain/index.js +12 -0
  139. package/lib/domain/mention.d.ts +17 -0
  140. package/lib/domain/mention.js +95 -0
  141. package/lib/domain/message-blocks.d.ts +29 -0
  142. package/lib/domain/message-blocks.js +63 -0
  143. package/lib/domain/message-menu.d.ts +4 -0
  144. package/lib/domain/message-menu.js +46 -0
  145. package/lib/domain/queue.d.ts +23 -0
  146. package/lib/domain/queue.js +52 -0
  147. package/lib/domain/reducer.d.ts +137 -0
  148. package/lib/domain/reducer.js +442 -0
  149. package/lib/domain/selection-actions.d.ts +13 -0
  150. package/lib/domain/selection-actions.js +56 -0
  151. package/lib/domain/selection-gates.d.ts +6 -0
  152. package/lib/domain/selection-gates.js +36 -0
  153. package/lib/domain/slash-commands.d.ts +16 -0
  154. package/lib/domain/slash-commands.js +142 -0
  155. package/lib/hooks/index.d.ts +8 -0
  156. package/lib/hooks/index.js +8 -0
  157. package/lib/hooks/useComposerPalette.d.ts +35 -0
  158. package/lib/hooks/useComposerPalette.js +120 -0
  159. package/lib/hooks/useComposerSubmit.d.ts +31 -0
  160. package/lib/hooks/useComposerSubmit.js +135 -0
  161. package/lib/hooks/useInputHistory.d.ts +14 -0
  162. package/lib/hooks/useInputHistory.js +52 -0
  163. package/lib/hooks/usePendingAsk.d.ts +11 -0
  164. package/lib/hooks/usePendingAsk.js +33 -0
  165. package/lib/hooks/usePendingPermissions.d.ts +10 -0
  166. package/lib/hooks/usePendingPermissions.js +26 -0
  167. package/lib/hooks/useQueuedPrompts.d.ts +12 -0
  168. package/lib/hooks/useQueuedPrompts.js +91 -0
  169. package/lib/hooks/useSelectionPop.d.ts +13 -0
  170. package/lib/hooks/useSelectionPop.js +130 -0
  171. package/lib/hooks/useStreamBridge.d.ts +1 -0
  172. package/lib/hooks/useStreamBridge.js +23 -0
  173. package/lib/index.d.ts +10 -0
  174. package/lib/index.js +10 -0
  175. package/lib/primitives/Badge.d.ts +7 -0
  176. package/lib/primitives/Badge.js +13 -0
  177. package/lib/primitives/Button.d.ts +9 -0
  178. package/lib/primitives/Button.js +21 -0
  179. package/lib/primitives/Collapsible.d.ts +12 -0
  180. package/lib/primitives/Collapsible.js +14 -0
  181. package/lib/primitives/Dialog.d.ts +10 -0
  182. package/lib/primitives/Dialog.js +19 -0
  183. package/lib/primitives/DropdownMenu.d.ts +28 -0
  184. package/lib/primitives/DropdownMenu.js +37 -0
  185. package/lib/primitives/Empty.d.ts +8 -0
  186. package/lib/primitives/Empty.js +6 -0
  187. package/lib/primitives/Input.d.ts +3 -0
  188. package/lib/primitives/Input.js +6 -0
  189. package/lib/primitives/Kbd.d.ts +2 -0
  190. package/lib/primitives/Kbd.js +5 -0
  191. package/lib/primitives/Popover.d.ts +15 -0
  192. package/lib/primitives/Popover.js +32 -0
  193. package/lib/primitives/ScrollArea.d.ts +5 -0
  194. package/lib/primitives/ScrollArea.js +5 -0
  195. package/lib/primitives/Separator.d.ts +5 -0
  196. package/lib/primitives/Separator.js +5 -0
  197. package/lib/primitives/Spinner.d.ts +5 -0
  198. package/lib/primitives/Spinner.js +5 -0
  199. package/lib/primitives/Textarea.d.ts +3 -0
  200. package/lib/primitives/Textarea.js +6 -0
  201. package/lib/primitives/Tooltip.d.ts +8 -0
  202. package/lib/primitives/Tooltip.js +7 -0
  203. package/lib/primitives/index.d.ts +14 -0
  204. package/lib/primitives/index.js +14 -0
  205. package/lib/reactbits/Motion.d.ts +24 -0
  206. package/lib/reactbits/Motion.js +52 -0
  207. package/lib/reactbits/index.d.ts +1 -0
  208. package/lib/reactbits/index.js +1 -0
  209. package/lib/stores/chat-store.d.ts +33 -0
  210. package/lib/stores/chat-store.js +93 -0
  211. package/lib/stores/display-store.d.ts +15 -0
  212. package/lib/stores/display-store.js +116 -0
  213. package/lib/stores/index.d.ts +3 -0
  214. package/lib/stores/index.js +3 -0
  215. package/lib/stores/theme-store.d.ts +8 -0
  216. package/lib/stores/theme-store.js +29 -0
  217. package/lib/tokens/index.d.ts +21 -0
  218. package/lib/tokens/index.js +66 -0
  219. package/lib/types/agent.d.ts +62 -0
  220. package/lib/types/agent.js +1 -0
  221. package/lib/types/callbacks.d.ts +55 -0
  222. package/lib/types/callbacks.js +1 -0
  223. package/lib/types/composer.d.ts +116 -0
  224. package/lib/types/composer.js +1 -0
  225. package/lib/types/conversation.d.ts +54 -0
  226. package/lib/types/conversation.js +1 -0
  227. package/lib/types/display.d.ts +25 -0
  228. package/lib/types/display.js +40 -0
  229. package/lib/types/index.d.ts +8 -0
  230. package/lib/types/index.js +8 -0
  231. package/lib/types/message.d.ts +100 -0
  232. package/lib/types/message.js +1 -0
  233. package/lib/types/selection.d.ts +60 -0
  234. package/lib/types/selection.js +1 -0
  235. package/lib/types/theme.d.ts +100 -0
  236. package/lib/types/theme.js +1 -0
  237. package/lib/utils/clipboard.d.ts +4 -0
  238. package/lib/utils/clipboard.js +41 -0
  239. package/lib/utils/cn.d.ts +2 -0
  240. package/lib/utils/cn.js +14 -0
  241. package/lib/utils/index.d.ts +3 -0
  242. package/lib/utils/index.js +3 -0
  243. package/lib/utils/storage.d.ts +11 -0
  244. package/lib/utils/storage.js +48 -0
  245. package/package.json +93 -4
  246. package/src/styles/blocks.css +2439 -0
  247. package/src/styles/index.css +3 -0
  248. package/src/tokens/theme.css +464 -0
@@ -0,0 +1,63 @@
1
+ export const TOOL_GROUP_MIN = 2;
2
+ export function isToolGroupPart(part) {
3
+ return part.kind === "tool" || part.kind === "sandbox";
4
+ }
5
+ export function toolGroupLabel(part) {
6
+ return part.kind === "tool" ? part.tool : part.title;
7
+ }
8
+ export function keyMessageParts(message) {
9
+ const counters = {};
10
+ return (message.parts ?? []).map((part) => {
11
+ const n = (counters[part.kind] = (counters[part.kind] ?? 0) + 1);
12
+ return { key: `${message.id}-${part.kind}-${n}`, part };
13
+ });
14
+ }
15
+ export function orderMessageBlocks(message, showBubble) {
16
+ const keyed = keyMessageParts(message);
17
+ const blocks = [];
18
+ let run = [];
19
+ const flush = () => {
20
+ if (run.length === 0)
21
+ return;
22
+ if (run.length >= TOOL_GROUP_MIN) {
23
+ blocks.push({
24
+ type: "tool-group",
25
+ key: `${message.id}-toolgroup-${run[0].key}`,
26
+ parts: run,
27
+ });
28
+ }
29
+ else {
30
+ for (const item of run) {
31
+ blocks.push({ type: "part", key: item.key, part: item.part });
32
+ }
33
+ }
34
+ run = [];
35
+ };
36
+ for (const item of keyed) {
37
+ if (isToolGroupPart(item.part)) {
38
+ run.push({ key: item.key, part: item.part });
39
+ continue;
40
+ }
41
+ flush();
42
+ blocks.push({ type: "part", key: item.key, part: item.part });
43
+ }
44
+ flush();
45
+ if (showBubble) {
46
+ blocks.push({ type: "text", key: `${message.id}-text` });
47
+ }
48
+ return blocks;
49
+ }
50
+ export function promoteMemoryFirst(blocks) {
51
+ const memory = [];
52
+ const rest = [];
53
+ for (const b of blocks) {
54
+ if (b.type === "part" && b.part.kind === "memory")
55
+ memory.push(b);
56
+ else
57
+ rest.push(b);
58
+ }
59
+ return [...memory, ...rest];
60
+ }
61
+ export function blockKind(block) {
62
+ return block.type === "part" ? block.part.kind : block.type;
63
+ }
@@ -0,0 +1,4 @@
1
+ import type { MessageMenuInput, MessageMenuItem } from "../types/selection";
2
+ export declare function messageTextOf(element: HTMLElement): string;
3
+ export declare function formatQuote(text: string): string;
4
+ export declare function messageMenuItems(input: MessageMenuInput): MessageMenuItem[];
@@ -0,0 +1,46 @@
1
+ export function messageTextOf(element) {
2
+ const bubble = element.matches('[data-cmp="ac/bubble"]')
3
+ ? element
4
+ : element.querySelector('[data-cmp="ac/bubble"]');
5
+ if (!bubble)
6
+ return "";
7
+ const text = bubble.innerText ?? bubble.textContent ?? "";
8
+ return text.trim();
9
+ }
10
+ export function formatQuote(text) {
11
+ return text
12
+ .split("\n")
13
+ .map((l) => l.trim())
14
+ .filter((l) => l.length > 0)
15
+ .slice(0, 3)
16
+ .map((l) => `> ${l}`)
17
+ .join("\n");
18
+ }
19
+ export function messageMenuItems(input) {
20
+ const { role, text, selection, id } = input;
21
+ const items = [];
22
+ const hasText = text.trim().length > 0;
23
+ const hasSelection = selection.trim().length > 0;
24
+ items.push({
25
+ id: "copy-text",
26
+ label: "复制消息",
27
+ disabled: !hasText,
28
+ ...(hasText ? {} : {}),
29
+ });
30
+ if (role === "assistant" && hasText) {
31
+ items.push({ id: "quote", label: "引用到输入框" });
32
+ }
33
+ items.push({ id: "multi-select", label: "多选" });
34
+ if (hasSelection) {
35
+ items.push({
36
+ id: "copy-selection",
37
+ label: "复制选中片段",
38
+ separatorBefore: true,
39
+ });
40
+ }
41
+ if (id) {
42
+ items.push({ id: "trace", label: "溯源", separatorBefore: true });
43
+ items.push({ id: "delete-message", label: "删除消息", danger: true });
44
+ }
45
+ return items;
46
+ }
@@ -0,0 +1,23 @@
1
+ import type { QueuedPrompt } from "../types/conversation";
2
+ import type { EnqueueOutcome, SubmitDecision } from "../types/composer";
3
+ export declare const MAX_QUEUED_PROMPTS = 8;
4
+ export declare const QUEUED_FULL_NOTICE = "\u5F85\u53D1\u961F\u5217\u5DF2\u6EE1\uFF088 \u6761\uFF09\uFF0C\u8BF7\u5148\u5904\u7406";
5
+ export declare function nextQueuedId(): string;
6
+ export declare function decideSubmit(streaming: boolean, full: boolean): SubmitDecision;
7
+ export declare function enqueuePrompt(items: readonly QueuedPrompt[], prompt: QueuedPrompt): QueuedPrompt[] | null;
8
+ export declare function removePrompt(items: readonly QueuedPrompt[], id: string): QueuedPrompt[];
9
+ export declare function movePrompt(items: readonly QueuedPrompt[], id: string, delta: -1 | 1): QueuedPrompt[];
10
+ export declare function takeHeadPrompt(items: readonly QueuedPrompt[]): {
11
+ rest: QueuedPrompt[];
12
+ taken: QueuedPrompt | null;
13
+ };
14
+ export declare function prependPrompt(items: readonly QueuedPrompt[], prompt: QueuedPrompt): QueuedPrompt[];
15
+ export interface QueueEdge {
16
+ conversationId: string;
17
+ status: "idle" | "loading" | "streaming" | "error";
18
+ }
19
+ export declare function flushEdge(prev: QueueEdge, next: QueueEdge, pending: readonly QueuedPrompt[]): {
20
+ rest: QueuedPrompt[];
21
+ taken: QueuedPrompt | null;
22
+ };
23
+ export type { EnqueueOutcome, SubmitDecision };
@@ -0,0 +1,52 @@
1
+ export const MAX_QUEUED_PROMPTS = 8;
2
+ export const QUEUED_FULL_NOTICE = `待发队列已满(${MAX_QUEUED_PROMPTS} 条),请先处理`;
3
+ let seq = 0;
4
+ export function nextQueuedId() {
5
+ seq += 1;
6
+ return `q-${Date.now()}-${seq}`;
7
+ }
8
+ export function decideSubmit(streaming, full) {
9
+ if (!streaming)
10
+ return "send";
11
+ return full ? "reject-full" : "enqueue";
12
+ }
13
+ export function enqueuePrompt(items, prompt) {
14
+ if (items.length >= MAX_QUEUED_PROMPTS)
15
+ return null;
16
+ return [...items, prompt];
17
+ }
18
+ export function removePrompt(items, id) {
19
+ return items.filter((p) => p.id !== id);
20
+ }
21
+ export function movePrompt(items, id, delta) {
22
+ const index = items.findIndex((p) => p.id === id);
23
+ if (index < 0)
24
+ return [...items];
25
+ const target = index + delta;
26
+ if (target < 0 || target >= items.length)
27
+ return [...items];
28
+ const next = [...items];
29
+ const [item] = next.splice(index, 1);
30
+ next.splice(target, 0, item);
31
+ return next;
32
+ }
33
+ export function takeHeadPrompt(items) {
34
+ if (items.length === 0)
35
+ return { rest: [], taken: null };
36
+ return { rest: items.slice(1), taken: items[0] };
37
+ }
38
+ export function prependPrompt(items, prompt) {
39
+ return [prompt, ...items];
40
+ }
41
+ export function flushEdge(prev, next, pending) {
42
+ if (pending.length === 0)
43
+ return { rest: [], taken: null };
44
+ const sameConversation = prev.conversationId === next.conversationId;
45
+ const settledSame = sameConversation &&
46
+ prev.status === "streaming" &&
47
+ next.status !== "streaming";
48
+ const switchedIdle = !sameConversation && next.status !== "streaming";
49
+ if (settledSame || switchedIdle)
50
+ return takeHeadPrompt(pending);
51
+ return { rest: [...pending], taken: null };
52
+ }
@@ -0,0 +1,137 @@
1
+ import type { Agent } from "../types/agent";
2
+ import type { Conversation, ConversationId, ConversationStatus } from "../types/conversation";
3
+ import type { ChatMessage } from "../types/message";
4
+ export interface ConversationState {
5
+ agents: Record<string, Agent>;
6
+ conversations: Conversation[];
7
+ messages: Record<ConversationId, ChatMessage[]>;
8
+ drafts: Record<ConversationId, string>;
9
+ activeId: ConversationId | null;
10
+ query: string;
11
+ persistError: string | null;
12
+ }
13
+ export type ConversationAction = {
14
+ type: "select";
15
+ id: ConversationId;
16
+ } | {
17
+ type: "query";
18
+ value: string;
19
+ } | {
20
+ type: "draft";
21
+ id: ConversationId;
22
+ value: string;
23
+ } | {
24
+ type: "append";
25
+ id: ConversationId;
26
+ message: ChatMessage;
27
+ } | {
28
+ type: "hydrateMessages";
29
+ id: ConversationId;
30
+ messages: ChatMessage[];
31
+ } | {
32
+ type: "deleteMessage";
33
+ id: ConversationId;
34
+ messageId: string;
35
+ } | {
36
+ type: "insertMessageAt";
37
+ id: ConversationId;
38
+ index: number;
39
+ message: ChatMessage;
40
+ } | {
41
+ type: "bindRequest";
42
+ requestId: string;
43
+ } | {
44
+ type: "streamDelta";
45
+ requestId: string;
46
+ text: string;
47
+ } | {
48
+ type: "streamEnd";
49
+ requestId: string;
50
+ outcome: "done" | "error";
51
+ error?: string;
52
+ } | {
53
+ type: "streamToolCall";
54
+ requestId: string;
55
+ toolCallId: string;
56
+ name: string;
57
+ args: unknown;
58
+ } | {
59
+ type: "streamToolResult";
60
+ requestId: string;
61
+ toolCallId: string;
62
+ result: string;
63
+ isError: boolean;
64
+ } | {
65
+ type: "streamReasoning";
66
+ requestId: string;
67
+ text: string;
68
+ } | {
69
+ type: "streamContextUsage";
70
+ requestId: string;
71
+ inputTokens: number;
72
+ outputTokens: number;
73
+ window: number;
74
+ } | {
75
+ type: "streamMemory";
76
+ requestId: string;
77
+ count: number;
78
+ excerpt: string;
79
+ } | {
80
+ type: "streamCompaction";
81
+ requestId: string | null;
82
+ beforeTokens: number;
83
+ afterTokens: number;
84
+ reason: string;
85
+ } | {
86
+ type: "streamDisplay";
87
+ requestId: string;
88
+ view: string;
89
+ title?: string;
90
+ payload?: unknown;
91
+ } | {
92
+ type: "streamOutput";
93
+ requestId: string;
94
+ outputKind: "text" | "file" | "link" | "json";
95
+ label?: string;
96
+ value: string;
97
+ } | {
98
+ type: "addConversation";
99
+ conversation: Conversation;
100
+ } | {
101
+ type: "dropConversation";
102
+ id: ConversationId;
103
+ } | {
104
+ type: "persistError";
105
+ value: string | null;
106
+ } | {
107
+ type: "togglePin";
108
+ id: ConversationId;
109
+ } | {
110
+ type: "toggleMute";
111
+ id: ConversationId;
112
+ } | {
113
+ type: "renameConversation";
114
+ id: ConversationId;
115
+ title: string;
116
+ } | {
117
+ type: "setMembers";
118
+ id: ConversationId;
119
+ memberIds: string[];
120
+ } | {
121
+ type: "setAutoRespond";
122
+ id: ConversationId;
123
+ value: boolean;
124
+ } | {
125
+ type: "createGroup";
126
+ members: string[];
127
+ title: string;
128
+ id: ConversationId;
129
+ } | {
130
+ type: "replaceAgents";
131
+ agents: Record<string, Agent>;
132
+ };
133
+ export declare function conversationReducer(state: ConversationState, action: ConversationAction): ConversationState;
134
+ export declare function createConversationState(partial?: Partial<ConversationState>): ConversationState;
135
+ export declare function isConversationStreaming(state: ConversationState, id: ConversationId): boolean;
136
+ export declare function inFlightRequestIds(state: ConversationState, id: ConversationId): string[];
137
+ export type { ConversationStatus };