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