@claudexor/daemon 4.6.2 → 4.8.1
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/client.d.ts +203 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +14 -0
- package/dist/client.js.map +1 -1
- package/dist/command-authority.d.ts +2 -0
- package/dist/command-authority.d.ts.map +1 -1
- package/dist/command-authority.js.map +1 -1
- package/dist/command-rpc.d.ts +1 -1
- package/dist/command-rpc.d.ts.map +1 -1
- package/dist/command-rpc.js +5 -2
- package/dist/command-rpc.js.map +1 -1
- package/dist/deferred-message-owner.d.ts +24 -0
- package/dist/deferred-message-owner.d.ts.map +1 -0
- package/dist/deferred-message-owner.js +12 -0
- package/dist/deferred-message-owner.js.map +1 -0
- package/dist/deferred-messages.d.ts +182 -0
- package/dist/deferred-messages.d.ts.map +1 -0
- package/dist/deferred-messages.js +285 -0
- package/dist/deferred-messages.js.map +1 -0
- package/dist/enqueue-command.d.ts +19 -0
- package/dist/enqueue-command.d.ts.map +1 -0
- package/dist/enqueue-command.js +37 -0
- package/dist/enqueue-command.js.map +1 -0
- package/dist/exact-retry-defaults.d.ts +7 -0
- package/dist/exact-retry-defaults.d.ts.map +1 -0
- package/dist/exact-retry-defaults.js +32 -0
- package/dist/exact-retry-defaults.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/interactions.d.ts +7 -1
- package/dist/interactions.d.ts.map +1 -1
- package/dist/interactions.js +40 -0
- package/dist/interactions.js.map +1 -1
- package/dist/quota-registry-support.d.ts +2 -2
- package/dist/quota-registry.d.ts +5 -5
- package/dist/run-observation.d.ts +7 -0
- package/dist/run-observation.d.ts.map +1 -0
- package/dist/run-observation.js +100 -0
- package/dist/run-observation.js.map +1 -0
- package/dist/server.d.ts +6 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +56 -41
- package/dist/server.js.map +1 -1
- package/dist/store/blob-files.d.ts +2 -2
- package/dist/store/blob-files.d.ts.map +1 -1
- package/dist/store/blob-files.js +1 -0
- package/dist/store/blob-files.js.map +1 -1
- package/dist/store/command-prune.d.ts.map +1 -1
- package/dist/store/command-prune.js +22 -4
- package/dist/store/command-prune.js.map +1 -1
- package/dist/store/command-queries.d.ts +6 -2
- package/dist/store/command-queries.d.ts.map +1 -1
- package/dist/store/command-queries.js +66 -1
- package/dist/store/command-queries.js.map +1 -1
- package/dist/store/commands.d.ts +22 -0
- package/dist/store/commands.d.ts.map +1 -1
- package/dist/store/commands.js +26 -13
- package/dist/store/commands.js.map +1 -1
- package/dist/store/deferred-message-rows.d.ts +23 -0
- package/dist/store/deferred-message-rows.d.ts.map +1 -0
- package/dist/store/deferred-message-rows.js +59 -0
- package/dist/store/deferred-message-rows.js.map +1 -0
- package/dist/store/deferred-messages.d.ts +58 -0
- package/dist/store/deferred-messages.d.ts.map +1 -0
- package/dist/store/deferred-messages.js +439 -0
- package/dist/store/deferred-messages.js.map +1 -0
- package/dist/store/deferred-retention.d.ts +6 -0
- package/dist/store/deferred-retention.d.ts.map +1 -0
- package/dist/store/deferred-retention.js +30 -0
- package/dist/store/deferred-retention.js.map +1 -0
- package/dist/store/generations.d.ts.map +1 -1
- package/dist/store/generations.js +7 -0
- package/dist/store/generations.js.map +1 -1
- package/dist/store/idempotency.d.ts +2 -2
- package/dist/store/idempotency.d.ts.map +1 -1
- package/dist/store/idempotency.js +4 -2
- package/dist/store/idempotency.js.map +1 -1
- package/dist/store/importer.js +3 -1
- package/dist/store/importer.js.map +1 -1
- package/dist/store/interactions.d.ts +2 -1
- package/dist/store/interactions.d.ts.map +1 -1
- package/dist/store/interactions.js +11 -1
- package/dist/store/interactions.js.map +1 -1
- package/dist/store/publish-blob.d.ts +4 -0
- package/dist/store/publish-blob.d.ts.map +1 -1
- package/dist/store/publish-blob.js +33 -10
- package/dist/store/publish-blob.js.map +1 -1
- package/dist/store/resource-rows.d.ts +6 -0
- package/dist/store/resource-rows.d.ts.map +1 -1
- package/dist/store/resource-rows.js.map +1 -1
- package/dist/store/resources.d.ts +22 -0
- package/dist/store/resources.d.ts.map +1 -1
- package/dist/store/resources.js +6 -0
- package/dist/store/resources.js.map +1 -1
- package/dist/store/retention-changes.d.ts +1 -0
- package/dist/store/retention-changes.d.ts.map +1 -1
- package/dist/store/retention-changes.js +1 -0
- package/dist/store/retention-changes.js.map +1 -1
- package/dist/store/retention-pages.d.ts +1 -1
- package/dist/store/retention-pages.d.ts.map +1 -1
- package/dist/store/retention-pages.js.map +1 -1
- package/dist/store/retention-references.d.ts.map +1 -1
- package/dist/store/retention-references.js +4 -0
- package/dist/store/retention-references.js.map +1 -1
- package/dist/store/retention.d.ts.map +1 -1
- package/dist/store/retention.js +5 -0
- package/dist/store/retention.js.map +1 -1
- package/dist/store/schema.d.ts +9 -2
- package/dist/store/schema.d.ts.map +1 -1
- package/dist/store/schema.js +35 -2
- package/dist/store/schema.js.map +1 -1
- package/dist/store/sql-command-router.d.ts +4 -0
- package/dist/store/sql-command-router.d.ts.map +1 -1
- package/dist/store/sql-command-router.js +18 -0
- package/dist/store/sql-command-router.js.map +1 -1
- package/dist/store/sql-daemon-services.d.ts.map +1 -1
- package/dist/store/sql-daemon-services.js +14 -1
- package/dist/store/sql-daemon-services.js.map +1 -1
- package/dist/store/sql-validation.d.ts.map +1 -1
- package/dist/store/sql-validation.js +8 -0
- package/dist/store/sql-validation.js.map +1 -1
- package/dist/store/store.d.ts +1 -1
- package/dist/store/store.d.ts.map +1 -1
- package/dist/store/thread-history-read.d.ts +81 -0
- package/dist/store/thread-history-read.d.ts.map +1 -0
- package/dist/store/thread-history-read.js +215 -0
- package/dist/store/thread-history-read.js.map +1 -0
- package/dist/store/thread-prompt-read.d.ts +7 -0
- package/dist/store/thread-prompt-read.d.ts.map +1 -0
- package/dist/store/thread-prompt-read.js +62 -0
- package/dist/store/thread-prompt-read.js.map +1 -0
- package/dist/store/upload-binding-retention.d.ts +3 -3
- package/dist/store/upload-binding-retention.d.ts.map +1 -1
- package/dist/store/upload-binding-retention.js +2 -1
- package/dist/store/upload-binding-retention.js.map +1 -1
- package/dist/store/upload-imports.d.ts +21 -0
- package/dist/store/upload-imports.d.ts.map +1 -0
- package/dist/store/upload-imports.js +96 -0
- package/dist/store/upload-imports.js.map +1 -0
- package/dist/store/uploads.d.ts +7 -2
- package/dist/store/uploads.d.ts.map +1 -1
- package/dist/store/uploads.js +44 -10
- package/dist/store/uploads.js.map +1 -1
- package/dist/store-contracts.d.ts +14 -1
- package/dist/store-contracts.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { THREAD_HISTORY_HEADER_BYTES, THREAD_HISTORY_METADATA_BYTES, THREAD_HISTORY_PROMPT_BYTES, THREAD_HISTORY_SESSION_LIMIT, threadHistoryProblem, } from "@claudexor/schema";
|
|
2
|
+
import { isServedPid } from "./generations.js";
|
|
3
|
+
import { readThreadPromptPart } from "./thread-prompt-read.js";
|
|
4
|
+
import { PLAN_ANSWER_PRESENT_SQL, PLAN_ANSWER_RUN_SQL } from "./schema.js";
|
|
5
|
+
const rawThreadFields = [
|
|
6
|
+
"id",
|
|
7
|
+
"title",
|
|
8
|
+
"folder",
|
|
9
|
+
"repo",
|
|
10
|
+
"mode",
|
|
11
|
+
"workspace",
|
|
12
|
+
"auth_preference",
|
|
13
|
+
"primary_harness",
|
|
14
|
+
"eligible_harnesses",
|
|
15
|
+
"credential_profile_id",
|
|
16
|
+
"access",
|
|
17
|
+
"state",
|
|
18
|
+
"trashed_at",
|
|
19
|
+
"purge_after",
|
|
20
|
+
"head_run_id",
|
|
21
|
+
"created_at",
|
|
22
|
+
"updated_at",
|
|
23
|
+
];
|
|
24
|
+
/** Address first, project second. No full thread/turn array or command bodies. */
|
|
25
|
+
export class SqlThreadHistoryRead {
|
|
26
|
+
store;
|
|
27
|
+
blobs;
|
|
28
|
+
probe;
|
|
29
|
+
constructor(store, blobs, probe) {
|
|
30
|
+
this.store = store;
|
|
31
|
+
this.blobs = blobs;
|
|
32
|
+
this.probe = probe;
|
|
33
|
+
}
|
|
34
|
+
identity(id) {
|
|
35
|
+
const row = this.store
|
|
36
|
+
.prepare(`SELECT t.pid,t.state,p.epoch FROM thread t
|
|
37
|
+
JOIN partition p ON p.id=t.pid WHERE t.id=?`)
|
|
38
|
+
.get(id);
|
|
39
|
+
if (!row)
|
|
40
|
+
throw threadHistoryProblem("thread_not_found", 404, "no such thread");
|
|
41
|
+
if (!isServedPid(this.store, row.pid))
|
|
42
|
+
throw threadHistoryProblem("thread_history_unavailable", 503, "thread partition is not served");
|
|
43
|
+
if (row.state === "purged")
|
|
44
|
+
throw threadHistoryProblem("thread_purged", 410, "thread was purged");
|
|
45
|
+
return row;
|
|
46
|
+
}
|
|
47
|
+
header(id) {
|
|
48
|
+
// SQLite extracts only header fields; the growing run_ids array never crosses
|
|
49
|
+
// the SQL boundary or reaches the JavaScript decoder.
|
|
50
|
+
const expression = `json_object(${rawThreadFields.map((k) => `'${k}',json_extract(CAST(body AS TEXT),'$.${k}')`).join(",")})`;
|
|
51
|
+
const row = this.store
|
|
52
|
+
.prepare(`SELECT CASE WHEN length(CAST(${expression} AS BLOB))<=?
|
|
53
|
+
THEN ${expression} END AS header FROM thread WHERE id=?`)
|
|
54
|
+
.get(THREAD_HISTORY_HEADER_BYTES, id);
|
|
55
|
+
if (row.header === null)
|
|
56
|
+
throw threadHistoryProblem("thread_history_header_too_large", 503, "thread header exceeds its byte bound");
|
|
57
|
+
const latest = this.store
|
|
58
|
+
.prepare(`SELECT id,ordinal,run_id AS runId,
|
|
59
|
+
CASE WHEN length(body)<=? THEN json_extract(CAST(body AS TEXT),'$.enqueue_error') END AS refusal,
|
|
60
|
+
length(body)>? AS oversized FROM turn INDEXED BY turn_thread WHERE thread_id=? ORDER BY ordinal DESC LIMIT 1`)
|
|
61
|
+
.get(THREAD_HISTORY_METADATA_BYTES, THREAD_HISTORY_METADATA_BYTES, id);
|
|
62
|
+
if (latest?.oversized)
|
|
63
|
+
throw threadHistoryProblem("thread_history_metadata_too_large", 503, "latest admission exceeds its byte bound");
|
|
64
|
+
const admission = latest
|
|
65
|
+
? this.store
|
|
66
|
+
.prepare(`SELECT id AS jobId,state FROM command INDEXED BY command_turn WHERE turn_id=? AND live=1 ORDER BY created_at DESC LIMIT 1`)
|
|
67
|
+
.get(latest.id)
|
|
68
|
+
: undefined;
|
|
69
|
+
const sessions = this.store
|
|
70
|
+
.prepare(`SELECT CASE WHEN length(body)<=? THEN body END AS body
|
|
71
|
+
FROM session INDEXED BY session_order WHERE thread_id=? ORDER BY insertion_ordinal DESC LIMIT ?`)
|
|
72
|
+
.all(THREAD_HISTORY_METADATA_BYTES, id, THREAD_HISTORY_SESSION_LIMIT + 1);
|
|
73
|
+
return {
|
|
74
|
+
thread: Object.fromEntries(Object.entries(JSON.parse(row.header)).filter(([, value]) => value !== null)),
|
|
75
|
+
latest: latest
|
|
76
|
+
? { ...latest, jobId: admission?.jobId ?? null, state: admission?.state ?? null }
|
|
77
|
+
: undefined,
|
|
78
|
+
sessions: sessions.slice(0, THREAD_HISTORY_SESSION_LIMIT).map((s) => {
|
|
79
|
+
if (s.body === null)
|
|
80
|
+
throw threadHistoryProblem("thread_history_metadata_too_large", 503, "session metadata exceeds its byte bound");
|
|
81
|
+
return JSON.parse(Buffer.from(s.body).toString("utf8"));
|
|
82
|
+
}),
|
|
83
|
+
sessionsComplete: sessions.length <= THREAD_HISTORY_SESSION_LIMIT,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
edge(threadId, turnId) {
|
|
87
|
+
const key = this.store
|
|
88
|
+
.prepare("SELECT id,ordinal,run_id AS runId FROM turn WHERE id=? AND thread_id=?")
|
|
89
|
+
.get(turnId, threadId);
|
|
90
|
+
if (!key)
|
|
91
|
+
throw threadHistoryProblem("thread_turn_not_found", 404, "turn does not belong to this thread");
|
|
92
|
+
return key;
|
|
93
|
+
}
|
|
94
|
+
select(input, cursor) {
|
|
95
|
+
let direction = cursor?.direction === "newer" ? "newer" : "older";
|
|
96
|
+
let where = "";
|
|
97
|
+
let edge = null;
|
|
98
|
+
const args = [input.threadId];
|
|
99
|
+
const ceiling = cursor?.ceiling ??
|
|
100
|
+
this.store
|
|
101
|
+
.prepare("SELECT ordinal FROM turn INDEXED BY turn_thread WHERE thread_id=? ORDER BY ordinal DESC LIMIT 1")
|
|
102
|
+
.get(input.threadId)?.ordinal ??
|
|
103
|
+
0;
|
|
104
|
+
if (cursor?.direction === "replay") {
|
|
105
|
+
where = " AND ordinal BETWEEN ? AND ?";
|
|
106
|
+
args.push(cursor.after === undefined ? cursor.low : cursor.after + 1, cursor.high);
|
|
107
|
+
direction = "newer";
|
|
108
|
+
}
|
|
109
|
+
else if (cursor) {
|
|
110
|
+
edge = direction === "older" ? cursor.low : cursor.high;
|
|
111
|
+
where = ` AND ordinal${direction === "older" ? "<" : ">"}${cursor.inclusive ? "=" : ""}?`;
|
|
112
|
+
args.push(edge);
|
|
113
|
+
}
|
|
114
|
+
else if (input.beforeTurnId || input.afterTurnId) {
|
|
115
|
+
direction = input.afterTurnId ? "newer" : "older";
|
|
116
|
+
where = direction === "older" ? " AND ordinal<?" : " AND ordinal>?";
|
|
117
|
+
edge = this.edge(input.threadId, (input.afterTurnId ?? input.beforeTurnId)).ordinal;
|
|
118
|
+
args.push(edge);
|
|
119
|
+
}
|
|
120
|
+
else if (input.aroundTurnId) {
|
|
121
|
+
// Anchor-first traversal guarantees a byte-limited around read includes it.
|
|
122
|
+
// Adjacent earlier rows follow; clients may then request the newer edge.
|
|
123
|
+
where = " AND ordinal<=?";
|
|
124
|
+
args.push(this.edge(input.threadId, input.aroundTurnId).ordinal);
|
|
125
|
+
}
|
|
126
|
+
where += " AND ordinal<=?";
|
|
127
|
+
args.push(ceiling);
|
|
128
|
+
const keys = this.store
|
|
129
|
+
.prepare(`SELECT id,ordinal,run_id AS runId FROM turn INDEXED BY turn_thread
|
|
130
|
+
WHERE thread_id=?${where} ORDER BY ordinal ${direction === "older" ? "DESC" : "ASC"} LIMIT ?`)
|
|
131
|
+
.all(...args, input.limit + 1);
|
|
132
|
+
if (this.probe)
|
|
133
|
+
this.probe.keys += keys.length;
|
|
134
|
+
return {
|
|
135
|
+
keys: keys.slice(0, input.limit),
|
|
136
|
+
probedMore: keys.length > input.limit,
|
|
137
|
+
direction,
|
|
138
|
+
ceiling,
|
|
139
|
+
edge,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
turn(threadId, key) {
|
|
143
|
+
const row = this.store
|
|
144
|
+
.prepare("SELECT CASE WHEN length(body)<=? THEN body END AS body FROM turn WHERE id=? AND thread_id=?")
|
|
145
|
+
.get(THREAD_HISTORY_METADATA_BYTES, key.id, threadId);
|
|
146
|
+
if (!row?.body)
|
|
147
|
+
throw threadHistoryProblem("thread_history_metadata_too_large", 503, "turn metadata is missing or exceeds its byte bound");
|
|
148
|
+
const prompt = readThreadPromptPart(this.store, this.blobs, {
|
|
149
|
+
threadId,
|
|
150
|
+
turnId: key.id,
|
|
151
|
+
offset: 0,
|
|
152
|
+
maxBytes: THREAD_HISTORY_PROMPT_BYTES,
|
|
153
|
+
});
|
|
154
|
+
if (this.probe) {
|
|
155
|
+
this.probe.bodies++;
|
|
156
|
+
this.probe.promptBytes += prompt.nextOffset;
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
raw: {
|
|
160
|
+
...JSON.parse(Buffer.from(row.body).toString("utf8")),
|
|
161
|
+
prompt: prompt.text,
|
|
162
|
+
},
|
|
163
|
+
promptInfo: {
|
|
164
|
+
textBytes: prompt.nextOffset,
|
|
165
|
+
totalTextBytes: prompt.totalBytes,
|
|
166
|
+
truncated: prompt.nextOffset < prompt.totalBytes,
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
/** First accepted relation, even beyond this page's frozen tail. Matches
|
|
171
|
+
* assertPlanAnswerSubmission / PlanAnswerSubmission.acceptedTurn: bound,
|
|
172
|
+
* unrefused queued, or retryable refusal; only a runless false refusal loses.
|
|
173
|
+
* No whole turn body is decoded, and only the selected prompt is read. */
|
|
174
|
+
planAnswer(threadId, planRunId) {
|
|
175
|
+
const row = this.store
|
|
176
|
+
.prepare(`SELECT id,length(body) AS metadataBytes FROM turn INDEXED BY turn_plan_answer
|
|
177
|
+
WHERE thread_id=? AND ${PLAN_ANSWER_PRESENT_SQL} AND ${PLAN_ANSWER_RUN_SQL}=?
|
|
178
|
+
AND CASE WHEN length(body)>? THEN 1 WHEN run_id IS NOT NULL THEN 1
|
|
179
|
+
ELSE json_type(CAST(body AS TEXT),'$.enqueue_error.retryable') IS NOT 'false' END
|
|
180
|
+
ORDER BY ordinal LIMIT 1`)
|
|
181
|
+
.get(threadId, planRunId, THREAD_HISTORY_METADATA_BYTES);
|
|
182
|
+
if (row && row.metadataBytes > THREAD_HISTORY_METADATA_BYTES)
|
|
183
|
+
throw threadHistoryProblem("thread_history_metadata_too_large", 503, "plan answer metadata exceeds its byte bound");
|
|
184
|
+
const prompt = row
|
|
185
|
+
? readThreadPromptPart(this.store, this.blobs, {
|
|
186
|
+
threadId,
|
|
187
|
+
turnId: row.id,
|
|
188
|
+
offset: 0,
|
|
189
|
+
maxBytes: THREAD_HISTORY_PROMPT_BYTES,
|
|
190
|
+
})
|
|
191
|
+
: null;
|
|
192
|
+
return {
|
|
193
|
+
answeredByTurnId: row?.id ?? null,
|
|
194
|
+
answeredByPrompt: row && prompt
|
|
195
|
+
? {
|
|
196
|
+
id: row.id,
|
|
197
|
+
prompt: prompt.text,
|
|
198
|
+
promptInfo: {
|
|
199
|
+
textBytes: prompt.nextOffset,
|
|
200
|
+
totalTextBytes: prompt.totalBytes,
|
|
201
|
+
truncated: prompt.nextOffset < prompt.totalBytes,
|
|
202
|
+
},
|
|
203
|
+
}
|
|
204
|
+
: null,
|
|
205
|
+
planAnswerComplete: true,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
coverage(threadId, low, high, ceiling) {
|
|
209
|
+
const probe = (op, value) => Boolean(this.store
|
|
210
|
+
.prepare(`SELECT 1 FROM turn INDEXED BY turn_thread WHERE thread_id=? AND ordinal${op}? AND ordinal<=? LIMIT 1`)
|
|
211
|
+
.get(threadId, value, ceiling));
|
|
212
|
+
return { hasOlder: probe("<", low), hasNewer: probe(">", high) };
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=thread-history-read.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread-history-read.js","sourceRoot":"","sources":["../../src/store/thread-history-read.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ThreadPromptPartInput, type ThreadPromptPart } from "@claudexor/schema";
|
|
2
|
+
import type { BlobFiles } from "./blob-files.js";
|
|
3
|
+
import type { EngineStore } from "./store.js";
|
|
4
|
+
/** Prompt blobs are immutable, already redacted by the turn owner before hashing.
|
|
5
|
+
* SQL substr bounds inline allocation; file reads allocate only maxBytes+1. */
|
|
6
|
+
export declare function readThreadPromptPart(store: EngineStore, blobs: BlobFiles, raw: ThreadPromptPartInput): ThreadPromptPart;
|
|
7
|
+
//# sourceMappingURL=thread-prompt-read.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread-prompt-read.d.ts","sourceRoot":"","sources":["../../src/store/thread-prompt-read.ts"],"names":[],"mappings":"AACA,OAAO,EACL,qBAAqB,EAErB,KAAK,gBAAgB,EACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;+EAC+E;AAC/E,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,SAAS,EAChB,GAAG,EAAE,qBAAqB,GACzB,gBAAgB,CAgElB"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { closeSync, constants, fstatSync, openSync, readSync } from "node:fs";
|
|
2
|
+
import { ThreadPromptPartInput, threadHistoryProblem, } from "@claudexor/schema";
|
|
3
|
+
/** Prompt blobs are immutable, already redacted by the turn owner before hashing.
|
|
4
|
+
* SQL substr bounds inline allocation; file reads allocate only maxBytes+1. */
|
|
5
|
+
export function readThreadPromptPart(store, blobs, raw) {
|
|
6
|
+
const input = ThreadPromptPartInput.parse(raw);
|
|
7
|
+
const row = store
|
|
8
|
+
.prepare(`SELECT t.prompt_sha AS sha256,b.size AS totalBytes,
|
|
9
|
+
substr(b.inline,?,?) AS bytes,b.inline IS NOT NULL AS isInline
|
|
10
|
+
FROM turn t LEFT JOIN blob b ON b.sha256=t.prompt_sha WHERE t.id=? AND t.thread_id=?`)
|
|
11
|
+
.get(input.offset + 1, input.maxBytes + 1, input.turnId, input.threadId);
|
|
12
|
+
if (!row)
|
|
13
|
+
throw threadHistoryProblem("thread_turn_not_found", 404, "no such thread turn prompt");
|
|
14
|
+
if (row.totalBytes === null)
|
|
15
|
+
throw threadHistoryProblem("thread_history_unavailable", 503, "stored prompt blob is unavailable");
|
|
16
|
+
if (input.offset > row.totalBytes)
|
|
17
|
+
throw threadHistoryProblem("invalid_prompt_offset", 400, "prompt offset is past the end");
|
|
18
|
+
let bytes;
|
|
19
|
+
if (row.isInline)
|
|
20
|
+
bytes = Buffer.from(row.bytes);
|
|
21
|
+
else {
|
|
22
|
+
let fd;
|
|
23
|
+
try {
|
|
24
|
+
fd = openSync(blobs.filePath(row.sha256), constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
|
|
25
|
+
const stat = fstatSync(fd);
|
|
26
|
+
if (!stat.isFile() || stat.size !== row.totalBytes)
|
|
27
|
+
throw new Error("prompt size changed");
|
|
28
|
+
bytes = Buffer.alloc(Math.min(input.maxBytes + 1, row.totalBytes - input.offset));
|
|
29
|
+
if (readSync(fd, bytes, 0, bytes.length, input.offset) !== bytes.length)
|
|
30
|
+
throw new Error("short prompt read");
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
throw threadHistoryProblem("thread_history_unavailable", 503, "stored prompt bytes are unavailable");
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
if (fd !== undefined)
|
|
37
|
+
closeSync(fd);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (bytes.length && (bytes[0] & 0xc0) === 0x80)
|
|
41
|
+
throw threadHistoryProblem("invalid_prompt_offset", 400, "offset must be a UTF-8 boundary");
|
|
42
|
+
let end = Math.min(input.maxBytes, bytes.length);
|
|
43
|
+
while (end > 0 && end < bytes.length && (bytes[end] & 0xc0) === 0x80)
|
|
44
|
+
end--;
|
|
45
|
+
let text;
|
|
46
|
+
try {
|
|
47
|
+
text = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes.subarray(0, end));
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
throw threadHistoryProblem("thread_history_unavailable", 503, "stored prompt is not UTF-8");
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
threadId: input.threadId,
|
|
54
|
+
turnId: input.turnId,
|
|
55
|
+
sha256: row.sha256,
|
|
56
|
+
totalBytes: row.totalBytes,
|
|
57
|
+
offset: input.offset,
|
|
58
|
+
nextOffset: input.offset + end,
|
|
59
|
+
text,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=thread-prompt-read.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread-prompt-read.js","sourceRoot":"","sources":["../../src/store/thread-prompt-read.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,16 +3,16 @@ import { type IdempotencyBinding } from "./idempotency.js";
|
|
|
3
3
|
import type { EngineStore } from "./store.js";
|
|
4
4
|
/** The accepted upload-binding lifetime starts at release/expiry, never at upload creation. */
|
|
5
5
|
export declare const UPLOAD_BINDING_RETENTION_MS: number;
|
|
6
|
-
export type UploadOperation = "create" | "finalize";
|
|
6
|
+
export type UploadOperation = "create" | "finalize" | "import";
|
|
7
7
|
export interface LegacyUploadBinding {
|
|
8
|
-
operation: UploadOperation
|
|
8
|
+
operation: Exclude<UploadOperation, "import">;
|
|
9
9
|
key: string;
|
|
10
10
|
requestDigest: string;
|
|
11
11
|
result: ControlUploadStatus | ControlResource;
|
|
12
12
|
}
|
|
13
13
|
export declare function uploadKeyDigest(operation: UploadOperation, key: string): string;
|
|
14
14
|
/** Pure parser for the importer; serving lookup refuses a present invalid record. */
|
|
15
|
-
export declare function parseLegacyUploadBinding(raw: unknown, operation:
|
|
15
|
+
export declare function parseLegacyUploadBinding(raw: unknown, operation: LegacyUploadBinding["operation"], key: string): LegacyUploadBinding | undefined;
|
|
16
16
|
/** SQL is authoritative once adopted. Historical files are point-read only on an enabled miss. */
|
|
17
17
|
export declare class UploadBindings {
|
|
18
18
|
private readonly store;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload-binding-retention.d.ts","sourceRoot":"","sources":["../../src/store/upload-binding-retention.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAEzE,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,kBAAkB,CAAC;AAQ1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,+FAA+F;AAC/F,eAAO,MAAM,2BAA2B,QAA4B,CAAC;AACrE,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"upload-binding-retention.d.ts","sourceRoot":"","sources":["../../src/store/upload-binding-retention.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAEzE,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,kBAAkB,CAAC;AAQ1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,+FAA+F;AAC/F,eAAO,MAAM,2BAA2B,QAA4B,CAAC;AACrE,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;AAC/D,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,OAAO,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;IAC9C,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,mBAAmB,GAAG,eAAe,CAAC;CAC/C;AACD,wBAAgB,eAAe,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/E;AAED,qFAAqF;AACrF,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,OAAO,EACZ,SAAS,EAAE,mBAAmB,CAAC,WAAW,CAAC,EAC3C,GAAG,EAAE,MAAM,GACV,mBAAmB,GAAG,SAAS,CAWjC;AAgDD,kGAAkG;AAClG,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,KAAK;IAAlC,YAA6B,KAAK,EAAE,WAAW,EAAI;IAEnD,MAAM,CACJ,SAAS,EAAE,eAAe,EAC1B,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,MAAM,EACrB,QAAQ,CAAC,EAAE,MAAM,GAChB,kBAAkB,GAAG,SAAS,CA0EhC;IAED,qFAAqF;IACrF,KAAK,IAAI,MAAM,CAiBd;IAED,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,UAAU;CAwBnB"}
|
|
@@ -75,7 +75,8 @@ export class UploadBindings {
|
|
|
75
75
|
runMutation(this.store, (tx) => deleteTargetIdempotencyInTx(tx, "upload", 0, target.target_id));
|
|
76
76
|
}
|
|
77
77
|
const saved = lookupIdempotency(this.store, address, requestDigest);
|
|
78
|
-
|
|
78
|
+
// Keyed imports postdate the legacy file store; SQL is their only authority.
|
|
79
|
+
if (saved || operation === "import")
|
|
79
80
|
return saved;
|
|
80
81
|
const enabled = this.store
|
|
81
82
|
.prepare("SELECT value FROM meta WHERE key='legacy_idempotency_dir'")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload-binding-retention.js","sourceRoot":"","sources":["../../src/store/upload-binding-retention.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,mBAAmB,EACnB,2BAA2B,EAC3B,iBAAiB,GAElB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EACL,aAAa,EACb,eAAe,EACf,aAAa,GAEd,MAAM,oBAAoB,CAAC;AAG5B,+FAA+F;AAC/F,MAAM,CAAC,MAAM,2BAA2B,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;AAQrE,MAAM,UAAU,eAAe,CAAC,SAA0B,EAAE,GAAW;IACrE,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,SAAS,KAAK,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC3E,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,wBAAwB,CACtC,GAAY,EACZ,
|
|
1
|
+
{"version":3,"file":"upload-binding-retention.js","sourceRoot":"","sources":["../../src/store/upload-binding-retention.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ControlUploadImport } from "@claudexor/schema";
|
|
2
|
+
import type { PublishBlob } from "./publish-blob.js";
|
|
3
|
+
import type { EngineStore } from "./store.js";
|
|
4
|
+
import type { SqlUploads } from "./uploads.js";
|
|
5
|
+
/**
|
|
6
|
+
* Keyed import over the existing upload owner. The key binds the semantic request,
|
|
7
|
+
* its first declaration binds the content, and every replay is answered from the
|
|
8
|
+
* store before a client needs its source again.
|
|
9
|
+
*/
|
|
10
|
+
export declare class SqlUploadImports {
|
|
11
|
+
private readonly store;
|
|
12
|
+
private readonly uploads;
|
|
13
|
+
private readonly publisher;
|
|
14
|
+
constructor(store: EngineStore, uploads: SqlUploads, publisher: PublishBlob);
|
|
15
|
+
import(raw: unknown, key: string): ControlUploadImport;
|
|
16
|
+
/** Publish verified bytes now, so a replay needs neither the source nor a client digest. */
|
|
17
|
+
private complete;
|
|
18
|
+
private project;
|
|
19
|
+
private row;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=upload-imports.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-imports.d.ts","sourceRoot":"","sources":["../../src/store/upload-imports.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EAGpB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAQrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAK/C;;;;GAIG;AACH,qBAAa,gBAAgB;IAEzB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAH5B,YACmB,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,UAAU,EACnB,SAAS,EAAE,WAAW,EACrC;IAEJ,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,mBAAmB,CA+CrD;IAED,4FAA4F;IAC5F,OAAO,CAAC,QAAQ;IAahB,OAAO,CAAC,OAAO;IAqBf,OAAO,CAAC,GAAG;CAWZ"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { ControlUploadImport, ControlUploadImportRequest, } from "@claudexor/schema";
|
|
2
|
+
import { hashJson, sensitiveResourcePolicy } from "@claudexor/util";
|
|
3
|
+
import { readResourceRow, readUploadRow, resourceError, sensitiveResourceError, } from "./resource-rows.js";
|
|
4
|
+
import { uploadKeyDigest } from "./upload-binding-retention.js";
|
|
5
|
+
/** A failed check of already received bytes means they were never a usable receipt. */
|
|
6
|
+
const UNVERIFIABLE = new Set(["digest_mismatch", "upload_size_mismatch"]);
|
|
7
|
+
/**
|
|
8
|
+
* Keyed import over the existing upload owner. The key binds the semantic request,
|
|
9
|
+
* its first declaration binds the content, and every replay is answered from the
|
|
10
|
+
* store before a client needs its source again.
|
|
11
|
+
*/
|
|
12
|
+
export class SqlUploadImports {
|
|
13
|
+
store;
|
|
14
|
+
uploads;
|
|
15
|
+
publisher;
|
|
16
|
+
constructor(store, uploads, publisher) {
|
|
17
|
+
this.store = store;
|
|
18
|
+
this.uploads = uploads;
|
|
19
|
+
this.publisher = publisher;
|
|
20
|
+
}
|
|
21
|
+
import(raw, key) {
|
|
22
|
+
const { expectedStoreId, content, ...request } = ControlUploadImportRequest.parse(raw);
|
|
23
|
+
// The store check precedes every lookup and effect; replay never adopts another store.
|
|
24
|
+
const storeId = this.store.storeId;
|
|
25
|
+
if (!storeId)
|
|
26
|
+
throw resourceError("durable store identity is unavailable", 503, "upload_import_unavailable");
|
|
27
|
+
if (expectedStoreId !== storeId)
|
|
28
|
+
throw resourceError("this import names another durable store", 409, "store_mismatch");
|
|
29
|
+
if (sensitiveResourcePolicy.classifyPath(request.name).sensitive)
|
|
30
|
+
throw sensitiveResourceError();
|
|
31
|
+
const requestDigest = hashJson({ ...request, source: request.source ?? null });
|
|
32
|
+
const bound = this.uploads.bindings.lookup("import", key, requestDigest);
|
|
33
|
+
if (!bound) {
|
|
34
|
+
if (!content)
|
|
35
|
+
throw resourceError("this store retains no import for this key; declare content to begin one", 404, "upload_import_not_found");
|
|
36
|
+
const { uploadId } = this.uploads.createImport({
|
|
37
|
+
kind: request.kind,
|
|
38
|
+
mime: request.mime,
|
|
39
|
+
name: request.name,
|
|
40
|
+
sizeBytes: content.sizeBytes,
|
|
41
|
+
}, { keyDigest: uploadKeyDigest("import", key), sha256: content.sha256 }, requestDigest);
|
|
42
|
+
return this.project(storeId, this.row(uploadId));
|
|
43
|
+
}
|
|
44
|
+
const row = this.row(bound.targetId);
|
|
45
|
+
const owned = boundContent(row);
|
|
46
|
+
if (content && (content.sizeBytes !== owned.sizeBytes || content.sha256 !== owned.sha256))
|
|
47
|
+
throw Object.assign(resourceError("this import key already owns other content; a new edition needs a new key", 409, "upload_import_content_conflict"), { context: { uploadId: row.status.uploadId, content: owned } });
|
|
48
|
+
return this.project(storeId, this.complete(row));
|
|
49
|
+
}
|
|
50
|
+
/** Publish verified bytes now, so a replay needs neither the source nor a client digest. */
|
|
51
|
+
complete(row) {
|
|
52
|
+
if (row.state !== "uploaded" && row.state !== "finalizing")
|
|
53
|
+
return row;
|
|
54
|
+
try {
|
|
55
|
+
this.publisher.publishImport(row);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
const code = error.code;
|
|
59
|
+
if (row.state === "uploaded" && typeof code === "string" && UNVERIFIABLE.has(code))
|
|
60
|
+
this.uploads.reopen(row.status.uploadId);
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
return this.row(row.status.uploadId);
|
|
64
|
+
}
|
|
65
|
+
project(storeId, row) {
|
|
66
|
+
const base = {
|
|
67
|
+
storeId,
|
|
68
|
+
uploadId: row.status.uploadId,
|
|
69
|
+
content: boundContent(row),
|
|
70
|
+
receivedBytes: row.status.receivedBytes,
|
|
71
|
+
};
|
|
72
|
+
if (row.state === "discarded")
|
|
73
|
+
return ControlUploadImport.parse({ ...base, state: "cancelled" });
|
|
74
|
+
if (row.state !== "published")
|
|
75
|
+
return ControlUploadImport.parse({
|
|
76
|
+
...base,
|
|
77
|
+
state: row.status.state === "uploading" ? "uploading" : "open",
|
|
78
|
+
});
|
|
79
|
+
const resource = row.finalization.result;
|
|
80
|
+
// Ordinary attachment resources are never released today; an absent row is not "ready".
|
|
81
|
+
if (readResourceRow(this.store, resource.resourceId)?.state !== "ready")
|
|
82
|
+
throw resourceError(`no such resource: ${resource.resourceId}`, 404, "resource_not_found");
|
|
83
|
+
return ControlUploadImport.parse({ ...base, state: "ready", resource });
|
|
84
|
+
}
|
|
85
|
+
row(uploadId) {
|
|
86
|
+
const row = readUploadRow(this.store, uploadId);
|
|
87
|
+
// A retained import binding always keeps its upload row; anything else is store damage.
|
|
88
|
+
if (!row?.import)
|
|
89
|
+
throw resourceError(`import upload ${uploadId} is missing for a retained binding`, 500, "upload_import_binding_invalid");
|
|
90
|
+
return row;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function boundContent(row) {
|
|
94
|
+
return { sizeBytes: row.request.sizeBytes, sha256: row.import.sha256 };
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=upload-imports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-imports.js","sourceRoot":"","sources":["../../src/store/upload-imports.ts"],"names":[],"mappings":"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"}
|
package/dist/store/uploads.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ControlUploadStatus } from "@claudexor/schema";
|
|
2
|
-
import { type UploadRow } from "./resource-rows.js";
|
|
1
|
+
import { ControlUploadCreateRequest, ControlUploadStatus } from "@claudexor/schema";
|
|
2
|
+
import { type UploadImportBinding, type UploadRow } from "./resource-rows.js";
|
|
3
3
|
import type { EngineStore } from "./store.js";
|
|
4
4
|
import { UploadBindings } from "./upload-binding-retention.js";
|
|
5
5
|
/** The shared main-thread decision used by cancel, post-publication cleanup and the sweep. */
|
|
@@ -12,6 +12,9 @@ export declare class SqlUploads {
|
|
|
12
12
|
constructor(store: EngineStore, defer: (work: Promise<unknown>) => void);
|
|
13
13
|
/** Omitting a caller key mints a new internal upload, with no historical replay to resolve. */
|
|
14
14
|
create(raw: unknown, callerKey?: string): ControlUploadStatus;
|
|
15
|
+
/** The import's key binds this upload in the same transaction that creates it. */
|
|
16
|
+
createImport(request: ControlUploadCreateRequest, binding: UploadImportBinding, requestDigest: string): ControlUploadStatus;
|
|
17
|
+
private open;
|
|
15
18
|
status(id: string): ControlUploadStatus;
|
|
16
19
|
get(id: string): UploadRow;
|
|
17
20
|
partPath(id: string): string;
|
|
@@ -25,6 +28,8 @@ export declare class SqlUploads {
|
|
|
25
28
|
private writeChunk;
|
|
26
29
|
private finishWrite;
|
|
27
30
|
private assertNotCancelled;
|
|
31
|
+
/** Unverified import bytes are not a receipt. An explicit cancel stays final. */
|
|
32
|
+
reopen(id: string): void;
|
|
28
33
|
private markCancelled;
|
|
29
34
|
private save;
|
|
30
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uploads.d.ts","sourceRoot":"","sources":["../../src/store/uploads.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"uploads.d.ts","sourceRoot":"","sources":["../../src/store/uploads.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAOpF,OAAO,EAKL,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EACL,cAAc,EAGf,MAAM,+BAA+B,CAAC;AAEvC,8FAA8F;AAC9F,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,SAAS,GAAG,OAAO,CAAC,CAwC9B;AAED,qBAAa,UAAU;IAKnB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK;IALxB,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAE7C,YACmB,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,EAazD;IAED,+FAA+F;IAC/F,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,mBAAmB,CAU5D;IAED,kFAAkF;IAClF,YAAY,CACV,OAAO,EAAE,0BAA0B,EACnC,OAAO,EAAE,mBAAmB,EAC5B,aAAa,EAAE,MAAM,GACpB,mBAAmB,CAErB;IAED,OAAO,CAAC,IAAI;IAkDZ,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,mBAAmB,CAEtC;IACD,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAKzB;IACD,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE3B;IAEK,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAqBvF;IAED,gFAAgF;IAChF,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI,CAY5C;IAED,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,mBAAmB,CAQtC;IAED,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAUxB;IACD,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAE1B;IAED,OAAO,CAAC,UAAU;IAalB,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,WAAW;IAoBnB,OAAO,CAAC,kBAAkB;IAI1B,iFAAiF;IACjF,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAMvB;IACD,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,IAAI;CAOb"}
|