@agentshouse/mdruntime 0.1.0-cedb03eaa48b6 → 0.1.0-cee9c8aa4cd86

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 (192) hide show
  1. package/AGENTS.md +86 -71
  2. package/README.md +9 -8
  3. package/dist/adapter.d.ts +44 -18
  4. package/dist/adapter.d.ts.map +1 -1
  5. package/dist/attached-model.d.ts +4 -1
  6. package/dist/attached-model.d.ts.map +1 -1
  7. package/dist/attached-model.js +13 -3
  8. package/dist/bootstrap.d.ts +13 -6
  9. package/dist/bootstrap.d.ts.map +1 -1
  10. package/dist/bootstrap.js +90 -61
  11. package/dist/chain.d.ts +11 -0
  12. package/dist/chain.d.ts.map +1 -0
  13. package/dist/chain.js +64 -0
  14. package/dist/change-set.d.ts +9 -16
  15. package/dist/change-set.d.ts.map +1 -1
  16. package/dist/change-set.js +11 -89
  17. package/dist/change.d.ts +31 -1
  18. package/dist/change.d.ts.map +1 -1
  19. package/dist/change.js +10 -1
  20. package/dist/chat/house.d.ts +25 -0
  21. package/dist/chat/house.d.ts.map +1 -0
  22. package/dist/chat/house.js +38 -0
  23. package/dist/chat/input.d.ts +3 -1
  24. package/dist/chat/input.d.ts.map +1 -1
  25. package/dist/chat/input.js +11 -18
  26. package/dist/chat/list.d.ts +2 -1
  27. package/dist/chat/list.d.ts.map +1 -1
  28. package/dist/chat/list.js +7 -3
  29. package/dist/chat/markdown.d.ts +1 -0
  30. package/dist/chat/markdown.d.ts.map +1 -1
  31. package/dist/chat/markdown.js +78 -20
  32. package/dist/chat/message.d.ts +1 -0
  33. package/dist/chat/message.d.ts.map +1 -1
  34. package/dist/chat/message.js +73 -11
  35. package/dist/chat/messages.d.ts +14 -1
  36. package/dist/chat/messages.d.ts.map +1 -1
  37. package/dist/chat/messages.js +79 -24
  38. package/dist/chat/name.d.ts +1 -0
  39. package/dist/chat/name.d.ts.map +1 -1
  40. package/dist/chat/name.js +1 -1
  41. package/dist/chat/opened.d.ts +1 -0
  42. package/dist/chat/opened.d.ts.map +1 -1
  43. package/dist/chat/opened.js +2 -0
  44. package/dist/chat/overlay.d.ts +1 -0
  45. package/dist/chat/overlay.d.ts.map +1 -1
  46. package/dist/chat/overlay.js +11 -5
  47. package/dist/chat/parts.d.ts +1 -0
  48. package/dist/chat/parts.d.ts.map +1 -1
  49. package/dist/chat/parts.js +3 -2
  50. package/dist/chat/pieces.d.ts +62 -0
  51. package/dist/chat/pieces.d.ts.map +1 -0
  52. package/dist/chat/pieces.js +1110 -0
  53. package/dist/chat/provider.d.ts +8 -1
  54. package/dist/chat/provider.d.ts.map +1 -1
  55. package/dist/chat/provider.js +88 -81
  56. package/dist/chat/ready.d.ts +5 -2
  57. package/dist/chat/ready.d.ts.map +1 -1
  58. package/dist/chat/ready.js +7 -5
  59. package/dist/chat/room-file.d.ts +8 -0
  60. package/dist/chat/room-file.d.ts.map +1 -0
  61. package/dist/chat/room-file.js +72 -0
  62. package/dist/chat/steady.d.ts +3 -0
  63. package/dist/chat/steady.d.ts.map +1 -0
  64. package/dist/chat/steady.js +26 -0
  65. package/dist/chat/style.d.ts.map +1 -1
  66. package/dist/chat/style.js +5 -0
  67. package/dist/chat.d.ts +3 -2
  68. package/dist/chat.d.ts.map +1 -1
  69. package/dist/chat.js +2 -2
  70. package/dist/client.d.ts +6 -1
  71. package/dist/client.d.ts.map +1 -1
  72. package/dist/client.js +29 -2
  73. package/dist/collection.d.ts +6 -19
  74. package/dist/collection.d.ts.map +1 -1
  75. package/dist/collection.js +30 -317
  76. package/dist/compile.d.ts +16 -0
  77. package/dist/compile.d.ts.map +1 -0
  78. package/dist/compile.js +718 -0
  79. package/dist/connection.d.ts +11 -5
  80. package/dist/connection.d.ts.map +1 -1
  81. package/dist/connection.js +1931 -706
  82. package/dist/conversation.d.ts +9 -3
  83. package/dist/conversation.d.ts.map +1 -1
  84. package/dist/conversation.js +85 -61
  85. package/dist/digest.d.ts +7 -0
  86. package/dist/digest.d.ts.map +1 -0
  87. package/dist/digest.js +113 -0
  88. package/dist/durability.d.ts +2 -1
  89. package/dist/durability.d.ts.map +1 -1
  90. package/dist/entry.d.ts +3 -1
  91. package/dist/entry.d.ts.map +1 -1
  92. package/dist/entry.js +18 -24
  93. package/dist/file.d.ts +2 -10
  94. package/dist/file.d.ts.map +1 -1
  95. package/dist/file.js +3 -120
  96. package/dist/fulltext.d.ts +27 -0
  97. package/dist/fulltext.d.ts.map +1 -0
  98. package/dist/fulltext.js +368 -0
  99. package/dist/host.d.ts +0 -1
  100. package/dist/host.d.ts.map +1 -1
  101. package/dist/host.js +10 -3
  102. package/dist/identity.d.ts +0 -1
  103. package/dist/identity.d.ts.map +1 -1
  104. package/dist/identity.js +0 -3
  105. package/dist/index.d.ts +8 -5
  106. package/dist/index.d.ts.map +1 -1
  107. package/dist/index.js +3 -0
  108. package/dist/live.d.ts +22 -0
  109. package/dist/live.d.ts.map +1 -0
  110. package/dist/live.js +123 -0
  111. package/dist/memory.d.ts +1 -0
  112. package/dist/memory.d.ts.map +1 -1
  113. package/dist/memory.js +22 -6
  114. package/dist/messages.d.ts +28 -0
  115. package/dist/messages.d.ts.map +1 -0
  116. package/dist/messages.js +90 -0
  117. package/dist/name.d.ts +4 -0
  118. package/dist/name.d.ts.map +1 -0
  119. package/dist/name.js +122 -0
  120. package/dist/observation.d.ts +12 -0
  121. package/dist/observation.d.ts.map +1 -1
  122. package/dist/observation.js +84 -0
  123. package/dist/opened.d.ts +22 -0
  124. package/dist/opened.d.ts.map +1 -0
  125. package/dist/opened.js +107 -0
  126. package/dist/outcome.d.ts +29 -4
  127. package/dist/outcome.d.ts.map +1 -1
  128. package/dist/outcome.js +25 -0
  129. package/dist/overlay.d.ts +2 -5
  130. package/dist/overlay.d.ts.map +1 -1
  131. package/dist/overlay.js +86 -171
  132. package/dist/query.d.ts +2 -1
  133. package/dist/query.d.ts.map +1 -1
  134. package/dist/query.js +1 -0
  135. package/dist/reach.d.ts +5 -1
  136. package/dist/reach.d.ts.map +1 -1
  137. package/dist/reach.js +158 -52
  138. package/dist/readiness.d.ts +3 -3
  139. package/dist/readiness.d.ts.map +1 -1
  140. package/dist/reads.js +1 -1
  141. package/dist/recovery.d.ts +2 -2
  142. package/dist/recovery.d.ts.map +1 -1
  143. package/dist/recovery.js +8 -7
  144. package/dist/refresh.d.ts +10 -13
  145. package/dist/refresh.d.ts.map +1 -1
  146. package/dist/refresh.js +74 -51
  147. package/dist/replica.d.ts +54 -36
  148. package/dist/replica.d.ts.map +1 -1
  149. package/dist/replica.js +277 -184
  150. package/dist/room-draft.d.ts +3 -1
  151. package/dist/room-draft.d.ts.map +1 -1
  152. package/dist/room-draft.js +29 -22
  153. package/dist/rows.d.ts +29 -31
  154. package/dist/rows.d.ts.map +1 -1
  155. package/dist/rows.js +113 -69
  156. package/dist/save.d.ts +50 -14
  157. package/dist/save.d.ts.map +1 -1
  158. package/dist/save.js +502 -178
  159. package/dist/search.d.ts +11 -43
  160. package/dist/search.d.ts.map +1 -1
  161. package/dist/search.js +0 -213
  162. package/dist/shared.d.ts +8 -3
  163. package/dist/shared.d.ts.map +1 -1
  164. package/dist/shared.js +129 -66
  165. package/dist/store.d.ts +79 -93
  166. package/dist/store.d.ts.map +1 -1
  167. package/dist/store.js +318 -687
  168. package/dist/stored.d.ts +138 -0
  169. package/dist/stored.d.ts.map +1 -0
  170. package/dist/stored.js +544 -0
  171. package/dist/tables.d.ts +332 -0
  172. package/dist/tables.d.ts.map +1 -0
  173. package/dist/tables.js +570 -0
  174. package/dist/turn.d.ts +4 -2
  175. package/dist/turn.d.ts.map +1 -1
  176. package/dist/turn.js +46 -22
  177. package/dist/validation.d.ts +30 -0
  178. package/dist/validation.d.ts.map +1 -0
  179. package/dist/validation.js +162 -0
  180. package/dist/windows.d.ts +2 -6
  181. package/dist/windows.d.ts.map +1 -1
  182. package/dist/windows.js +30 -34
  183. package/dist/wire.d.ts +16 -0
  184. package/dist/wire.d.ts.map +1 -1
  185. package/dist/wire.js +4 -0
  186. package/dist/words.d.ts +19 -0
  187. package/dist/words.d.ts.map +1 -0
  188. package/dist/words.js +150 -0
  189. package/package.json +10 -4
  190. package/dist/read-side.d.ts +0 -27
  191. package/dist/read-side.d.ts.map +0 -1
  192. package/dist/read-side.js +0 -824
