@agentshouse/mdruntime 0.1.0-cfcbb238a5fa0 → 0.1.0-cfe148b32e3d8

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 (211) hide show
  1. package/AGENTS.md +229 -211
  2. package/README.md +9 -8
  3. package/dist/adapter.d.ts +69 -35
  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/binary.d.ts +0 -5
  9. package/dist/binary.d.ts.map +1 -1
  10. package/dist/binary.js +1 -1
  11. package/dist/bootstrap.d.ts +24 -6
  12. package/dist/bootstrap.d.ts.map +1 -1
  13. package/dist/bootstrap.js +167 -82
  14. package/dist/chain.d.ts +11 -0
  15. package/dist/chain.d.ts.map +1 -0
  16. package/dist/chain.js +64 -0
  17. package/dist/change-set.d.ts +9 -16
  18. package/dist/change-set.d.ts.map +1 -1
  19. package/dist/change-set.js +11 -89
  20. package/dist/change.d.ts +31 -1
  21. package/dist/change.d.ts.map +1 -1
  22. package/dist/change.js +10 -1
  23. package/dist/chat/earlier.d.ts +10 -0
  24. package/dist/chat/earlier.d.ts.map +1 -0
  25. package/dist/chat/earlier.js +54 -0
  26. package/dist/chat/house.d.ts +25 -0
  27. package/dist/chat/house.d.ts.map +1 -0
  28. package/dist/chat/house.js +38 -0
  29. package/dist/chat/input.d.ts +3 -1
  30. package/dist/chat/input.d.ts.map +1 -1
  31. package/dist/chat/input.js +11 -18
  32. package/dist/chat/list.d.ts +2 -1
  33. package/dist/chat/list.d.ts.map +1 -1
  34. package/dist/chat/list.js +45 -5
  35. package/dist/chat/markdown.d.ts +2 -2
  36. package/dist/chat/markdown.d.ts.map +1 -1
  37. package/dist/chat/markdown.js +80 -39
  38. package/dist/chat/message.d.ts +1 -0
  39. package/dist/chat/message.d.ts.map +1 -1
  40. package/dist/chat/message.js +73 -11
  41. package/dist/chat/messages.d.ts +14 -1
  42. package/dist/chat/messages.d.ts.map +1 -1
  43. package/dist/chat/messages.js +79 -24
  44. package/dist/chat/name.d.ts +1 -0
  45. package/dist/chat/name.d.ts.map +1 -1
  46. package/dist/chat/name.js +1 -1
  47. package/dist/chat/opened.d.ts +1 -0
  48. package/dist/chat/opened.d.ts.map +1 -1
  49. package/dist/chat/opened.js +2 -0
  50. package/dist/chat/overlay.d.ts +1 -0
  51. package/dist/chat/overlay.d.ts.map +1 -1
  52. package/dist/chat/overlay.js +11 -5
  53. package/dist/chat/parts.d.ts +1 -0
  54. package/dist/chat/parts.d.ts.map +1 -1
  55. package/dist/chat/parts.js +3 -2
  56. package/dist/chat/pieces.d.ts +62 -0
  57. package/dist/chat/pieces.d.ts.map +1 -0
  58. package/dist/chat/pieces.js +1110 -0
  59. package/dist/chat/provider.d.ts +8 -1
  60. package/dist/chat/provider.d.ts.map +1 -1
  61. package/dist/chat/provider.js +98 -92
  62. package/dist/chat/question.d.ts +1 -1
  63. package/dist/chat/question.d.ts.map +1 -1
  64. package/dist/chat/question.js +7 -18
  65. package/dist/chat/ready.d.ts +5 -2
  66. package/dist/chat/ready.d.ts.map +1 -1
  67. package/dist/chat/ready.js +7 -5
  68. package/dist/chat/room-file.d.ts +8 -0
  69. package/dist/chat/room-file.d.ts.map +1 -0
  70. package/dist/chat/room-file.js +72 -0
  71. package/dist/chat/steady.d.ts +3 -0
  72. package/dist/chat/steady.d.ts.map +1 -0
  73. package/dist/chat/steady.js +26 -0
  74. package/dist/chat/style.d.ts.map +1 -1
  75. package/dist/chat/style.js +6 -1
  76. package/dist/chat.d.ts +3 -2
  77. package/dist/chat.d.ts.map +1 -1
  78. package/dist/chat.js +2 -2
  79. package/dist/client.d.ts +11 -4
  80. package/dist/client.d.ts.map +1 -1
  81. package/dist/client.js +35 -5
  82. package/dist/collection.d.ts +6 -19
  83. package/dist/collection.d.ts.map +1 -1
  84. package/dist/collection.js +30 -287
  85. package/dist/compile.d.ts +16 -0
  86. package/dist/compile.d.ts.map +1 -0
  87. package/dist/compile.js +721 -0
  88. package/dist/connection.d.ts +19 -9
  89. package/dist/connection.d.ts.map +1 -1
  90. package/dist/connection.js +2392 -848
  91. package/dist/conversation.d.ts +14 -3
  92. package/dist/conversation.d.ts.map +1 -1
  93. package/dist/conversation.js +198 -89
  94. package/dist/digest.d.ts +7 -0
  95. package/dist/digest.d.ts.map +1 -0
  96. package/dist/digest.js +113 -0
  97. package/dist/durability.d.ts +3 -1
  98. package/dist/durability.d.ts.map +1 -1
  99. package/dist/entry.d.ts +3 -1
  100. package/dist/entry.d.ts.map +1 -1
  101. package/dist/entry.js +18 -23
  102. package/dist/file.d.ts +2 -10
  103. package/dist/file.d.ts.map +1 -1
  104. package/dist/file.js +3 -120
  105. package/dist/fulltext.d.ts +27 -0
  106. package/dist/fulltext.d.ts.map +1 -0
  107. package/dist/fulltext.js +368 -0
  108. package/dist/host.d.ts +1 -4
  109. package/dist/host.d.ts.map +1 -1
  110. package/dist/host.js +21 -8
  111. package/dist/identity.d.ts +0 -1
  112. package/dist/identity.d.ts.map +1 -1
  113. package/dist/identity.js +0 -3
  114. package/dist/index.d.ts +11 -8
  115. package/dist/index.d.ts.map +1 -1
  116. package/dist/index.js +3 -0
  117. package/dist/live.d.ts +22 -0
  118. package/dist/live.d.ts.map +1 -0
  119. package/dist/live.js +123 -0
  120. package/dist/memory.d.ts +3 -2
  121. package/dist/memory.d.ts.map +1 -1
  122. package/dist/memory.js +30 -20
  123. package/dist/messages.d.ts +28 -0
  124. package/dist/messages.d.ts.map +1 -0
  125. package/dist/messages.js +90 -0
  126. package/dist/name.d.ts +4 -0
  127. package/dist/name.d.ts.map +1 -0
  128. package/dist/name.js +122 -0
  129. package/dist/observation.d.ts +14 -0
  130. package/dist/observation.d.ts.map +1 -1
  131. package/dist/observation.js +93 -3
  132. package/dist/opened.d.ts +22 -0
  133. package/dist/opened.d.ts.map +1 -0
  134. package/dist/opened.js +107 -0
  135. package/dist/outcome.d.ts +34 -4
  136. package/dist/outcome.d.ts.map +1 -1
  137. package/dist/outcome.js +25 -0
  138. package/dist/overlay.d.ts +2 -5
  139. package/dist/overlay.d.ts.map +1 -1
  140. package/dist/overlay.js +87 -172
  141. package/dist/query.d.ts +26 -2
  142. package/dist/query.d.ts.map +1 -1
  143. package/dist/query.js +41 -6
  144. package/dist/reach.d.ts +5 -3
  145. package/dist/reach.d.ts.map +1 -1
  146. package/dist/reach.js +158 -57
  147. package/dist/react.d.ts +1 -2
  148. package/dist/react.d.ts.map +1 -1
  149. package/dist/react.js +2 -14
  150. package/dist/readiness.d.ts +18 -3
  151. package/dist/readiness.d.ts.map +1 -1
  152. package/dist/readiness.js +1 -1
  153. package/dist/reads.d.ts.map +1 -1
  154. package/dist/reads.js +4 -2
  155. package/dist/recovery.d.ts +2 -2
  156. package/dist/recovery.d.ts.map +1 -1
  157. package/dist/recovery.js +8 -7
  158. package/dist/refresh.d.ts +11 -13
  159. package/dist/refresh.d.ts.map +1 -1
  160. package/dist/refresh.js +78 -51
  161. package/dist/replica.d.ts +57 -33
  162. package/dist/replica.d.ts.map +1 -1
  163. package/dist/replica.js +295 -186
  164. package/dist/room-draft.d.ts +3 -1
  165. package/dist/room-draft.d.ts.map +1 -1
  166. package/dist/room-draft.js +29 -22
  167. package/dist/rows.d.ts +29 -30
  168. package/dist/rows.d.ts.map +1 -1
  169. package/dist/rows.js +113 -64
  170. package/dist/save.d.ts +51 -14
  171. package/dist/save.d.ts.map +1 -1
  172. package/dist/save.js +518 -180
  173. package/dist/search.d.ts +23 -42
  174. package/dist/search.d.ts.map +1 -1
  175. package/dist/search.js +28 -182
  176. package/dist/seed.d.ts.map +1 -1
  177. package/dist/seed.js +18 -4
  178. package/dist/shared.d.ts +8 -3
  179. package/dist/shared.d.ts.map +1 -1
  180. package/dist/shared.js +129 -66
  181. package/dist/store.d.ts +97 -88
  182. package/dist/store.d.ts.map +1 -1
  183. package/dist/store.js +335 -659
  184. package/dist/stored.d.ts +145 -0
  185. package/dist/stored.d.ts.map +1 -0
  186. package/dist/stored.js +567 -0
  187. package/dist/tables.d.ts +342 -0
  188. package/dist/tables.d.ts.map +1 -0
  189. package/dist/tables.js +576 -0
  190. package/dist/turn.d.ts +5 -3
  191. package/dist/turn.d.ts.map +1 -1
  192. package/dist/turn.js +51 -21
  193. package/dist/validation.d.ts +30 -0
  194. package/dist/validation.d.ts.map +1 -0
  195. package/dist/validation.js +162 -0
  196. package/dist/windows.d.ts +22 -0
  197. package/dist/windows.d.ts.map +1 -0
  198. package/dist/windows.js +89 -0
  199. package/dist/wire.d.ts +29 -1
  200. package/dist/wire.d.ts.map +1 -1
  201. package/dist/wire.js +8 -1
  202. package/dist/words.d.ts +19 -0
  203. package/dist/words.d.ts.map +1 -0
  204. package/dist/words.js +150 -0
  205. package/package.json +10 -4
  206. package/dist/acquisition.d.ts +0 -14
  207. package/dist/acquisition.d.ts.map +0 -1
  208. package/dist/acquisition.js +0 -24
  209. package/dist/read-side.d.ts +0 -25
  210. package/dist/read-side.d.ts.map +0 -1
  211. package/dist/read-side.js +0 -642
