@agentshouse/mdruntime 0.1.0-c1db74d14e5fa → 0.1.0-c210758b77baa

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 (220) hide show
  1. package/AGENTS.md +268 -251
  2. package/README.md +9 -8
  3. package/dist/adapter.d.ts +76 -40
  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 +26 -7
  12. package/dist/bootstrap.d.ts.map +1 -1
  13. package/dist/bootstrap.js +148 -78
  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 -88
  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/kit.d.ts +2 -1
  33. package/dist/chat/kit.d.ts.map +1 -1
  34. package/dist/chat/kit.js +3 -3
  35. package/dist/chat/list.d.ts +3 -1
  36. package/dist/chat/list.d.ts.map +1 -1
  37. package/dist/chat/list.js +47 -6
  38. package/dist/chat/markdown.d.ts +2 -2
  39. package/dist/chat/markdown.d.ts.map +1 -1
  40. package/dist/chat/markdown.js +83 -40
  41. package/dist/chat/message.d.ts +1 -0
  42. package/dist/chat/message.d.ts.map +1 -1
  43. package/dist/chat/message.js +73 -11
  44. package/dist/chat/messages.d.ts +15 -1
  45. package/dist/chat/messages.d.ts.map +1 -1
  46. package/dist/chat/messages.js +82 -23
  47. package/dist/chat/name.d.ts +1 -0
  48. package/dist/chat/name.d.ts.map +1 -1
  49. package/dist/chat/name.js +1 -1
  50. package/dist/chat/opened.d.ts +1 -0
  51. package/dist/chat/opened.d.ts.map +1 -1
  52. package/dist/chat/opened.js +2 -0
  53. package/dist/chat/overlay.d.ts +1 -0
  54. package/dist/chat/overlay.d.ts.map +1 -1
  55. package/dist/chat/overlay.js +11 -5
  56. package/dist/chat/parts.d.ts +1 -0
  57. package/dist/chat/parts.d.ts.map +1 -1
  58. package/dist/chat/parts.js +3 -2
  59. package/dist/chat/pieces.d.ts +62 -0
  60. package/dist/chat/pieces.d.ts.map +1 -0
  61. package/dist/chat/pieces.js +1110 -0
  62. package/dist/chat/provider.d.ts +9 -2
  63. package/dist/chat/provider.d.ts.map +1 -1
  64. package/dist/chat/provider.js +121 -106
  65. package/dist/chat/question.d.ts +1 -1
  66. package/dist/chat/question.d.ts.map +1 -1
  67. package/dist/chat/question.js +7 -18
  68. package/dist/chat/ready.d.ts +5 -1
  69. package/dist/chat/ready.d.ts.map +1 -1
  70. package/dist/chat/ready.js +7 -5
  71. package/dist/chat/room-file.d.ts +8 -0
  72. package/dist/chat/room-file.d.ts.map +1 -0
  73. package/dist/chat/room-file.js +72 -0
  74. package/dist/chat/steady.d.ts +3 -0
  75. package/dist/chat/steady.d.ts.map +1 -0
  76. package/dist/chat/steady.js +26 -0
  77. package/dist/chat/style.d.ts.map +1 -1
  78. package/dist/chat/style.js +6 -1
  79. package/dist/chat.d.ts +3 -2
  80. package/dist/chat.d.ts.map +1 -1
  81. package/dist/chat.js +2 -2
  82. package/dist/client.d.ts +15 -6
  83. package/dist/client.d.ts.map +1 -1
  84. package/dist/client.js +47 -8
  85. package/dist/collection.d.ts +6 -19
  86. package/dist/collection.d.ts.map +1 -1
  87. package/dist/collection.js +30 -287
  88. package/dist/compile.d.ts +16 -0
  89. package/dist/compile.d.ts.map +1 -0
  90. package/dist/compile.js +721 -0
  91. package/dist/connection.d.ts +25 -12
  92. package/dist/connection.d.ts.map +1 -1
  93. package/dist/connection.js +2615 -946
  94. package/dist/conversation.d.ts +18 -3
  95. package/dist/conversation.d.ts.map +1 -1
  96. package/dist/conversation.js +341 -107
  97. package/dist/digest.d.ts +7 -0
  98. package/dist/digest.d.ts.map +1 -0
  99. package/dist/digest.js +113 -0
  100. package/dist/durability.d.ts +3 -5
  101. package/dist/durability.d.ts.map +1 -1
  102. package/dist/durability.js +5 -0
  103. package/dist/entry.d.ts +3 -1
  104. package/dist/entry.d.ts.map +1 -1
  105. package/dist/entry.js +18 -23
  106. package/dist/file.d.ts +2 -10
  107. package/dist/file.d.ts.map +1 -1
  108. package/dist/file.js +3 -120
  109. package/dist/fulltext.d.ts +27 -0
  110. package/dist/fulltext.d.ts.map +1 -0
  111. package/dist/fulltext.js +368 -0
  112. package/dist/host.d.ts +10 -8
  113. package/dist/host.d.ts.map +1 -1
  114. package/dist/host.js +95 -18
  115. package/dist/identity.d.ts +0 -1
  116. package/dist/identity.d.ts.map +1 -1
  117. package/dist/identity.js +0 -3
  118. package/dist/index.d.ts +15 -11
  119. package/dist/index.d.ts.map +1 -1
  120. package/dist/index.js +5 -1
  121. package/dist/live.d.ts +22 -0
  122. package/dist/live.d.ts.map +1 -0
  123. package/dist/live.js +123 -0
  124. package/dist/memory.d.ts +8 -3
  125. package/dist/memory.d.ts.map +1 -1
  126. package/dist/memory.js +43 -25
  127. package/dist/messages.d.ts +28 -0
  128. package/dist/messages.d.ts.map +1 -0
  129. package/dist/messages.js +90 -0
  130. package/dist/model.d.ts +3 -2
  131. package/dist/model.d.ts.map +1 -1
  132. package/dist/model.js +1 -1
  133. package/dist/name.d.ts +4 -0
  134. package/dist/name.d.ts.map +1 -0
  135. package/dist/name.js +122 -0
  136. package/dist/observation.d.ts +14 -0
  137. package/dist/observation.d.ts.map +1 -1
  138. package/dist/observation.js +93 -3
  139. package/dist/opened.d.ts +22 -0
  140. package/dist/opened.d.ts.map +1 -0
  141. package/dist/opened.js +107 -0
  142. package/dist/outcome.d.ts +34 -4
  143. package/dist/outcome.d.ts.map +1 -1
  144. package/dist/outcome.js +25 -0
  145. package/dist/overlay.d.ts +3 -5
  146. package/dist/overlay.d.ts.map +1 -1
  147. package/dist/overlay.js +95 -156
  148. package/dist/query.d.ts +33 -2
  149. package/dist/query.d.ts.map +1 -1
  150. package/dist/query.js +48 -7
  151. package/dist/reach.d.ts +6 -5
  152. package/dist/reach.d.ts.map +1 -1
  153. package/dist/reach.js +170 -62
  154. package/dist/react.d.ts +3 -3
  155. package/dist/react.d.ts.map +1 -1
  156. package/dist/react.js +7 -17
  157. package/dist/readiness.d.ts +20 -9
  158. package/dist/readiness.d.ts.map +1 -1
  159. package/dist/readiness.js +6 -6
  160. package/dist/reads.d.ts +11 -0
  161. package/dist/reads.d.ts.map +1 -0
  162. package/dist/reads.js +100 -0
  163. package/dist/recovery.d.ts +2 -2
  164. package/dist/recovery.d.ts.map +1 -1
  165. package/dist/recovery.js +8 -7
  166. package/dist/refresh.d.ts +16 -15
  167. package/dist/refresh.d.ts.map +1 -1
  168. package/dist/refresh.js +112 -45
  169. package/dist/replica.d.ts +57 -33
  170. package/dist/replica.d.ts.map +1 -1
  171. package/dist/replica.js +295 -177
  172. package/dist/room-draft.d.ts +17 -2
  173. package/dist/room-draft.d.ts.map +1 -1
  174. package/dist/room-draft.js +65 -25
  175. package/dist/rows.d.ts +29 -29
  176. package/dist/rows.d.ts.map +1 -1
  177. package/dist/rows.js +113 -62
  178. package/dist/save.d.ts +51 -14
  179. package/dist/save.d.ts.map +1 -1
  180. package/dist/save.js +518 -180
  181. package/dist/search.d.ts +32 -43
  182. package/dist/search.d.ts.map +1 -1
  183. package/dist/search.js +37 -168
  184. package/dist/seed.d.ts +16 -0
  185. package/dist/seed.d.ts.map +1 -0
  186. package/dist/seed.js +75 -0
  187. package/dist/shared.d.ts +8 -3
  188. package/dist/shared.d.ts.map +1 -1
  189. package/dist/shared.js +129 -66
  190. package/dist/store.d.ts +99 -88
  191. package/dist/store.d.ts.map +1 -1
  192. package/dist/store.js +335 -641
  193. package/dist/stored.d.ts +145 -0
  194. package/dist/stored.d.ts.map +1 -0
  195. package/dist/stored.js +567 -0
  196. package/dist/tables.d.ts +354 -0
  197. package/dist/tables.d.ts.map +1 -0
  198. package/dist/tables.js +624 -0
  199. package/dist/turn.d.ts +5 -3
  200. package/dist/turn.d.ts.map +1 -1
  201. package/dist/turn.js +51 -21
  202. package/dist/validation.d.ts +30 -0
  203. package/dist/validation.d.ts.map +1 -0
  204. package/dist/validation.js +162 -0
  205. package/dist/windows.d.ts +22 -0
  206. package/dist/windows.d.ts.map +1 -0
  207. package/dist/windows.js +89 -0
  208. package/dist/wire.d.ts +163 -33
  209. package/dist/wire.d.ts.map +1 -1
  210. package/dist/wire.js +54 -32
  211. package/dist/words.d.ts +19 -0
  212. package/dist/words.d.ts.map +1 -0
  213. package/dist/words.js +150 -0
  214. package/package.json +11 -5
  215. package/dist/acquisition.d.ts +0 -14
  216. package/dist/acquisition.d.ts.map +0 -1
  217. package/dist/acquisition.js +0 -24
  218. package/dist/read-side.d.ts +0 -25
  219. package/dist/read-side.d.ts.map +0 -1
  220. package/dist/read-side.js +0 -639
