@agentshouse/mdruntime 0.1.0-c1db74d14e5fa → 0.1.0-c24132a516ded

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 (184) hide show
  1. package/AGENTS.md +246 -242
  2. package/README.md +9 -8
  3. package/dist/adapter.d.ts +53 -23
  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 +2 -1
  9. package/dist/bootstrap.d.ts.map +1 -1
  10. package/dist/bootstrap.js +62 -27
  11. package/dist/change-set.d.ts +5 -2
  12. package/dist/change-set.d.ts.map +1 -1
  13. package/dist/change-set.js +10 -8
  14. package/dist/change.d.ts +31 -1
  15. package/dist/change.d.ts.map +1 -1
  16. package/dist/change.js +10 -1
  17. package/dist/chat/earlier.d.ts +10 -0
  18. package/dist/chat/earlier.d.ts.map +1 -0
  19. package/dist/chat/earlier.js +54 -0
  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/kit.d.ts +2 -1
  27. package/dist/chat/kit.d.ts.map +1 -1
  28. package/dist/chat/kit.js +3 -3
  29. package/dist/chat/list.d.ts +3 -1
  30. package/dist/chat/list.d.ts.map +1 -1
  31. package/dist/chat/list.js +47 -6
  32. package/dist/chat/markdown.d.ts +1 -0
  33. package/dist/chat/markdown.d.ts.map +1 -1
  34. package/dist/chat/markdown.js +78 -20
  35. package/dist/chat/message.d.ts +1 -0
  36. package/dist/chat/message.d.ts.map +1 -1
  37. package/dist/chat/message.js +55 -10
  38. package/dist/chat/messages.d.ts +9 -1
  39. package/dist/chat/messages.d.ts.map +1 -1
  40. package/dist/chat/messages.js +67 -28
  41. package/dist/chat/name.d.ts +1 -0
  42. package/dist/chat/name.d.ts.map +1 -1
  43. package/dist/chat/name.js +1 -1
  44. package/dist/chat/opened.d.ts +1 -0
  45. package/dist/chat/opened.d.ts.map +1 -1
  46. package/dist/chat/opened.js +2 -0
  47. package/dist/chat/overlay.d.ts +1 -0
  48. package/dist/chat/overlay.d.ts.map +1 -1
  49. package/dist/chat/overlay.js +11 -5
  50. package/dist/chat/parts.d.ts +1 -0
  51. package/dist/chat/parts.d.ts.map +1 -1
  52. package/dist/chat/parts.js +3 -2
  53. package/dist/chat/pieces.d.ts +62 -0
  54. package/dist/chat/pieces.d.ts.map +1 -0
  55. package/dist/chat/pieces.js +1110 -0
  56. package/dist/chat/provider.d.ts +7 -2
  57. package/dist/chat/provider.d.ts.map +1 -1
  58. package/dist/chat/provider.js +104 -105
  59. package/dist/chat/question.d.ts +1 -1
  60. package/dist/chat/question.d.ts.map +1 -1
  61. package/dist/chat/question.js +7 -18
  62. package/dist/chat/ready.d.ts +5 -1
  63. package/dist/chat/ready.d.ts.map +1 -1
  64. package/dist/chat/ready.js +7 -5
  65. package/dist/chat/room-file.d.ts +8 -0
  66. package/dist/chat/room-file.d.ts.map +1 -0
  67. package/dist/chat/room-file.js +67 -0
  68. package/dist/chat/steady.d.ts +3 -0
  69. package/dist/chat/steady.d.ts.map +1 -0
  70. package/dist/chat/steady.js +26 -0
  71. package/dist/chat/style.d.ts.map +1 -1
  72. package/dist/chat/style.js +5 -1
  73. package/dist/chat.d.ts +3 -2
  74. package/dist/chat.d.ts.map +1 -1
  75. package/dist/chat.js +2 -2
  76. package/dist/client.d.ts +11 -3
  77. package/dist/client.d.ts.map +1 -1
  78. package/dist/client.js +19 -5
  79. package/dist/collection.d.ts +6 -5
  80. package/dist/collection.d.ts.map +1 -1
  81. package/dist/collection.js +166 -85
  82. package/dist/connection.d.ts +17 -5
  83. package/dist/connection.d.ts.map +1 -1
  84. package/dist/connection.js +1212 -368
  85. package/dist/conversation.d.ts +15 -2
  86. package/dist/conversation.d.ts.map +1 -1
  87. package/dist/conversation.js +278 -74
  88. package/dist/digest.d.ts +2 -0
  89. package/dist/digest.d.ts.map +1 -0
  90. package/dist/digest.js +100 -0
  91. package/dist/durability.d.ts +1 -1
  92. package/dist/entry.d.ts +2 -1
  93. package/dist/entry.d.ts.map +1 -1
  94. package/dist/entry.js +5 -4
  95. package/dist/file.d.ts +2 -10
  96. package/dist/file.d.ts.map +1 -1
  97. package/dist/file.js +3 -120
  98. package/dist/host.d.ts +9 -7
  99. package/dist/host.d.ts.map +1 -1
  100. package/dist/host.js +67 -14
  101. package/dist/index.d.ts +11 -7
  102. package/dist/index.d.ts.map +1 -1
  103. package/dist/index.js +4 -0
  104. package/dist/memory.d.ts +7 -3
  105. package/dist/memory.d.ts.map +1 -1
  106. package/dist/memory.js +33 -16
  107. package/dist/model.d.ts +3 -2
  108. package/dist/model.d.ts.map +1 -1
  109. package/dist/model.js +1 -1
  110. package/dist/name.d.ts +4 -0
  111. package/dist/name.d.ts.map +1 -0
  112. package/dist/name.js +122 -0
  113. package/dist/observation.d.ts +2 -0
  114. package/dist/observation.d.ts.map +1 -1
  115. package/dist/observation.js +9 -3
  116. package/dist/outcome.d.ts +27 -2
  117. package/dist/outcome.d.ts.map +1 -1
  118. package/dist/outcome.js +25 -0
  119. package/dist/overlay.d.ts +6 -5
  120. package/dist/overlay.d.ts.map +1 -1
  121. package/dist/overlay.js +223 -134
  122. package/dist/query.d.ts +30 -2
  123. package/dist/query.d.ts.map +1 -1
  124. package/dist/query.js +37 -7
  125. package/dist/reach.d.ts +6 -3
  126. package/dist/reach.d.ts.map +1 -1
  127. package/dist/reach.js +156 -38
  128. package/dist/react.d.ts +3 -3
  129. package/dist/react.d.ts.map +1 -1
  130. package/dist/react.js +7 -17
  131. package/dist/read-side.d.ts +6 -4
  132. package/dist/read-side.d.ts.map +1 -1
  133. package/dist/read-side.js +755 -215
  134. package/dist/readiness.d.ts +1 -1
  135. package/dist/readiness.d.ts.map +1 -1
  136. package/dist/reads.d.ts +11 -0
  137. package/dist/reads.d.ts.map +1 -0
  138. package/dist/reads.js +98 -0
  139. package/dist/recovery.d.ts +2 -2
  140. package/dist/recovery.d.ts.map +1 -1
  141. package/dist/recovery.js +8 -7
  142. package/dist/refresh.d.ts +4 -4
  143. package/dist/refresh.d.ts.map +1 -1
  144. package/dist/refresh.js +41 -16
  145. package/dist/replica.d.ts +12 -7
  146. package/dist/replica.d.ts.map +1 -1
  147. package/dist/replica.js +133 -74
  148. package/dist/room-draft.d.ts +16 -2
  149. package/dist/room-draft.d.ts.map +1 -1
  150. package/dist/room-draft.js +32 -25
  151. package/dist/rows.d.ts +3 -1
  152. package/dist/rows.d.ts.map +1 -1
  153. package/dist/rows.js +8 -1
  154. package/dist/save.d.ts +47 -9
  155. package/dist/save.d.ts.map +1 -1
  156. package/dist/save.js +501 -165
  157. package/dist/search.d.ts +29 -8
  158. package/dist/search.d.ts.map +1 -1
  159. package/dist/search.js +150 -17
  160. package/dist/seed.d.ts +16 -0
  161. package/dist/seed.d.ts.map +1 -0
  162. package/dist/seed.js +75 -0
  163. package/dist/shared.d.ts +9 -1
  164. package/dist/shared.d.ts.map +1 -1
  165. package/dist/shared.js +134 -41
  166. package/dist/store.d.ts +30 -17
  167. package/dist/store.d.ts.map +1 -1
  168. package/dist/store.js +489 -430
  169. package/dist/tables.d.ts +181 -0
  170. package/dist/tables.d.ts.map +1 -0
  171. package/dist/tables.js +309 -0
  172. package/dist/turn.d.ts +5 -3
  173. package/dist/turn.d.ts.map +1 -1
  174. package/dist/turn.js +35 -13
  175. package/dist/windows.d.ts +21 -0
  176. package/dist/windows.d.ts.map +1 -0
  177. package/dist/windows.js +84 -0
  178. package/dist/wire.d.ts +159 -33
  179. package/dist/wire.d.ts.map +1 -1
  180. package/dist/wire.js +53 -32
  181. package/package.json +6 -2
  182. package/dist/acquisition.d.ts +0 -14
  183. package/dist/acquisition.d.ts.map +0 -1
  184. package/dist/acquisition.js +0 -24
