@agentshouse/mdruntime 0.1.0-ccbe92df1c4f6 → 0.1.0-ccd098ff75bbf

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 (131) hide show
  1. package/README.md +10 -8
  2. package/dist/adapter.d.ts +1 -1
  3. package/dist/adapter.d.ts.map +1 -1
  4. package/dist/attached-model.d.ts +2 -1
  5. package/dist/attached-model.d.ts.map +1 -1
  6. package/dist/attached-model.js +10 -3
  7. package/dist/bootstrap.d.ts +1 -2
  8. package/dist/bootstrap.d.ts.map +1 -1
  9. package/dist/bootstrap.js +7 -8
  10. package/dist/client.d.ts +2 -1
  11. package/dist/client.d.ts.map +1 -1
  12. package/dist/client.js +2 -1
  13. package/dist/collection.d.ts.map +1 -1
  14. package/dist/collection.js +1 -2
  15. package/dist/compile.d.ts.map +1 -1
  16. package/dist/compile.js +31 -12
  17. package/dist/connection.d.ts +1 -1
  18. package/dist/connection.d.ts.map +1 -1
  19. package/dist/connection.js +150 -157
  20. package/dist/conversation.d.ts.map +1 -1
  21. package/dist/conversation.js +5 -2
  22. package/dist/host.d.ts.map +1 -1
  23. package/dist/host.js +27 -7
  24. package/dist/memory.d.ts +1 -1
  25. package/dist/memory.d.ts.map +1 -1
  26. package/dist/memory.js +2 -6
  27. package/dist/model.d.ts.map +1 -1
  28. package/dist/model.js +1 -1
  29. package/dist/reach.d.ts.map +1 -1
  30. package/dist/reach.js +16 -9
  31. package/dist/readiness.d.ts +1 -0
  32. package/dist/readiness.d.ts.map +1 -1
  33. package/dist/readiness.js +4 -4
  34. package/dist/refresh.d.ts.map +1 -1
  35. package/dist/refresh.js +1 -5
  36. package/dist/replica.d.ts +1 -2
  37. package/dist/replica.d.ts.map +1 -1
  38. package/dist/replica.js +2 -2
  39. package/dist/room-draft.d.ts +1 -0
  40. package/dist/room-draft.d.ts.map +1 -1
  41. package/dist/room-draft.js +33 -0
  42. package/dist/rows.d.ts +11 -4
  43. package/dist/rows.d.ts.map +1 -1
  44. package/dist/rows.js +73 -54
  45. package/dist/store.d.ts +0 -1
  46. package/dist/store.d.ts.map +1 -1
  47. package/dist/stored.d.ts.map +1 -1
  48. package/dist/stored.js +6 -16
  49. package/dist/tables.d.ts +10 -0
  50. package/dist/tables.d.ts.map +1 -1
  51. package/dist/tables.js +46 -2
  52. package/package.json +10 -17
  53. package/AGENTS.md +0 -317
  54. package/dist/chat/acts.d.ts +0 -33
  55. package/dist/chat/acts.d.ts.map +0 -1
  56. package/dist/chat/acts.js +0 -36
  57. package/dist/chat/context.d.ts +0 -3
  58. package/dist/chat/context.d.ts.map +0 -1
  59. package/dist/chat/context.js +0 -10
  60. package/dist/chat/earlier.d.ts +0 -10
  61. package/dist/chat/earlier.d.ts.map +0 -1
  62. package/dist/chat/earlier.js +0 -54
  63. package/dist/chat/house.d.ts +0 -25
  64. package/dist/chat/house.d.ts.map +0 -1
  65. package/dist/chat/house.js +0 -38
  66. package/dist/chat/input.d.ts +0 -11
  67. package/dist/chat/input.d.ts.map +0 -1
  68. package/dist/chat/input.js +0 -92
  69. package/dist/chat/kit.d.ts +0 -61
  70. package/dist/chat/kit.d.ts.map +0 -1
  71. package/dist/chat/kit.js +0 -123
  72. package/dist/chat/lasting.d.ts +0 -6
  73. package/dist/chat/lasting.d.ts.map +0 -1
  74. package/dist/chat/lasting.js +0 -19
  75. package/dist/chat/list.d.ts +0 -28
  76. package/dist/chat/list.d.ts.map +0 -1
  77. package/dist/chat/list.js +0 -103
  78. package/dist/chat/markdown.d.ts +0 -20
  79. package/dist/chat/markdown.d.ts.map +0 -1
  80. package/dist/chat/markdown.js +0 -229
  81. package/dist/chat/message.d.ts +0 -7
  82. package/dist/chat/message.d.ts.map +0 -1
  83. package/dist/chat/message.js +0 -254
  84. package/dist/chat/messages.d.ts +0 -35
  85. package/dist/chat/messages.d.ts.map +0 -1
  86. package/dist/chat/messages.js +0 -210
  87. package/dist/chat/name.d.ts +0 -7
  88. package/dist/chat/name.d.ts.map +0 -1
  89. package/dist/chat/name.js +0 -37
  90. package/dist/chat/opened.d.ts +0 -12
  91. package/dist/chat/opened.d.ts.map +0 -1
  92. package/dist/chat/opened.js +0 -19
  93. package/dist/chat/overlay.d.ts +0 -32
  94. package/dist/chat/overlay.d.ts.map +0 -1
  95. package/dist/chat/overlay.js +0 -103
  96. package/dist/chat/parts.d.ts +0 -58
  97. package/dist/chat/parts.d.ts.map +0 -1
  98. package/dist/chat/parts.js +0 -120
  99. package/dist/chat/pieces.d.ts +0 -62
  100. package/dist/chat/pieces.d.ts.map +0 -1
  101. package/dist/chat/pieces.js +0 -1110
  102. package/dist/chat/process.d.ts +0 -20
  103. package/dist/chat/process.d.ts.map +0 -1
  104. package/dist/chat/process.js +0 -32
  105. package/dist/chat/provider.d.ts +0 -70
  106. package/dist/chat/provider.d.ts.map +0 -1
  107. package/dist/chat/provider.js +0 -635
  108. package/dist/chat/question.d.ts +0 -9
  109. package/dist/chat/question.d.ts.map +0 -1
  110. package/dist/chat/question.js +0 -69
  111. package/dist/chat/questions.d.ts +0 -31
  112. package/dist/chat/questions.d.ts.map +0 -1
  113. package/dist/chat/questions.js +0 -111
  114. package/dist/chat/read.d.ts +0 -5
  115. package/dist/chat/read.d.ts.map +0 -1
  116. package/dist/chat/read.js +0 -13
  117. package/dist/chat/ready.d.ts +0 -37
  118. package/dist/chat/ready.d.ts.map +0 -1
  119. package/dist/chat/ready.js +0 -93
  120. package/dist/chat/room-file.d.ts +0 -8
  121. package/dist/chat/room-file.d.ts.map +0 -1
  122. package/dist/chat/room-file.js +0 -72
  123. package/dist/chat/steady.d.ts +0 -3
  124. package/dist/chat/steady.d.ts.map +0 -1
  125. package/dist/chat/steady.js +0 -26
  126. package/dist/chat/style.d.ts +0 -4
  127. package/dist/chat/style.d.ts.map +0 -1
  128. package/dist/chat/style.js +0 -307
  129. package/dist/chat.d.ts +0 -15
  130. package/dist/chat.d.ts.map +0 -1
  131. package/dist/chat.js +0 -8
