@agentshouse/mdruntime 0.1.0-c3903a68dcbbf → 0.1.0-c7b0ab1aa40a3
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 +51 -29
- package/README.md +11 -11
- package/dist/adapter.d.ts +78 -51
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +1 -9
- package/dist/attached-model.d.ts +11 -0
- package/dist/attached-model.d.ts.map +1 -0
- package/dist/attached-model.js +34 -0
- package/dist/bootstrap.d.ts +5 -3
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +2 -3
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +2 -6
- package/dist/client.d.ts +4 -9
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +3 -16
- package/dist/collection.d.ts +0 -2
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +2 -12
- package/dist/connection.d.ts +10 -28
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +516 -639
- package/dist/conversation.d.ts +22 -11
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +250 -105
- package/dist/host.d.ts +7 -2
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +37 -57
- package/dist/index.d.ts +4 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/memory.d.ts +11 -5
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +77 -27
- package/dist/model.d.ts +4 -11
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +4 -3
- package/dist/observation.d.ts +2 -0
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +24 -14
- package/dist/outcome.d.ts +5 -21
- package/dist/outcome.d.ts.map +1 -1
- package/dist/query.d.ts +7 -2
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +29 -20
- package/dist/reach.d.ts +40 -0
- package/dist/reach.d.ts.map +1 -0
- package/dist/reach.js +270 -0
- package/dist/react.d.ts +31 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +62 -0
- package/dist/read-side.d.ts +4 -0
- package/dist/read-side.d.ts.map +1 -1
- package/dist/read-side.js +16 -10
- package/dist/refresh.d.ts +2 -1
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +7 -3
- package/dist/replica.d.ts +4 -4
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +14 -19
- package/dist/room-draft.d.ts +3 -0
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +6 -4
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +1 -4
- package/dist/save.d.ts +0 -2
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +5 -11
- package/dist/store.d.ts +5 -16
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +10 -32
- package/dist/wire.d.ts +51 -16
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +50 -65
- package/package.json +14 -2
package/dist/conversation.d.ts
CHANGED
|
@@ -1,19 +1,30 @@
|
|
|
1
|
-
import type { ConversationAction,
|
|
1
|
+
import type { ConversationAction, ConversationAgents, ConversationEvent, ConversationMessage, ConversationStream, ProcessCommand, SessionOption, TurnContext } from './adapter.js';
|
|
2
2
|
import { type ChangeSet } from './change-set.js';
|
|
3
3
|
import { type ChatDraftFile } from './file.js';
|
|
4
4
|
import type { CallResult } from './outcome.js';
|
|
5
|
-
import type { DocumentResult
|
|
5
|
+
import type { DocumentResult } from './query.js';
|
|
6
6
|
import type { SearchedMessage } from './search.js';
|
|
7
7
|
import type { CycleProgress } from './status.js';
|
|
8
8
|
import type { ChatDraftRecord, HeldConversation, RuntimeStore } from './store.js';
|
|
9
|
+
export type ConversationState = 'working' | 'asking' | 'idle';
|
|
9
10
|
export type ConversationEntry = {
|
|
10
11
|
conversation: string;
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
agent: {
|
|
13
|
+
identity: string;
|
|
14
|
+
name: string | null;
|
|
15
|
+
};
|
|
16
|
+
name: string;
|
|
17
|
+
created: string;
|
|
18
|
+
finished: string | null;
|
|
19
|
+
outcome: string | null;
|
|
20
|
+
state: ConversationState;
|
|
21
|
+
started: string | null;
|
|
13
22
|
};
|
|
14
|
-
export type
|
|
23
|
+
export type RunningTurn = {
|
|
15
24
|
turn: string;
|
|
16
|
-
|
|
25
|
+
started: string | null;
|
|
26
|
+
parts: readonly unknown[];
|
|
27
|
+
context: TurnContext | null;
|
|
17
28
|
};
|
|
18
29
|
export type ChatDraft = {
|
|
19
30
|
text: string;
|
|
@@ -25,9 +36,7 @@ export type ConversationOptions = {
|
|
|
25
36
|
export type ConversationView = {
|
|
26
37
|
conversation: string;
|
|
27
38
|
messages: readonly ConversationMessage[];
|
|
28
|
-
|
|
29
|
-
workingNote: WorkingNote | null;
|
|
30
|
-
plan: readonly PlanStep[] | null;
|
|
39
|
+
turn: RunningTurn | null;
|
|
31
40
|
questions: readonly unknown[];
|
|
32
41
|
process: {
|
|
33
42
|
running: boolean;
|
|
@@ -52,7 +61,7 @@ export type ChatDraftSurface = {
|
|
|
52
61
|
discard(conversation: string): Promise<void>;
|
|
53
62
|
};
|
|
54
63
|
export type ConversationDependencies = {
|
|
55
|
-
|
|
64
|
+
agents(): ConversationAgents | undefined;
|
|
56
65
|
documents(locator: string): Promise<DocumentResult>;
|
|
57
66
|
call(name: ConversationAction, input: unknown): Promise<CallResult>;
|
|
58
67
|
durably<T>(work: (local: RuntimeStore) => Promise<T>): Promise<T>;
|
|
@@ -69,11 +78,13 @@ export type ConversationStore = {
|
|
|
69
78
|
current(): boolean;
|
|
70
79
|
reconnected(): void;
|
|
71
80
|
watch(conversation: string, options: ConversationOptions, deliver: (view: ConversationView) => void): () => void;
|
|
81
|
+
watchList(deliver: (entries: readonly ConversationEntry[]) => void): () => void;
|
|
72
82
|
changed(set: ChangeSet): void;
|
|
73
|
-
receive(event: ConversationEvent):
|
|
83
|
+
receive(event: ConversationEvent): boolean;
|
|
74
84
|
messages(): readonly SearchedMessage[];
|
|
75
85
|
message(conversation: string, identity: string): SearchedMessage | null;
|
|
76
86
|
close(): void;
|
|
77
87
|
};
|
|
88
|
+
export declare function unheldView(conversation: string): ConversationView;
|
|
78
89
|
export declare function createConversationStore(deps: ConversationDependencies): ConversationStore;
|
|
79
90
|
//# sourceMappingURL=conversation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../src/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,kBAAkB,EAClB,
|
|
1
|
+
{"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../src/conversation.ts"],"names":[],"mappings":"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"}
|
package/dist/conversation.js
CHANGED
|
@@ -1,14 +1,73 @@
|
|
|
1
1
|
import { conversationChangeSet } from './change-set.js';
|
|
2
2
|
import { declaredFile } from './file.js';
|
|
3
3
|
const QUIET = {
|
|
4
|
-
|
|
5
|
-
plan: null,
|
|
6
|
-
workingNote: null,
|
|
4
|
+
turn: null,
|
|
7
5
|
questions: [],
|
|
8
6
|
process: null,
|
|
9
7
|
commands: [],
|
|
10
8
|
options: [],
|
|
11
9
|
};
|
|
10
|
+
export function unheldView(conversation) {
|
|
11
|
+
return {
|
|
12
|
+
conversation,
|
|
13
|
+
messages: [],
|
|
14
|
+
turn: null,
|
|
15
|
+
questions: [],
|
|
16
|
+
process: null,
|
|
17
|
+
commands: [],
|
|
18
|
+
options: [],
|
|
19
|
+
chatDraft: null,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function startedTurn(turn, operation) {
|
|
23
|
+
if (operation.op === 'begin')
|
|
24
|
+
return { turn, started: operation.at, parts: [], context: null };
|
|
25
|
+
if (operation.op === 'context') {
|
|
26
|
+
return {
|
|
27
|
+
turn,
|
|
28
|
+
started: null,
|
|
29
|
+
parts: [],
|
|
30
|
+
context: { used: operation.used, window: operation.window },
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
return operation.op === 'start' && operation.index === 0
|
|
34
|
+
? { turn, started: null, parts: [structuredClone(operation.part)], context: null }
|
|
35
|
+
: null;
|
|
36
|
+
}
|
|
37
|
+
function changedFields(part, operation) {
|
|
38
|
+
if (operation.op === 'append') {
|
|
39
|
+
return { text: `${String(part.text ?? '')}${operation.text}` };
|
|
40
|
+
}
|
|
41
|
+
if (operation.op === 'status') {
|
|
42
|
+
return { status: operation.status, result: structuredClone(operation.result) };
|
|
43
|
+
}
|
|
44
|
+
if (operation.op === 'count')
|
|
45
|
+
return { count: operation.count };
|
|
46
|
+
return { entries: structuredClone(operation.entries) };
|
|
47
|
+
}
|
|
48
|
+
function appliedTurn(held, operation) {
|
|
49
|
+
if (operation.op === 'begin')
|
|
50
|
+
return { ...held, started: operation.at };
|
|
51
|
+
if (operation.op === 'context') {
|
|
52
|
+
return { ...held, context: { used: operation.used, window: operation.window } };
|
|
53
|
+
}
|
|
54
|
+
if (operation.op === 'start') {
|
|
55
|
+
if (operation.index !== 0 && operation.index !== held.parts.length)
|
|
56
|
+
return null;
|
|
57
|
+
return {
|
|
58
|
+
...held,
|
|
59
|
+
parts: [...held.parts.slice(0, operation.index), structuredClone(operation.part)],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const part = held.parts[operation.index];
|
|
63
|
+
if (typeof part !== 'object' || part === null)
|
|
64
|
+
return null;
|
|
65
|
+
const changed = { ...part, ...changedFields(part, operation) };
|
|
66
|
+
return {
|
|
67
|
+
...held,
|
|
68
|
+
parts: held.parts.map((kept, at) => (at === operation.index ? changed : kept)),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
12
71
|
function ordered(left, right) {
|
|
13
72
|
if (left.position !== right.position)
|
|
14
73
|
return left.position < right.position ? -1 : 1;
|
|
@@ -106,27 +165,33 @@ export function createConversationStore(deps) {
|
|
|
106
165
|
const gaps = new Map();
|
|
107
166
|
const lives = new Map();
|
|
108
167
|
const views = new Map();
|
|
168
|
+
const listing = new Map();
|
|
169
|
+
const listWatchers = new Set();
|
|
170
|
+
let listKnown = false;
|
|
171
|
+
let agentNames = new Map();
|
|
172
|
+
let agentsRead = null;
|
|
109
173
|
let replicated = new Set();
|
|
110
174
|
let handedReplicated;
|
|
111
175
|
function liveOf(conversation) {
|
|
112
176
|
return lives.get(conversation) ?? QUIET;
|
|
113
177
|
}
|
|
114
|
-
function
|
|
178
|
+
function shownMessages(conversation, limit) {
|
|
115
179
|
const held = messages.get(conversation) ?? [];
|
|
116
180
|
const shown = limit === undefined ? held : held.slice(Math.max(0, held.length - limit));
|
|
181
|
+
return shown.map(({ identity, turn, text, message }) => ({
|
|
182
|
+
identity,
|
|
183
|
+
turn,
|
|
184
|
+
text,
|
|
185
|
+
message: structuredClone(message),
|
|
186
|
+
}));
|
|
187
|
+
}
|
|
188
|
+
function viewOf(conversation, limit, shown = shownMessages(conversation, limit)) {
|
|
117
189
|
const draft = drafts.get(conversation);
|
|
118
190
|
const facts = liveOf(conversation);
|
|
119
191
|
return {
|
|
120
192
|
conversation,
|
|
121
|
-
messages: shown
|
|
122
|
-
|
|
123
|
-
turn,
|
|
124
|
-
text,
|
|
125
|
-
message: structuredClone(message),
|
|
126
|
-
})),
|
|
127
|
-
growingText: facts.growingText === null ? null : { ...facts.growingText },
|
|
128
|
-
workingNote: facts.workingNote === null ? null : { ...facts.workingNote },
|
|
129
|
-
plan: structuredClone(facts.plan?.plan ?? null),
|
|
193
|
+
messages: shown,
|
|
194
|
+
turn: structuredClone(facts.turn),
|
|
130
195
|
questions: structuredClone(facts.questions),
|
|
131
196
|
process: facts.process === null ? null : { ...facts.process },
|
|
132
197
|
commands: structuredClone(facts.commands),
|
|
@@ -136,33 +201,100 @@ export function createConversationStore(deps) {
|
|
|
136
201
|
: { text: draft.text, files: [...draft.files] },
|
|
137
202
|
};
|
|
138
203
|
}
|
|
139
|
-
function emit(conversation) {
|
|
204
|
+
function emit(conversation, messagesChanged = true) {
|
|
140
205
|
if (deps.closed())
|
|
141
206
|
return;
|
|
142
207
|
for (const view of views.values()) {
|
|
143
208
|
if (view.conversation !== conversation)
|
|
144
209
|
continue;
|
|
210
|
+
if (messagesChanged)
|
|
211
|
+
view.messages = null;
|
|
145
212
|
const ready = [...view.watchers].filter((watcher) => watcher.ready);
|
|
146
213
|
if (ready.length === 0)
|
|
147
214
|
continue;
|
|
148
|
-
|
|
215
|
+
view.messages ??= shownMessages(conversation, view.limit);
|
|
216
|
+
const value = viewOf(conversation, view.limit, view.messages);
|
|
149
217
|
for (const watcher of ready)
|
|
150
218
|
watcher.notify(value);
|
|
151
219
|
}
|
|
152
220
|
}
|
|
221
|
+
function stateOf(conversation) {
|
|
222
|
+
const facts = liveOf(conversation);
|
|
223
|
+
if (facts.questions.length > 0)
|
|
224
|
+
return 'asking';
|
|
225
|
+
return facts.turn === null ? 'idle' : 'working';
|
|
226
|
+
}
|
|
227
|
+
function entries() {
|
|
228
|
+
return [...listing.values()].map((entry) => ({
|
|
229
|
+
conversation: entry.conversation,
|
|
230
|
+
agent: { identity: entry.agent, name: agentNames.get(entry.agent) ?? null },
|
|
231
|
+
name: entry.name,
|
|
232
|
+
created: entry.created,
|
|
233
|
+
finished: entry.finished,
|
|
234
|
+
outcome: entry.outcome,
|
|
235
|
+
state: stateOf(entry.conversation),
|
|
236
|
+
started: lives.get(entry.conversation)?.turn?.started ?? null,
|
|
237
|
+
}));
|
|
238
|
+
}
|
|
239
|
+
function emitList() {
|
|
240
|
+
if (deps.closed() || listWatchers.size === 0)
|
|
241
|
+
return;
|
|
242
|
+
const value = entries();
|
|
243
|
+
for (const watcher of listWatchers)
|
|
244
|
+
watcher(value);
|
|
245
|
+
}
|
|
246
|
+
function setLive(conversation, next) {
|
|
247
|
+
const before = stateOf(conversation);
|
|
248
|
+
const began = lives.get(conversation)?.turn?.started;
|
|
249
|
+
if (next === null)
|
|
250
|
+
lives.delete(conversation);
|
|
251
|
+
else
|
|
252
|
+
lives.set(conversation, next);
|
|
253
|
+
if (!listing.has(conversation))
|
|
254
|
+
return;
|
|
255
|
+
if (stateOf(conversation) !== before || next?.turn?.started !== began)
|
|
256
|
+
emitList();
|
|
257
|
+
}
|
|
258
|
+
async function readAgents() {
|
|
259
|
+
const declaration = deps.agents();
|
|
260
|
+
if (declaration === undefined)
|
|
261
|
+
return;
|
|
262
|
+
const { documents } = await deps.documents(declaration.locator);
|
|
263
|
+
const names = new Map();
|
|
264
|
+
for (const document of documents) {
|
|
265
|
+
if (document.type !== declaration.type)
|
|
266
|
+
continue;
|
|
267
|
+
const identity = document.fields?.[declaration.identity];
|
|
268
|
+
const name = document.fields?.[declaration.name];
|
|
269
|
+
if (typeof identity === 'string' && typeof name === 'string')
|
|
270
|
+
names.set(identity, name);
|
|
271
|
+
}
|
|
272
|
+
if (JSON.stringify([...names]) === JSON.stringify([...agentNames]))
|
|
273
|
+
return;
|
|
274
|
+
agentNames = names;
|
|
275
|
+
emitList();
|
|
276
|
+
}
|
|
277
|
+
function agentsReady() {
|
|
278
|
+
agentsRead ??= readAgents().catch(() => {
|
|
279
|
+
agentsRead = null;
|
|
280
|
+
});
|
|
281
|
+
return agentsRead;
|
|
282
|
+
}
|
|
153
283
|
function live(conversation, change) {
|
|
154
|
-
|
|
155
|
-
emit(conversation);
|
|
284
|
+
setLive(conversation, { ...liveOf(conversation), ...change });
|
|
285
|
+
emit(conversation, false);
|
|
286
|
+
}
|
|
287
|
+
function relayed(conversation, turn, operation) {
|
|
288
|
+
const held = liveOf(conversation).turn;
|
|
289
|
+
const next = held?.turn === turn ? appliedTurn(held, operation) : startedTurn(turn, operation);
|
|
290
|
+
if (next !== null)
|
|
291
|
+
live(conversation, { turn: next });
|
|
156
292
|
}
|
|
157
293
|
function sealTurns(conversation, turns) {
|
|
158
294
|
const held = lives.get(conversation);
|
|
159
|
-
if (held
|
|
295
|
+
if (held?.turn == null || !turns.has(held.turn.turn))
|
|
160
296
|
return false;
|
|
161
|
-
|
|
162
|
-
const plan = held.plan !== null && turns.has(held.plan.turn) ? null : held.plan;
|
|
163
|
-
if (growingText === held.growingText && plan === held.plan)
|
|
164
|
-
return false;
|
|
165
|
-
lives.set(conversation, { ...held, growingText, plan });
|
|
297
|
+
setLive(conversation, { ...held, turn: null });
|
|
166
298
|
return true;
|
|
167
299
|
}
|
|
168
300
|
function handReplicated() {
|
|
@@ -176,27 +308,6 @@ export function createConversationStore(deps) {
|
|
|
176
308
|
handedReplicated = named;
|
|
177
309
|
stream.replicate(held);
|
|
178
310
|
}
|
|
179
|
-
async function documented() {
|
|
180
|
-
const declaration = deps.cards();
|
|
181
|
-
if (declaration === undefined)
|
|
182
|
-
return [];
|
|
183
|
-
const { documents } = await deps.documents(declaration.locator);
|
|
184
|
-
return documents.filter((document) => typeof document.type === 'string');
|
|
185
|
-
}
|
|
186
|
-
function carded(documents) {
|
|
187
|
-
const declaration = deps.cards();
|
|
188
|
-
if (declaration === undefined)
|
|
189
|
-
return [];
|
|
190
|
-
const cards = [];
|
|
191
|
-
for (const card of documents) {
|
|
192
|
-
if (card.type !== declaration.type)
|
|
193
|
-
continue;
|
|
194
|
-
const identity = card.fields[declaration.identity];
|
|
195
|
-
if (typeof identity === 'string')
|
|
196
|
-
cards.push({ conversation: identity, card });
|
|
197
|
-
}
|
|
198
|
-
return cards;
|
|
199
|
-
}
|
|
200
311
|
async function remove(leaving) {
|
|
201
312
|
await deps.durably(async (local) => {
|
|
202
313
|
await local.dropConversations(leaving);
|
|
@@ -213,7 +324,7 @@ export function createConversationStore(deps) {
|
|
|
213
324
|
reads.delete(conversation);
|
|
214
325
|
drafts.delete(conversation);
|
|
215
326
|
behind.delete(conversation);
|
|
216
|
-
|
|
327
|
+
setLive(conversation, null);
|
|
217
328
|
}
|
|
218
329
|
if (changed.length > 0)
|
|
219
330
|
deps.publish(conversationChangeSet(removed, changed));
|
|
@@ -309,6 +420,48 @@ export function createConversationStore(deps) {
|
|
|
309
420
|
}
|
|
310
421
|
});
|
|
311
422
|
}
|
|
423
|
+
function heard(event) {
|
|
424
|
+
const { conversation } = event;
|
|
425
|
+
if (event.kind === 'gap') {
|
|
426
|
+
if (replicated.has(conversation))
|
|
427
|
+
gap(conversation);
|
|
428
|
+
const held = lives.get(conversation);
|
|
429
|
+
if (held === undefined)
|
|
430
|
+
return;
|
|
431
|
+
setLive(conversation, { ...QUIET, turn: held.turn });
|
|
432
|
+
emit(conversation, false);
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
if (event.kind === 'turn') {
|
|
436
|
+
relayed(conversation, event.turn, event.operation);
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
if (event.kind === 'questions') {
|
|
440
|
+
live(conversation, { questions: structuredClone(event.questions) });
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
if (event.kind === 'process') {
|
|
444
|
+
live(conversation, { process: { running: event.running } });
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
if (event.kind === 'commands') {
|
|
448
|
+
live(conversation, { commands: structuredClone(event.commands) });
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
if (event.kind === 'options') {
|
|
452
|
+
live(conversation, { options: structuredClone(event.options) });
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
const arriving = acceptedMessage(event.message);
|
|
456
|
+
if (arriving === null)
|
|
457
|
+
return;
|
|
458
|
+
if (replicated.has(conversation)) {
|
|
459
|
+
void keep(conversation, arriving).catch(() => { });
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
if (sealTurns(conversation, new Set([arriving.turn])))
|
|
463
|
+
emit(conversation);
|
|
464
|
+
}
|
|
312
465
|
function withDraft(conversation, next) {
|
|
313
466
|
return deps.durably(async (local) => {
|
|
314
467
|
const following = next(drafts.get(conversation));
|
|
@@ -330,17 +483,8 @@ export function createConversationStore(deps) {
|
|
|
330
483
|
}
|
|
331
484
|
const surface = {
|
|
332
485
|
async list() {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
return [];
|
|
336
|
-
const documents = await documented();
|
|
337
|
-
const entries = carded(documents).map(({ conversation, card }) => ({
|
|
338
|
-
conversation,
|
|
339
|
-
card,
|
|
340
|
-
agent: documents.find((document) => document.backlinks.some((backlink) => backlink.path === card.path && backlink.field === declaration.agent)) ?? null,
|
|
341
|
-
}));
|
|
342
|
-
entries.sort((left, right) => (left.conversation < right.conversation ? -1 : 1));
|
|
343
|
-
return entries;
|
|
486
|
+
await agentsReady();
|
|
487
|
+
return entries();
|
|
344
488
|
},
|
|
345
489
|
async read(conversation, options = {}) {
|
|
346
490
|
const limit = limitOf(options);
|
|
@@ -424,6 +568,8 @@ export function createConversationStore(deps) {
|
|
|
424
568
|
hydrate(held, stored) {
|
|
425
569
|
messages.clear();
|
|
426
570
|
reads.clear();
|
|
571
|
+
for (const view of views.values())
|
|
572
|
+
view.messages = null;
|
|
427
573
|
for (const entry of held) {
|
|
428
574
|
messages.set(entry.conversation, [...entry.messages].sort(ordered));
|
|
429
575
|
if (entry.read !== undefined)
|
|
@@ -434,7 +580,9 @@ export function createConversationStore(deps) {
|
|
|
434
580
|
drafts.set(record.conversation, record);
|
|
435
581
|
},
|
|
436
582
|
async reconcile() {
|
|
437
|
-
|
|
583
|
+
if (!listKnown)
|
|
584
|
+
return;
|
|
585
|
+
const named = new Set(listing.keys());
|
|
438
586
|
const leaving = [
|
|
439
587
|
...new Set([...replicated, ...messages.keys(), ...reads.keys(), ...drafts.keys()]),
|
|
440
588
|
].filter((conversation) => !named.has(conversation));
|
|
@@ -467,7 +615,12 @@ export function createConversationStore(deps) {
|
|
|
467
615
|
watch(conversation, options, deliver) {
|
|
468
616
|
const limit = limitOf(options);
|
|
469
617
|
const key = JSON.stringify([conversation, limit ?? null]);
|
|
470
|
-
const view = views.get(key) ?? {
|
|
618
|
+
const view = views.get(key) ?? {
|
|
619
|
+
conversation,
|
|
620
|
+
limit,
|
|
621
|
+
watchers: new Set(),
|
|
622
|
+
messages: null,
|
|
623
|
+
};
|
|
471
624
|
views.set(key, view);
|
|
472
625
|
const watcher = { notify: deliver, ready: false };
|
|
473
626
|
view.watchers.add(watcher);
|
|
@@ -487,60 +640,51 @@ export function createConversationStore(deps) {
|
|
|
487
640
|
views.delete(key);
|
|
488
641
|
};
|
|
489
642
|
},
|
|
643
|
+
watchList(deliver) {
|
|
644
|
+
listWatchers.add(deliver);
|
|
645
|
+
void agentsReady().then(() => {
|
|
646
|
+
if (!deps.closed() && listWatchers.has(deliver))
|
|
647
|
+
deliver(entries());
|
|
648
|
+
});
|
|
649
|
+
return () => {
|
|
650
|
+
listWatchers.delete(deliver);
|
|
651
|
+
};
|
|
652
|
+
},
|
|
490
653
|
changed(set) {
|
|
491
654
|
for (const conversation of set.conversations)
|
|
492
655
|
emit(conversation);
|
|
656
|
+
const declaration = deps.agents();
|
|
657
|
+
if (declaration !== undefined &&
|
|
658
|
+
set.documents.some((change) => change.locator === declaration.locator)) {
|
|
659
|
+
agentsRead = readAgents().catch(() => {
|
|
660
|
+
agentsRead = null;
|
|
661
|
+
});
|
|
662
|
+
}
|
|
493
663
|
},
|
|
494
664
|
receive(event) {
|
|
495
665
|
if (deps.closed())
|
|
496
|
-
return;
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
return
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
workingNote: event.note === null ? null : { noteId: event.note.noteId, text: event.note.text },
|
|
516
|
-
});
|
|
517
|
-
return;
|
|
518
|
-
}
|
|
519
|
-
if (event.kind === 'questions') {
|
|
520
|
-
live(conversation, { questions: structuredClone(event.questions) });
|
|
521
|
-
return;
|
|
522
|
-
}
|
|
523
|
-
if (event.kind === 'process') {
|
|
524
|
-
live(conversation, { process: { running: event.running } });
|
|
525
|
-
return;
|
|
526
|
-
}
|
|
527
|
-
if (event.kind === 'commands') {
|
|
528
|
-
live(conversation, { commands: structuredClone(event.commands) });
|
|
529
|
-
return;
|
|
530
|
-
}
|
|
531
|
-
if (event.kind === 'options') {
|
|
532
|
-
live(conversation, { options: structuredClone(event.options) });
|
|
533
|
-
return;
|
|
534
|
-
}
|
|
535
|
-
const arriving = acceptedMessage(event.message);
|
|
536
|
-
if (arriving === null)
|
|
537
|
-
return;
|
|
538
|
-
if (replicated.has(conversation)) {
|
|
539
|
-
void keep(conversation, arriving).catch(() => { });
|
|
540
|
-
return;
|
|
666
|
+
return false;
|
|
667
|
+
if (event.kind === 'list' || event.kind === 'listed' || event.kind === 'unlisted') {
|
|
668
|
+
if (event.kind === 'list') {
|
|
669
|
+
listing.clear();
|
|
670
|
+
for (const entry of event.entries)
|
|
671
|
+
listing.set(entry.conversation, { ...entry });
|
|
672
|
+
listKnown = true;
|
|
673
|
+
}
|
|
674
|
+
else if (event.kind === 'listed') {
|
|
675
|
+
listing.set(event.entry.conversation, { ...event.entry });
|
|
676
|
+
}
|
|
677
|
+
else {
|
|
678
|
+
listing.delete(event.conversation);
|
|
679
|
+
}
|
|
680
|
+
emitList();
|
|
681
|
+
return (event.kind !== 'list' &&
|
|
682
|
+
listKnown &&
|
|
683
|
+
(listing.size !== replicated.size ||
|
|
684
|
+
[...listing.keys()].some((conversation) => !replicated.has(conversation))));
|
|
541
685
|
}
|
|
542
|
-
|
|
543
|
-
|
|
686
|
+
heard(event);
|
|
687
|
+
return false;
|
|
544
688
|
},
|
|
545
689
|
messages() {
|
|
546
690
|
return [...messages].flatMap(([conversation, held]) => held.map(({ identity, text }) => ({ conversation, identity, text })));
|
|
@@ -552,6 +696,7 @@ export function createConversationStore(deps) {
|
|
|
552
696
|
close() {
|
|
553
697
|
views.clear();
|
|
554
698
|
lives.clear();
|
|
699
|
+
listWatchers.clear();
|
|
555
700
|
},
|
|
556
701
|
};
|
|
557
702
|
}
|
package/dist/host.d.ts
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { type MdRuntimeOptions } from './connection.js';
|
|
2
|
+
import type { PortReach } from './reach.js';
|
|
2
3
|
import { type RuntimePort } from './wire.js';
|
|
3
4
|
export type MdRuntimeHostOptions = MdRuntimeOptions & {
|
|
4
5
|
deploymentFacts?: unknown;
|
|
5
6
|
};
|
|
7
|
+
export type AttachedPort = {
|
|
8
|
+
detach(): void;
|
|
9
|
+
narrow(reach: PortReach): void;
|
|
10
|
+
};
|
|
6
11
|
export type MdRuntimeHost = {
|
|
7
|
-
|
|
8
|
-
attach(port: RuntimePort, app: string, release?: string): () => void;
|
|
12
|
+
attach(port: RuntimePort, app: string, release?: string, reach?: PortReach): AttachedPort;
|
|
9
13
|
endAuthorization(): Promise<void>;
|
|
10
14
|
stop(): Promise<void>;
|
|
11
15
|
};
|
|
12
16
|
export declare function serveMdRuntime(options: MdRuntimeHostOptions): MdRuntimeHost;
|
|
17
|
+
export type { PortReach, ReachedDocument } from './reach.js';
|
|
13
18
|
export type { RuntimePort } from './wire.js';
|
|
14
19
|
//# sourceMappingURL=host.d.ts.map
|
package/dist/host.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,gBAAgB,EAEtB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,gBAAgB,EAEtB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C,OAAO,EAGL,KAAK,WAAW,EAOjB,MAAM,WAAW,CAAC;AAInB,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEpF,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,IAAI,IAAI,CAAC;IACf,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,GAAG,YAAY,CAAC;IAC1F,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB,CAAC;AA0EF,wBAAgB,cAAc,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAwH3E;AAED,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7D,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
|