@@ -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;
@@ -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,27 +1,28 @@
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)
17
21
  return held;
18
- const fresh = { overlay: overlay(), created: new Map(), sends: 0 };
22
+ const fresh = { overlay: overlay(), created: new Map(), renewed: new Set(), sends: 0 };
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,26 @@ 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
+ };
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
+ };
322
324
  const done = (to = opened.current.conversation) => to === null
323
325
  ? Promise.resolve(false)
324
326
  : control('conversation.markDone', { conversation_id: to }, conversationChanged(to, { finished: new Date().toISOString() }, (one) => one.finished !== null));
@@ -394,7 +396,9 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
394
396
  const aui = useExternalStoreRuntime({
395
397
  messages,
396
398
  isRunning: running,
397
- convertMessage: (message) => message,
399
+ hasEarlier: paged.hasEarlier,
400
+ onLoadEarlier: paged.loadEarlier,
401
+ convertMessage: AS_IT_IS,
398
402
  queue: lined(),
399
403
  onNew: async (message) => lined().enqueue(message),
400
404
  onCancel: async () => {
@@ -406,12 +410,11 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
406
410
  const said = askedBefore(view, parent);
407
411
  if (said === null)
408
412
  return;
409
- const draft = { text: said, files: [] };
413
+ const draft = { text: said };
410
414
  const into = thread;
411
415
  deliverDraft(draft, () => back(draft, into), () => undefined);
412
416
  },
413
417
  adapters: {
414
- attachments: ATTACHMENTS,
415
418
  threadList: {
416
419
  ...(thread === null ? {} : { threadId: thread }),
417
420
  threads: threads.regular,
@@ -436,15 +439,39 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
436
439
  });
437
440
  function back(one, into) {
438
441
  if (current.current !== into) {
439
- void returned(into, one);
442
+ void client.chatDraft.prepend(into, one);
440
443
  return;
441
444
  }
442
445
  const composer = aui.thread.composer;
443
446
  const now = composer.getState().text;
444
447
  composer.setText(now === '' ? one.text : `${one.text}\n${now}`);
445
- for (const file of one.files)
446
- void composer.addAttachment(fileOf(file));
447
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
+ };
448
475
  function taken(message) {
449
476
  const said = textOf(message.content);
450
477
  if (lone === null || commandIn(said, commands))
@@ -512,7 +539,7 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
512
539
  const message = unqueue(id);
513
540
  if (thread === null || item === undefined)
514
541
  return;
515
- back(message === undefined ? { text: textOf(item.parts), files: [] } : draftOf(message), thread);
542
+ back(message === undefined ? { text: textOf(item.parts) } : draftOf(message), thread);
516
543
  };
517
544
  const reconcile = useRef(() => undefined);
518
545
  reconcile.current = () => {
@@ -531,42 +558,25 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
531
558
  }
532
559
  own.current = own.current.filter((one) => !one.startsWith(at));
533
560
  const composer = aui.thread.composer;
534
- const state = composer.getState();
561
+ const typed = composer.getState().text;
535
562
  const stored = view.chatDraft;
536
- const typed = { text: state.text, files: filesOf(state.attachments) };
537
- const kept = !known && (typed.text !== '' || typed.files.length > 0);
563
+ const kept = !known && typed !== '';
538
564
  if (kept && stored === null) {
539
- shown.current = `${at}${composed(state)}`;
540
- keep(thread, typed);
565
+ shown.current = `${at}${typed}`;
566
+ keep(thread, { text: typed });
541
567
  return;
542
568
  }
543
569
  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)}`;
570
+ ? [stored?.text ?? '', typed].filter((one) => one !== '').join('\n')
571
+ : (stored?.text ?? '');
572
+ shown.current = `${at}${draft}`;
573
+ if (typed === draft)
553
574
  return;
554
- }
555
575
  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
- });
576
+ composer.setText(draft);
577
+ seeding.current = false;
578
+ if (kept)
579
+ keep(thread, { text: draft });
570
580
  };
571
581
  useEffect(() => reconcile.current(), [aui, thread, view]);
572
582
  useEffect(() => {
@@ -577,12 +587,12 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
577
587
  return composer.subscribe(() => {
578
588
  if (seeding.current || !heard.current.startsWith(at))
579
589
  return;
580
- const state = composer.getState();
581
- const next = `${at}${composed(state)}`;
590
+ const typed = composer.getState().text;
591
+ const next = `${at}${typed}`;
582
592
  if (next === shown.current)
583
593
  return;
584
594
  shown.current = next;
585
- keep(thread, { text: state.text, files: filesOf(state.attachments) });
595
+ keep(thread, { text: typed });
586
596
  });
587
597
  }, [aui, thread, keep]);
588
598
  const queued = lanes().map((item) => ({ id: item.id, text: textOf(item.parts) }));
@@ -591,6 +601,7 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
591
601
  conversations,
592
602
  agents,
593
603
  view,
604
+ waiting: awaiting,
594
605
  running,
595
606
  questions,
596
607
  lone,
@@ -600,13 +611,17 @@ export function ChatProvider({ client, conversation = null, agent = null, onOpen
600
611
  queued,
601
612
  sending: { busy: sending.busy, outcome: sending.outcome, again },
602
613
  acting: { busy: acting.busy, outcome: acting.outcome },
614
+ renewed: open.conversation !== null && shared.renewed.has(open.conversation),
603
615
  open: openConversation,
604
616
  start,
605
617
  send: (draft) => lined().enqueue(appended(draft)),
618
+ attach: attachTo === null ? null : (files) => attach(attachTo, files),
606
619
  answer,
607
620
  choose,
608
621
  stop,
609
622
  kill,
623
+ retry,
624
+ renew,
610
625
  done: () => done(),
611
626
  rename: (name) => rename(name),
612
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,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);