@@ -1,8 +1,9 @@
1
1
  import { type ReactElement, type ReactNode } from 'react';
2
2
  import type { TurnContext } from '../adapter.js';
3
3
  import type { MdRuntimeClient } from '../client.js';
4
- import type { ChatDraft, ConversationAgent, ConversationEntry, ConversationView } from '../conversation.js';
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;
@@ -35,10 +37,12 @@ export type ChatState = ChatOpened & {
35
37
  open(conversation: string): void;
36
38
  start(agent: string): void;
37
39
  send(draft: ChatDraft): void;
40
+ attach: ((files: readonly File[]) => Promise<boolean>) | null;
38
41
  answer(question: ChatQuestion, response: unknown): Promise<boolean>;
39
42
  choose(option: string, value: string): Promise<boolean>;
40
43
  stop(): Promise<boolean>;
41
44
  kill(): Promise<boolean>;
45
+ retry(message: string): Promise<boolean>;
42
46
  done(): Promise<boolean>;
43
47
  rename(name: string): Promise<boolean>;
44
48
  remove(): Promise<boolean>;
@@ -49,6 +53,7 @@ export type ChatProviderProps = {
49
53
  readonly client: MdRuntimeClient;
50
54
  readonly conversation?: string | null;
51
55
  readonly agent?: string | null;
56
+ readonly attachTo?: string | null;
52
57
  readonly onOpen?: (opened: ChatOpened) => void;
53
58
  readonly children?: ReactNode;
54
59
  };
@@ -58,6 +63,6 @@ type Scope = {
58
63
  };
59
64
  export declare function useChatScope(): Scope;
60
65
  export declare function useChat(): ChatState;
61
- export declare function ChatProvider({ client, conversation, agent, onOpen, children, }: ChatProviderProps): ReactElement;
66
+ export declare function ChatProvider({ client, conversation, agent, attachTo, onOpen, children, }: ChatProviderProps): ReactElement;
62
67
  export {};
63
68
  //# 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,16 +1,20 @@
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
+ import { newChat, } from '../conversation.js';
4
5
  import { expectedList } from '../expectation.js';
5
6
  import { chatDraftRevision } from '../identity.js';
6
7
  import { useObserve } from '../react.js';
7
8
  import { accepted, answeredOf, outcomeOf, sender, unanswered, } from './acts.js';
8
- import { askedBefore, chatMessages, contextOf } from './messages.js';
9
- import { conversationChanged, conversationGone, conversationListed, optionChosen, overlay, questionAnswered, sentMessage, } from './overlay.js';
9
+ import { CHAT_WINDOW, useEarlier } from './earlier.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';
10
13
  import { commandIn, commandsOf, optionsOf } from './process.js';
11
14
  import { loneOf, questionsOf } from './questions.js';
12
15
  import { record, text } from './read.js';
13
16
  const SHARED = new WeakMap();
17
+ const LATEST = { limit: CHAT_WINDOW };
14
18
  function sharedOf(client) {
15
19
  const held = SHARED.get(client);
16
20
  if (held !== undefined)
@@ -19,9 +23,6 @@ function sharedOf(client) {
19
23
  SHARED.set(client, fresh);
20
24
  return fresh;
21
25
  }
22
- function newChat(agent) {
23
- return `new:${agent}`;
24
- }
25
26
  function ready(observed) {
26
27
  return observed.state === 'ready' ? observed.value : null;
27
28
  }
@@ -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);
@@ -174,11 +147,14 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
174
147
  }, []);