@@ -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,22 +1,25 @@
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';
6
6
  import { chatDraftRevision } from '../identity.js';
7
7
  import { useObserve } from '../react.js';
8
8
  import { accepted, answeredOf, outcomeOf, sender, unanswered, } from './acts.js';
9
- import { askedBefore, chatMessages, contextOf } from './messages.js';
10
- 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';
11
13
  import { commandIn, commandsOf, optionsOf } from './process.js';
12
14
  import { loneOf, questionsOf } from './questions.js';
13
15
  import { record, text } from './read.js';
14
16
  const SHARED = new WeakMap();
17
+ const LATEST = { limit: CHAT_WINDOW };
15
18
  function sharedOf(client) {
16
19
  const held = SHARED.get(client);
17
20
  if (held !== undefined)
18
21
  return held;
19
- const fresh = { overlay: overlay(), created: new Map(), sends: 0 };
22
+ const fresh = { overlay: overlay(), created: new Map(), renewed: new Set(), sends: 0 };
20
23
  SHARED.set(client, fresh);
21
24
  return fresh;
22
25
  }
@@ -88,46 +91,21 @@ function useActs(overlay, online) {
88
91
  }, [overlay, online, tried]);
89
92
  return { ...running, call, clear };
90
93
  }
91
- const ATTACHMENTS = {
92
- accept: '*',
93
- add: ({ file }) => Promise.resolve({
94
- id: generateId(),
95
- type: 'file',
96
- name: file.name,
97
- contentType: file.type,
98
- file,
99
- status: { type: 'requires-action', reason: 'composer-send' },
100
- }),
101
- send: (attachment) => Promise.resolve({ ...attachment, status: { type: 'complete' }, content: [] }),
102
- remove: () => Promise.resolve(),
103
- };
104
- function filesOf(attachments) {
105
- return attachments.flatMap((one) => one.file === undefined ? [] : [{ name: one.name, blob: one.file }]);
106
- }
107
- function fileOf(file) {
108
- return file.blob instanceof File && file.blob.name === file.name
109
- ? file.blob
110
- : new File([file.blob], file.name, { type: file.blob.type });
111
- }
94
+ const AS_IT_IS = (message) => message;
112
95
  function textOf(parts) {
113
96
  return parts.map((part) => (part.type === 'text' ? (part.text ?? '') : '')).join('');
114
97
  }
