@agentshouse/mdruntime 0.1.0-cb1f56e16291b → 0.1.0-cb3bb3b233fa1
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/README.md +21 -19
- package/dist/acceptance.d.ts +3 -0
- package/dist/acceptance.d.ts.map +1 -0
- package/dist/acceptance.js +299 -0
- package/dist/act-lanes.d.ts +30 -0
- package/dist/act-lanes.d.ts.map +1 -0
- package/dist/act-lanes.js +225 -0
- package/dist/actions.d.ts +26 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +302 -0
- package/dist/adapter.d.ts +113 -81
- package/dist/adapter.d.ts.map +1 -1
- package/dist/attached-model.d.ts +3 -11
- package/dist/attached-model.d.ts.map +1 -1
- package/dist/attached-model.js +20 -60
- package/dist/authored.d.ts +88 -0
- package/dist/authored.d.ts.map +1 -0
- package/dist/authored.js +345 -0
- package/dist/bootstrap.d.ts +9 -5
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +204 -85
- package/dist/cell.d.ts +6 -0
- package/dist/cell.d.ts.map +1 -0
- package/dist/cell.js +9 -0
- package/dist/chain.d.ts +2 -1
- package/dist/chain.d.ts.map +1 -1
- package/dist/change-set.d.ts +4 -0
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +6 -0
- package/dist/change.d.ts +5 -0
- package/dist/change.d.ts.map +1 -1
- package/dist/change.js +7 -2
- package/dist/chat-types.d.ts +3 -0
- package/dist/chat-types.d.ts.map +1 -0
- package/dist/chat-types.js +11 -0
- package/dist/client.d.ts +30 -22
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +39 -20
- package/dist/collection.d.ts +26 -4
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +19 -2
- package/dist/column.d.ts +5 -0
- package/dist/column.d.ts.map +1 -0
- package/dist/column.js +9 -0
- package/dist/compile.d.ts +9 -7
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +252 -318
- package/dist/connection.d.ts +5 -141
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +111 -5282
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +1 -1
- package/dist/conversation-live.d.ts +150 -0
- package/dist/conversation-live.d.ts.map +1 -0
- package/dist/conversation-live.js +259 -0
- package/dist/conversation-row.d.ts +40 -0
- package/dist/conversation-row.d.ts.map +1 -0
- package/dist/conversation-row.js +66 -0
- package/dist/conversation.d.ts +62 -43
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +987 -902
- package/dist/declaration.d.ts +10 -0
- package/dist/declaration.d.ts.map +1 -0
- package/dist/declaration.js +24 -0
- package/dist/discovery.d.ts +10 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +150 -0
- package/dist/durability.d.ts +19 -0
- package/dist/durability.d.ts.map +1 -1
- package/dist/durability.js +4 -0
- package/dist/entry.d.ts +2 -2
- package/dist/entry.d.ts.map +1 -1
- package/dist/entry.js +18 -9
- package/dist/expectation.d.ts +26 -13
- package/dist/expectation.d.ts.map +1 -1
- package/dist/expectation.js +72 -19
- package/dist/failure.d.ts +3 -0
- package/dist/failure.d.ts.map +1 -1
- package/dist/failure.js +6 -0
- package/dist/figures.d.ts +49 -0
- package/dist/figures.d.ts.map +1 -0
- package/dist/figures.js +199 -0
- package/dist/file.d.ts +1 -1
- package/dist/file.d.ts.map +1 -1
- package/dist/file.js +3 -2
- package/dist/holdings.d.ts +29 -0
- package/dist/holdings.d.ts.map +1 -0
- package/dist/holdings.js +95 -0
- package/dist/host.d.ts +20 -4
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +72 -28
- 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 +32 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -5
- package/dist/install.d.ts +60 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +537 -0
- package/dist/lifecycle.d.ts +7 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +282 -0
- package/dist/listing.d.ts +52 -0
- package/dist/listing.d.ts.map +1 -0
- package/dist/listing.js +152 -0
- package/dist/live.d.ts +8 -6
- package/dist/live.d.ts.map +1 -1
- package/dist/live.js +110 -31
- package/dist/loaded.d.ts +5 -0
- package/dist/loaded.d.ts.map +1 -0
- package/dist/loaded.js +40 -0
- package/dist/locks.d.ts +7 -0
- package/dist/locks.d.ts.map +1 -0
- package/dist/locks.js +32 -0
- package/dist/lost.d.ts +5 -0
- package/dist/lost.d.ts.map +1 -0
- package/dist/lost.js +49 -0
- package/dist/media.d.ts +6 -1
- package/dist/media.d.ts.map +1 -1
- package/dist/media.js +68 -17
- package/dist/memory.d.ts +11 -3
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +132 -33
- package/dist/messages.d.ts +33 -3
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +98 -27
- package/dist/model.d.ts +2 -10
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +0 -14
- package/dist/models.d.ts +10 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +153 -0
- package/dist/observation.d.ts +27 -12
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +184 -85
- package/dist/opened.d.ts +1 -1
- package/dist/opened.d.ts.map +1 -1
- package/dist/opened.js +5 -5
- package/dist/opening.d.ts +4 -0
- package/dist/opening.d.ts.map +1 -0
- package/dist/opening.js +53 -0
- package/dist/outcome.d.ts +17 -2
- package/dist/outcome.d.ts.map +1 -1
- package/dist/outcome.js +35 -2
- package/dist/overlay.d.ts +7 -2
- package/dist/overlay.d.ts.map +1 -1
- package/dist/overlay.js +48 -24
- package/dist/page-metadata.d.ts +8 -0
- package/dist/page-metadata.d.ts.map +1 -0
- package/dist/page-metadata.js +19 -0
- package/dist/parts.d.ts +4 -0
- package/dist/parts.d.ts.map +1 -0
- package/dist/parts.js +13 -0
- package/dist/paths.d.ts +1 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +22 -0
- package/dist/preparation.d.ts +41 -0
- package/dist/preparation.d.ts.map +1 -0
- package/dist/preparation.js +314 -0
- package/dist/presence.d.ts +58 -0
- package/dist/presence.d.ts.map +1 -0
- package/dist/presence.js +231 -0
- package/dist/queries.d.ts +16 -0
- package/dist/queries.d.ts.map +1 -0
- package/dist/queries.js +308 -0
- package/dist/query.d.ts +13 -213
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +3 -524
- package/dist/questions.d.ts +30 -0
- package/dist/questions.d.ts.map +1 -0
- package/dist/questions.js +116 -0
- package/dist/queue.d.ts +40 -0
- package/dist/queue.d.ts.map +1 -0
- package/dist/queue.js +480 -0
- package/dist/reach.d.ts +10 -10
- package/dist/reach.d.ts.map +1 -1
- package/dist/reach.js +235 -120
- package/dist/react.d.ts +17 -3
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +33 -1
- package/dist/read.d.ts +7 -0
- package/dist/read.d.ts.map +1 -0
- package/dist/read.js +17 -0
- package/dist/readiness.d.ts +9 -4
- package/dist/readiness.d.ts.map +1 -1
- package/dist/readiness.js +3 -5
- package/dist/reads.d.ts +39 -0
- package/dist/reads.d.ts.map +1 -0
- package/dist/reads.js +178 -0
- package/dist/recovery.d.ts +3 -1
- package/dist/recovery.d.ts.map +1 -1
- package/dist/recovery.js +38 -8
- package/dist/refresh.d.ts +1 -1
- package/dist/refresh.d.ts.map +1 -1
- package/dist/refresh.js +10 -22
- package/dist/refusal.d.ts +5 -0
- package/dist/refusal.d.ts.map +1 -0
- package/dist/refusal.js +55 -0
- package/dist/replica.d.ts +11 -16
- package/dist/replica.d.ts.map +1 -1
- package/dist/replica.js +66 -35
- package/dist/retried.d.ts +30 -0
- package/dist/retried.d.ts.map +1 -0
- package/dist/retried.js +72 -0
- package/dist/room-draft.d.ts +32 -9
- package/dist/room-draft.d.ts.map +1 -1
- package/dist/room-draft.js +273 -66
- package/dist/room-drafts.d.ts +24 -0
- package/dist/room-drafts.d.ts.map +1 -0
- package/dist/room-drafts.js +220 -0
- package/dist/room-list.d.ts +10 -0
- package/dist/room-list.d.ts.map +1 -0
- package/dist/room-list.js +45 -0
- package/dist/rows.d.ts +16 -23
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +49 -191
- package/dist/runtime.d.ts +34 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +1 -0
- package/dist/save.d.ts +42 -86
- package/dist/save.d.ts.map +1 -1
- package/dist/save.js +332 -228
- package/dist/saves.d.ts +34 -0
- package/dist/saves.d.ts.map +1 -0
- package/dist/saves.js +437 -0
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +1 -1
- package/dist/seed.d.ts +11 -2
- package/dist/seed.d.ts.map +1 -1
- package/dist/seed.js +71 -1
- package/dist/shared.d.ts +1 -6
- package/dist/shared.d.ts.map +1 -1
- package/dist/shared.js +13 -95
- package/dist/shown.d.ts +33 -0
- package/dist/shown.d.ts.map +1 -0
- package/dist/shown.js +309 -0
- package/dist/socket/admission.d.ts +7 -0
- package/dist/socket/admission.d.ts.map +1 -0
- package/dist/socket/admission.js +39 -0
- package/dist/socket/answers.d.ts +6 -0
- package/dist/socket/answers.d.ts.map +1 -0
- package/dist/socket/answers.js +20 -0
- package/dist/socket/lanes.d.ts +28 -0
- package/dist/socket/lanes.d.ts.map +1 -0
- package/dist/socket/lanes.js +103 -0
- package/dist/socket/reads.d.ts +10 -0
- package/dist/socket/reads.d.ts.map +1 -0
- package/dist/socket/reads.js +31 -0
- package/dist/socket/session.d.ts +38 -0
- package/dist/socket/session.d.ts.map +1 -0
- package/dist/socket/session.js +23 -0
- package/dist/socket.d.ts +67 -0
- package/dist/socket.d.ts.map +1 -0
- package/dist/socket.js +164 -0
- package/dist/source.d.ts +59 -0
- package/dist/source.d.ts.map +1 -0
- package/dist/source.js +93 -0
- package/dist/status.d.ts +0 -2
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +0 -6
- package/dist/store/installs.d.ts +30 -0
- package/dist/store/installs.d.ts.map +1 -0
- package/dist/store/installs.js +40 -0
- package/dist/store/readiness.d.ts +11 -0
- package/dist/store/readiness.d.ts.map +1 -0
- package/dist/store/readiness.js +68 -0
- package/dist/store/records.d.ts +223 -0
- package/dist/store/records.d.ts.map +1 -0
- package/dist/store/records.js +465 -0
- package/dist/store/room-held.d.ts +8 -0
- package/dist/store/room-held.d.ts.map +1 -0
- package/dist/store/room-held.js +17 -0
- package/dist/store/rooms-shown.d.ts +8 -0
- package/dist/store/rooms-shown.d.ts.map +1 -0
- package/dist/store/rooms-shown.js +13 -0
- package/dist/store/space.d.ts +11 -0
- package/dist/store/space.d.ts.map +1 -0
- package/dist/store/space.js +41 -0
- package/dist/store/watchers.d.ts +17 -0
- package/dist/store/watchers.d.ts.map +1 -0
- package/dist/store/watchers.js +56 -0
- package/dist/store/writes.d.ts +24 -0
- package/dist/store/writes.d.ts.map +1 -0
- package/dist/store/writes.js +125 -0
- package/dist/store.d.ts +115 -152
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +171 -395
- package/dist/stored.d.ts +72 -67
- package/dist/stored.d.ts.map +1 -1
- package/dist/stored.js +317 -166
- package/dist/surface.d.ts +90 -0
- package/dist/surface.d.ts.map +1 -0
- package/dist/surface.js +225 -0
- package/dist/sync.d.ts +19 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +536 -0
- package/dist/tables.d.ts +112 -89
- package/dist/tables.d.ts.map +1 -1
- package/dist/tables.js +197 -283
- package/dist/tallies.d.ts +18 -0
- package/dist/tallies.d.ts.map +1 -0
- package/dist/tallies.js +128 -0
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +9 -12
- package/dist/windows.d.ts +1 -12
- package/dist/windows.d.ts.map +1 -1
- package/dist/windows.js +2 -75
- package/dist/wire.d.ts +68 -7
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +23 -4
- package/package.json +3 -2
- package/dist/attempt.d.ts +0 -16
- package/dist/attempt.d.ts.map +0 -1
- package/dist/attempt.js +0 -70
- package/dist/fence.d.ts +0 -6
- package/dist/fence.d.ts.map +0 -1
- package/dist/fence.js +0 -10
- package/dist/job.d.ts +0 -14
- package/dist/job.d.ts.map +0 -1
- package/dist/job.js +0 -28
- package/dist/log.d.ts +0 -5
- package/dist/log.d.ts.map +0 -1
- package/dist/log.js +0 -14
- package/dist/phrase.d.ts +0 -3
- package/dist/phrase.d.ts.map +0 -1
- package/dist/phrase.js +0 -8
package/dist/memory.js
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
|
+
import { definitionAt, documentFacts, keyedDestination, keyedLink, parse, } from '@agentshouse/mdmodel';
|
|
2
|
+
import { NO_ROOM_TYPES, schemaTypes } from './attached-model.js';
|
|
3
|
+
import { selected } from './collection.js';
|
|
4
|
+
import { declaredType } from './outcome.js';
|
|
1
5
|
import { sameChange } from './overlay.js';
|
|
2
6
|
const ATTACHMENTS = 'attachments';
|
|
7
|
+
const UNFOUND = {
|
|
8
|
+
kind: 'rejected',
|
|
9
|
+
code: 'not_found',
|
|
10
|
+
fields: {},
|
|
11
|
+
retryable: false,
|
|
12
|
+
};
|
|
3
13
|
function lastName(path) {
|
|
4
14
|
return path.slice(path.lastIndexOf('/') + 1);
|
|
5
15
|
}
|
|
6
16
|
const FIXTURE_RETENTION = {
|
|
7
17
|
history: { kind: 'duration', seconds: 1 },
|
|
8
|
-
outcome: 604_800,
|
|
9
18
|
refreshHorizon: 1,
|
|
10
19
|
};
|
|
11
20
|
function declaredRetention(value) {
|
|
@@ -52,9 +61,10 @@ export function createMemoryAdapter(options = {}) {
|
|
|
52
61
|
const listeners = new Set();
|
|
53
62
|
const modeObservers = new Set();
|
|
54
63
|
const scripted = new Map();
|
|
55
|
-
const
|
|
64
|
+
const repeats = new Map();
|
|
56
65
|
const historyPageSize = options.historyPageSize;
|
|
57
66
|
const attached = new Map();
|
|
67
|
+
const keyed = new Map();
|
|
58
68
|
const linked = new WeakMap();
|
|
59
69
|
const carried = new Map();
|
|
60
70
|
let expiring = [];
|
|
@@ -62,6 +72,7 @@ export function createMemoryAdapter(options = {}) {
|
|
|
62
72
|
const declaredRooms = new Set();
|
|
63
73
|
let replicated = [];
|
|
64
74
|
let heldCursor = null;
|
|
75
|
+
let agents = structuredClone(options.agents ?? []);
|
|
65
76
|
let issued = 0;
|
|
66
77
|
function scriptConversations(entries) {
|
|
67
78
|
scripted.clear();
|
|
@@ -92,6 +103,25 @@ export function createMemoryAdapter(options = {}) {
|
|
|
92
103
|
function heldBlob(room, path) {
|
|
93
104
|
return attached.get(`${room.locator}\u0000${path}`) ?? room.blobs?.[path];
|
|
94
105
|
}
|
|
106
|
+
function linkTo(room, path) {
|
|
107
|
+
const blob = room === undefined ? undefined : heldBlob(room, path);
|
|
108
|
+
if (blob === undefined)
|
|
109
|
+
return UNFOUND;
|
|
110
|
+
const url = linked.get(blob) ?? URL.createObjectURL(blob);
|
|
111
|
+
linked.set(blob, url);
|
|
112
|
+
return { kind: 'link', url, name: lastName(path), mediaType: declaredType(blob) };
|
|
113
|
+
}
|
|
114
|
+
function attachedKeyed(request) {
|
|
115
|
+
const room = rooms.find((entry) => entry.locator === options.privateRoom);
|
|
116
|
+
if (room === undefined) {
|
|
117
|
+
return { kind: 'rejected', code: 'room_not_found', fields: {}, retryable: false };
|
|
118
|
+
}
|
|
119
|
+
const path = freePath(room, request.name);
|
|
120
|
+
attached.set(`${room.locator}\u0000${path}`, request.blob);
|
|
121
|
+
const key = `memory-${keyed.size + 1}`;
|
|
122
|
+
keyed.set(key, { locator: room.locator, path });
|
|
123
|
+
return { kind: 'linked', link: keyedDestination(`/rooms/${room.handle}/${path}`, key) };
|
|
124
|
+
}
|
|
95
125
|
function freePath(room, name) {
|
|
96
126
|
const dot = name.lastIndexOf('.');
|
|
97
127
|
const stem = dot > 0 ? name.slice(0, dot) : name;
|
|
@@ -102,8 +132,40 @@ export function createMemoryAdapter(options = {}) {
|
|
|
102
132
|
return path;
|
|
103
133
|
}
|
|
104
134
|
}
|
|
135
|
+
const saved = new WeakMap();
|
|
136
|
+
const roomTypes = options.roomTypes ?? NO_ROOM_TYPES;
|
|
137
|
+
function factsAt(room, path, content) {
|
|
138
|
+
const types = selected({ selection: room.typedSelection ?? null }, path)
|
|
139
|
+
? roomTypes.types
|
|
140
|
+
: schemaTypes(room.model?.kind === 'model' ? room.model.snapshot.schema : null, roomTypes);
|
|
141
|
+
let held = saved.get(types);
|
|
142
|
+
if (held === undefined) {
|
|
143
|
+
held = new Map();
|
|
144
|
+
saved.set(types, held);
|
|
145
|
+
}
|
|
146
|
+
const key = `${path}\u0000${content}`;
|
|
147
|
+
if (!held.has(key)) {
|
|
148
|
+
const facts = documentFacts(path, parse(content, path, definitionAt({ types }, path, options.typedPaths)), {
|
|
149
|
+
types,
|
|
150
|
+
});
|
|
151
|
+
held.set(key, facts === null ? null : JSON.parse(JSON.stringify(facts)));
|
|
152
|
+
}
|
|
153
|
+
return held.get(key);
|
|
154
|
+
}
|
|
155
|
+
function factsIn(room, paths) {
|
|
156
|
+
const facts = {};
|
|
157
|
+
for (const path of paths) {
|
|
158
|
+
const content = room.documents?.[path];
|
|
159
|
+
const held = room.facts?.[path] ?? (content === undefined ? null : factsAt(room, path, content));
|
|
160
|
+
if (held !== null)
|
|
161
|
+
facts[path] = held;
|
|
162
|
+
}
|
|
163
|
+
return facts;
|
|
164
|
+
}
|
|
105
165
|
function retain(entries) {
|
|
106
166
|
for (const room of entries) {
|
|
167
|
+
for (const [path, content] of Object.entries(room.documents ?? {}))
|
|
168
|
+
factsAt(room, path, content);
|
|
107
169
|
note(room.locator, room);
|
|
108
170
|
const versions = served.get(room.locator) ?? new Map();
|
|
109
171
|
versions.set(room.roomVersion, room);
|
|
@@ -119,8 +181,9 @@ export function createMemoryAdapter(options = {}) {
|
|
|
119
181
|
roomVersion: room.roomVersion,
|
|
120
182
|
operations: room.operations,
|
|
121
183
|
replica: room.replica,
|
|
122
|
-
|
|
184
|
+
typedSelection: room.typedSelection ?? null,
|
|
123
185
|
providerOwnedPaths: room.providerOwnedPaths,
|
|
186
|
+
authoredPaths: room.authoredPaths ?? ['**'],
|
|
124
187
|
};
|
|
125
188
|
}
|
|
126
189
|
function page(room, after) {
|
|
@@ -136,10 +199,14 @@ export function createMemoryAdapter(options = {}) {
|
|
|
136
199
|
roomVersion: room.roomVersion,
|
|
137
200
|
...(opening ? { models: modelsOf(room) } : {}),
|
|
138
201
|
documents: named(room.documents ?? {}, taken),
|
|
202
|
+
facts: factsIn(room, taken),
|
|
139
203
|
revisions: named(room.revisions ?? {}, [...taken, ...targets]),
|
|
140
204
|
...(room.fileIds === undefined
|
|
141
205
|
? {}
|
|
142
206
|
: { fileIds: named(room.fileIds, [...taken, ...targets]) }),
|
|
207
|
+
...(room.created === undefined
|
|
208
|
+
? {}
|
|
209
|
+
: { created: named(room.created, [...taken, ...targets]) }),
|
|
143
210
|
changes: named(room.changes ?? {}, [...taken, ...targets]),
|
|
144
211
|
binaryFiles: named(room.binaryFiles ?? {}, targets),
|
|
145
212
|
...(opening && room.folders !== undefined ? { folders: room.folders } : {}),
|
|
@@ -163,6 +230,7 @@ export function createMemoryAdapter(options = {}) {
|
|
|
163
230
|
const previousTargets = new Set(Object.keys(from.binaryFiles ?? {}));
|
|
164
231
|
const headMoved = (path) => room.revisions?.[path] !== from.revisions?.[path] ||
|
|
165
232
|
room.fileIds?.[path] !== from.fileIds?.[path] ||
|
|
233
|
+
room.created?.[path] !== from.created?.[path] ||
|
|
166
234
|
!sameChange(room.changes?.[path], from.changes?.[path]);
|
|
167
235
|
const changed = Object.keys(current)
|
|
168
236
|
.filter((path) => current[path] !== previous[path] || headMoved(path))
|
|
@@ -183,10 +251,14 @@ export function createMemoryAdapter(options = {}) {
|
|
|
183
251
|
roomVersion: room.roomVersion,
|
|
184
252
|
...(models === undefined ? {} : { models }),
|
|
185
253
|
documents: named(current, taken),
|
|
254
|
+
facts: factsIn(room, taken),
|
|
186
255
|
revisions: named(room.revisions ?? {}, [...taken, ...targets]),
|
|
187
256
|
...(room.fileIds === undefined
|
|
188
257
|
? {}
|
|
189
258
|
: { fileIds: named(room.fileIds, [...taken, ...targets]) }),
|
|
259
|
+
...(room.created === undefined
|
|
260
|
+
? {}
|
|
261
|
+
: { created: named(room.created, [...taken, ...targets]) }),
|
|
190
262
|
changes: named(room.changes ?? {}, [...taken, ...targets]),
|
|
191
263
|
binaryFiles: named(room.binaryFiles ?? {}, targets),
|
|
192
264
|
...(opening ? foldersMoved(room, from) : {}),
|
|
@@ -221,16 +293,14 @@ export function createMemoryAdapter(options = {}) {
|
|
|
221
293
|
}
|
|
222
294
|
function pageOf(conversation, after) {
|
|
223
295
|
const messages = conversation.messages ?? [];
|
|
224
|
-
const first = typeof after === 'string' ? messages.findIndex((message) => message.
|
|
296
|
+
const first = typeof after === 'string' ? messages.findIndex((message) => message.change > after) : 0;
|
|
225
297
|
const from = first === -1 ? messages.length : first;
|
|
226
298
|
const page = messages.slice(from, from + (historyPageSize ?? messages.length));
|
|
227
299
|
const last = page.at(-1);
|
|
228
300
|
return {
|
|
229
301
|
conversation: conversation.conversation,
|
|
230
302
|
messages: page,
|
|
231
|
-
...(last !== undefined && from + page.length < messages.length
|
|
232
|
-
? { next: last.position }
|
|
233
|
-
: {}),
|
|
303
|
+
...(last !== undefined && from + page.length < messages.length ? { next: last.change } : {}),
|
|
234
304
|
};
|
|
235
305
|
}
|
|
236
306
|
function historiesOf(request) {
|
|
@@ -250,11 +320,20 @@ export function createMemoryAdapter(options = {}) {
|
|
|
250
320
|
function conversationAction(request) {
|
|
251
321
|
const name = request.name;
|
|
252
322
|
const input = (request.input ?? {});
|
|
323
|
+
const operation = typeof input.operation_id === 'string' ? `${name}\u0000${input.operation_id}` : null;
|
|
324
|
+
const first = (answer) => {
|
|
325
|
+
if (operation !== null)
|
|
326
|
+
repeats.set(operation, answer);
|
|
327
|
+
return answer;
|
|
328
|
+
};
|
|
329
|
+
const repeated = operation === null ? undefined : repeats.get(operation);
|
|
253
330
|
if (name === 'conversations/create') {
|
|
331
|
+
if (repeated !== undefined)
|
|
332
|
+
return repeated;
|
|
254
333
|
issued += 1;
|
|
255
334
|
const conversation = `conversation-${issued}`;
|
|
256
335
|
scripted.set(conversation, { conversation });
|
|
257
|
-
return { kind: 'action', result: { conversation_id: conversation } };
|
|
336
|
+
return first({ kind: 'action', result: { conversation_id: conversation } });
|
|
258
337
|
}
|
|
259
338
|
const named = typeof input.conversation_id === 'string' ? input.conversation_id : '';
|
|
260
339
|
const conversation = scripted.get(named);
|
|
@@ -270,26 +349,39 @@ export function createMemoryAdapter(options = {}) {
|
|
|
270
349
|
if (outcome !== undefined)
|
|
271
350
|
return outcome;
|
|
272
351
|
if (name === 'conversations/send') {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
if (answered !== undefined)
|
|
276
|
-
return { kind: 'action', result: { message_id: answered } };
|
|
352
|
+
if (repeated !== undefined)
|
|
353
|
+
return repeated;
|
|
277
354
|
issued += 1;
|
|
278
|
-
|
|
279
|
-
if (operation !== null)
|
|
280
|
-
sentTurns.set(operation, turn);
|
|
281
|
-
return { kind: 'action', result: { message_id: turn } };
|
|
355
|
+
return first({ kind: 'action', result: { message_id: `turn-${issued}` } });
|
|
282
356
|
}
|
|
283
357
|
if (name === 'conversations/delete')
|
|
284
358
|
scripted.delete(named);
|
|
285
359
|
return { kind: 'action', result: { conversation_id: named } };
|
|
286
360
|
}
|
|
361
|
+
function decided(request) {
|
|
362
|
+
const { request: asked, message, decision, } = (request.input ?? {});
|
|
363
|
+
return {
|
|
364
|
+
kind: 'action',
|
|
365
|
+
result: {
|
|
366
|
+
request: asked,
|
|
367
|
+
...(message === undefined ? {} : { message }),
|
|
368
|
+
state: decision === 'approve' ? 'started' : 'declined',
|
|
369
|
+
},
|
|
370
|
+
};
|
|
371
|
+
}
|
|
287
372
|
function announceList() {
|
|
288
373
|
const entries = [...scripted.values()].flatMap(({ conversation, listed, messages = [] }) => listed === undefined
|
|
289
374
|
? []
|
|
290
|
-
: [{ conversation, ...listed, newest: messages.at(-1)?.
|
|
375
|
+
: [{ conversation, ...listed, newest: messages.at(-1)?.change ?? null }]);
|
|
291
376
|
for (const listener of listeners) {
|
|
292
|
-
listener({
|
|
377
|
+
listener({
|
|
378
|
+
kind: 'list',
|
|
379
|
+
agents: structuredClone(agents),
|
|
380
|
+
entries,
|
|
381
|
+
whole: true,
|
|
382
|
+
more: false,
|
|
383
|
+
cursor: null,
|
|
384
|
+
});
|
|
293
385
|
}
|
|
294
386
|
}
|
|
295
387
|
function discovery() {
|
|
@@ -337,6 +429,7 @@ export function createMemoryAdapter(options = {}) {
|
|
|
337
429
|
}
|
|
338
430
|
return {
|
|
339
431
|
...(options.roomTypes === undefined ? {} : { roomTypes: options.roomTypes }),
|
|
432
|
+
...(options.typedPaths === undefined ? {} : { typedPaths: options.typedPaths }),
|
|
340
433
|
setRooms(next) {
|
|
341
434
|
rooms = [...next];
|
|
342
435
|
retain(rooms);
|
|
@@ -344,6 +437,9 @@ export function createMemoryAdapter(options = {}) {
|
|
|
344
437
|
setConversations(next) {
|
|
345
438
|
scriptConversations(next);
|
|
346
439
|
},
|
|
440
|
+
setAgents(next) {
|
|
441
|
+
agents = structuredClone(next);
|
|
442
|
+
},
|
|
347
443
|
open() {
|
|
348
444
|
carried.clear();
|
|
349
445
|
announceList();
|
|
@@ -406,9 +502,6 @@ export function createMemoryAdapter(options = {}) {
|
|
|
406
502
|
};
|
|
407
503
|
},
|
|
408
504
|
history: (request) => Promise.resolve(historiesOf(request)),
|
|
409
|
-
...(options.agents === undefined
|
|
410
|
-
? {}
|
|
411
|
-
: { agents: () => Promise.resolve(structuredClone(options.agents)) }),
|
|
412
505
|
},
|
|
413
506
|
serviceMode: {
|
|
414
507
|
observe(notify) {
|
|
@@ -423,9 +516,10 @@ export function createMemoryAdapter(options = {}) {
|
|
|
423
516
|
const named = asked.map((room) => room.locator);
|
|
424
517
|
const unknown = asked.flatMap((room) => {
|
|
425
518
|
const current = rooms.find((entry) => entry.locator === room.locator);
|
|
519
|
+
const version = room.roomVersion;
|
|
426
520
|
return current === undefined ||
|
|
427
|
-
|
|
428
|
-
|
|
521
|
+
(version !== null &&
|
|
522
|
+
(current.roomVersion === version || served.get(room.locator)?.has(version) === true))
|
|
429
523
|
? []
|
|
430
524
|
: [room.locator];
|
|
431
525
|
});
|
|
@@ -435,7 +529,7 @@ export function createMemoryAdapter(options = {}) {
|
|
|
435
529
|
expiring = expiring.filter((locator) => !named.includes(locator));
|
|
436
530
|
queueMicrotask(() => {
|
|
437
531
|
for (const room of asked) {
|
|
438
|
-
if (expired.includes(room.locator))
|
|
532
|
+
if (expired.includes(room.locator) || room.roomVersion === null)
|
|
439
533
|
carried.delete(room.locator);
|
|
440
534
|
else {
|
|
441
535
|
carried.set(room.locator, room.roomVersion);
|
|
@@ -559,26 +653,29 @@ export function createMemoryAdapter(options = {}) {
|
|
|
559
653
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
560
654
|
const blob = heldBlob(room, request.path);
|
|
561
655
|
return blob === undefined
|
|
562
|
-
? { kind: 'rejected', code: '
|
|
563
|
-
: { kind: 'binary', body: blob.stream(), mediaType: blob
|
|
656
|
+
? { kind: 'rejected', code: 'not_found', fields: {}, retryable: false }
|
|
657
|
+
: { kind: 'binary', body: blob.stream(), mediaType: declaredType(blob) };
|
|
564
658
|
}, request);
|
|
565
659
|
},
|
|
566
660
|
async link(_authorization, request) {
|
|
567
661
|
return resolveScript(scripts.link, () => {
|
|
662
|
+
if (request.kind === 'key') {
|
|
663
|
+
const key = keyedLink(request.link)?.key;
|
|
664
|
+
const named = key === undefined ? undefined : keyed.get(key);
|
|
665
|
+
if (named === undefined)
|
|
666
|
+
return UNFOUND;
|
|
667
|
+
return linkTo(rooms.find((entry) => entry.locator === named.locator), named.path);
|
|
668
|
+
}
|
|
568
669
|
const room = rooms.find((entry) => entry.locator === request.locator);
|
|
569
670
|
if (room === undefined)
|
|
570
671
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
571
|
-
|
|
572
|
-
if (blob === undefined) {
|
|
573
|
-
return { kind: 'rejected', code: 'file_not_found', fields: {}, retryable: false };
|
|
574
|
-
}
|
|
575
|
-
const url = linked.get(blob) ?? URL.createObjectURL(blob);
|
|
576
|
-
linked.set(blob, url);
|
|
577
|
-
return { kind: 'link', url, name: lastName(request.path), mediaType: blob.type };
|
|
672
|
+
return linkTo(room, request.path);
|
|
578
673
|
}, request);
|
|
579
674
|
},
|
|
580
675
|
async attach(_authorization, request) {
|
|
581
676
|
return resolveScript(scripts.attach, () => {
|
|
677
|
+
if (request.locator === undefined)
|
|
678
|
+
return attachedKeyed(request);
|
|
582
679
|
const room = rooms.find((entry) => entry.locator === request.locator);
|
|
583
680
|
if (room === undefined)
|
|
584
681
|
return { kind: 'room-not-readable', locator: request.locator };
|
|
@@ -591,6 +688,8 @@ export function createMemoryAdapter(options = {}) {
|
|
|
591
688
|
return resolveScript(scripts.action, () => {
|
|
592
689
|
if (request.name.startsWith('conversations/'))
|
|
593
690
|
return conversationAction(request);
|
|
691
|
+
if (request.name === 'agent-functions/decide')
|
|
692
|
+
return decided(request);
|
|
594
693
|
return { kind: 'rejected', code: 'unscripted-action', fields: {}, retryable: false };
|
|
595
694
|
}, request).then((answer) => {
|
|
596
695
|
if (answer.kind === 'action' && answer.at !== undefined)
|
package/dist/messages.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AcceptedMessage } from './adapter.js';
|
|
2
2
|
import type { Connection } from './tables.js';
|
|
3
3
|
export declare const MESSAGE_TABLES: readonly string[];
|
|
4
|
+
export declare const ROWS = "WITH chosen AS (\n SELECT listed.value AS conversation,\n (SELECT id FROM conversation_messages WHERE conversation = listed.value AND json_extract(message, '$.role') = 'assistant' ORDER BY position DESC, identity DESC LIMIT 1) AS answer,\n (SELECT id FROM conversation_messages WHERE conversation = listed.value AND text <> '' ORDER BY position DESC, identity DESC LIMIT 1) AS said,\n (SELECT id FROM conversation_messages WHERE conversation = listed.value AND json_extract(message, '$.role') = 'house' ORDER BY position, identity LIMIT 1) AS opened,\n (SELECT id FROM conversation_messages WHERE conversation = listed.value AND json_extract(message, '$.role') = 'house' AND json_extract(message, '$.waiting') = 1 ORDER BY position, identity LIMIT 1) AS asking\n FROM json_each(?) AS listed\n )\n SELECT chosen.conversation AS conversation,\n substr(said.text, 1, 512) AS said_text,\n json_extract(said.message, '$.role') AS said_role,\n json_extract(said.message, '$.accepted_at') AS said_at,\n answer.turn AS answered,\n substr(json_extract(answer.message, '$.failure'), 1, 512) AS failure,\n (SELECT value FROM conversation_facts WHERE conversation = chosen.conversation AND name = 'openedTurn') AS opened_turn,\n json_extract(opened.message, '$.source') AS opened_source,\n json_extract(opened.message, '$.sender') AS opened_sender,\n asking.identity AS asking_identity,\n asking.text AS asking_text,\n json_extract(asking.message, '$.accepted_at') AS asking_at,\n json_extract(asking.message, '$.source') AS asking_source,\n json_extract(asking.message, '$.sender') AS asking_sender\n FROM chosen\n LEFT JOIN conversation_messages said ON said.id = chosen.said\n LEFT JOIN conversation_messages answer ON answer.id = chosen.answer\n LEFT JOIN conversation_messages opened ON opened.id = chosen.opened\n LEFT JOIN conversation_messages asking ON asking.id = chosen.asking";
|
|
4
5
|
export type HeldConversation = {
|
|
5
6
|
readonly conversation: string;
|
|
6
7
|
readonly read: string | null | undefined;
|
|
@@ -10,6 +11,33 @@ export type MessageWindow = {
|
|
|
10
11
|
readonly messages: AcceptedMessage[];
|
|
11
12
|
readonly more: boolean;
|
|
12
13
|
};
|
|
14
|
+
export type HeldSource = {
|
|
15
|
+
readonly source: unknown;
|
|
16
|
+
readonly sender: string | null;
|
|
17
|
+
};
|
|
18
|
+
export type HeldRow = {
|
|
19
|
+
readonly conversation: string;
|
|
20
|
+
readonly said: {
|
|
21
|
+
readonly text: string;
|
|
22
|
+
readonly role: string | null;
|
|
23
|
+
readonly at: string | null;
|
|
24
|
+
} | null;
|
|
25
|
+
readonly answered: string | null;
|
|
26
|
+
readonly openedTurn: string | null;
|
|
27
|
+
readonly failure: string | null;
|
|
28
|
+
readonly opened: HeldSource | null;
|
|
29
|
+
readonly asking: (HeldSource & {
|
|
30
|
+
readonly identity: string;
|
|
31
|
+
readonly text: string;
|
|
32
|
+
readonly at: string | null;
|
|
33
|
+
}) | null;
|
|
34
|
+
};
|
|
35
|
+
export type ConversationFact = 'openedTurn' | 'dismissedSuggestion';
|
|
36
|
+
export type HeldFact = {
|
|
37
|
+
readonly conversation: string;
|
|
38
|
+
readonly name: ConversationFact;
|
|
39
|
+
readonly value: string;
|
|
40
|
+
};
|
|
13
41
|
export type ConversationWrite = {
|
|
14
42
|
readonly conversation: string;
|
|
15
43
|
readonly messages: readonly AcceptedMessage[];
|
|
@@ -18,11 +46,13 @@ export type ConversationWrite = {
|
|
|
18
46
|
readonly partial: boolean;
|
|
19
47
|
};
|
|
20
48
|
};
|
|
21
|
-
export declare function heldConversations(connection: Connection): HeldConversation[];
|
|
49
|
+
export declare function heldConversations(connection: Connection, conversations: readonly string[] | null): HeldConversation[];
|
|
22
50
|
export declare function keptMessages(connection: Connection, { conversation, messages, read }: ConversationWrite): null;
|
|
23
51
|
export declare function messageWindow(connection: Connection, conversation: string, limit: number, before: readonly [string, string] | null, phrase: string | null): MessageWindow;
|
|
24
52
|
export declare function messageCount(connection: Connection, conversation: string, phrase: string | null): number;
|
|
53
|
+
export declare function conversationRows(connection: Connection, conversations: readonly string[]): HeldRow[];
|
|
25
54
|
export declare function turnArrived(connection: Connection, conversation: string, turn: string): boolean;
|
|
26
|
-
export declare function
|
|
27
|
-
export declare function
|
|
55
|
+
export declare function conversationFacts(connection: Connection): HeldFact[];
|
|
56
|
+
export declare function keptFact(connection: Connection, { conversation, name, value }: HeldFact): null;
|
|
57
|
+
export declare function forgottenConversations(connection: Connection): void;
|
|
28
58
|
//# sourceMappingURL=messages.d.ts.map
|
package/dist/messages.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"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"}
|
package/dist/messages.js
CHANGED
|
@@ -1,24 +1,60 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { sql } from '@agentshouse/mdmodel';
|
|
2
|
+
import { text } from './column.js';
|
|
3
|
+
import { EXCERPT } from './read.js';
|
|
4
|
+
import { tablesOf } from './stored.js';
|
|
5
|
+
const SAID_BY_HOUSE = `json_extract(message, '$.role') = 'house'`;
|
|
6
|
+
const ANSWERS_THE_TURN = `json_extract(message, '$.role') = 'assistant'`;
|
|
2
7
|
export const MESSAGE_TABLES = [
|
|
3
8
|
'CREATE TABLE conversation_reads (conversation TEXT PRIMARY KEY, read TEXT, partial INTEGER NOT NULL) WITHOUT ROWID',
|
|
4
|
-
'CREATE TABLE conversation_messages (id INTEGER PRIMARY KEY, conversation TEXT NOT NULL, identity TEXT NOT NULL, turn TEXT NOT NULL, position TEXT NOT NULL, message TEXT NOT NULL, text TEXT NOT NULL)',
|
|
9
|
+
'CREATE TABLE conversation_messages (id INTEGER PRIMARY KEY, conversation TEXT NOT NULL, identity TEXT NOT NULL, turn TEXT NOT NULL, position TEXT NOT NULL, change TEXT NOT NULL, message TEXT NOT NULL, text TEXT NOT NULL)',
|
|
5
10
|
'CREATE UNIQUE INDEX conversation_messages_identity ON conversation_messages (conversation, identity)',
|
|
6
11
|
'CREATE INDEX conversation_messages_position ON conversation_messages (conversation, position, identity)',
|
|
7
12
|
'CREATE INDEX conversation_messages_turn ON conversation_messages (conversation, turn)',
|
|
13
|
+
`CREATE INDEX conversation_messages_house ON conversation_messages (conversation, position, identity) WHERE ${SAID_BY_HOUSE}`,
|
|
14
|
+
'CREATE TABLE conversation_facts (conversation TEXT NOT NULL, name TEXT NOT NULL, value TEXT NOT NULL, PRIMARY KEY (conversation, name)) WITHOUT ROWID',
|
|
8
15
|
];
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
export
|
|
16
|
+
const NEWEST_FIRST = 'ORDER BY position DESC, identity DESC LIMIT 1';
|
|
17
|
+
const OLDEST_FIRST = 'ORDER BY position, identity LIMIT 1';
|
|
18
|
+
const OF_THE_ROW = 'SELECT id FROM conversation_messages WHERE conversation = listed.value';
|
|
19
|
+
export const ROWS = `WITH chosen AS (
|
|
20
|
+
SELECT listed.value AS conversation,
|
|
21
|
+
(${OF_THE_ROW} AND ${ANSWERS_THE_TURN} ${NEWEST_FIRST}) AS answer,
|
|
22
|
+
(${OF_THE_ROW} AND text <> '' ${NEWEST_FIRST}) AS said,
|
|
23
|
+
(${OF_THE_ROW} AND ${SAID_BY_HOUSE} ${OLDEST_FIRST}) AS opened,
|
|
24
|
+
(${OF_THE_ROW} AND ${SAID_BY_HOUSE} AND json_extract(message, '$.waiting') = 1 ${OLDEST_FIRST}) AS asking
|
|
25
|
+
FROM json_each(?) AS listed
|
|
26
|
+
)
|
|
27
|
+
SELECT chosen.conversation AS conversation,
|
|
28
|
+
substr(said.text, 1, ${EXCERPT}) AS said_text,
|
|
29
|
+
json_extract(said.message, '$.role') AS said_role,
|
|
30
|
+
json_extract(said.message, '$.accepted_at') AS said_at,
|
|
31
|
+
answer.turn AS answered,
|
|
32
|
+
substr(json_extract(answer.message, '$.failure'), 1, ${EXCERPT}) AS failure,
|
|
33
|
+
(SELECT value FROM conversation_facts WHERE conversation = chosen.conversation AND name = 'openedTurn') AS opened_turn,
|
|
34
|
+
json_extract(opened.message, '$.source') AS opened_source,
|
|
35
|
+
json_extract(opened.message, '$.sender') AS opened_sender,
|
|
36
|
+
asking.identity AS asking_identity,
|
|
37
|
+
asking.text AS asking_text,
|
|
38
|
+
json_extract(asking.message, '$.accepted_at') AS asking_at,
|
|
39
|
+
json_extract(asking.message, '$.source') AS asking_source,
|
|
40
|
+
json_extract(asking.message, '$.sender') AS asking_sender
|
|
41
|
+
FROM chosen
|
|
42
|
+
LEFT JOIN conversation_messages said ON said.id = chosen.said
|
|
43
|
+
LEFT JOIN conversation_messages answer ON answer.id = chosen.answer
|
|
44
|
+
LEFT JOIN conversation_messages opened ON opened.id = chosen.opened
|
|
45
|
+
LEFT JOIN conversation_messages asking ON asking.id = chosen.asking`;
|
|
46
|
+
export function heldConversations(connection, conversations) {
|
|
47
|
+
const named = conversations === null ? '' : ' AND conversation IN (SELECT value FROM json_each(?))';
|
|
48
|
+
const bound = conversations === null ? [] : [JSON.stringify(conversations)];
|
|
13
49
|
const held = new Map();
|
|
14
|
-
for (const row of connection.rows(
|
|
50
|
+
for (const row of connection.rows(`SELECT conversation, read, partial FROM conversation_reads WHERE 1 = 1${named}`, bound)) {
|
|
15
51
|
held.set(text(row.conversation), {
|
|
16
52
|
conversation: text(row.conversation),
|
|
17
53
|
read: row.read === null ? null : text(row.read),
|
|
18
54
|
partial: Number(row.partial) === 1,
|
|
19
55
|
});
|
|
20
56
|
}
|
|
21
|
-
for (const row of connection.rows(
|
|
57
|
+
for (const row of connection.rows(`SELECT DISTINCT conversation FROM conversation_messages WHERE conversation NOT IN (SELECT conversation FROM conversation_reads)${named}`, bound)) {
|
|
22
58
|
held.set(text(row.conversation), {
|
|
23
59
|
conversation: text(row.conversation),
|
|
24
60
|
read: undefined,
|
|
@@ -29,19 +65,15 @@ export function heldConversations(connection) {
|
|
|
29
65
|
}
|
|
30
66
|
export function keptMessages(connection, { conversation, messages, read }) {
|
|
31
67
|
for (const message of messages) {
|
|
32
|
-
|
|
33
|
-
|
|
68
|
+
connection.run('INSERT INTO conversation_messages (conversation, identity, turn, position, change, message, text) VALUES (?, ?, ?, ?, ?, ?, ?) ON CONFLICT (conversation, identity) DO UPDATE SET turn = excluded.turn, position = excluded.position, change = excluded.change, message = excluded.message, text = excluded.text', [
|
|
69
|
+
conversation,
|
|
70
|
+
message.identity,
|
|
34
71
|
message.turn,
|
|
35
72
|
message.position,
|
|
73
|
+
message.change,
|
|
36
74
|
JSON.stringify(message.message ?? null),
|
|
37
75
|
message.text,
|
|
38
|
-
];
|
|
39
|
-
if (held === undefined) {
|
|
40
|
-
connection.run('INSERT INTO conversation_messages (conversation, identity, turn, position, message, text) VALUES (?, ?, ?, ?, ?, ?)', [conversation, message.identity, ...record]);
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
connection.run('UPDATE conversation_messages SET turn = ?, position = ?, message = ?, text = ? WHERE id = ?', [...record, held.id]);
|
|
44
|
-
}
|
|
76
|
+
]);
|
|
45
77
|
}
|
|
46
78
|
if (read !== undefined) {
|
|
47
79
|
connection.run('INSERT OR REPLACE INTO conversation_reads (conversation, read, partial) VALUES (?, ?, ?)', [conversation, read.at, read.partial ? 1 : 0]);
|
|
@@ -53,6 +85,7 @@ function accepted(row) {
|
|
|
53
85
|
identity: text(row.identity),
|
|
54
86
|
turn: text(row.turn),
|
|
55
87
|
position: text(row.position),
|
|
88
|
+
change: text(row.change),
|
|
56
89
|
text: text(row.text),
|
|
57
90
|
message: JSON.parse(text(row.message)),
|
|
58
91
|
};
|
|
@@ -60,11 +93,11 @@ function accepted(row) {
|
|
|
60
93
|
function holding(phrase) {
|
|
61
94
|
return phrase === null
|
|
62
95
|
? { sql: '', bind: [] }
|
|
63
|
-
: { sql: ` AND ${HOLDS_PHRASE}(text, ?)`, bind: [phrase.toLowerCase()] };
|
|
96
|
+
: { sql: ` AND ${sql.HOLDS_PHRASE}(text, ?)`, bind: [phrase.toLowerCase()] };
|
|
64
97
|
}
|
|
65
98
|
export function messageWindow(connection, conversation, limit, before, phrase) {
|
|
66
99
|
const held = holding(phrase);
|
|
67
|
-
const rows = connection.rows(`SELECT identity, turn, position, message, text FROM conversation_messages WHERE conversation = ?${held.sql}${before === null ? '' : ' AND (position < ? OR (position = ? AND identity < ?))'} ORDER BY position DESC, identity DESC LIMIT ?`, before === null
|
|
100
|
+
const rows = connection.rows(`SELECT identity, turn, position, change, message, text FROM conversation_messages WHERE conversation = ?${held.sql}${before === null ? '' : ' AND (position < ? OR (position = ? AND identity < ?))'} ORDER BY position DESC, identity DESC LIMIT ?`, before === null
|
|
68
101
|
? [conversation, ...held.bind, limit + 1]
|
|
69
102
|
: [conversation, ...held.bind, before[0], before[0], before[1], limit + 1]);
|
|
70
103
|
return { messages: rows.slice(0, limit).map(accepted).reverse(), more: rows.length > limit };
|
|
@@ -74,16 +107,54 @@ export function messageCount(connection, conversation, phrase) {
|
|
|
74
107
|
const [counted] = connection.rows(`SELECT count(*) AS held FROM conversation_messages WHERE conversation = ?${held.sql}`, [conversation, ...held.bind]);
|
|
75
108
|
return Number(counted?.held ?? 0);
|
|
76
109
|
}
|
|
110
|
+
function textOrNull(value) {
|
|
111
|
+
return value === null ? null : text(value);
|
|
112
|
+
}
|
|
113
|
+
function heldSource(source, sender) {
|
|
114
|
+
return {
|
|
115
|
+
source: source === null ? null : JSON.parse(text(source)),
|
|
116
|
+
sender: textOrNull(sender),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
export function conversationRows(connection, conversations) {
|
|
120
|
+
return connection.rows(ROWS, [JSON.stringify(conversations)]).map((row) => ({
|
|
121
|
+
conversation: text(row.conversation),
|
|
122
|
+
said: row.said_text === null
|
|
123
|
+
? null
|
|
124
|
+
: {
|
|
125
|
+
text: text(row.said_text),
|
|
126
|
+
role: textOrNull(row.said_role),
|
|
127
|
+
at: textOrNull(row.said_at),
|
|
128
|
+
},
|
|
129
|
+
answered: textOrNull(row.answered),
|
|
130
|
+
openedTurn: textOrNull(row.opened_turn),
|
|
131
|
+
failure: textOrNull(row.failure),
|
|
132
|
+
opened: row.opened_source === null ? null : heldSource(row.opened_source, row.opened_sender),
|
|
133
|
+
asking: row.asking_identity === null
|
|
134
|
+
? null
|
|
135
|
+
: {
|
|
136
|
+
...heldSource(row.asking_source, row.asking_sender),
|
|
137
|
+
identity: text(row.asking_identity),
|
|
138
|
+
text: text(row.asking_text),
|
|
139
|
+
at: textOrNull(row.asking_at),
|
|
140
|
+
},
|
|
141
|
+
}));
|
|
142
|
+
}
|
|
77
143
|
export function turnArrived(connection, conversation, turn) {
|
|
78
144
|
return (connection.rows('SELECT 1 FROM conversation_messages WHERE conversation = ? AND turn = ? LIMIT 1', [conversation, turn]).length > 0);
|
|
79
145
|
}
|
|
80
|
-
export function
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
146
|
+
export function conversationFacts(connection) {
|
|
147
|
+
return connection.rows('SELECT conversation, name, value FROM conversation_facts').map((row) => ({
|
|
148
|
+
conversation: text(row.conversation),
|
|
149
|
+
name: text(row.name),
|
|
150
|
+
value: text(row.value),
|
|
151
|
+
}));
|
|
152
|
+
}
|
|
153
|
+
export function keptFact(connection, { conversation, name, value }) {
|
|
154
|
+
connection.run('INSERT OR REPLACE INTO conversation_facts (conversation, name, value) VALUES (?, ?, ?)', [conversation, name, value]);
|
|
155
|
+
return null;
|
|
85
156
|
}
|
|
86
|
-
export function
|
|
87
|
-
|
|
88
|
-
|
|
157
|
+
export function forgottenConversations(connection) {
|
|
158
|
+
for (const table of tablesOf(MESSAGE_TABLES))
|
|
159
|
+
connection.run(`DELETE FROM ${table}`);
|
|
89
160
|
}
|
package/dist/model.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Definition,
|
|
1
|
+
import type { Definition, VerifiedModel } from '@agentshouse/mdmodel';
|
|
2
2
|
import type { Open } from './open.js';
|
|
3
3
|
export type ModelIdentity = {
|
|
4
4
|
identity: string;
|
|
@@ -8,7 +8,7 @@ export type ModelSnapshot = ModelIdentity & {
|
|
|
8
8
|
schema: string | null;
|
|
9
9
|
revision: string | null;
|
|
10
10
|
};
|
|
11
|
-
export type ModelUnavailableReason = Open<'not-readable' | 'revoked' | 'not-acquired'
|
|
11
|
+
export type ModelUnavailableReason = Open<'not-readable' | 'revoked' | 'not-acquired'>;
|
|
12
12
|
export type ModelResult = {
|
|
13
13
|
kind: 'model';
|
|
14
14
|
snapshot: ModelSnapshot;
|
|
@@ -20,8 +20,6 @@ export type MdType = Definition;
|
|
|
20
20
|
export type ModelState = {
|
|
21
21
|
status: 'unavailable';
|
|
22
22
|
reason: ModelUnavailableReason;
|
|
23
|
-
schema?: string | null;
|
|
24
|
-
revision?: string | null;
|
|
25
23
|
} | {
|
|
26
24
|
status: 'current' | 'cached';
|
|
27
25
|
snapshot: ModelSnapshot;
|
|
@@ -37,8 +35,6 @@ export type TypesResult = {
|
|
|
37
35
|
status: Open<'unavailable'>;
|
|
38
36
|
reason: ModelUnavailableReason;
|
|
39
37
|
types: null;
|
|
40
|
-
schema?: string | null;
|
|
41
|
-
revision?: string | null;
|
|
42
38
|
} | {
|
|
43
39
|
status: Open<'current' | 'cached'>;
|
|
44
40
|
identity: string;
|
|
@@ -54,10 +50,6 @@ export type ValidationReceipt = {
|
|
|
54
50
|
source: Open<'current' | 'cached'>;
|
|
55
51
|
};
|
|
56
52
|
export declare const NO_MODEL: ModelState;
|
|
57
|
-
export declare function definitionOf(state: ModelState, type: string | undefined): Definition | undefined;
|
|
58
53
|
export declare function modelTypes(state: ModelState): TypesResult;
|
|
59
54
|
export declare function storedModel(state: ModelState): StoredModel;
|
|
60
|
-
export declare function cached(state: ModelState): ModelState;
|
|
61
|
-
export declare function sameModel(left: ModelIdentity, right: ModelIdentity): boolean;
|
|
62
|
-
export declare function referenceField(facts: ValueFacts | undefined): boolean;
|
|
63
55
|
//# sourceMappingURL=model.d.ts.map
|
package/dist/model.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAClE,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAC/F,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,cAAc,GAAG,SAAS,GAAG,cAAc,CAAC,CAAC;AACvF,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,CAAC;AAClE,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC;AAChC,MAAM,MAAM,UAAU,GAClB;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAA;CAAE,GACzD;IACE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,QAAQ,EAAE,aAAa,CAAC;IACxB,YAAY,EAAE,aAAa,CAAC;IAC5B,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;CAC/B,CAAC;AACN,MAAM,MAAM,WAAW,GACnB,OAAO,CAAC,UAAU,EAAE;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE,CAAC,GAC9C,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE;IAAE,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAA;CAAE,CAAC,EAAE,OAAO,CAAC,CAAC;AACzE,MAAM,MAAM,WAAW,GACnB;IAAE,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,GAC5E;IACE,MAAM,EAAE,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,aAAa,CAAC;IAC5B,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC;AACN,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC;CACpC,CAAC;AACF,eAAO,MAAM,QAAQ,EAAE,UAA8D,CAAC;AACtF,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAczD;AACD,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAI1D"}
|