@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.
- package/AGENTS.md +268 -251
- package/README.md +9 -8
- package/dist/adapter.d.ts +76 -40
- 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/binary.d.ts +0 -5
- package/dist/binary.d.ts.map +1 -1
- package/dist/binary.js +1 -1
- package/dist/bootstrap.d.ts +26 -7
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +148 -78
- 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 -88
- package/dist/change.d.ts +31 -1
- package/dist/change.d.ts.map +1 -1
- package/dist/change.js +10 -1
- package/dist/chat/earlier.d.ts +10 -0
- package/dist/chat/earlier.d.ts.map +1 -0
- package/dist/chat/earlier.js +54 -0
- 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/kit.d.ts +2 -1
- package/dist/chat/kit.d.ts.map +1 -1
- package/dist/chat/kit.js +3 -3
- package/dist/chat/list.d.ts +3 -1
- package/dist/chat/list.d.ts.map +1 -1
- package/dist/chat/list.js +47 -6
- package/dist/chat/markdown.d.ts +2 -2
- package/dist/chat/markdown.d.ts.map +1 -1
- package/dist/chat/markdown.js +83 -40
- 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 +15 -1
- package/dist/chat/messages.d.ts.map +1 -1
- package/dist/chat/messages.js +82 -23
- 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 +9 -2
- package/dist/chat/provider.d.ts.map +1 -1
- package/dist/chat/provider.js +121 -106
- package/dist/chat/question.d.ts +1 -1
- package/dist/chat/question.d.ts.map +1 -1
- package/dist/chat/question.js +7 -18
- package/dist/chat/ready.d.ts +5 -1
- 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 +6 -1
- 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 +15 -6
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +47 -8
- package/dist/collection.d.ts +6 -19
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +30 -287
- package/dist/compile.d.ts +16 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +721 -0
- package/dist/connection.d.ts +25 -12
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +2615 -946
- package/dist/conversation.d.ts +18 -3
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +341 -107
- 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 +3 -5
- package/dist/durability.d.ts.map +1 -1
- package/dist/durability.js +5 -0
- package/dist/entry.d.ts +3 -1
- package/dist/entry.d.ts.map +1 -1
- package/dist/entry.js +18 -23
- 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 +10 -8
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +95 -18
- 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 +15 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- 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 +8 -3
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +43 -25
- package/dist/messages.d.ts +28 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +90 -0
- package/dist/model.d.ts +3 -2
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +1 -1
- 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 +14 -0
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +93 -3
- 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 +34 -4
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +25 -0
- package/dist/overlay.d.ts +3 -5
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +95 -156
- package/dist/query.d.ts +33 -2
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +48 -7
- package/dist/reach.d.ts +6 -5
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +170 -62
- package/dist/react.d.ts +3 -3
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +7 -17
- package/dist/readiness.d.ts +20 -9
- package/dist/readiness.d.ts.map +1 -1
- package/dist/readiness.js +6 -6
- package/dist/reads.d.ts +11 -0
- package/dist/reads.d.ts.map +1 -0
- package/dist/reads.js +100 -0
- 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 +16 -15
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +112 -45
- package/dist/replica.d.ts +57 -33
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +295 -177
- package/dist/room-draft.d.ts +17 -2
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +65 -25
- package/dist/rows.d.ts +29 -29
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +113 -62
- package/dist/save.d.ts +51 -14
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +518 -180
- package/dist/search.d.ts +32 -43
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +37 -168
- package/dist/seed.d.ts +16 -0
- package/dist/seed.d.ts.map +1 -0
- package/dist/seed.js +75 -0
- 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 +99 -88
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +335 -641
- package/dist/stored.d.ts +145 -0
- package/dist/stored.d.ts.map +1 -0
- package/dist/stored.js +567 -0
- package/dist/tables.d.ts +354 -0
- package/dist/tables.d.ts.map +1 -0
- package/dist/tables.js +624 -0
- package/dist/turn.d.ts +5 -3
- package/dist/turn.d.ts.map +1 -1
- package/dist/turn.js +51 -21
- 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 +22 -0
- package/dist/windows.d.ts.map +1 -0
- package/dist/windows.js +89 -0
- package/dist/wire.d.ts +163 -33
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +54 -32
- package/dist/words.d.ts +19 -0
- package/dist/words.d.ts.map +1 -0
- package/dist/words.js +150 -0
- package/package.json +11 -5
- package/dist/acquisition.d.ts +0 -14
- package/dist/acquisition.d.ts.map +0 -1
- package/dist/acquisition.js +0 -24
- package/dist/read-side.d.ts +0 -25
- package/dist/read-side.d.ts.map +0 -1
- package/dist/read-side.js +0 -639
package/dist/chat/provider.d.ts
CHANGED
|
@@ -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
|
|
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,27 +1,28 @@
|
|
|
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
|
+
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 {
|
|
9
|
-
import {
|
|
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
|
|
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);
|
|
@@ -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
|
|
150
|
+
const readiness = ready(useObserve(client, 'readiness'));
|
|
178
151
|
const refusal = ready(useObserve(client, 'connection-refusal'));
|
|
179
|
-
const online =
|
|
180
|
-
const thread = open.conversation ??
|
|
181
|
-
|
|
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(() =>
|
|
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 === ''
|
|
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
|
-
|
|
267
|
-
|
|
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
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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)
|
|
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
|
|
561
|
+
const typed = composer.getState().text;
|
|
535
562
|
const stored = view.chatDraft;
|
|
536
|
-
const
|
|
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}${
|
|
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
|
-
|
|
546
|
-
|
|
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
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
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
|
|
581
|
-
const next = `${at}${
|
|
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:
|
|
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(),
|
package/dist/chat/question.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ReactElement } from 'react';
|
|
2
|
-
import {
|
|
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,
|
|
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"}
|
package/dist/chat/question.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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(
|
|
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
|
|
28
|
+
void client.presentation.edit({ [key]: next });
|
|
40
29
|
},
|
|
41
30
|
];
|
|
42
31
|
}
|
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,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;
|
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, 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);
|