@kognitivedev/ui 0.2.11

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 (258) hide show
  1. package/.turbo/turbo-build.log +2 -0
  2. package/CHANGELOG.md +19 -0
  3. package/README.md +264 -0
  4. package/dist/__tests__/context-provider.test.d.ts +1 -0
  5. package/dist/__tests__/context-provider.test.js +38 -0
  6. package/dist/__tests__/event-emitter.test.d.ts +1 -0
  7. package/dist/__tests__/event-emitter.test.js +62 -0
  8. package/dist/__tests__/keyboard-shortcuts.test.d.ts +1 -0
  9. package/dist/__tests__/keyboard-shortcuts.test.js +36 -0
  10. package/dist/__tests__/kognitive-runtime.test.d.ts +1 -0
  11. package/dist/__tests__/kognitive-runtime.test.js +58 -0
  12. package/dist/__tests__/kognitive-transport.test.d.ts +1 -0
  13. package/dist/__tests__/kognitive-transport.test.js +96 -0
  14. package/dist/__tests__/make-tool-ui.test.d.ts +1 -0
  15. package/dist/__tests__/make-tool-ui.test.js +50 -0
  16. package/dist/__tests__/message-helpers.test.d.ts +1 -0
  17. package/dist/__tests__/message-helpers.test.js +80 -0
  18. package/dist/__tests__/thread-manager.test.d.ts +1 -0
  19. package/dist/__tests__/thread-manager.test.js +84 -0
  20. package/dist/__tests__/tool-ui-registry.test.d.ts +1 -0
  21. package/dist/__tests__/tool-ui-registry.test.js +68 -0
  22. package/dist/__tests__/toolkit.test.d.ts +1 -0
  23. package/dist/__tests__/toolkit.test.js +33 -0
  24. package/dist/components/attachment-preview.d.ts +8 -0
  25. package/dist/components/attachment-preview.js +10 -0
  26. package/dist/components/composer.d.ts +6 -0
  27. package/dist/components/composer.js +10 -0
  28. package/dist/components/error-banner.d.ts +6 -0
  29. package/dist/components/error-banner.js +8 -0
  30. package/dist/components/markdown-content.d.ts +13 -0
  31. package/dist/components/markdown-content.js +31 -0
  32. package/dist/components/message.d.ts +7 -0
  33. package/dist/components/message.js +28 -0
  34. package/dist/components/status-indicator.d.ts +6 -0
  35. package/dist/components/status-indicator.js +16 -0
  36. package/dist/components/suggestions.d.ts +4 -0
  37. package/dist/components/suggestions.js +12 -0
  38. package/dist/components/thread-list.d.ts +4 -0
  39. package/dist/components/thread-list.js +20 -0
  40. package/dist/components/thread.d.ts +15 -0
  41. package/dist/components/thread.js +19 -0
  42. package/dist/components/tool-approval.d.ts +7 -0
  43. package/dist/components/tool-approval.js +12 -0
  44. package/dist/components/tool-invocation.d.ts +5 -0
  45. package/dist/components/tool-invocation.js +33 -0
  46. package/dist/context/kognitive-context.d.ts +2 -0
  47. package/dist/context/kognitive-context.js +6 -0
  48. package/dist/context/types.d.ts +44 -0
  49. package/dist/context/types.js +2 -0
  50. package/dist/context/use-kognitive.d.ts +1 -0
  51. package/dist/context/use-kognitive.js +7 -0
  52. package/dist/hooks/use-auto-scroll.d.ts +2 -0
  53. package/dist/hooks/use-auto-scroll.js +18 -0
  54. package/dist/hooks/use-copy-to-clipboard.d.ts +4 -0
  55. package/dist/hooks/use-copy-to-clipboard.js +13 -0
  56. package/dist/hooks/use-keyboard-shortcuts.d.ts +8 -0
  57. package/dist/hooks/use-keyboard-shortcuts.js +24 -0
  58. package/dist/hooks/use-kognitive-chat.d.ts +38 -0
  59. package/dist/hooks/use-kognitive-chat.js +35 -0
  60. package/dist/hooks/use-kognitive-event.d.ts +12 -0
  61. package/dist/hooks/use-kognitive-event.js +47 -0
  62. package/dist/hooks/use-streaming-status.d.ts +2 -0
  63. package/dist/hooks/use-streaming-status.js +8 -0
  64. package/dist/hooks/use-thread-manager.d.ts +20 -0
  65. package/dist/hooks/use-thread-manager.js +83 -0
  66. package/dist/index.d.ts +41 -0
  67. package/dist/index.js +92 -0
  68. package/dist/kognitive-ui.d.ts +48 -0
  69. package/dist/kognitive-ui.js +130 -0
  70. package/dist/primitives/action-bar/action-bar-copy.d.ts +6 -0
  71. package/dist/primitives/action-bar/action-bar-copy.js +16 -0
  72. package/dist/primitives/action-bar/action-bar-edit.d.ts +6 -0
  73. package/dist/primitives/action-bar/action-bar-edit.js +11 -0
  74. package/dist/primitives/action-bar/action-bar-feedback.d.ts +10 -0
  75. package/dist/primitives/action-bar/action-bar-feedback.js +30 -0
  76. package/dist/primitives/action-bar/action-bar-retry.d.ts +6 -0
  77. package/dist/primitives/action-bar/action-bar-retry.js +25 -0
  78. package/dist/primitives/action-bar/action-bar-root.d.ts +6 -0
  79. package/dist/primitives/action-bar/action-bar-root.js +7 -0
  80. package/dist/primitives/action-bar/action-bar-stop.d.ts +6 -0
  81. package/dist/primitives/action-bar/action-bar-stop.js +11 -0
  82. package/dist/primitives/action-bar/index.d.ts +14 -0
  83. package/dist/primitives/action-bar/index.js +17 -0
  84. package/dist/primitives/composer/composer-attachment-trigger.d.ts +7 -0
  85. package/dist/primitives/composer/composer-attachment-trigger.js +33 -0
  86. package/dist/primitives/composer/composer-attachments.d.ts +7 -0
  87. package/dist/primitives/composer/composer-attachments.js +16 -0
  88. package/dist/primitives/composer/composer-input.d.ts +6 -0
  89. package/dist/primitives/composer/composer-input.js +19 -0
  90. package/dist/primitives/composer/composer-root.d.ts +6 -0
  91. package/dist/primitives/composer/composer-root.js +91 -0
  92. package/dist/primitives/composer/composer-send.d.ts +6 -0
  93. package/dist/primitives/composer/composer-send.js +10 -0
  94. package/dist/primitives/composer/edit-composer-root.d.ts +11 -0
  95. package/dist/primitives/composer/edit-composer-root.js +24 -0
  96. package/dist/primitives/composer/index.d.ts +15 -0
  97. package/dist/primitives/composer/index.js +19 -0
  98. package/dist/primitives/composer/use-composer.d.ts +12 -0
  99. package/dist/primitives/composer/use-composer.js +6 -0
  100. package/dist/primitives/message/index.d.ts +9 -0
  101. package/dist/primitives/message/index.js +13 -0
  102. package/dist/primitives/message/message-content.d.ts +25 -0
  103. package/dist/primitives/message/message-content.js +70 -0
  104. package/dist/primitives/message/message-role.d.ts +6 -0
  105. package/dist/primitives/message/message-role.js +11 -0
  106. package/dist/primitives/message/message-root.d.ts +9 -0
  107. package/dist/primitives/message/message-root.js +38 -0
  108. package/dist/primitives/message/use-message.d.ts +10 -0
  109. package/dist/primitives/message/use-message.js +6 -0
  110. package/dist/primitives/thread/index.d.ts +17 -0
  111. package/dist/primitives/thread/index.js +21 -0
  112. package/dist/primitives/thread/thread-empty.d.ts +5 -0
  113. package/dist/primitives/thread/thread-empty.js +11 -0
  114. package/dist/primitives/thread/thread-error.d.ts +6 -0
  115. package/dist/primitives/thread/thread-error.js +11 -0
  116. package/dist/primitives/thread/thread-loading.d.ts +5 -0
  117. package/dist/primitives/thread/thread-loading.js +11 -0
  118. package/dist/primitives/thread/thread-messages.d.ts +6 -0
  119. package/dist/primitives/thread/thread-messages.js +9 -0
  120. package/dist/primitives/thread/thread-root.d.ts +6 -0
  121. package/dist/primitives/thread/thread-root.js +12 -0
  122. package/dist/primitives/thread/thread-scroll-to-bottom.d.ts +6 -0
  123. package/dist/primitives/thread/thread-scroll-to-bottom.js +14 -0
  124. package/dist/primitives/thread/thread-suggestions.d.ts +6 -0
  125. package/dist/primitives/thread/thread-suggestions.js +14 -0
  126. package/dist/primitives/thread/use-thread.d.ts +9 -0
  127. package/dist/primitives/thread/use-thread.js +6 -0
  128. package/dist/primitives/thread-list/index.d.ts +11 -0
  129. package/dist/primitives/thread-list/index.js +15 -0
  130. package/dist/primitives/thread-list/thread-list-item.d.ts +9 -0
  131. package/dist/primitives/thread-list/thread-list-item.js +13 -0
  132. package/dist/primitives/thread-list/thread-list-items.d.ts +6 -0
  133. package/dist/primitives/thread-list/thread-list-items.js +9 -0
  134. package/dist/primitives/thread-list/thread-list-new.d.ts +6 -0
  135. package/dist/primitives/thread-list/thread-list-new.js +13 -0
  136. package/dist/primitives/thread-list/thread-list-root.d.ts +6 -0
  137. package/dist/primitives/thread-list/thread-list-root.js +16 -0
  138. package/dist/primitives/thread-list/use-thread-list.d.ts +9 -0
  139. package/dist/primitives/thread-list/use-thread-list.js +6 -0
  140. package/dist/primitives/tool-ui/index.d.ts +7 -0
  141. package/dist/primitives/tool-ui/index.js +11 -0
  142. package/dist/primitives/tool-ui/tool-ui-fallback.d.ts +5 -0
  143. package/dist/primitives/tool-ui/tool-ui-fallback.js +20 -0
  144. package/dist/primitives/tool-ui/tool-ui-root.d.ts +5 -0
  145. package/dist/primitives/tool-ui/tool-ui-root.js +20 -0
  146. package/dist/primitives/tool-ui/use-tool-ui.d.ts +2 -0
  147. package/dist/primitives/tool-ui/use-tool-ui.js +8 -0
  148. package/dist/runtime/kognitive-runtime.d.ts +30 -0
  149. package/dist/runtime/kognitive-runtime.js +32 -0
  150. package/dist/runtime/kognitive-transport.d.ts +26 -0
  151. package/dist/runtime/kognitive-transport.js +42 -0
  152. package/dist/runtime/thread-manager.d.ts +17 -0
  153. package/dist/runtime/thread-manager.js +62 -0
  154. package/dist/runtime/types.d.ts +58 -0
  155. package/dist/runtime/types.js +2 -0
  156. package/dist/tool-ui/make-tool-ui.d.ts +59 -0
  157. package/dist/tool-ui/make-tool-ui.js +10 -0
  158. package/dist/tool-ui/registry.d.ts +9 -0
  159. package/dist/tool-ui/registry.js +26 -0
  160. package/dist/tool-ui/tool-ui-context.d.ts +2 -0
  161. package/dist/tool-ui/tool-ui-context.js +6 -0
  162. package/dist/tool-ui/toolkit.d.ts +31 -0
  163. package/dist/tool-ui/toolkit.js +33 -0
  164. package/dist/tool-ui/types.d.ts +19 -0
  165. package/dist/tool-ui/types.js +2 -0
  166. package/dist/utils/cn.d.ts +2 -0
  167. package/dist/utils/cn.js +8 -0
  168. package/dist/utils/create-context.d.ts +1 -0
  169. package/dist/utils/create-context.js +16 -0
  170. package/dist/utils/message-helpers.d.ts +6 -0
  171. package/dist/utils/message-helpers.js +46 -0
  172. package/package.json +56 -0
  173. package/src/__tests__/context-provider.test.ts +43 -0
  174. package/src/__tests__/event-emitter.test.ts +69 -0
  175. package/src/__tests__/keyboard-shortcuts.test.ts +55 -0
  176. package/src/__tests__/kognitive-runtime.test.ts +62 -0
  177. package/src/__tests__/kognitive-transport.test.ts +113 -0
  178. package/src/__tests__/make-tool-ui.test.ts +60 -0
  179. package/src/__tests__/message-helpers.test.ts +101 -0
  180. package/src/__tests__/thread-manager.test.ts +118 -0
  181. package/src/__tests__/tool-ui-registry.test.ts +80 -0
  182. package/src/__tests__/toolkit.test.ts +37 -0
  183. package/src/components/attachment-preview.tsx +46 -0
  184. package/src/components/composer.tsx +59 -0
  185. package/src/components/error-banner.tsx +33 -0
  186. package/src/components/markdown-content.tsx +64 -0
  187. package/src/components/message.tsx +145 -0
  188. package/src/components/status-indicator.tsx +26 -0
  189. package/src/components/suggestions.tsx +27 -0
  190. package/src/components/thread-list.tsx +69 -0
  191. package/src/components/thread.tsx +89 -0
  192. package/src/components/tool-approval.tsx +54 -0
  193. package/src/components/tool-invocation.tsx +94 -0
  194. package/src/context/kognitive-context.tsx +8 -0
  195. package/src/context/types.ts +43 -0
  196. package/src/context/use-kognitive.ts +5 -0
  197. package/src/hooks/use-auto-scroll.ts +19 -0
  198. package/src/hooks/use-copy-to-clipboard.ts +16 -0
  199. package/src/hooks/use-keyboard-shortcuts.ts +34 -0
  200. package/src/hooks/use-kognitive-chat.ts +73 -0
  201. package/src/hooks/use-kognitive-event.ts +56 -0
  202. package/src/hooks/use-streaming-status.ts +7 -0
  203. package/src/hooks/use-thread-manager.ts +114 -0
  204. package/src/index.ts +56 -0
  205. package/src/kognitive-ui.tsx +216 -0
  206. package/src/primitives/action-bar/action-bar-copy.tsx +30 -0
  207. package/src/primitives/action-bar/action-bar-edit.tsx +24 -0
  208. package/src/primitives/action-bar/action-bar-feedback.tsx +59 -0
  209. package/src/primitives/action-bar/action-bar-retry.tsx +38 -0
  210. package/src/primitives/action-bar/action-bar-root.tsx +14 -0
  211. package/src/primitives/action-bar/action-bar-stop.tsx +24 -0
  212. package/src/primitives/action-bar/index.ts +15 -0
  213. package/src/primitives/composer/composer-attachment-trigger.tsx +70 -0
  214. package/src/primitives/composer/composer-attachments.tsx +36 -0
  215. package/src/primitives/composer/composer-input.tsx +46 -0
  216. package/src/primitives/composer/composer-root.tsx +130 -0
  217. package/src/primitives/composer/composer-send.tsx +23 -0
  218. package/src/primitives/composer/edit-composer-root.tsx +52 -0
  219. package/src/primitives/composer/index.ts +17 -0
  220. package/src/primitives/composer/use-composer.ts +19 -0
  221. package/src/primitives/message/index.ts +11 -0
  222. package/src/primitives/message/message-content.tsx +117 -0
  223. package/src/primitives/message/message-role.tsx +13 -0
  224. package/src/primitives/message/message-root.tsx +64 -0
  225. package/src/primitives/message/use-message.ts +17 -0
  226. package/src/primitives/thread/index.ts +19 -0
  227. package/src/primitives/thread/thread-empty.tsx +12 -0
  228. package/src/primitives/thread/thread-error.tsx +18 -0
  229. package/src/primitives/thread/thread-loading.tsx +12 -0
  230. package/src/primitives/thread/thread-messages.tsx +12 -0
  231. package/src/primitives/thread/thread-root.tsx +28 -0
  232. package/src/primitives/thread/thread-scroll-to-bottom.tsx +26 -0
  233. package/src/primitives/thread/thread-suggestions.tsx +31 -0
  234. package/src/primitives/thread/use-thread.ts +16 -0
  235. package/src/primitives/thread-list/index.ts +13 -0
  236. package/src/primitives/thread-list/thread-list-item.tsx +37 -0
  237. package/src/primitives/thread-list/thread-list-items.tsx +19 -0
  238. package/src/primitives/thread-list/thread-list-new.tsx +26 -0
  239. package/src/primitives/thread-list/thread-list-root.tsx +29 -0
  240. package/src/primitives/thread-list/use-thread-list.ts +16 -0
  241. package/src/primitives/tool-ui/index.ts +9 -0
  242. package/src/primitives/tool-ui/tool-ui-fallback.tsx +63 -0
  243. package/src/primitives/tool-ui/tool-ui-root.tsx +26 -0
  244. package/src/primitives/tool-ui/use-tool-ui.ts +7 -0
  245. package/src/runtime/kognitive-runtime.ts +56 -0
  246. package/src/runtime/kognitive-transport.ts +56 -0
  247. package/src/runtime/thread-manager.ts +92 -0
  248. package/src/runtime/types.ts +63 -0
  249. package/src/tool-ui/make-tool-ui.ts +71 -0
  250. package/src/tool-ui/registry.ts +27 -0
  251. package/src/tool-ui/tool-ui-context.tsx +8 -0
  252. package/src/tool-ui/toolkit.ts +40 -0
  253. package/src/tool-ui/types.ts +29 -0
  254. package/src/utils/cn.ts +6 -0
  255. package/src/utils/create-context.ts +18 -0
  256. package/src/utils/message-helpers.ts +42 -0
  257. package/tsconfig.json +15 -0
  258. package/vitest.config.ts +8 -0
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const message_helpers_1 = require("../utils/message-helpers");
5
+ function makeMessage(parts, role = "assistant") {
6
+ return {
7
+ id: "msg-1",
8
+ role,
9
+ parts,
10
+ createdAt: new Date(),
11
+ };
12
+ }
13
+ (0, vitest_1.describe)("extractTextContent", () => {
14
+ (0, vitest_1.it)("returns string content as-is", () => {
15
+ (0, vitest_1.expect)((0, message_helpers_1.extractTextContent)("hello")).toBe("hello");
16
+ });
17
+ (0, vitest_1.it)("extracts text from an array of parts", () => {
18
+ (0, vitest_1.expect)((0, message_helpers_1.extractTextContent)([
19
+ { text: "hello" },
20
+ { text: "world" },
21
+ ])).toBe("hello\nworld");
22
+ });
23
+ (0, vitest_1.it)("returns empty string for non-string non-array input", () => {
24
+ (0, vitest_1.expect)((0, message_helpers_1.extractTextContent)(42)).toBe("");
25
+ (0, vitest_1.expect)((0, message_helpers_1.extractTextContent)(null)).toBe("");
26
+ (0, vitest_1.expect)((0, message_helpers_1.extractTextContent)(undefined)).toBe("");
27
+ });
28
+ (0, vitest_1.it)("skips non-text parts", () => {
29
+ (0, vitest_1.expect)((0, message_helpers_1.extractTextContent)([
30
+ { text: "keep" },
31
+ { type: "image" },
32
+ { text: "this" },
33
+ ])).toBe("keep\nthis");
34
+ });
35
+ });
36
+ (0, vitest_1.describe)("getMessageText", () => {
37
+ (0, vitest_1.it)("extracts text from message parts", () => {
38
+ const msg = makeMessage([
39
+ { type: "text", text: "Hello " },
40
+ { type: "text", text: "world" },
41
+ ]);
42
+ (0, vitest_1.expect)((0, message_helpers_1.getMessageText)(msg)).toBe("Hello \nworld");
43
+ });
44
+ (0, vitest_1.it)("skips non-text parts", () => {
45
+ const msg = makeMessage([
46
+ { type: "text", text: "before" },
47
+ { type: "text", text: "after" },
48
+ ]);
49
+ (0, vitest_1.expect)((0, message_helpers_1.getMessageText)(msg)).toBe("before\nafter");
50
+ });
51
+ (0, vitest_1.it)("returns empty string for message with no text parts", () => {
52
+ const msg = makeMessage([]);
53
+ (0, vitest_1.expect)((0, message_helpers_1.getMessageText)(msg)).toBe("");
54
+ });
55
+ });
56
+ (0, vitest_1.describe)("getMessagePreview", () => {
57
+ (0, vitest_1.it)("returns full text when under maxLength", () => {
58
+ const msg = makeMessage([{ type: "text", text: "Short" }]);
59
+ (0, vitest_1.expect)((0, message_helpers_1.getMessagePreview)(msg)).toBe("Short");
60
+ });
61
+ (0, vitest_1.it)("truncates and adds ellipsis when over maxLength", () => {
62
+ const longText = "A".repeat(100);
63
+ const msg = makeMessage([{ type: "text", text: longText }]);
64
+ const preview = (0, message_helpers_1.getMessagePreview)(msg, 50);
65
+ (0, vitest_1.expect)(preview.length).toBeLessThanOrEqual(53); // 50 + "..."
66
+ (0, vitest_1.expect)(preview.endsWith("...")).toBe(true);
67
+ });
68
+ });
69
+ (0, vitest_1.describe)("getToolInvocations", () => {
70
+ (0, vitest_1.it)("returns empty array when no tool invocations", () => {
71
+ const msg = makeMessage([{ type: "text", text: "hello" }]);
72
+ (0, vitest_1.expect)((0, message_helpers_1.getToolInvocations)(msg)).toHaveLength(0);
73
+ });
74
+ });
75
+ (0, vitest_1.describe)("hasToolInvocations", () => {
76
+ (0, vitest_1.it)("returns false when message has no tool invocations", () => {
77
+ const msg = makeMessage([{ type: "text", text: "hello" }]);
78
+ (0, vitest_1.expect)((0, message_helpers_1.hasToolInvocations)(msg)).toBe(false);
79
+ });
80
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const thread_manager_1 = require("../runtime/thread-manager");
5
+ (0, vitest_1.describe)("ThreadManager", () => {
6
+ const mockFetch = vitest_1.vi.fn();
7
+ (0, vitest_1.beforeEach)(() => {
8
+ vitest_1.vi.stubGlobal("fetch", mockFetch);
9
+ mockFetch.mockReset();
10
+ });
11
+ const manager = new thread_manager_1.ThreadManager({
12
+ baseUrl: "http://localhost:3001/api/agents/my-agent/threads",
13
+ });
14
+ (0, vitest_1.it)("list() fetches threads", async () => {
15
+ mockFetch.mockResolvedValueOnce({
16
+ ok: true,
17
+ json: async () => ({ threads: [{ sessionId: "s1", title: "Hello" }] }),
18
+ });
19
+ const threads = await manager.list();
20
+ (0, vitest_1.expect)(threads).toHaveLength(1);
21
+ (0, vitest_1.expect)(threads[0].sessionId).toBe("s1");
22
+ (0, vitest_1.expect)(mockFetch).toHaveBeenCalledWith("http://localhost:3001/api/agents/my-agent/threads", vitest_1.expect.objectContaining({ headers: vitest_1.expect.any(Object) }));
23
+ });
24
+ (0, vitest_1.it)("get() fetches a single thread", async () => {
25
+ mockFetch.mockResolvedValueOnce({
26
+ ok: true,
27
+ json: async () => ({
28
+ session: { id: "1", sessionId: "s1", messageCount: 5 },
29
+ events: [],
30
+ traces: [],
31
+ runs: [],
32
+ }),
33
+ });
34
+ const detail = await manager.get("s1");
35
+ (0, vitest_1.expect)(detail.session.sessionId).toBe("s1");
36
+ (0, vitest_1.expect)(mockFetch).toHaveBeenCalledWith("http://localhost:3001/api/agents/my-agent/threads/s1", vitest_1.expect.objectContaining({ headers: vitest_1.expect.any(Object) }));
37
+ });
38
+ (0, vitest_1.it)("create() POSTs to create a thread", async () => {
39
+ mockFetch.mockResolvedValueOnce({
40
+ ok: true,
41
+ json: async () => ({ thread: { sessionId: "new-s", title: "" } }),
42
+ });
43
+ const thread = await manager.create();
44
+ (0, vitest_1.expect)(thread.sessionId).toBe("new-s");
45
+ (0, vitest_1.expect)(mockFetch).toHaveBeenCalledWith("http://localhost:3001/api/agents/my-agent/threads", vitest_1.expect.objectContaining({ method: "POST" }));
46
+ });
47
+ (0, vitest_1.it)("fork() POSTs to fork a thread", async () => {
48
+ mockFetch.mockResolvedValueOnce({
49
+ ok: true,
50
+ json: async () => ({ thread: { sessionId: "forked-s", title: "" } }),
51
+ });
52
+ const thread = await manager.fork("s1");
53
+ (0, vitest_1.expect)(thread.sessionId).toBe("forked-s");
54
+ (0, vitest_1.expect)(mockFetch).toHaveBeenCalledWith("http://localhost:3001/api/agents/my-agent/threads/s1/fork", vitest_1.expect.objectContaining({ method: "POST" }));
55
+ });
56
+ (0, vitest_1.it)("interrupt() POSTs to interrupt a thread", async () => {
57
+ mockFetch.mockResolvedValueOnce({ ok: true, json: async () => ({}) });
58
+ await manager.interrupt("s1");
59
+ (0, vitest_1.expect)(mockFetch).toHaveBeenCalledWith("http://localhost:3001/api/agents/my-agent/threads/s1/interrupt", vitest_1.expect.objectContaining({ method: "POST" }));
60
+ });
61
+ (0, vitest_1.it)("throws on HTTP error", async () => {
62
+ mockFetch.mockResolvedValueOnce({
63
+ ok: false,
64
+ json: async () => ({ error: "Not found" }),
65
+ });
66
+ await (0, vitest_1.expect)(manager.get("bad-id")).rejects.toThrow("Not found");
67
+ });
68
+ (0, vitest_1.it)("includes custom headers", async () => {
69
+ const authManager = new thread_manager_1.ThreadManager({
70
+ baseUrl: "http://localhost:3001/api/threads",
71
+ headers: { Authorization: "Bearer secret" },
72
+ });
73
+ mockFetch.mockResolvedValueOnce({
74
+ ok: true,
75
+ json: async () => ({ threads: [] }),
76
+ });
77
+ await authManager.list();
78
+ (0, vitest_1.expect)(mockFetch).toHaveBeenCalledWith(vitest_1.expect.any(String), vitest_1.expect.objectContaining({
79
+ headers: vitest_1.expect.objectContaining({
80
+ Authorization: "Bearer secret",
81
+ }),
82
+ }));
83
+ });
84
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const registry_1 = require("../tool-ui/registry");
5
+ const make_tool_ui_1 = require("../tool-ui/make-tool-ui");
6
+ (0, vitest_1.describe)("ToolUIRegistry", () => {
7
+ (0, vitest_1.it)("registers and retrieves a tool UI component", () => {
8
+ const registry = new registry_1.ToolUIRegistry();
9
+ const render = () => null;
10
+ registry.register({ toolName: "test_tool", component: render });
11
+ (0, vitest_1.expect)(registry.has("test_tool")).toBe(true);
12
+ (0, vitest_1.expect)(registry.get("test_tool")).toBe(render);
13
+ });
14
+ (0, vitest_1.it)("returns undefined for unregistered tools", () => {
15
+ const registry = new registry_1.ToolUIRegistry();
16
+ (0, vitest_1.expect)(registry.has("nonexistent")).toBe(false);
17
+ (0, vitest_1.expect)(registry.get("nonexistent")).toBeUndefined();
18
+ });
19
+ (0, vitest_1.it)("registers multiple tools via registerAll", () => {
20
+ const registry = new registry_1.ToolUIRegistry();
21
+ const renderA = () => null;
22
+ const renderB = () => null;
23
+ registry.registerAll([
24
+ { toolName: "tool_a", component: renderA },
25
+ { toolName: "tool_b", component: renderB },
26
+ ]);
27
+ (0, vitest_1.expect)(registry.has("tool_a")).toBe(true);
28
+ (0, vitest_1.expect)(registry.has("tool_b")).toBe(true);
29
+ (0, vitest_1.expect)(registry.get("tool_a")).toBe(renderA);
30
+ (0, vitest_1.expect)(registry.get("tool_b")).toBe(renderB);
31
+ });
32
+ (0, vitest_1.it)("lists registered tool names", () => {
33
+ const registry = new registry_1.ToolUIRegistry();
34
+ registry.register({ toolName: "alpha", component: () => null });
35
+ registry.register({ toolName: "beta", component: () => null });
36
+ const names = registry.names();
37
+ (0, vitest_1.expect)(names).toContain("alpha");
38
+ (0, vitest_1.expect)(names).toContain("beta");
39
+ (0, vitest_1.expect)(names).toHaveLength(2);
40
+ });
41
+ (0, vitest_1.it)("overwrites a registration for the same tool name", () => {
42
+ const registry = new registry_1.ToolUIRegistry();
43
+ const first = () => null;
44
+ const second = () => null;
45
+ registry.register({ toolName: "tool", component: first });
46
+ (0, vitest_1.expect)(registry.get("tool")).toBe(first);
47
+ registry.register({ toolName: "tool", component: second });
48
+ (0, vitest_1.expect)(registry.get("tool")).toBe(second);
49
+ });
50
+ });
51
+ (0, vitest_1.describe)("makeToolUI", () => {
52
+ (0, vitest_1.it)("creates a registration from a tool object", () => {
53
+ const registration = (0, make_tool_ui_1.makeToolUI)({
54
+ tool: { id: "get_weather" },
55
+ render: () => null,
56
+ });
57
+ (0, vitest_1.expect)(registration.toolName).toBe("get_weather");
58
+ (0, vitest_1.expect)(typeof registration.component).toBe("function");
59
+ });
60
+ (0, vitest_1.it)("creates a registration from a tool name string", () => {
61
+ const registration = (0, make_tool_ui_1.makeToolUI)({
62
+ toolName: "search_db",
63
+ render: () => null,
64
+ });
65
+ (0, vitest_1.expect)(registration.toolName).toBe("search_db");
66
+ (0, vitest_1.expect)(typeof registration.component).toBe("function");
67
+ });
68
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const toolkit_1 = require("../tool-ui/toolkit");
5
+ const registry_1 = require("../tool-ui/registry");
6
+ (0, vitest_1.describe)("toolkit", () => {
7
+ (0, vitest_1.it)("creates registrations from a map of tool names to render functions", () => {
8
+ const registrations = (0, toolkit_1.toolkit)({
9
+ weather: { render: () => null },
10
+ search: { render: () => null },
11
+ });
12
+ (0, vitest_1.expect)(registrations).toHaveLength(2);
13
+ (0, vitest_1.expect)(registrations[0].toolName).toBe("weather");
14
+ (0, vitest_1.expect)(registrations[1].toolName).toBe("search");
15
+ });
16
+ (0, vitest_1.it)("creates an empty array from an empty map", () => {
17
+ const registrations = (0, toolkit_1.toolkit)({});
18
+ (0, vitest_1.expect)(registrations).toHaveLength(0);
19
+ });
20
+ (0, vitest_1.it)("integrates with ToolUIRegistry.registerAll", () => {
21
+ const registrations = (0, toolkit_1.toolkit)({
22
+ tool_a: { render: () => null },
23
+ tool_b: { render: () => null },
24
+ tool_c: { render: () => null },
25
+ });
26
+ const registry = new registry_1.ToolUIRegistry();
27
+ registry.registerAll(registrations);
28
+ (0, vitest_1.expect)(registry.has("tool_a")).toBe(true);
29
+ (0, vitest_1.expect)(registry.has("tool_b")).toBe(true);
30
+ (0, vitest_1.expect)(registry.has("tool_c")).toBe(true);
31
+ (0, vitest_1.expect)(registry.names()).toHaveLength(3);
32
+ });
33
+ });
@@ -0,0 +1,8 @@
1
+ export interface AttachmentPreviewProps {
2
+ url: string;
3
+ mediaType: string;
4
+ filename?: string;
5
+ className?: string;
6
+ onRemove?: () => void;
7
+ }
8
+ export declare function AttachmentPreview({ url, mediaType, filename, className, onRemove }: AttachmentPreviewProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AttachmentPreview = AttachmentPreview;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const cn_1 = require("../utils/cn");
6
+ function AttachmentPreview({ url, mediaType, filename, className, onRemove }) {
7
+ var _a, _b;
8
+ const isImage = mediaType.startsWith("image/");
9
+ return ((0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)("relative inline-flex items-center gap-2 rounded-lg border border-zinc-200 p-2 dark:border-zinc-700", className), "data-mime-type": mediaType, children: [isImage ? ((0, jsx_runtime_1.jsx)("img", { src: url, alt: filename !== null && filename !== void 0 ? filename : "Attachment", className: "h-16 w-16 rounded object-cover" })) : ((0, jsx_runtime_1.jsx)("div", { className: "flex h-16 w-16 items-center justify-center rounded bg-zinc-100 text-xs dark:bg-zinc-800", children: (_b = filename !== null && filename !== void 0 ? filename : (_a = mediaType.split("/")[1]) === null || _a === void 0 ? void 0 : _a.toUpperCase()) !== null && _b !== void 0 ? _b : "FILE" })), onRemove && ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: onRemove, className: "absolute -right-1.5 -top-1.5 flex h-5 w-5 items-center justify-center rounded-full bg-zinc-500 text-xs text-white hover:bg-zinc-600", "aria-label": "Remove attachment", children: "x" }))] }));
10
+ }
@@ -0,0 +1,6 @@
1
+ export interface ComposerProps {
2
+ className?: string;
3
+ placeholder?: string;
4
+ allowAttachments?: boolean;
5
+ }
6
+ export declare function Composer({ className, placeholder, allowAttachments, }: ComposerProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Composer = Composer;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const cn_1 = require("../utils/cn");
6
+ const composer_1 = require("../primitives/composer");
7
+ const attachment_preview_1 = require("./attachment-preview");
8
+ function Composer({ className, placeholder = "Send a message...", allowAttachments = false, }) {
9
+ return ((0, jsx_runtime_1.jsxs)(composer_1.ComposerPrimitive.Root, { className: (0, cn_1.cn)("border-t border-zinc-200 p-4 dark:border-zinc-700", className), children: [(0, jsx_runtime_1.jsx)(composer_1.ComposerPrimitive.Attachments, { className: "mb-2 flex flex-wrap gap-2", children: (file, index, remove) => ((0, jsx_runtime_1.jsx)(attachment_preview_1.AttachmentPreview, { url: file.url, mediaType: file.mediaType, filename: file.filename, onRemove: remove }, index)) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-end gap-2", children: [allowAttachments && ((0, jsx_runtime_1.jsx)(composer_1.ComposerPrimitive.AttachmentTrigger, { className: "flex h-10 w-10 items-center justify-center rounded-lg text-zinc-400 hover:bg-zinc-100 hover:text-zinc-600 dark:hover:bg-zinc-800 dark:hover:text-zinc-300", accept: "image/*,.pdf,.txt,.md,.json,.csv", children: "+" })), (0, jsx_runtime_1.jsx)(composer_1.ComposerPrimitive.Input, { placeholder: placeholder, className: "flex-1 resize-none rounded-lg border border-zinc-200 bg-white px-3 py-2 text-sm outline-none placeholder:text-zinc-400 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 dark:border-zinc-700 dark:bg-zinc-900 dark:placeholder:text-zinc-500 dark:focus:border-blue-400", rows: 1 }), (0, jsx_runtime_1.jsx)(composer_1.ComposerPrimitive.Send, { className: "flex h-10 items-center rounded-lg bg-blue-600 px-4 text-sm font-medium text-white hover:bg-blue-700 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-blue-500 dark:hover:bg-blue-600", children: "Send" })] })] }));
10
+ }
@@ -0,0 +1,6 @@
1
+ export interface ErrorBannerProps {
2
+ message: string;
3
+ className?: string;
4
+ onDismiss?: () => void;
5
+ }
6
+ export declare function ErrorBanner({ message, className, onDismiss }: ErrorBannerProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ErrorBanner = ErrorBanner;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const cn_1 = require("../utils/cn");
6
+ function ErrorBanner({ message, className, onDismiss }) {
7
+ return ((0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)("flex items-center gap-2 rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700 dark:border-red-800 dark:bg-red-950/30 dark:text-red-400", className), role: "alert", children: [(0, jsx_runtime_1.jsx)("span", { className: "shrink-0", children: "\u26A0" }), (0, jsx_runtime_1.jsx)("span", { className: "flex-1", children: message }), onDismiss && ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: onDismiss, className: "shrink-0 text-red-500 hover:text-red-700 dark:hover:text-red-300", "aria-label": "Dismiss error", children: "x" }))] }));
8
+ }
@@ -0,0 +1,13 @@
1
+ export interface MarkdownContentProps {
2
+ text: string;
3
+ className?: string;
4
+ }
5
+ /**
6
+ * Simple markdown-like text renderer.
7
+ *
8
+ * For full markdown support, override the Text component in MessagePrimitive.Content
9
+ * with your preferred markdown library (e.g., react-markdown).
10
+ *
11
+ * This component provides basic paragraph splitting and code block detection.
12
+ */
13
+ export declare function MarkdownContent({ text, className }: MarkdownContentProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MarkdownContent = MarkdownContent;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const cn_1 = require("../utils/cn");
6
+ /**
7
+ * Simple markdown-like text renderer.
8
+ *
9
+ * For full markdown support, override the Text component in MessagePrimitive.Content
10
+ * with your preferred markdown library (e.g., react-markdown).
11
+ *
12
+ * This component provides basic paragraph splitting and code block detection.
13
+ */
14
+ function MarkdownContent({ text, className }) {
15
+ const paragraphs = text.split("\n\n").filter(Boolean);
16
+ return ((0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)("space-y-2", className), children: paragraphs.map((paragraph, i) => {
17
+ // Code block
18
+ if (paragraph.startsWith("```")) {
19
+ const lines = paragraph.split("\n");
20
+ const lang = lines[0].replace("```", "").trim();
21
+ const code = lines.slice(1, lines[lines.length - 1] === "```" ? -1 : undefined).join("\n");
22
+ return ((0, jsx_runtime_1.jsx)("pre", { className: "overflow-x-auto rounded-lg bg-zinc-900 p-3 text-sm text-zinc-100", "data-language": lang || undefined, children: (0, jsx_runtime_1.jsx)("code", { children: code }) }, i));
23
+ }
24
+ // Inline code
25
+ const parts = paragraph.split(/(`[^`]+`)/g);
26
+ if (parts.length > 1) {
27
+ return ((0, jsx_runtime_1.jsx)("p", { children: parts.map((part, j) => part.startsWith("`") && part.endsWith("`") ? ((0, jsx_runtime_1.jsx)("code", { className: "rounded bg-zinc-100 px-1 py-0.5 text-sm dark:bg-zinc-800", children: part.slice(1, -1) }, j)) : ((0, jsx_runtime_1.jsx)("span", { children: part }, j))) }, i));
28
+ }
29
+ return (0, jsx_runtime_1.jsx)("p", { children: paragraph }, i);
30
+ }) }));
31
+ }
@@ -0,0 +1,7 @@
1
+ import type { UIMessage } from "ai";
2
+ export interface MessageProps {
3
+ message: UIMessage;
4
+ index?: number;
5
+ className?: string;
6
+ }
7
+ export declare function Message({ message, index, className }: MessageProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Message = Message;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const cn_1 = require("../utils/cn");
6
+ const message_1 = require("../primitives/message");
7
+ const action_bar_1 = require("../primitives/action-bar");
8
+ const composer_1 = require("../primitives/composer");
9
+ const markdown_content_1 = require("./markdown-content");
10
+ const tool_invocation_1 = require("./tool-invocation");
11
+ const use_message_1 = require("../primitives/message/use-message");
12
+ function MessageInner({ className }) {
13
+ const { message, isEditing } = (0, use_message_1.useMessage)();
14
+ const isUser = message.role === "user";
15
+ return ((0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)("flex gap-3 py-4", isUser ? "flex-row-reverse" : "flex-row", className), children: [(0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)("flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-sm", isUser
16
+ ? "bg-blue-100 text-blue-600 dark:bg-blue-900/30 dark:text-blue-400"
17
+ : "bg-zinc-100 text-zinc-600 dark:bg-zinc-800 dark:text-zinc-400"), children: isUser ? "U" : "A" }), (0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)("flex-1 space-y-1", isUser ? "text-right" : "text-left"), children: [isEditing ? ((0, jsx_runtime_1.jsx)(composer_1.ComposerPrimitive.EditRoot, { className: "space-y-2", children: ({ value, setValue, submit, cancel }) => ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("textarea", { value: value, onChange: (e) => setValue(e.target.value), className: "w-full resize-none rounded-lg border border-zinc-300 bg-white px-3 py-2 text-sm outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500 dark:border-zinc-600 dark:bg-zinc-900", rows: 3 }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", onClick: submit, className: "rounded-lg bg-blue-600 px-3 py-1 text-xs font-medium text-white hover:bg-blue-700", children: "Save & Send" }), (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: cancel, className: "rounded-lg border border-zinc-300 px-3 py-1 text-xs text-zinc-600 hover:bg-zinc-100 dark:border-zinc-600 dark:text-zinc-400 dark:hover:bg-zinc-800", children: "Cancel" })] })] })) })) : ((0, jsx_runtime_1.jsx)(message_1.MessagePrimitive.Content, { components: {
18
+ Text: ({ text }) => (0, jsx_runtime_1.jsx)(markdown_content_1.MarkdownContent, { text: text }),
19
+ ToolInvocation: (props) => (0, jsx_runtime_1.jsx)(tool_invocation_1.ToolInvocation, Object.assign({}, props)),
20
+ } })), !isEditing && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(message_1.MessagePrimitive.Role, { match: "user", children: (0, jsx_runtime_1.jsx)(action_bar_1.ActionBarPrimitive.Root, { className: "flex gap-1 pt-1", children: (0, jsx_runtime_1.jsx)(action_bar_1.ActionBarPrimitive.Edit, { className: "rounded px-2 py-1 text-xs text-zinc-400 hover:bg-zinc-100 hover:text-zinc-600 dark:hover:bg-zinc-800 dark:hover:text-zinc-300" }) }) }), (0, jsx_runtime_1.jsx)(message_1.MessagePrimitive.Role, { match: "assistant", children: (0, jsx_runtime_1.jsxs)(action_bar_1.ActionBarPrimitive.Root, { className: "flex gap-1 pt-1", children: [(0, jsx_runtime_1.jsx)(action_bar_1.ActionBarPrimitive.Copy, { className: "rounded px-2 py-1 text-xs text-zinc-400 hover:bg-zinc-100 hover:text-zinc-600 dark:hover:bg-zinc-800 dark:hover:text-zinc-300", children: (copied) => (copied ? "Copied!" : "Copy") }), (0, jsx_runtime_1.jsx)(action_bar_1.ActionBarPrimitive.Feedback, { className: "flex gap-1", children: ({ selected, onPositive, onNegative }) => ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("button", { type: "button", onClick: onPositive, className: (0, cn_1.cn)("rounded px-1.5 py-1 text-xs transition-colors", selected === "positive"
21
+ ? "bg-emerald-100 text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400"
22
+ : "text-zinc-400 hover:bg-zinc-100 hover:text-zinc-600 dark:hover:bg-zinc-800 dark:hover:text-zinc-300"), "aria-label": "Good response", children: "\uD83D\uDC4D" }), (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: onNegative, className: (0, cn_1.cn)("rounded px-1.5 py-1 text-xs transition-colors", selected === "negative"
23
+ ? "bg-red-100 text-red-600 dark:bg-red-900/30 dark:text-red-400"
24
+ : "text-zinc-400 hover:bg-zinc-100 hover:text-zinc-600 dark:hover:bg-zinc-800 dark:hover:text-zinc-300"), "aria-label": "Bad response", children: "\uD83D\uDC4E" })] })) })] }) })] }))] })] }));
25
+ }
26
+ function Message({ message, index, className }) {
27
+ return ((0, jsx_runtime_1.jsx)(message_1.MessagePrimitive.Root, { message: message, index: index, children: (0, jsx_runtime_1.jsx)(MessageInner, { className: className }) }));
28
+ }
@@ -0,0 +1,6 @@
1
+ import type { ChatStatus } from "ai";
2
+ export interface StatusIndicatorProps {
3
+ status: ChatStatus;
4
+ className?: string;
5
+ }
6
+ export declare function StatusIndicator({ status, className }: StatusIndicatorProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StatusIndicator = StatusIndicator;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const cn_1 = require("../utils/cn");
6
+ const statusConfig = {
7
+ ready: { color: "bg-emerald-500", label: "Ready" },
8
+ submitted: { color: "bg-amber-500", label: "Sending..." },
9
+ streaming: { color: "bg-amber-500 animate-pulse", label: "Responding..." },
10
+ error: { color: "bg-red-500", label: "Error" },
11
+ };
12
+ function StatusIndicator({ status, className }) {
13
+ var _a;
14
+ const config = (_a = statusConfig[status]) !== null && _a !== void 0 ? _a : statusConfig.ready;
15
+ return ((0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)("flex items-center gap-2 text-xs", className), "data-status": status, children: [(0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)("h-2 w-2 rounded-full", config.color) }), (0, jsx_runtime_1.jsx)("span", { children: config.label })] }));
16
+ }
@@ -0,0 +1,4 @@
1
+ export interface SuggestionsProps {
2
+ className?: string;
3
+ }
4
+ export declare function Suggestions({ className }: SuggestionsProps): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Suggestions = Suggestions;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const cn_1 = require("../utils/cn");
6
+ const kognitive_context_1 = require("../context/kognitive-context");
7
+ function Suggestions({ className }) {
8
+ const { suggestions, send, isStreaming } = (0, kognitive_context_1.useKognitiveContext)();
9
+ if (suggestions.length === 0 || isStreaming)
10
+ return null;
11
+ return ((0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)("flex flex-wrap gap-2 py-3", className), "data-suggestions": true, children: suggestions.map((suggestion, i) => ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: () => send(suggestion), className: "rounded-full border border-zinc-200 bg-white px-3 py-1.5 text-xs text-zinc-700 transition-colors hover:bg-zinc-100 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-300 dark:hover:bg-zinc-800", children: suggestion }, i))) }));
12
+ }
@@ -0,0 +1,4 @@
1
+ export interface ThreadListProps {
2
+ className?: string;
3
+ }
4
+ export declare function ThreadList({ className }: ThreadListProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ThreadList = ThreadList;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const cn_1 = require("../utils/cn");
6
+ const thread_list_1 = require("../primitives/thread-list");
7
+ const statusColors = {
8
+ running: "bg-amber-500",
9
+ completed: "bg-emerald-500",
10
+ interrupted: "bg-orange-500",
11
+ error: "bg-red-500",
12
+ };
13
+ function ThreadList({ className }) {
14
+ return ((0, jsx_runtime_1.jsxs)(thread_list_1.ThreadListPrimitive.Root, { className: (0, cn_1.cn)("flex h-full flex-col border-r border-zinc-200 bg-zinc-50 dark:border-zinc-700 dark:bg-zinc-900", className), children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between border-b border-zinc-200 px-4 py-3 dark:border-zinc-700", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-sm font-medium", children: "Conversations" }), (0, jsx_runtime_1.jsx)(thread_list_1.ThreadListPrimitive.New, { className: "rounded-lg bg-blue-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600", children: "New" })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 overflow-y-auto", children: (0, jsx_runtime_1.jsx)(thread_list_1.ThreadListPrimitive.Items, { children: (thread, isActive) => {
15
+ var _a;
16
+ return ((0, jsx_runtime_1.jsxs)(thread_list_1.ThreadListPrimitive.Item, { thread: thread, isActive: isActive, className: (0, cn_1.cn)("flex w-full flex-col gap-1 border-b border-zinc-100 px-4 py-3 text-left text-sm transition-colors dark:border-zinc-800", isActive
17
+ ? "bg-white dark:bg-zinc-800"
18
+ : "hover:bg-zinc-100 dark:hover:bg-zinc-800/50"), children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)("h-2 w-2 shrink-0 rounded-full", (_a = statusColors[thread.status]) !== null && _a !== void 0 ? _a : "bg-zinc-400") }), (0, jsx_runtime_1.jsx)("span", { className: "truncate font-medium", children: thread.title || thread.lastUserPreview || "New conversation" })] }), thread.lastAssistantPreview && ((0, jsx_runtime_1.jsx)("p", { className: "truncate text-xs text-zinc-500 dark:text-zinc-400", children: thread.lastAssistantPreview }))] }, thread.sessionId));
19
+ } }) })] }));
20
+ }
@@ -0,0 +1,15 @@
1
+ import React from "react";
2
+ import type { ComponentType } from "react";
3
+ export interface ThreadProps {
4
+ className?: string;
5
+ emptyState?: React.ReactNode;
6
+ allowAttachments?: boolean;
7
+ components?: {
8
+ Message?: ComponentType<{
9
+ message: any;
10
+ index: number;
11
+ }>;
12
+ Composer?: ComponentType;
13
+ };
14
+ }
15
+ export declare function Thread({ className, emptyState, allowAttachments, components, }: ThreadProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Thread = Thread;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const cn_1 = require("../utils/cn");
6
+ const thread_1 = require("../primitives/thread");
7
+ const message_1 = require("./message");
8
+ const composer_1 = require("./composer");
9
+ const status_indicator_1 = require("./status-indicator");
10
+ const error_banner_1 = require("./error-banner");
11
+ const suggestions_1 = require("./suggestions");
12
+ const kognitive_context_1 = require("../context/kognitive-context");
13
+ function Thread({ className, emptyState, allowAttachments = false, components, }) {
14
+ var _a, _b;
15
+ const { status } = (0, kognitive_context_1.useKognitiveContext)();
16
+ const MessageComponent = (_a = components === null || components === void 0 ? void 0 : components.Message) !== null && _a !== void 0 ? _a : message_1.Message;
17
+ const ComposerComponent = (_b = components === null || components === void 0 ? void 0 : components.Composer) !== null && _b !== void 0 ? _b : composer_1.Composer;
18
+ return ((0, jsx_runtime_1.jsxs)(thread_1.ThreadPrimitive.Root, { className: (0, cn_1.cn)("flex h-full flex-col", className), children: [(0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-between border-b border-zinc-200 px-4 py-2 dark:border-zinc-700", children: (0, jsx_runtime_1.jsx)(status_indicator_1.StatusIndicator, { status: status }) }), (0, jsx_runtime_1.jsx)(thread_1.ThreadPrimitive.Error, { className: "px-4 pt-3", children: (error) => (0, jsx_runtime_1.jsx)(error_banner_1.ErrorBanner, { message: error.message }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 overflow-y-auto px-4", "data-kognitive-thread-root": true, children: [(0, jsx_runtime_1.jsx)(thread_1.ThreadPrimitive.Empty, { children: emptyState !== null && emptyState !== void 0 ? emptyState : ((0, jsx_runtime_1.jsx)("div", { className: "flex h-full items-center justify-center text-zinc-400", children: (0, jsx_runtime_1.jsx)("p", { children: "Start a conversation" }) })) }), (0, jsx_runtime_1.jsx)(thread_1.ThreadPrimitive.Messages, { children: (message, index) => ((0, jsx_runtime_1.jsx)(MessageComponent, { message: message, index: index }, message.id)) }), (0, jsx_runtime_1.jsx)(thread_1.ThreadPrimitive.Loading, { children: (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-3 py-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-zinc-100 text-sm text-zinc-600 dark:bg-zinc-800 dark:text-zinc-400", children: "A" }), (0, jsx_runtime_1.jsx)("div", { className: "flex items-center", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-1", children: [(0, jsx_runtime_1.jsx)("div", { className: "h-2 w-2 animate-bounce rounded-full bg-zinc-400", style: { animationDelay: "0ms" } }), (0, jsx_runtime_1.jsx)("div", { className: "h-2 w-2 animate-bounce rounded-full bg-zinc-400", style: { animationDelay: "150ms" } }), (0, jsx_runtime_1.jsx)("div", { className: "h-2 w-2 animate-bounce rounded-full bg-zinc-400", style: { animationDelay: "300ms" } })] }) })] }) }), (0, jsx_runtime_1.jsx)(suggestions_1.Suggestions, {})] }), (components === null || components === void 0 ? void 0 : components.Composer) ? ((0, jsx_runtime_1.jsx)(ComposerComponent, {})) : ((0, jsx_runtime_1.jsx)(composer_1.Composer, { allowAttachments: allowAttachments }))] }));
19
+ }
@@ -0,0 +1,7 @@
1
+ export interface ToolApprovalProps {
2
+ toolCallId: string;
3
+ toolName: string;
4
+ input: unknown;
5
+ className?: string;
6
+ }
7
+ export declare function ToolApproval({ toolCallId, toolName, input, className }: ToolApprovalProps): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ToolApproval = ToolApproval;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const cn_1 = require("../utils/cn");
6
+ const kognitive_context_1 = require("../context/kognitive-context");
7
+ function ToolApproval({ toolCallId, toolName, input, className }) {
8
+ const { onToolApproval } = (0, kognitive_context_1.useKognitiveContext)();
9
+ if (!onToolApproval)
10
+ return null;
11
+ return ((0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)("my-2 rounded-lg border border-amber-200 bg-amber-50 p-4 dark:border-amber-800 dark:bg-amber-950/30", className), "data-tool-approval": toolCallId, children: [(0, jsx_runtime_1.jsxs)("div", { className: "mb-2 flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-amber-600", children: "\u26A0" }), (0, jsx_runtime_1.jsxs)("span", { className: "text-sm font-medium", children: [(0, jsx_runtime_1.jsx)("strong", { children: toolName }), " requires approval"] })] }), input !== undefined && input !== null && ((0, jsx_runtime_1.jsx)("pre", { className: "mb-3 overflow-auto rounded bg-amber-100/50 p-2 text-xs dark:bg-amber-900/20", children: JSON.stringify(input, null, 2) })), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", onClick: () => onToolApproval(toolCallId, true), className: "rounded-lg bg-emerald-600 px-4 py-1.5 text-sm font-medium text-white hover:bg-emerald-700", children: "Approve" }), (0, jsx_runtime_1.jsx)("button", { type: "button", onClick: () => onToolApproval(toolCallId, false), className: "rounded-lg border border-zinc-300 px-4 py-1.5 text-sm font-medium text-zinc-700 hover:bg-zinc-100 dark:border-zinc-600 dark:text-zinc-300 dark:hover:bg-zinc-800", children: "Reject" })] })] }));
12
+ }
@@ -0,0 +1,5 @@
1
+ import type { ToolUIRenderProps } from "../tool-ui/types";
2
+ export interface ToolInvocationProps extends ToolUIRenderProps {
3
+ className?: string;
4
+ }
5
+ export declare function ToolInvocation({ toolName, toolCallId, input, output, state, className, }: ToolInvocationProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ToolInvocation = ToolInvocation;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const cn_1 = require("../utils/cn");
7
+ const tool_approval_1 = require("./tool-approval");
8
+ function isComplete(state) {
9
+ return state === "output-available";
10
+ }
11
+ function stateLabel(state) {
12
+ switch (state) {
13
+ case "input-streaming": return "streaming...";
14
+ case "input-available": return "calling...";
15
+ case "approval-requested": return "awaiting approval";
16
+ case "approval-responded": return "approved";
17
+ case "output-available": return "completed";
18
+ case "error": return "error";
19
+ default: return state;
20
+ }
21
+ }
22
+ function ToolInvocation({ toolName, toolCallId, input, output, state, className, }) {
23
+ const [expanded, setExpanded] = (0, react_1.useState)(false);
24
+ const done = isComplete(state);
25
+ if (state === "approval-requested") {
26
+ return (0, jsx_runtime_1.jsx)(tool_approval_1.ToolApproval, { toolCallId: toolCallId, toolName: toolName, input: input, className: className });
27
+ }
28
+ return ((0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)("my-2 rounded-lg border border-zinc-200 dark:border-zinc-700", className), "data-tool": toolName, "data-tool-state": state, children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", onClick: () => setExpanded(!expanded), className: "flex w-full items-center gap-2 px-3 py-2 text-left text-sm hover:bg-zinc-50 dark:hover:bg-zinc-800/50", "aria-expanded": expanded, children: [(0, jsx_runtime_1.jsx)("span", { className: "text-amber-500", children: "\uD83D\uDD27" }), (0, jsx_runtime_1.jsx)("span", { className: "font-medium", children: toolName }), (0, jsx_runtime_1.jsx)("span", { className: (0, cn_1.cn)("ml-auto rounded-full px-2 py-0.5 text-xs", done
29
+ ? "bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400"
30
+ : state === "error"
31
+ ? "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400"
32
+ : "bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400"), children: stateLabel(state) }), (0, jsx_runtime_1.jsx)("span", { className: "text-zinc-400", children: expanded ? "\u25BC" : "\u25B6" })] }), expanded && ((0, jsx_runtime_1.jsxs)("div", { className: "border-t border-zinc-200 px-3 py-2 dark:border-zinc-700", children: [input !== undefined && ((0, jsx_runtime_1.jsxs)("div", { className: "mb-2", children: [(0, jsx_runtime_1.jsx)("div", { className: "mb-1 text-xs font-medium text-zinc-500", children: "Arguments" }), (0, jsx_runtime_1.jsx)("pre", { className: "overflow-auto rounded bg-zinc-50 p-2 text-xs dark:bg-zinc-800/50", children: JSON.stringify(input, null, 2) })] })), output !== undefined && ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { className: "mb-1 text-xs font-medium text-zinc-500", children: "Result" }), (0, jsx_runtime_1.jsx)("pre", { className: "overflow-auto rounded bg-zinc-50 p-2 text-xs dark:bg-zinc-800/50", children: JSON.stringify(output, null, 2) })] }))] }))] }));
33
+ }
@@ -0,0 +1,2 @@
1
+ import type { KognitiveContextValue } from "./types";
2
+ export declare const KognitiveContextProvider: import("react").Provider<KognitiveContextValue | null>, useKognitiveContext: () => KognitiveContextValue, KognitiveContext: import("react").Context<KognitiveContextValue | null>;