@agentshouse/mdruntime 0.1.0-ca7c26c6bc27e → 0.1.0-cacb4c3f6734e
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 +53 -24
- package/README.md +10 -10
- package/dist/adapter.d.ts +24 -6
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +1 -9
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +1 -0
- package/dist/client.d.ts +3 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +3 -10
- package/dist/connection.d.ts +7 -6
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +25 -46
- package/dist/conversation.d.ts +17 -6
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +167 -78
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +3 -11
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/memory.d.ts +2 -3
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +13 -7
- package/dist/model.d.ts +3 -6
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +4 -3
- package/dist/paths.d.ts +0 -1
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +0 -16
- package/dist/query.d.ts +1 -1
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +100 -33
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +9 -16
- package/dist/react.d.ts +32 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +62 -0
- package/dist/read-side.d.ts.map +1 -1
- package/dist/read-side.js +102 -46
- package/dist/replica.d.ts +2 -3
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +5 -10
- package/dist/rows.d.ts +2 -1
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +75 -38
- package/dist/save.d.ts +1 -2
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +90 -48
- package/dist/store.d.ts +1 -0
- package/dist/store.d.ts.map +1 -1
- package/dist/wire.d.ts +1 -12
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +1 -15
- package/package.json +14 -2
package/dist/connection.js
CHANGED
|
@@ -4,11 +4,10 @@ import { observing } from './observation.js';
|
|
|
4
4
|
import { filterOf, identityOf, planOf, } from './query.js';
|
|
5
5
|
import { createReadSide } from './read-side.js';
|
|
6
6
|
import { createSearchIndex, searchPlanOf, } from './search.js';
|
|
7
|
-
import { ROOM_CONTRACT_VERSION, VERSION_1_CAPABILITIES, } from './adapter.js';
|
|
8
7
|
import { bootstrapRoom } from './bootstrap.js';
|
|
9
8
|
import { changeSet, mergeChangeSets } from './change-set.js';
|
|
10
9
|
import { createConversationStore, } from './conversation.js';
|
|
11
|
-
import {
|
|
10
|
+
import { parseCollection, validRoot } from './collection.js';
|
|
12
11
|
import { createLog } from './log.js';
|
|
13
12
|
import { refreshRoom } from './refresh.js';
|
|
14
13
|
import { buildBatch } from './save.js';
|
|
@@ -21,7 +20,6 @@ import { beneath, normalize } from './paths.js';
|
|
|
21
20
|
import { openRuntimeStore, } from './store.js';
|
|
22
21
|
import { unconfirmed } from './transfer.js';
|
|
23
22
|
import { governs, holds, narrowed, planReach, } from './reach.js';
|
|
24
|
-
const knownCapabilities = new Set(VERSION_1_CAPABILITIES);
|
|
25
23
|
function within(root, path) {
|
|
26
24
|
return root === '' || beneath(root, path);
|
|
27
25
|
}
|
|
@@ -45,11 +43,6 @@ export function composeRuntime(options) {
|
|
|
45
43
|
const presentations = new Map();
|
|
46
44
|
let limits = [];
|
|
47
45
|
let capabilities = [];
|
|
48
|
-
function rewriting() {
|
|
49
|
-
return capabilities.some((capability) => capability.name === 'move-reference-rewrites')
|
|
50
|
-
? 'provider'
|
|
51
|
-
: 'runtime';
|
|
52
|
-
}
|
|
53
46
|
const rooms = new Map();
|
|
54
47
|
const unreadable = new Set();
|
|
55
48
|
const models = new Map();
|
|
@@ -112,7 +105,7 @@ export function composeRuntime(options) {
|
|
|
112
105
|
let openSignals = 0;
|
|
113
106
|
const serviceModeListeners = new Set();
|
|
114
107
|
const conversations = createConversationStore({
|
|
115
|
-
|
|
108
|
+
agents: declaredAgents,
|
|
116
109
|
documents: (locator) => readSide.query(planOf({ rooms: [locator], select: 'all' }, roomFacts())),
|
|
117
110
|
call: (name, input) => invokeAction(name, input),
|
|
118
111
|
durably,
|
|
@@ -306,10 +299,6 @@ export function composeRuntime(options) {
|
|
|
306
299
|
for (const app of set.presentations)
|
|
307
300
|
emitPresentation(app);
|
|
308
301
|
conversations.changed(set);
|
|
309
|
-
const cards = declaredCards();
|
|
310
|
-
if (cards !== undefined && set.documents.some((change) => change.locator === cards.locator)) {
|
|
311
|
-
scheduleCurrency();
|
|
312
|
-
}
|
|
313
302
|
}
|
|
314
303
|
function stopTimer() {
|
|
315
304
|
if (resetTimer === undefined)
|
|
@@ -375,7 +364,7 @@ export function composeRuntime(options) {
|
|
|
375
364
|
};
|
|
376
365
|
const read = readConfirmed(record, before.confirmed);
|
|
377
366
|
replicas.set(locator, read.kind === 'staged'
|
|
378
|
-
? replicaOf(read.confirmed, before.queue,
|
|
367
|
+
? replicaOf(read.confirmed, before.queue, before)
|
|
379
368
|
: { ...before, confirmed: { ...before.confirmed, record } });
|
|
380
369
|
}
|
|
381
370
|
rooms.set(locator, {
|
|
@@ -406,6 +395,7 @@ export function composeRuntime(options) {
|
|
|
406
395
|
rooms.set(room.locator, {
|
|
407
396
|
name: room.name,
|
|
408
397
|
locator: room.locator,
|
|
398
|
+
handle: room.handle,
|
|
409
399
|
operations: room.operations,
|
|
410
400
|
replica: room.replica,
|
|
411
401
|
model: modelTypes(modelOf(room.locator)),
|
|
@@ -537,7 +527,7 @@ export function composeRuntime(options) {
|
|
|
537
527
|
record: retyped,
|
|
538
528
|
collection: parseCollection(retyped.documents, compositionOf(retyped)),
|
|
539
529
|
};
|
|
540
|
-
replicas.set(record.locator, replicaOf(confirmed, queuedBatches.get(record.locator) ?? [],
|
|
530
|
+
replicas.set(record.locator, replicaOf(confirmed, queuedBatches.get(record.locator) ?? [], prior));
|
|
541
531
|
const existing = rooms.get(record.locator);
|
|
542
532
|
if (existing === undefined)
|
|
543
533
|
list(record, false);
|
|
@@ -620,7 +610,7 @@ export function composeRuntime(options) {
|
|
|
620
610
|
return state !== undefined && state.submission.state !== 'submitted' && !state.lost;
|
|
621
611
|
}
|
|
622
612
|
async function settle(local, locator, before, confirmed, queue, settling = {}) {
|
|
623
|
-
const withdrawn = withdrawals(confirmed, queue, withdrawable
|
|
613
|
+
const withdrawn = withdrawals(confirmed, queue, withdrawable);
|
|
624
614
|
const kept = queue.filter((batch) => !withdrawn.includes(batch));
|
|
625
615
|
const returning = [
|
|
626
616
|
...withdrawn.map((batch) => ({ batch, returned: { kind: 'withdrawn' } })).reverse(),
|
|
@@ -656,7 +646,7 @@ export function composeRuntime(options) {
|
|
|
656
646
|
rememberRoomDraft(record);
|
|
657
647
|
for (const batch of withdrawn)
|
|
658
648
|
journal.record(`outcome ${locator} ${batch.id} withdrawn`);
|
|
659
|
-
replicas.set(locator, replicaOf(confirmed, kept,
|
|
649
|
+
replicas.set(locator, replicaOf(confirmed, kept, before));
|
|
660
650
|
return changeSet(locator, before ?? null, replicas.get(locator) ?? null, {
|
|
661
651
|
room: settling.room,
|
|
662
652
|
queue: kept.length !== (before?.queue.length ?? 0),
|
|
@@ -751,7 +741,7 @@ export function composeRuntime(options) {
|
|
|
751
741
|
operations: room.operations,
|
|
752
742
|
providerOwnedPaths: room.providerOwnedPaths,
|
|
753
743
|
providerLimits: limits,
|
|
754
|
-
|
|
744
|
+
handle: room.handle,
|
|
755
745
|
visible: replica.visible,
|
|
756
746
|
changes: parts.flatMap(({ changes }) => changes),
|
|
757
747
|
bases: parts.flatMap(({ bases }) => bases),
|
|
@@ -778,7 +768,7 @@ export function composeRuntime(options) {
|
|
|
778
768
|
recorded = false;
|
|
779
769
|
for (const path of consumed)
|
|
780
770
|
forgetRoomDraft(locator, path);
|
|
781
|
-
replicas.set(locator, replicaOf(replica.confirmed, batches,
|
|
771
|
+
replicas.set(locator, replicaOf(replica.confirmed, batches, replica));
|
|
782
772
|
publishChangeSet(changeSet(locator, replica, replicas.get(locator) ?? null, {
|
|
783
773
|
queue: true,
|
|
784
774
|
drafts: consumed,
|
|
@@ -849,10 +839,10 @@ export function composeRuntime(options) {
|
|
|
849
839
|
return { kind: 'transport-uncertainty' };
|
|
850
840
|
}
|
|
851
841
|
}
|
|
852
|
-
function
|
|
842
|
+
function declaredAgents() {
|
|
853
843
|
for (const capability of capabilities) {
|
|
854
|
-
if (capability.
|
|
855
|
-
return capability.
|
|
844
|
+
if (capability.conversationAgents !== undefined)
|
|
845
|
+
return capability.conversationAgents;
|
|
856
846
|
}
|
|
857
847
|
return undefined;
|
|
858
848
|
}
|
|
@@ -952,9 +942,9 @@ export function composeRuntime(options) {
|
|
|
952
942
|
if (!continuing())
|
|
953
943
|
return unconfirmed;
|
|
954
944
|
if (refreshed.kind === 'still-current') {
|
|
955
|
-
if (sourceRefusals.has(room.locator))
|
|
956
|
-
return unconfirmed;
|
|
957
945
|
stale.delete(room.locator);
|
|
946
|
+
if (sourceRefusals.has(room.locator))
|
|
947
|
+
return null;
|
|
958
948
|
if (unreadable.delete(room.locator)) {
|
|
959
949
|
scopedRefusals.delete(room.locator);
|
|
960
950
|
list(room, true);
|
|
@@ -984,7 +974,10 @@ export function composeRuntime(options) {
|
|
|
984
974
|
return null;
|
|
985
975
|
}
|
|
986
976
|
async function withhold(withheld, room, local, progress) {
|
|
987
|
-
|
|
977
|
+
if (withheld.kind === 'refused')
|
|
978
|
+
stale.delete(room.locator);
|
|
979
|
+
else
|
|
980
|
+
stale.add(room.locator);
|
|
988
981
|
if (withheld.kind === 'scoped-refusal') {
|
|
989
982
|
await scoped(withheld, room, local);
|
|
990
983
|
}
|
|
@@ -1264,7 +1257,7 @@ export function composeRuntime(options) {
|
|
|
1264
1257
|
queue: held.queue,
|
|
1265
1258
|
});
|
|
1266
1259
|
if (read.kind === 'staged') {
|
|
1267
|
-
replicas.set(room.locator, replicaOf(read.confirmed, held.queue,
|
|
1260
|
+
replicas.set(room.locator, replicaOf(read.confirmed, held.queue, held));
|
|
1268
1261
|
if (declarationRefusals.delete(room.locator)) {
|
|
1269
1262
|
sourceRefusals.delete(room.locator);
|
|
1270
1263
|
unreadable.delete(room.locator);
|
|
@@ -1458,17 +1451,6 @@ export function composeRuntime(options) {
|
|
|
1458
1451
|
notifyReady();
|
|
1459
1452
|
return;
|
|
1460
1453
|
}
|
|
1461
|
-
if (!result.supportedVersions.includes(ROOM_CONTRACT_VERSION)) {
|
|
1462
|
-
await refuse('no-matching-version');
|
|
1463
|
-
notifyReady();
|
|
1464
|
-
return;
|
|
1465
|
-
}
|
|
1466
|
-
if (result.mdModel.identity !== MD_MODEL.identity ||
|
|
1467
|
-
result.mdModel.version !== MD_MODEL.version) {
|
|
1468
|
-
await refuse('md-model-version-mismatch');
|
|
1469
|
-
notifyReady();
|
|
1470
|
-
return;
|
|
1471
|
-
}
|
|
1472
1454
|
for (const room of result.rooms) {
|
|
1473
1455
|
if (room.operations === undefined ||
|
|
1474
1456
|
!['read', 'sync', 'write', 'delete'].every((operation) => Array.isArray(room.operations[operation]) &&
|
|
@@ -1489,14 +1471,6 @@ export function composeRuntime(options) {
|
|
|
1489
1471
|
return;
|
|
1490
1472
|
}
|
|
1491
1473
|
}
|
|
1492
|
-
const declared = new Set(result.capabilities.map((capability) => capability.name));
|
|
1493
|
-
for (const required of options.requiredGuarantees) {
|
|
1494
|
-
if (!knownCapabilities.has(required) || !declared.has(required)) {
|
|
1495
|
-
await refuse('missing-required-guarantee');
|
|
1496
|
-
notifyReady();
|
|
1497
|
-
return;
|
|
1498
|
-
}
|
|
1499
|
-
}
|
|
1500
1474
|
if (refusal !== null) {
|
|
1501
1475
|
refusal = null;
|
|
1502
1476
|
emitRefusal();
|
|
@@ -1791,7 +1765,10 @@ export function composeRuntime(options) {
|
|
|
1791
1765
|
if (stream === undefined || withdrawConversations !== undefined)
|
|
1792
1766
|
return;
|
|
1793
1767
|
withdrawConversations = stream.observe((event) => {
|
|
1794
|
-
conversations.receive(event)
|
|
1768
|
+
if (conversations.receive(event)) {
|
|
1769
|
+
void ready.then(scheduleCurrency);
|
|
1770
|
+
return;
|
|
1771
|
+
}
|
|
1795
1772
|
if (event.kind !== 'gap' || conversations.current())
|
|
1796
1773
|
return;
|
|
1797
1774
|
show();
|
|
@@ -1909,6 +1886,8 @@ export function composeRuntime(options) {
|
|
|
1909
1886
|
if (topic === 'conversation') {
|
|
1910
1887
|
return conversations.watch(input[0], input[1], deliver);
|
|
1911
1888
|
}
|
|
1889
|
+
if (topic === 'conversations')
|
|
1890
|
+
return conversations.watchList(deliver);
|
|
1912
1891
|
if (topic === 'presentation') {
|
|
1913
1892
|
const listener = {
|
|
1914
1893
|
app: input[0],
|
package/dist/conversation.d.ts
CHANGED
|
@@ -1,18 +1,28 @@
|
|
|
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
23
|
export type RunningTurn = {
|
|
15
24
|
turn: string;
|
|
25
|
+
started: string | null;
|
|
16
26
|
parts: readonly unknown[];
|
|
17
27
|
context: TurnContext | null;
|
|
18
28
|
};
|
|
@@ -51,7 +61,7 @@ export type ChatDraftSurface = {
|
|
|
51
61
|
discard(conversation: string): Promise<void>;
|
|
52
62
|
};
|
|
53
63
|
export type ConversationDependencies = {
|
|
54
|
-
|
|
64
|
+
agents(): ConversationAgents | undefined;
|
|
55
65
|
documents(locator: string): Promise<DocumentResult>;
|
|
56
66
|
call(name: ConversationAction, input: unknown): Promise<CallResult>;
|
|
57
67
|
durably<T>(work: (local: RuntimeStore) => Promise<T>): Promise<T>;
|
|
@@ -68,8 +78,9 @@ export type ConversationStore = {
|
|
|
68
78
|
current(): boolean;
|
|
69
79
|
reconnected(): void;
|
|
70
80
|
watch(conversation: string, options: ConversationOptions, deliver: (view: ConversationView) => void): () => void;
|
|
81
|
+
watchList(deliver: (entries: readonly ConversationEntry[]) => void): () => void;
|
|
71
82
|
changed(set: ChangeSet): void;
|
|
72
|
-
receive(event: ConversationEvent):
|
|
83
|
+
receive(event: ConversationEvent): boolean;
|
|
73
84
|
messages(): readonly SearchedMessage[];
|
|
74
85
|
message(conversation: string, identity: string): SearchedMessage | null;
|
|
75
86
|
close(): void;
|
|
@@ -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
|
@@ -20,11 +20,18 @@ export function unheldView(conversation) {
|
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
function startedTurn(turn, operation) {
|
|
23
|
+
if (operation.op === 'begin')
|
|
24
|
+
return { turn, started: operation.at, parts: [], context: null };
|
|
23
25
|
if (operation.op === 'context') {
|
|
24
|
-
return {
|
|
26
|
+
return {
|
|
27
|
+
turn,
|
|
28
|
+
started: null,
|
|
29
|
+
parts: [],
|
|
30
|
+
context: { used: operation.used, window: operation.window },
|
|
31
|
+
};
|
|
25
32
|
}
|
|
26
33
|
return operation.op === 'start' && operation.index === 0
|
|
27
|
-
? { turn, parts: [structuredClone(operation.part)], context: null }
|
|
34
|
+
? { turn, started: null, parts: [structuredClone(operation.part)], context: null }
|
|
28
35
|
: null;
|
|
29
36
|
}
|
|
30
37
|
function changedFields(part, operation) {
|
|
@@ -39,6 +46,8 @@ function changedFields(part, operation) {
|
|
|
39
46
|
return { entries: structuredClone(operation.entries) };
|
|
40
47
|
}
|
|
41
48
|
function appliedTurn(held, operation) {
|
|
49
|
+
if (operation.op === 'begin')
|
|
50
|
+
return { ...held, started: operation.at };
|
|
42
51
|
if (operation.op === 'context') {
|
|
43
52
|
return { ...held, context: { used: operation.used, window: operation.window } };
|
|
44
53
|
}
|
|
@@ -156,6 +165,11 @@ export function createConversationStore(deps) {
|
|
|
156
165
|
const gaps = new Map();
|
|
157
166
|
const lives = new Map();
|
|
158
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;
|
|
159
173
|
let replicated = new Set();
|
|
160
174
|
let handedReplicated;
|
|
161
175
|
function liveOf(conversation) {
|
|
@@ -204,8 +218,70 @@ export function createConversationStore(deps) {
|
|
|
204
218
|
watcher.notify(value);
|
|
205
219
|
}
|
|
206
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
|
+
}
|
|
207
283
|
function live(conversation, change) {
|
|
208
|
-
|
|
284
|
+
setLive(conversation, { ...liveOf(conversation), ...change });
|
|
209
285
|
emit(conversation, false);
|
|
210
286
|
}
|
|
211
287
|
function relayed(conversation, turn, operation) {
|
|
@@ -218,7 +294,7 @@ export function createConversationStore(deps) {
|
|
|
218
294
|
const held = lives.get(conversation);
|
|
219
295
|
if (held?.turn == null || !turns.has(held.turn.turn))
|
|
220
296
|
return false;
|
|
221
|
-
|
|
297
|
+
setLive(conversation, { ...held, turn: null });
|
|
222
298
|
return true;
|
|
223
299
|
}
|
|
224
300
|
function handReplicated() {
|
|
@@ -232,27 +308,6 @@ export function createConversationStore(deps) {
|
|
|
232
308
|
handedReplicated = named;
|
|
233
309
|
stream.replicate(held);
|
|
234
310
|
}
|
|
235
|
-
async function documented() {
|
|
236
|
-
const declaration = deps.cards();
|
|
237
|
-
if (declaration === undefined)
|
|
238
|
-
return [];
|
|
239
|
-
const { documents } = await deps.documents(declaration.locator);
|
|
240
|
-
return documents.filter((document) => typeof document.type === 'string');
|
|
241
|
-
}
|
|
242
|
-
function carded(documents) {
|
|
243
|
-
const declaration = deps.cards();
|
|
244
|
-
if (declaration === undefined)
|
|
245
|
-
return [];
|
|
246
|
-
const cards = [];
|
|
247
|
-
for (const card of documents) {
|
|
248
|
-
if (card.type !== declaration.type)
|
|
249
|
-
continue;
|
|
250
|
-
const identity = card.fields[declaration.identity];
|
|
251
|
-
if (typeof identity === 'string')
|
|
252
|
-
cards.push({ conversation: identity, card });
|
|
253
|
-
}
|
|
254
|
-
return cards;
|
|
255
|
-
}
|
|
256
311
|
async function remove(leaving) {
|
|
257
312
|
await deps.durably(async (local) => {
|
|
258
313
|
await local.dropConversations(leaving);
|
|
@@ -269,7 +324,7 @@ export function createConversationStore(deps) {
|
|
|
269
324
|
reads.delete(conversation);
|
|
270
325
|
drafts.delete(conversation);
|
|
271
326
|
behind.delete(conversation);
|
|
272
|
-
|
|
327
|
+
setLive(conversation, null);
|
|
273
328
|
}
|
|
274
329
|
if (changed.length > 0)
|
|
275
330
|
deps.publish(conversationChangeSet(removed, changed));
|
|
@@ -365,6 +420,48 @@ export function createConversationStore(deps) {
|
|
|
365
420
|
}
|
|
366
421
|
});
|
|
367
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
|
+
}
|
|
368
465
|
function withDraft(conversation, next) {
|
|
369
466
|
return deps.durably(async (local) => {
|
|
370
467
|
const following = next(drafts.get(conversation));
|
|
@@ -386,17 +483,8 @@ export function createConversationStore(deps) {
|
|
|
386
483
|
}
|
|
387
484
|
const surface = {
|
|
388
485
|
async list() {
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
return [];
|
|
392
|
-
const documents = await documented();
|
|
393
|
-
const entries = carded(documents).map(({ conversation, card }) => ({
|
|
394
|
-
conversation,
|
|
395
|
-
card,
|
|
396
|
-
agent: documents.find((document) => document.backlinks.some((backlink) => backlink.path === card.path && backlink.field === declaration.agent)) ?? null,
|
|
397
|
-
}));
|
|
398
|
-
entries.sort((left, right) => (left.conversation < right.conversation ? -1 : 1));
|
|
399
|
-
return entries;
|
|
486
|
+
await agentsReady();
|
|
487
|
+
return entries();
|
|
400
488
|
},
|
|
401
489
|
async read(conversation, options = {}) {
|
|
402
490
|
const limit = limitOf(options);
|
|
@@ -492,7 +580,9 @@ export function createConversationStore(deps) {
|
|
|
492
580
|
drafts.set(record.conversation, record);
|
|
493
581
|
},
|
|
494
582
|
async reconcile() {
|
|
495
|
-
|
|
583
|
+
if (!listKnown)
|
|
584
|
+
return;
|
|
585
|
+
const named = new Set(listing.keys());
|
|
496
586
|
const leaving = [
|
|
497
587
|
...new Set([...replicated, ...messages.keys(), ...reads.keys(), ...drafts.keys()]),
|
|
498
588
|
].filter((conversation) => !named.has(conversation));
|
|
@@ -550,53 +640,51 @@ export function createConversationStore(deps) {
|
|
|
550
640
|
views.delete(key);
|
|
551
641
|
};
|
|
552
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
|
+
},
|
|
553
653
|
changed(set) {
|
|
554
654
|
for (const conversation of set.conversations)
|
|
555
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
|
+
}
|
|
556
663
|
},
|
|
557
664
|
receive(event) {
|
|
558
665
|
if (deps.closed())
|
|
559
|
-
return;
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
}
|
|
579
|
-
if (event.kind === 'process') {
|
|
580
|
-
live(conversation, { process: { running: event.running } });
|
|
581
|
-
return;
|
|
582
|
-
}
|
|
583
|
-
if (event.kind === 'commands') {
|
|
584
|
-
live(conversation, { commands: structuredClone(event.commands) });
|
|
585
|
-
return;
|
|
586
|
-
}
|
|
587
|
-
if (event.kind === 'options') {
|
|
588
|
-
live(conversation, { options: structuredClone(event.options) });
|
|
589
|
-
return;
|
|
590
|
-
}
|
|
591
|
-
const arriving = acceptedMessage(event.message);
|
|
592
|
-
if (arriving === null)
|
|
593
|
-
return;
|
|
594
|
-
if (replicated.has(conversation)) {
|
|
595
|
-
void keep(conversation, arriving).catch(() => { });
|
|
596
|
-
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))));
|
|
597
685
|
}
|
|
598
|
-
|
|
599
|
-
|
|
686
|
+
heard(event);
|
|
687
|
+
return false;
|
|
600
688
|
},
|
|
601
689
|
messages() {
|
|
602
690
|
return [...messages].flatMap(([conversation, held]) => held.map(({ identity, text }) => ({ conversation, identity, text })));
|
|
@@ -608,6 +696,7 @@ export function createConversationStore(deps) {
|
|
|
608
696
|
close() {
|
|
609
697
|
views.clear();
|
|
610
698
|
lives.clear();
|
|
699
|
+
listWatchers.clear();
|
|
611
700
|
},
|
|
612
701
|
};
|
|
613
702
|
}
|
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;AAGzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C,OAAO,
|
|
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"}
|
package/dist/host.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { composeRuntime, } from './connection.js';
|
|
2
2
|
import { removeRuntimeStore } from './store.js';
|
|
3
|
-
import { AUTHORIZATION_ENDED,
|
|
3
|
+
import { AUTHORIZATION_ENDED, request, WIRE_REACH, } from './wire.js';
|
|
4
4
|
const NARROWED = new Set(['within', 'whole']);
|
|
5
5
|
function answered(md, app, writtenBy, member, input) {
|
|
6
6
|
switch (member) {
|
|
@@ -87,7 +87,7 @@ export function serveMdRuntime(options) {
|
|
|
87
87
|
const observations = new Map();
|
|
88
88
|
let serving = true;
|
|
89
89
|
const send = (message) => {
|
|
90
|
-
port.postMessage(
|
|
90
|
+
port.postMessage(message);
|
|
91
91
|
};
|
|
92
92
|
const detach = () => {
|
|
93
93
|
if (!serving)
|
|
@@ -143,15 +143,7 @@ export function serveMdRuntime(options) {
|
|
|
143
143
|
port.addEventListener('message', (event) => {
|
|
144
144
|
if (!serving)
|
|
145
145
|
return;
|
|
146
|
-
const
|
|
147
|
-
if (wire === null)
|
|
148
|
-
return;
|
|
149
|
-
if (!wire.matching) {
|
|
150
|
-
send({ kind: 'refusal', refusal: PROTOCOL_MISMATCH });
|
|
151
|
-
detach();
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
const message = request(wire.message);
|
|
146
|
+
const message = request(event.data);
|
|
155
147
|
if (message === null)
|
|
156
148
|
return;
|
|
157
149
|
void serve(message);
|