effect-agent 0.1.0-beta.140 → 0.1.0-beta.142
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/dist/{AgentRuntime-RdmnK_aD.mjs → AgentRuntime-xeCUXutN.mjs} +10 -9
- package/dist/AgentRuntime-xeCUXutN.mjs.map +1 -0
- package/dist/{DurableAgentRuntime-BmG_UVZG.mjs → DurableAgentRuntime-DQXDcPKQ.mjs} +2 -2
- package/dist/{DurableAgentRuntime-BmG_UVZG.mjs.map → DurableAgentRuntime-DQXDcPKQ.mjs.map} +1 -1
- package/dist/{Subagent-Bnc7I-kb.mjs → Subagent-8RzJkqJ9.mjs} +2 -2
- package/dist/{Subagent-Bnc7I-kb.mjs.map → Subagent-8RzJkqJ9.mjs.map} +1 -1
- package/dist/capabilities/Subagent.mjs +1 -1
- package/dist/durable/DurableAgentRuntime.mjs +1 -1
- package/dist/engine/AgentRuntime.mjs +1 -1
- package/dist/index.d.mts +1 -2
- package/dist/index.mjs +4 -5
- package/package.json +1 -1
- package/src/engine/internal/agent-runtime.ts +49 -19
- package/src/index.ts +0 -2
- package/dist/AgentRuntime-RdmnK_aD.mjs.map +0 -1
- package/dist/durable/SqlMessageDeliveryStore.d.mts +0 -42
- package/dist/durable/SqlMessageDeliveryStore.mjs +0 -179
- package/dist/durable/SqlMessageDeliveryStore.mjs.map +0 -1
- package/dist/durable/SqlStorageV2Upgrade.d.mts +0 -21
- package/dist/durable/SqlStorageV2Upgrade.mjs +0 -459
- package/dist/durable/SqlStorageV2Upgrade.mjs.map +0 -1
- package/dist/durable/SqlSubscriptionStore.d.mts +0 -62
- package/dist/durable/SqlSubscriptionStore.mjs +0 -751
- package/dist/durable/SqlSubscriptionStore.mjs.map +0 -1
- package/dist/durable/SqlThreadNativeReads.d.mts +0 -55
- package/dist/durable/SqlThreadNativeReads.mjs +0 -196
- package/dist/durable/SqlThreadNativeReads.mjs.map +0 -1
- package/src/durable/SqlMessageDeliveryStore.ts +0 -335
- package/src/durable/SqlStorageV2Upgrade.ts +0 -500
- package/src/durable/SqlSubscriptionStore.ts +0 -1440
- package/src/durable/SqlThreadNativeReads.ts +0 -343
- package/src/durable/internal/storage-v2-layout.ts +0 -163
- package/src/durable/internal/storage-v2.ts +0 -73
|
@@ -1,343 +0,0 @@
|
|
|
1
|
-
import { Effect, Schema } from "effect";
|
|
2
|
-
import * as SqlClient from "effect/unstable/sql/SqlClient";
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
CanonicalRecord,
|
|
6
|
-
CanonicalRecordEnvelope,
|
|
7
|
-
CanonicalSequence,
|
|
8
|
-
Digest,
|
|
9
|
-
ProducerEpoch,
|
|
10
|
-
RecordId,
|
|
11
|
-
} from "./Records.ts";
|
|
12
|
-
import { runIdForSubmission, subagentLineageRecordId, workerOriginRecordId } from "./RunJournal.ts";
|
|
13
|
-
import type { ThreadStore } from "./ThreadStore.ts";
|
|
14
|
-
import {
|
|
15
|
-
SelectedThreadRead,
|
|
16
|
-
ThreadPeerCountRequest,
|
|
17
|
-
ThreadIdentity,
|
|
18
|
-
ThreadIdentityRequest,
|
|
19
|
-
ThreadNotMaterialized,
|
|
20
|
-
ThreadStoreError,
|
|
21
|
-
} from "./ThreadStore.ts";
|
|
22
|
-
|
|
23
|
-
const failure = (operation: string, cause?: unknown) =>
|
|
24
|
-
ThreadStoreError.make({
|
|
25
|
-
operation,
|
|
26
|
-
message: "Native canonical read is incomplete or corrupt",
|
|
27
|
-
...(cause === undefined ? {} : { cause }),
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
/** Adapter-owned metadata on canonical rows, never a second copy of execution records. */
|
|
31
|
-
export const createNativeReadIndexes = Effect.gen(function* () {
|
|
32
|
-
const sql = yield* SqlClient.SqlClient;
|
|
33
|
-
|
|
34
|
-
yield* sql`ALTER TABLE effect_agent_canonical_records ADD COLUMN outstanding INTEGER NOT NULL DEFAULT 0`;
|
|
35
|
-
yield* sql`CREATE INDEX effect_agent_records_outstanding ON effect_agent_canonical_records(thread_id, sequence) WHERE outstanding <> 0`;
|
|
36
|
-
yield* sql`CREATE INDEX effect_agent_records_call ON effect_agent_canonical_records(thread_id, json_extract(record_json, '$.payload._tag'), json_extract(record_json, '$.payload.runId'), json_extract(record_json, '$.payload.toolCallId'))`;
|
|
37
|
-
yield* sql`CREATE INDEX effect_agent_records_run_input ON effect_agent_canonical_records(thread_id, json_extract(record_json, '$.payload.runId')) WHERE json_extract(record_json, '$.payload._tag') = 'UserInputRecorded' AND json_extract(record_json, '$.payload.kind') = 'user'`;
|
|
38
|
-
yield* sql`CREATE INDEX effect_agent_records_subtree ON effect_agent_canonical_records(thread_id, json_extract(record_json, '$.payload.sourceSubmissionId'), sequence) WHERE json_extract(record_json, '$.payload._tag') = 'SubtreeBudgetReserved'`;
|
|
39
|
-
yield* sql`CREATE INDEX effect_agent_records_worker_input ON effect_agent_canonical_records(thread_id, json_extract(record_json, '$.payload.admission.messageId')) WHERE json_extract(record_json, '$.payload._tag') = 'WorkerInputRequested'`;
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
/** Must run in the canonical append/upgrade transaction, after inserting this record. */
|
|
43
|
-
export const indexCanonicalRecord = Effect.fnUntraced(function* (
|
|
44
|
-
threadId: string,
|
|
45
|
-
record: CanonicalRecord,
|
|
46
|
-
) {
|
|
47
|
-
const sql = yield* SqlClient.SqlClient;
|
|
48
|
-
const payload = record.payload;
|
|
49
|
-
|
|
50
|
-
switch (payload._tag) {
|
|
51
|
-
case "ToolCallPrepared":
|
|
52
|
-
case "ToolCallUnknown": {
|
|
53
|
-
if (payload._tag === "ToolCallUnknown")
|
|
54
|
-
yield* sql`
|
|
55
|
-
UPDATE effect_agent_canonical_records SET outstanding = 0
|
|
56
|
-
WHERE thread_id = ${threadId} AND json_extract(record_json, '$.payload._tag') = 'ToolCallPrepared'
|
|
57
|
-
AND json_extract(record_json, '$.payload.runId') = ${payload.runId}
|
|
58
|
-
AND json_extract(record_json, '$.payload.toolCallId') = ${payload.toolCallId}`;
|
|
59
|
-
yield* sql`UPDATE effect_agent_canonical_records SET outstanding = ${payload._tag === "ToolCallPrepared" ? 1 : 2}
|
|
60
|
-
WHERE thread_id = ${threadId} AND record_id = ${record.recordId}`;
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
case "ToolCallSettled":
|
|
64
|
-
for (const tag of ["ToolCallPrepared", "ToolCallUnknown"])
|
|
65
|
-
yield* sql`
|
|
66
|
-
UPDATE effect_agent_canonical_records SET outstanding = 0
|
|
67
|
-
WHERE thread_id = ${threadId} AND json_extract(record_json, '$.payload._tag') = ${tag}
|
|
68
|
-
AND json_extract(record_json, '$.payload.runId') = ${payload.runId}
|
|
69
|
-
AND json_extract(record_json, '$.payload.toolCallId') = ${payload.toolCallId}`;
|
|
70
|
-
break;
|
|
71
|
-
case "WorkerInputRequested":
|
|
72
|
-
yield* sql`UPDATE effect_agent_canonical_records SET outstanding = 3 WHERE thread_id = ${threadId} AND record_id = ${record.recordId}`;
|
|
73
|
-
break;
|
|
74
|
-
case "WorkerInputCompleted":
|
|
75
|
-
yield* sql`
|
|
76
|
-
UPDATE effect_agent_canonical_records SET outstanding = ${payload.effectsResolved ? 0 : 4}
|
|
77
|
-
WHERE thread_id = ${threadId} AND json_extract(record_json, '$.payload._tag') = 'WorkerInputRequested'
|
|
78
|
-
AND json_extract(record_json, '$.payload.admission.messageId') = ${payload.messageId}`;
|
|
79
|
-
break;
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
/** One-time native index construction during the atomic supported-format upgrade. */
|
|
84
|
-
export const seedNativeReadIndexes = Effect.gen(function* () {
|
|
85
|
-
const sql = yield* SqlClient.SqlClient;
|
|
86
|
-
|
|
87
|
-
// This is the one supported-format upgrade, in the adapter transaction. Decode in
|
|
88
|
-
// bounded pages; malformed rows or gaps roll back both metadata and version.
|
|
89
|
-
const gaps =
|
|
90
|
-
yield* sql`SELECT t.thread_id FROM effect_agent_threads t LEFT JOIN effect_agent_canonical_records r ON r.thread_id = t.thread_id
|
|
91
|
-
GROUP BY t.thread_id HAVING count(r.sequence) <> t.tail_sequence OR coalesce(max(r.sequence), 0) <> t.tail_sequence
|
|
92
|
-
UNION ALL SELECT r.thread_id FROM effect_agent_canonical_records r LEFT JOIN effect_agent_threads t ON t.thread_id = r.thread_id WHERE t.thread_id IS NULL LIMIT 1`;
|
|
93
|
-
|
|
94
|
-
if (gaps.length > 0) return yield* failure("native index upgrade canonical gap");
|
|
95
|
-
let afterThread = "";
|
|
96
|
-
let afterSequence = 0;
|
|
97
|
-
|
|
98
|
-
while (true) {
|
|
99
|
-
const rows = yield* sql<{
|
|
100
|
-
thread_id: string;
|
|
101
|
-
record_id: string;
|
|
102
|
-
sequence: number;
|
|
103
|
-
record_json: string;
|
|
104
|
-
}>`SELECT thread_id, record_id, sequence, record_json FROM effect_agent_canonical_records
|
|
105
|
-
WHERE (thread_id, sequence) > (${afterThread}, ${afterSequence}) ORDER BY thread_id, sequence LIMIT 100`;
|
|
106
|
-
|
|
107
|
-
if (rows.length === 0) break;
|
|
108
|
-
for (const row of rows) {
|
|
109
|
-
const record = yield* Schema.decodeEffect(Schema.fromJsonString(CanonicalRecord))(
|
|
110
|
-
row.record_json,
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
if (
|
|
114
|
-
record.recordId !== row.record_id ||
|
|
115
|
-
row.sequence !== (row.thread_id === afterThread ? afterSequence : 0) + 1
|
|
116
|
-
)
|
|
117
|
-
return yield* failure("native index upgrade canonical identity");
|
|
118
|
-
yield* indexCanonicalRecord(row.thread_id, record);
|
|
119
|
-
afterThread = row.thread_id;
|
|
120
|
-
afterSequence = row.sequence;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
const Row = Schema.Struct({
|
|
126
|
-
thread_id: SelectedThreadRead.fields.threadId,
|
|
127
|
-
sequence: CanonicalSequence,
|
|
128
|
-
record_id: RecordId,
|
|
129
|
-
batch_id: CanonicalRecordEnvelope.fields.batchId,
|
|
130
|
-
record_json: Schema.String,
|
|
131
|
-
outstanding: Schema.optionalKey(Schema.Int),
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
export const makeSelectedReads = Effect.fnUntraced(function* (
|
|
135
|
-
envelope: (row: typeof Row.Type) => Effect.Effect<CanonicalRecordEnvelope, ThreadStoreError>,
|
|
136
|
-
) {
|
|
137
|
-
const sql = yield* SqlClient.SqlClient;
|
|
138
|
-
|
|
139
|
-
const requireThread = Effect.fnUntraced(function* (threadId: SelectedThreadRead["threadId"]) {
|
|
140
|
-
const rows =
|
|
141
|
-
yield* sql`SELECT tail_sequence, tail_digest FROM effect_agent_threads WHERE thread_id = ${threadId}`;
|
|
142
|
-
|
|
143
|
-
if (rows.length === 0) return yield* ThreadNotMaterialized.make({ threadId });
|
|
144
|
-
|
|
145
|
-
const decoded = yield* Schema.decodeUnknownEffect(
|
|
146
|
-
Schema.Array(Schema.Struct({ tail_sequence: CanonicalSequence, tail_digest: Digest })),
|
|
147
|
-
)(rows);
|
|
148
|
-
|
|
149
|
-
if (decoded.length !== 1 || decoded[0] === undefined)
|
|
150
|
-
return yield* failure("native thread tail");
|
|
151
|
-
|
|
152
|
-
return decoded[0];
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
const read = Effect.fnUntraced(
|
|
156
|
-
function* (request: SelectedThreadRead) {
|
|
157
|
-
return yield* sql.withTransaction(
|
|
158
|
-
Effect.gen(function* () {
|
|
159
|
-
const tail = yield* requireThread(request.threadId);
|
|
160
|
-
const selection = request.selection;
|
|
161
|
-
|
|
162
|
-
if (
|
|
163
|
-
"expectedTailSequence" in selection &&
|
|
164
|
-
(tail.tail_sequence !== selection.expectedTailSequence ||
|
|
165
|
-
tail.tail_digest !== selection.expectedTailDigest)
|
|
166
|
-
)
|
|
167
|
-
return yield* failure("selected read tail changed");
|
|
168
|
-
const after = request.page.afterSequence ?? 0;
|
|
169
|
-
let rows: unknown;
|
|
170
|
-
|
|
171
|
-
switch (selection._tag) {
|
|
172
|
-
case "RecordId":
|
|
173
|
-
rows =
|
|
174
|
-
yield* sql`SELECT thread_id, sequence, record_id, batch_id, record_json FROM effect_agent_canonical_records WHERE thread_id = ${request.threadId} AND record_id = ${selection.recordId} AND sequence > ${after}`;
|
|
175
|
-
break;
|
|
176
|
-
case "RunInput":
|
|
177
|
-
rows =
|
|
178
|
-
yield* sql`SELECT thread_id, sequence, record_id, batch_id, record_json FROM effect_agent_canonical_records WHERE thread_id = ${request.threadId} AND json_extract(record_json, '$.payload._tag') = 'UserInputRecorded' AND json_extract(record_json, '$.payload.kind') = 'user' AND json_extract(record_json, '$.payload.runId') = ${selection.runId} LIMIT 2`;
|
|
179
|
-
break;
|
|
180
|
-
case "Outstanding":
|
|
181
|
-
rows =
|
|
182
|
-
yield* sql`SELECT thread_id, sequence, record_id, batch_id, record_json, outstanding FROM effect_agent_canonical_records WHERE thread_id = ${request.threadId} AND outstanding <> 0 AND sequence > ${after} ORDER BY sequence LIMIT ${request.page.limit}`;
|
|
183
|
-
break;
|
|
184
|
-
case "WorkerExecution":
|
|
185
|
-
rows = (yield* Effect.forEach(
|
|
186
|
-
["UserInputRecorded", "RunStarted"],
|
|
187
|
-
(tag) =>
|
|
188
|
-
sql`SELECT thread_id, sequence, record_id, batch_id, record_json FROM effect_agent_canonical_records
|
|
189
|
-
WHERE thread_id = ${request.threadId} AND json_extract(record_json, '$.payload._tag') = ${tag}
|
|
190
|
-
AND json_extract(record_json, '$.payload.runId') IS NOT NULL
|
|
191
|
-
ORDER BY sequence DESC LIMIT 1`,
|
|
192
|
-
))
|
|
193
|
-
.flat()
|
|
194
|
-
.filter((row) => Number(row.sequence) > after)
|
|
195
|
-
.sort((a, b) => Number(a.sequence) - Number(b.sequence))
|
|
196
|
-
.slice(0, request.page.limit);
|
|
197
|
-
break;
|
|
198
|
-
case "WorkerState": {
|
|
199
|
-
const runId =
|
|
200
|
-
selection.sourceSubmissionId === undefined
|
|
201
|
-
? null
|
|
202
|
-
: runIdForSubmission(selection.sourceSubmissionId);
|
|
203
|
-
|
|
204
|
-
rows = yield* sql`
|
|
205
|
-
SELECT thread_id, sequence, record_id, batch_id, record_json FROM effect_agent_canonical_records
|
|
206
|
-
WHERE thread_id = ${request.threadId} AND sequence > ${after} AND json_extract(record_json, '$.payload._tag') IN ('ThreadCreated', 'WorkerOriginRecorded', 'SubagentLineageRecorded', 'WorkerInputRequested', 'WorkerInputCompleted', 'WorkerStopRequested')
|
|
207
|
-
UNION ALL
|
|
208
|
-
SELECT thread_id, sequence, record_id, batch_id, record_json FROM effect_agent_canonical_records
|
|
209
|
-
WHERE thread_id = ${request.threadId} AND sequence > ${after} AND json_extract(record_json, '$.payload._tag') = 'SubtreeBudgetReserved' AND json_extract(record_json, '$.payload.sourceSubmissionId') IS ${selection.sourceSubmissionId ?? null}
|
|
210
|
-
UNION ALL
|
|
211
|
-
SELECT thread_id, sequence, record_id, batch_id, record_json FROM effect_agent_canonical_records
|
|
212
|
-
WHERE thread_id = ${request.threadId} AND sequence > ${after} AND json_extract(record_json, '$.payload._tag') = 'SubagentJoined' AND json_extract(record_json, '$.payload.runId') = ${runId}
|
|
213
|
-
ORDER BY sequence LIMIT ${request.page.limit}`;
|
|
214
|
-
break;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
const decoded = yield* Schema.decodeUnknownEffect(Schema.Array(Row))(rows);
|
|
218
|
-
|
|
219
|
-
if (selection._tag === "RunInput" && decoded.length > 1)
|
|
220
|
-
return yield* failure("ambiguous original Run input");
|
|
221
|
-
|
|
222
|
-
return yield* Effect.forEach(
|
|
223
|
-
decoded.filter((row) => row.sequence > after),
|
|
224
|
-
(row) =>
|
|
225
|
-
Effect.gen(function* () {
|
|
226
|
-
const value = yield* envelope(row);
|
|
227
|
-
|
|
228
|
-
if (
|
|
229
|
-
value.record.recordId !== row.record_id ||
|
|
230
|
-
row.thread_id !== request.threadId ||
|
|
231
|
-
(selection._tag === "Outstanding" &&
|
|
232
|
-
!(
|
|
233
|
-
(row.outstanding === 1 && value.record.payload._tag === "ToolCallPrepared") ||
|
|
234
|
-
(row.outstanding === 2 && value.record.payload._tag === "ToolCallUnknown") ||
|
|
235
|
-
(row.outstanding === 3 &&
|
|
236
|
-
value.record.payload._tag === "WorkerInputRequested")
|
|
237
|
-
))
|
|
238
|
-
)
|
|
239
|
-
return yield* failure("selected record incomplete or corrupt");
|
|
240
|
-
|
|
241
|
-
return value;
|
|
242
|
-
}),
|
|
243
|
-
);
|
|
244
|
-
}),
|
|
245
|
-
);
|
|
246
|
-
},
|
|
247
|
-
Effect.mapError((cause) =>
|
|
248
|
-
cause._tag === "ThreadNotMaterialized" || cause._tag === "ThreadStoreError"
|
|
249
|
-
? cause
|
|
250
|
-
: failure("selected read", cause),
|
|
251
|
-
),
|
|
252
|
-
);
|
|
253
|
-
|
|
254
|
-
const readIdentity: ThreadStore["Service"]["readIdentity"] = Effect.fnUntraced(
|
|
255
|
-
function* (request) {
|
|
256
|
-
yield* Schema.decodeEffect(Schema.toType(ThreadIdentityRequest))(request);
|
|
257
|
-
|
|
258
|
-
return yield* sql.withTransaction(
|
|
259
|
-
Effect.gen(function* () {
|
|
260
|
-
const tails = yield* sql`SELECT tail_sequence, tail_digest, producer_epoch
|
|
261
|
-
FROM effect_agent_threads WHERE thread_id = ${request.threadId}`;
|
|
262
|
-
|
|
263
|
-
if (tails.length === 0)
|
|
264
|
-
return yield* ThreadNotMaterialized.make({ threadId: request.threadId });
|
|
265
|
-
|
|
266
|
-
const decoded = yield* Schema.decodeUnknownEffect(
|
|
267
|
-
Schema.Array(
|
|
268
|
-
Schema.Struct({
|
|
269
|
-
tail_sequence: CanonicalSequence,
|
|
270
|
-
tail_digest: Digest,
|
|
271
|
-
producer_epoch: ProducerEpoch,
|
|
272
|
-
}),
|
|
273
|
-
),
|
|
274
|
-
)(tails);
|
|
275
|
-
|
|
276
|
-
const tail = decoded[0];
|
|
277
|
-
|
|
278
|
-
if (decoded.length !== 1 || tail === undefined) return yield* failure("identity tail");
|
|
279
|
-
const origin = workerOriginRecordId(request.threadId);
|
|
280
|
-
const lineage = subagentLineageRecordId(request.threadId);
|
|
281
|
-
|
|
282
|
-
const rows =
|
|
283
|
-
yield* sql`SELECT thread_id, sequence, record_id, batch_id, record_json FROM (
|
|
284
|
-
SELECT thread_id, sequence, record_id, batch_id, record_json, 0 AS identity_order
|
|
285
|
-
FROM effect_agent_canonical_records WHERE thread_id = ${request.threadId} AND sequence = 1
|
|
286
|
-
UNION ALL
|
|
287
|
-
SELECT thread_id, sequence, record_id, batch_id, record_json, 1 AS identity_order
|
|
288
|
-
FROM effect_agent_canonical_records WHERE thread_id = ${request.threadId} AND record_id = ${origin} AND sequence <> 1
|
|
289
|
-
UNION ALL
|
|
290
|
-
SELECT thread_id, sequence, record_id, batch_id, record_json, 2 AS identity_order
|
|
291
|
-
FROM effect_agent_canonical_records WHERE thread_id = ${request.threadId} AND record_id = ${lineage} AND sequence <> 1
|
|
292
|
-
) ORDER BY identity_order`;
|
|
293
|
-
|
|
294
|
-
const records = yield* Schema.decodeUnknownEffect(Schema.Array(Row))(rows).pipe(
|
|
295
|
-
Effect.flatMap(
|
|
296
|
-
Effect.forEach((row) =>
|
|
297
|
-
envelope(row).pipe(
|
|
298
|
-
Effect.filterOrFail(
|
|
299
|
-
(value) => value.record.recordId === row.record_id,
|
|
300
|
-
() => failure("identity record locator"),
|
|
301
|
-
),
|
|
302
|
-
),
|
|
303
|
-
),
|
|
304
|
-
),
|
|
305
|
-
);
|
|
306
|
-
|
|
307
|
-
return yield* ThreadIdentity.makeEffect({
|
|
308
|
-
threadId: request.threadId,
|
|
309
|
-
tailSequence: tail.tail_sequence,
|
|
310
|
-
tailDigest: tail.tail_digest,
|
|
311
|
-
producerEpoch: tail.producer_epoch,
|
|
312
|
-
records,
|
|
313
|
-
});
|
|
314
|
-
}),
|
|
315
|
-
);
|
|
316
|
-
},
|
|
317
|
-
Effect.mapError((cause) =>
|
|
318
|
-
cause._tag === "ThreadNotMaterialized" || cause._tag === "ThreadStoreError"
|
|
319
|
-
? cause
|
|
320
|
-
: failure("readIdentity", cause),
|
|
321
|
-
),
|
|
322
|
-
);
|
|
323
|
-
|
|
324
|
-
const countPeerMessages: NonNullable<ThreadStore["Service"]["countPeerMessages"]> =
|
|
325
|
-
Effect.fnUntraced(
|
|
326
|
-
function* (request) {
|
|
327
|
-
yield* Schema.decodeEffect(ThreadPeerCountRequest)(request);
|
|
328
|
-
yield* requireThread(request.threadId);
|
|
329
|
-
|
|
330
|
-
const rows =
|
|
331
|
-
yield* sql`SELECT 1 FROM effect_agent_canonical_records WHERE thread_id = ${request.threadId} AND json_extract(record_json, '$.payload._tag') = 'PeerMessagePrepared' LIMIT ${request.limit}`;
|
|
332
|
-
|
|
333
|
-
return rows.length;
|
|
334
|
-
},
|
|
335
|
-
Effect.mapError((cause) =>
|
|
336
|
-
cause._tag === "ThreadNotMaterialized" || cause._tag === "ThreadStoreError"
|
|
337
|
-
? cause
|
|
338
|
-
: failure("countPeerMessages", cause),
|
|
339
|
-
),
|
|
340
|
-
);
|
|
341
|
-
|
|
342
|
-
return { read, countPeerMessages, readIdentity };
|
|
343
|
-
});
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
// Column inventories from unpatched beta50 internal/migrations.ts.
|
|
2
|
-
export const v2Columns = {
|
|
3
|
-
effect_agent_threads: [
|
|
4
|
-
"thread_id",
|
|
5
|
-
"created_at",
|
|
6
|
-
"tail_sequence",
|
|
7
|
-
"tail_digest",
|
|
8
|
-
"producer_epoch",
|
|
9
|
-
],
|
|
10
|
-
effect_agent_canonical_batches: [
|
|
11
|
-
"thread_id",
|
|
12
|
-
"batch_id",
|
|
13
|
-
"first_sequence",
|
|
14
|
-
"last_sequence",
|
|
15
|
-
"batch_digest",
|
|
16
|
-
"tail_digest",
|
|
17
|
-
"batch_json",
|
|
18
|
-
],
|
|
19
|
-
effect_agent_canonical_records: ["thread_id", "sequence", "record_id", "batch_id", "record_json"],
|
|
20
|
-
effect_agent_checkpoints: ["thread_id", "through_sequence", "tail_digest", "checkpoint_json"],
|
|
21
|
-
effect_agent_submissions: [
|
|
22
|
-
"submission_id",
|
|
23
|
-
"thread_id",
|
|
24
|
-
"queue_sequence",
|
|
25
|
-
"principal",
|
|
26
|
-
"idempotency_key",
|
|
27
|
-
"agent_id",
|
|
28
|
-
"agent_digests_json",
|
|
29
|
-
"deployment_id",
|
|
30
|
-
"input_json",
|
|
31
|
-
"input_digest",
|
|
32
|
-
"receipt_id",
|
|
33
|
-
"state",
|
|
34
|
-
"settled_outcome",
|
|
35
|
-
"created_at",
|
|
36
|
-
"ready_at",
|
|
37
|
-
"input_applied_record_id",
|
|
38
|
-
"input_applied_sequence",
|
|
39
|
-
"joined_host_submission_id",
|
|
40
|
-
"suspended_reason_json",
|
|
41
|
-
"suspended_at",
|
|
42
|
-
"unknown_reason",
|
|
43
|
-
"unknown_tool_call_ids_json",
|
|
44
|
-
"parent_submission_id",
|
|
45
|
-
"parent_tool_call_id",
|
|
46
|
-
],
|
|
47
|
-
effect_agent_submission_ownership: [
|
|
48
|
-
"submission_id",
|
|
49
|
-
"attempt_id",
|
|
50
|
-
"ownership_token",
|
|
51
|
-
"producer_epoch",
|
|
52
|
-
"owner_producer_id",
|
|
53
|
-
"lease_expires_at",
|
|
54
|
-
],
|
|
55
|
-
effect_agent_attempts: [
|
|
56
|
-
"attempt_id",
|
|
57
|
-
"submission_id",
|
|
58
|
-
"thread_id",
|
|
59
|
-
"owner_producer_id",
|
|
60
|
-
"producer_epoch",
|
|
61
|
-
"claimed_at",
|
|
62
|
-
],
|
|
63
|
-
effect_agent_settlement_reservations: [
|
|
64
|
-
"submission_id",
|
|
65
|
-
"settlement_id",
|
|
66
|
-
"outcome",
|
|
67
|
-
"record_id",
|
|
68
|
-
"record_json",
|
|
69
|
-
"record_digest",
|
|
70
|
-
"reserved_at",
|
|
71
|
-
"finalized_at",
|
|
72
|
-
],
|
|
73
|
-
effect_agent_abort_intents: [
|
|
74
|
-
"submission_id",
|
|
75
|
-
"author",
|
|
76
|
-
"reason",
|
|
77
|
-
"requested_at",
|
|
78
|
-
"canonical_record_id",
|
|
79
|
-
],
|
|
80
|
-
effect_agent_approval_decisions: [
|
|
81
|
-
"submission_id",
|
|
82
|
-
"tool_call_id",
|
|
83
|
-
"decision",
|
|
84
|
-
"resolver",
|
|
85
|
-
"reason",
|
|
86
|
-
"decided_at",
|
|
87
|
-
],
|
|
88
|
-
effect_agent_unknown_resolutions: [
|
|
89
|
-
"submission_id",
|
|
90
|
-
"tool_call_id",
|
|
91
|
-
"author",
|
|
92
|
-
"reason",
|
|
93
|
-
"resolution_json",
|
|
94
|
-
"resolved_at",
|
|
95
|
-
],
|
|
96
|
-
effect_agent_child_reservations: [
|
|
97
|
-
"reservation_id",
|
|
98
|
-
"parent_submission_id",
|
|
99
|
-
"parent_tool_call_id",
|
|
100
|
-
"child_submission_id",
|
|
101
|
-
"status",
|
|
102
|
-
"allocation_json",
|
|
103
|
-
"allocation_digest",
|
|
104
|
-
"accounting_json",
|
|
105
|
-
"reserved_at",
|
|
106
|
-
"release_began_at",
|
|
107
|
-
"released_at",
|
|
108
|
-
],
|
|
109
|
-
effect_agent_schedules: [
|
|
110
|
-
"tenant_id",
|
|
111
|
-
"owner_id",
|
|
112
|
-
"schedule_id",
|
|
113
|
-
"deadline_at_millis",
|
|
114
|
-
"record_json",
|
|
115
|
-
],
|
|
116
|
-
effect_agent_subscription_sequences: [
|
|
117
|
-
"tenant_id",
|
|
118
|
-
"source_address",
|
|
119
|
-
"sequence",
|
|
120
|
-
"event_scan_cursor",
|
|
121
|
-
"delivery_scan_cursor",
|
|
122
|
-
"recovery_scan_cursor",
|
|
123
|
-
],
|
|
124
|
-
effect_agent_subscriptions: [
|
|
125
|
-
"tenant_id",
|
|
126
|
-
"source_address",
|
|
127
|
-
"owner_id",
|
|
128
|
-
"subscription_id",
|
|
129
|
-
"ordinal",
|
|
130
|
-
"source_name",
|
|
131
|
-
"source_version",
|
|
132
|
-
"matching_key",
|
|
133
|
-
"state",
|
|
134
|
-
"expires_at_millis",
|
|
135
|
-
"recovery_at_millis",
|
|
136
|
-
"record_json",
|
|
137
|
-
],
|
|
138
|
-
effect_agent_subscription_events: [
|
|
139
|
-
"tenant_id",
|
|
140
|
-
"source_address",
|
|
141
|
-
"event_id",
|
|
142
|
-
"source_name",
|
|
143
|
-
"source_version",
|
|
144
|
-
"matching_key",
|
|
145
|
-
"payload_digest",
|
|
146
|
-
"cutoff",
|
|
147
|
-
"cursor",
|
|
148
|
-
"routing_complete",
|
|
149
|
-
"next_attempt_at_millis",
|
|
150
|
-
"record_json",
|
|
151
|
-
],
|
|
152
|
-
effect_agent_subscription_deliveries: [
|
|
153
|
-
"tenant_id",
|
|
154
|
-
"source_address",
|
|
155
|
-
"owner_id",
|
|
156
|
-
"subscription_id",
|
|
157
|
-
"event_id",
|
|
158
|
-
"delivery_key",
|
|
159
|
-
"state",
|
|
160
|
-
"next_attempt_at_millis",
|
|
161
|
-
"record_json",
|
|
162
|
-
],
|
|
163
|
-
} as const;
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { Schema } from "effect";
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
ScheduleConfiguration,
|
|
5
|
-
ScheduledEnvelope,
|
|
6
|
-
ScheduleRecord,
|
|
7
|
-
ScheduleRetry,
|
|
8
|
-
ScheduleInstant,
|
|
9
|
-
} from "../Schedule.ts";
|
|
10
|
-
import {
|
|
11
|
-
PreparedInput,
|
|
12
|
-
SubscriptionConfiguration,
|
|
13
|
-
SubscriptionDelivery,
|
|
14
|
-
SubscriptionRecord,
|
|
15
|
-
} from "../Subscription.ts";
|
|
16
|
-
|
|
17
|
-
// Frozen beta49/beta50 persisted shapes, before 75898aef (#341). Decode with
|
|
18
|
-
// onExcessProperty:error: a patched or partially upgraded v2 store is not this contract.
|
|
19
|
-
const withoutAdmission = <F extends Schema.Struct.Fields>(fields: F) => {
|
|
20
|
-
const { admissionGroup: _group, admissionFence: _fence, ...rest } = fields;
|
|
21
|
-
|
|
22
|
-
return rest;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const {
|
|
26
|
-
generation: _generation,
|
|
27
|
-
automaticAttempts: _automatic,
|
|
28
|
-
parked: _parked,
|
|
29
|
-
...retry
|
|
30
|
-
} = ScheduleRetry.fields;
|
|
31
|
-
|
|
32
|
-
export const V2Retry = Schema.Struct(retry);
|
|
33
|
-
const V2ScheduleConfiguration = Schema.Struct(withoutAdmission(ScheduleConfiguration.fields));
|
|
34
|
-
const V2Envelope = Schema.Struct(withoutAdmission(ScheduledEnvelope.fields));
|
|
35
|
-
|
|
36
|
-
export const V2Schedule = Schema.Struct({
|
|
37
|
-
...ScheduleRecord.fields,
|
|
38
|
-
configuration: V2ScheduleConfiguration,
|
|
39
|
-
pending: Schema.NullOr(Schema.Struct({ envelope: V2Envelope, retry: V2Retry })),
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
const V2Configuration = Schema.Struct({
|
|
43
|
-
...withoutAdmission(SubscriptionConfiguration.fields),
|
|
44
|
-
expiresAtMillis: ScheduleInstant,
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
const {
|
|
48
|
-
configurationRevision: _revision,
|
|
49
|
-
configurationFingerprint: _fingerprint,
|
|
50
|
-
creationConfiguration: _creation,
|
|
51
|
-
...registration
|
|
52
|
-
} = SubscriptionRecord.fields;
|
|
53
|
-
|
|
54
|
-
export const V2Subscription = Schema.Struct({
|
|
55
|
-
...registration,
|
|
56
|
-
configuration: V2Configuration,
|
|
57
|
-
state: Schema.Literals(["active", "consumed", "cancelled"]),
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
const {
|
|
61
|
-
configurationRevision: _deliveryRevision,
|
|
62
|
-
configuration: _configuration,
|
|
63
|
-
observeSettlement: _observe,
|
|
64
|
-
settledAtMillis: _settled,
|
|
65
|
-
completedAtMillis: _completed,
|
|
66
|
-
...delivery
|
|
67
|
-
} = SubscriptionDelivery.fields;
|
|
68
|
-
|
|
69
|
-
export const V2Delivery = Schema.Struct({
|
|
70
|
-
...delivery,
|
|
71
|
-
envelope: Schema.NullOr(Schema.Struct(withoutAdmission(PreparedInput.fields))),
|
|
72
|
-
retry: V2Retry,
|
|
73
|
-
});
|