@@ -3,6 +3,7 @@ import type { TurnContext } from '../adapter.js';
3
3
  import type { MdRuntimeClient } from '../client.js';
4
4
  import { type ChatDraft, type ConversationAgent, type ConversationEntry, type ConversationView } from '../conversation.js';
5
5
  import { type ChatOutcome } from './acts.js';
6
+ import type { ChatRequest } from './house.js';
6
7
  import { type ChatCommand, type ChatOption } from './process.js';
7
8
  import { type ChatLone, type ChatQuestion } from './questions.js';
8
9
  export type ChatOpened = {
@@ -21,6 +22,7 @@ export type ChatState = ChatOpened & {
21
22
  readonly conversations: readonly ConversationEntry[];
22
23
  readonly agents: readonly ConversationAgent[];
23
24
  readonly view: ConversationView | null;
25
+ readonly waiting: ChatRequest | null;
24
26
  readonly running: boolean;
25
27
  readonly questions: readonly ChatQuestion[];
26
28
  readonly lone: ChatLone | null;
@@ -32,13 +34,17 @@ export type ChatState = ChatOpened & {
32
34
  readonly again: (() => void) | null;
33
35
  };
34
36
  readonly acting: ChatActing;
37
+ readonly renewed: boolean;
35
38
  open(conversation: string): void;
36
39
  start(agent: string): void;
37
40
  send(draft: ChatDraft): void;
41
+ attach: ((files: readonly File[]) => Promise<boolean>) | null;
38
42
  answer(question: ChatQuestion, response: unknown): Promise<boolean>;
39
43
  choose(option: string, value: string): Promise<boolean>;
40
44
  stop(): Promise<boolean>;
41
45
  kill(): Promise<boolean>;
46
+ retry(message: string): Promise<boolean>;
47
+ renew(): Promise<boolean>;
42
48
  done(): Promise<boolean>;
43
49
  rename(name: string): Promise<boolean>;
44
50
  remove(): Promise<boolean>;
@@ -49,6 +55,7 @@ export type ChatProviderProps = {
49
55
  readonly client: MdRuntimeClient;
50
56
  readonly conversation?: string | null;
51
57
  readonly agent?: string | null;
58
+ readonly attachTo?: string | null;
52
59
  readonly onOpen?: (opened: ChatOpened) => void;
53
60
  readonly children?: ReactNode;
54
61
  };
@@ -58,6 +65,6 @@ type Scope = {
58
65
  };
59
66
  export declare function useChatScope(): Scope;
60
67
  export declare function useChat(): ChatState;
61
- export declare function ChatProvider({ client, conversation, agent, onOpen, children, }: ChatProviderProps): ReactElement;
68
+ export declare function ChatProvider({ client, conversation, agent, attachTo, onOpen, children, }: ChatProviderProps): ReactElement;
62
69
  export {};
63
70
  //# sourceMappingURL=provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/chat/provider.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/chat/provider.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { createContext, createElement, useCallback, useContext, useEffect, useMemo, useReducer, useRef, useState, useSyncExternalStore, } from 'react';
2
- import { AssistantRuntimeProvider, createMessageQueue, generateId, useExternalStoreRuntime, } from '@assistant-ui/react';
2
+ import { AssistantRuntimeProvider, createMessageQueue, useExternalStoreRuntime, } from '@assistant-ui/react';
3
3
  import { attempts } from '../attempt.js';
4
4
  import { newChat, } from '../conversation.js';
5
5
  import { expectedList } from '../expectation.js';
@@ -7,8 +7,9 @@ import { chatDraftRevision } from '../identity.js';
7
7
  import { useObserve } from '../react.js';
8
8
  import { accepted, answeredOf, outcomeOf, sender, unanswered, } from './acts.js';
9
9
  import { CHAT_WINDOW, useEarlier } from './earlier.js';
10
- import { askedBefore, chatMessages, contextOf } from './messages.js';
11
- import { conversationChanged, conversationGone, conversationListed, optionChosen, overlay, questionAnswered, sentMessage, } from './overlay.js';
10
+ import { askedBefore, chatMessages, contextOf, requestIn } from './messages.js';
11
+ import { useSteady } from './steady.js';
12
+ import { conversationChanged, conversationGone, conversationListed, deliveryRetried, optionChosen, overlay, questionAnswered, sentMessage, } from './overlay.js';
12
13
  import { commandIn, commandsOf, optionsOf } from './process.js';
13
14
  import { loneOf, questionsOf } from './questions.js';
14
15
  import { record, text } from './read.js';
@@ -18,7 +19,7 @@ function sharedOf(client) {
18
19
  const held = SHARED.get(client);
19
20
  if (held !== undefined)
20
21
  return held;
21
- const fresh = { overlay: overlay(), created: new Map(), sends: 0 };
22
+ const fresh = { overlay: overlay(), created: new Map(), renewed: new Set(), sends: 0 };
22
23
  SHARED.set(client, fresh);
23
24
  return fresh;
24
25
  }
@@ -90,46 +91,21 @@ function useActs(overlay, online) {
90
91
  }, [overlay, online, tried]);
91
92
  return { ...running, call, clear };
92
93
  }