115
98
  function draftOf(message) {
116
- 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})`;
117
103
  }
118
104
  function appended(draft) {
119
105
  return {
120
106
  role: 'user',
121
107
  content: [{ type: 'text', text: draft.text }],
122
- attachments: draft.files.map((file) => ({
123
- id: generateId(),
124
- type: 'file',
125
- name: file.name,
126
- contentType: file.blob.type,
127
- file: fileOf(file),
128
- status: { type: 'complete' },
129
- content: [],
130
- })),
108
+ attachments: [],
131
109
  metadata: { custom: {} },
132
110
  createdAt: new Date(),
133
111
  parentId: null,
@@ -135,9 +113,6 @@ function appended(draft) {
135
113
  runConfig: undefined,
136
114
  };
137
115
  }
138
- function composed(state) {
139
- return JSON.stringify([state.text, state.attachments.map((one) => one.id)]);
140
- }
141
116
  const ChatContext = createContext(null);
142
117
  const ScopeContext = createContext(null);
143
118
  export function useChatScope() {
@@ -152,7 +127,7 @@ export function useChat() {
152
127
  throw new Error('useChat is called outside a ChatProvider');
153
128
  return chat;
154
129
  }
155
- export function ChatProvider({ client, conversation = null, agent = null, onOpen, children, }) {
130
+ export function ChatProvider({ client, conversation = null, agent = null, attachTo = null, onOpen, children, }) {
156
131
  const shared = sharedOf(client);
157
132
  const asked = JSON.stringify([conversation, agent]);
158
133
  const [followed, setFollowed] = useState(asked);
@@ -172,12 +147,14 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
172
147
  }, []);
173
148
  const listedHeld = ready(useObserve(client, 'conversations'));
174
149
  const agentsHeld = ready(useObserve(client, 'agents'));
175
- const sync = ready(useObserve(client, 'sync-status'));
150
+ const readiness = ready(useObserve(client, 'readiness'));
176
151
  const refusal = ready(useObserve(client, 'connection-refusal'));
177
- const online = sync !== null && !sync.providerUnreachable && refusal === null;
152
+ const online = readiness?.connection !== 'unreachable' && refusal === null;
178
153
  const thread = open.conversation ??
179
154
  (open.agent === null ? null : (shared.created.get(open.agent) ?? newChat(open.agent)));
180
- const held = ready(useObserve(thread === null ? null : client, 'conversation', thread ?? '', {}));
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));
181
158
  const version = useSyncExternalStore(shared.overlay.subscribe, shared.overlay.version);
182
159
  useEffect(() => {
183
160
  if (listedHeld !== null)
@@ -188,7 +165,7 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
188
165
  shared.overlay.heard(held);
189
166
  }, [shared, held, version]);
190
167
  const conversations = useMemo(() => shared.overlay.conversations(listedHeld ?? []), [shared, listedHeld, version]);
191
- 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]);
192
169
  const agents = agentsHeld ?? [];
193
170
  const known = useRef(agents);
194
171
  known.current = agents;
@@ -198,6 +175,10 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
198
175
  const lone = loneOf(questions);
199
176
  const commands = useMemo(() => commandsOf(view), [view]);
200
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]);
201
182
  const sending = useActs(shared.overlay, online);
202
183
  const behind = useActs(shared.overlay, online);
203
184
  const acting = useActs(shared.overlay, online);
@@ -220,7 +201,7 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
220
201
  own.current = [...own.current, `${to}\u0000${revision ?? ''}`];
221
202
  }, []);
222
203
  const keep = useCallback((to, draft) => {
223
- const revision = draft.text === '' && draft.files.length === 0 ? null : chatDraftRevision();
204
+ const revision = draft.text === '' ? null : chatDraftRevision();
224
205
  noted(to, revision);
225
206
  void (revision === null
226
207
  ? client.chatDraft.discard(to)
@@ -265,6 +246,7 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
265
246
  created: new Date().toISOString(),
266
247
  finished: null,
267
248
  outcome: null,
249
+ waiting: false,
268
250
  state: 'idle',
269
251
  started: null,
270
252
  }));
@@ -281,13 +263,6 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
281
263
  return result;
282
264
  }, sentMessage(key, drafted, said, null));
283
265
  };
284
- const returned = async (to, one) => {
285
- const now = (await client.conversation.read(to)).chatDraft;
286
- await client.chatDraft.write(to, {
287
- text: now === null || now.text === '' ? one.text : `${one.text}\n${now.text}`,
288
- files: [...one.files, ...(now?.files ?? [])],
289
- });
290
- };
291
266
  const sent = () => {
292
267
  shared.sends += 1;
293
268
  return `sent ${shared.sends}`;
@@ -326,6 +301,26 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
326
301
  return Promise.resolve(false);
327
302
  return control('conversation.setOption', { conversation_id: to, option, value }, optionChosen(to, option, value));
328
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
+ };
329
324
  const done = (to = opened.current.conversation) => to === null
330
325
  ? Promise.resolve(false)
331
326
  : control('conversation.markDone', { conversation_id: to }, conversationChanged(to, { finished: new Date().toISOString() }, (one) => one.finished !== null));
@@ -401,7 +396,9 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
401
396
  const aui = useExternalStoreRuntime({
402
397
  messages,
403
398
  isRunning: running,
404
- convertMessage: (message) => message,
399
+ hasEarlier: paged.hasEarlier,
400
+ onLoadEarlier: paged.loadEarlier,
401
+ convertMessage: AS_IT_IS,
405
402
  queue: lined(),
406
403
  onNew: async (message) => lined().enqueue(message),
407
404
  onCancel: async () => {
@@ -413,12 +410,11 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
413
410
  const said = askedBefore(view, parent);
414
411
  if (said === null)
415
412
  return;
416
- const draft = { text: said, files: [] };
413
+ const draft = { text: said };
417
414
  const into = thread;
418
415
  deliverDraft(draft, () => back(draft, into), () => undefined);
419
416
  },
420
417
  adapters: {
421
- attachments: ATTACHMENTS,
422
418
  threadList: {
423
419
  ...(thread === null ? {} : { threadId: thread }),
424
420
  threads: threads.regular,
@@ -443,15 +439,39 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
443
439
  });
444
440
  function back(one, into) {
445
441
  if (current.current !== into) {
446
- void returned(into, one);
442
+ void client.chatDraft.prepend(into, one);
447
443
  return;
448
444
  }
449
445
  const composer = aui.thread.composer;
450
446
  const now = composer.getState().text;
451
447
  composer.setText(now === '' ? one.text : `${one.text}\n${now}`);
452
- for (const file of one.files)
453
- void composer.addAttachment(fileOf(file));
454
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
+ };
455
475
  function taken(message) {
456
476
  const said = textOf(message.content);
457
477
  if (lone === null || commandIn(said, commands))
@@ -519,7 +539,7 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
519
539
  const message = unqueue(id);
520
540
  if (thread === null || item === undefined)
521
541
  return;
522
- back(message === undefined ? { text: textOf(item.parts), files: [] } : draftOf(message), thread);
542
+ back(message === undefined ? { text: textOf(item.parts) } : draftOf(message), thread);
523
543
  };
524
544
  const reconcile = useRef(() => undefined);
525
545
  reconcile.current = () => {
@@ -538,44 +558,25 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
538
558
  }
539
559
  own.current = own.current.filter((one) => !one.startsWith(at));
540
560
  const composer = aui.thread.composer;
541
- const state = composer.getState();
561
+ const typed = composer.getState().text;
542
562
  const stored = view.chatDraft;
543
- const typed = { text: state.text, files: filesOf(state.attachments) };
544
- const kept = !known && (typed.text !== '' || typed.files.length > 0);
563
+ const kept = !known && typed !== '';
545
564
  if (kept && stored === null) {
546
- shown.current = `${at}${composed(state)}`;
547
- keep(thread, typed);
565
+ shown.current = `${at}${typed}`;
566
+ keep(thread, { text: typed });
548
567
  return;
549
568
  }
550
569
  const draft = kept
551
- ? {
552
- text: [stored?.text ?? '', typed.text].filter((one) => one !== '').join('\n'),
553
- files: [...(stored?.files ?? []), ...typed.files],
554
- }
555
- : stored;
556
- if (state.text === (draft?.text ?? '') &&
557
- state.attachments.length === 0 &&
558
- (draft?.files.length ?? 0) === 0) {
559
- 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)
560
574
  return;
561
- }
562
575
  seeding.current = true;
563
- composer.setText(draft?.text ?? '');
564
- void composer
565
- .clearAttachments()
566
- .then(() => Promise.all((draft?.files ?? []).map((file) => composer.addAttachment(fileOf(file)))))
567
- .finally(() => {
568
- seeding.current = false;
569
- if (current.current !== thread) {
570
- reconcile.current();
571
- return;
572
- }
573
- const seeded = composer.getState();
574
- shown.current = `${at}${composed(seeded)}`;
575
- if (kept)
576
- keep(thread, { text: seeded.text, files: filesOf(seeded.attachments) });
577
- reconcile.current();
578
- });
576
+ composer.setText(draft);
577
+ seeding.current = false;
578
+ if (kept)
579
+ keep(thread, { text: draft });
579
580
  };
580
581
  useEffect(() => reconcile.current(), [aui, thread, view]);
581
582
  useEffect(() => {
@@ -586,12 +587,12 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
586
587
  return composer.subscribe(() => {
587
588
  if (seeding.current || !heard.current.startsWith(at))
588
589
  return;
589
- const state = composer.getState();
590
- const next = `${at}${composed(state)}`;
590
+ const typed = composer.getState().text;
591
+ const next = `${at}${typed}`;
591
592
  if (next === shown.current)
592
593
  return;
593
594
  shown.current = next;
594
- keep(thread, { text: state.text, files: filesOf(state.attachments) });
595
+ keep(thread, { text: typed });
595
596
  });
596
597
  }, [aui, thread, keep]);
597
598
  const queued = lanes().map((item) => ({ id: item.id, text: textOf(item.parts) }));
@@ -600,6 +601,7 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
600
601
  conversations,
601
602
  agents,
602
603
  view,
604
+ waiting: awaiting,
603
605
  running,
604
606
  questions,
605
607
  lone,
@@ -609,13 +611,17 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
609
611
  queued,
610
612
  sending: { busy: sending.busy, outcome: sending.outcome, again },
611
613
  acting: { busy: acting.busy, outcome: acting.outcome },
614
+ renewed: open.conversation !== null && shared.renewed.has(open.conversation),
612
615
  open: openConversation,
613
616
  start,
614
617
  send: (draft) => lined().enqueue(appended(draft)),
618
+ attach: attachTo === null ? null : (files) => attach(attachTo, files),
615
619
  answer,
616
620
  choose,
617
621
  stop,
618
622
  kill,
623
+ retry,
624
+ renew,
619
625
  done: () => done(),
620
626
  rename: (name) => rename(name),
621
627
  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,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"}