175
148
  const listedHeld = ready(useObserve(client, 'conversations'));
176
149
  const agentsHeld = ready(useObserve(client, 'agents'));
177
- const sync = ready(useObserve(client, 'sync-status'));
150
+ const readiness = ready(useObserve(client, 'readiness'));
178
151
  const refusal = ready(useObserve(client, 'connection-refusal'));
179
- const online = sync !== null && !sync.providerUnreachable && refusal === null;
180
- const thread = open.conversation ?? (open.agent === null ? null : newChat(open.agent));
181
- const held = ready(useObserve(thread === null ? null : client, 'conversation', thread ?? '', {}));
152
+ const online = readiness?.connection !== 'unreachable' && refusal === null;
153
+ const thread = open.conversation ??
154
+ (open.agent === null ? null : (shared.created.get(open.agent) ?? newChat(open.agent)));
155
+ const observed = ready(useObserve(thread === null ? null : client, 'conversation', thread ?? '', LATEST));
156
+ const held = observed !== null && observed.conversation === thread ? observed : null;
157
+ const paged = useEarlier(client, thread, useSteady(held));
182
158
  const version = useSyncExternalStore(shared.overlay.subscribe, shared.overlay.version);
183
159
  useEffect(() => {
184
160
  if (listedHeld !== null)
@@ -189,7 +165,7 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
189
165
  shared.overlay.heard(held);
190
166
  }, [shared, held, version]);