@@ -1,635 +0,0 @@
1
- import { createContext, createElement, useCallback, useContext, useEffect, useMemo, useReducer, useRef, useState, useSyncExternalStore, } from 'react';
2
- import { AssistantRuntimeProvider, createMessageQueue, useExternalStoreRuntime, } from '@assistant-ui/react';
3
- import { attempts } from '../attempt.js';
4
- import { newChat, } from '../conversation.js';
5
- import { expectedList } from '../expectation.js';
6
- import { chatDraftRevision } from '../identity.js';
7
- import { useObserve } from '../react.js';
8
- import { accepted, answeredOf, outcomeOf, sender, unanswered, } from './acts.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';
13
- import { commandIn, commandsOf, optionsOf } from './process.js';
14
- import { loneOf, questionsOf } from './questions.js';
15
- import { record, text } from './read.js';
16
- const SHARED = new WeakMap();
17
- const LATEST = { limit: CHAT_WINDOW };
18
- function sharedOf(client) {
19
- const held = SHARED.get(client);
20
- if (held !== undefined)
21
- return held;
22
- const fresh = { overlay: overlay(), created: new Map(), renewed: new Set(), sends: 0 };
23
- SHARED.set(client, fresh);
24
- return fresh;
25
- }
26
- function ready(observed) {
27
- return observed.state === 'ready' ? observed.value : null;
28
- }
29
- function turnOf(result) {
30
- return accepted(result) ? text(record(result.result), 'turn') : null;
31
- }
32
- async function deliver(client, send, conversation, said, key, idle) {
33
- const result = await send.numbered('conversation.send', { conversation, key }, (operation) => client.conversation.send(conversation, operation, said));
34
- if (accepted(result))
35
- send.expect(sentMessage(key, [conversation], said, turnOf(result)));
36
- else if (!unanswered(result))
37
- idle();
38
- return result;
39
- }
40
- const IDLE = { busy: false, outcome: null };
41
- const SENDING = { state: 'sending' };
42
- function useActs(overlay, online) {
43
- const [running, setRunning] = useState(IDLE);
44
- const [tried] = useState(() => attempts());
45
- const latest = useRef(0);
46
- const mounted = useRef(true);
47
- useEffect(() => {
48
- mounted.current = true;
49
- return () => {
50
- mounted.current = false;
51
- };
52
- }, []);
53
- const clear = useCallback(() => {
54
- latest.current += 1;
55
- setRunning(IDLE);
56
- }, []);
57
- const call = useCallback((steps, expected = null, then) => {
58
- latest.current += 1;
59
- const mine = latest.current;
60
- const act = overlay.begin();
61
- const drawn = typeof expected === 'function' ? null : expected;
62
- overlay.expect(act, drawn);
63
- setRunning({ busy: true, outcome: expectedList(drawn).length > 0 ? null : SENDING });
64
- const attempt = tried.begin(act);
65
- const send = sender({
66
- online,
67
- identity: attempt.identity,
68
- expect: (expecting) => overlay.expect(overlay.begin(), expecting),
69
- draw: (expecting) => overlay.expect(act, expecting),
70
- });
71
- return steps(send)
72
- .catch(() => ({
73
- kind: 'transport-uncertainty',
74
- code: 'transport-uncertainty',
75
- fields: {},
76
- retryable: true,
77
- }))
78
- .then((result) => {
79
- if (accepted(result) && typeof expected === 'function') {
80
- overlay.expect(act, expected(result.result));
81
- }
82
- attempt.settle(answeredOf(result), (one) => overlay.drop(one));
83
- if (!mounted.current || latest.current !== mine)
84
- return accepted(result);
85
- if (accepted(result))
86
- then?.(result.result);
87
- if (latest.current === mine)
88
- setRunning({ busy: false, outcome: outcomeOf(result) });
89
- return accepted(result);
90
- });
91
- }, [overlay, online, tried]);
92
- return { ...running, call, clear };
93
- }
94
- const AS_IT_IS = (message) => message;
95
- function textOf(parts) {
96
- return parts.map((part) => (part.type === 'text' ? (part.text ?? '') : '')).join('');
97
- }
98
- function draftOf(message) {
99
- return { text: textOf(message.content) };
100
- }
101
- function linkOf(path) {
102
- return `[${path.slice(path.lastIndexOf('/') + 1)}](${path})`;
103
- }
104
- function appended(draft) {
105
- return {
106
- role: 'user',
107
- content: [{ type: 'text', text: draft.text }],
108
- attachments: [],
109
- metadata: { custom: {} },
110
- createdAt: new Date(),
111
- parentId: null,
112
- sourceId: null,
113
- runConfig: undefined,
114
- };
115
- }
116
- const ChatContext = createContext(null);
117
- const ScopeContext = createContext(null);
118
- export function useChatScope() {
119
- const scope = useContext(ScopeContext);
120
- if (scope === null)
121
- throw new Error('useChat is called outside a ChatProvider');
122
- return scope;
123
- }
124
- export function useChat() {
125
- const chat = useContext(ChatContext);
126
- if (chat === null)
127
- throw new Error('useChat is called outside a ChatProvider');
128
- return chat;
129
- }
130
- export function ChatProvider({ client, conversation = null, agent = null, attachTo = null, onOpen, children, }) {
131
- const shared = sharedOf(client);
132
- const asked = JSON.stringify([conversation, agent]);
133
- const [followed, setFollowed] = useState(asked);
134
- const [open, setOpen] = useState({ conversation, agent });
135
- if (followed !== asked) {
136
- setFollowed(asked);
137
- setOpen({ conversation, agent });
138
- }
139
- const opened = useRef(open);
140
- opened.current = open;
141
- const told = useRef(onOpen);
142
- told.current = onOpen;
143
- const go = useCallback((next) => {
144
- opened.current = next;
145
- setOpen(next);
146
- told.current?.(next);
147
- }, []);
148
- const listedHeld = ready(useObserve(client, 'conversations'));
149
- const agentsHeld = ready(useObserve(client, 'agents'));
150
- const readiness = ready(useObserve(client, 'readiness'));
151
- const refusal = ready(useObserve(client, 'connection-refusal'));
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));
158
- const version = useSyncExternalStore(shared.overlay.subscribe, shared.overlay.version);
159
- useEffect(() => {
160
- if (listedHeld !== null)
161
- shared.overlay.heardList(listedHeld);
162
- }, [shared, listedHeld, version]);
163
- useEffect(() => {
164
- if (held !== null)
165
- shared.overlay.heard(held);
166
- }, [shared, held, version]);
167
- const conversations = useMemo(() => shared.overlay.conversations(listedHeld ?? []), [shared, listedHeld, version]);
168
- const view = useMemo(() => (paged.view === null ? null : shared.overlay.conversation(paged.view)), [shared, paged.view, version]);
169
- const agents = agentsHeld ?? [];
170
- const known = useRef(agents);
171
- known.current = agents;
172
- const entry = conversations.find((one) => one.conversation === open.conversation);
173
- const running = entry?.state === 'working' || view?.turn != null;
174
- const questions = useMemo(() => questionsOf(view), [view]);
175
- const lone = loneOf(questions);
176
- const commands = useMemo(() => commandsOf(view), [view]);
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]);
182
- const sending = useActs(shared.overlay, online);
183
- const behind = useActs(shared.overlay, online);
184
- const acting = useActs(shared.overlay, online);
185
- const [again, setAgain] = useState(null);
186
- const current = useRef(thread);
187
- current.current = thread;
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);
197
- const heard = useRef('');
198
- const shown = useRef('');
199
- const own = useRef([]);
200
- const noted = useCallback((to, revision) => {
201
- own.current = [...own.current, `${to}\u0000${revision ?? ''}`];
202
- }, []);
203
- const keep = useCallback((to, draft) => {
204
- const revision = draft.text === '' ? null : chatDraftRevision();
205
- noted(to, revision);
206
- void (revision === null
207
- ? client.chatDraft.discard(to)
208
- : client.chatDraft.write(to, draft, revision));
209
- }, [client, noted]);
210
- useEffect(() => {
211
- heard.current = '';
212
- shown.current = '';
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;
218
- sending.clear();
219
- acting.clear();
220
- setAgain(null);
221
- }, [thread, sending.clear, acting.clear]);
222
- const sendTo = (to, said, key, idle, acts = sending) => acts.call((send) => deliver(client, send, to, said, key, idle), sentMessage(key, [to], said, null));
223
- const first = (to, said, key, returning, idle) => {
224
- const drafted = [newChat(to)];
225
- return sending.call(async (send) => {
226
- let conversation = shared.created.get(to);
227
- if (conversation === undefined) {
228
- const answer = await send.carried('conversation.create', { agent: to }, (operation) => client.conversation.create({ agent_id: to, operation_id: operation }));
229
- if (!accepted(answer)) {
230
- if (!unanswered(answer)) {
231
- returning();
232
- idle();
233
- }
234
- return answer;
235
- }
236
- const named = text(record(answer.result), 'conversation');
237
- if (named === null)
238
- return answer;
239
- conversation = named;
240
- shared.created.set(to, conversation);
241
- const name = known.current.find((one) => one.identity === to)?.name ?? null;
242
- send.expect(conversationListed({
243
- conversation,
244
- agent: { identity: to, name },
245
- name: name ?? '',
246
- created: new Date().toISOString(),
247
- finished: null,
248
- outcome: null,
249
- waiting: false,
250
- state: 'idle',
251
- started: null,
252
- }));
253
- }
254
- send.draw(sentMessage(key, [...drafted, conversation], said, null));
255
- const result = await deliver(client, send, conversation, said, key, idle);
256
- if (!accepted(result))
257
- return result;
258
- shared.created.delete(to);
259
- const now = opened.current;
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));
265
- };
266
- const sent = () => {
267
- shared.sends += 1;
268
- return `sent ${shared.sends}`;
269
- };
270
- const deliverDraft = (said, returning, idle) => {
271
- const key = sent();
272
- const { conversation: to, agent: by } = opened.current;
273
- const attempt = to !== null
274
- ? () => void sendTo(to, said, key, idle)
275
- : by !== null
276
- ? () => void first(by, said, key, returning, idle)
277
- : null;
278
- if (attempt === null)
279
- return;
280
- setAgain(() => attempt);
281
- attempt();
282
- };
283
- const control = (name, input, expected) => acting.call((send) => send.carried(name, input, (operation) => client.call(name, { ...input, operation_id: operation })), expected);
284
- const carried = (name, act) => {
285
- const to = opened.current.conversation;
286
- if (to === null)
287
- return Promise.resolve(false);
288
- return acting.call((send) => send.carried(name, { conversation: to }, () => act(to)));
289
- };
290
- const stop = () => carried('conversation.interrupt', (to) => client.conversation.interrupt(to));
291
- const kill = () => carried('conversation.kill', (to) => client.conversation.kill(to));
292
- const answer = (question, response) => {
293
- const to = opened.current.conversation;
294
- if (to === null || question.secret)
295
- return Promise.resolve(false);
296
- return acting.call((send) => send.carried('conversation.answer', { conversation: to, question: question.interaction }, () => client.conversation.answer(to, { interaction_id: question.interaction, response })), () => questionAnswered(to, question.interaction));
297
- };
298
- const choose = (option, value) => {
299
- const to = opened.current.conversation;
300
- if (to === null)
301
- return Promise.resolve(false);
302
- return control('conversation.setOption', { conversation_id: to, option, value }, optionChosen(to, option, value));
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
- };
324
- const done = (to = opened.current.conversation) => to === null
325
- ? Promise.resolve(false)
326
- : control('conversation.markDone', { conversation_id: to }, conversationChanged(to, { finished: new Date().toISOString() }, (one) => one.finished !== null));
327
- const rename = (name, to = opened.current.conversation) => to === null
328
- ? Promise.resolve(false)
329
- : control('conversation.rename', { conversation_id: to, name }, conversationChanged(to, { name }, (one) => one.name === name));
330
- const remove = (to = opened.current.conversation) => to === null
331
- ? Promise.resolve(false)
332
- : acting.call((send) => send.carried('conversation.delete', { conversation: to }, () => client.conversation.delete(to)), conversationGone(to), () => {
333
- const now = opened.current;
334
- if (now.conversation === to)
335
- go({ conversation: null, agent: now.agent });
336
- });
337
- const openConversation = (id) => go({
338
- conversation: id,
339
- agent: conversations.find((one) => one.conversation === id)?.agent.identity ?? null,
340
- });
341
- const start = (by) => go({ conversation: null, agent: by });
342
- const dispatch = useRef(() => undefined);
343
- const queues = useRef(new Map());
344
- const into = thread ?? '';
345
- const laneOf = (key) => {
346
- const held = queues.current.get(key);
347
- if (held !== undefined)
348
- return held;
349
- const fresh = {
350
- queue: createMessageQueue({ run: (message) => dispatch.current(message, key) }),
351
- running: false,
352
- };
353
- queues.current.set(key, fresh);
354
- return fresh;
355
- };
356
- const lane = laneOf(into);
357
- const queue = lane.queue;
358
- const [, moved] = useReducer((count) => count + 1, 0);
359
- useEffect(() => queue.subscribe(moved), [queue]);
360
- useEffect(() => {
361
- for (const [key, one] of queues.current) {
362
- const now = key === into
363
- ? running
364
- : conversations.some((entry) => entry.conversation === key && entry.state !== 'idle');
365
- const empty = one.queue.adapter.items.length + one.queue.adapter.steerItems.length === 0;
366
- if (key !== into && !now && empty) {
367
- queues.current.delete(key);
368
- continue;
369
- }
370
- if (now === one.running)
371
- continue;
372
- one.running = now;
373
- if (now)
374
- one.queue.notifyBusy();
375
- else
376
- one.queue.notifyIdle();
377
- }
378
- }, [into, running, conversations]);
379
- const waiting = useRef(new Map());
380
- const lanes = () => [...queue.adapter.steerItems, ...queue.adapter.items];
381
- const threads = useMemo(() => {
382
- const item = (one) => ({
383
- id: one.conversation,
384
- title: one.name,
385
- custom: { agent: one.agent.identity, state: one.state, finished: one.finished },
386
- });
387
- return {
388
- regular: conversations
389
- .filter((one) => one.finished === null)
390
- .map((one) => ({ ...item(one), status: 'regular' })),
391
- archived: conversations
392
- .filter((one) => one.finished !== null)
393
- .map((one) => ({ ...item(one), status: 'archived' })),
394
- };
395
- }, [conversations]);
396
- const aui = useExternalStoreRuntime({
397
- messages,
398
- isRunning: running,
399
- hasEarlier: paged.hasEarlier,
400
- onLoadEarlier: paged.loadEarlier,
401
- convertMessage: AS_IT_IS,
402
- queue: lined(),
403
- onNew: async (message) => lined().enqueue(message),
404
- onCancel: async () => {
405
- void stop();
406
- },
407
- onReload: thread === null
408
- ? undefined
409
- : async (parent) => {
410
- const said = askedBefore(view, parent);
411
- if (said === null)
412
- return;
413
- const draft = { text: said };
414
- const into = thread;
415
- deliverDraft(draft, () => back(draft, into), () => undefined);
416
- },
417
- adapters: {
418
- threadList: {
419
- ...(thread === null ? {} : { threadId: thread }),
420
- threads: threads.regular,
421
- archivedThreads: threads.archived,
422
- onSwitchToThread: (id) => openConversation(id),
423
- onSwitchToNewThread: () => {
424
- const by = open.agent ?? known.current[0]?.identity;
425
- if (by !== undefined)
426
- start(by);
427
- },
428
- onRename: (id, name) => {
429
- void rename(name, id);
430
- },
431
- onArchive: (id) => {
432
- void done(id);
433
- },
434
- onDelete: (id) => {
435
- void remove(id);
436
- },
437
- },
438
- },
439
- });
440
- function back(one, into) {
441
- if (current.current !== into) {
442
- void client.chatDraft.prepend(into, one);
443
- return;
444
- }
445
- const composer = aui.thread.composer;
446
- const now = composer.getState().text;
447
- composer.setText(now === '' ? one.text : `${one.text}\n${now}`);
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
- };
475
- function taken(message) {
476
- const said = textOf(message.content);
477
- if (lone === null || commandIn(said, commands))
478
- return false;
479
- void answer(lone.question, lone.question.accept({ [lone.field.name]: said }));
480
- return true;
481
- }
482
- function lined() {
483
- const holding = (put) => (message) => {
484
- if (taken(message))
485
- return;
486
- if (!online) {
487
- const draft = draftOf(message);
488
- const at = current.current;
489
- deliverDraft(draft, () => {
490
- if (at !== null)
491
- back(draft, at);
492
- }, () => undefined);
493
- return;
494
- }
495
- const known = new Set(lanes().map((one) => one.id));
496
- if (!lane.running)
497
- queue.notifyIdle();
498
- put(message);
499
- const added = lanes().find((one) => !known.has(one.id));
500
- if (added !== undefined)
501
- waiting.current.set(added.id, message);
502
- };
503
- return {
504
- get items() {
505
- return queue.adapter.items;
506
- },
507
- get steerItems() {
508
- return queue.adapter.steerItems;
509
- },
510
- enqueue: holding(queue.adapter.enqueue),
511
- steer: holding(queue.adapter.steer),
512
- move: queue.adapter.move,
513
- edit: queue.adapter.edit,
514
- remove: queue.adapter.remove,
515
- __internal_setDispatchTransform: queue.adapter.__internal_setDispatchTransform,
516
- };
517
- }
518
- dispatch.current = (message, key) => {
519
- const draft = draftOf(message);
520
- const idle = () => queues.current.get(key)?.queue.notifyIdle();
521
- if (key !== (current.current ?? '')) {
522
- void sendTo(key, draft, sent(), idle, behind);
523
- return;
524
- }
525
- const into = current.current;
526
- deliverDraft(draft, () => {
527
- if (into !== null)
528
- back(draft, into);
529
- }, idle);
530
- };
531
- const unqueue = (id) => {
532
- const message = waiting.current.get(id);
533
- waiting.current.delete(id);
534
- queue.adapter.remove(id);
535
- return message;
536
- };
537
- const edit = (id) => {
538
- const item = lanes().find((one) => one.id === id);
539
- const message = unqueue(id);
540
- if (thread === null || item === undefined)
541
- return;
542
- back(message === undefined ? { text: textOf(item.parts) } : draftOf(message), thread);
543
- };
544
- const reconcile = useRef(() => undefined);
545
- reconcile.current = () => {
546
- if (thread === null || view === null || seeding.current)
547
- return;
548
- const at = `${thread}\u0000`;
549
- const now = `${at}${view.chatDraft?.revision ?? ''}`;
550
- if (now === heard.current)
551
- return;
552
- const echo = own.current.indexOf(now);
553
- const known = heard.current.startsWith(at);
554
- heard.current = now;
555
- if (known && echo >= 0) {
556
- own.current = own.current.slice(echo);
557
- return;
558
- }
559
- own.current = own.current.filter((one) => !one.startsWith(at));
560
- const composer = aui.thread.composer;
561
- const typed = composer.getState().text;
562
- const stored = view.chatDraft;
563
- const kept = !known && typed !== '';
564
- if (kept && stored === null) {
565
- shown.current = `${at}${typed}`;
566
- keep(thread, { text: typed });
567
- return;
568
- }
569
- const draft = kept
570
- ? [stored?.text ?? '', typed].filter((one) => one !== '').join('\n')
571
- : (stored?.text ?? '');
572
- shown.current = `${at}${draft}`;
573
- if (typed === draft)
574
- return;
575
- seeding.current = true;
576
- composer.setText(draft);
577
- seeding.current = false;
578
- if (kept)
579
- keep(thread, { text: draft });
580
- };
581
- useEffect(() => reconcile.current(), [aui, thread, view]);
582
- useEffect(() => {
583
- if (thread === null)
584
- return;
585
- const at = `${thread}\u0000`;
586
- const composer = aui.thread.composer;
587
- return composer.subscribe(() => {
588
- if (seeding.current || !heard.current.startsWith(at))
589
- return;
590
- const typed = composer.getState().text;
591
- const next = `${at}${typed}`;
592
- if (next === shown.current)
593
- return;
594
- shown.current = next;
595
- keep(thread, { text: typed });
596
- });
597
- }, [aui, thread, keep]);
598
- const queued = lanes().map((item) => ({ id: item.id, text: textOf(item.parts) }));
599
- const chat = {
600
- ...open,
601
- conversations,
602
- agents,
603
- view,
604
- waiting: awaiting,
605
- running,
606
- questions,
607
- lone,
608
- options: optionsOf(view),
609
- commands,
610
- context: contextOf(view),
611
- queued,
612
- sending: { busy: sending.busy, outcome: sending.outcome, again },
613
- acting: { busy: acting.busy, outcome: acting.outcome },
614
- renewed: open.conversation !== null && shared.renewed.has(open.conversation),
615
- open: openConversation,
616
- start,
617
- send: (draft) => lined().enqueue(appended(draft)),
618
- attach: attachTo === null ? null : (files) => attach(attachTo, files),
619
- answer,
620
- choose,
621
- stop,
622
- kill,
623
- retry,
624
- renew,
625
- done: () => done(),
626
- rename: (name) => rename(name),
627
- remove: () => remove(),
628
- edit,
629
- unqueue: (id) => {
630
- unqueue(id);
631
- },
632
- };
633
- const scope = useMemo(() => ({ client, known: agentsHeld !== null }), [client, agentsHeld]);
634
- return createElement(AssistantRuntimeProvider, { runtime: aui }, createElement(ScopeContext.Provider, { value: scope }, createElement(ChatContext.Provider, { value: chat }, children)));
635
- }
@@ -1,9 +0,0 @@
1
- import { type ReactElement } from 'react';
2
- import type { MdRuntimeClient } from '../client.js';
3
- import type { ChatQuestion } from './questions.js';
4
- export declare function forgetAnswers(client: MdRuntimeClient, conversation: string, interaction?: string): Promise<void>;
5
- export type ChatQuestionCardProps = {
6
- readonly question: ChatQuestion;
7
- };
8
- export declare function ChatQuestionCard({ question }: ChatQuestionCardProps): ReactElement;
9
- //# sourceMappingURL=question.d.ts.map
@@ -1 +0,0 @@
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"}