@agentshouse/mdruntime 0.1.0-c8c4b020a3ec7 → 0.1.0-c967d1ca66fee
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 +94 -33
- package/README.md +10 -10
- package/dist/adapter.d.ts +92 -46
- 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 +47 -0
- package/dist/bootstrap.d.ts +20 -6
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +89 -35
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +13 -7
- package/dist/change.d.ts +4 -0
- package/dist/change.d.ts.map +1 -1
- package/dist/client.d.ts +8 -5
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +57 -24
- package/dist/collection.d.ts +6 -11
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +56 -19
- package/dist/connection.d.ts +20 -16
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +711 -587
- package/dist/conversation.d.ts +23 -11
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +252 -106
- package/dist/failure.d.ts +13 -0
- package/dist/failure.d.ts.map +1 -0
- package/dist/failure.js +19 -0
- package/dist/host.d.ts +8 -1
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +38 -38
- package/dist/identity.d.ts +1 -0
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +7 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/memory.d.ts +12 -5
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +108 -36
- package/dist/model.d.ts +13 -12
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +6 -3
- package/dist/observation.d.ts +2 -0
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +24 -14
- package/dist/open.d.ts +2 -0
- package/dist/open.d.ts.map +1 -0
- package/dist/open.js +1 -0
- package/dist/outcome.d.ts +22 -3
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +35 -1
- package/dist/overlay.d.ts +1 -1
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +19 -15
- 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 +10 -3
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +78 -36
- package/dist/reach.d.ts +40 -0
- package/dist/reach.d.ts.map +1 -0
- package/dist/reach.js +272 -0
- package/dist/react.d.ts +40 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +64 -0
- package/dist/read-side.d.ts +4 -0
- package/dist/read-side.d.ts.map +1 -1
- package/dist/read-side.js +116 -54
- package/dist/refresh.d.ts +12 -1
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +35 -22
- package/dist/replica.d.ts +6 -6
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +53 -39
- package/dist/room-draft.d.ts +11 -8
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +19 -26
- package/dist/rows.d.ts +4 -1
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +82 -39
- package/dist/save.d.ts +4 -3
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +127 -68
- package/dist/search.d.ts +3 -2
- package/dist/search.d.ts.map +1 -1
- package/dist/status.d.ts +2 -2
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +0 -8
- package/dist/store.d.ts +25 -2
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +206 -90
- package/dist/wire.d.ts +55 -19
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +62 -61
- package/package.json +14 -2
package/dist/conversation.d.ts
CHANGED
|
@@ -1,19 +1,31 @@
|
|
|
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
|
+
import type { Open } from './open.js';
|
|
4
5
|
import type { CallResult } from './outcome.js';
|
|
5
|
-
import type { DocumentResult
|
|
6
|
+
import type { DocumentResult } from './query.js';
|
|
6
7
|
import type { SearchedMessage } from './search.js';
|
|
7
8
|
import type { CycleProgress } from './status.js';
|
|
8
9
|
import type { ChatDraftRecord, HeldConversation, RuntimeStore } from './store.js';
|
|
10
|
+
export type ConversationState = Open<'working' | 'asking' | 'idle'>;
|
|
9
11
|
export type ConversationEntry = {
|
|
10
12
|
conversation: string;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
agent: {
|
|
14
|
+
identity: string;
|
|
15
|
+
name: string | null;
|
|
16
|
+
};
|
|
17
|
+
name: string;
|
|
18
|
+
created: string;
|
|
19
|
+
finished: string | null;
|
|
20
|
+
outcome: string | null;
|
|
21
|
+
state: ConversationState;
|
|
22
|
+
started: string | null;
|
|
13
23
|
};
|
|
14
|
-
export type
|
|
24
|
+
export type RunningTurn = {
|
|
15
25
|
turn: string;
|
|
16
|
-
|
|
26
|
+
started: string | null;
|
|
27
|
+
parts: readonly unknown[];
|
|
28
|
+
context: TurnContext | null;
|
|
17
29
|
};
|
|
18
30
|
export type ChatDraft = {
|
|
19
31
|
text: string;
|
|
@@ -25,9 +37,7 @@ export type ConversationOptions = {
|
|
|
25
37
|
export type ConversationView = {
|
|
26
38
|
conversation: string;
|
|
27
39
|
messages: readonly ConversationMessage[];
|
|
28
|
-
|
|
29
|
-
workingNote: WorkingNote | null;
|
|
30
|
-
plan: readonly PlanStep[] | null;
|
|
40
|
+
turn: RunningTurn | null;
|
|
31
41
|
questions: readonly unknown[];
|
|
32
42
|
process: {
|
|
33
43
|
running: boolean;
|
|
@@ -52,7 +62,7 @@ export type ChatDraftSurface = {
|
|
|
52
62
|
discard(conversation: string): Promise<void>;
|
|
53
63
|
};
|
|
54
64
|
export type ConversationDependencies = {
|
|
55
|
-
|
|
65
|
+
agents(): ConversationAgents | undefined;
|
|
56
66
|
documents(locator: string): Promise<DocumentResult>;
|
|
57
67
|
call(name: ConversationAction, input: unknown): Promise<CallResult>;
|
|
58
68
|
durably<T>(work: (local: RuntimeStore) => Promise<T>): Promise<T>;
|
|
@@ -69,11 +79,13 @@ export type ConversationStore = {
|
|
|
69
79
|
current(): boolean;
|
|
70
80
|
reconnected(): void;
|
|
71
81
|
watch(conversation: string, options: ConversationOptions, deliver: (view: ConversationView) => void): () => void;
|
|
82
|
+
watchList(deliver: (entries: readonly ConversationEntry[]) => void): () => void;
|
|
72
83
|
changed(set: ChangeSet): void;
|
|
73
|
-
receive(event: ConversationEvent):
|
|
84
|
+
receive(event: ConversationEvent): boolean;
|
|
74
85
|
messages(): readonly SearchedMessage[];
|
|
75
86
|
message(conversation: string, identity: string): SearchedMessage | null;
|
|
76
87
|
close(): void;
|
|
77
88
|
};
|
|
89
|
+
export declare function unheldView(conversation: string): ConversationView;
|
|
78
90
|
export declare function createConversationStore(deps: ConversationDependencies): ConversationStore;
|
|
79
91
|
//# 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,74 @@
|
|
|
1
1
|
import { conversationChangeSet } from './change-set.js';
|
|
2
|
+
import { runtimeError } from './failure.js';
|
|
2
3
|
import { declaredFile } from './file.js';
|
|
3
4
|
const QUIET = {
|
|
4
|
-
|
|
5
|
-
plan: null,
|
|
6
|
-
workingNote: null,
|
|
5
|
+
turn: null,
|
|
7
6
|
questions: [],
|
|
8
7
|
process: null,
|
|
9
8
|
commands: [],
|
|
10
9
|
options: [],
|
|
11
10
|
};
|
|
11
|
+
export function unheldView(conversation) {
|
|
12
|
+
return {
|
|
13
|
+
conversation,
|
|
14
|
+
messages: [],
|
|
15
|
+
turn: null,
|
|
16
|
+
questions: [],
|
|
17
|
+
process: null,
|
|
18
|
+
commands: [],
|
|
19
|
+
options: [],
|
|
20
|
+
chatDraft: null,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function startedTurn(turn, operation) {
|
|
24
|
+
if (operation.op === 'begin')
|
|
25
|
+
return { turn, started: operation.at, parts: [], context: null };
|
|
26
|
+
if (operation.op === 'context') {
|
|
27
|
+
return {
|
|
28
|
+
turn,
|
|
29
|
+
started: null,
|
|
30
|
+
parts: [],
|
|
31
|
+
context: { used: operation.used, window: operation.window },
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return operation.op === 'start' && operation.index === 0
|
|
35
|
+
? { turn, started: null, parts: [structuredClone(operation.part)], context: null }
|
|
36
|
+
: null;
|
|
37
|
+
}
|
|
38
|
+
function changedFields(part, operation) {
|
|
39
|
+
if (operation.op === 'append') {
|
|
40
|
+
return { text: `${String(part.text ?? '')}${operation.text}` };
|
|
41
|
+
}
|
|
42
|
+
if (operation.op === 'status') {
|
|
43
|
+
return { status: operation.status, result: structuredClone(operation.result) };
|
|
44
|
+
}
|
|
45
|
+
if (operation.op === 'count')
|
|
46
|
+
return { count: operation.count };
|
|
47
|
+
return { entries: structuredClone(operation.entries) };
|
|
48
|
+
}
|
|
49
|
+
function appliedTurn(held, operation) {
|
|
50
|
+
if (operation.op === 'begin')
|
|
51
|
+
return { ...held, started: operation.at };
|
|
52
|
+
if (operation.op === 'context') {
|
|
53
|
+
return { ...held, context: { used: operation.used, window: operation.window } };
|
|
54
|
+
}
|
|
55
|
+
if (operation.op === 'start') {
|
|
56
|
+
if (operation.index !== 0 && operation.index !== held.parts.length)
|
|
57
|
+
return null;
|
|
58
|
+
return {
|
|
59
|
+
...held,
|
|
60
|
+
parts: [...held.parts.slice(0, operation.index), structuredClone(operation.part)],
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
const part = held.parts[operation.index];
|
|
64
|
+
if (typeof part !== 'object' || part === null)
|
|
65
|
+
return null;
|
|
66
|
+
const changed = { ...part, ...changedFields(part, operation) };
|
|
67
|
+
return {
|
|
68
|
+
...held,
|
|
69
|
+
parts: held.parts.map((kept, at) => (at === operation.index ? changed : kept)),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
12
72
|
function ordered(left, right) {
|
|
13
73
|
if (left.position !== right.position)
|
|
14
74
|
return left.position < right.position ? -1 : 1;
|
|
@@ -93,7 +153,7 @@ function limitOf(options) {
|
|
|
93
153
|
if (limit === undefined)
|
|
94
154
|
return undefined;
|
|
95
155
|
if (!Number.isInteger(limit) || limit < 0) {
|
|
96
|
-
throw
|
|
156
|
+
throw runtimeError('invalid-limit', `conversation limit must be a non-negative integer, got ${String(limit)}`);
|
|
97
157
|
}
|
|
98
158
|
return limit;
|
|
99
159
|
}
|
|
@@ -106,27 +166,33 @@ export function createConversationStore(deps) {
|
|
|
106
166
|
const gaps = new Map();
|
|
107
167
|
const lives = new Map();
|
|
108
168
|
const views = new Map();
|
|
169
|
+
const listing = new Map();
|
|
170
|
+
const listWatchers = new Set();
|
|
171
|
+
let listKnown = false;
|
|
172
|
+
let agentNames = new Map();
|
|
173
|
+
let agentsRead = null;
|
|
109
174
|
let replicated = new Set();
|
|
110
175
|
let handedReplicated;
|
|
111
176
|
function liveOf(conversation) {
|
|
112
177
|
return lives.get(conversation) ?? QUIET;
|
|
113
178
|
}
|
|
114
|
-
function
|
|
179
|
+
function shownMessages(conversation, limit) {
|
|
115
180
|
const held = messages.get(conversation) ?? [];
|
|
116
181
|
const shown = limit === undefined ? held : held.slice(Math.max(0, held.length - limit));
|
|
182
|
+
return shown.map(({ identity, turn, text, message }) => ({
|
|
183
|
+
identity,
|
|
184
|
+
turn,
|
|
185
|
+
text,
|
|
186
|
+
message: structuredClone(message),
|
|
187
|
+
}));
|
|
188
|
+
}
|
|
189
|
+
function viewOf(conversation, limit, shown = shownMessages(conversation, limit)) {
|
|
117
190
|
const draft = drafts.get(conversation);
|
|
118
191
|
const facts = liveOf(conversation);
|
|
119
192
|
return {
|
|
120
193
|
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),
|
|
194
|
+
messages: shown,
|
|
195
|
+
turn: structuredClone(facts.turn),
|
|
130
196
|
questions: structuredClone(facts.questions),
|
|
131
197
|
process: facts.process === null ? null : { ...facts.process },
|
|
132
198
|
commands: structuredClone(facts.commands),
|
|
@@ -136,33 +202,100 @@ export function createConversationStore(deps) {
|
|
|
136
202
|
: { text: draft.text, files: [...draft.files] },
|
|
137
203
|
};
|
|
138
204
|
}
|
|
139
|
-
function emit(conversation) {
|
|
205
|
+
function emit(conversation, messagesChanged = true) {
|
|
140
206
|
if (deps.closed())
|
|
141
207
|
return;
|
|
142
208
|
for (const view of views.values()) {
|
|
143
209
|
if (view.conversation !== conversation)
|
|
144
210
|
continue;
|
|
211
|
+
if (messagesChanged)
|
|
212
|
+
view.messages = null;
|
|
145
213
|
const ready = [...view.watchers].filter((watcher) => watcher.ready);
|
|
146
214
|
if (ready.length === 0)
|
|
147
215
|
continue;
|
|
148
|
-
|
|
216
|
+
view.messages ??= shownMessages(conversation, view.limit);
|
|
217
|
+
const value = viewOf(conversation, view.limit, view.messages);
|
|
149
218
|
for (const watcher of ready)
|
|
150
219
|
watcher.notify(value);
|
|
151
220
|
}
|
|
152
221
|
}
|
|
222
|
+
function stateOf(conversation) {
|
|
223
|
+
const facts = liveOf(conversation);
|
|
224
|
+
if (facts.questions.length > 0)
|
|
225
|
+
return 'asking';
|
|
226
|
+
return facts.turn === null ? 'idle' : 'working';
|
|
227
|
+
}
|
|
228
|
+
function entries() {
|
|
229
|
+
return [...listing.values()].map((entry) => ({
|
|
230
|
+
conversation: entry.conversation,
|
|
231
|
+
agent: { identity: entry.agent, name: agentNames.get(entry.agent) ?? null },
|
|
232
|
+
name: entry.name,
|
|
233
|
+
created: entry.created,
|
|
234
|
+
finished: entry.finished,
|
|
235
|
+
outcome: entry.outcome,
|
|
236
|
+
state: stateOf(entry.conversation),
|
|
237
|
+
started: lives.get(entry.conversation)?.turn?.started ?? null,
|
|
238
|
+
}));
|
|
239
|
+
}
|
|
240
|
+
function emitList() {
|
|
241
|
+
if (deps.closed() || listWatchers.size === 0)
|
|
242
|
+
return;
|
|
243
|
+
const value = entries();
|
|
244
|
+
for (const watcher of listWatchers)
|
|
245
|
+
watcher(value);
|
|
246
|
+
}
|
|
247
|
+
function setLive(conversation, next) {
|
|
248
|
+
const before = stateOf(conversation);
|
|
249
|
+
const began = lives.get(conversation)?.turn?.started;
|
|
250
|
+
if (next === null)
|
|
251
|
+
lives.delete(conversation);
|
|
252
|
+
else
|
|
253
|
+
lives.set(conversation, next);
|
|
254
|
+
if (!listing.has(conversation))
|
|
255
|
+
return;
|
|
256
|
+
if (stateOf(conversation) !== before || next?.turn?.started !== began)
|
|
257
|
+
emitList();
|
|
258
|
+
}
|
|
259
|
+
async function readAgents() {
|
|
260
|
+
const declaration = deps.agents();
|
|
261
|
+
if (declaration === undefined)
|
|
262
|
+
return;
|
|
263
|
+
const { documents } = await deps.documents(declaration.locator);
|
|
264
|
+
const names = new Map();
|
|
265
|
+
for (const document of documents) {
|
|
266
|
+
if (document.type !== declaration.type)
|
|
267
|
+
continue;
|
|
268
|
+
const identity = document.fields?.[declaration.identity];
|
|
269
|
+
const name = document.fields?.[declaration.name];
|
|
270
|
+
if (typeof identity === 'string' && typeof name === 'string')
|
|
271
|
+
names.set(identity, name);
|
|
272
|
+
}
|
|
273
|
+
if (JSON.stringify([...names]) === JSON.stringify([...agentNames]))
|
|
274
|
+
return;
|
|
275
|
+
agentNames = names;
|
|
276
|
+
emitList();
|
|
277
|
+
}
|
|
278
|
+
function agentsReady() {
|
|
279
|
+
agentsRead ??= readAgents().catch(() => {
|
|
280
|
+
agentsRead = null;
|
|
281
|
+
});
|
|
282
|
+
return agentsRead;
|
|
283
|
+
}
|
|
153
284
|
function live(conversation, change) {
|
|
154
|
-
|
|
155
|
-
emit(conversation);
|
|
285
|
+
setLive(conversation, { ...liveOf(conversation), ...change });
|
|
286
|
+
emit(conversation, false);
|
|
287
|
+
}
|
|
288
|
+
function relayed(conversation, turn, operation) {
|
|
289
|
+
const held = liveOf(conversation).turn;
|
|
290
|
+
const next = held?.turn === turn ? appliedTurn(held, operation) : startedTurn(turn, operation);
|
|
291
|
+
if (next !== null)
|
|
292
|
+
live(conversation, { turn: next });
|
|
156
293
|
}
|
|
157
294
|
function sealTurns(conversation, turns) {
|
|
158
295
|
const held = lives.get(conversation);
|
|
159
|
-
if (held
|
|
296
|
+
if (held?.turn == null || !turns.has(held.turn.turn))
|
|
160
297
|
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 });
|
|
298
|
+
setLive(conversation, { ...held, turn: null });
|
|
166
299
|
return true;
|
|
167
300
|
}
|
|
168
301
|
function handReplicated() {
|
|
@@ -176,27 +309,6 @@ export function createConversationStore(deps) {
|
|
|
176
309
|
handedReplicated = named;
|
|
177
310
|
stream.replicate(held);
|
|
178
311
|
}
|
|
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
312
|
async function remove(leaving) {
|
|
201
313
|
await deps.durably(async (local) => {
|
|
202
314
|
await local.dropConversations(leaving);
|
|
@@ -213,7 +325,7 @@ export function createConversationStore(deps) {
|
|
|
213
325
|
reads.delete(conversation);
|
|
214
326
|
drafts.delete(conversation);
|
|
215
327
|
behind.delete(conversation);
|
|
216
|
-
|
|
328
|
+
setLive(conversation, null);
|
|
217
329
|
}
|
|
218
330
|
if (changed.length > 0)
|
|
219
331
|
deps.publish(conversationChangeSet(removed, changed));
|
|
@@ -309,6 +421,48 @@ export function createConversationStore(deps) {
|
|
|
309
421
|
}
|
|
310
422
|
});
|
|
311
423
|
}
|
|
424
|
+
function heard(event) {
|
|
425
|
+
const { conversation } = event;
|
|
426
|
+
if (event.kind === 'gap') {
|
|
427
|
+
if (replicated.has(conversation))
|
|
428
|
+
gap(conversation);
|
|
429
|
+
const held = lives.get(conversation);
|
|
430
|
+
if (held === undefined)
|
|
431
|
+
return;
|
|
432
|
+
setLive(conversation, { ...QUIET, turn: held.turn });
|
|
433
|
+
emit(conversation, false);
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
if (event.kind === 'turn') {
|
|
437
|
+
relayed(conversation, event.turn, event.operation);
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
if (event.kind === 'questions') {
|
|
441
|
+
live(conversation, { questions: structuredClone(event.questions) });
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
if (event.kind === 'process') {
|
|
445
|
+
live(conversation, { process: { running: event.running } });
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
if (event.kind === 'commands') {
|
|
449
|
+
live(conversation, { commands: structuredClone(event.commands) });
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
if (event.kind === 'options') {
|
|
453
|
+
live(conversation, { options: structuredClone(event.options) });
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
const arriving = acceptedMessage(event.message);
|
|
457
|
+
if (arriving === null)
|
|
458
|
+
return;
|
|
459
|
+
if (replicated.has(conversation)) {
|
|
460
|
+
void keep(conversation, arriving).catch(() => { });
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
if (sealTurns(conversation, new Set([arriving.turn])))
|
|
464
|
+
emit(conversation);
|
|
465
|
+
}
|
|
312
466
|
function withDraft(conversation, next) {
|
|
313
467
|
return deps.durably(async (local) => {
|
|
314
468
|
const following = next(drafts.get(conversation));
|
|
@@ -330,17 +484,8 @@ export function createConversationStore(deps) {
|
|
|
330
484
|
}
|
|
331
485
|
const surface = {
|
|
332
486
|
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;
|
|
487
|
+
await agentsReady();
|
|
488
|
+
return entries();
|
|
344
489
|
},
|
|
345
490
|
async read(conversation, options = {}) {
|
|
346
491
|
const limit = limitOf(options);
|
|
@@ -424,6 +569,8 @@ export function createConversationStore(deps) {
|
|
|
424
569
|
hydrate(held, stored) {
|
|
425
570
|
messages.clear();
|
|
426
571
|
reads.clear();
|
|
572
|
+
for (const view of views.values())
|
|
573
|
+
view.messages = null;
|
|
427
574
|
for (const entry of held) {
|
|
428
575
|
messages.set(entry.conversation, [...entry.messages].sort(ordered));
|
|
429
576
|
if (entry.read !== undefined)
|
|
@@ -434,7 +581,9 @@ export function createConversationStore(deps) {
|
|
|
434
581
|
drafts.set(record.conversation, record);
|
|
435
582
|
},
|
|
436
583
|
async reconcile() {
|
|
437
|
-
|
|
584
|
+
if (!listKnown)
|
|
585
|
+
return;
|
|
586
|
+
const named = new Set(listing.keys());
|
|
438
587
|
const leaving = [
|
|
439
588
|
...new Set([...replicated, ...messages.keys(), ...reads.keys(), ...drafts.keys()]),
|
|
440
589
|
].filter((conversation) => !named.has(conversation));
|
|
@@ -467,7 +616,12 @@ export function createConversationStore(deps) {
|
|
|
467
616
|
watch(conversation, options, deliver) {
|
|
468
617
|
const limit = limitOf(options);
|
|
469
618
|
const key = JSON.stringify([conversation, limit ?? null]);
|
|
470
|
-
const view = views.get(key) ?? {
|
|
619
|
+
const view = views.get(key) ?? {
|
|
620
|
+
conversation,
|
|
621
|
+
limit,
|
|
622
|
+
watchers: new Set(),
|
|
623
|
+
messages: null,
|
|
624
|
+
};
|
|
471
625
|
views.set(key, view);
|
|
472
626
|
const watcher = { notify: deliver, ready: false };
|
|
473
627
|
view.watchers.add(watcher);
|
|
@@ -487,60 +641,51 @@ export function createConversationStore(deps) {
|
|
|
487
641
|
views.delete(key);
|
|
488
642
|
};
|
|
489
643
|
},
|
|
644
|
+
watchList(deliver) {
|
|
645
|
+
listWatchers.add(deliver);
|
|
646
|
+
void agentsReady().then(() => {
|
|
647
|
+
if (!deps.closed() && listWatchers.has(deliver))
|
|
648
|
+
deliver(entries());
|
|
649
|
+
});
|
|
650
|
+
return () => {
|
|
651
|
+
listWatchers.delete(deliver);
|
|
652
|
+
};
|
|
653
|
+
},
|
|
490
654
|
changed(set) {
|
|
491
655
|
for (const conversation of set.conversations)
|
|
492
656
|
emit(conversation);
|
|
657
|
+
const declaration = deps.agents();
|
|
658
|
+
if (declaration !== undefined &&
|
|
659
|
+
set.documents.some((change) => change.locator === declaration.locator)) {
|
|
660
|
+
agentsRead = readAgents().catch(() => {
|
|
661
|
+
agentsRead = null;
|
|
662
|
+
});
|
|
663
|
+
}
|
|
493
664
|
},
|
|
494
665
|
receive(event) {
|
|
495
666
|
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;
|
|
667
|
+
return false;
|
|
668
|
+
if (event.kind === 'list' || event.kind === 'listed' || event.kind === 'unlisted') {
|
|
669
|
+
if (event.kind === 'list') {
|
|
670
|
+
listing.clear();
|
|
671
|
+
for (const entry of event.entries)
|
|
672
|
+
listing.set(entry.conversation, { ...entry });
|
|
673
|
+
listKnown = true;
|
|
674
|
+
}
|
|
675
|
+
else if (event.kind === 'listed') {
|
|
676
|
+
listing.set(event.entry.conversation, { ...event.entry });
|
|
677
|
+
}
|
|
678
|
+
else {
|
|
679
|
+
listing.delete(event.conversation);
|
|
680
|
+
}
|
|
681
|
+
emitList();
|
|
682
|
+
return (event.kind !== 'list' &&
|
|
683
|
+
listKnown &&
|
|
684
|
+
(listing.size !== replicated.size ||
|
|
685
|
+
[...listing.keys()].some((conversation) => !replicated.has(conversation))));
|
|
541
686
|
}
|
|
542
|
-
|
|
543
|
-
|
|
687
|
+
heard(event);
|
|
688
|
+
return false;
|
|
544
689
|
},
|
|
545
690
|
messages() {
|
|
546
691
|
return [...messages].flatMap(([conversation, held]) => held.map(({ identity, text }) => ({ conversation, identity, text })));
|
|
@@ -552,6 +697,7 @@ export function createConversationStore(deps) {
|
|
|
552
697
|
close() {
|
|
553
698
|
views.clear();
|
|
554
699
|
lives.clear();
|
|
700
|
+
listWatchers.clear();
|
|
555
701
|
},
|
|
556
702
|
};
|
|
557
703
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type RuntimeError = Error & {
|
|
2
|
+
readonly code: string;
|
|
3
|
+
readonly retryable: boolean;
|
|
4
|
+
};
|
|
5
|
+
export type Described = {
|
|
6
|
+
message: string;
|
|
7
|
+
code: string;
|
|
8
|
+
retryable: boolean;
|
|
9
|
+
};
|
|
10
|
+
export declare function runtimeError(code: string, message?: string, retryable?: boolean): RuntimeError;
|
|
11
|
+
export declare function failed(error: unknown): RuntimeError;
|
|
12
|
+
export declare function described(error: unknown): Described;
|
|
13
|
+
//# sourceMappingURL=failure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failure.d.ts","sourceRoot":"","sources":["../src/failure.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC;AAE1F,MAAM,MAAM,SAAS,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC;AAE9E,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAAa,EACtB,SAAS,UAAQ,GAChB,YAAY,CAEd;AAYD,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAGnD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,CAGnD"}
|
package/dist/failure.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function runtimeError(code, message = code, retryable = false) {
|
|
2
|
+
return Object.assign(new Error(message), { code, retryable });
|
|
3
|
+
}
|
|
4
|
+
function coded(error) {
|
|
5
|
+
return (error instanceof Error &&
|
|
6
|
+
'code' in error &&
|
|
7
|
+
typeof error.code === 'string' &&
|
|
8
|
+
'retryable' in error &&
|
|
9
|
+
typeof error.retryable === 'boolean');
|
|
10
|
+
}
|
|
11
|
+
export function failed(error) {
|
|
12
|
+
if (coded(error))
|
|
13
|
+
return error;
|
|
14
|
+
return runtimeError('runtime-failure', error instanceof Error ? error.message : String(error));
|
|
15
|
+
}
|
|
16
|
+
export function described(error) {
|
|
17
|
+
const { message, code, retryable } = failed(error);
|
|
18
|
+
return { message, code, retryable };
|
|
19
|
+
}
|
package/dist/host.d.ts
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
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
|
-
attach(port: RuntimePort, app: string, release?: string):
|
|
12
|
+
attach(port: RuntimePort, app: string, release?: string, reach?: PortReach): AttachedPort;
|
|
8
13
|
endAuthorization(): Promise<void>;
|
|
9
14
|
stop(): Promise<void>;
|
|
10
15
|
};
|
|
11
16
|
export declare function serveMdRuntime(options: MdRuntimeHostOptions): MdRuntimeHost;
|
|
17
|
+
export type { PortReach, ReachedDocument } from './reach.js';
|
|
18
|
+
export { STORE_SCHEMA } from './store.js';
|
|
12
19
|
export type { RuntimePort } from './wire.js';
|
|
13
20
|
//# 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;AAI5C,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,CAkH3E;AAED,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
|