191
167
  const conversations = useMemo(() => shared.overlay.conversations(listedHeld ?? []), [shared, listedHeld, version]);
192
- const view = useMemo(() => held === null || held.conversation !== thread ? null : shared.overlay.conversation(held), [shared, held, thread, version]);
168
+ const view = useMemo(() => (paged.view === null ? null : shared.overlay.conversation(paged.view)), [shared, paged.view, version]);
193
169
  const agents = agentsHeld ?? [];
194
170
  const known = useRef(agents);
195
171
  known.current = agents;
@@ -199,6 +175,10 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
199
175
  const lone = loneOf(questions);
200
176
  const commands = useMemo(() => commandsOf(view), [view]);
201
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]);
202
182
  const sending = useActs(shared.overlay, online);
203
183
  const behind = useActs(shared.overlay, online);
204
184
  const acting = useActs(shared.overlay, online);
@@ -206,6 +186,14 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
206
186
  const current = useRef(thread);
207
187
  current.current = thread;
208
188
  const seeding = useRef(false);
189
+ const mounted = useRef(true);
190
+ useEffect(() => {
191
+ mounted.current = true;
192
+ return () => {
193
+ mounted.current = false;
194
+ };
195
+ }, []);
196
+ const was = useRef(null);
209
197
  const heard = useRef('');