93
- const ATTACHMENTS = {
94
- accept: '*',
95
- add: ({ file }) => Promise.resolve({
96
- id: generateId(),
97
- type: 'file',
98
- name: file.name,
99
- contentType: file.type,
100
- file,
101
- status: { type: 'requires-action', reason: 'composer-send' },
102
- }),
103
- send: (attachment) => Promise.resolve({ ...attachment, status: { type: 'complete' }, content: [] }),
104
- remove: () => Promise.resolve(),
105
- };
106
- function filesOf(attachments) {
107
- return attachments.flatMap((one) => one.file === undefined ? [] : [{ name: one.name, blob: one.file }]);
108
- }
109
- function fileOf(file) {
110
- return file.blob instanceof File && file.blob.name === file.name
111
- ? file.blob
112
- : new File([file.blob], file.name, { type: file.blob.type });
113
- }
94
+ const AS_IT_IS = (message) => message;
114
95
  function textOf(parts) {
115
96
  return parts.map((part) => (part.type === 'text' ? (part.text ?? '') : '')).join('');
116
97
  }
117
98
  function draftOf(message) {
118
- return { text: textOf(message.content), files: filesOf(message.attachments ?? []) };
99
+ return { text: textOf(message.content) };
100
+ }
101
+ function linkOf(path) {
102
+ return `[${path.slice(path.lastIndexOf('/') + 1)}](${path})`;
119
103
  }