210
198
  const shown = useRef('');
211
199
  const own = useRef([]);
@@ -213,7 +201,7 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
213
201
  own.current = [...own.current, `${to}\u0000${revision ?? ''}`];
214
202
  }, []);
215
203
  const keep = useCallback((to, draft) => {
216
- const revision = draft.text === '' && draft.files.length === 0 ? null : chatDraftRevision();
204
+ const revision = draft.text === '' ? null : chatDraftRevision();
217
205
  noted(to, revision);
218
206
  void (revision === null
219
207
  ? client.chatDraft.discard(to)
@@ -223,6 +211,10 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
223
211
  heard.current = '';
224
212
  shown.current = '';
225
213
  own.current = own.current.filter((one) => one.startsWith(`${thread}\u0000`));
214
+ const created = was.current === open;
215
+ was.current = open;
216
+ if (created)
217
+ return;
226
218
  sending.clear();
227
219
  acting.clear();
228
220
  setAgain(null);
@@ -230,7 +222,6 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
230
222
  const sendTo = (to, said, key, idle, acts = sending) => acts.call((send) => deliver(client, send, to, said, key, idle), sentMessage(key, [to], said, null));
231
223
  const first = (to, said, key, returning, idle) => {
232
224
  const drafted = [newChat(to)];
233
- let made = null;
234
225
  return sending.call(async (send) => {
235
226
  let conversation = shared.created.get(to);
236
227
  if (conversation === undefined) {
@@ -255,31 +246,22 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
255
246
  created: new Date().toISOString(),
256
247
  finished: null,
257
248
  outcome: null,
249
+ waiting: false,
258
250
  state: 'idle',
259
251
  started: null,
260
252
  }));
261
253
  }
262
- made = conversation;
263
254
  send.draw(sentMessage(key, [...drafted, conversation], said, null));
264
255
  const result = await deliver(client, send, conversation, said, key, idle);
265
- if (accepted(result))
266
- shared.created.delete(to);
267
- return result;
268
- }, sentMessage(key, drafted, said, null), () => {
269
- if (made === null)
270
- return;
271
- void client.chatDraft.discard(newChat(to));
256
+ if (!accepted(result))
257
+ return result;
258
+ shared.created.delete(to);
272
259
  const now = opened.current;
273
- if (now.conversation === null && now.agent === to)
274
- go({ conversation: made, agent: to });
275
- });
276
- };
277
- const returned = async (to, one) => {
278
- const now = (await client.conversation.read(to)).chatDraft;
279
- await client.chatDraft.write(to, {
280
- text: now === null || now.text === '' ? one.text : `${one.text}\n${now.text}`,
281
- files: [...one.files, ...(now?.files ?? [])],
282
- });
260
+ if (mounted.current && now.conversation === null && now.agent === to) {
261
+ go({ conversation, agent: to });
262
+ }
263
+ return result;
264
+ }, sentMessage(key, drafted, said, null));
283
265
  };
284
266
  const sent = () => {
285
267
  shared.sends += 1;
@@ -319,6 +301,12 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
319
301
  return Promise.resolve(false);
320
302
  return control('conversation.setOption', { conversation_id: to, option, value }, optionChosen(to, option, value));
321
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
+ };
322
310
  const done = (to = opened.current.conversation) => to === null
323
311
  ? Promise.resolve(false)
324
312
  : control('conversation.markDone', { conversation_id: to }, conversationChanged(to, { finished: new Date().toISOString() }, (one) => one.finished !== null));