120
104
  function appended(draft) {
121
105
  return {
122
106
  role: 'user',
123
107
  content: [{ type: 'text', text: draft.text }],
124
- attachments: draft.files.map((file) => ({
125
- id: generateId(),
126
- type: 'file',
127
- name: file.name,
128
- contentType: file.blob.type,
129
- file: fileOf(file),
130
- status: { type: 'complete' },
131
- content: [],
132
- })),
108
+ attachments: [],
133
109
  metadata: { custom: {} },
134
110
  createdAt: new Date(),
135
111
  parentId: null,
@@ -137,9 +113,6 @@ function appended(draft) {
137
113
  runConfig: undefined,
138
114
  };
139
115
  }
140
- function composed(state) {
141
- return JSON.stringify([state.text, state.attachments.map((one) => one.id)]);
142
- }
143
116
  const ChatContext = createContext(null);
144
117
  const ScopeContext = createContext(null);
145
118
  export function useChatScope() {
@@ -154,7 +127,7 @@ export function useChat() {
154
127
  throw new Error('useChat is called outside a ChatProvider');
155
128
  return chat;
156
129
  }
157
- export function ChatProvider({ client, conversation = null, agent = null, onOpen, children, }) {
130
+ export function ChatProvider({ client, conversation = null, agent = null, attachTo = null, onOpen, children, }) {
158
131
  const shared = sharedOf(client);
159
132
  const asked = JSON.stringify([conversation, agent]);
160
133
  const [followed, setFollowed] = useState(asked);
@@ -181,7 +154,7 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
181
154
  (open.agent === null ? null : (shared.created.get(open.agent) ?? newChat(open.agent)));
182
155
  const observed = ready(useObserve(thread === null ? null : client, 'conversation', thread ?? '', LATEST));
183
156
  const held = observed !== null && observed.conversation === thread ? observed : null;
184
- const paged = useEarlier(client, thread, held);
157
+ const paged = useEarlier(client, thread, useSteady(held));
185
158
  const version = useSyncExternalStore(shared.overlay.subscribe, shared.overlay.version);
186
159
  useEffect(() => {
187
160
  if (listedHeld !== null)
@@ -202,6 +175,10 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
202
175
  const lone = loneOf(questions);
203
176
  const commands = useMemo(() => commandsOf(view), [view]);
204
177
  const messages = useMemo(() => chatMessages(view), [view]);
178
+ const awaiting = useMemo(() => {
179
+ const held = requestIn(view);
180
+ return held?.waiting === true ? held.request : null;
181
+ }, [view]);
205
182
  const sending = useActs(shared.overlay, online);
206
183
  const behind = useActs(shared.overlay, online);
207
184
  const acting = useActs(shared.overlay, online);
@@ -224,7 +201,7 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
224
201
  own.current = [...own.current, `${to}\u0000${revision ?? ''}`];
225
202
  }, []);
226
203
  const keep = useCallback((to, draft) => {
227
- const revision = draft.text === '' && draft.files.length === 0 ? null : chatDraftRevision();
204
+ const revision = draft.text === '' ? null : chatDraftRevision();
228
205
  noted(to, revision);
229
206
  void (revision === null
230
207
  ? client.chatDraft.discard(to)
@@ -269,6 +246,7 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
269
246
  created: new Date().toISOString(),
270
247
  finished: null,
271
248
  outcome: null,
249
+ waiting: false,
272
250
  state: 'idle',
273
251
  started: null,
274
252
  }));
@@ -323,6 +301,26 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
323
301
  return Promise.resolve(false);
324
302
  return control('conversation.setOption', { conversation_id: to, option, value }, optionChosen(to, option, value));
325
303
  };
304
+ const retry = (message) => {
305
+ const to = opened.current.conversation;
306
+ if (to === null)
307
+ return Promise.resolve(false);
308
+ return control('conversation.retry', { conversation_id: to, message_id: message }, deliveryRetried(to, message));
309
+ };
310
+ const renew = () => {
311
+ const from = opened.current.conversation;
312
+ const by = conversations.find((one) => one.conversation === from)?.agent.identity ??
313
+ opened.current.agent;
314
+ if (from === null || by === null)
315
+ return Promise.resolve(false);
316
+ return acting.call((send) => send.carried('conversation.create', { agent: by, replaces: from }, (operation) => client.conversation.create({ agent_id: by, operation_id: operation, replaces: from })), null, (result) => {
317
+ const conversation = text(record(result), 'conversation');
318
+ if (conversation === null)
319
+ return;
320
+ shared.renewed.add(conversation);
321
+ go({ conversation, agent: by });
322
+ });
323
+ };
326
324
  const done = (to = opened.current.conversation) => to === null
327
325
  ? Promise.resolve(false)
328
326
  : control('conversation.markDone', { conversation_id: to }, conversationChanged(to, { finished: new Date().toISOString() }, (one) => one.finished !== null));
@@ -400,7 +398,7 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
400
398
  isRunning: running,
401
399
  hasEarlier: paged.hasEarlier,
402
400
  onLoadEarlier: paged.loadEarlier,
403
- convertMessage: (message) => message,
401
+ convertMessage: AS_IT_IS,
404
402
  queue: lined(),
405
403
  onNew: async (message) => lined().enqueue(message),
406
404
  onCancel: async () => {
@@ -412,12 +410,11 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
412
410
  const said = askedBefore(view, parent);
413
411
  if (said === null)
414
412
  return;
415
- const draft = { text: said, files: [] };
413
+ const draft = { text: said };
416
414
  const into = thread;
417
415
  deliverDraft(draft, () => back(draft, into), () => undefined);
418
416
  },
419
417
  adapters: {
420
- attachments: ATTACHMENTS,
421
418
  threadList: {
422
419
  ...(thread === null ? {} : { threadId: thread }),
423
420
  threads: threads.regular,
@@ -448,9 +445,33 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
448
445
  const composer = aui.thread.composer;
449
446
  const now = composer.getState().text;
450
447
  composer.setText(now === '' ? one.text : `${one.text}\n${now}`);
451
- for (const file of one.files)
452
- void composer.addAttachment(fileOf(file));
453
448
  }
449
+ function linked(path, into) {
450
+ if (current.current !== into) {
451
+ void client.chatDraft.prepend(into, { text: linkOf(path) });
452
+ return;
453
+ }
454
+ const composer = aui.thread.composer;
455
+ const now = composer.getState().text;
456
+ composer.setText(now === '' ? linkOf(path) : `${now}\n${linkOf(path)}`);
457
+ }
458
+ const attach = (room, files) => {
459
+ const into = thread;
460
+ if (into === null || files.length === 0)
461
+ return Promise.resolve(false);
462
+ return acting.call(async (send) => {
463
+ let result = { kind: 'offline' };
464
+ for (const file of files) {
465
+ result = await send.numbered('conversation.attach', { room, name: file.name }, () => client.conversation.attach(room, { name: file.name, blob: file }));
466
+ if (!accepted(result))
467
+ return result;
468
+ const path = text(record(result.result), 'path');
469
+ if (path !== null)
470
+ linked(path, into);
471
+ }
472
+ return result;
473
+ });
474
+ };
454
475
  function taken(message) {
455
476
  const said = textOf(message.content);
456
477
  if (lone === null || commandIn(said, commands))
@@ -518,7 +539,7 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
518
539
  const message = unqueue(id);
519
540
  if (thread === null || item === undefined)
520
541
  return;
521
- back(message === undefined ? { text: textOf(item.parts), files: [] } : draftOf(message), thread);
542
+ back(message === undefined ? { text: textOf(item.parts) } : draftOf(message), thread);
522
543
  };
523
544
  const reconcile = useRef(() => undefined);
524
545
  reconcile.current = () => {
@@ -537,44 +558,25 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
537
558
  }
538
559
  own.current = own.current.filter((one) => !one.startsWith(at));
539
560
  const composer = aui.thread.composer;
540
- const state = composer.getState();
561
+ const typed = composer.getState().text;
541
562
  const stored = view.chatDraft;
542
- const typed = { text: state.text, files: filesOf(state.attachments) };
543
- const kept = !known && (typed.text !== '' || typed.files.length > 0);
563
+ const kept = !known && typed !== '';
544
564
  if (kept && stored === null) {
545
- shown.current = `${at}${composed(state)}`;
546
- keep(thread, typed);
565
+ shown.current = `${at}${typed}`;
566
+ keep(thread, { text: typed });
547
567
  return;
548
568
  }
549
569
  const draft = kept
550
- ? {
551
- text: [stored?.text ?? '', typed.text].filter((one) => one !== '').join('\n'),
552
- files: [...(stored?.files ?? []), ...typed.files],
553
- }
554
- : stored;
555
- if (state.text === (draft?.text ?? '') &&
556
- state.attachments.length === 0 &&
557
- (draft?.files.length ?? 0) === 0) {
558
- shown.current = `${at}${composed(state)}`;
570
+ ? [stored?.text ?? '', typed].filter((one) => one !== '').join('\n')
571
+ : (stored?.text ?? '');
572
+ shown.current = `${at}${draft}`;
573
+ if (typed === draft)
559
574
  return;
560
- }
561
575
  seeding.current = true;
562
- composer.setText(draft?.text ?? '');
563
- void composer
564
- .clearAttachments()
565
- .then(() => Promise.all((draft?.files ?? []).map((file) => composer.addAttachment(fileOf(file)))))
566
- .finally(() => {
567
- seeding.current = false;
568
- if (current.current !== thread) {
569
- reconcile.current();
570
- return;
571
- }
572
- const seeded = composer.getState();
573
- shown.current = `${at}${composed(seeded)}`;
574
- if (kept)
575
- keep(thread, { text: seeded.text, files: filesOf(seeded.attachments) });
576
- reconcile.current();
577
- });
576
+ composer.setText(draft);
577
+ seeding.current = false;
578
+ if (kept)
579
+ keep(thread, { text: draft });
578
580
  };
579
581
  useEffect(() => reconcile.current(), [aui, thread, view]);
580
582
  useEffect(() => {
@@ -585,12 +587,12 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
585
587
  return composer.subscribe(() => {
586
588
  if (seeding.current || !heard.current.startsWith(at))
587
589
  return;
588
- const state = composer.getState();
589
- const next = `${at}${composed(state)}`;
590
+ const typed = composer.getState().text;
591
+ const next = `${at}${typed}`;
590
592
  if (next === shown.current)
591
593
  return;
592
594
  shown.current = next;
593
- keep(thread, { text: state.text, files: filesOf(state.attachments) });
595
+ keep(thread, { text: typed });
594
596
  });
595
597
  }, [aui, thread, keep]);
596
598
  const queued = lanes().map((item) => ({ id: item.id, text: textOf(item.parts) }));
@@ -599,6 +601,7 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
599
601
  conversations,
600
602
  agents,
601
603
  view,
604
+ waiting: awaiting,
602
605
  running,
603
606
  questions,
604
607
  lone,
@@ -608,13 +611,17 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
608
611
  queued,
609
612
  sending: { busy: sending.busy, outcome: sending.outcome, again },
610
613
  acting: { busy: acting.busy, outcome: acting.outcome },
614
+ renewed: open.conversation !== null && shared.renewed.has(open.conversation),
611
615
  open: openConversation,
612
616
  start,
613
617
  send: (draft) => lined().enqueue(appended(draft)),
618
+ attach: attachTo === null ? null : (files) => attach(attachTo, files),
614
619
  answer,
615
620
  choose,
616
621
  stop,
617
622
  kill,
623
+ retry,
624
+ renew,
618
625
  done: () => done(),
619
626
  rename: (name) => rename(name),
620
627
  remove: () => remove(),
@@ -1,5 +1,6 @@
1
1
  import { type CSSProperties, type ReactElement, type ReactNode } from 'react';
2
2
  import type { MdRuntimeClient } from '../client.js';
3
+ import type { ChatRequest } from './house.js';
3
4
  import { type ChatNoteProps } from './kit.js';
4
5
  import { type AgentLook } from './list.js';
5
6
  import { type ChatOpened, type ChatState } from './provider.js';
@@ -8,6 +9,7 @@ export type ChatProps = AgentLook & {
8
9
  readonly client?: MdRuntimeClient;
9
10
  readonly conversation?: string | null;
10
11
  readonly agent?: string | null;
12
+ readonly attachTo?: string | null;
11
13
  readonly onOpen?: (opened: ChatOpened) => void;
12
14
  readonly width?: ChatWidth;
13
15
  readonly showChats?: boolean;
@@ -17,11 +19,12 @@ export type ChatProps = AgentLook & {
17
19
  readonly about?: (chat: ChatState) => ReactNode;
18
20
  readonly actions?: ReactNode;
19
21
  readonly note?: (note: ChatNoteProps) => ReactNode;
20
- readonly waiting?: string | null;
22
+ readonly waiting?: (chat: ChatState) => string | null;
21
23
  readonly messageLength?: number;
22
24
  readonly autoFocus?: boolean;
25
+ readonly decision?: (request: ChatRequest) => ReactNode;
23
26
  };
24
- export declare function Chat({ client, conversation, agent, onOpen, ...look }: ChatProps): ReactElement;
27
+ export declare function Chat({ client, conversation, agent, attachTo, onOpen, ...look }: ChatProps): ReactElement;
25
28
  export type MountedChat = {
26
29
  update(props: ChatProps & {
27
30
  readonly client: MdRuntimeClient;
@@ -1 +1 @@
1
- {"version":3,"file":"ready.d.ts","sourceRoot":"","sources":["../../src/chat/ready.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAUf,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAGpD,OAAO,EASL,KAAK,aAAa,EACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAwC,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAGjF,OAAO,EAA8B,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAI5F,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAEvD,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IAC/C,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,SAAS,CAAC;IAChD,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,SAAS,CAAC;IACnD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAmQF,wBAAgB,IAAI,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,SAAS,GAAG,YAAY,CAY9F;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG;QAAE,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAA;KAAE,GAAG,IAAI,CAAC;IACtE,OAAO,IAAI,IAAI,CAAC;CACjB,CAAC;AAEF,wBAAgB,SAAS,CACvB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,SAAS,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GACtD,WAAW,CAOb"}
1
+ {"version":3,"file":"ready.d.ts","sourceRoot":"","sources":["../../src/chat/ready.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAUf,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EASL,KAAK,aAAa,EACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAwC,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAGjF,OAAO,EAA8B,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAI5F,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAEvD,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IAC/C,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,SAAS,CAAC;IAChD,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,SAAS,CAAC;IACnD,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,MAAM,GAAG,IAAI,CAAC;IACtD,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,SAAS,CAAC;CACzD,CAAC;AAyQF,wBAAgB,IAAI,CAAC,EACnB,MAAM,EACN,YAAY,EACZ,KAAK,EACL,QAAQ,EACR,MAAM,EACN,GAAG,IAAI,EACR,EAAE,SAAS,GAAG,YAAY,CAa1B;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG;QAAE,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAA;KAAE,GAAG,IAAI,CAAC;IACtE,OAAO,IAAI,IAAI,CAAC;CACjB,CAAC;AAEF,wBAAgB,SAAS,CACvB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,SAAS,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GACtD,WAAW,CAOb"}
@@ -56,17 +56,19 @@ function Head({ about, actions, listing, }) {
56
56
  (chat.deleted ? (_jsx(Name, { text: `${chat.name}, deleted · read only`, className: "ahc-head__line" })) : (_jsx(Name, { text: [chat.name, chat.view?.process?.running === false ? 'not running' : null]
57
57
  .filter(Boolean)
58
58
  .join(' · '), className: "ahc-head__line" })));
59
- return (_jsxs("div", { className: "ahc-head", children: [_jsxs("div", { className: "ahc-head__column", children: [listing === null ? null : (_jsx("span", { className: "ahc-list-toggle", children: _jsx(IconButton, { label: "Chats", onClick: listing, children: _jsx(MessagesSquare, { size: 20, "aria-hidden": "true" }) }) })), chat.by === null ? null : agentMark?.(chat.by, 20), _jsxs("div", { className: "ahc-head__names", children: [_jsx(Title, { name: name, renaming: renaming, onRename: (next) => void chat.rename(next), onDone: () => setRenaming(false) }, name), line] }), fresh ? null : chat.deleted ? (_jsx(Button, { variant: "danger-outline", onClick: () => setAsking('delete'), children: "Delete chat\u2026" })) : (_jsxs(_Fragment, { children: [actions, _jsxs(Menu, { trigger: _jsx(IconButton, { label: "Conversation options", children: _jsx(Ellipsis, { size: 20, "aria-hidden": "true" }) }), children: [_jsx(MenuItem, { icon: _jsx(Check, { "aria-hidden": "true" }), onSelect: () => void chat.done(), children: "Done" }), _jsx(MenuItem, { icon: _jsx(Pencil, { "aria-hidden": "true" }), onSelect: () => setRenaming(true), children: "Rename" }), chat.busy ? (_jsxs(_Fragment, { children: [_jsx(MenuItem, { icon: _jsx(CircleStop, { "aria-hidden": "true" }), onSelect: () => void chat.stop().then(forgotten), children: "Stop" }), _jsx(MenuItem, { icon: _jsx(OctagonX, { "aria-hidden": "true" }), onSelect: () => setAsking('kill'), children: "Kill\u2026" })] })) : null, _jsx(MenuGap, {}), _jsx(MenuItem, { icon: _jsx(Trash2, { "aria-hidden": "true" }), danger: true, onSelect: () => setAsking('delete'), children: "Delete chat\u2026" })] })] }))] }), asking === 'delete' ? (_jsx(Confirm, { title: "Delete this chat?", text: `“${name}” is deleted from House with its history. Files ${chat.name} wrote stay in their Rooms.`, action: "Delete chat", onConfirm: () => void chat.remove(), onClose: () => setAsking(null) })) : null, asking === 'kill' ? (_jsx(Confirm, { title: `Kill ${chat.name}’s process?`, text: "Stop asks the turn to end. Kill ends the process at once, and nothing after its last saved step is kept.", action: "Kill", onConfirm: () => void chat.kill().then(forgotten), onClose: () => setAsking(null) })) : null] }));
59
+ return (_jsxs("div", { className: "ahc-head", children: [_jsxs("div", { className: "ahc-head__column", children: [listing === null ? null : (_jsx("span", { className: "ahc-list-toggle", children: _jsx(IconButton, { label: "Chats", onClick: listing, children: _jsx(MessagesSquare, { size: 20, "aria-hidden": "true" }) }) })), chat.by === null ? null : agentMark?.(chat.by, 20), _jsxs("div", { className: "ahc-head__names", children: [_jsx(Title, { name: name, renaming: renaming, onRename: (next) => void chat.rename(next), onDone: () => setRenaming(false) }, name), line] }), fresh ? null : chat.deleted ? (_jsx(Button, { variant: "danger-outline", onClick: () => setAsking('delete'), children: "Delete chat\u2026" })) : (_jsxs(_Fragment, { children: [actions, _jsxs(Menu, { trigger: _jsx(IconButton, { label: "Conversation options", children: _jsx(Ellipsis, { size: 20, "aria-hidden": "true" }) }), children: [_jsx(MenuItem, { icon: _jsx(Check, { "aria-hidden": "true" }), onSelect: () => void chat.done(), children: "Done" }), _jsx(MenuItem, { icon: _jsx(Pencil, { "aria-hidden": "true" }), onSelect: () => setRenaming(true), children: "Rename" }), chat.busy ? (_jsxs(_Fragment, { children: [_jsx(MenuItem, { icon: _jsx(CircleStop, { "aria-hidden": "true" }), onSelect: () => void chat.stop().then(forgotten), children: "Stop" }), _jsx(MenuItem, { icon: _jsx(OctagonX, { "aria-hidden": "true" }), onSelect: () => setAsking('kill'), children: "Kill\u2026" })] })) : null, _jsx(MenuGap, {}), _jsx(MenuItem, { icon: _jsx(Trash2, { "aria-hidden": "true" }), danger: true, onSelect: () => setAsking('delete'), children: "Delete chat\u2026" })] })] }))] }), asking === 'delete' ? (_jsx(Confirm, { title: "Delete this chat?", text: chat.waits
60
+ ? `“${name}” waits for your approval. Deleting it declines the request.`
61
+ : `“${name}” is deleted from House with its history. Files ${chat.name} wrote stay in their Rooms.`, action: "Delete chat", onConfirm: () => void chat.remove(), onClose: () => setAsking(null) })) : null, asking === 'kill' ? (_jsx(Confirm, { title: `Kill ${chat.name}’s process?`, text: "Stop asks the turn to end. Kill ends the process at once, and nothing after its last saved step is kept.", action: "Kill", onConfirm: () => void chat.kill().then(forgotten), onClose: () => setAsking(null) })) : null] }));
60
62
  }
61
63
  function Deleted() {
62
64
  const chat = useOpened();
63
65
  return (_jsx("div", { className: "ahc-deleted", children: _jsxs("div", { role: "note", className: "ahc-column ahc-deleted__note", children: [_jsx("span", { className: "ahc-deleted__icon", children: _jsx(Info, { "aria-hidden": "true" }) }), _jsx("span", { children: `${chat.name} was deleted. Its chats stay here for you to read or delete.` })] }) }));
64
66
  }
65
- function Frame({ showChats, onLink, about, actions, note, waiting, messageLength, autoFocus, }) {
67
+ function Frame({ showChats, onLink, about, actions, note, waiting, messageLength, autoFocus, decision, }) {
66
68
  const chat = useOpened();
67
69
  const [listed, setListed] = useState(false);
68
70
  const thread = chat.conversation ?? `new:${chat.agent ?? ''}`;
69
- return (_jsxs("div", { className: "ahc-frame", children: [showChats === true ? (_jsx("div", { className: "ahc-side", "data-open": listed ? '' : undefined, children: _jsx(ChatList, { onChoose: () => setListed(false) }) })) : null, _jsxs("div", { className: "ahc-pane", children: [_jsx(Head, { about: about, actions: actions, listing: showChats === true ? () => setListed((open) => !open) : null }, thread), chat.deleted ? _jsx(Deleted, {}) : null, _jsx(ChatMessageList, { ...(onLink === undefined ? {} : { onLink }), waiting: waiting ?? null, footer: _jsx(ChatInput, { ...(messageLength === undefined ? {} : { messageLength }), ...(note === undefined ? {} : { note }), autoFocus: autoFocus === true }) })] })] }));
71
+ return (_jsxs("div", { className: "ahc-frame", children: [showChats === true ? (_jsx("div", { className: "ahc-side", "data-open": listed ? '' : undefined, children: _jsx(ChatList, { onChoose: () => setListed(false) }) })) : null, _jsxs("div", { className: "ahc-pane", children: [_jsx(Head, { about: about, actions: actions, listing: showChats === true ? () => setListed((open) => !open) : null }, thread), chat.deleted ? _jsx(Deleted, {}) : null, _jsx(ChatMessageList, { ...(onLink === undefined ? {} : { onLink }), ...(waiting === undefined ? {} : { waiting }), footer: _jsx(ChatInput, { ...(messageLength === undefined ? {} : { messageLength }), ...(note === undefined ? {} : { note }), ...(decision === undefined ? {} : { decision }), autoFocus: autoFocus === true }) })] })] }));
70
72
  }
71
73
  function Ready({ width = 'full', className, style, agentMark, agentDetail, AgentLink, ...rest }) {
72
74
  const [root, setRoot] = useState(null);
@@ -76,10 +78,10 @@ function Ready({ width = 'full', className, style, agentMark, agentDetail, Agent
76
78
  }, []);
77
79
  return (_jsx("div", { ref: attach, className: className === undefined ? 'ahc ahc-chat' : `ahc ahc-chat ${className}`, "data-width": width, style: style, children: root === null ? null : (_jsx(Within, { root: root, children: _jsx(Described.Provider, { value: { agentMark, agentDetail, AgentLink }, children: _jsx(Frame, { ...rest }) }) })) }));
78
80
  }
79
- export function Chat({ client, conversation, agent, onOpen, ...look }) {
81
+ export function Chat({ client, conversation, agent, attachTo, onOpen, ...look }) {
80
82
  if (client === undefined)
81
83
  return _jsx(Ready, { ...look });
82
- return (_jsx(ChatProvider, { client: client, ...(conversation === undefined ? {} : { conversation }), ...(agent === undefined ? {} : { agent }), ...(onOpen === undefined ? {} : { onOpen }), children: _jsx(Ready, { ...look }) }));
84
+ return (_jsx(ChatProvider, { client: client, ...(conversation === undefined ? {} : { conversation }), ...(agent === undefined ? {} : { agent }), ...(attachTo === undefined ? {} : { attachTo }), ...(onOpen === undefined ? {} : { onOpen }), children: _jsx(Ready, { ...look }) }));
83
85
  }
84
86
  export function mountChat(element, props) {
85
87
  const root = createRoot(element);
@@ -0,0 +1,8 @@
1
+ import { type ReactNode } from 'react';
2
+ export declare function isRoomPath(href: string): boolean;
3
+ export declare function RoomFile({ href, name, otherwise, }: {
4
+ href: string;
5
+ name: string;
6
+ otherwise: ReactNode;
7
+ }): ReactNode;
8
+ //# sourceMappingURL=room-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"room-file.d.ts","sourceRoot":"","sources":["../../src/chat/room-file.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAmD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAoBxF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhD;AAoED,wBAAgB,QAAQ,CAAC,EACvB,IAAI,EACJ,IAAI,EACJ,SAAS,GACV,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,SAAS,CAAC;CACtB,GAAG,SAAS,CAQZ"}
@@ -0,0 +1,72 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useState } from 'react';
3
+ import FileGlyph from 'lucide-react/dist/esm/icons/file.mjs';
4
+ import { useObserve } from '../react.js';
5
+ import { Name } from './kit.js';
6
+ import { useChatScope } from './provider.js';
7
+ const ROOM_PATH = /^\/rooms\/([^/]+)\/(.+)$/u;
8
+ const INLINE_IMAGE = /^image\/(?:png|jpeg|gif|webp)$/u;
9
+ const NOTHING = { rooms: [], select: {} };
10
+ export function isRoomPath(href) {
11
+ return ROOM_PATH.test(href);
12
+ }
13
+ function useHeld(href) {
14
+ const { client } = useChatScope();
15
+ const rooms = useObserve(client, 'rooms');
16
+ const [, handle, path] = ROOM_PATH.exec(href) ?? [];
17
+ const locator = rooms.state === 'ready'
18
+ ? (rooms.value.find((room) => room.handle === handle)?.locator ?? null)
19
+ : null;
20
+ const query = useMemo(() => locator === null || path === undefined
21
+ ? null
22
+ : { rooms: [locator], paths: [path], select: {} }, [locator, path]);
23
+ const found = useObserve(query === null ? null : client, 'query', query ?? NOTHING);
24
+ if (locator === null || path === undefined || found.state !== 'ready')
25
+ return null;
26
+ const held = 'documents' in found.value ? found.value.documents[0]?.binaryFile : undefined;
27
+ return held?.state === 'accepted'
28
+ ? { locator, path, revision: held.revision, mediaType: held.mediaType }
29
+ : null;
30
+ }
31
+ function Picture({ held, name }) {
32
+ const { client } = useChatScope();
33
+ const [address, setAddress] = useState(null);
34
+ useEffect(() => {
35
+ let live = true;
36
+ let made = null;
37
+ void client.binaryFile
38
+ .read(held.locator, held.path, held.revision)
39
+ .then((answer) => answer.kind === 'binary'
40
+ ? new Response(answer.stream, { headers: { 'content-type': answer.mediaType } }).blob()
41
+ : null)
42
+ .then((blob) => {
43
+ if (!live || blob === null)
44
+ return;
45
+ made = URL.createObjectURL(blob);
46
+ setAddress(made);
47
+ });
48
+ return () => {
49
+ live = false;
50
+ if (made !== null)
51
+ URL.revokeObjectURL(made);
52
+ };
53
+ }, [client, held.locator, held.path, held.revision]);
54
+ return address === null ? null : _jsx("img", { className: "ahc-picture", src: address, alt: name });
55
+ }
56
+ function Opened({ held, name }) {
57
+ const { client } = useChatScope();
58
+ const open = () => void client.binaryFile.link(held.locator, held.path, held.revision).then((answer) => {
59
+ if (answer.kind !== 'link')
60
+ return;
61
+ const anchor = document.createElement('a');
62
+ anchor.href = answer.url;
63
+ anchor.click();
64
+ });
65
+ return (_jsxs("button", { type: "button", className: "ahc-chip", onClick: open, children: [_jsx(FileGlyph, { "aria-hidden": "true" }), _jsx(Name, { text: name })] }));
66
+ }
67
+ export function RoomFile({ href, name, otherwise, }) {
68
+ const held = useHeld(href);
69
+ if (held === null)
70
+ return otherwise;
71
+ return INLINE_IMAGE.test(held.mediaType) ? (_jsx(Picture, { held: held, name: name })) : (_jsx(Opened, { held: held, name: name }));
72
+ }
@@ -0,0 +1,3 @@
1
+ import type { ConversationView } from '../conversation.js';
2
+ export declare function useSteady(held: ConversationView | null): ConversationView | null;
3
+ //# sourceMappingURL=steady.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"steady.d.ts","sourceRoot":"","sources":["../../src/chat/steady.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAwB3D,wBAAgB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,GAAG,gBAAgB,GAAG,IAAI,CAMhF"}
@@ -0,0 +1,26 @@
1
+ import { useState } from 'react';
2
+ function same(held, now) {
3
+ return (held.turn === now.turn &&
4
+ held.text === now.text &&
5
+ JSON.stringify(held.message) === JSON.stringify(now.message));
6
+ }
7
+ function steadied(before, after) {
8
+ if (before === null || before.conversation !== after.conversation)
9
+ return after;
10
+ const held = new Map(before.messages.map((one) => [one.identity, one]));
11
+ return {
12
+ ...after,
13
+ messages: after.messages.map((one) => {
14
+ const was = held.get(one.identity);
15
+ return was !== undefined && same(was, one) ? was : one;
16
+ }),
17
+ };
18
+ }
19
+ export function useSteady(held) {
20
+ const [steady, setSteady] = useState({ from: held, view: held });
21
+ if (steady.from === held)
22
+ return steady.view;
23
+ const view = held === null ? null : steadied(steady.view, held);
24
+ setSteady({ from: held, view });
25
+ return view;
26
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../src/chat/style.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,MAAM,CAAC;AAEnC,eAAO,MAAM,kBAAkB,QAAsB,CAAC;AA2StD,wBAAgB,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI,CASrD"}
1
+ {"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../src/chat/style.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,MAAM,CAAC;AAEnC,eAAO,MAAM,kBAAkB,QAAsB,CAAC;AAgTtD,wBAAgB,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI,CASrD"}
@@ -223,6 +223,11 @@ const CSS = `
223
223
  .ahc-you { align-self: flex-end; max-width: 85%; display: flex; flex-direction: column; align-items: flex-end; }
224
224
  .ahc-bubble { max-width: 100%; padding: 10px var(--ahc-stack); border-radius: var(--ahc-r-bubble); background: var(--ahc-well); font-size: var(--ahc-read); line-height: var(--ahc-read-lead); text-wrap: pretty; }
225
225
  .ahc-said { white-space: pre-wrap; }
226
+ .ahc-transcript { display: block; margin-block: var(--ahc-unit); }
227
+ .ahc-picture { display: block; max-width: 100%; max-height: 320px; border-radius: var(--ahc-r-control); }
228
+ .ahc-house { display: flex; flex-direction: column; gap: var(--ahc-unit); padding: var(--ahc-inset) var(--ahc-stack); border: 1px solid var(--ahc-line); border-radius: var(--ahc-r-tile); font-size: var(--ahc-read); line-height: var(--ahc-read-lead); }
229
+ .ahc-house__from { display: flex; flex-direction: column; }
230
+ .ahc-house__title { font-size: var(--ahc-meta); line-height: var(--ahc-meta-lead); font-weight: 500; }
226
231
  .ahc-turn { position: relative; display: flex; flex-direction: column; min-width: 0; }
227
232
  .ahc-text { margin: 0; font-size: var(--ahc-read); line-height: var(--ahc-read-lead); text-wrap: pretty; }
228
233
  .ahc-text > :first-child { margin-top: 0; }
package/dist/chat.d.ts CHANGED
@@ -1,13 +1,14 @@
1
1
  export { ChatProvider, useChat, type ChatActing, type ChatOpened, type ChatProviderProps, type ChatQueued, type ChatState, } from './chat/provider.js';
2
- export { chatMessages } from './chat/messages.js';
2
+ export { awaitsTurn, chatMessages } from './chat/messages.js';
3
3
  export { Chat, mountChat, type ChatProps, type ChatWidth, type MountedChat } from './chat/ready.js';
4
4
  export { ChatMessageList, type ChatMessageListProps } from './chat/list.js';
5
5
  export { ChatInput, type ChatInputProps } from './chat/input.js';
6
6
  export { ChatQuestionCard, type ChatQuestionCardProps } from './chat/question.js';
7
7
  export type { ChatNoteProps } from './chat/kit.js';
8
8
  export { ChatName } from './chat/name.js';
9
- export { Markdown, anchorOf, plainText, slugOf, type FileReference, type MarkdownProps, } from './chat/markdown.js';
9
+ export { Markdown, anchorOf, plainText, revealed, slugOf, type FileReference, type MarkdownProps, } from './chat/markdown.js';
10
10
  export type { ChatOutcome } from './chat/acts.js';
11
+ export type { ChatRequest } from './chat/house.js';
11
12
  export type { ChatWork } from './chat/parts.js';
12
13
  export type { ChatCommand, ChatOption, ChatOptionValue } from './chat/process.js';
13
14
  export type { ChatAnswer, ChatChoice, ChatField, ChatLone, ChatQuestion, } from './chat/questions.js';