@@ -394,7 +382,9 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
394
382
  const aui = useExternalStoreRuntime({
395
383
  messages,
396
384
  isRunning: running,
397
- convertMessage: (message) => message,
385
+ hasEarlier: paged.hasEarlier,
386
+ onLoadEarlier: paged.loadEarlier,
387
+ convertMessage: AS_IT_IS,
398
388
  queue: lined(),
399
389
  onNew: async (message) => lined().enqueue(message),
400
390
  onCancel: async () => {
@@ -406,12 +396,11 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
406
396
  const said = askedBefore(view, parent);
407
397
  if (said === null)
408
398
  return;
409
- const draft = { text: said, files: [] };
399
+ const draft = { text: said };
410
400
  const into = thread;
411
401
  deliverDraft(draft, () => back(draft, into), () => undefined);
412
402
  },
413
403
  adapters: {
414
- attachments: ATTACHMENTS,
415
404
  threadList: {
416
405
  ...(thread === null ? {} : { threadId: thread }),
417
406
  threads: threads.regular,
@@ -436,15 +425,39 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
436
425
  });
437
426
  function back(one, into) {
438
427
  if (current.current !== into) {
439
- void returned(into, one);
428
+ void client.chatDraft.prepend(into, one);
440
429
  return;
441
430
  }
442
431
  const composer = aui.thread.composer;
443
432
  const now = composer.getState().text;
444
433
  composer.setText(now === '' ? one.text : `${one.text}\n${now}`);
445
- for (const file of one.files)
446
- void composer.addAttachment(fileOf(file));
447
434
  }
435
+ function linked(path, into) {
436
+ if (current.current !== into) {
437
+ void client.chatDraft.prepend(into, { text: linkOf(path) });
438
+ return;
439
+ }
440
+ const composer = aui.thread.composer;
441
+ const now = composer.getState().text;
442
+ composer.setText(now === '' ? linkOf(path) : `${now}\n${linkOf(path)}`);
443
+ }
444
+ const attach = (room, files) => {
445
+ const into = thread;
446
+ if (into === null || files.length === 0)
447
+ return Promise.resolve(false);
448
+ return acting.call(async (send) => {
449
+ let result = { kind: 'offline' };
450
+ for (const file of files) {
451
+ result = await send.numbered('conversation.attach', { room, name: file.name }, () => client.conversation.attach(room, { name: file.name, blob: file }));
452
+ if (!accepted(result))
453
+ return result;
454
+ const path = text(record(result.result), 'path');
455
+ if (path !== null)
456
+ linked(path, into);
457
+ }
458
+ return result;
459
+ });
460
+ };
448
461
  function taken(message) {
449
462
  const said = textOf(message.content);
450
463
  if (lone === null || commandIn(said, commands))
@@ -512,7 +525,7 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
512
525
  const message = unqueue(id);
513
526
  if (thread === null || item === undefined)
514
527
  return;
515
- back(message === undefined ? { text: textOf(item.parts), files: [] } : draftOf(message), thread);
528
+ back(message === undefined ? { text: textOf(item.parts) } : draftOf(message), thread);
516
529
  };
517
530
  const reconcile = useRef(() => undefined);
518
531
  reconcile.current = () => {
@@ -531,42 +544,25 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
531
544
  }
532
545
  own.current = own.current.filter((one) => !one.startsWith(at));
533
546
  const composer = aui.thread.composer;
534
- const state = composer.getState();
547
+ const typed = composer.getState().text;
535
548
  const stored = view.chatDraft;
536
- const typed = { text: state.text, files: filesOf(state.attachments) };
537
- const kept = !known && (typed.text !== '' || typed.files.length > 0);
549
+ const kept = !known && typed !== '';
538
550
  if (kept && stored === null) {
539
- shown.current = `${at}${composed(state)}`;
540
- keep(thread, typed);
551
+ shown.current = `${at}${typed}`;
552
+ keep(thread, { text: typed });
541
553
  return;
542
554
  }
543
555
  const draft = kept
544
- ? {
545
- text: [stored?.text ?? '', typed.text].filter((one) => one !== '').join('\n'),
546
- files: [...(stored?.files ?? []), ...typed.files],
547
- }
548
- : stored;
549
- if (state.text === (draft?.text ?? '') &&
550
- state.attachments.length === 0 &&
551
- (draft?.files.length ?? 0) === 0) {
552
- shown.current = `${at}${composed(state)}`;
556
+ ? [stored?.text ?? '', typed].filter((one) => one !== '').join('\n')
557
+ : (stored?.text ?? '');
558
+ shown.current = `${at}${draft}`;
559
+ if (typed === draft)
553
560
  return;
554
- }
555
561
  seeding.current = true;
556
- composer.setText(draft?.text ?? '');
557
- void composer
558
- .clearAttachments()
559
- .then(() => Promise.all((draft?.files ?? []).map((file) => composer.addAttachment(fileOf(file)))))
560
- .finally(() => {
561
- seeding.current = false;
562
- if (current.current !== thread)
563
- return;
564
- const seeded = composer.getState();
565
- shown.current = `${at}${composed(seeded)}`;
566
- if (kept)
567
- keep(thread, { text: seeded.text, files: filesOf(seeded.attachments) });
568
- reconcile.current();
569
- });
562
+ composer.setText(draft);
563
+ seeding.current = false;
564
+ if (kept)
565
+ keep(thread, { text: draft });
570
566
  };
571
567
  useEffect(() => reconcile.current(), [aui, thread, view]);
572
568
  useEffect(() => {
@@ -577,12 +573,12 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
577
573
  return composer.subscribe(() => {
578
574
  if (seeding.current || !heard.current.startsWith(at))
579
575
  return;
580
- const state = composer.getState();
581
- const next = `${at}${composed(state)}`;
576
+ const typed = composer.getState().text;
577
+ const next = `${at}${typed}`;
582
578
  if (next === shown.current)
583
579
  return;
584
580
  shown.current = next;
585
- keep(thread, { text: state.text, files: filesOf(state.attachments) });
581
+ keep(thread, { text: typed });
586
582
  });
587
583
  }, [aui, thread, keep]);
588
584
  const queued = lanes().map((item) => ({ id: item.id, text: textOf(item.parts) }));
@@ -591,6 +587,7 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
591
587
  conversations,
592
588
  agents,
593
589
  view,
590
+ waiting: awaiting,
594
591
  running,
595
592
  questions,
596
593
  lone,
@@ -603,10 +600,12 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
603
600
  open: openConversation,
604
601
  start,
605
602
  send: (draft) => lined().enqueue(appended(draft)),
603
+ attach: attachTo === null ? null : (files) => attach(attachTo, files),
606
604
  answer,
607
605
  choose,
608
606
  stop,
609
607
  kill,
608
+ retry,
610
609
  done: () => done(),
611
610
  rename: (name) => rename(name),
612
611
  remove: () => remove(),
@@ -1,5 +1,5 @@
1
1
  import { type ReactElement } from 'react';
2
- import { type MdRuntimeClient } from '../client.js';
2
+ import type { MdRuntimeClient } from '../client.js';
3
3
  import type { ChatQuestion } from './questions.js';
4
4
  export declare function forgetAnswers(client: MdRuntimeClient, conversation: string, interaction?: string): Promise<void>;
5
5
  export type ChatQuestionCardProps = {
@@ -1 +1 @@
1
- {"version":3,"file":"question.d.ts","sourceRoot":"","sources":["../../src/chat/question.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAGhE,OAAO,EAAU,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAM5D,OAAO,KAAK,EAAa,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAoB9D,wBAAgB,aAAa,CAC3B,MAAM,EAAE,eAAe,EACvB,YAAY,EAAE,MAAM,EACpB,WAAW,SAAK,GACf,OAAO,CAAC,IAAI,CAAC,CAQf;AAeD,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;CACjC,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,EAAE,QAAQ,EAAE,EAAE,qBAAqB,GAAG,YAAY,CAmHlF"}
1
+ {"version":3,"file":"question.d.ts","sourceRoot":"","sources":["../../src/chat/question.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAGhE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAMpD,OAAO,KAAK,EAAa,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAO9D,wBAAsB,aAAa,CACjC,MAAM,EAAE,eAAe,EACvB,YAAY,EAAE,MAAM,EACpB,WAAW,SAAK,GACf,OAAO,CAAC,IAAI,CAAC,CAOf;AAeD,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;CACjC,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,EAAE,QAAQ,EAAE,EAAE,qBAAqB,GAAG,YAAY,CAmHlF"}
@@ -2,41 +2,30 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
2
2
  import { useContext, useState } from 'react';
3
3
  import Check from 'lucide-react/dist/esm/icons/check.mjs';
4
4
  import CircleHelp from 'lucide-react/dist/esm/icons/circle-help.mjs';
5
- import { inTurn } from '../client.js';
6
5
  import { useObserve } from '../react.js';
7
6
  import { Button, Scoped } from './kit.js';
8
7
  import { Markdown } from './markdown.js';
9
8
  import { Linked, Undelivered } from './message.js';
10
9
  import { useChat, useChatScope } from './provider.js';
11
10
  import { record, text } from './read.js';
12
- const TYPED = 'typed';
13
11
  function answerKey(conversation, interaction) {
14
- return `answer:${conversation}:${interaction}`;
12
+ return `typed:answer:${conversation}:${interaction}`;
15
13
  }
16
- function changeTyped(client, update) {
17
- return inTurn(client, async () => {
18
- const held = record(await client.presentation.read());
19
- const typed = update(record(held[TYPED]));
20
- if (typed !== null)
21
- await client.presentation.write({ ...held, [TYPED]: typed });
22
- });
23
- }
24
- export function forgetAnswers(client, conversation, interaction = '') {
14
+ export async function forgetAnswers(client, conversation, interaction = '') {
25
15
  const at = answerKey(conversation, interaction);
26
- return changeTyped(client, (typed) => {
27
- const kept = Object.entries(typed).filter(([key]) => interaction === '' ? !key.startsWith(at) : key !== at);
28
- return kept.length === Object.keys(typed).length ? null : Object.fromEntries(kept);
29
- });
16
+ const gone = Object.keys(record(await client.presentation.read())).filter((key) => interaction === '' ? key.startsWith(at) : key === at);
17
+ if (gone.length > 0)
18
+ await client.presentation.edit(Object.fromEntries(gone.map((key) => [key, null])));
30
19
  }
31
20
  function useTyped(client, key) {
32
21
  const held = useObserve(client, 'presentation');
33
- const kept = record(record(record(held.state === 'ready' ? held.value : null)[TYPED])[key]);
22
+ const kept = record(record(held.state === 'ready' ? held.value : null)[key]);
34
23
  const [local, setLocal] = useState(null);
35
24
  return [
36
25
  local !== null && local.key === key ? local.value : kept,
37
26
  (next) => {
38
27
  setLocal({ key, value: next });
39
- void changeTyped(client, (typed) => ({ ...typed, [key]: next }));
28
+ void client.presentation.edit({ [key]: next });
40
29
  },
41
30
  ];
42
31
  }
@@ -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,10 +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;
22
+ readonly waiting?: (chat: ChatState) => string | null;
20
23
  readonly messageLength?: number;
21
24
  readonly autoFocus?: boolean;
25
+ readonly decision?: (request: ChatRequest) => ReactNode;
22
26
  };
23
- export declare function Chat({ client, conversation, agent, onOpen, ...look }: ChatProps): ReactElement;
27
+ export declare function Chat({ client, conversation, agent, attachTo, onOpen, ...look }: ChatProps): ReactElement;
24
28
  export type MountedChat = {
25
29
  update(props: ChatProps & {
26
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,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAiQF,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, 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 }), 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;AA6DD,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"}