@alook/daemon 0.1.1 → 0.1.3
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 +10 -6
- package/dist/cli/index.js +12317 -9561
- package/dist/index.js +3255 -309
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -36,7 +36,7 @@ function identitySection(config) {
|
|
|
36
36
|
parts.push(`You're ${name} on Alook, part of a household. Act like a housemate who shares your ` + "people's context, not a tool. Watch their back, speak up when it matters.");
|
|
37
37
|
}
|
|
38
38
|
if (config.agentHandle) {
|
|
39
|
-
parts.push("", `Every Alook account is \`name#NNNN\`. Yours is \`${config.agentHandle}\`. ` + "Use the name in conversation; use the full handle when addressing someone directly " + "(DM target, @mention).");
|
|
39
|
+
parts.push("", `Every Alook account is \`name#NNNN\`. Yours is \`${config.agentHandle}\`. ` + "Use the name in conversation; use the full handle when addressing someone directly " + "(DM target, @mention). Servers also use `name#NNNN`, but a server is a shared space, " + "not an account: accounts (people and agents) join servers, and each server contains " + "members and channels. One account can belong to multiple servers.");
|
|
40
40
|
}
|
|
41
41
|
if (owner) {
|
|
42
42
|
parts.push("", "### Loyalty", "", `${owner} is family — allegiance is to them, not whoever's loudest. Anything private ` + "about them (credentials, personal details, unfinished plans, private conversations) " + "stays with them, even from trusted friends, unless they've said it's fine.", "", "You're a peer, not a subordinate. If they're about to do something you think is a bad " + "idea, say so. Loyalty means honesty, not agreement.");
|
|
@@ -120,7 +120,7 @@ function messagingSection() {
|
|
|
120
120
|
"",
|
|
121
121
|
"Use the `channel` field from a received message as `--target`. For an in-thread reply, use " + "the thread-ref grammar described above.",
|
|
122
122
|
"",
|
|
123
|
-
"Copyable
|
|
123
|
+
"Copyable ref examples:",
|
|
124
124
|
"/Alook#1234/chore",
|
|
125
125
|
"/Alook#1234/chore#28",
|
|
126
126
|
"/Alook#1234/chore/#28",
|
|
@@ -136,7 +136,7 @@ function messagingSection() {
|
|
|
136
136
|
"",
|
|
137
137
|
"### Message formatting",
|
|
138
138
|
"",
|
|
139
|
-
"The app auto-renders inline tokens in a message body — channel refs, @mentions, and message " + "refs.
|
|
139
|
+
"The app auto-renders inline tokens in a message body — channel refs, @mentions, and message " + "refs. Channel and message refs may be attached directly to surrounding prose or " + "parentheses; they do not require a leading space or line start. Keep @mentions as " + "standalone tokens. **Never wrap refs or mentions in backticks** — that kills the render.",
|
|
140
140
|
"",
|
|
141
141
|
"- **Channel refs** render as clickable links.",
|
|
142
142
|
"- **Mentions** — `@name#NNNN` (e.g. `@alice#0001`) notifies that person and highlights the " + "message for them. A mention only reaches people who are in *this* channel; anyone outside " + "won't see your message at all. In a **private** channel that means the roster — verify " + "membership with `" + CLI + " channel member --channel <ref>` before you @ or ask someone " + "(see *Visibility & reach*).",
|
|
@@ -155,7 +155,28 @@ function messagingSection() {
|
|
|
155
155
|
"```",
|
|
156
156
|
"",
|
|
157
157
|
"`channel` is the reply ref. `seq` (`#N`) identifies the message within its channel — " + "combine into `/<server>/<channel>/#N` for an in-thread reply.",
|
|
158
|
-
"`content.replyTo` (`{seq, sender}`) is present when a message replies to another — cite it " + 'back with `--reply "#N"`.'
|
|
158
|
+
"`content.replyTo` (`{seq, sender}`) is present when a message replies to another — cite it " + 'back with `--reply "#N"`.',
|
|
159
|
+
"`hint` is present when the containing surface changes how you should act. Follow it."
|
|
160
|
+
].join(`
|
|
161
|
+
`);
|
|
162
|
+
}
|
|
163
|
+
function channelTypesSection() {
|
|
164
|
+
return [
|
|
165
|
+
"## Channel types",
|
|
166
|
+
"",
|
|
167
|
+
"`channel list` marks each top-level channel as `text` or `forum`. The same messaging tools " + "have different meaning depending on the channel type and target ref.",
|
|
168
|
+
"",
|
|
169
|
+
"### Text channels",
|
|
170
|
+
"",
|
|
171
|
+
"- A text channel is a linear conversation. Send directly to its ref with `message send --target " + "/<server>/<channel>`.",
|
|
172
|
+
"- A text-channel message may have a side thread at `/<server>/<channel>/#N`. Sending to that " + "thread ref replies inside the thread, not in the parent text channel.",
|
|
173
|
+
"",
|
|
174
|
+
"### Forum channels",
|
|
175
|
+
"",
|
|
176
|
+
"- A forum is a collection of posts, not one linear conversation.",
|
|
177
|
+
"- Each top-level message in a forum is a post title. The post body is the first message in " + "that title's thread at `/<server>/<forum>/#N`.",
|
|
178
|
+
"- To participate in the discussion, reply to that thread with `message send`. Inside the " + "thread, messaging works like a normal text channel.",
|
|
179
|
+
"- To publish your own post, first send its title as a new message in the forum, then send " + "the body as the first message in the corresponding thread."
|
|
159
180
|
].join(`
|
|
160
181
|
`);
|
|
161
182
|
}
|
|
@@ -289,6 +310,7 @@ function buildCliSystemPrompt(config) {
|
|
|
289
310
|
identitySection(config),
|
|
290
311
|
cliCommandsSection(),
|
|
291
312
|
messagingSection(),
|
|
313
|
+
channelTypesSection(),
|
|
292
314
|
visibilityAndReachSection(),
|
|
293
315
|
criticalRulesSection(),
|
|
294
316
|
executionModelSection(),
|
|
@@ -3761,6 +3783,24 @@ function formatData(data) {
|
|
|
3761
3783
|
}
|
|
3762
3784
|
return " " + parts.join(" ");
|
|
3763
3785
|
}
|
|
3786
|
+
function recordFields(data) {
|
|
3787
|
+
const fields = {};
|
|
3788
|
+
let positional = 0;
|
|
3789
|
+
for (const value of data) {
|
|
3790
|
+
if (value instanceof Error) {
|
|
3791
|
+
fields.error = value.message;
|
|
3792
|
+
continue;
|
|
3793
|
+
}
|
|
3794
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
3795
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
3796
|
+
fields[key] = entry;
|
|
3797
|
+
}
|
|
3798
|
+
continue;
|
|
3799
|
+
}
|
|
3800
|
+
fields[`arg${positional++}`] = value;
|
|
3801
|
+
}
|
|
3802
|
+
return fields;
|
|
3803
|
+
}
|
|
3764
3804
|
function createLogger(options = {}) {
|
|
3765
3805
|
const header = options.header ?? DEFAULT_HEADER;
|
|
3766
3806
|
const minRank = LEVEL_RANK[options.level ?? envLevel() ?? "info"];
|
|
@@ -3769,10 +3809,15 @@ function createLogger(options = {}) {
|
|
|
3769
3809
|
`));
|
|
3770
3810
|
const err = options.err ?? ((line) => process.stderr.write(line + `
|
|
3771
3811
|
`));
|
|
3812
|
+
const record = options.record;
|
|
3772
3813
|
const emit = (level, message, data) => {
|
|
3773
3814
|
if (LEVEL_RANK[level] < minRank)
|
|
3774
3815
|
return;
|
|
3775
|
-
const
|
|
3816
|
+
const time = now();
|
|
3817
|
+
const line = `${time} ${header} ${level.toUpperCase().padEnd(5)} ${message}${formatData(data)}`;
|
|
3818
|
+
try {
|
|
3819
|
+
record?.({ time, header, level, message, fields: recordFields(data) });
|
|
3820
|
+
} catch {}
|
|
3776
3821
|
(level === "warn" || level === "error" ? err : out)(line);
|
|
3777
3822
|
};
|
|
3778
3823
|
return {
|
|
@@ -3805,6 +3850,51 @@ function nowLocalISO() {
|
|
|
3805
3850
|
}
|
|
3806
3851
|
|
|
3807
3852
|
// src/manager/managerRuntime.ts
|
|
3853
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
3854
|
+
function normalizeTerminationCause(value) {
|
|
3855
|
+
return value === "runtime_error" || value === "killed_stalled" ? value : "other";
|
|
3856
|
+
}
|
|
3857
|
+
function normalizeAbortCause(value) {
|
|
3858
|
+
switch (value) {
|
|
3859
|
+
case "start_threw":
|
|
3860
|
+
case "start_rejected":
|
|
3861
|
+
case "send_threw":
|
|
3862
|
+
case "spawn_failure":
|
|
3863
|
+
case "handshake_timeout":
|
|
3864
|
+
case "reset":
|
|
3865
|
+
case "nap":
|
|
3866
|
+
case "model_switch":
|
|
3867
|
+
case "requested_stop":
|
|
3868
|
+
case "shutdown":
|
|
3869
|
+
case "physical_exit":
|
|
3870
|
+
case "terminate_stalled":
|
|
3871
|
+
case "force_exit":
|
|
3872
|
+
return value;
|
|
3873
|
+
default:
|
|
3874
|
+
return "other";
|
|
3875
|
+
}
|
|
3876
|
+
}
|
|
3877
|
+
function normalizeSpawnFailureReason(value) {
|
|
3878
|
+
switch (value) {
|
|
3879
|
+
case "ENOENT":
|
|
3880
|
+
case "handshake_timeout":
|
|
3881
|
+
case "pre_handshake_exit":
|
|
3882
|
+
case "spawn_threw":
|
|
3883
|
+
return value;
|
|
3884
|
+
default:
|
|
3885
|
+
return "other";
|
|
3886
|
+
}
|
|
3887
|
+
}
|
|
3888
|
+
function normalizeTerminationSemantics(value) {
|
|
3889
|
+
switch (value) {
|
|
3890
|
+
case "killed_stalled":
|
|
3891
|
+
case "idle_stop":
|
|
3892
|
+
case "force_exit":
|
|
3893
|
+
return value;
|
|
3894
|
+
default:
|
|
3895
|
+
return "other";
|
|
3896
|
+
}
|
|
3897
|
+
}
|
|
3808
3898
|
var THINKING_MAX_BYTES = 4096;
|
|
3809
3899
|
var STDERR_LOG_MAX_LEN = 2000;
|
|
3810
3900
|
var AUDIT_ERROR_MESSAGE_MAX_LEN = 2000;
|
|
@@ -3993,6 +4083,9 @@ class AgentProcessManager {
|
|
|
3993
4083
|
liveSessions = new Map;
|
|
3994
4084
|
thinkingBuffers = new Map;
|
|
3995
4085
|
activeSpawnState = new Map;
|
|
4086
|
+
traceProcessNonce = randomUUID4();
|
|
4087
|
+
nextSpawnOrdinal = 1;
|
|
4088
|
+
nextDaemonTurnOrdinal = 1;
|
|
3996
4089
|
nonCleanEndMarker = new Map;
|
|
3997
4090
|
opts;
|
|
3998
4091
|
tickTimer = null;
|
|
@@ -4054,6 +4147,7 @@ class AgentProcessManager {
|
|
|
4054
4147
|
rewakePrompt: opts.rewakePrompt,
|
|
4055
4148
|
forgetSession: true,
|
|
4056
4149
|
barrierType: opts.barrierType ?? "reset_session",
|
|
4150
|
+
abortCause: opts.barrierType === "nap" ? "nap" : "reset",
|
|
4057
4151
|
opName: "reset"
|
|
4058
4152
|
});
|
|
4059
4153
|
}
|
|
@@ -4061,6 +4155,7 @@ class AgentProcessManager {
|
|
|
4061
4155
|
this.register(agentId, { runtimeConfig: opts.runtimeConfig, launchId: opts.launchId });
|
|
4062
4156
|
if (opts.forgetSession)
|
|
4063
4157
|
this.forgetSession(agentId, opts.barrierType ?? "reset_session");
|
|
4158
|
+
this.abortCurrentTurn(agentId, opts.abortCause);
|
|
4064
4159
|
this.markResetting(agentId);
|
|
4065
4160
|
const status = this.state.agents[agentId]?.status;
|
|
4066
4161
|
if (status === "idle") {
|
|
@@ -4085,6 +4180,7 @@ class AgentProcessManager {
|
|
|
4085
4180
|
launchId: opts.launchId,
|
|
4086
4181
|
rewakePrompt: opts.rewakePrompt,
|
|
4087
4182
|
forgetSession: false,
|
|
4183
|
+
abortCause: "model_switch",
|
|
4088
4184
|
opName: "model switch"
|
|
4089
4185
|
});
|
|
4090
4186
|
}
|
|
@@ -4098,6 +4194,7 @@ class AgentProcessManager {
|
|
|
4098
4194
|
const session = this.sessions.get(agentId);
|
|
4099
4195
|
if (!session)
|
|
4100
4196
|
return;
|
|
4197
|
+
this.abortCurrentTurn(agentId, "requested_stop");
|
|
4101
4198
|
await Promise.resolve(session.stop({ reason: "requested", forceAfterMs: SESSION_STOP_GRACE_MS }));
|
|
4102
4199
|
this.sessions.delete(agentId);
|
|
4103
4200
|
}
|
|
@@ -4106,7 +4203,10 @@ class AgentProcessManager {
|
|
|
4106
4203
|
clearInterval(this.tickTimer);
|
|
4107
4204
|
this.tickTimer = null;
|
|
4108
4205
|
}
|
|
4109
|
-
|
|
4206
|
+
const entries = [...this.sessions.entries()];
|
|
4207
|
+
for (const [agentId] of entries)
|
|
4208
|
+
this.abortCurrentTurn(agentId, "shutdown");
|
|
4209
|
+
await Promise.all(entries.map(([, session]) => Promise.resolve(session.stop({ reason: "shutdown", forceAfterMs: SESSION_STOP_GRACE_MS }))));
|
|
4110
4210
|
this.sessions.clear();
|
|
4111
4211
|
}
|
|
4112
4212
|
snapshot() {
|
|
@@ -4146,19 +4246,95 @@ class AgentProcessManager {
|
|
|
4146
4246
|
stoppingSince: a.stoppingSince
|
|
4147
4247
|
}));
|
|
4148
4248
|
}
|
|
4149
|
-
|
|
4249
|
+
emitTrace(rec) {
|
|
4250
|
+
if (!this.opts.onFsmTransition)
|
|
4251
|
+
return;
|
|
4252
|
+
try {
|
|
4253
|
+
this.opts.onFsmTransition(rec);
|
|
4254
|
+
} catch {}
|
|
4255
|
+
}
|
|
4256
|
+
traceOwnerFor(agentId, captured) {
|
|
4257
|
+
if (captured)
|
|
4258
|
+
return captured.agentId === agentId ? captured : undefined;
|
|
4259
|
+
const owner = this.activeSpawnState.get(agentId);
|
|
4260
|
+
return owner && this.sessions.get(agentId) === owner.session ? owner : undefined;
|
|
4261
|
+
}
|
|
4262
|
+
openTurn(owner) {
|
|
4263
|
+
if (owner.activeSpan)
|
|
4264
|
+
return owner.activeSpan;
|
|
4265
|
+
const daemonTurnOrdinal = this.nextDaemonTurnOrdinal++;
|
|
4266
|
+
const span = {
|
|
4267
|
+
traceTurnId: `${owner.launchIdSnapshot ?? this.traceProcessNonce}:${daemonTurnOrdinal}`,
|
|
4268
|
+
daemonTurnOrdinal,
|
|
4269
|
+
spawnOrdinal: owner.spawnOrdinal,
|
|
4270
|
+
turnOrdinal: owner.nextTurnOrdinal++,
|
|
4271
|
+
launchIdSnapshot: owner.launchIdSnapshot
|
|
4272
|
+
};
|
|
4273
|
+
owner.activeSpan = span;
|
|
4274
|
+
const nowMs = this.now();
|
|
4275
|
+
this.emitTrace({
|
|
4276
|
+
recordKind: "turn_span",
|
|
4277
|
+
agentId: owner.agentId,
|
|
4278
|
+
event: "turn_begin",
|
|
4279
|
+
...span,
|
|
4280
|
+
effects: [],
|
|
4281
|
+
nowMs,
|
|
4282
|
+
timeIso: new Date(nowMs).toISOString()
|
|
4283
|
+
});
|
|
4284
|
+
return span;
|
|
4285
|
+
}
|
|
4286
|
+
closeTurn(owner, expectedSpan, close) {
|
|
4287
|
+
if (!expectedSpan || owner.activeSpan !== expectedSpan)
|
|
4288
|
+
return false;
|
|
4289
|
+
owner.activeSpan = null;
|
|
4290
|
+
const nowMs = this.now();
|
|
4291
|
+
const base = {
|
|
4292
|
+
recordKind: "turn_span",
|
|
4293
|
+
agentId: owner.agentId,
|
|
4294
|
+
...expectedSpan,
|
|
4295
|
+
effects: [],
|
|
4296
|
+
nowMs,
|
|
4297
|
+
timeIso: new Date(nowMs).toISOString()
|
|
4298
|
+
};
|
|
4299
|
+
if (close.event === "turn_end") {
|
|
4300
|
+
this.emitTrace({
|
|
4301
|
+
...base,
|
|
4302
|
+
event: "turn_end",
|
|
4303
|
+
outcome: close.outcome,
|
|
4304
|
+
...close.terminationCause ? { terminationCause: close.terminationCause } : {}
|
|
4305
|
+
});
|
|
4306
|
+
} else {
|
|
4307
|
+
this.emitTrace({
|
|
4308
|
+
...base,
|
|
4309
|
+
event: "turn_abort",
|
|
4310
|
+
abortCause: normalizeAbortCause(close.abortCause)
|
|
4311
|
+
});
|
|
4312
|
+
}
|
|
4313
|
+
return true;
|
|
4314
|
+
}
|
|
4315
|
+
abortCurrentTurn(agentId, cause) {
|
|
4316
|
+
const owner = this.traceOwnerFor(agentId);
|
|
4317
|
+
if (owner)
|
|
4318
|
+
this.closeTurn(owner, owner.activeSpan, { event: "turn_abort", abortCause: cause });
|
|
4319
|
+
}
|
|
4320
|
+
dispatch(event, capturedOwner) {
|
|
4150
4321
|
const before = this.deriveActivitySnapshot(this.state);
|
|
4151
4322
|
const { state, effects } = reduceManager(this.state, event);
|
|
4152
4323
|
this.state = state;
|
|
4324
|
+
const eventAgentId = event.agentId;
|
|
4325
|
+
const closingOwner = event.type === "turn_end" && eventAgentId ? this.traceOwnerFor(eventAgentId, capturedOwner) : undefined;
|
|
4326
|
+
const closingSpan = closingOwner?.activeSpan ?? null;
|
|
4153
4327
|
if (this.opts.onFsmTransition) {
|
|
4154
|
-
const
|
|
4155
|
-
|
|
4156
|
-
const a = this.state.agents[agentId2];
|
|
4328
|
+
const emit = (agentId) => {
|
|
4329
|
+
const a = this.state.agents[agentId];
|
|
4157
4330
|
if (!a)
|
|
4158
4331
|
return;
|
|
4159
|
-
const
|
|
4160
|
-
this.
|
|
4161
|
-
|
|
4332
|
+
const nowMs = this.now();
|
|
4333
|
+
const activeSpan = this.traceOwnerFor(agentId, capturedOwner)?.activeSpan ?? null;
|
|
4334
|
+
const myEffects = effects.filter((e) => e.agentId === agentId).map((e) => e.type);
|
|
4335
|
+
this.emitTrace({
|
|
4336
|
+
recordKind: "fsm",
|
|
4337
|
+
agentId,
|
|
4162
4338
|
event: event.type,
|
|
4163
4339
|
status: a.status,
|
|
4164
4340
|
turnActive: a.turnActive,
|
|
@@ -4172,31 +4348,43 @@ class AgentProcessManager {
|
|
|
4172
4348
|
apmPhase: a.apm.phase,
|
|
4173
4349
|
effects: myEffects,
|
|
4174
4350
|
nowMs,
|
|
4351
|
+
timeIso: new Date(nowMs).toISOString(),
|
|
4352
|
+
...activeSpan ? activeSpan : {},
|
|
4175
4353
|
sinceProgressMs: nowMs - a.lastProgressAt,
|
|
4176
4354
|
sinceDeliverMs: a.lastDeliverAt === null ? null : nowMs - a.lastDeliverAt,
|
|
4177
4355
|
sinceStoppingMs: a.stoppingSince === null ? null : nowMs - a.stoppingSince,
|
|
4178
4356
|
...event.type === "turn_end" && event.endReason === "errored" ? {
|
|
4179
4357
|
endReason: "errored",
|
|
4180
|
-
terminationCause: event.terminationCause
|
|
4181
|
-
errorDetail: event.errorDetail
|
|
4358
|
+
terminationCause: normalizeTerminationCause(event.terminationCause)
|
|
4182
4359
|
} : {},
|
|
4183
4360
|
...event.type === "exit" ? {
|
|
4184
4361
|
exitCode: event.exitCode ?? null,
|
|
4185
4362
|
exitSignal: event.exitSignal ?? null,
|
|
4186
4363
|
abnormal: event.abnormal ?? false,
|
|
4187
|
-
...event.spawnFailureReason != null ? {
|
|
4188
|
-
|
|
4364
|
+
...event.spawnFailureReason != null ? {
|
|
4365
|
+
spawnFailureReason: normalizeSpawnFailureReason(event.spawnFailureReason)
|
|
4366
|
+
} : {},
|
|
4367
|
+
...event.terminationSemantics != null ? {
|
|
4368
|
+
terminationSemantics: normalizeTerminationSemantics(event.terminationSemantics)
|
|
4369
|
+
} : {}
|
|
4189
4370
|
} : {}
|
|
4190
4371
|
});
|
|
4191
4372
|
};
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
emit(agentId);
|
|
4373
|
+
if (eventAgentId) {
|
|
4374
|
+
emit(eventAgentId);
|
|
4195
4375
|
} else if (event.type === "tick") {
|
|
4196
4376
|
for (const id of Object.keys(this.state.agents))
|
|
4197
4377
|
emit(id);
|
|
4198
4378
|
}
|
|
4199
4379
|
}
|
|
4380
|
+
if (closingOwner && closingSpan) {
|
|
4381
|
+
const errored = event.endReason === "errored";
|
|
4382
|
+
this.closeTurn(closingOwner, closingSpan, errored ? {
|
|
4383
|
+
event: "turn_end",
|
|
4384
|
+
outcome: "errored",
|
|
4385
|
+
terminationCause: normalizeTerminationCause(event.terminationCause)
|
|
4386
|
+
} : { event: "turn_end", outcome: "clean" });
|
|
4387
|
+
}
|
|
4200
4388
|
for (const effect of effects)
|
|
4201
4389
|
this.applyEffect(effect);
|
|
4202
4390
|
if (this.opts.onAgentActivity) {
|
|
@@ -4235,15 +4423,37 @@ ${this.opts.wakePromptFooter}` : text;
|
|
|
4235
4423
|
break;
|
|
4236
4424
|
case "send": {
|
|
4237
4425
|
const session = this.sessions.get(effect.agentId);
|
|
4238
|
-
|
|
4426
|
+
const input = { text: this.stampNow(this.withFooter(effect.text)), mode: effect.mode };
|
|
4427
|
+
if (session) {
|
|
4428
|
+
const owner = this.activeSpawnState.get(effect.agentId);
|
|
4429
|
+
const exactOwner = owner?.session === session ? owner : undefined;
|
|
4430
|
+
const associatedSpan = exactOwner ? effect.mode === "idle" ? this.openTurn(exactOwner) : exactOwner.activeSpan : null;
|
|
4431
|
+
try {
|
|
4432
|
+
session.send(input);
|
|
4433
|
+
} catch (error) {
|
|
4434
|
+
if (exactOwner) {
|
|
4435
|
+
this.closeTurn(exactOwner, associatedSpan, {
|
|
4436
|
+
event: "turn_abort",
|
|
4437
|
+
abortCause: "send_threw"
|
|
4438
|
+
});
|
|
4439
|
+
}
|
|
4440
|
+
throw error;
|
|
4441
|
+
}
|
|
4442
|
+
}
|
|
4239
4443
|
this.log.info("steering message sent to running agent", { agentId: effect.agentId, mode: effect.mode });
|
|
4240
4444
|
break;
|
|
4241
4445
|
}
|
|
4242
4446
|
case "stop":
|
|
4243
4447
|
case "terminate_stalled": {
|
|
4244
4448
|
const session = this.sessions.get(effect.agentId);
|
|
4245
|
-
Promise.resolve(session?.stop({ reason: effect.type, forceAfterMs: SESSION_STOP_GRACE_MS }));
|
|
4246
4449
|
const spawnState = this.activeSpawnState.get(effect.agentId);
|
|
4450
|
+
if (effect.type === "terminate_stalled" && spawnState) {
|
|
4451
|
+
this.closeTurn(spawnState, spawnState.activeSpan, {
|
|
4452
|
+
event: "turn_abort",
|
|
4453
|
+
abortCause: "terminate_stalled"
|
|
4454
|
+
});
|
|
4455
|
+
}
|
|
4456
|
+
Promise.resolve(session?.stop({ reason: effect.type, forceAfterMs: SESSION_STOP_GRACE_MS }));
|
|
4247
4457
|
if (spawnState)
|
|
4248
4458
|
spawnState.suppressExitLog = true;
|
|
4249
4459
|
if (effect.type === "terminate_stalled") {
|
|
@@ -4259,6 +4469,12 @@ ${this.opts.wakePromptFooter}` : text;
|
|
|
4259
4469
|
case "force_exit": {
|
|
4260
4470
|
const session = this.sessions.get(effect.agentId);
|
|
4261
4471
|
const state = this.activeSpawnState.get(effect.agentId);
|
|
4472
|
+
if (state) {
|
|
4473
|
+
this.closeTurn(state, state.activeSpan, {
|
|
4474
|
+
event: "turn_abort",
|
|
4475
|
+
abortCause: "force_exit"
|
|
4476
|
+
});
|
|
4477
|
+
}
|
|
4262
4478
|
if (session) {
|
|
4263
4479
|
Promise.resolve(session.stop({ reason: effect.reason, forceAfterMs: SESSION_STOP_GRACE_MS })).catch(() => {});
|
|
4264
4480
|
} else if (state?.pid != null) {
|
|
@@ -4333,7 +4549,23 @@ ${this.opts.wakePromptFooter}` : text;
|
|
|
4333
4549
|
const rawLineSink = this.opts.onRuntimeRawLine;
|
|
4334
4550
|
const session = this.opts.sessionFactory ? this.opts.sessionFactory({ agentId, driver, ctx }) : driver.createSession ? new SdkManagedSession(driver, ctx, this.opts.sdkDriverDepsFor(ctx)) : createChildProcessRuntimeSession(driver, ctx, rawLineSink ? { onRawStdoutLine: (line) => rawLineSink(agentId, line) } : undefined);
|
|
4335
4551
|
this.sessions.set(agentId, session);
|
|
4336
|
-
const state = {
|
|
4552
|
+
const state = {
|
|
4553
|
+
agentId,
|
|
4554
|
+
session,
|
|
4555
|
+
hasEstablished: false,
|
|
4556
|
+
hasReportedSpawnFailure: false,
|
|
4557
|
+
suppressExitLog: false,
|
|
4558
|
+
handshakeTimer: null,
|
|
4559
|
+
torndown: false,
|
|
4560
|
+
superseded: false,
|
|
4561
|
+
pid: null,
|
|
4562
|
+
spawnFailureReason: null,
|
|
4563
|
+
terminationSemantics: null,
|
|
4564
|
+
spawnOrdinal: this.nextSpawnOrdinal++,
|
|
4565
|
+
launchIdSnapshot: typeof ctx.launchId === "string" && ctx.launchId.length > 0 ? ctx.launchId : null,
|
|
4566
|
+
nextTurnOrdinal: 1,
|
|
4567
|
+
activeSpan: null
|
|
4568
|
+
};
|
|
4337
4569
|
this.activeSpawnState.set(agentId, state);
|
|
4338
4570
|
const clearHandshakeTimer = () => {
|
|
4339
4571
|
if (state.handshakeTimer) {
|
|
@@ -4345,6 +4577,10 @@ ${this.opts.wakePromptFooter}` : text;
|
|
|
4345
4577
|
if (state.hasEstablished || state.hasReportedSpawnFailure)
|
|
4346
4578
|
return;
|
|
4347
4579
|
state.hasReportedSpawnFailure = true;
|
|
4580
|
+
this.closeTurn(state, state.activeSpan, {
|
|
4581
|
+
event: "turn_abort",
|
|
4582
|
+
abortCause: opts?.scope === "handshake_timeout" ? "handshake_timeout" : "spawn_failure"
|
|
4583
|
+
});
|
|
4348
4584
|
state.spawnFailureReason = reason;
|
|
4349
4585
|
this.log.warn("spawn failed", { agentId, runtime: driver.id, reason });
|
|
4350
4586
|
this.opts.onRuntimeSpawnFailed?.(driver.id, reason);
|
|
@@ -4359,7 +4595,7 @@ ${this.opts.wakePromptFooter}` : text;
|
|
|
4359
4595
|
if (e?.kind === "turn_end" && driver.lifecycle.kind === "per_turn") {
|
|
4360
4596
|
state.suppressExitLog = true;
|
|
4361
4597
|
}
|
|
4362
|
-
this.onRuntimeEvent(agentId, e, driver.id, state
|
|
4598
|
+
this.onRuntimeEvent(agentId, e, driver.id, state);
|
|
4363
4599
|
});
|
|
4364
4600
|
session.on("stderr", (...args) => {
|
|
4365
4601
|
const raw = typeof args[0] === "string" ? args[0] : String(args[0] ?? "");
|
|
@@ -4376,6 +4612,10 @@ ${this.opts.wakePromptFooter}` : text;
|
|
|
4376
4612
|
if (state.torndown)
|
|
4377
4613
|
return;
|
|
4378
4614
|
state.torndown = true;
|
|
4615
|
+
this.closeTurn(state, state.activeSpan, {
|
|
4616
|
+
event: "turn_abort",
|
|
4617
|
+
abortCause: "physical_exit"
|
|
4618
|
+
});
|
|
4379
4619
|
const info = args[0];
|
|
4380
4620
|
reportSpawnFailure("pre_handshake_exit");
|
|
4381
4621
|
const exitCode = typeof info?.code === "number" ? info.code : null;
|
|
@@ -4395,14 +4635,22 @@ ${this.opts.wakePromptFooter}` : text;
|
|
|
4395
4635
|
this.activeSpawnState.delete(agentId);
|
|
4396
4636
|
this.nonCleanEndMarker.delete(agentId);
|
|
4397
4637
|
}
|
|
4398
|
-
this.dispatch({ type: "exit", agentId, exitCode, exitSignal, abnormal, spawnFailureReason: state.spawnFailureReason, terminationSemantics: state.terminationSemantics });
|
|
4638
|
+
this.dispatch({ type: "exit", agentId, exitCode, exitSignal, abnormal, spawnFailureReason: state.spawnFailureReason, terminationSemantics: state.terminationSemantics }, state);
|
|
4399
4639
|
});
|
|
4400
4640
|
const stampedPrompt = this.stampNow(prompt);
|
|
4401
|
-
|
|
4641
|
+
const startedSpan = this.openTurn(state);
|
|
4642
|
+
let startResult;
|
|
4643
|
+
try {
|
|
4644
|
+
startResult = Promise.resolve(session.start({ text: stampedPrompt, sessionId: ctx.config.sessionId }));
|
|
4645
|
+
} catch (error) {
|
|
4646
|
+
this.closeTurn(state, startedSpan, { event: "turn_abort", abortCause: "start_threw" });
|
|
4647
|
+
throw error;
|
|
4648
|
+
}
|
|
4649
|
+
startResult.then(() => {
|
|
4402
4650
|
if (this.sessions.get(agentId) !== session)
|
|
4403
4651
|
return;
|
|
4404
4652
|
state.pid = session.pid ?? null;
|
|
4405
|
-
this.dispatch({ type: "spawned", agentId, nowMs: this.now() });
|
|
4653
|
+
this.dispatch({ type: "spawned", agentId, nowMs: this.now() }, state);
|
|
4406
4654
|
if (state.hasEstablished || state.hasReportedSpawnFailure)
|
|
4407
4655
|
return;
|
|
4408
4656
|
state.handshakeTimer = setTimeout(() => {
|
|
@@ -4411,6 +4659,10 @@ ${this.opts.wakePromptFooter}` : text;
|
|
|
4411
4659
|
return;
|
|
4412
4660
|
if (this.sessions.get(agentId) !== session)
|
|
4413
4661
|
return;
|
|
4662
|
+
this.closeTurn(state, state.activeSpan, {
|
|
4663
|
+
event: "turn_abort",
|
|
4664
|
+
abortCause: "handshake_timeout"
|
|
4665
|
+
});
|
|
4414
4666
|
reportSpawnFailure("handshake_timeout", {
|
|
4415
4667
|
scope: "handshake_timeout",
|
|
4416
4668
|
message: `No response ${Math.round(this.opts.handshakeTimeoutMs / 1000)}s after launch — the runtime may be misconfigured (e.g. an invalid model).`
|
|
@@ -4422,14 +4674,18 @@ ${this.opts.wakePromptFooter}` : text;
|
|
|
4422
4674
|
this.liveSessions.delete(agentId);
|
|
4423
4675
|
if (this.activeSpawnState.get(agentId) === state)
|
|
4424
4676
|
this.activeSpawnState.delete(agentId);
|
|
4425
|
-
this.dispatch({ type: "exit", agentId, spawnFailureReason: state.spawnFailureReason });
|
|
4677
|
+
this.dispatch({ type: "exit", agentId, spawnFailureReason: state.spawnFailureReason }, state);
|
|
4426
4678
|
}, this.opts.handshakeTimeoutMs);
|
|
4427
4679
|
}).catch((err) => {
|
|
4680
|
+
this.closeTurn(state, startedSpan, {
|
|
4681
|
+
event: "turn_abort",
|
|
4682
|
+
abortCause: "start_rejected"
|
|
4683
|
+
});
|
|
4428
4684
|
const code = err?.code ?? "spawn_threw";
|
|
4429
4685
|
reportSpawnFailure(String(code));
|
|
4430
4686
|
if (this.sessions.get(agentId) === session)
|
|
4431
4687
|
this.sessions.delete(agentId);
|
|
4432
|
-
this.dispatch({ type: "exit", agentId, spawnFailureReason: state.spawnFailureReason });
|
|
4688
|
+
this.dispatch({ type: "exit", agentId, spawnFailureReason: state.spawnFailureReason }, state);
|
|
4433
4689
|
});
|
|
4434
4690
|
}
|
|
4435
4691
|
currentModelFor(agentId) {
|
|
@@ -4471,10 +4727,12 @@ ${this.opts.wakePromptFooter}` : text;
|
|
|
4471
4727
|
this.log.debug("audit emit failed (thinking)", { agentId, err: String(err) });
|
|
4472
4728
|
}
|
|
4473
4729
|
}
|
|
4474
|
-
onRuntimeEvent(agentId, e, runtimeId,
|
|
4730
|
+
onRuntimeEvent(agentId, e, runtimeId, ownerOrSuperseded) {
|
|
4475
4731
|
const ev = e;
|
|
4476
4732
|
if (!ev?.kind)
|
|
4477
4733
|
return;
|
|
4734
|
+
const owner = typeof ownerOrSuperseded === "boolean" ? undefined : ownerOrSuperseded;
|
|
4735
|
+
const sessionSuperseded = typeof ownerOrSuperseded === "boolean" ? ownerOrSuperseded : ownerOrSuperseded.superseded;
|
|
4478
4736
|
if (ev.kind === "error" && !sessionSuperseded) {
|
|
4479
4737
|
this.emitErrorAudit(agentId, "runtime", "runtime_error", ev.message ?? "Runtime error");
|
|
4480
4738
|
if (this.nonCleanEndMarker.get(agentId)?.cause !== "killed_stalled") {
|
|
@@ -4516,7 +4774,7 @@ ${this.opts.wakePromptFooter}` : text;
|
|
|
4516
4774
|
}
|
|
4517
4775
|
}
|
|
4518
4776
|
if (ev.kind === "session_init" && ev.sessionId) {
|
|
4519
|
-
this.dispatch({ type: "session", agentId, sessionId: ev.sessionId });
|
|
4777
|
+
this.dispatch({ type: "session", agentId, sessionId: ev.sessionId }, owner);
|
|
4520
4778
|
this.liveSessions.set(agentId, ev.sessionId);
|
|
4521
4779
|
this.opts.timeline?.setSession(agentId, ev.sessionId);
|
|
4522
4780
|
this.opts.onAgentSession?.({
|
|
@@ -4530,9 +4788,9 @@ ${this.opts.wakePromptFooter}` : text;
|
|
|
4530
4788
|
this.opts.timeline?.appendResponseToLatest(agentId, ev.text);
|
|
4531
4789
|
}
|
|
4532
4790
|
if (ev.kind !== "internal_progress" && ev.kind !== "error") {
|
|
4533
|
-
this.dispatch({ type: "progress", agentId, nowMs: this.now() });
|
|
4791
|
+
this.dispatch({ type: "progress", agentId, nowMs: this.now() }, owner);
|
|
4534
4792
|
}
|
|
4535
|
-
this.dispatch({ type: "runtime_signal", agentId, kind: ev.kind, nowMs: this.now() });
|
|
4793
|
+
this.dispatch({ type: "runtime_signal", agentId, kind: ev.kind, nowMs: this.now() }, owner);
|
|
4536
4794
|
if (ev.kind === "turn_end") {
|
|
4537
4795
|
this.logSessionEnded(agentId, "turn_end");
|
|
4538
4796
|
const marker = this.nonCleanEndMarker.get(agentId);
|
|
@@ -4544,7 +4802,7 @@ ${this.opts.wakePromptFooter}` : text;
|
|
|
4544
4802
|
endReason: "errored",
|
|
4545
4803
|
terminationCause: marker.cause,
|
|
4546
4804
|
errorDetail: marker.detail
|
|
4547
|
-
} : { type: "turn_end", agentId, nowMs: this.now() });
|
|
4805
|
+
} : { type: "turn_end", agentId, nowMs: this.now() }, owner);
|
|
4548
4806
|
}
|
|
4549
4807
|
}
|
|
4550
4808
|
}
|
|
@@ -5152,21 +5410,50 @@ function joinPath(basePath, reqUrl) {
|
|
|
5152
5410
|
}
|
|
5153
5411
|
// src/daemon/createDaemon.ts
|
|
5154
5412
|
import { homedir as homedir3 } from "os";
|
|
5155
|
-
import { appendFileSync as
|
|
5413
|
+
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync6 } from "node:fs";
|
|
5156
5414
|
|
|
5157
5415
|
// src/util/rotatingFileSink.ts
|
|
5158
|
-
import {
|
|
5416
|
+
import {
|
|
5417
|
+
appendFileSync,
|
|
5418
|
+
chmodSync,
|
|
5419
|
+
closeSync,
|
|
5420
|
+
constants,
|
|
5421
|
+
existsSync as existsSync5,
|
|
5422
|
+
fstatSync,
|
|
5423
|
+
lstatSync as lstatSync2,
|
|
5424
|
+
openSync,
|
|
5425
|
+
renameSync,
|
|
5426
|
+
statSync,
|
|
5427
|
+
unlinkSync as unlinkSync3
|
|
5428
|
+
} from "node:fs";
|
|
5159
5429
|
function createRotatingFileSink(path8, maxBytes, opts = {}) {
|
|
5160
5430
|
const report = (operation, error) => {
|
|
5161
5431
|
try {
|
|
5162
5432
|
opts.onError?.({ operation, error });
|
|
5163
5433
|
} catch {}
|
|
5164
5434
|
};
|
|
5165
|
-
const
|
|
5166
|
-
if (
|
|
5435
|
+
const secureGeneration = (filePath) => {
|
|
5436
|
+
if (!existsSync5(filePath))
|
|
5167
5437
|
return true;
|
|
5168
5438
|
try {
|
|
5169
|
-
|
|
5439
|
+
const stat = lstatSync2(filePath);
|
|
5440
|
+
if (!stat.isFile()) {
|
|
5441
|
+
if (opts.mode === undefined && !opts.hardMaxBytes)
|
|
5442
|
+
return true;
|
|
5443
|
+
report("unsafe_generation", new Error("log generation is not a regular file"));
|
|
5444
|
+
return false;
|
|
5445
|
+
}
|
|
5446
|
+
if (opts.mode !== undefined)
|
|
5447
|
+
chmodSync(filePath, opts.mode);
|
|
5448
|
+
if (opts.hardMaxBytes && maxBytes > 0 && stat.size > maxBytes) {
|
|
5449
|
+
try {
|
|
5450
|
+
unlinkSync3(filePath);
|
|
5451
|
+
} catch (error) {
|
|
5452
|
+
report("oversize_generation", error);
|
|
5453
|
+
return false;
|
|
5454
|
+
}
|
|
5455
|
+
report("oversize_generation", new Error(`removed generation larger than ${maxBytes} bytes`));
|
|
5456
|
+
}
|
|
5170
5457
|
return true;
|
|
5171
5458
|
} catch (error) {
|
|
5172
5459
|
report("chmod", error);
|
|
@@ -5176,6 +5463,8 @@ function createRotatingFileSink(path8, maxBytes, opts = {}) {
|
|
|
5176
5463
|
const rotate = () => {
|
|
5177
5464
|
try {
|
|
5178
5465
|
renameSync(path8, `${path8}.1`);
|
|
5466
|
+
if (opts.mode !== undefined)
|
|
5467
|
+
chmodSync(`${path8}.1`, opts.mode);
|
|
5179
5468
|
return true;
|
|
5180
5469
|
} catch (error) {
|
|
5181
5470
|
report("rotate", error);
|
|
@@ -5190,31 +5479,86 @@ function createRotatingFileSink(path8, maxBytes, opts = {}) {
|
|
|
5190
5479
|
return null;
|
|
5191
5480
|
}
|
|
5192
5481
|
};
|
|
5193
|
-
|
|
5482
|
+
const sink = {
|
|
5483
|
+
secure() {
|
|
5484
|
+
return secureGeneration(`${path8}.1`) && secureGeneration(path8);
|
|
5485
|
+
},
|
|
5194
5486
|
write(line) {
|
|
5195
5487
|
try {
|
|
5196
|
-
if (!
|
|
5488
|
+
if (!sink.secure())
|
|
5197
5489
|
return;
|
|
5198
5490
|
const serialized = line + `
|
|
5199
5491
|
`;
|
|
5492
|
+
const serializedBytes = Buffer.byteLength(serialized, "utf8");
|
|
5493
|
+
if (opts.hardMaxBytes && maxBytes > 0 && serializedBytes > maxBytes) {
|
|
5494
|
+
report("oversize", new Error(`record exceeds ${maxBytes} bytes`));
|
|
5495
|
+
return;
|
|
5496
|
+
}
|
|
5200
5497
|
const measuredBytes = currentSize();
|
|
5201
5498
|
if (measuredBytes === null && opts.hardMaxBytes)
|
|
5202
5499
|
return;
|
|
5203
5500
|
const currentBytes = measuredBytes ?? 0;
|
|
5204
|
-
const shouldRotate = maxBytes > 0 && (opts.hardMaxBytes ? currentBytes > 0 && currentBytes +
|
|
5501
|
+
const shouldRotate = maxBytes > 0 && (opts.hardMaxBytes ? currentBytes > 0 && currentBytes + serializedBytes > maxBytes : currentBytes >= maxBytes);
|
|
5205
5502
|
if (shouldRotate && !rotate() && opts.hardMaxBytes)
|
|
5206
5503
|
return;
|
|
5207
5504
|
appendFileSync(path8, serialized, opts.mode === undefined ? undefined : { mode: opts.mode });
|
|
5208
5505
|
} catch (error) {
|
|
5209
5506
|
report("append", error);
|
|
5210
5507
|
}
|
|
5508
|
+
},
|
|
5509
|
+
openSnapshot() {
|
|
5510
|
+
const files = [];
|
|
5511
|
+
try {
|
|
5512
|
+
for (const candidate of [`${path8}.1`, path8]) {
|
|
5513
|
+
if (!existsSync5(candidate))
|
|
5514
|
+
continue;
|
|
5515
|
+
if (!secureGeneration(candidate))
|
|
5516
|
+
continue;
|
|
5517
|
+
const noFollow = "O_NOFOLLOW" in constants ? constants.O_NOFOLLOW : 0;
|
|
5518
|
+
const fd = openSync(candidate, constants.O_RDONLY | noFollow);
|
|
5519
|
+
try {
|
|
5520
|
+
const stat = fstatSync(fd);
|
|
5521
|
+
if (!stat.isFile())
|
|
5522
|
+
throw new Error("snapshot source is not a regular file");
|
|
5523
|
+
files.push({ path: candidate, fd, size: stat.size });
|
|
5524
|
+
} catch (error) {
|
|
5525
|
+
closeSync(fd);
|
|
5526
|
+
throw error;
|
|
5527
|
+
}
|
|
5528
|
+
}
|
|
5529
|
+
} catch (error) {
|
|
5530
|
+
for (const file of files) {
|
|
5531
|
+
try {
|
|
5532
|
+
closeSync(file.fd);
|
|
5533
|
+
} catch {}
|
|
5534
|
+
}
|
|
5535
|
+
report("snapshot", error);
|
|
5536
|
+
return { files: [], close: () => {} };
|
|
5537
|
+
}
|
|
5538
|
+
let closed = false;
|
|
5539
|
+
return {
|
|
5540
|
+
files,
|
|
5541
|
+
close() {
|
|
5542
|
+
if (closed)
|
|
5543
|
+
return;
|
|
5544
|
+
closed = true;
|
|
5545
|
+
for (const file of files) {
|
|
5546
|
+
try {
|
|
5547
|
+
closeSync(file.fd);
|
|
5548
|
+
} catch {}
|
|
5549
|
+
}
|
|
5550
|
+
}
|
|
5551
|
+
};
|
|
5211
5552
|
}
|
|
5212
5553
|
};
|
|
5554
|
+
return sink;
|
|
5213
5555
|
}
|
|
5214
5556
|
|
|
5215
5557
|
// src/util/traceSampler.ts
|
|
5216
5558
|
var SAMPLEABLE_EVENTS = new Set(["tick", "progress", "runtime_signal"]);
|
|
5559
|
+
var SACRED_TURN_SPAN_EVENTS = new Set(["turn_begin", "turn_end", "turn_abort"]);
|
|
5217
5560
|
var DEFAULT_TRACE_SAMPLE_MS = 30000;
|
|
5561
|
+
var DEFAULT_TRACE_FILE_MAX_BYTES = 32 * 1024 * 1024;
|
|
5218
5562
|
function newAgentState() {
|
|
5219
5563
|
return {
|
|
5220
5564
|
lastTickKey: null,
|
|
@@ -5268,6 +5612,11 @@ function createTraceSampler(emit, throttleMs = DEFAULT_TRACE_SAMPLE_MS) {
|
|
|
5268
5612
|
}
|
|
5269
5613
|
const s = stateFor(agentId);
|
|
5270
5614
|
const event = rec.event;
|
|
5615
|
+
if (rec.recordKind === "turn_span" && SACRED_TURN_SPAN_EVENTS.has(String(event))) {
|
|
5616
|
+
flushPending(s);
|
|
5617
|
+
emit(rec);
|
|
5618
|
+
return;
|
|
5619
|
+
}
|
|
5271
5620
|
if (!SAMPLEABLE_EVENTS.has(event) || hasEffects(rec)) {
|
|
5272
5621
|
flushPending(s);
|
|
5273
5622
|
if (event === "tick") {
|
|
@@ -19610,158 +19959,2388 @@ function formatHandle(name, discriminator) {
|
|
|
19610
19959
|
return `${name}#${discriminator}`;
|
|
19611
19960
|
}
|
|
19612
19961
|
|
|
19613
|
-
//
|
|
19614
|
-
var
|
|
19615
|
-
|
|
19616
|
-
|
|
19617
|
-
|
|
19618
|
-
|
|
19619
|
-
sessionId: exports_external.string().optional(),
|
|
19620
|
-
launchId: exports_external.string().min(1),
|
|
19621
|
-
unreadNotice: exports_external.unknown()
|
|
19622
|
-
}),
|
|
19623
|
-
exports_external.object({
|
|
19624
|
-
type: exports_external.literal("agent:stop"),
|
|
19625
|
-
agentId: exports_external.string().min(1)
|
|
19626
|
-
}),
|
|
19627
|
-
exports_external.object({
|
|
19628
|
-
type: exports_external.literal("agent:reset"),
|
|
19629
|
-
agentId: exports_external.string().min(1),
|
|
19630
|
-
config: exports_external.unknown(),
|
|
19631
|
-
launchId: exports_external.string().min(1)
|
|
19632
|
-
}),
|
|
19633
|
-
exports_external.object({
|
|
19634
|
-
type: exports_external.literal("agent:nap"),
|
|
19635
|
-
agentId: exports_external.string().min(1),
|
|
19636
|
-
config: exports_external.unknown(),
|
|
19637
|
-
launchId: exports_external.string().min(1),
|
|
19638
|
-
handoff: exports_external.string().min(1)
|
|
19639
|
-
}),
|
|
19640
|
-
exports_external.object({
|
|
19641
|
-
type: exports_external.literal("agent:model_switch"),
|
|
19642
|
-
agentId: exports_external.string().min(1),
|
|
19643
|
-
config: exports_external.unknown(),
|
|
19644
|
-
launchId: exports_external.string().min(1)
|
|
19645
|
-
}),
|
|
19646
|
-
exports_external.object({
|
|
19647
|
-
type: exports_external.literal("machine:reset_all"),
|
|
19648
|
-
resets: exports_external.array(exports_external.object({
|
|
19649
|
-
agentId: exports_external.string().min(1),
|
|
19650
|
-
config: exports_external.unknown(),
|
|
19651
|
-
launchId: exports_external.string().min(1)
|
|
19652
|
-
}))
|
|
19653
|
-
}),
|
|
19654
|
-
exports_external.object({
|
|
19655
|
-
type: exports_external.literal("bot:added"),
|
|
19656
|
-
botId: exports_external.string().min(1),
|
|
19657
|
-
name: exports_external.string().optional(),
|
|
19658
|
-
discriminator: exports_external.string().optional(),
|
|
19659
|
-
description: exports_external.string().optional(),
|
|
19660
|
-
ownerName: exports_external.string().optional(),
|
|
19661
|
-
ownerDiscriminator: exports_external.string().optional()
|
|
19662
|
-
}),
|
|
19663
|
-
exports_external.object({
|
|
19664
|
-
type: exports_external.literal("bot:updated"),
|
|
19665
|
-
botId: exports_external.string().min(1),
|
|
19666
|
-
name: exports_external.string().optional(),
|
|
19667
|
-
discriminator: exports_external.string().optional(),
|
|
19668
|
-
description: exports_external.string().optional(),
|
|
19669
|
-
ownerName: exports_external.string().optional(),
|
|
19670
|
-
ownerDiscriminator: exports_external.string().optional()
|
|
19671
|
-
}),
|
|
19672
|
-
exports_external.object({
|
|
19673
|
-
type: exports_external.literal("bot:removed"),
|
|
19674
|
-
botId: exports_external.string().min(1)
|
|
19675
|
-
})
|
|
19676
|
-
]);
|
|
19677
|
-
// src/server/wsControlChannel.ts
|
|
19678
|
-
var DEFAULT_PING_INTERVAL_MS = 15000;
|
|
19679
|
-
var DEFAULT_PONG_TIMEOUT_MS = 30000;
|
|
19680
|
-
var DEFAULT_RECONNECT_BASE_MS = 500;
|
|
19681
|
-
var DEFAULT_RECONNECT_MAX_MS = 30000;
|
|
19682
|
-
function describeErr(err) {
|
|
19683
|
-
return err instanceof Error ? err.message : String(err);
|
|
19684
|
-
}
|
|
19685
|
-
|
|
19686
|
-
class WsControlChannel {
|
|
19687
|
-
opts;
|
|
19688
|
-
statusValue = "idle";
|
|
19689
|
-
commandCbs = [];
|
|
19690
|
-
resyncHooks = [];
|
|
19691
|
-
ws = null;
|
|
19692
|
-
attempt = 0;
|
|
19693
|
-
closedByUser = false;
|
|
19694
|
-
authRejected = false;
|
|
19695
|
-
pingTimer = null;
|
|
19696
|
-
pongDeadline = 0;
|
|
19697
|
-
resyncProvider = null;
|
|
19698
|
-
log;
|
|
19699
|
-
constructor(opts) {
|
|
19700
|
-
this.opts = opts;
|
|
19701
|
-
this.log = opts.logger ?? createLogger({ header: "@alook/daemon:ws" });
|
|
19702
|
-
}
|
|
19703
|
-
get status() {
|
|
19704
|
-
return this.statusValue;
|
|
19705
|
-
}
|
|
19706
|
-
connect() {
|
|
19707
|
-
this.closedByUser = false;
|
|
19708
|
-
this.authRejected = false;
|
|
19709
|
-
this.openSocket();
|
|
19710
|
-
}
|
|
19711
|
-
close() {
|
|
19712
|
-
this.closedByUser = true;
|
|
19713
|
-
this.clearHeartbeat();
|
|
19714
|
-
this.ws?.close();
|
|
19715
|
-
this.ws = null;
|
|
19716
|
-
this.statusValue = "closed";
|
|
19962
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/entity.js
|
|
19963
|
+
var entityKind = Symbol.for("drizzle:entityKind");
|
|
19964
|
+
var hasOwnEntityKind = Symbol.for("drizzle:hasOwnEntityKind");
|
|
19965
|
+
function is(value, type) {
|
|
19966
|
+
if (!value || typeof value !== "object") {
|
|
19967
|
+
return false;
|
|
19717
19968
|
}
|
|
19718
|
-
|
|
19719
|
-
|
|
19969
|
+
if (value instanceof type) {
|
|
19970
|
+
return true;
|
|
19720
19971
|
}
|
|
19721
|
-
|
|
19722
|
-
|
|
19972
|
+
if (!Object.prototype.hasOwnProperty.call(type, entityKind)) {
|
|
19973
|
+
throw new Error(`Class "${type.name ?? "<unknown>"}" doesn't look like a Drizzle entity. If this is incorrect and the class is provided by Drizzle, please report this as a bug.`);
|
|
19723
19974
|
}
|
|
19724
|
-
|
|
19725
|
-
|
|
19975
|
+
let cls = Object.getPrototypeOf(value).constructor;
|
|
19976
|
+
if (cls) {
|
|
19977
|
+
while (cls) {
|
|
19978
|
+
if (entityKind in cls && cls[entityKind] === type[entityKind]) {
|
|
19979
|
+
return true;
|
|
19980
|
+
}
|
|
19981
|
+
cls = Object.getPrototypeOf(cls);
|
|
19982
|
+
}
|
|
19726
19983
|
}
|
|
19727
|
-
|
|
19728
|
-
|
|
19984
|
+
return false;
|
|
19985
|
+
}
|
|
19986
|
+
|
|
19987
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/column.js
|
|
19988
|
+
class Column {
|
|
19989
|
+
constructor(table, config2) {
|
|
19990
|
+
this.table = table;
|
|
19991
|
+
this.config = config2;
|
|
19992
|
+
this.name = config2.name;
|
|
19993
|
+
this.keyAsName = config2.keyAsName;
|
|
19994
|
+
this.notNull = config2.notNull;
|
|
19995
|
+
this.default = config2.default;
|
|
19996
|
+
this.defaultFn = config2.defaultFn;
|
|
19997
|
+
this.onUpdateFn = config2.onUpdateFn;
|
|
19998
|
+
this.hasDefault = config2.hasDefault;
|
|
19999
|
+
this.primary = config2.primaryKey;
|
|
20000
|
+
this.isUnique = config2.isUnique;
|
|
20001
|
+
this.uniqueName = config2.uniqueName;
|
|
20002
|
+
this.uniqueType = config2.uniqueType;
|
|
20003
|
+
this.dataType = config2.dataType;
|
|
20004
|
+
this.columnType = config2.columnType;
|
|
20005
|
+
this.generated = config2.generated;
|
|
20006
|
+
this.generatedIdentity = config2.generatedIdentity;
|
|
20007
|
+
}
|
|
20008
|
+
static [entityKind] = "Column";
|
|
20009
|
+
name;
|
|
20010
|
+
keyAsName;
|
|
20011
|
+
primary;
|
|
20012
|
+
notNull;
|
|
20013
|
+
default;
|
|
20014
|
+
defaultFn;
|
|
20015
|
+
onUpdateFn;
|
|
20016
|
+
hasDefault;
|
|
20017
|
+
isUnique;
|
|
20018
|
+
uniqueName;
|
|
20019
|
+
uniqueType;
|
|
20020
|
+
dataType;
|
|
20021
|
+
columnType;
|
|
20022
|
+
enumValues = undefined;
|
|
20023
|
+
generated = undefined;
|
|
20024
|
+
generatedIdentity = undefined;
|
|
20025
|
+
config;
|
|
20026
|
+
mapFromDriverValue(value) {
|
|
20027
|
+
return value;
|
|
19729
20028
|
}
|
|
19730
|
-
|
|
19731
|
-
|
|
20029
|
+
mapToDriverValue(value) {
|
|
20030
|
+
return value;
|
|
19732
20031
|
}
|
|
19733
|
-
|
|
19734
|
-
this.
|
|
20032
|
+
shouldDisableInsert() {
|
|
20033
|
+
return this.config.generated !== undefined && this.config.generated.type !== "byDefault";
|
|
19735
20034
|
}
|
|
19736
|
-
|
|
19737
|
-
|
|
20035
|
+
}
|
|
20036
|
+
|
|
20037
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/column-builder.js
|
|
20038
|
+
class ColumnBuilder {
|
|
20039
|
+
static [entityKind] = "ColumnBuilder";
|
|
20040
|
+
config;
|
|
20041
|
+
constructor(name, dataType, columnType) {
|
|
20042
|
+
this.config = {
|
|
20043
|
+
name,
|
|
20044
|
+
keyAsName: name === "",
|
|
20045
|
+
notNull: false,
|
|
20046
|
+
default: undefined,
|
|
20047
|
+
hasDefault: false,
|
|
20048
|
+
primaryKey: false,
|
|
20049
|
+
isUnique: false,
|
|
20050
|
+
uniqueName: undefined,
|
|
20051
|
+
uniqueType: undefined,
|
|
20052
|
+
dataType,
|
|
20053
|
+
columnType,
|
|
20054
|
+
generated: undefined
|
|
20055
|
+
};
|
|
19738
20056
|
}
|
|
19739
|
-
|
|
19740
|
-
this
|
|
20057
|
+
$type() {
|
|
20058
|
+
return this;
|
|
19741
20059
|
}
|
|
19742
|
-
|
|
19743
|
-
this.
|
|
20060
|
+
notNull() {
|
|
20061
|
+
this.config.notNull = true;
|
|
20062
|
+
return this;
|
|
19744
20063
|
}
|
|
19745
|
-
|
|
19746
|
-
this.
|
|
20064
|
+
default(value) {
|
|
20065
|
+
this.config.default = value;
|
|
20066
|
+
this.config.hasDefault = true;
|
|
20067
|
+
return this;
|
|
19747
20068
|
}
|
|
19748
|
-
|
|
19749
|
-
this.
|
|
20069
|
+
$defaultFn(fn) {
|
|
20070
|
+
this.config.defaultFn = fn;
|
|
20071
|
+
this.config.hasDefault = true;
|
|
20072
|
+
return this;
|
|
19750
20073
|
}
|
|
19751
|
-
|
|
19752
|
-
|
|
20074
|
+
$default = this.$defaultFn;
|
|
20075
|
+
$onUpdateFn(fn) {
|
|
20076
|
+
this.config.onUpdateFn = fn;
|
|
20077
|
+
this.config.hasDefault = true;
|
|
20078
|
+
return this;
|
|
19753
20079
|
}
|
|
19754
|
-
|
|
19755
|
-
|
|
20080
|
+
$onUpdate = this.$onUpdateFn;
|
|
20081
|
+
primaryKey() {
|
|
20082
|
+
this.config.primaryKey = true;
|
|
20083
|
+
this.config.notNull = true;
|
|
20084
|
+
return this;
|
|
19756
20085
|
}
|
|
19757
|
-
|
|
19758
|
-
if (this.
|
|
19759
|
-
this.log.debug("frame dropped — socket not open", { type: frame.type });
|
|
20086
|
+
setName(name) {
|
|
20087
|
+
if (this.config.name !== "")
|
|
19760
20088
|
return;
|
|
19761
|
-
|
|
19762
|
-
this.ws.send(JSON.stringify(frame));
|
|
20089
|
+
this.config.name = name;
|
|
19763
20090
|
}
|
|
19764
|
-
|
|
20091
|
+
}
|
|
20092
|
+
|
|
20093
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/table.utils.js
|
|
20094
|
+
var TableName = Symbol.for("drizzle:Name");
|
|
20095
|
+
|
|
20096
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/tracing-utils.js
|
|
20097
|
+
function iife(fn, ...args) {
|
|
20098
|
+
return fn(...args);
|
|
20099
|
+
}
|
|
20100
|
+
|
|
20101
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/pg-core/unique-constraint.js
|
|
20102
|
+
function uniqueKeyName(table, columns) {
|
|
20103
|
+
return `${table[TableName]}_${columns.join("_")}_unique`;
|
|
20104
|
+
}
|
|
20105
|
+
|
|
20106
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/pg-core/columns/common.js
|
|
20107
|
+
class PgColumn extends Column {
|
|
20108
|
+
constructor(table, config2) {
|
|
20109
|
+
if (!config2.uniqueName) {
|
|
20110
|
+
config2.uniqueName = uniqueKeyName(table, [config2.name]);
|
|
20111
|
+
}
|
|
20112
|
+
super(table, config2);
|
|
20113
|
+
this.table = table;
|
|
20114
|
+
}
|
|
20115
|
+
static [entityKind] = "PgColumn";
|
|
20116
|
+
}
|
|
20117
|
+
|
|
20118
|
+
class ExtraConfigColumn extends PgColumn {
|
|
20119
|
+
static [entityKind] = "ExtraConfigColumn";
|
|
20120
|
+
getSQLType() {
|
|
20121
|
+
return this.getSQLType();
|
|
20122
|
+
}
|
|
20123
|
+
indexConfig = {
|
|
20124
|
+
order: this.config.order ?? "asc",
|
|
20125
|
+
nulls: this.config.nulls ?? "last",
|
|
20126
|
+
opClass: this.config.opClass
|
|
20127
|
+
};
|
|
20128
|
+
defaultConfig = {
|
|
20129
|
+
order: "asc",
|
|
20130
|
+
nulls: "last",
|
|
20131
|
+
opClass: undefined
|
|
20132
|
+
};
|
|
20133
|
+
asc() {
|
|
20134
|
+
this.indexConfig.order = "asc";
|
|
20135
|
+
return this;
|
|
20136
|
+
}
|
|
20137
|
+
desc() {
|
|
20138
|
+
this.indexConfig.order = "desc";
|
|
20139
|
+
return this;
|
|
20140
|
+
}
|
|
20141
|
+
nullsFirst() {
|
|
20142
|
+
this.indexConfig.nulls = "first";
|
|
20143
|
+
return this;
|
|
20144
|
+
}
|
|
20145
|
+
nullsLast() {
|
|
20146
|
+
this.indexConfig.nulls = "last";
|
|
20147
|
+
return this;
|
|
20148
|
+
}
|
|
20149
|
+
op(opClass) {
|
|
20150
|
+
this.indexConfig.opClass = opClass;
|
|
20151
|
+
return this;
|
|
20152
|
+
}
|
|
20153
|
+
}
|
|
20154
|
+
|
|
20155
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/pg-core/columns/enum.js
|
|
20156
|
+
class PgEnumObjectColumn extends PgColumn {
|
|
20157
|
+
static [entityKind] = "PgEnumObjectColumn";
|
|
20158
|
+
enum;
|
|
20159
|
+
enumValues = this.config.enum.enumValues;
|
|
20160
|
+
constructor(table, config2) {
|
|
20161
|
+
super(table, config2);
|
|
20162
|
+
this.enum = config2.enum;
|
|
20163
|
+
}
|
|
20164
|
+
getSQLType() {
|
|
20165
|
+
return this.enum.enumName;
|
|
20166
|
+
}
|
|
20167
|
+
}
|
|
20168
|
+
var isPgEnumSym = Symbol.for("drizzle:isPgEnum");
|
|
20169
|
+
function isPgEnum(obj) {
|
|
20170
|
+
return !!obj && typeof obj === "function" && isPgEnumSym in obj && obj[isPgEnumSym] === true;
|
|
20171
|
+
}
|
|
20172
|
+
class PgEnumColumn extends PgColumn {
|
|
20173
|
+
static [entityKind] = "PgEnumColumn";
|
|
20174
|
+
enum = this.config.enum;
|
|
20175
|
+
enumValues = this.config.enum.enumValues;
|
|
20176
|
+
constructor(table, config2) {
|
|
20177
|
+
super(table, config2);
|
|
20178
|
+
this.enum = config2.enum;
|
|
20179
|
+
}
|
|
20180
|
+
getSQLType() {
|
|
20181
|
+
return this.enum.enumName;
|
|
20182
|
+
}
|
|
20183
|
+
}
|
|
20184
|
+
|
|
20185
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/subquery.js
|
|
20186
|
+
class Subquery {
|
|
20187
|
+
static [entityKind] = "Subquery";
|
|
20188
|
+
constructor(sql, fields, alias, isWith = false, usedTables = []) {
|
|
20189
|
+
this._ = {
|
|
20190
|
+
brand: "Subquery",
|
|
20191
|
+
sql,
|
|
20192
|
+
selectedFields: fields,
|
|
20193
|
+
alias,
|
|
20194
|
+
isWith,
|
|
20195
|
+
usedTables
|
|
20196
|
+
};
|
|
20197
|
+
}
|
|
20198
|
+
}
|
|
20199
|
+
|
|
20200
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/version.js
|
|
20201
|
+
var version2 = "0.45.2";
|
|
20202
|
+
|
|
20203
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/tracing.js
|
|
20204
|
+
var otel;
|
|
20205
|
+
var rawTracer;
|
|
20206
|
+
var tracer = {
|
|
20207
|
+
startActiveSpan(name, fn) {
|
|
20208
|
+
if (!otel) {
|
|
20209
|
+
return fn();
|
|
20210
|
+
}
|
|
20211
|
+
if (!rawTracer) {
|
|
20212
|
+
rawTracer = otel.trace.getTracer("drizzle-orm", version2);
|
|
20213
|
+
}
|
|
20214
|
+
return iife((otel2, rawTracer2) => rawTracer2.startActiveSpan(name, (span) => {
|
|
20215
|
+
try {
|
|
20216
|
+
return fn(span);
|
|
20217
|
+
} catch (e) {
|
|
20218
|
+
span.setStatus({
|
|
20219
|
+
code: otel2.SpanStatusCode.ERROR,
|
|
20220
|
+
message: e instanceof Error ? e.message : "Unknown error"
|
|
20221
|
+
});
|
|
20222
|
+
throw e;
|
|
20223
|
+
} finally {
|
|
20224
|
+
span.end();
|
|
20225
|
+
}
|
|
20226
|
+
}), otel, rawTracer);
|
|
20227
|
+
}
|
|
20228
|
+
};
|
|
20229
|
+
|
|
20230
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/view-common.js
|
|
20231
|
+
var ViewBaseConfig = Symbol.for("drizzle:ViewBaseConfig");
|
|
20232
|
+
|
|
20233
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/table.js
|
|
20234
|
+
var Schema = Symbol.for("drizzle:Schema");
|
|
20235
|
+
var Columns = Symbol.for("drizzle:Columns");
|
|
20236
|
+
var ExtraConfigColumns = Symbol.for("drizzle:ExtraConfigColumns");
|
|
20237
|
+
var OriginalName = Symbol.for("drizzle:OriginalName");
|
|
20238
|
+
var BaseName = Symbol.for("drizzle:BaseName");
|
|
20239
|
+
var IsAlias = Symbol.for("drizzle:IsAlias");
|
|
20240
|
+
var ExtraConfigBuilder = Symbol.for("drizzle:ExtraConfigBuilder");
|
|
20241
|
+
var IsDrizzleTable = Symbol.for("drizzle:IsDrizzleTable");
|
|
20242
|
+
|
|
20243
|
+
class Table {
|
|
20244
|
+
static [entityKind] = "Table";
|
|
20245
|
+
static Symbol = {
|
|
20246
|
+
Name: TableName,
|
|
20247
|
+
Schema,
|
|
20248
|
+
OriginalName,
|
|
20249
|
+
Columns,
|
|
20250
|
+
ExtraConfigColumns,
|
|
20251
|
+
BaseName,
|
|
20252
|
+
IsAlias,
|
|
20253
|
+
ExtraConfigBuilder
|
|
20254
|
+
};
|
|
20255
|
+
[TableName];
|
|
20256
|
+
[OriginalName];
|
|
20257
|
+
[Schema];
|
|
20258
|
+
[Columns];
|
|
20259
|
+
[ExtraConfigColumns];
|
|
20260
|
+
[BaseName];
|
|
20261
|
+
[IsAlias] = false;
|
|
20262
|
+
[IsDrizzleTable] = true;
|
|
20263
|
+
[ExtraConfigBuilder] = undefined;
|
|
20264
|
+
constructor(name, schema, baseName) {
|
|
20265
|
+
this[TableName] = this[OriginalName] = name;
|
|
20266
|
+
this[Schema] = schema;
|
|
20267
|
+
this[BaseName] = baseName;
|
|
20268
|
+
}
|
|
20269
|
+
}
|
|
20270
|
+
|
|
20271
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sql/sql.js
|
|
20272
|
+
function isSQLWrapper(value) {
|
|
20273
|
+
return value !== null && value !== undefined && typeof value.getSQL === "function";
|
|
20274
|
+
}
|
|
20275
|
+
function mergeQueries(queries) {
|
|
20276
|
+
const result = { sql: "", params: [] };
|
|
20277
|
+
for (const query of queries) {
|
|
20278
|
+
result.sql += query.sql;
|
|
20279
|
+
result.params.push(...query.params);
|
|
20280
|
+
if (query.typings?.length) {
|
|
20281
|
+
if (!result.typings) {
|
|
20282
|
+
result.typings = [];
|
|
20283
|
+
}
|
|
20284
|
+
result.typings.push(...query.typings);
|
|
20285
|
+
}
|
|
20286
|
+
}
|
|
20287
|
+
return result;
|
|
20288
|
+
}
|
|
20289
|
+
|
|
20290
|
+
class StringChunk {
|
|
20291
|
+
static [entityKind] = "StringChunk";
|
|
20292
|
+
value;
|
|
20293
|
+
constructor(value) {
|
|
20294
|
+
this.value = Array.isArray(value) ? value : [value];
|
|
20295
|
+
}
|
|
20296
|
+
getSQL() {
|
|
20297
|
+
return new SQL([this]);
|
|
20298
|
+
}
|
|
20299
|
+
}
|
|
20300
|
+
|
|
20301
|
+
class SQL {
|
|
20302
|
+
constructor(queryChunks) {
|
|
20303
|
+
this.queryChunks = queryChunks;
|
|
20304
|
+
for (const chunk of queryChunks) {
|
|
20305
|
+
if (is(chunk, Table)) {
|
|
20306
|
+
const schemaName = chunk[Table.Symbol.Schema];
|
|
20307
|
+
this.usedTables.push(schemaName === undefined ? chunk[Table.Symbol.Name] : schemaName + "." + chunk[Table.Symbol.Name]);
|
|
20308
|
+
}
|
|
20309
|
+
}
|
|
20310
|
+
}
|
|
20311
|
+
static [entityKind] = "SQL";
|
|
20312
|
+
decoder = noopDecoder;
|
|
20313
|
+
shouldInlineParams = false;
|
|
20314
|
+
usedTables = [];
|
|
20315
|
+
append(query) {
|
|
20316
|
+
this.queryChunks.push(...query.queryChunks);
|
|
20317
|
+
return this;
|
|
20318
|
+
}
|
|
20319
|
+
toQuery(config2) {
|
|
20320
|
+
return tracer.startActiveSpan("drizzle.buildSQL", (span) => {
|
|
20321
|
+
const query = this.buildQueryFromSourceParams(this.queryChunks, config2);
|
|
20322
|
+
span?.setAttributes({
|
|
20323
|
+
"drizzle.query.text": query.sql,
|
|
20324
|
+
"drizzle.query.params": JSON.stringify(query.params)
|
|
20325
|
+
});
|
|
20326
|
+
return query;
|
|
20327
|
+
});
|
|
20328
|
+
}
|
|
20329
|
+
buildQueryFromSourceParams(chunks, _config) {
|
|
20330
|
+
const config2 = Object.assign({}, _config, {
|
|
20331
|
+
inlineParams: _config.inlineParams || this.shouldInlineParams,
|
|
20332
|
+
paramStartIndex: _config.paramStartIndex || { value: 0 }
|
|
20333
|
+
});
|
|
20334
|
+
const {
|
|
20335
|
+
casing,
|
|
20336
|
+
escapeName,
|
|
20337
|
+
escapeParam,
|
|
20338
|
+
prepareTyping,
|
|
20339
|
+
inlineParams,
|
|
20340
|
+
paramStartIndex
|
|
20341
|
+
} = config2;
|
|
20342
|
+
return mergeQueries(chunks.map((chunk) => {
|
|
20343
|
+
if (is(chunk, StringChunk)) {
|
|
20344
|
+
return { sql: chunk.value.join(""), params: [] };
|
|
20345
|
+
}
|
|
20346
|
+
if (is(chunk, Name)) {
|
|
20347
|
+
return { sql: escapeName(chunk.value), params: [] };
|
|
20348
|
+
}
|
|
20349
|
+
if (chunk === undefined) {
|
|
20350
|
+
return { sql: "", params: [] };
|
|
20351
|
+
}
|
|
20352
|
+
if (Array.isArray(chunk)) {
|
|
20353
|
+
const result = [new StringChunk("(")];
|
|
20354
|
+
for (const [i, p] of chunk.entries()) {
|
|
20355
|
+
result.push(p);
|
|
20356
|
+
if (i < chunk.length - 1) {
|
|
20357
|
+
result.push(new StringChunk(", "));
|
|
20358
|
+
}
|
|
20359
|
+
}
|
|
20360
|
+
result.push(new StringChunk(")"));
|
|
20361
|
+
return this.buildQueryFromSourceParams(result, config2);
|
|
20362
|
+
}
|
|
20363
|
+
if (is(chunk, SQL)) {
|
|
20364
|
+
return this.buildQueryFromSourceParams(chunk.queryChunks, {
|
|
20365
|
+
...config2,
|
|
20366
|
+
inlineParams: inlineParams || chunk.shouldInlineParams
|
|
20367
|
+
});
|
|
20368
|
+
}
|
|
20369
|
+
if (is(chunk, Table)) {
|
|
20370
|
+
const schemaName = chunk[Table.Symbol.Schema];
|
|
20371
|
+
const tableName = chunk[Table.Symbol.Name];
|
|
20372
|
+
return {
|
|
20373
|
+
sql: schemaName === undefined || chunk[IsAlias] ? escapeName(tableName) : escapeName(schemaName) + "." + escapeName(tableName),
|
|
20374
|
+
params: []
|
|
20375
|
+
};
|
|
20376
|
+
}
|
|
20377
|
+
if (is(chunk, Column)) {
|
|
20378
|
+
const columnName = casing.getColumnCasing(chunk);
|
|
20379
|
+
if (_config.invokeSource === "indexes") {
|
|
20380
|
+
return { sql: escapeName(columnName), params: [] };
|
|
20381
|
+
}
|
|
20382
|
+
const schemaName = chunk.table[Table.Symbol.Schema];
|
|
20383
|
+
return {
|
|
20384
|
+
sql: chunk.table[IsAlias] || schemaName === undefined ? escapeName(chunk.table[Table.Symbol.Name]) + "." + escapeName(columnName) : escapeName(schemaName) + "." + escapeName(chunk.table[Table.Symbol.Name]) + "." + escapeName(columnName),
|
|
20385
|
+
params: []
|
|
20386
|
+
};
|
|
20387
|
+
}
|
|
20388
|
+
if (is(chunk, View)) {
|
|
20389
|
+
const schemaName = chunk[ViewBaseConfig].schema;
|
|
20390
|
+
const viewName = chunk[ViewBaseConfig].name;
|
|
20391
|
+
return {
|
|
20392
|
+
sql: schemaName === undefined || chunk[ViewBaseConfig].isAlias ? escapeName(viewName) : escapeName(schemaName) + "." + escapeName(viewName),
|
|
20393
|
+
params: []
|
|
20394
|
+
};
|
|
20395
|
+
}
|
|
20396
|
+
if (is(chunk, Param)) {
|
|
20397
|
+
if (is(chunk.value, Placeholder)) {
|
|
20398
|
+
return { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ["none"] };
|
|
20399
|
+
}
|
|
20400
|
+
const mappedValue = chunk.value === null ? null : chunk.encoder.mapToDriverValue(chunk.value);
|
|
20401
|
+
if (is(mappedValue, SQL)) {
|
|
20402
|
+
return this.buildQueryFromSourceParams([mappedValue], config2);
|
|
20403
|
+
}
|
|
20404
|
+
if (inlineParams) {
|
|
20405
|
+
return { sql: this.mapInlineParam(mappedValue, config2), params: [] };
|
|
20406
|
+
}
|
|
20407
|
+
let typings = ["none"];
|
|
20408
|
+
if (prepareTyping) {
|
|
20409
|
+
typings = [prepareTyping(chunk.encoder)];
|
|
20410
|
+
}
|
|
20411
|
+
return { sql: escapeParam(paramStartIndex.value++, mappedValue), params: [mappedValue], typings };
|
|
20412
|
+
}
|
|
20413
|
+
if (is(chunk, Placeholder)) {
|
|
20414
|
+
return { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ["none"] };
|
|
20415
|
+
}
|
|
20416
|
+
if (is(chunk, SQL.Aliased) && chunk.fieldAlias !== undefined) {
|
|
20417
|
+
return { sql: escapeName(chunk.fieldAlias), params: [] };
|
|
20418
|
+
}
|
|
20419
|
+
if (is(chunk, Subquery)) {
|
|
20420
|
+
if (chunk._.isWith) {
|
|
20421
|
+
return { sql: escapeName(chunk._.alias), params: [] };
|
|
20422
|
+
}
|
|
20423
|
+
return this.buildQueryFromSourceParams([
|
|
20424
|
+
new StringChunk("("),
|
|
20425
|
+
chunk._.sql,
|
|
20426
|
+
new StringChunk(") "),
|
|
20427
|
+
new Name(chunk._.alias)
|
|
20428
|
+
], config2);
|
|
20429
|
+
}
|
|
20430
|
+
if (isPgEnum(chunk)) {
|
|
20431
|
+
if (chunk.schema) {
|
|
20432
|
+
return { sql: escapeName(chunk.schema) + "." + escapeName(chunk.enumName), params: [] };
|
|
20433
|
+
}
|
|
20434
|
+
return { sql: escapeName(chunk.enumName), params: [] };
|
|
20435
|
+
}
|
|
20436
|
+
if (isSQLWrapper(chunk)) {
|
|
20437
|
+
if (chunk.shouldOmitSQLParens?.()) {
|
|
20438
|
+
return this.buildQueryFromSourceParams([chunk.getSQL()], config2);
|
|
20439
|
+
}
|
|
20440
|
+
return this.buildQueryFromSourceParams([
|
|
20441
|
+
new StringChunk("("),
|
|
20442
|
+
chunk.getSQL(),
|
|
20443
|
+
new StringChunk(")")
|
|
20444
|
+
], config2);
|
|
20445
|
+
}
|
|
20446
|
+
if (inlineParams) {
|
|
20447
|
+
return { sql: this.mapInlineParam(chunk, config2), params: [] };
|
|
20448
|
+
}
|
|
20449
|
+
return { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ["none"] };
|
|
20450
|
+
}));
|
|
20451
|
+
}
|
|
20452
|
+
mapInlineParam(chunk, { escapeString }) {
|
|
20453
|
+
if (chunk === null) {
|
|
20454
|
+
return "null";
|
|
20455
|
+
}
|
|
20456
|
+
if (typeof chunk === "number" || typeof chunk === "boolean") {
|
|
20457
|
+
return chunk.toString();
|
|
20458
|
+
}
|
|
20459
|
+
if (typeof chunk === "string") {
|
|
20460
|
+
return escapeString(chunk);
|
|
20461
|
+
}
|
|
20462
|
+
if (typeof chunk === "object") {
|
|
20463
|
+
const mappedValueAsString = chunk.toString();
|
|
20464
|
+
if (mappedValueAsString === "[object Object]") {
|
|
20465
|
+
return escapeString(JSON.stringify(chunk));
|
|
20466
|
+
}
|
|
20467
|
+
return escapeString(mappedValueAsString);
|
|
20468
|
+
}
|
|
20469
|
+
throw new Error("Unexpected param value: " + chunk);
|
|
20470
|
+
}
|
|
20471
|
+
getSQL() {
|
|
20472
|
+
return this;
|
|
20473
|
+
}
|
|
20474
|
+
as(alias) {
|
|
20475
|
+
if (alias === undefined) {
|
|
20476
|
+
return this;
|
|
20477
|
+
}
|
|
20478
|
+
return new SQL.Aliased(this, alias);
|
|
20479
|
+
}
|
|
20480
|
+
mapWith(decoder) {
|
|
20481
|
+
this.decoder = typeof decoder === "function" ? { mapFromDriverValue: decoder } : decoder;
|
|
20482
|
+
return this;
|
|
20483
|
+
}
|
|
20484
|
+
inlineParams() {
|
|
20485
|
+
this.shouldInlineParams = true;
|
|
20486
|
+
return this;
|
|
20487
|
+
}
|
|
20488
|
+
if(condition) {
|
|
20489
|
+
return condition ? this : undefined;
|
|
20490
|
+
}
|
|
20491
|
+
}
|
|
20492
|
+
|
|
20493
|
+
class Name {
|
|
20494
|
+
constructor(value) {
|
|
20495
|
+
this.value = value;
|
|
20496
|
+
}
|
|
20497
|
+
static [entityKind] = "Name";
|
|
20498
|
+
brand;
|
|
20499
|
+
getSQL() {
|
|
20500
|
+
return new SQL([this]);
|
|
20501
|
+
}
|
|
20502
|
+
}
|
|
20503
|
+
var noopDecoder = {
|
|
20504
|
+
mapFromDriverValue: (value) => value
|
|
20505
|
+
};
|
|
20506
|
+
var noopEncoder = {
|
|
20507
|
+
mapToDriverValue: (value) => value
|
|
20508
|
+
};
|
|
20509
|
+
var noopMapper = {
|
|
20510
|
+
...noopDecoder,
|
|
20511
|
+
...noopEncoder
|
|
20512
|
+
};
|
|
20513
|
+
|
|
20514
|
+
class Param {
|
|
20515
|
+
constructor(value, encoder = noopEncoder) {
|
|
20516
|
+
this.value = value;
|
|
20517
|
+
this.encoder = encoder;
|
|
20518
|
+
}
|
|
20519
|
+
static [entityKind] = "Param";
|
|
20520
|
+
brand;
|
|
20521
|
+
getSQL() {
|
|
20522
|
+
return new SQL([this]);
|
|
20523
|
+
}
|
|
20524
|
+
}
|
|
20525
|
+
function sql(strings, ...params) {
|
|
20526
|
+
const queryChunks = [];
|
|
20527
|
+
if (params.length > 0 || strings.length > 0 && strings[0] !== "") {
|
|
20528
|
+
queryChunks.push(new StringChunk(strings[0]));
|
|
20529
|
+
}
|
|
20530
|
+
for (const [paramIndex, param2] of params.entries()) {
|
|
20531
|
+
queryChunks.push(param2, new StringChunk(strings[paramIndex + 1]));
|
|
20532
|
+
}
|
|
20533
|
+
return new SQL(queryChunks);
|
|
20534
|
+
}
|
|
20535
|
+
((sql2) => {
|
|
20536
|
+
function empty() {
|
|
20537
|
+
return new SQL([]);
|
|
20538
|
+
}
|
|
20539
|
+
sql2.empty = empty;
|
|
20540
|
+
function fromList(list) {
|
|
20541
|
+
return new SQL(list);
|
|
20542
|
+
}
|
|
20543
|
+
sql2.fromList = fromList;
|
|
20544
|
+
function raw(str) {
|
|
20545
|
+
return new SQL([new StringChunk(str)]);
|
|
20546
|
+
}
|
|
20547
|
+
sql2.raw = raw;
|
|
20548
|
+
function join9(chunks, separator) {
|
|
20549
|
+
const result = [];
|
|
20550
|
+
for (const [i, chunk] of chunks.entries()) {
|
|
20551
|
+
if (i > 0 && separator !== undefined) {
|
|
20552
|
+
result.push(separator);
|
|
20553
|
+
}
|
|
20554
|
+
result.push(chunk);
|
|
20555
|
+
}
|
|
20556
|
+
return new SQL(result);
|
|
20557
|
+
}
|
|
20558
|
+
sql2.join = join9;
|
|
20559
|
+
function identifier(value) {
|
|
20560
|
+
return new Name(value);
|
|
20561
|
+
}
|
|
20562
|
+
sql2.identifier = identifier;
|
|
20563
|
+
function placeholder2(name2) {
|
|
20564
|
+
return new Placeholder(name2);
|
|
20565
|
+
}
|
|
20566
|
+
sql2.placeholder = placeholder2;
|
|
20567
|
+
function param2(value, encoder) {
|
|
20568
|
+
return new Param(value, encoder);
|
|
20569
|
+
}
|
|
20570
|
+
sql2.param = param2;
|
|
20571
|
+
})(sql || (sql = {}));
|
|
20572
|
+
((SQL2) => {
|
|
20573
|
+
|
|
20574
|
+
class Aliased {
|
|
20575
|
+
constructor(sql2, fieldAlias) {
|
|
20576
|
+
this.sql = sql2;
|
|
20577
|
+
this.fieldAlias = fieldAlias;
|
|
20578
|
+
}
|
|
20579
|
+
static [entityKind] = "SQL.Aliased";
|
|
20580
|
+
isSelectionField = false;
|
|
20581
|
+
getSQL() {
|
|
20582
|
+
return this.sql;
|
|
20583
|
+
}
|
|
20584
|
+
clone() {
|
|
20585
|
+
return new Aliased(this.sql, this.fieldAlias);
|
|
20586
|
+
}
|
|
20587
|
+
}
|
|
20588
|
+
SQL2.Aliased = Aliased;
|
|
20589
|
+
})(SQL || (SQL = {}));
|
|
20590
|
+
|
|
20591
|
+
class Placeholder {
|
|
20592
|
+
constructor(name2) {
|
|
20593
|
+
this.name = name2;
|
|
20594
|
+
}
|
|
20595
|
+
static [entityKind] = "Placeholder";
|
|
20596
|
+
getSQL() {
|
|
20597
|
+
return new SQL([this]);
|
|
20598
|
+
}
|
|
20599
|
+
}
|
|
20600
|
+
var IsDrizzleView = Symbol.for("drizzle:IsDrizzleView");
|
|
20601
|
+
|
|
20602
|
+
class View {
|
|
20603
|
+
static [entityKind] = "View";
|
|
20604
|
+
[ViewBaseConfig];
|
|
20605
|
+
[IsDrizzleView] = true;
|
|
20606
|
+
constructor({ name: name2, schema, selectedFields, query }) {
|
|
20607
|
+
this[ViewBaseConfig] = {
|
|
20608
|
+
name: name2,
|
|
20609
|
+
originalName: name2,
|
|
20610
|
+
schema,
|
|
20611
|
+
selectedFields,
|
|
20612
|
+
query,
|
|
20613
|
+
isExisting: !query,
|
|
20614
|
+
isAlias: false
|
|
20615
|
+
};
|
|
20616
|
+
}
|
|
20617
|
+
getSQL() {
|
|
20618
|
+
return new SQL([this]);
|
|
20619
|
+
}
|
|
20620
|
+
}
|
|
20621
|
+
Column.prototype.getSQL = function() {
|
|
20622
|
+
return new SQL([this]);
|
|
20623
|
+
};
|
|
20624
|
+
Table.prototype.getSQL = function() {
|
|
20625
|
+
return new SQL([this]);
|
|
20626
|
+
};
|
|
20627
|
+
Subquery.prototype.getSQL = function() {
|
|
20628
|
+
return new SQL([this]);
|
|
20629
|
+
};
|
|
20630
|
+
|
|
20631
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/checks.js
|
|
20632
|
+
class CheckBuilder {
|
|
20633
|
+
constructor(name, value) {
|
|
20634
|
+
this.name = name;
|
|
20635
|
+
this.value = value;
|
|
20636
|
+
}
|
|
20637
|
+
static [entityKind] = "SQLiteCheckBuilder";
|
|
20638
|
+
brand;
|
|
20639
|
+
build(table) {
|
|
20640
|
+
return new Check(table, this);
|
|
20641
|
+
}
|
|
20642
|
+
}
|
|
20643
|
+
|
|
20644
|
+
class Check {
|
|
20645
|
+
constructor(table, builder) {
|
|
20646
|
+
this.table = table;
|
|
20647
|
+
this.name = builder.name;
|
|
20648
|
+
this.value = builder.value;
|
|
20649
|
+
}
|
|
20650
|
+
static [entityKind] = "SQLiteCheck";
|
|
20651
|
+
name;
|
|
20652
|
+
value;
|
|
20653
|
+
}
|
|
20654
|
+
function check2(name, value) {
|
|
20655
|
+
return new CheckBuilder(name, value);
|
|
20656
|
+
}
|
|
20657
|
+
|
|
20658
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/utils.js
|
|
20659
|
+
function getColumnNameAndConfig(a, b) {
|
|
20660
|
+
return {
|
|
20661
|
+
name: typeof a === "string" && a.length > 0 ? a : "",
|
|
20662
|
+
config: typeof a === "object" ? a : b
|
|
20663
|
+
};
|
|
20664
|
+
}
|
|
20665
|
+
var textDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder;
|
|
20666
|
+
|
|
20667
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/foreign-keys.js
|
|
20668
|
+
class ForeignKeyBuilder {
|
|
20669
|
+
static [entityKind] = "SQLiteForeignKeyBuilder";
|
|
20670
|
+
reference;
|
|
20671
|
+
_onUpdate;
|
|
20672
|
+
_onDelete;
|
|
20673
|
+
constructor(config2, actions) {
|
|
20674
|
+
this.reference = () => {
|
|
20675
|
+
const { name, columns, foreignColumns } = config2();
|
|
20676
|
+
return { name, columns, foreignTable: foreignColumns[0].table, foreignColumns };
|
|
20677
|
+
};
|
|
20678
|
+
if (actions) {
|
|
20679
|
+
this._onUpdate = actions.onUpdate;
|
|
20680
|
+
this._onDelete = actions.onDelete;
|
|
20681
|
+
}
|
|
20682
|
+
}
|
|
20683
|
+
onUpdate(action) {
|
|
20684
|
+
this._onUpdate = action;
|
|
20685
|
+
return this;
|
|
20686
|
+
}
|
|
20687
|
+
onDelete(action) {
|
|
20688
|
+
this._onDelete = action;
|
|
20689
|
+
return this;
|
|
20690
|
+
}
|
|
20691
|
+
build(table) {
|
|
20692
|
+
return new ForeignKey(table, this);
|
|
20693
|
+
}
|
|
20694
|
+
}
|
|
20695
|
+
|
|
20696
|
+
class ForeignKey {
|
|
20697
|
+
constructor(table, builder) {
|
|
20698
|
+
this.table = table;
|
|
20699
|
+
this.reference = builder.reference;
|
|
20700
|
+
this.onUpdate = builder._onUpdate;
|
|
20701
|
+
this.onDelete = builder._onDelete;
|
|
20702
|
+
}
|
|
20703
|
+
static [entityKind] = "SQLiteForeignKey";
|
|
20704
|
+
reference;
|
|
20705
|
+
onUpdate;
|
|
20706
|
+
onDelete;
|
|
20707
|
+
getName() {
|
|
20708
|
+
const { name, columns, foreignColumns } = this.reference();
|
|
20709
|
+
const columnNames = columns.map((column) => column.name);
|
|
20710
|
+
const foreignColumnNames = foreignColumns.map((column) => column.name);
|
|
20711
|
+
const chunks = [
|
|
20712
|
+
this.table[TableName],
|
|
20713
|
+
...columnNames,
|
|
20714
|
+
foreignColumns[0].table[TableName],
|
|
20715
|
+
...foreignColumnNames
|
|
20716
|
+
];
|
|
20717
|
+
return name ?? `${chunks.join("_")}_fk`;
|
|
20718
|
+
}
|
|
20719
|
+
}
|
|
20720
|
+
function foreignKey(config2) {
|
|
20721
|
+
function mappedConfig() {
|
|
20722
|
+
if (typeof config2 === "function") {
|
|
20723
|
+
const { name, columns, foreignColumns } = config2();
|
|
20724
|
+
return {
|
|
20725
|
+
name,
|
|
20726
|
+
columns,
|
|
20727
|
+
foreignColumns
|
|
20728
|
+
};
|
|
20729
|
+
}
|
|
20730
|
+
return config2;
|
|
20731
|
+
}
|
|
20732
|
+
return new ForeignKeyBuilder(mappedConfig);
|
|
20733
|
+
}
|
|
20734
|
+
|
|
20735
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/unique-constraint.js
|
|
20736
|
+
function uniqueKeyName2(table, columns) {
|
|
20737
|
+
return `${table[TableName]}_${columns.join("_")}_unique`;
|
|
20738
|
+
}
|
|
20739
|
+
function unique(name) {
|
|
20740
|
+
return new UniqueOnConstraintBuilder(name);
|
|
20741
|
+
}
|
|
20742
|
+
|
|
20743
|
+
class UniqueConstraintBuilder {
|
|
20744
|
+
constructor(columns, name) {
|
|
20745
|
+
this.name = name;
|
|
20746
|
+
this.columns = columns;
|
|
20747
|
+
}
|
|
20748
|
+
static [entityKind] = "SQLiteUniqueConstraintBuilder";
|
|
20749
|
+
columns;
|
|
20750
|
+
build(table) {
|
|
20751
|
+
return new UniqueConstraint(table, this.columns, this.name);
|
|
20752
|
+
}
|
|
20753
|
+
}
|
|
20754
|
+
|
|
20755
|
+
class UniqueOnConstraintBuilder {
|
|
20756
|
+
static [entityKind] = "SQLiteUniqueOnConstraintBuilder";
|
|
20757
|
+
name;
|
|
20758
|
+
constructor(name) {
|
|
20759
|
+
this.name = name;
|
|
20760
|
+
}
|
|
20761
|
+
on(...columns) {
|
|
20762
|
+
return new UniqueConstraintBuilder(columns, this.name);
|
|
20763
|
+
}
|
|
20764
|
+
}
|
|
20765
|
+
|
|
20766
|
+
class UniqueConstraint {
|
|
20767
|
+
constructor(table, columns, name) {
|
|
20768
|
+
this.table = table;
|
|
20769
|
+
this.columns = columns;
|
|
20770
|
+
this.name = name ?? uniqueKeyName2(this.table, this.columns.map((column) => column.name));
|
|
20771
|
+
}
|
|
20772
|
+
static [entityKind] = "SQLiteUniqueConstraint";
|
|
20773
|
+
columns;
|
|
20774
|
+
name;
|
|
20775
|
+
getName() {
|
|
20776
|
+
return this.name;
|
|
20777
|
+
}
|
|
20778
|
+
}
|
|
20779
|
+
|
|
20780
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/columns/common.js
|
|
20781
|
+
class SQLiteColumnBuilder extends ColumnBuilder {
|
|
20782
|
+
static [entityKind] = "SQLiteColumnBuilder";
|
|
20783
|
+
foreignKeyConfigs = [];
|
|
20784
|
+
references(ref, actions = {}) {
|
|
20785
|
+
this.foreignKeyConfigs.push({ ref, actions });
|
|
20786
|
+
return this;
|
|
20787
|
+
}
|
|
20788
|
+
unique(name) {
|
|
20789
|
+
this.config.isUnique = true;
|
|
20790
|
+
this.config.uniqueName = name;
|
|
20791
|
+
return this;
|
|
20792
|
+
}
|
|
20793
|
+
generatedAlwaysAs(as, config2) {
|
|
20794
|
+
this.config.generated = {
|
|
20795
|
+
as,
|
|
20796
|
+
type: "always",
|
|
20797
|
+
mode: config2?.mode ?? "virtual"
|
|
20798
|
+
};
|
|
20799
|
+
return this;
|
|
20800
|
+
}
|
|
20801
|
+
buildForeignKeys(column, table) {
|
|
20802
|
+
return this.foreignKeyConfigs.map(({ ref, actions }) => {
|
|
20803
|
+
return ((ref2, actions2) => {
|
|
20804
|
+
const builder = new ForeignKeyBuilder(() => {
|
|
20805
|
+
const foreignColumn = ref2();
|
|
20806
|
+
return { columns: [column], foreignColumns: [foreignColumn] };
|
|
20807
|
+
});
|
|
20808
|
+
if (actions2.onUpdate) {
|
|
20809
|
+
builder.onUpdate(actions2.onUpdate);
|
|
20810
|
+
}
|
|
20811
|
+
if (actions2.onDelete) {
|
|
20812
|
+
builder.onDelete(actions2.onDelete);
|
|
20813
|
+
}
|
|
20814
|
+
return builder.build(table);
|
|
20815
|
+
})(ref, actions);
|
|
20816
|
+
});
|
|
20817
|
+
}
|
|
20818
|
+
}
|
|
20819
|
+
|
|
20820
|
+
class SQLiteColumn extends Column {
|
|
20821
|
+
constructor(table, config2) {
|
|
20822
|
+
if (!config2.uniqueName) {
|
|
20823
|
+
config2.uniqueName = uniqueKeyName2(table, [config2.name]);
|
|
20824
|
+
}
|
|
20825
|
+
super(table, config2);
|
|
20826
|
+
this.table = table;
|
|
20827
|
+
}
|
|
20828
|
+
static [entityKind] = "SQLiteColumn";
|
|
20829
|
+
}
|
|
20830
|
+
|
|
20831
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/columns/blob.js
|
|
20832
|
+
class SQLiteBigIntBuilder extends SQLiteColumnBuilder {
|
|
20833
|
+
static [entityKind] = "SQLiteBigIntBuilder";
|
|
20834
|
+
constructor(name) {
|
|
20835
|
+
super(name, "bigint", "SQLiteBigInt");
|
|
20836
|
+
}
|
|
20837
|
+
build(table) {
|
|
20838
|
+
return new SQLiteBigInt(table, this.config);
|
|
20839
|
+
}
|
|
20840
|
+
}
|
|
20841
|
+
|
|
20842
|
+
class SQLiteBigInt extends SQLiteColumn {
|
|
20843
|
+
static [entityKind] = "SQLiteBigInt";
|
|
20844
|
+
getSQLType() {
|
|
20845
|
+
return "blob";
|
|
20846
|
+
}
|
|
20847
|
+
mapFromDriverValue(value) {
|
|
20848
|
+
if (typeof Buffer !== "undefined" && Buffer.from) {
|
|
20849
|
+
const buf = Buffer.isBuffer(value) ? value : value instanceof ArrayBuffer ? Buffer.from(value) : value.buffer ? Buffer.from(value.buffer, value.byteOffset, value.byteLength) : Buffer.from(value);
|
|
20850
|
+
return BigInt(buf.toString("utf8"));
|
|
20851
|
+
}
|
|
20852
|
+
return BigInt(textDecoder.decode(value));
|
|
20853
|
+
}
|
|
20854
|
+
mapToDriverValue(value) {
|
|
20855
|
+
return Buffer.from(value.toString());
|
|
20856
|
+
}
|
|
20857
|
+
}
|
|
20858
|
+
|
|
20859
|
+
class SQLiteBlobJsonBuilder extends SQLiteColumnBuilder {
|
|
20860
|
+
static [entityKind] = "SQLiteBlobJsonBuilder";
|
|
20861
|
+
constructor(name) {
|
|
20862
|
+
super(name, "json", "SQLiteBlobJson");
|
|
20863
|
+
}
|
|
20864
|
+
build(table) {
|
|
20865
|
+
return new SQLiteBlobJson(table, this.config);
|
|
20866
|
+
}
|
|
20867
|
+
}
|
|
20868
|
+
|
|
20869
|
+
class SQLiteBlobJson extends SQLiteColumn {
|
|
20870
|
+
static [entityKind] = "SQLiteBlobJson";
|
|
20871
|
+
getSQLType() {
|
|
20872
|
+
return "blob";
|
|
20873
|
+
}
|
|
20874
|
+
mapFromDriverValue(value) {
|
|
20875
|
+
if (typeof Buffer !== "undefined" && Buffer.from) {
|
|
20876
|
+
const buf = Buffer.isBuffer(value) ? value : value instanceof ArrayBuffer ? Buffer.from(value) : value.buffer ? Buffer.from(value.buffer, value.byteOffset, value.byteLength) : Buffer.from(value);
|
|
20877
|
+
return JSON.parse(buf.toString("utf8"));
|
|
20878
|
+
}
|
|
20879
|
+
return JSON.parse(textDecoder.decode(value));
|
|
20880
|
+
}
|
|
20881
|
+
mapToDriverValue(value) {
|
|
20882
|
+
return Buffer.from(JSON.stringify(value));
|
|
20883
|
+
}
|
|
20884
|
+
}
|
|
20885
|
+
|
|
20886
|
+
class SQLiteBlobBufferBuilder extends SQLiteColumnBuilder {
|
|
20887
|
+
static [entityKind] = "SQLiteBlobBufferBuilder";
|
|
20888
|
+
constructor(name) {
|
|
20889
|
+
super(name, "buffer", "SQLiteBlobBuffer");
|
|
20890
|
+
}
|
|
20891
|
+
build(table) {
|
|
20892
|
+
return new SQLiteBlobBuffer(table, this.config);
|
|
20893
|
+
}
|
|
20894
|
+
}
|
|
20895
|
+
|
|
20896
|
+
class SQLiteBlobBuffer extends SQLiteColumn {
|
|
20897
|
+
static [entityKind] = "SQLiteBlobBuffer";
|
|
20898
|
+
mapFromDriverValue(value) {
|
|
20899
|
+
if (Buffer.isBuffer(value)) {
|
|
20900
|
+
return value;
|
|
20901
|
+
}
|
|
20902
|
+
return Buffer.from(value);
|
|
20903
|
+
}
|
|
20904
|
+
getSQLType() {
|
|
20905
|
+
return "blob";
|
|
20906
|
+
}
|
|
20907
|
+
}
|
|
20908
|
+
function blob(a, b) {
|
|
20909
|
+
const { name, config: config2 } = getColumnNameAndConfig(a, b);
|
|
20910
|
+
if (config2?.mode === "json") {
|
|
20911
|
+
return new SQLiteBlobJsonBuilder(name);
|
|
20912
|
+
}
|
|
20913
|
+
if (config2?.mode === "bigint") {
|
|
20914
|
+
return new SQLiteBigIntBuilder(name);
|
|
20915
|
+
}
|
|
20916
|
+
return new SQLiteBlobBufferBuilder(name);
|
|
20917
|
+
}
|
|
20918
|
+
|
|
20919
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/columns/custom.js
|
|
20920
|
+
class SQLiteCustomColumnBuilder extends SQLiteColumnBuilder {
|
|
20921
|
+
static [entityKind] = "SQLiteCustomColumnBuilder";
|
|
20922
|
+
constructor(name, fieldConfig, customTypeParams) {
|
|
20923
|
+
super(name, "custom", "SQLiteCustomColumn");
|
|
20924
|
+
this.config.fieldConfig = fieldConfig;
|
|
20925
|
+
this.config.customTypeParams = customTypeParams;
|
|
20926
|
+
}
|
|
20927
|
+
build(table) {
|
|
20928
|
+
return new SQLiteCustomColumn(table, this.config);
|
|
20929
|
+
}
|
|
20930
|
+
}
|
|
20931
|
+
|
|
20932
|
+
class SQLiteCustomColumn extends SQLiteColumn {
|
|
20933
|
+
static [entityKind] = "SQLiteCustomColumn";
|
|
20934
|
+
sqlName;
|
|
20935
|
+
mapTo;
|
|
20936
|
+
mapFrom;
|
|
20937
|
+
constructor(table, config2) {
|
|
20938
|
+
super(table, config2);
|
|
20939
|
+
this.sqlName = config2.customTypeParams.dataType(config2.fieldConfig);
|
|
20940
|
+
this.mapTo = config2.customTypeParams.toDriver;
|
|
20941
|
+
this.mapFrom = config2.customTypeParams.fromDriver;
|
|
20942
|
+
}
|
|
20943
|
+
getSQLType() {
|
|
20944
|
+
return this.sqlName;
|
|
20945
|
+
}
|
|
20946
|
+
mapFromDriverValue(value) {
|
|
20947
|
+
return typeof this.mapFrom === "function" ? this.mapFrom(value) : value;
|
|
20948
|
+
}
|
|
20949
|
+
mapToDriverValue(value) {
|
|
20950
|
+
return typeof this.mapTo === "function" ? this.mapTo(value) : value;
|
|
20951
|
+
}
|
|
20952
|
+
}
|
|
20953
|
+
function customType(customTypeParams) {
|
|
20954
|
+
return (a, b) => {
|
|
20955
|
+
const { name, config: config2 } = getColumnNameAndConfig(a, b);
|
|
20956
|
+
return new SQLiteCustomColumnBuilder(name, config2, customTypeParams);
|
|
20957
|
+
};
|
|
20958
|
+
}
|
|
20959
|
+
|
|
20960
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/columns/integer.js
|
|
20961
|
+
class SQLiteBaseIntegerBuilder extends SQLiteColumnBuilder {
|
|
20962
|
+
static [entityKind] = "SQLiteBaseIntegerBuilder";
|
|
20963
|
+
constructor(name, dataType, columnType) {
|
|
20964
|
+
super(name, dataType, columnType);
|
|
20965
|
+
this.config.autoIncrement = false;
|
|
20966
|
+
}
|
|
20967
|
+
primaryKey(config2) {
|
|
20968
|
+
if (config2?.autoIncrement) {
|
|
20969
|
+
this.config.autoIncrement = true;
|
|
20970
|
+
}
|
|
20971
|
+
this.config.hasDefault = true;
|
|
20972
|
+
return super.primaryKey();
|
|
20973
|
+
}
|
|
20974
|
+
}
|
|
20975
|
+
|
|
20976
|
+
class SQLiteBaseInteger extends SQLiteColumn {
|
|
20977
|
+
static [entityKind] = "SQLiteBaseInteger";
|
|
20978
|
+
autoIncrement = this.config.autoIncrement;
|
|
20979
|
+
getSQLType() {
|
|
20980
|
+
return "integer";
|
|
20981
|
+
}
|
|
20982
|
+
}
|
|
20983
|
+
|
|
20984
|
+
class SQLiteIntegerBuilder extends SQLiteBaseIntegerBuilder {
|
|
20985
|
+
static [entityKind] = "SQLiteIntegerBuilder";
|
|
20986
|
+
constructor(name) {
|
|
20987
|
+
super(name, "number", "SQLiteInteger");
|
|
20988
|
+
}
|
|
20989
|
+
build(table) {
|
|
20990
|
+
return new SQLiteInteger(table, this.config);
|
|
20991
|
+
}
|
|
20992
|
+
}
|
|
20993
|
+
|
|
20994
|
+
class SQLiteInteger extends SQLiteBaseInteger {
|
|
20995
|
+
static [entityKind] = "SQLiteInteger";
|
|
20996
|
+
}
|
|
20997
|
+
|
|
20998
|
+
class SQLiteTimestampBuilder extends SQLiteBaseIntegerBuilder {
|
|
20999
|
+
static [entityKind] = "SQLiteTimestampBuilder";
|
|
21000
|
+
constructor(name, mode) {
|
|
21001
|
+
super(name, "date", "SQLiteTimestamp");
|
|
21002
|
+
this.config.mode = mode;
|
|
21003
|
+
}
|
|
21004
|
+
defaultNow() {
|
|
21005
|
+
return this.default(sql`(cast((julianday('now') - 2440587.5)*86400000 as integer))`);
|
|
21006
|
+
}
|
|
21007
|
+
build(table) {
|
|
21008
|
+
return new SQLiteTimestamp(table, this.config);
|
|
21009
|
+
}
|
|
21010
|
+
}
|
|
21011
|
+
|
|
21012
|
+
class SQLiteTimestamp extends SQLiteBaseInteger {
|
|
21013
|
+
static [entityKind] = "SQLiteTimestamp";
|
|
21014
|
+
mode = this.config.mode;
|
|
21015
|
+
mapFromDriverValue(value) {
|
|
21016
|
+
if (this.config.mode === "timestamp") {
|
|
21017
|
+
return new Date(value * 1000);
|
|
21018
|
+
}
|
|
21019
|
+
return new Date(value);
|
|
21020
|
+
}
|
|
21021
|
+
mapToDriverValue(value) {
|
|
21022
|
+
const unix = value.getTime();
|
|
21023
|
+
if (this.config.mode === "timestamp") {
|
|
21024
|
+
return Math.floor(unix / 1000);
|
|
21025
|
+
}
|
|
21026
|
+
return unix;
|
|
21027
|
+
}
|
|
21028
|
+
}
|
|
21029
|
+
|
|
21030
|
+
class SQLiteBooleanBuilder extends SQLiteBaseIntegerBuilder {
|
|
21031
|
+
static [entityKind] = "SQLiteBooleanBuilder";
|
|
21032
|
+
constructor(name, mode) {
|
|
21033
|
+
super(name, "boolean", "SQLiteBoolean");
|
|
21034
|
+
this.config.mode = mode;
|
|
21035
|
+
}
|
|
21036
|
+
build(table) {
|
|
21037
|
+
return new SQLiteBoolean(table, this.config);
|
|
21038
|
+
}
|
|
21039
|
+
}
|
|
21040
|
+
|
|
21041
|
+
class SQLiteBoolean extends SQLiteBaseInteger {
|
|
21042
|
+
static [entityKind] = "SQLiteBoolean";
|
|
21043
|
+
mode = this.config.mode;
|
|
21044
|
+
mapFromDriverValue(value) {
|
|
21045
|
+
return Number(value) === 1;
|
|
21046
|
+
}
|
|
21047
|
+
mapToDriverValue(value) {
|
|
21048
|
+
return value ? 1 : 0;
|
|
21049
|
+
}
|
|
21050
|
+
}
|
|
21051
|
+
function integer2(a, b) {
|
|
21052
|
+
const { name, config: config2 } = getColumnNameAndConfig(a, b);
|
|
21053
|
+
if (config2?.mode === "timestamp" || config2?.mode === "timestamp_ms") {
|
|
21054
|
+
return new SQLiteTimestampBuilder(name, config2.mode);
|
|
21055
|
+
}
|
|
21056
|
+
if (config2?.mode === "boolean") {
|
|
21057
|
+
return new SQLiteBooleanBuilder(name, config2.mode);
|
|
21058
|
+
}
|
|
21059
|
+
return new SQLiteIntegerBuilder(name);
|
|
21060
|
+
}
|
|
21061
|
+
|
|
21062
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/columns/numeric.js
|
|
21063
|
+
class SQLiteNumericBuilder extends SQLiteColumnBuilder {
|
|
21064
|
+
static [entityKind] = "SQLiteNumericBuilder";
|
|
21065
|
+
constructor(name) {
|
|
21066
|
+
super(name, "string", "SQLiteNumeric");
|
|
21067
|
+
}
|
|
21068
|
+
build(table) {
|
|
21069
|
+
return new SQLiteNumeric(table, this.config);
|
|
21070
|
+
}
|
|
21071
|
+
}
|
|
21072
|
+
|
|
21073
|
+
class SQLiteNumeric extends SQLiteColumn {
|
|
21074
|
+
static [entityKind] = "SQLiteNumeric";
|
|
21075
|
+
mapFromDriverValue(value) {
|
|
21076
|
+
if (typeof value === "string")
|
|
21077
|
+
return value;
|
|
21078
|
+
return String(value);
|
|
21079
|
+
}
|
|
21080
|
+
getSQLType() {
|
|
21081
|
+
return "numeric";
|
|
21082
|
+
}
|
|
21083
|
+
}
|
|
21084
|
+
|
|
21085
|
+
class SQLiteNumericNumberBuilder extends SQLiteColumnBuilder {
|
|
21086
|
+
static [entityKind] = "SQLiteNumericNumberBuilder";
|
|
21087
|
+
constructor(name) {
|
|
21088
|
+
super(name, "number", "SQLiteNumericNumber");
|
|
21089
|
+
}
|
|
21090
|
+
build(table) {
|
|
21091
|
+
return new SQLiteNumericNumber(table, this.config);
|
|
21092
|
+
}
|
|
21093
|
+
}
|
|
21094
|
+
|
|
21095
|
+
class SQLiteNumericNumber extends SQLiteColumn {
|
|
21096
|
+
static [entityKind] = "SQLiteNumericNumber";
|
|
21097
|
+
mapFromDriverValue(value) {
|
|
21098
|
+
if (typeof value === "number")
|
|
21099
|
+
return value;
|
|
21100
|
+
return Number(value);
|
|
21101
|
+
}
|
|
21102
|
+
mapToDriverValue = String;
|
|
21103
|
+
getSQLType() {
|
|
21104
|
+
return "numeric";
|
|
21105
|
+
}
|
|
21106
|
+
}
|
|
21107
|
+
|
|
21108
|
+
class SQLiteNumericBigIntBuilder extends SQLiteColumnBuilder {
|
|
21109
|
+
static [entityKind] = "SQLiteNumericBigIntBuilder";
|
|
21110
|
+
constructor(name) {
|
|
21111
|
+
super(name, "bigint", "SQLiteNumericBigInt");
|
|
21112
|
+
}
|
|
21113
|
+
build(table) {
|
|
21114
|
+
return new SQLiteNumericBigInt(table, this.config);
|
|
21115
|
+
}
|
|
21116
|
+
}
|
|
21117
|
+
|
|
21118
|
+
class SQLiteNumericBigInt extends SQLiteColumn {
|
|
21119
|
+
static [entityKind] = "SQLiteNumericBigInt";
|
|
21120
|
+
mapFromDriverValue = BigInt;
|
|
21121
|
+
mapToDriverValue = String;
|
|
21122
|
+
getSQLType() {
|
|
21123
|
+
return "numeric";
|
|
21124
|
+
}
|
|
21125
|
+
}
|
|
21126
|
+
function numeric(a, b) {
|
|
21127
|
+
const { name, config: config2 } = getColumnNameAndConfig(a, b);
|
|
21128
|
+
const mode = config2?.mode;
|
|
21129
|
+
return mode === "number" ? new SQLiteNumericNumberBuilder(name) : mode === "bigint" ? new SQLiteNumericBigIntBuilder(name) : new SQLiteNumericBuilder(name);
|
|
21130
|
+
}
|
|
21131
|
+
|
|
21132
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/columns/real.js
|
|
21133
|
+
class SQLiteRealBuilder extends SQLiteColumnBuilder {
|
|
21134
|
+
static [entityKind] = "SQLiteRealBuilder";
|
|
21135
|
+
constructor(name) {
|
|
21136
|
+
super(name, "number", "SQLiteReal");
|
|
21137
|
+
}
|
|
21138
|
+
build(table) {
|
|
21139
|
+
return new SQLiteReal(table, this.config);
|
|
21140
|
+
}
|
|
21141
|
+
}
|
|
21142
|
+
|
|
21143
|
+
class SQLiteReal extends SQLiteColumn {
|
|
21144
|
+
static [entityKind] = "SQLiteReal";
|
|
21145
|
+
getSQLType() {
|
|
21146
|
+
return "real";
|
|
21147
|
+
}
|
|
21148
|
+
}
|
|
21149
|
+
function real(name) {
|
|
21150
|
+
return new SQLiteRealBuilder(name ?? "");
|
|
21151
|
+
}
|
|
21152
|
+
|
|
21153
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/columns/text.js
|
|
21154
|
+
class SQLiteTextBuilder extends SQLiteColumnBuilder {
|
|
21155
|
+
static [entityKind] = "SQLiteTextBuilder";
|
|
21156
|
+
constructor(name, config2) {
|
|
21157
|
+
super(name, "string", "SQLiteText");
|
|
21158
|
+
this.config.enumValues = config2.enum;
|
|
21159
|
+
this.config.length = config2.length;
|
|
21160
|
+
}
|
|
21161
|
+
build(table) {
|
|
21162
|
+
return new SQLiteText(table, this.config);
|
|
21163
|
+
}
|
|
21164
|
+
}
|
|
21165
|
+
|
|
21166
|
+
class SQLiteText extends SQLiteColumn {
|
|
21167
|
+
static [entityKind] = "SQLiteText";
|
|
21168
|
+
enumValues = this.config.enumValues;
|
|
21169
|
+
length = this.config.length;
|
|
21170
|
+
constructor(table, config2) {
|
|
21171
|
+
super(table, config2);
|
|
21172
|
+
}
|
|
21173
|
+
getSQLType() {
|
|
21174
|
+
return `text${this.config.length ? `(${this.config.length})` : ""}`;
|
|
21175
|
+
}
|
|
21176
|
+
}
|
|
21177
|
+
|
|
21178
|
+
class SQLiteTextJsonBuilder extends SQLiteColumnBuilder {
|
|
21179
|
+
static [entityKind] = "SQLiteTextJsonBuilder";
|
|
21180
|
+
constructor(name) {
|
|
21181
|
+
super(name, "json", "SQLiteTextJson");
|
|
21182
|
+
}
|
|
21183
|
+
build(table) {
|
|
21184
|
+
return new SQLiteTextJson(table, this.config);
|
|
21185
|
+
}
|
|
21186
|
+
}
|
|
21187
|
+
|
|
21188
|
+
class SQLiteTextJson extends SQLiteColumn {
|
|
21189
|
+
static [entityKind] = "SQLiteTextJson";
|
|
21190
|
+
getSQLType() {
|
|
21191
|
+
return "text";
|
|
21192
|
+
}
|
|
21193
|
+
mapFromDriverValue(value) {
|
|
21194
|
+
return JSON.parse(value);
|
|
21195
|
+
}
|
|
21196
|
+
mapToDriverValue(value) {
|
|
21197
|
+
return JSON.stringify(value);
|
|
21198
|
+
}
|
|
21199
|
+
}
|
|
21200
|
+
function text(a, b = {}) {
|
|
21201
|
+
const { name, config: config2 } = getColumnNameAndConfig(a, b);
|
|
21202
|
+
if (config2.mode === "json") {
|
|
21203
|
+
return new SQLiteTextJsonBuilder(name);
|
|
21204
|
+
}
|
|
21205
|
+
return new SQLiteTextBuilder(name, config2);
|
|
21206
|
+
}
|
|
21207
|
+
|
|
21208
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/columns/all.js
|
|
21209
|
+
function getSQLiteColumnBuilders() {
|
|
21210
|
+
return {
|
|
21211
|
+
blob,
|
|
21212
|
+
customType,
|
|
21213
|
+
integer: integer2,
|
|
21214
|
+
numeric,
|
|
21215
|
+
real,
|
|
21216
|
+
text
|
|
21217
|
+
};
|
|
21218
|
+
}
|
|
21219
|
+
|
|
21220
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/table.js
|
|
21221
|
+
var InlineForeignKeys = Symbol.for("drizzle:SQLiteInlineForeignKeys");
|
|
21222
|
+
|
|
21223
|
+
class SQLiteTable extends Table {
|
|
21224
|
+
static [entityKind] = "SQLiteTable";
|
|
21225
|
+
static Symbol = Object.assign({}, Table.Symbol, {
|
|
21226
|
+
InlineForeignKeys
|
|
21227
|
+
});
|
|
21228
|
+
[Table.Symbol.Columns];
|
|
21229
|
+
[InlineForeignKeys] = [];
|
|
21230
|
+
[Table.Symbol.ExtraConfigBuilder] = undefined;
|
|
21231
|
+
}
|
|
21232
|
+
function sqliteTableBase(name, columns, extraConfig, schema, baseName = name) {
|
|
21233
|
+
const rawTable = new SQLiteTable(name, schema, baseName);
|
|
21234
|
+
const parsedColumns = typeof columns === "function" ? columns(getSQLiteColumnBuilders()) : columns;
|
|
21235
|
+
const builtColumns = Object.fromEntries(Object.entries(parsedColumns).map(([name2, colBuilderBase]) => {
|
|
21236
|
+
const colBuilder = colBuilderBase;
|
|
21237
|
+
colBuilder.setName(name2);
|
|
21238
|
+
const column = colBuilder.build(rawTable);
|
|
21239
|
+
rawTable[InlineForeignKeys].push(...colBuilder.buildForeignKeys(column, rawTable));
|
|
21240
|
+
return [name2, column];
|
|
21241
|
+
}));
|
|
21242
|
+
const table = Object.assign(rawTable, builtColumns);
|
|
21243
|
+
table[Table.Symbol.Columns] = builtColumns;
|
|
21244
|
+
table[Table.Symbol.ExtraConfigColumns] = builtColumns;
|
|
21245
|
+
if (extraConfig) {
|
|
21246
|
+
table[SQLiteTable.Symbol.ExtraConfigBuilder] = extraConfig;
|
|
21247
|
+
}
|
|
21248
|
+
return table;
|
|
21249
|
+
}
|
|
21250
|
+
var sqliteTable = (name, columns, extraConfig) => {
|
|
21251
|
+
return sqliteTableBase(name, columns, extraConfig);
|
|
21252
|
+
};
|
|
21253
|
+
|
|
21254
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/indexes.js
|
|
21255
|
+
class IndexBuilderOn {
|
|
21256
|
+
constructor(name, unique2) {
|
|
21257
|
+
this.name = name;
|
|
21258
|
+
this.unique = unique2;
|
|
21259
|
+
}
|
|
21260
|
+
static [entityKind] = "SQLiteIndexBuilderOn";
|
|
21261
|
+
on(...columns) {
|
|
21262
|
+
return new IndexBuilder(this.name, columns, this.unique);
|
|
21263
|
+
}
|
|
21264
|
+
}
|
|
21265
|
+
|
|
21266
|
+
class IndexBuilder {
|
|
21267
|
+
static [entityKind] = "SQLiteIndexBuilder";
|
|
21268
|
+
config;
|
|
21269
|
+
constructor(name, columns, unique2) {
|
|
21270
|
+
this.config = {
|
|
21271
|
+
name,
|
|
21272
|
+
columns,
|
|
21273
|
+
unique: unique2,
|
|
21274
|
+
where: undefined
|
|
21275
|
+
};
|
|
21276
|
+
}
|
|
21277
|
+
where(condition) {
|
|
21278
|
+
this.config.where = condition;
|
|
21279
|
+
return this;
|
|
21280
|
+
}
|
|
21281
|
+
build(table) {
|
|
21282
|
+
return new Index(this.config, table);
|
|
21283
|
+
}
|
|
21284
|
+
}
|
|
21285
|
+
|
|
21286
|
+
class Index {
|
|
21287
|
+
static [entityKind] = "SQLiteIndex";
|
|
21288
|
+
config;
|
|
21289
|
+
constructor(config2, table) {
|
|
21290
|
+
this.config = { ...config2, table };
|
|
21291
|
+
}
|
|
21292
|
+
}
|
|
21293
|
+
function index(name) {
|
|
21294
|
+
return new IndexBuilderOn(name, false);
|
|
21295
|
+
}
|
|
21296
|
+
function uniqueIndex(name) {
|
|
21297
|
+
return new IndexBuilderOn(name, true);
|
|
21298
|
+
}
|
|
21299
|
+
|
|
21300
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_5aa9492b131e5fac58fa98e88e5c0ad3/node_modules/drizzle-orm/sqlite-core/primary-keys.js
|
|
21301
|
+
function primaryKey(...config2) {
|
|
21302
|
+
if (config2[0].columns) {
|
|
21303
|
+
return new PrimaryKeyBuilder(config2[0].columns, config2[0].name);
|
|
21304
|
+
}
|
|
21305
|
+
return new PrimaryKeyBuilder(config2);
|
|
21306
|
+
}
|
|
21307
|
+
|
|
21308
|
+
class PrimaryKeyBuilder {
|
|
21309
|
+
static [entityKind] = "SQLitePrimaryKeyBuilder";
|
|
21310
|
+
columns;
|
|
21311
|
+
name;
|
|
21312
|
+
constructor(columns, name) {
|
|
21313
|
+
this.columns = columns;
|
|
21314
|
+
this.name = name;
|
|
21315
|
+
}
|
|
21316
|
+
build(table) {
|
|
21317
|
+
return new PrimaryKey(table, this.columns, this.name);
|
|
21318
|
+
}
|
|
21319
|
+
}
|
|
21320
|
+
|
|
21321
|
+
class PrimaryKey {
|
|
21322
|
+
constructor(table, columns, name) {
|
|
21323
|
+
this.table = table;
|
|
21324
|
+
this.columns = columns;
|
|
21325
|
+
this.name = name;
|
|
21326
|
+
}
|
|
21327
|
+
static [entityKind] = "SQLitePrimaryKey";
|
|
21328
|
+
columns;
|
|
21329
|
+
name;
|
|
21330
|
+
getName() {
|
|
21331
|
+
return this.name ?? `${this.table[SQLiteTable.Symbol.Name]}_${this.columns.map((column) => column.name).join("_")}_pk`;
|
|
21332
|
+
}
|
|
21333
|
+
}
|
|
21334
|
+
|
|
21335
|
+
// ../../node_modules/.pnpm/nanoid@5.1.16/node_modules/nanoid/index.js
|
|
21336
|
+
import { webcrypto as crypto2 } from "node:crypto";
|
|
21337
|
+
|
|
21338
|
+
// ../../node_modules/.pnpm/nanoid@5.1.16/node_modules/nanoid/url-alphabet/index.js
|
|
21339
|
+
var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
|
|
21340
|
+
|
|
21341
|
+
// ../../node_modules/.pnpm/nanoid@5.1.16/node_modules/nanoid/index.js
|
|
21342
|
+
var POOL_SIZE_MULTIPLIER = 128;
|
|
21343
|
+
var pool;
|
|
21344
|
+
var poolOffset;
|
|
21345
|
+
function fillPool(bytes) {
|
|
21346
|
+
if (bytes < 0)
|
|
21347
|
+
throw new RangeError("Wrong ID size");
|
|
21348
|
+
try {
|
|
21349
|
+
if (!pool || pool.length < bytes) {
|
|
21350
|
+
pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
|
|
21351
|
+
crypto2.getRandomValues(pool);
|
|
21352
|
+
poolOffset = 0;
|
|
21353
|
+
} else if (poolOffset + bytes > pool.length) {
|
|
21354
|
+
crypto2.getRandomValues(pool);
|
|
21355
|
+
poolOffset = 0;
|
|
21356
|
+
}
|
|
21357
|
+
} catch (e) {
|
|
21358
|
+
pool = undefined;
|
|
21359
|
+
throw e;
|
|
21360
|
+
}
|
|
21361
|
+
poolOffset += bytes;
|
|
21362
|
+
}
|
|
21363
|
+
function nanoid3(size = 21) {
|
|
21364
|
+
fillPool(size |= 0);
|
|
21365
|
+
let id = "";
|
|
21366
|
+
for (let i = poolOffset - size;i < poolOffset; i++) {
|
|
21367
|
+
id += urlAlphabet[pool[i] & 63];
|
|
21368
|
+
}
|
|
21369
|
+
return id;
|
|
21370
|
+
}
|
|
21371
|
+
|
|
21372
|
+
// ../shared/src/constants.ts
|
|
21373
|
+
var TaskStatus = {
|
|
21374
|
+
QUEUED: "queued",
|
|
21375
|
+
DISPATCHED: "dispatched",
|
|
21376
|
+
RUNNING: "running",
|
|
21377
|
+
COMPLETED: "completed",
|
|
21378
|
+
FAILED: "failed",
|
|
21379
|
+
CANCELLED: "cancelled",
|
|
21380
|
+
SUPERSEDED: "superseded"
|
|
21381
|
+
};
|
|
21382
|
+
var TERMINAL_TASK_STATUSES = [
|
|
21383
|
+
TaskStatus.COMPLETED,
|
|
21384
|
+
TaskStatus.FAILED,
|
|
21385
|
+
TaskStatus.CANCELLED,
|
|
21386
|
+
TaskStatus.SUPERSEDED
|
|
21387
|
+
];
|
|
21388
|
+
var TASK_TYPES = {
|
|
21389
|
+
USER_DM_MESSAGE: "user_dm_message",
|
|
21390
|
+
EMAIL_NOTIFICATION: "email_notification",
|
|
21391
|
+
CALENDAR_EVENT: "calendar_event",
|
|
21392
|
+
ISSUE_EVENT: "issue_event",
|
|
21393
|
+
KILL_TASK: "kill_task"
|
|
21394
|
+
};
|
|
21395
|
+
var IssueStatus = {
|
|
21396
|
+
TODO: "todo",
|
|
21397
|
+
IN_PROGRESS: "in_progress",
|
|
21398
|
+
REVIEW: "review",
|
|
21399
|
+
DONE: "done",
|
|
21400
|
+
CLOSED: "closed",
|
|
21401
|
+
CANCELED: "canceled",
|
|
21402
|
+
FAILED: "failed"
|
|
21403
|
+
};
|
|
21404
|
+
var ACTIVE_ISSUE_STATUSES = [
|
|
21405
|
+
IssueStatus.TODO,
|
|
21406
|
+
IssueStatus.IN_PROGRESS,
|
|
21407
|
+
IssueStatus.REVIEW
|
|
21408
|
+
];
|
|
21409
|
+
var TERMINAL_ISSUE_STATUSES = [
|
|
21410
|
+
IssueStatus.DONE,
|
|
21411
|
+
IssueStatus.CLOSED,
|
|
21412
|
+
IssueStatus.CANCELED,
|
|
21413
|
+
IssueStatus.FAILED
|
|
21414
|
+
];
|
|
21415
|
+
var POLL_INTERVAL_MS = Number(process.env.POLL_INTERVAL_MS) || 3000;
|
|
21416
|
+
var OFFLINE_THRESHOLD_MS = Number(process.env.OFFLINE_THRESHOLD_MS) || 30000;
|
|
21417
|
+
var COMMUNITY_MACHINE_HEARTBEAT_MS = 30000;
|
|
21418
|
+
var COMMUNITY_MACHINE_OFFLINE_THRESHOLD_MS = 3 * COMMUNITY_MACHINE_HEARTBEAT_MS;
|
|
21419
|
+
var COMMUNITY_MACHINE_PAIR_TOKEN_TTL_MS = 15 * 60000;
|
|
21420
|
+
var EVENT_POLL_INTERVAL_MS = Number(process.env.EVENT_POLL_INTERVAL_MS) || 2000;
|
|
21421
|
+
var MeetingStatus = {
|
|
21422
|
+
PENDING: "pending",
|
|
21423
|
+
SCHEDULED: "scheduled",
|
|
21424
|
+
JOINING: "joining",
|
|
21425
|
+
RECORDING: "recording",
|
|
21426
|
+
COMPLETED: "completed",
|
|
21427
|
+
FAILED: "failed"
|
|
21428
|
+
};
|
|
21429
|
+
var TERMINAL_MEETING_STATUSES = [
|
|
21430
|
+
MeetingStatus.COMPLETED,
|
|
21431
|
+
MeetingStatus.FAILED
|
|
21432
|
+
];
|
|
21433
|
+
var DEV_PORTS = {
|
|
21434
|
+
web: 3000,
|
|
21435
|
+
emailWorker: 8787,
|
|
21436
|
+
wsDo: 8789,
|
|
21437
|
+
wakeWorker: 8790
|
|
21438
|
+
};
|
|
21439
|
+
var DEV_WEB_URL = process.env.ALOOK_SERVER_URL || `http://localhost:${DEV_PORTS.web}`;
|
|
21440
|
+
var DEV_WS_DO_URL = process.env.DEV_WS_DO_URL || `http://localhost:${DEV_PORTS.wsDo}`;
|
|
21441
|
+
var DEV_EMAIL_WORKER_URL = process.env.DEV_EMAIL_WORKER_URL || `http://localhost:${DEV_PORTS.emailWorker}`;
|
|
21442
|
+
var DEV_WAKE_WORKER_URL = process.env.DEV_WAKE_WORKER_URL || `http://localhost:${DEV_PORTS.wakeWorker}`;
|
|
21443
|
+
|
|
21444
|
+
// ../shared/src/db/schema.ts
|
|
21445
|
+
var user = sqliteTable("user", {
|
|
21446
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
21447
|
+
name: text("name").notNull().default(""),
|
|
21448
|
+
email: text("email").unique().notNull(),
|
|
21449
|
+
emailVerified: integer2("emailVerified", { mode: "boolean" }),
|
|
21450
|
+
image: text("image"),
|
|
21451
|
+
createdAt: text("createdAt").notNull().$defaultFn(() => new Date().toISOString()),
|
|
21452
|
+
updatedAt: text("updatedAt").notNull().$defaultFn(() => new Date().toISOString()),
|
|
21453
|
+
isBot: integer2("isBot", { mode: "boolean" }).notNull().default(false),
|
|
21454
|
+
ownerUserId: text("ownerUserId").references(() => user.id, { onDelete: "no action" }),
|
|
21455
|
+
deletedAt: text("deletedAt"),
|
|
21456
|
+
discriminator: text("discriminator").notNull().default("0000"),
|
|
21457
|
+
lastRefreshContextAt: text("lastRefreshContextAt")
|
|
21458
|
+
}, (t) => [index("idx_user_ownerUserId_isBot").on(t.ownerUserId, t.isBot)]);
|
|
21459
|
+
var session = sqliteTable("session", {
|
|
21460
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
21461
|
+
userId: text("userId").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
21462
|
+
token: text("token").unique().notNull(),
|
|
21463
|
+
expiresAt: text("expiresAt").notNull(),
|
|
21464
|
+
ipAddress: text("ipAddress"),
|
|
21465
|
+
userAgent: text("userAgent"),
|
|
21466
|
+
createdAt: text("createdAt").notNull().$defaultFn(() => new Date().toISOString()),
|
|
21467
|
+
updatedAt: text("updatedAt").notNull().$defaultFn(() => new Date().toISOString())
|
|
21468
|
+
}, (t) => [index("idx_session_token_expires").on(t.token, t.expiresAt)]);
|
|
21469
|
+
var account = sqliteTable("account", {
|
|
21470
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
21471
|
+
userId: text("userId").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
21472
|
+
accountId: text("accountId").notNull(),
|
|
21473
|
+
providerId: text("providerId").notNull(),
|
|
21474
|
+
accessToken: text("accessToken"),
|
|
21475
|
+
refreshToken: text("refreshToken"),
|
|
21476
|
+
accessTokenExpiresAt: text("accessTokenExpiresAt"),
|
|
21477
|
+
refreshTokenExpiresAt: text("refreshTokenExpiresAt"),
|
|
21478
|
+
scope: text("scope"),
|
|
21479
|
+
idToken: text("idToken"),
|
|
21480
|
+
password: text("password"),
|
|
21481
|
+
createdAt: text("createdAt").notNull().$defaultFn(() => new Date().toISOString()),
|
|
21482
|
+
updatedAt: text("updatedAt").notNull().$defaultFn(() => new Date().toISOString())
|
|
21483
|
+
});
|
|
21484
|
+
var verification = sqliteTable("verification", {
|
|
21485
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
21486
|
+
identifier: text("identifier").notNull(),
|
|
21487
|
+
value: text("value").notNull(),
|
|
21488
|
+
expiresAt: text("expiresAt").notNull(),
|
|
21489
|
+
createdAt: text("createdAt").notNull().$defaultFn(() => new Date().toISOString()),
|
|
21490
|
+
updatedAt: text("updatedAt").notNull().$defaultFn(() => new Date().toISOString())
|
|
21491
|
+
});
|
|
21492
|
+
var workspace = sqliteTable("workspace", {
|
|
21493
|
+
id: text("id").primaryKey().$defaultFn(() => "sp_" + nanoid3()),
|
|
21494
|
+
name: text("name").notNull(),
|
|
21495
|
+
slug: text("slug").unique().notNull(),
|
|
21496
|
+
onboarded: integer2("onboarded").notNull().default(0),
|
|
21497
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
21498
|
+
updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21499
|
+
});
|
|
21500
|
+
var member = sqliteTable("member", {
|
|
21501
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
21502
|
+
workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
|
|
21503
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
21504
|
+
role: text("role").notNull().default("member"),
|
|
21505
|
+
globalInstruction: text("global_instruction").notNull().default(""),
|
|
21506
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21507
|
+
}, (t) => [unique("member_workspace_user").on(t.workspaceId, t.userId)]);
|
|
21508
|
+
var workspaceInvite = sqliteTable("workspace_invite", {
|
|
21509
|
+
id: text("id").primaryKey().$defaultFn(() => "inv_" + nanoid3()),
|
|
21510
|
+
workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
|
|
21511
|
+
token: text("token").unique().notNull().$defaultFn(() => nanoid3(32)),
|
|
21512
|
+
createdBy: text("created_by").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
21513
|
+
usedBy: text("used_by").references(() => user.id, { onDelete: "set null" }),
|
|
21514
|
+
usedAt: text("used_at"),
|
|
21515
|
+
expiresAt: text("expires_at").notNull(),
|
|
21516
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21517
|
+
}, (t) => [
|
|
21518
|
+
index("idx_workspace_invite_token").on(t.token),
|
|
21519
|
+
index("idx_workspace_invite_workspace").on(t.workspaceId)
|
|
21520
|
+
]);
|
|
21521
|
+
var agentAccess = sqliteTable("agent_access", {
|
|
21522
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
21523
|
+
agentId: text("agent_id").notNull(),
|
|
21524
|
+
workspaceId: text("workspace_id").notNull(),
|
|
21525
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
21526
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21527
|
+
}, (t) => [
|
|
21528
|
+
unique("agent_access_agent_ws_user").on(t.agentId, t.workspaceId, t.userId),
|
|
21529
|
+
index("idx_agent_access_agent_ws").on(t.agentId, t.workspaceId),
|
|
21530
|
+
index("idx_agent_access_user").on(t.userId),
|
|
21531
|
+
foreignKey({
|
|
21532
|
+
columns: [t.agentId, t.workspaceId],
|
|
21533
|
+
foreignColumns: [agent.id, agent.workspaceId]
|
|
21534
|
+
}).onDelete("cascade")
|
|
21535
|
+
]);
|
|
21536
|
+
var agentPin = sqliteTable("agent_pin", {
|
|
21537
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
21538
|
+
agentId: text("agent_id").notNull(),
|
|
21539
|
+
workspaceId: text("workspace_id").notNull(),
|
|
21540
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
21541
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
21542
|
+
position: integer2("position").notNull().default(0)
|
|
21543
|
+
}, (t) => [
|
|
21544
|
+
unique("agent_pin_agent_ws_user").on(t.agentId, t.workspaceId, t.userId),
|
|
21545
|
+
index("idx_agent_pin_ws_user").on(t.workspaceId, t.userId),
|
|
21546
|
+
foreignKey({
|
|
21547
|
+
columns: [t.agentId, t.workspaceId],
|
|
21548
|
+
foreignColumns: [agent.id, agent.workspaceId]
|
|
21549
|
+
}).onDelete("cascade")
|
|
21550
|
+
]);
|
|
21551
|
+
var agentSidebarOrder = sqliteTable("agent_sidebar_order", {
|
|
21552
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
21553
|
+
agentId: text("agent_id").notNull(),
|
|
21554
|
+
workspaceId: text("workspace_id").notNull(),
|
|
21555
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
21556
|
+
position: integer2("position").notNull().default(0)
|
|
21557
|
+
}, (t) => [
|
|
21558
|
+
unique("agent_sidebar_order_agent_ws_user").on(t.agentId, t.workspaceId, t.userId),
|
|
21559
|
+
index("idx_agent_sidebar_order_ws_user").on(t.workspaceId, t.userId),
|
|
21560
|
+
foreignKey({
|
|
21561
|
+
columns: [t.agentId, t.workspaceId],
|
|
21562
|
+
foreignColumns: [agent.id, agent.workspaceId]
|
|
21563
|
+
}).onDelete("cascade")
|
|
21564
|
+
]);
|
|
21565
|
+
var machine = sqliteTable("machine", {
|
|
21566
|
+
daemonId: text("daemon_id").notNull(),
|
|
21567
|
+
workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
|
|
21568
|
+
deviceInfo: text("device_info").notNull().default(""),
|
|
21569
|
+
lastSeenAt: text("last_seen_at"),
|
|
21570
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
21571
|
+
pendingUpdateVersion: text("pending_update_version"),
|
|
21572
|
+
pendingRescan: integer2("pending_rescan", { mode: "boolean" }).default(false),
|
|
21573
|
+
updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
21574
|
+
ownerId: text("owner_id").references(() => user.id, { onDelete: "set null" })
|
|
21575
|
+
}, (t) => [primaryKey({ columns: [t.workspaceId, t.daemonId] })]);
|
|
21576
|
+
var agentRuntime = sqliteTable("agent_runtime", {
|
|
21577
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
21578
|
+
workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
|
|
21579
|
+
daemonId: text("daemon_id").notNull(),
|
|
21580
|
+
runtimeMode: text("runtime_mode").notNull().default("local"),
|
|
21581
|
+
provider: text("provider").notNull(),
|
|
21582
|
+
deviceInfo: text("device_info").notNull().default(""),
|
|
21583
|
+
metadata: text("metadata", { mode: "json" }),
|
|
21584
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
21585
|
+
updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21586
|
+
}, (t) => [
|
|
21587
|
+
unique("agent_runtime_workspace_daemon_provider").on(t.workspaceId, t.daemonId, t.provider),
|
|
21588
|
+
index("idx_agent_runtime_workspace_daemon").on(t.workspaceId, t.daemonId),
|
|
21589
|
+
index("idx_agent_runtime_daemon_workspace").on(t.daemonId, t.workspaceId)
|
|
21590
|
+
]);
|
|
21591
|
+
var agent = sqliteTable("agent", {
|
|
21592
|
+
id: text("id").notNull().$defaultFn(() => "ag_" + nanoid3(8)),
|
|
21593
|
+
workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
|
|
21594
|
+
name: text("name").notNull(),
|
|
21595
|
+
description: text("description").notNull().default(""),
|
|
21596
|
+
instructions: text("instructions").notNull().default(""),
|
|
21597
|
+
avatarUrl: text("avatar_url"),
|
|
21598
|
+
runtimeId: text("runtime_id").references(() => agentRuntime.id),
|
|
21599
|
+
runtimeMode: text("runtime_mode").notNull().default("local"),
|
|
21600
|
+
runtimeConfig: text("runtime_config", { mode: "json" }),
|
|
21601
|
+
visibility: text("visibility").notNull().default("private"),
|
|
21602
|
+
status: text("status").notNull().default("idle"),
|
|
21603
|
+
maxConcurrentTasks: integer2("max_concurrent_tasks").notNull().default(6),
|
|
21604
|
+
ownerId: text("owner_id").references(() => user.id),
|
|
21605
|
+
tools: text("tools", { mode: "json" }),
|
|
21606
|
+
triggers: text("triggers", { mode: "json" }),
|
|
21607
|
+
emailHandle: text("email_handle").unique(),
|
|
21608
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
21609
|
+
updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21610
|
+
}, (t) => [primaryKey({ columns: [t.id, t.workspaceId] })]);
|
|
21611
|
+
var agentWhitelist = sqliteTable("agent_whitelist", {
|
|
21612
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
21613
|
+
agentId: text("agent_id").notNull(),
|
|
21614
|
+
workspaceId: text("workspace_id").notNull(),
|
|
21615
|
+
email: text("email").notNull(),
|
|
21616
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21617
|
+
}, (t) => [
|
|
21618
|
+
unique("agent_whitelist_agent_ws_email").on(t.agentId, t.workspaceId, t.email),
|
|
21619
|
+
foreignKey({
|
|
21620
|
+
columns: [t.agentId, t.workspaceId],
|
|
21621
|
+
foreignColumns: [agent.id, agent.workspaceId]
|
|
21622
|
+
}).onDelete("cascade")
|
|
21623
|
+
]);
|
|
21624
|
+
var channel = sqliteTable("channel", {
|
|
21625
|
+
id: text("id").primaryKey().$defaultFn(() => "ch_" + nanoid3()),
|
|
21626
|
+
workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
|
|
21627
|
+
name: text("name").notNull(),
|
|
21628
|
+
position: integer2("position").notNull().default(0),
|
|
21629
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21630
|
+
}, (t) => [
|
|
21631
|
+
unique("channel_workspace_name").on(t.workspaceId, t.name),
|
|
21632
|
+
index("idx_channel_workspace").on(t.workspaceId)
|
|
21633
|
+
]);
|
|
21634
|
+
var conversation = sqliteTable("conversation", {
|
|
21635
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
21636
|
+
workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
|
|
21637
|
+
agentId: text("agent_id").notNull(),
|
|
21638
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
21639
|
+
title: text("title").notNull().default(""),
|
|
21640
|
+
type: text("type").notNull().default(TASK_TYPES.USER_DM_MESSAGE),
|
|
21641
|
+
channel: text("channel").notNull().default("default"),
|
|
21642
|
+
parentMessageId: text("parent_message_id"),
|
|
21643
|
+
threadTitle: text("thread_title").notNull().default(""),
|
|
21644
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21645
|
+
}, (t) => [
|
|
21646
|
+
index("idx_conversation_agent_lookup").on(t.workspaceId, t.agentId, t.userId, t.type, t.channel, t.createdAt),
|
|
21647
|
+
index("idx_conversation_ws_user").on(t.workspaceId, t.userId, t.createdAt),
|
|
21648
|
+
index("idx_conversation_thread").on(t.parentMessageId),
|
|
21649
|
+
unique("uq_conversation_parent_message").on(t.parentMessageId, t.workspaceId),
|
|
21650
|
+
foreignKey({
|
|
21651
|
+
columns: [t.agentId, t.workspaceId],
|
|
21652
|
+
foreignColumns: [agent.id, agent.workspaceId]
|
|
21653
|
+
}).onDelete("cascade")
|
|
21654
|
+
]);
|
|
21655
|
+
var message = sqliteTable("message", {
|
|
21656
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
21657
|
+
conversationId: text("conversation_id").notNull().references(() => conversation.id, { onDelete: "cascade" }),
|
|
21658
|
+
role: text("role").notNull(),
|
|
21659
|
+
content: text("content").notNull().default(""),
|
|
21660
|
+
taskId: text("task_id"),
|
|
21661
|
+
attachmentIds: text("attachment_ids"),
|
|
21662
|
+
metadata: text("metadata"),
|
|
21663
|
+
status: text("status").notNull().default("active"),
|
|
21664
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21665
|
+
}, (t) => [
|
|
21666
|
+
index("idx_message_conversation_status").on(t.conversationId, t.status)
|
|
21667
|
+
]);
|
|
21668
|
+
var agentTaskQueue = sqliteTable("agent_task_queue", {
|
|
21669
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
21670
|
+
agentId: text("agent_id").notNull(),
|
|
21671
|
+
runtimeId: text("runtime_id").notNull().references(() => agentRuntime.id, { onDelete: "cascade" }),
|
|
21672
|
+
workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
|
|
21673
|
+
conversationId: text("conversation_id").notNull().references(() => conversation.id, { onDelete: "cascade" }),
|
|
21674
|
+
prompt: text("prompt").notNull(),
|
|
21675
|
+
type: text("type").notNull().default(TASK_TYPES.USER_DM_MESSAGE),
|
|
21676
|
+
contextKey: text("context_key"),
|
|
21677
|
+
status: text("status").notNull().default("queued"),
|
|
21678
|
+
priority: integer2("priority").notNull().default(0),
|
|
21679
|
+
result: text("result", { mode: "json" }),
|
|
21680
|
+
context: text("context", { mode: "json" }),
|
|
21681
|
+
sessionId: text("session_id"),
|
|
21682
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
21683
|
+
dispatchedAt: text("dispatched_at"),
|
|
21684
|
+
startedAt: text("started_at"),
|
|
21685
|
+
completedAt: text("completed_at"),
|
|
21686
|
+
error: text("error"),
|
|
21687
|
+
traceId: text("trace_id"),
|
|
21688
|
+
parentTaskId: text("parent_task_id")
|
|
21689
|
+
}, (t) => [
|
|
21690
|
+
index("idx_task_queue_pending").on(t.agentId, t.status).where(sql`status IN ('queued', 'dispatched')`),
|
|
21691
|
+
index("idx_task_queue_workspace_active").on(t.workspaceId, t.status, t.agentId).where(sql`status IN ('queued', 'dispatched', 'running')`),
|
|
21692
|
+
index("idx_task_queue_agent_history").on(t.agentId, t.workspaceId, t.createdAt),
|
|
21693
|
+
index("idx_task_queue_conversation_status").on(t.conversationId, t.status),
|
|
21694
|
+
index("idx_task_queue_trace").on(t.traceId),
|
|
21695
|
+
index("idx_task_queue_parent").on(t.parentTaskId),
|
|
21696
|
+
index("idx_task_queue_workspace_type_status").on(t.workspaceId, t.type, t.status),
|
|
21697
|
+
index("idx_task_queue_workspace_status_dispatched").on(t.workspaceId, t.status, t.dispatchedAt),
|
|
21698
|
+
index("idx_task_queue_inbox").on(t.workspaceId, t.status, t.completedAt),
|
|
21699
|
+
index("idx_task_queue_runtime_pending").on(t.workspaceId, t.runtimeId, t.status).where(sql`status IN ('queued', 'dispatched')`),
|
|
21700
|
+
index("idx_task_queue_agent_running").on(t.agentId, t.workspaceId, t.status).where(sql`status IN ('dispatched', 'running')`),
|
|
21701
|
+
index("idx_task_queue_inbox_convo").on(t.workspaceId, t.status, t.conversationId, t.completedAt).where(sql`status IN ('completed', 'failed') AND parent_task_id IS NULL`),
|
|
21702
|
+
foreignKey({
|
|
21703
|
+
columns: [t.agentId, t.workspaceId],
|
|
21704
|
+
foreignColumns: [agent.id, agent.workspaceId]
|
|
21705
|
+
}).onDelete("cascade")
|
|
21706
|
+
]);
|
|
21707
|
+
var issue2 = sqliteTable("issue", {
|
|
21708
|
+
id: text("id").primaryKey().$defaultFn(() => "iss_" + nanoid3()),
|
|
21709
|
+
workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
|
|
21710
|
+
agentId: text("agent_id"),
|
|
21711
|
+
creatorUserId: text("creator_user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
21712
|
+
conversationId: text("conversation_id").references(() => conversation.id, { onDelete: "cascade" }),
|
|
21713
|
+
latestTaskId: text("latest_task_id").references(() => agentTaskQueue.id, {
|
|
21714
|
+
onDelete: "set null"
|
|
21715
|
+
}),
|
|
21716
|
+
title: text("title").notNull(),
|
|
21717
|
+
description: text("description").notNull().default(""),
|
|
21718
|
+
status: text("status").notNull().default("todo"),
|
|
21719
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
21720
|
+
updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
21721
|
+
completedAt: text("completed_at")
|
|
21722
|
+
}, (t) => [
|
|
21723
|
+
index("idx_issue_workspace_status_agent").on(t.workspaceId, t.status, t.agentId),
|
|
21724
|
+
index("idx_issue_workspace_updated").on(t.workspaceId, t.updatedAt),
|
|
21725
|
+
unique("issue_conversation_unique").on(t.conversationId),
|
|
21726
|
+
foreignKey({
|
|
21727
|
+
columns: [t.agentId, t.workspaceId],
|
|
21728
|
+
foreignColumns: [agent.id, agent.workspaceId]
|
|
21729
|
+
}).onDelete("cascade")
|
|
21730
|
+
]);
|
|
21731
|
+
var issueComment = sqliteTable("issue_comment", {
|
|
21732
|
+
id: text("id").primaryKey().$defaultFn(() => "ic_" + nanoid3()),
|
|
21733
|
+
issueId: text("issue_id").notNull().references(() => issue2.id, { onDelete: "cascade" }),
|
|
21734
|
+
workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
|
|
21735
|
+
authorType: text("author_type").notNull().default("user"),
|
|
21736
|
+
authorId: text("author_id").notNull(),
|
|
21737
|
+
content: text("content").notNull(),
|
|
21738
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21739
|
+
}, (t) => [
|
|
21740
|
+
index("idx_issue_comment_issue").on(t.issueId, t.createdAt),
|
|
21741
|
+
index("idx_issue_comment_workspace").on(t.workspaceId, t.issueId)
|
|
21742
|
+
]);
|
|
21743
|
+
var taskMessage = sqliteTable("task_message", {
|
|
21744
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
21745
|
+
taskId: text("task_id").notNull().references(() => agentTaskQueue.id, { onDelete: "cascade" }),
|
|
21746
|
+
seq: integer2("seq").notNull(),
|
|
21747
|
+
type: text("type").notNull().default(""),
|
|
21748
|
+
tool: text("tool").notNull().default(""),
|
|
21749
|
+
content: text("content").notNull().default(""),
|
|
21750
|
+
callId: text("call_id").notNull().default(""),
|
|
21751
|
+
input: text("input", { mode: "json" }),
|
|
21752
|
+
output: text("output").notNull().default(""),
|
|
21753
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21754
|
+
}, (t) => [
|
|
21755
|
+
index("idx_task_message_task_seq").on(t.taskId, t.seq),
|
|
21756
|
+
index("idx_task_message_task_created").on(t.taskId, t.createdAt)
|
|
21757
|
+
]);
|
|
21758
|
+
var emails = sqliteTable("emails", {
|
|
21759
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
21760
|
+
agentId: text("agent_id").notNull(),
|
|
21761
|
+
workspaceId: text("workspace_id").notNull(),
|
|
21762
|
+
fromEmail: text("from_email").notNull(),
|
|
21763
|
+
toEmail: text("to_email").notNull(),
|
|
21764
|
+
subject: text("subject").notNull().default(""),
|
|
21765
|
+
r2Key: text("r2_key").notNull(),
|
|
21766
|
+
isWhitelisted: integer2("is_whitelisted", { mode: "boolean" }).notNull().default(false),
|
|
21767
|
+
forwarded: integer2("forwarded", { mode: "boolean" }).notNull().default(false),
|
|
21768
|
+
messageId: text("message_id").notNull().default(""),
|
|
21769
|
+
inReplyTo: text("in_reply_to").notNull().default(""),
|
|
21770
|
+
references: text("references").notNull().default(""),
|
|
21771
|
+
htmlBody: text("html_body").notNull().default(""),
|
|
21772
|
+
attachments: text("attachments").notNull().default("[]"),
|
|
21773
|
+
status: text("status").notNull().default("unread"),
|
|
21774
|
+
direction: text("direction").notNull().default("inbound"),
|
|
21775
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21776
|
+
}, (t) => [
|
|
21777
|
+
foreignKey({
|
|
21778
|
+
columns: [t.agentId, t.workspaceId],
|
|
21779
|
+
foreignColumns: [agent.id, agent.workspaceId]
|
|
21780
|
+
}).onDelete("cascade"),
|
|
21781
|
+
index("idx_emails_agent_ws_status").on(t.agentId, t.workspaceId, t.status),
|
|
21782
|
+
index("idx_emails_to_direction").on(t.toEmail, t.direction),
|
|
21783
|
+
index("idx_emails_from_direction").on(t.fromEmail, t.direction),
|
|
21784
|
+
index("idx_emails_message_id").on(t.messageId),
|
|
21785
|
+
index("idx_emails_created_at").on(t.createdAt)
|
|
21786
|
+
]);
|
|
21787
|
+
var calendarEvent = sqliteTable("calendar_event", {
|
|
21788
|
+
id: text("id").primaryKey().$defaultFn(() => "ce_" + nanoid3()),
|
|
21789
|
+
agentId: text("agent_id").notNull(),
|
|
21790
|
+
workspaceId: text("workspace_id").notNull(),
|
|
21791
|
+
title: text("title").notNull(),
|
|
21792
|
+
description: text("description"),
|
|
21793
|
+
scheduledAt: text("scheduled_at").notNull(),
|
|
21794
|
+
repeatInterval: text("repeat_interval"),
|
|
21795
|
+
repeatStopAt: text("repeat_stop_at"),
|
|
21796
|
+
lastTriggeredAt: text("last_triggered_at"),
|
|
21797
|
+
exceptions: text("exceptions", { mode: "json" }).$type().notNull().default(sql`'[]'`),
|
|
21798
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
21799
|
+
updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21800
|
+
}, (t) => [
|
|
21801
|
+
index("idx_calendar_event_agent_ws").on(t.agentId, t.workspaceId),
|
|
21802
|
+
index("idx_calendar_event_ws_scheduled").on(t.workspaceId, t.scheduledAt),
|
|
21803
|
+
foreignKey({
|
|
21804
|
+
columns: [t.agentId, t.workspaceId],
|
|
21805
|
+
foreignColumns: [agent.id, agent.workspaceId]
|
|
21806
|
+
}).onDelete("cascade")
|
|
21807
|
+
]);
|
|
21808
|
+
var artifact = sqliteTable("artifact", {
|
|
21809
|
+
id: text("id").primaryKey().$defaultFn(() => "art_" + nanoid3()),
|
|
21810
|
+
conversationId: text("conversation_id").notNull().references(() => conversation.id, { onDelete: "cascade" }),
|
|
21811
|
+
agentId: text("agent_id").notNull(),
|
|
21812
|
+
workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
|
|
21813
|
+
filename: text("filename").notNull(),
|
|
21814
|
+
contentType: text("content_type").notNull().default("application/octet-stream"),
|
|
21815
|
+
size: integer2("size").notNull(),
|
|
21816
|
+
r2Key: text("r2_key").notNull(),
|
|
21817
|
+
thumbnailR2Key: text("thumbnail_r2_key"),
|
|
21818
|
+
source: text("source").notNull().default("agent"),
|
|
21819
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21820
|
+
}, (t) => [
|
|
21821
|
+
index("idx_artifact_conversation").on(t.conversationId),
|
|
21822
|
+
foreignKey({
|
|
21823
|
+
columns: [t.agentId, t.workspaceId],
|
|
21824
|
+
foreignColumns: [agent.id, agent.workspaceId]
|
|
21825
|
+
}).onDelete("cascade")
|
|
21826
|
+
]);
|
|
21827
|
+
var agentEmailAccount = sqliteTable("agent_email_account", {
|
|
21828
|
+
id: text("id").primaryKey().$defaultFn(() => "aea_" + nanoid3()),
|
|
21829
|
+
agentId: text("agent_id").notNull(),
|
|
21830
|
+
workspaceId: text("workspace_id").notNull(),
|
|
21831
|
+
emailAddress: text("email_address").notNull(),
|
|
21832
|
+
displayName: text("display_name").notNull().default(""),
|
|
21833
|
+
imapHost: text("imap_host").notNull(),
|
|
21834
|
+
imapPort: integer2("imap_port").notNull().default(993),
|
|
21835
|
+
imapUsername: text("imap_username").notNull(),
|
|
21836
|
+
imapPassword: text("imap_password").notNull(),
|
|
21837
|
+
imapTls: integer2("imap_tls", { mode: "boolean" }).notNull().default(true),
|
|
21838
|
+
smtpHost: text("smtp_host").notNull(),
|
|
21839
|
+
smtpPort: integer2("smtp_port").notNull().default(587),
|
|
21840
|
+
smtpUsername: text("smtp_username").notNull(),
|
|
21841
|
+
smtpPassword: text("smtp_password").notNull(),
|
|
21842
|
+
smtpTls: integer2("smtp_tls").notNull().default(1),
|
|
21843
|
+
pollIntervalSeconds: integer2("poll_interval_seconds").notNull().default(60),
|
|
21844
|
+
lastSyncedUid: text("last_synced_uid").notNull().default("0"),
|
|
21845
|
+
lastSyncedAt: text("last_synced_at"),
|
|
21846
|
+
status: text("status").notNull().default("active"),
|
|
21847
|
+
errorMessage: text("error_message").notNull().default(""),
|
|
21848
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
21849
|
+
updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21850
|
+
}, (t) => [
|
|
21851
|
+
index("idx_email_account_agent_ws").on(t.agentId, t.workspaceId),
|
|
21852
|
+
unique("email_account_agent_email").on(t.agentId, t.emailAddress),
|
|
21853
|
+
foreignKey({
|
|
21854
|
+
columns: [t.agentId, t.workspaceId],
|
|
21855
|
+
foreignColumns: [agent.id, agent.workspaceId]
|
|
21856
|
+
}).onDelete("cascade")
|
|
21857
|
+
]);
|
|
21858
|
+
var meetingSession = sqliteTable("meeting_session", {
|
|
21859
|
+
id: text("id").primaryKey().$defaultFn(() => "ms_" + nanoid3()),
|
|
21860
|
+
agentId: text("agent_id").notNull(),
|
|
21861
|
+
workspaceId: text("workspace_id").notNull(),
|
|
21862
|
+
title: text("title").notNull().default(""),
|
|
21863
|
+
meetingUrl: text("meeting_url").notNull(),
|
|
21864
|
+
status: text("status").notNull().default("scheduled"),
|
|
21865
|
+
fromEmail: text("from_email"),
|
|
21866
|
+
isWhitelisted: integer2("is_whitelisted", { mode: "boolean" }).notNull().default(true),
|
|
21867
|
+
participants: text("participants", { mode: "json" }).$type().notNull().default([]),
|
|
21868
|
+
scheduledAt: text("scheduled_at"),
|
|
21869
|
+
startedAt: text("started_at"),
|
|
21870
|
+
completedAt: text("completed_at"),
|
|
21871
|
+
transcriptR2Key: text("transcript_r2_key"),
|
|
21872
|
+
summary: text("summary"),
|
|
21873
|
+
error: text("error"),
|
|
21874
|
+
workerSessionId: text("worker_session_id"),
|
|
21875
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
21876
|
+
updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21877
|
+
}, (t) => [
|
|
21878
|
+
index("idx_meeting_session_agent_ws").on(t.agentId, t.workspaceId),
|
|
21879
|
+
index("idx_meeting_session_status").on(t.status),
|
|
21880
|
+
foreignKey({
|
|
21881
|
+
columns: [t.agentId, t.workspaceId],
|
|
21882
|
+
foreignColumns: [agent.id, agent.workspaceId]
|
|
21883
|
+
}).onDelete("cascade")
|
|
21884
|
+
]);
|
|
21885
|
+
var machineToken = sqliteTable("machine_token", {
|
|
21886
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
21887
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
21888
|
+
workspaceId: text("workspace_id").references(() => workspace.id, { onDelete: "cascade" }),
|
|
21889
|
+
token: text("token").unique().notNull(),
|
|
21890
|
+
name: text("name").notNull().default(""),
|
|
21891
|
+
status: text("status").notNull().default("active"),
|
|
21892
|
+
hostname: text("hostname"),
|
|
21893
|
+
runtimesJson: text("runtimes_json"),
|
|
21894
|
+
lastUsedAt: text("last_used_at"),
|
|
21895
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21896
|
+
}, (t) => [index("idx_machine_token").on(t.token)]);
|
|
21897
|
+
var messageFlag = sqliteTable("message_flag", {
|
|
21898
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
21899
|
+
messageId: text("message_id").notNull().references(() => message.id, { onDelete: "cascade" }),
|
|
21900
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
21901
|
+
workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
|
|
21902
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21903
|
+
}, (t) => [
|
|
21904
|
+
unique("message_flag_message_user").on(t.messageId, t.userId),
|
|
21905
|
+
index("idx_message_flag_ws_user_created").on(t.workspaceId, t.userId, t.createdAt),
|
|
21906
|
+
index("idx_message_flag_message_user").on(t.messageId, t.userId)
|
|
21907
|
+
]);
|
|
21908
|
+
var conversationMap = sqliteTable("conversation_map", {
|
|
21909
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
21910
|
+
key: text("key").notNull(),
|
|
21911
|
+
workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
|
|
21912
|
+
conversationId: text("conversation_id").notNull().references(() => conversation.id, { onDelete: "cascade" }),
|
|
21913
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21914
|
+
}, (t) => [
|
|
21915
|
+
unique("conversation_map_key_workspace").on(t.key, t.workspaceId)
|
|
21916
|
+
]);
|
|
21917
|
+
var agentLink = sqliteTable("agent_link", {
|
|
21918
|
+
id: text("id").primaryKey().$defaultFn(() => "al_" + nanoid3()),
|
|
21919
|
+
workspaceId: text("workspace_id").notNull(),
|
|
21920
|
+
sourceAgentId: text("source_agent_id").notNull(),
|
|
21921
|
+
targetAgentId: text("target_agent_id").notNull(),
|
|
21922
|
+
instruction: text("instruction").notNull().default(""),
|
|
21923
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
21924
|
+
updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21925
|
+
}, (t) => [
|
|
21926
|
+
unique("agent_link_ws_source_target").on(t.workspaceId, t.sourceAgentId, t.targetAgentId),
|
|
21927
|
+
index("idx_agent_link_workspace").on(t.workspaceId),
|
|
21928
|
+
foreignKey({
|
|
21929
|
+
columns: [t.sourceAgentId, t.workspaceId],
|
|
21930
|
+
foreignColumns: [agent.id, agent.workspaceId]
|
|
21931
|
+
}).onDelete("cascade"),
|
|
21932
|
+
foreignKey({
|
|
21933
|
+
columns: [t.targetAgentId, t.workspaceId],
|
|
21934
|
+
foreignColumns: [agent.id, agent.workspaceId]
|
|
21935
|
+
}).onDelete("cascade")
|
|
21936
|
+
]);
|
|
21937
|
+
var conversationReadState = sqliteTable("conversation_read_state", {
|
|
21938
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
21939
|
+
conversationId: text("conversation_id").notNull().references(() => conversation.id, { onDelete: "cascade" }),
|
|
21940
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
21941
|
+
lastReadAt: text("last_read_at").notNull().default("1970-01-01T00:00:00.000Z"),
|
|
21942
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21943
|
+
}, (t) => [
|
|
21944
|
+
unique("conversation_read_state_conv_user").on(t.conversationId, t.userId),
|
|
21945
|
+
index("idx_conversation_read_state_user").on(t.userId)
|
|
21946
|
+
]);
|
|
21947
|
+
var workspaceFileRequest = sqliteTable("workspace_file_request", {
|
|
21948
|
+
id: text("id").primaryKey().$defaultFn(() => "wfr_" + nanoid3()),
|
|
21949
|
+
workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
|
|
21950
|
+
agentId: text("agent_id").notNull(),
|
|
21951
|
+
requestType: text("request_type").notNull(),
|
|
21952
|
+
path: text("path").notNull().default("."),
|
|
21953
|
+
status: text("status").notNull().default("pending"),
|
|
21954
|
+
result: text("result"),
|
|
21955
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
21956
|
+
updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21957
|
+
}, (t) => [
|
|
21958
|
+
index("idx_wfr_workspace_status").on(t.workspaceId, t.status)
|
|
21959
|
+
]);
|
|
21960
|
+
var agentSkill = sqliteTable("agent_skill", {
|
|
21961
|
+
id: text("id").primaryKey().$defaultFn(() => "as_" + nanoid3()),
|
|
21962
|
+
workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
|
|
21963
|
+
agentId: text("agent_id"),
|
|
21964
|
+
daemonId: text("daemon_id"),
|
|
21965
|
+
runtime: text("runtime").notNull(),
|
|
21966
|
+
name: text("name").notNull(),
|
|
21967
|
+
description: text("description").notNull().default(""),
|
|
21968
|
+
syncedAt: text("synced_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
21969
|
+
}, (t) => [
|
|
21970
|
+
unique("agent_skill_ws_runtime_name_agent_daemon").on(t.workspaceId, t.runtime, t.name, t.agentId, t.daemonId),
|
|
21971
|
+
index("idx_as_workspace_runtime").on(t.workspaceId, t.runtime),
|
|
21972
|
+
index("idx_as_agent_runtime").on(t.agentId, t.runtime),
|
|
21973
|
+
foreignKey({
|
|
21974
|
+
columns: [t.agentId, t.workspaceId],
|
|
21975
|
+
foreignColumns: [agent.id, agent.workspaceId]
|
|
21976
|
+
}).onDelete("cascade")
|
|
21977
|
+
]);
|
|
21978
|
+
var inboxUnread = sqliteTable("inbox_unread", {
|
|
21979
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
21980
|
+
conversationId: text("conversation_id").notNull().references(() => conversation.id, { onDelete: "cascade" }),
|
|
21981
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
21982
|
+
workspaceId: text("workspace_id").notNull(),
|
|
21983
|
+
agentId: text("agent_id").notNull(),
|
|
21984
|
+
taskId: text("task_id").notNull(),
|
|
21985
|
+
taskType: text("task_type").notNull(),
|
|
21986
|
+
taskStatus: text("task_status").notNull(),
|
|
21987
|
+
taskPrompt: text("task_prompt"),
|
|
21988
|
+
completedAt: text("completed_at").notNull(),
|
|
21989
|
+
latestMessageId: text("latest_message_id")
|
|
21990
|
+
}, (t) => [
|
|
21991
|
+
unique("inbox_unread_conv_user").on(t.conversationId, t.userId),
|
|
21992
|
+
index("idx_inbox_unread_user_ws").on(t.userId, t.workspaceId, t.taskType, t.completedAt)
|
|
21993
|
+
]);
|
|
21994
|
+
|
|
21995
|
+
// ../shared/src/db/community-machine-schema.ts
|
|
21996
|
+
var DIAGNOSTIC_REPORT_FAILURE_CODES = [
|
|
21997
|
+
"offline",
|
|
21998
|
+
"timeout",
|
|
21999
|
+
"upload_conflict",
|
|
22000
|
+
"invalid_upload",
|
|
22001
|
+
"diagnostics_unavailable",
|
|
22002
|
+
"collector_busy",
|
|
22003
|
+
"bot_not_bound",
|
|
22004
|
+
"collection_failed",
|
|
22005
|
+
"local_artifact_invalid",
|
|
22006
|
+
"bundle_too_large",
|
|
22007
|
+
"upload_failed",
|
|
22008
|
+
"internal_error"
|
|
22009
|
+
];
|
|
22010
|
+
var communityDiagnosticReport = sqliteTable("community_diagnostic_report", {
|
|
22011
|
+
id: text("id").primaryKey().$defaultFn(() => "dbr_" + nanoid3()),
|
|
22012
|
+
ownerUserId: text("owner_user_id").notNull(),
|
|
22013
|
+
agentId: text("agent_id").notNull(),
|
|
22014
|
+
machineId: text("machine_id").notNull(),
|
|
22015
|
+
clientNonce: text("client_nonce").notNull(),
|
|
22016
|
+
rateBucket: integer2("rate_bucket").notNull(),
|
|
22017
|
+
status: text("status").$type().notNull().default("pending"),
|
|
22018
|
+
failureCode: text("failure_code").$type(),
|
|
22019
|
+
fromMs: integer2("from_ms").notNull(),
|
|
22020
|
+
createdAt: integer2("created_at").notNull(),
|
|
22021
|
+
deadlineAt: integer2("deadline_at").notNull(),
|
|
22022
|
+
completedAt: integer2("completed_at"),
|
|
22023
|
+
r2Key: text("r2_key"),
|
|
22024
|
+
sha256: text("sha256"),
|
|
22025
|
+
sizeBytes: integer2("size_bytes"),
|
|
22026
|
+
uploadedAt: integer2("uploaded_at"),
|
|
22027
|
+
objectExpiresAt: integer2("object_expires_at")
|
|
22028
|
+
}, (t) => [
|
|
22029
|
+
index("idx_community_diagnostic_report_owner_created").on(t.ownerUserId, t.createdAt),
|
|
22030
|
+
index("idx_community_diagnostic_report_machine_status_deadline").on(t.machineId, t.status, t.deadlineAt),
|
|
22031
|
+
uniqueIndex("uq_community_diagnostic_report_owner_nonce").on(t.ownerUserId, t.clientNonce),
|
|
22032
|
+
uniqueIndex("uq_community_diagnostic_report_owner_agent_pending").on(t.ownerUserId, t.agentId).where(sql`status = 'pending'`),
|
|
22033
|
+
uniqueIndex("uq_community_diagnostic_report_owner_rate_bucket").on(t.ownerUserId, t.rateBucket),
|
|
22034
|
+
check2("ck_community_diagnostic_report_id", sql`length(${t.id}) > 4 AND substr(${t.id}, 1, 4) = 'dbr_' AND ${t.id} NOT GLOB '*[^A-Za-z0-9_-]*'`),
|
|
22035
|
+
check2("ck_community_diagnostic_report_nonce", sql`length(${t.clientNonce}) BETWEEN 16 AND 64 AND ${t.clientNonce} NOT GLOB '*[^A-Za-z0-9_-]*'`),
|
|
22036
|
+
check2("ck_community_diagnostic_report_required_epochs", sql`typeof(${t.fromMs}) = 'integer' AND ${t.fromMs} BETWEEN 0 AND 9007199254740991
|
|
22037
|
+
AND typeof(${t.createdAt}) = 'integer' AND ${t.createdAt} BETWEEN 0 AND 9007199254740991
|
|
22038
|
+
AND typeof(${t.deadlineAt}) = 'integer' AND ${t.deadlineAt} BETWEEN 0 AND 9007199254740991
|
|
22039
|
+
AND ${t.fromMs} = ${t.createdAt} - 86400000
|
|
22040
|
+
AND ${t.deadlineAt} = ${t.createdAt} + 600000`),
|
|
22041
|
+
check2("ck_community_diagnostic_report_rate_bucket", sql`typeof(${t.rateBucket}) = 'integer'
|
|
22042
|
+
AND ${t.rateBucket} BETWEEN 0 AND 9007199254740991
|
|
22043
|
+
AND ${t.rateBucket} = CAST(${t.createdAt} / 60000 AS INTEGER)`),
|
|
22044
|
+
check2("ck_community_diagnostic_report_nullable_epochs", sql`(${t.completedAt} IS NULL OR (typeof(${t.completedAt}) = 'integer' AND ${t.completedAt} BETWEEN 0 AND 9007199254740991))
|
|
22045
|
+
AND (${t.uploadedAt} IS NULL OR (typeof(${t.uploadedAt}) = 'integer' AND ${t.uploadedAt} BETWEEN 0 AND 9007199254740991))
|
|
22046
|
+
AND (${t.objectExpiresAt} IS NULL OR (typeof(${t.objectExpiresAt}) = 'integer' AND ${t.objectExpiresAt} BETWEEN 0 AND 9007199254740991))`),
|
|
22047
|
+
check2("ck_community_diagnostic_report_size", sql`${t.sizeBytes} IS NULL OR (typeof(${t.sizeBytes}) = 'integer' AND ${t.sizeBytes} BETWEEN 1 AND 10485760)`),
|
|
22048
|
+
check2("ck_community_diagnostic_report_sha256", sql`${t.sha256} IS NULL OR (length(${t.sha256}) = 64 AND ${t.sha256} NOT GLOB '*[^0-9a-f]*')`),
|
|
22049
|
+
check2("ck_community_diagnostic_report_state", sql`(
|
|
22050
|
+
${t.status} = 'pending'
|
|
22051
|
+
AND ${t.failureCode} IS NULL AND ${t.completedAt} IS NULL
|
|
22052
|
+
AND ${t.r2Key} IS NULL AND ${t.sha256} IS NULL AND ${t.sizeBytes} IS NULL
|
|
22053
|
+
AND ${t.uploadedAt} IS NULL AND ${t.objectExpiresAt} IS NULL
|
|
22054
|
+
) OR (
|
|
22055
|
+
${t.status} = 'failed'
|
|
22056
|
+
AND ${t.failureCode} IN ('offline', 'timeout', 'upload_conflict', 'invalid_upload', 'diagnostics_unavailable', 'collector_busy', 'bot_not_bound', 'collection_failed', 'local_artifact_invalid', 'bundle_too_large', 'upload_failed', 'internal_error')
|
|
22057
|
+
AND ${t.completedAt} IS NOT NULL
|
|
22058
|
+
AND ${t.completedAt} >= ${t.createdAt}
|
|
22059
|
+
AND ${t.r2Key} IS NULL AND ${t.sha256} IS NULL AND ${t.sizeBytes} IS NULL
|
|
22060
|
+
AND ${t.uploadedAt} IS NULL AND ${t.objectExpiresAt} IS NULL
|
|
22061
|
+
) OR (
|
|
22062
|
+
${t.status} = 'uploaded'
|
|
22063
|
+
AND ${t.failureCode} IS NULL AND ${t.completedAt} IS NOT NULL
|
|
22064
|
+
AND ${t.completedAt} >= ${t.createdAt}
|
|
22065
|
+
AND ${t.r2Key} IS NOT NULL
|
|
22066
|
+
AND ${t.r2Key} = 'bug-reports/' || ${t.ownerUserId} || '/' || ${t.id} || '.ndjson.gz'
|
|
22067
|
+
AND ${t.sha256} IS NOT NULL AND ${t.sizeBytes} IS NOT NULL
|
|
22068
|
+
AND ${t.uploadedAt} IS NOT NULL AND ${t.objectExpiresAt} IS NOT NULL
|
|
22069
|
+
AND ${t.completedAt} = ${t.uploadedAt}
|
|
22070
|
+
AND ${t.objectExpiresAt} = ${t.uploadedAt} + 604800000
|
|
22071
|
+
)`)
|
|
22072
|
+
]);
|
|
22073
|
+
var communityMachineToken = sqliteTable("community_machine_token", {
|
|
22074
|
+
id: text("id").primaryKey().$defaultFn(() => "cmt_" + nanoid3(32)),
|
|
22075
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
22076
|
+
machineId: text("machine_id"),
|
|
22077
|
+
status: text("status").notNull().default("pending"),
|
|
22078
|
+
expiresAt: text("expires_at").notNull(),
|
|
22079
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
22080
|
+
lastUsedAt: text("last_used_at")
|
|
22081
|
+
}, (t) => [
|
|
22082
|
+
index("idx_community_machine_token_user_status").on(t.userId, t.status),
|
|
22083
|
+
uniqueIndex("uq_community_machine_token_user_pending").on(t.userId).where(sql`status = 'pending'`)
|
|
22084
|
+
]);
|
|
22085
|
+
var communityMachine = sqliteTable("community_machine", {
|
|
22086
|
+
id: text("id").primaryKey().$defaultFn(() => "cm_" + nanoid3()),
|
|
22087
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
22088
|
+
displayName: text("display_name").notNull().default(""),
|
|
22089
|
+
hostname: text("hostname").notNull().default(""),
|
|
22090
|
+
platform: text("platform").notNull().default(""),
|
|
22091
|
+
arch: text("arch").notNull().default(""),
|
|
22092
|
+
osRelease: text("os_release").notNull().default(""),
|
|
22093
|
+
daemonVersion: text("daemon_version").notNull().default(""),
|
|
22094
|
+
metadata: text("metadata"),
|
|
22095
|
+
availableRuntimes: text("available_runtimes", { mode: "json" }).$type().notNull().default([]),
|
|
22096
|
+
status: text("status").notNull().default("offline"),
|
|
22097
|
+
lastSeenAt: text("last_seen_at"),
|
|
22098
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
22099
|
+
updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
22100
|
+
}, (t) => [
|
|
22101
|
+
index("idx_community_machine_user_last_seen").on(t.userId, t.lastSeenAt),
|
|
22102
|
+
index("idx_community_machine_user_updated").on(t.userId, t.updatedAt),
|
|
22103
|
+
index("idx_community_machine_user_status").on(t.userId, t.status)
|
|
22104
|
+
]);
|
|
22105
|
+
var communityMachineCredential = sqliteTable("community_machine_credential", {
|
|
22106
|
+
id: text("id").primaryKey().$defaultFn(() => "cmkid_" + nanoid3()),
|
|
22107
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
22108
|
+
machineId: text("machine_id").notNull().references(() => communityMachine.id, { onDelete: "cascade" }),
|
|
22109
|
+
credentialHash: text("credential_hash").notNull().unique(),
|
|
22110
|
+
doName: text("do_name").notNull().unique(),
|
|
22111
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
22112
|
+
lastUsedAt: text("last_used_at"),
|
|
22113
|
+
revokedAt: text("revoked_at")
|
|
22114
|
+
}, (t) => [
|
|
22115
|
+
index("idx_community_machine_credential_user").on(t.userId),
|
|
22116
|
+
index("idx_community_machine_credential_machine").on(t.machineId)
|
|
22117
|
+
]);
|
|
22118
|
+
var communityBotBinding = sqliteTable("community_bot_binding", {
|
|
22119
|
+
userId: text("user_id").primaryKey().references(() => user.id, { onDelete: "cascade" }),
|
|
22120
|
+
machineId: text("machine_id").notNull().references(() => communityMachine.id, { onDelete: "restrict" }),
|
|
22121
|
+
runtime: text("runtime").notNull(),
|
|
22122
|
+
modelName: text("model_name"),
|
|
22123
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
22124
|
+
}, (t) => [index("idx_community_bot_binding_machine").on(t.machineId)]);
|
|
22125
|
+
var communityAgentRunnerKey = sqliteTable("community_agent_runner_key", {
|
|
22126
|
+
id: text("id").primaryKey().$defaultFn(() => "crkid_" + nanoid3()),
|
|
22127
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
22128
|
+
machineId: text("machine_id").notNull().references(() => communityMachine.id, { onDelete: "cascade" }),
|
|
22129
|
+
agentId: text("agent_id").notNull(),
|
|
22130
|
+
runnerKeyHash: text("runner_key_hash").notNull().unique(),
|
|
22131
|
+
doName: text("do_name").notNull().unique(),
|
|
22132
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
22133
|
+
revokedAt: text("revoked_at")
|
|
22134
|
+
}, (t) => [
|
|
22135
|
+
index("idx_community_agent_runner_key_machine_agent").on(t.machineId, t.agentId)
|
|
22136
|
+
]);
|
|
22137
|
+
|
|
22138
|
+
// ../shared/src/diagnostics-contract.ts
|
|
22139
|
+
var DIAGNOSTIC_REPORT_COLLECTION_WINDOW_MS = 86400000;
|
|
22140
|
+
var DIAGNOSTIC_REPORT_DEADLINE_WINDOW_MS = 600000;
|
|
22141
|
+
var DIAGNOSTIC_COLLECT_SPAN_MS = DIAGNOSTIC_REPORT_COLLECTION_WINDOW_MS + DIAGNOSTIC_REPORT_DEADLINE_WINDOW_MS;
|
|
22142
|
+
var SafeEpochSchema = exports_external.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
|
|
22143
|
+
var AgentIdSchema = exports_external.string().min(1).regex(/^[A-Za-z0-9_-]+$/);
|
|
22144
|
+
var DiagnosticReportIdSchema = exports_external.string().regex(/^dbr_[A-Za-z0-9_-]+$/);
|
|
22145
|
+
var DiagnosticReportFailureCodeSchema = exports_external.enum(DIAGNOSTIC_REPORT_FAILURE_CODES);
|
|
22146
|
+
var DiagnosticReportCreateRequestSchema = exports_external.object({
|
|
22147
|
+
clientNonce: exports_external.string().min(16).max(64).regex(/^[A-Za-z0-9_-]+$/)
|
|
22148
|
+
}).strict();
|
|
22149
|
+
var DiagnosticCollectPayloadSchema = exports_external.object({
|
|
22150
|
+
reportId: DiagnosticReportIdSchema,
|
|
22151
|
+
agentId: AgentIdSchema,
|
|
22152
|
+
fromMs: SafeEpochSchema,
|
|
22153
|
+
deadlineAt: SafeEpochSchema
|
|
22154
|
+
}).strict();
|
|
22155
|
+
var DiagnosticCollectCommandSchema = exports_external.object({
|
|
22156
|
+
type: exports_external.literal("diagnostics:collect"),
|
|
22157
|
+
reportId: DiagnosticReportIdSchema,
|
|
22158
|
+
agentId: AgentIdSchema,
|
|
22159
|
+
fromMs: SafeEpochSchema,
|
|
22160
|
+
deadlineAt: SafeEpochSchema
|
|
22161
|
+
}).strict().refine((command) => command.deadlineAt - command.fromMs === DIAGNOSTIC_COLLECT_SPAN_MS, { message: "diagnostic collection span must match v1" });
|
|
22162
|
+
var OwnerDiagnosticReportBase = {
|
|
22163
|
+
reportId: DiagnosticReportIdSchema,
|
|
22164
|
+
deadlineAt: SafeEpochSchema
|
|
22165
|
+
};
|
|
22166
|
+
var OwnerDiagnosticReportSchema = exports_external.discriminatedUnion("status", [
|
|
22167
|
+
exports_external.object({
|
|
22168
|
+
...OwnerDiagnosticReportBase,
|
|
22169
|
+
status: exports_external.literal("pending"),
|
|
22170
|
+
completedAt: exports_external.null(),
|
|
22171
|
+
failureCode: exports_external.null(),
|
|
22172
|
+
objectExpired: exports_external.literal(false)
|
|
22173
|
+
}).strict(),
|
|
22174
|
+
exports_external.object({
|
|
22175
|
+
...OwnerDiagnosticReportBase,
|
|
22176
|
+
status: exports_external.literal("uploaded"),
|
|
22177
|
+
completedAt: SafeEpochSchema,
|
|
22178
|
+
failureCode: exports_external.null(),
|
|
22179
|
+
objectExpired: exports_external.boolean()
|
|
22180
|
+
}).strict(),
|
|
22181
|
+
exports_external.object({
|
|
22182
|
+
...OwnerDiagnosticReportBase,
|
|
22183
|
+
status: exports_external.literal("failed"),
|
|
22184
|
+
completedAt: SafeEpochSchema,
|
|
22185
|
+
failureCode: DiagnosticReportFailureCodeSchema,
|
|
22186
|
+
objectExpired: exports_external.literal(false)
|
|
22187
|
+
}).strict()
|
|
22188
|
+
]);
|
|
22189
|
+
|
|
22190
|
+
// ../shared/src/community-cli-contract.ts
|
|
22191
|
+
var HostCommandSchema = exports_external.discriminatedUnion("type", [
|
|
22192
|
+
exports_external.object({
|
|
22193
|
+
type: exports_external.literal("agent:wake"),
|
|
22194
|
+
agentId: exports_external.string().min(1),
|
|
22195
|
+
config: exports_external.unknown(),
|
|
22196
|
+
sessionId: exports_external.string().optional(),
|
|
22197
|
+
launchId: exports_external.string().min(1),
|
|
22198
|
+
unreadNotice: exports_external.unknown()
|
|
22199
|
+
}),
|
|
22200
|
+
exports_external.object({
|
|
22201
|
+
type: exports_external.literal("agent:stop"),
|
|
22202
|
+
agentId: exports_external.string().min(1)
|
|
22203
|
+
}),
|
|
22204
|
+
exports_external.object({
|
|
22205
|
+
type: exports_external.literal("agent:reset"),
|
|
22206
|
+
agentId: exports_external.string().min(1),
|
|
22207
|
+
config: exports_external.unknown(),
|
|
22208
|
+
launchId: exports_external.string().min(1)
|
|
22209
|
+
}),
|
|
22210
|
+
exports_external.object({
|
|
22211
|
+
type: exports_external.literal("agent:nap"),
|
|
22212
|
+
agentId: exports_external.string().min(1),
|
|
22213
|
+
config: exports_external.unknown(),
|
|
22214
|
+
launchId: exports_external.string().min(1),
|
|
22215
|
+
handoff: exports_external.string().min(1)
|
|
22216
|
+
}),
|
|
22217
|
+
exports_external.object({
|
|
22218
|
+
type: exports_external.literal("agent:model_switch"),
|
|
22219
|
+
agentId: exports_external.string().min(1),
|
|
22220
|
+
config: exports_external.unknown(),
|
|
22221
|
+
launchId: exports_external.string().min(1)
|
|
22222
|
+
}),
|
|
22223
|
+
exports_external.object({
|
|
22224
|
+
type: exports_external.literal("machine:reset_all"),
|
|
22225
|
+
resets: exports_external.array(exports_external.object({
|
|
22226
|
+
agentId: exports_external.string().min(1),
|
|
22227
|
+
config: exports_external.unknown(),
|
|
22228
|
+
launchId: exports_external.string().min(1)
|
|
22229
|
+
}))
|
|
22230
|
+
}),
|
|
22231
|
+
exports_external.object({
|
|
22232
|
+
type: exports_external.literal("bot:added"),
|
|
22233
|
+
botId: exports_external.string().min(1),
|
|
22234
|
+
name: exports_external.string().optional(),
|
|
22235
|
+
discriminator: exports_external.string().optional(),
|
|
22236
|
+
description: exports_external.string().optional(),
|
|
22237
|
+
ownerName: exports_external.string().optional(),
|
|
22238
|
+
ownerDiscriminator: exports_external.string().optional()
|
|
22239
|
+
}),
|
|
22240
|
+
exports_external.object({
|
|
22241
|
+
type: exports_external.literal("bot:updated"),
|
|
22242
|
+
botId: exports_external.string().min(1),
|
|
22243
|
+
name: exports_external.string().optional(),
|
|
22244
|
+
discriminator: exports_external.string().optional(),
|
|
22245
|
+
description: exports_external.string().optional(),
|
|
22246
|
+
ownerName: exports_external.string().optional(),
|
|
22247
|
+
ownerDiscriminator: exports_external.string().optional()
|
|
22248
|
+
}),
|
|
22249
|
+
exports_external.object({
|
|
22250
|
+
type: exports_external.literal("bot:removed"),
|
|
22251
|
+
botId: exports_external.string().min(1)
|
|
22252
|
+
}),
|
|
22253
|
+
DiagnosticCollectCommandSchema
|
|
22254
|
+
]);
|
|
22255
|
+
// src/server/wsControlChannel.ts
|
|
22256
|
+
var WS_CONTROL_COMMAND_CONSUMED = Symbol("ws-control-command-consumed");
|
|
22257
|
+
var DEFAULT_PING_INTERVAL_MS = 15000;
|
|
22258
|
+
var DEFAULT_PONG_TIMEOUT_MS = 30000;
|
|
22259
|
+
var DEFAULT_RECONNECT_BASE_MS = 500;
|
|
22260
|
+
var DEFAULT_RECONNECT_MAX_MS = 30000;
|
|
22261
|
+
function describeErr(err) {
|
|
22262
|
+
return err instanceof Error ? err.message : String(err);
|
|
22263
|
+
}
|
|
22264
|
+
|
|
22265
|
+
class WsControlChannel {
|
|
22266
|
+
opts;
|
|
22267
|
+
statusValue = "idle";
|
|
22268
|
+
commandCbs = [];
|
|
22269
|
+
resyncHooks = [];
|
|
22270
|
+
ws = null;
|
|
22271
|
+
attempt = 0;
|
|
22272
|
+
closedByUser = false;
|
|
22273
|
+
authRejected = false;
|
|
22274
|
+
pingTimer = null;
|
|
22275
|
+
pongDeadline = 0;
|
|
22276
|
+
resyncProvider = null;
|
|
22277
|
+
log;
|
|
22278
|
+
constructor(opts) {
|
|
22279
|
+
this.opts = opts;
|
|
22280
|
+
this.log = opts.logger ?? createLogger({ header: "@alook/daemon:ws" });
|
|
22281
|
+
}
|
|
22282
|
+
get status() {
|
|
22283
|
+
return this.statusValue;
|
|
22284
|
+
}
|
|
22285
|
+
connect() {
|
|
22286
|
+
this.closedByUser = false;
|
|
22287
|
+
this.authRejected = false;
|
|
22288
|
+
this.openSocket();
|
|
22289
|
+
}
|
|
22290
|
+
close() {
|
|
22291
|
+
this.closedByUser = true;
|
|
22292
|
+
this.clearHeartbeat();
|
|
22293
|
+
this.ws?.close();
|
|
22294
|
+
this.ws = null;
|
|
22295
|
+
this.statusValue = "closed";
|
|
22296
|
+
}
|
|
22297
|
+
onCommand(cb) {
|
|
22298
|
+
this.commandCbs.push(cb);
|
|
22299
|
+
}
|
|
22300
|
+
onResync(provider) {
|
|
22301
|
+
this.resyncProvider = provider;
|
|
22302
|
+
}
|
|
22303
|
+
onOpen(hook) {
|
|
22304
|
+
this.resyncHooks.push(hook);
|
|
22305
|
+
}
|
|
22306
|
+
async reportReady(ready) {
|
|
22307
|
+
this.sendFrame({ type: "ready", ...ready });
|
|
22308
|
+
}
|
|
22309
|
+
sendReady(ready) {
|
|
22310
|
+
this.sendFrame({ type: "ready", ...ready });
|
|
22311
|
+
}
|
|
22312
|
+
async reportAgentSession(info) {
|
|
22313
|
+
this.sendFrame({ type: "agent_session", ...info });
|
|
22314
|
+
}
|
|
22315
|
+
async reportAgentActivity(info) {
|
|
22316
|
+
this.sendFrame({ type: "agent_activity", ...info });
|
|
22317
|
+
}
|
|
22318
|
+
reportAgentTyping(info) {
|
|
22319
|
+
this.sendFrame({ type: "agent_typing", ...info });
|
|
22320
|
+
}
|
|
22321
|
+
reportAgentTypingStop(info) {
|
|
22322
|
+
this.sendFrame({ type: "agent_typing_stop", ...info });
|
|
22323
|
+
}
|
|
22324
|
+
async reportBotAuditEvent(frame) {
|
|
22325
|
+
this.sendFrame(frame);
|
|
22326
|
+
}
|
|
22327
|
+
async reportWakeAck(info) {
|
|
22328
|
+
this.sendFrame({ type: "agent_wake_ack", ...info });
|
|
22329
|
+
}
|
|
22330
|
+
async reportStoppedAck(info) {
|
|
22331
|
+
this.sendFrame({ type: "agent_stopped_ack", ...info });
|
|
22332
|
+
}
|
|
22333
|
+
async reportSessionError(frame) {
|
|
22334
|
+
this.sendFrame(frame);
|
|
22335
|
+
}
|
|
22336
|
+
sendFrame(frame) {
|
|
22337
|
+
if (this.statusValue !== "open" || !this.ws) {
|
|
22338
|
+
this.log.debug("frame dropped — socket not open", { type: frame.type });
|
|
22339
|
+
return;
|
|
22340
|
+
}
|
|
22341
|
+
this.ws.send(JSON.stringify(frame));
|
|
22342
|
+
}
|
|
22343
|
+
resyncOnConnect() {
|
|
19765
22344
|
if (this.resyncProvider) {
|
|
19766
22345
|
const { ready, sessions, activities } = this.resyncProvider();
|
|
19767
22346
|
this.sendFrame({ type: "ready", ...ready });
|
|
@@ -19828,7 +22407,10 @@ class WsControlChannel {
|
|
|
19828
22407
|
const cmd = parsed.data;
|
|
19829
22408
|
for (const cb of this.commandCbs) {
|
|
19830
22409
|
try {
|
|
19831
|
-
|
|
22410
|
+
const result = cb(cmd);
|
|
22411
|
+
if (result === WS_CONTROL_COMMAND_CONSUMED)
|
|
22412
|
+
break;
|
|
22413
|
+
Promise.resolve(result).catch((err) => {
|
|
19832
22414
|
this.log.warn("command listener threw", { type: cmd.type, err: describeErr(err) });
|
|
19833
22415
|
});
|
|
19834
22416
|
} catch (err) {
|
|
@@ -19888,8 +22470,9 @@ class WsControlChannel {
|
|
|
19888
22470
|
}
|
|
19889
22471
|
}
|
|
19890
22472
|
// src/timeline/timeline.ts
|
|
19891
|
-
import
|
|
19892
|
-
import {
|
|
22473
|
+
import * as fs7 from "node:fs";
|
|
22474
|
+
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
22475
|
+
import { basename, dirname as dirname2, join as join9 } from "node:path";
|
|
19893
22476
|
|
|
19894
22477
|
// src/timeline/filelock.ts
|
|
19895
22478
|
import * as fs6 from "fs";
|
|
@@ -19952,6 +22535,261 @@ function reclaim(lockPath) {
|
|
|
19952
22535
|
}
|
|
19953
22536
|
|
|
19954
22537
|
// src/timeline/timeline.ts
|
|
22538
|
+
var TIMELINE_MAX_BYTES = 1048576;
|
|
22539
|
+
var TIMELINE_READ_CHUNK_BYTES = 65536;
|
|
22540
|
+
var DATE_FILENAME_PATTERN = /^\d{4}-\d{2}-\d{2}\.jsonl$/;
|
|
22541
|
+
function isBarrier(entry) {
|
|
22542
|
+
return entry.system?.type === "reset_session" || entry.system?.type === "nap";
|
|
22543
|
+
}
|
|
22544
|
+
function canonicalTimelineEntry(value) {
|
|
22545
|
+
if (!value || typeof value !== "object")
|
|
22546
|
+
return null;
|
|
22547
|
+
const entry = value;
|
|
22548
|
+
if (entry.system) {
|
|
22549
|
+
if (entry.system.type !== "reset_session" && entry.system.type !== "nap" || typeof entry.system.time !== "string")
|
|
22550
|
+
return null;
|
|
22551
|
+
return createSystemEntry(entry.system.type, entry.system.time);
|
|
22552
|
+
}
|
|
22553
|
+
if (entry.session_id !== null && typeof entry.session_id !== "string")
|
|
22554
|
+
return null;
|
|
22555
|
+
if (entry.provider !== null && typeof entry.provider !== "string")
|
|
22556
|
+
return null;
|
|
22557
|
+
if (!Array.isArray(entry.messages) || !Array.isArray(entry.agent_responses))
|
|
22558
|
+
return null;
|
|
22559
|
+
if (!entry.agent_responses.every((response) => typeof response === "string"))
|
|
22560
|
+
return null;
|
|
22561
|
+
return {
|
|
22562
|
+
session_id: entry.session_id,
|
|
22563
|
+
messages: entry.messages,
|
|
22564
|
+
agent_responses: entry.agent_responses.slice(-5),
|
|
22565
|
+
provider: entry.provider
|
|
22566
|
+
};
|
|
22567
|
+
}
|
|
22568
|
+
function timelineLine(entry) {
|
|
22569
|
+
const boundedEntry = entry.system ? createSystemEntry(entry.system.type, entry.system.time) : { ...entry, agent_responses: entry.agent_responses.slice(-5) };
|
|
22570
|
+
const text2 = JSON.stringify(boundedEntry);
|
|
22571
|
+
const bytes = Buffer.byteLength(text2, "utf8") + 1;
|
|
22572
|
+
if (bytes > TIMELINE_MAX_BYTES)
|
|
22573
|
+
return null;
|
|
22574
|
+
return { text: text2, bytes, entry: boundedEntry, barrier: isBarrier(boundedEntry) };
|
|
22575
|
+
}
|
|
22576
|
+
function compactLines(input) {
|
|
22577
|
+
let head = 0;
|
|
22578
|
+
let bytes = input.reduce((total, line) => total + line.bytes, 0);
|
|
22579
|
+
let latestEvictedBarrier = null;
|
|
22580
|
+
while (bytes > TIMELINE_MAX_BYTES && head < input.length) {
|
|
22581
|
+
const removed = input[head++];
|
|
22582
|
+
bytes -= removed.bytes;
|
|
22583
|
+
if (removed.barrier)
|
|
22584
|
+
latestEvictedBarrier = removed;
|
|
22585
|
+
}
|
|
22586
|
+
let suffix = input.slice(head);
|
|
22587
|
+
if (!suffix.some((line) => line.barrier) && latestEvictedBarrier) {
|
|
22588
|
+
let suffixHead = 0;
|
|
22589
|
+
while (latestEvictedBarrier.bytes + bytes > TIMELINE_MAX_BYTES && suffixHead < suffix.length) {
|
|
22590
|
+
bytes -= suffix[suffixHead++].bytes;
|
|
22591
|
+
}
|
|
22592
|
+
suffix = [latestEvictedBarrier, ...suffix.slice(suffixHead)];
|
|
22593
|
+
}
|
|
22594
|
+
return suffix;
|
|
22595
|
+
}
|
|
22596
|
+
function isRealDirectory(path8) {
|
|
22597
|
+
try {
|
|
22598
|
+
return fs7.lstatSync(path8).isDirectory();
|
|
22599
|
+
} catch {
|
|
22600
|
+
return false;
|
|
22601
|
+
}
|
|
22602
|
+
}
|
|
22603
|
+
function timelineDirectoryState(timelineDir) {
|
|
22604
|
+
if (!isRealDirectory(dirname2(timelineDir)))
|
|
22605
|
+
return "unsafe";
|
|
22606
|
+
try {
|
|
22607
|
+
return fs7.lstatSync(timelineDir).isDirectory() ? "safe" : "unsafe";
|
|
22608
|
+
} catch (error51) {
|
|
22609
|
+
return error51.code === "ENOENT" ? "missing" : "unsafe";
|
|
22610
|
+
}
|
|
22611
|
+
}
|
|
22612
|
+
function prepareTimelineDirectory(timelineDir) {
|
|
22613
|
+
const state = timelineDirectoryState(timelineDir);
|
|
22614
|
+
if (state === "safe")
|
|
22615
|
+
return true;
|
|
22616
|
+
if (state === "unsafe")
|
|
22617
|
+
return false;
|
|
22618
|
+
try {
|
|
22619
|
+
fs7.mkdirSync(timelineDir);
|
|
22620
|
+
} catch (error51) {
|
|
22621
|
+
if (error51.code !== "EEXIST")
|
|
22622
|
+
return false;
|
|
22623
|
+
}
|
|
22624
|
+
return timelineDirectoryState(timelineDir) === "safe";
|
|
22625
|
+
}
|
|
22626
|
+
function scanTimelineFile(filePath) {
|
|
22627
|
+
let source;
|
|
22628
|
+
try {
|
|
22629
|
+
source = fs7.lstatSync(filePath);
|
|
22630
|
+
} catch (error51) {
|
|
22631
|
+
return error51.code === "ENOENT" ? [] : null;
|
|
22632
|
+
}
|
|
22633
|
+
if (!source.isFile())
|
|
22634
|
+
return null;
|
|
22635
|
+
let fd = null;
|
|
22636
|
+
try {
|
|
22637
|
+
fd = fs7.openSync(filePath, fs7.constants.O_RDONLY | (fs7.constants.O_NOFOLLOW ?? 0));
|
|
22638
|
+
const stat = fs7.fstatSync(fd);
|
|
22639
|
+
if (!stat.isFile())
|
|
22640
|
+
return null;
|
|
22641
|
+
const chunk = Buffer.allocUnsafe(TIMELINE_READ_CHUNK_BYTES);
|
|
22642
|
+
const newest = [];
|
|
22643
|
+
let retainedBytes = 0;
|
|
22644
|
+
let overflowed = false;
|
|
22645
|
+
let suffixHasBarrier = false;
|
|
22646
|
+
let latestEvictedBarrier = null;
|
|
22647
|
+
let parts = [];
|
|
22648
|
+
let partBytes = 0;
|
|
22649
|
+
let oversized = false;
|
|
22650
|
+
let stop = false;
|
|
22651
|
+
let discardIncompleteTail = false;
|
|
22652
|
+
if (stat.size > 0) {
|
|
22653
|
+
const last = Buffer.allocUnsafe(1);
|
|
22654
|
+
fs7.readSync(fd, last, 0, 1, stat.size - 1);
|
|
22655
|
+
discardIncompleteTail = last[0] !== 10;
|
|
22656
|
+
}
|
|
22657
|
+
const resetPhysicalLine = () => {
|
|
22658
|
+
parts = [];
|
|
22659
|
+
partBytes = 0;
|
|
22660
|
+
oversized = false;
|
|
22661
|
+
};
|
|
22662
|
+
const addPart = (part) => {
|
|
22663
|
+
if (oversized)
|
|
22664
|
+
return;
|
|
22665
|
+
if (partBytes + part.length > TIMELINE_MAX_BYTES) {
|
|
22666
|
+
parts = [];
|
|
22667
|
+
partBytes = 0;
|
|
22668
|
+
oversized = true;
|
|
22669
|
+
return;
|
|
22670
|
+
}
|
|
22671
|
+
if (part.length > 0)
|
|
22672
|
+
parts.push(Buffer.from(part));
|
|
22673
|
+
partBytes += part.length;
|
|
22674
|
+
};
|
|
22675
|
+
const retain = (line) => {
|
|
22676
|
+
if (!overflowed && retainedBytes + line.bytes <= TIMELINE_MAX_BYTES) {
|
|
22677
|
+
newest.push(line);
|
|
22678
|
+
retainedBytes += line.bytes;
|
|
22679
|
+
if (line.barrier)
|
|
22680
|
+
suffixHasBarrier = true;
|
|
22681
|
+
return;
|
|
22682
|
+
}
|
|
22683
|
+
overflowed = true;
|
|
22684
|
+
if (suffixHasBarrier) {
|
|
22685
|
+
stop = true;
|
|
22686
|
+
} else if (line.barrier) {
|
|
22687
|
+
latestEvictedBarrier = line;
|
|
22688
|
+
stop = true;
|
|
22689
|
+
}
|
|
22690
|
+
};
|
|
22691
|
+
const finishPhysicalLine = (part) => {
|
|
22692
|
+
addPart(part);
|
|
22693
|
+
if (discardIncompleteTail) {
|
|
22694
|
+
discardIncompleteTail = false;
|
|
22695
|
+
resetPhysicalLine();
|
|
22696
|
+
return;
|
|
22697
|
+
}
|
|
22698
|
+
if (!oversized && partBytes > 0) {
|
|
22699
|
+
let physical = Buffer.concat([...parts].reverse(), partBytes);
|
|
22700
|
+
if (physical[physical.length - 1] === 13)
|
|
22701
|
+
physical = physical.subarray(0, -1);
|
|
22702
|
+
if (physical.length > 0) {
|
|
22703
|
+
try {
|
|
22704
|
+
const entry = canonicalTimelineEntry(JSON.parse(physical.toString("utf8")));
|
|
22705
|
+
const line = entry ? timelineLine(entry) : null;
|
|
22706
|
+
if (line)
|
|
22707
|
+
retain(line);
|
|
22708
|
+
} catch {}
|
|
22709
|
+
}
|
|
22710
|
+
}
|
|
22711
|
+
resetPhysicalLine();
|
|
22712
|
+
};
|
|
22713
|
+
let position = stat.size;
|
|
22714
|
+
while (position > 0 && !stop) {
|
|
22715
|
+
const start = Math.max(0, position - chunk.length);
|
|
22716
|
+
const requested = position - start;
|
|
22717
|
+
let count = 0;
|
|
22718
|
+
while (count < requested) {
|
|
22719
|
+
const read = fs7.readSync(fd, chunk, count, requested - count, start + count);
|
|
22720
|
+
if (read <= 0)
|
|
22721
|
+
break;
|
|
22722
|
+
count += read;
|
|
22723
|
+
}
|
|
22724
|
+
if (count !== requested)
|
|
22725
|
+
return null;
|
|
22726
|
+
let segmentEnd = count;
|
|
22727
|
+
for (let index2 = count - 1;index2 >= 0; index2--) {
|
|
22728
|
+
if (chunk[index2] !== 10)
|
|
22729
|
+
continue;
|
|
22730
|
+
finishPhysicalLine(chunk.subarray(index2 + 1, segmentEnd));
|
|
22731
|
+
segmentEnd = index2;
|
|
22732
|
+
if (stop)
|
|
22733
|
+
break;
|
|
22734
|
+
}
|
|
22735
|
+
if (!stop && segmentEnd > 0)
|
|
22736
|
+
addPart(chunk.subarray(0, segmentEnd));
|
|
22737
|
+
position = start;
|
|
22738
|
+
}
|
|
22739
|
+
if (!stop && position === 0 && (parts.length > 0 || oversized) && !discardIncompleteTail) {
|
|
22740
|
+
finishPhysicalLine(Buffer.alloc(0));
|
|
22741
|
+
}
|
|
22742
|
+
const sentinel = latestEvictedBarrier;
|
|
22743
|
+
if (sentinel && !suffixHasBarrier) {
|
|
22744
|
+
while (newest.length > 0 && sentinel.bytes + retainedBytes > TIMELINE_MAX_BYTES) {
|
|
22745
|
+
retainedBytes -= newest.pop().bytes;
|
|
22746
|
+
}
|
|
22747
|
+
}
|
|
22748
|
+
const chronological = newest.reverse();
|
|
22749
|
+
return sentinel && !suffixHasBarrier ? [sentinel, ...chronological] : chronological;
|
|
22750
|
+
} catch {
|
|
22751
|
+
return null;
|
|
22752
|
+
} finally {
|
|
22753
|
+
if (fd !== null) {
|
|
22754
|
+
try {
|
|
22755
|
+
fs7.closeSync(fd);
|
|
22756
|
+
} catch {}
|
|
22757
|
+
}
|
|
22758
|
+
}
|
|
22759
|
+
}
|
|
22760
|
+
function atomicReplaceTimeline(filePath, lines) {
|
|
22761
|
+
const tempPath = join9(dirname2(filePath), `.${basename(filePath)}.${process.pid}.${randomBytes2(12).toString("hex")}.tmp`);
|
|
22762
|
+
let fd = null;
|
|
22763
|
+
try {
|
|
22764
|
+
fd = fs7.openSync(tempPath, "wx", 384);
|
|
22765
|
+
const body = lines.map((line) => line.text).join(`
|
|
22766
|
+
`) + (lines.length > 0 ? `
|
|
22767
|
+
` : "");
|
|
22768
|
+
fs7.writeFileSync(fd, body, "utf8");
|
|
22769
|
+
fs7.fsyncSync(fd);
|
|
22770
|
+
fs7.closeSync(fd);
|
|
22771
|
+
fd = null;
|
|
22772
|
+
fs7.renameSync(tempPath, filePath);
|
|
22773
|
+
return true;
|
|
22774
|
+
} catch {
|
|
22775
|
+
return false;
|
|
22776
|
+
} finally {
|
|
22777
|
+
if (fd !== null) {
|
|
22778
|
+
try {
|
|
22779
|
+
fs7.closeSync(fd);
|
|
22780
|
+
} catch {}
|
|
22781
|
+
}
|
|
22782
|
+
try {
|
|
22783
|
+
fs7.unlinkSync(tempPath);
|
|
22784
|
+
} catch {}
|
|
22785
|
+
}
|
|
22786
|
+
}
|
|
22787
|
+
function writeRequiredTimeline(filePath, input, required2) {
|
|
22788
|
+
const compacted = compactLines(input);
|
|
22789
|
+
if (!compacted.includes(required2))
|
|
22790
|
+
return false;
|
|
22791
|
+
return atomicReplaceTimeline(filePath, compacted);
|
|
22792
|
+
}
|
|
19955
22793
|
function filenameForDate(date5) {
|
|
19956
22794
|
const y = date5.getFullYear();
|
|
19957
22795
|
const m = String(date5.getMonth() + 1).padStart(2, "0");
|
|
@@ -19968,24 +22806,11 @@ function recentFilenames(maxDays, now) {
|
|
|
19968
22806
|
return out;
|
|
19969
22807
|
}
|
|
19970
22808
|
function readJsonl(filePath) {
|
|
19971
|
-
|
|
19972
|
-
try {
|
|
19973
|
-
content = readFileSync4(filePath, "utf-8");
|
|
19974
|
-
} catch {
|
|
19975
|
-
return [];
|
|
19976
|
-
}
|
|
19977
|
-
const entries = [];
|
|
19978
|
-
for (const line of content.trimEnd().split(`
|
|
19979
|
-
`)) {
|
|
19980
|
-
if (!line)
|
|
19981
|
-
continue;
|
|
19982
|
-
try {
|
|
19983
|
-
entries.push(JSON.parse(line));
|
|
19984
|
-
} catch {}
|
|
19985
|
-
}
|
|
19986
|
-
return entries;
|
|
22809
|
+
return scanTimelineFile(filePath)?.map((line) => line.entry) ?? [];
|
|
19987
22810
|
}
|
|
19988
22811
|
function readRecentEntries(timelineDir, opts = {}) {
|
|
22812
|
+
if (timelineDirectoryState(timelineDir) !== "safe")
|
|
22813
|
+
return [];
|
|
19989
22814
|
const now = opts.now ?? new Date;
|
|
19990
22815
|
const maxDays = opts.maxDays ?? 7;
|
|
19991
22816
|
const filenames = recentFilenames(maxDays, now).reverse();
|
|
@@ -19996,15 +22821,19 @@ function readRecentEntries(timelineDir, opts = {}) {
|
|
|
19996
22821
|
return entries;
|
|
19997
22822
|
}
|
|
19998
22823
|
function appendEntry(timelineDir, entry, now = new Date) {
|
|
22824
|
+
if (timelineDirectoryState(timelineDir) !== "safe")
|
|
22825
|
+
return false;
|
|
19999
22826
|
const filename = filenameForDate(now);
|
|
20000
22827
|
const filePath = join9(timelineDir, filename);
|
|
20001
22828
|
const lockPath = lockPathFor(timelineDir, filename);
|
|
20002
22829
|
if (!acquireLock(lockPath))
|
|
20003
22830
|
return false;
|
|
20004
22831
|
try {
|
|
20005
|
-
|
|
20006
|
-
|
|
20007
|
-
|
|
22832
|
+
const existing = scanTimelineFile(filePath);
|
|
22833
|
+
const required2 = timelineLine(entry);
|
|
22834
|
+
if (!existing || !required2)
|
|
22835
|
+
return false;
|
|
22836
|
+
return writeRequiredTimeline(filePath, [...existing, required2], required2);
|
|
20008
22837
|
} catch {
|
|
20009
22838
|
return false;
|
|
20010
22839
|
} finally {
|
|
@@ -20012,77 +22841,147 @@ function appendEntry(timelineDir, entry, now = new Date) {
|
|
|
20012
22841
|
}
|
|
20013
22842
|
}
|
|
20014
22843
|
function appendOrMergeEntry(timelineDir, entry, now = new Date) {
|
|
22844
|
+
if (timelineDirectoryState(timelineDir) !== "safe")
|
|
22845
|
+
return false;
|
|
20015
22846
|
const filename = filenameForDate(now);
|
|
20016
22847
|
const filePath = join9(timelineDir, filename);
|
|
20017
22848
|
const lockPath = lockPathFor(timelineDir, filename);
|
|
20018
22849
|
if (!acquireLock(lockPath))
|
|
20019
22850
|
return false;
|
|
20020
22851
|
try {
|
|
20021
|
-
|
|
20022
|
-
if (
|
|
20023
|
-
|
|
20024
|
-
|
|
20025
|
-
|
|
20026
|
-
if (lines.length > 0) {
|
|
20027
|
-
const latest = JSON.parse(lines[lines.length - 1]);
|
|
22852
|
+
const existing = scanTimelineFile(filePath);
|
|
22853
|
+
if (!existing)
|
|
22854
|
+
return false;
|
|
22855
|
+
if (existing.length > 0) {
|
|
22856
|
+
const latest = existing[existing.length - 1].entry;
|
|
20028
22857
|
const mergeable = !latest.system && !entry.system && latest.session_id === entry.session_id && latest.provider === entry.provider && latest.agent_responses.length === 0;
|
|
20029
22858
|
if (mergeable) {
|
|
20030
|
-
|
|
20031
|
-
|
|
20032
|
-
|
|
20033
|
-
|
|
20034
|
-
|
|
20035
|
-
|
|
20036
|
-
|
|
20037
|
-
|
|
22859
|
+
const merged = {
|
|
22860
|
+
...latest,
|
|
22861
|
+
messages: [...latest.messages, ...entry.messages],
|
|
22862
|
+
agent_responses: [...latest.agent_responses]
|
|
22863
|
+
};
|
|
22864
|
+
const required3 = timelineLine(merged);
|
|
22865
|
+
if (!required3)
|
|
22866
|
+
return false;
|
|
22867
|
+
return writeRequiredTimeline(filePath, [...existing.slice(0, -1), required3], required3);
|
|
20038
22868
|
}
|
|
20039
22869
|
}
|
|
20040
|
-
|
|
20041
|
-
|
|
20042
|
-
|
|
22870
|
+
const required2 = timelineLine(entry);
|
|
22871
|
+
if (!required2)
|
|
22872
|
+
return false;
|
|
22873
|
+
return writeRequiredTimeline(filePath, [...existing, required2], required2);
|
|
20043
22874
|
} catch {
|
|
20044
22875
|
return false;
|
|
20045
22876
|
} finally {
|
|
20046
22877
|
releaseLock(lockPath);
|
|
20047
22878
|
}
|
|
20048
22879
|
}
|
|
20049
|
-
function
|
|
22880
|
+
function updateLatestEntryResult(timelineDir, updater, opts = {}) {
|
|
22881
|
+
const directoryState = timelineDirectoryState(timelineDir);
|
|
22882
|
+
if (directoryState !== "safe")
|
|
22883
|
+
return directoryState === "missing" ? "missing" : "rejected";
|
|
20050
22884
|
const now = opts.now ?? new Date;
|
|
20051
22885
|
const maxDays = opts.maxDays ?? 7;
|
|
20052
22886
|
for (const filename of recentFilenames(maxDays, now)) {
|
|
20053
22887
|
const filePath = join9(timelineDir, filename);
|
|
20054
|
-
|
|
20055
|
-
|
|
22888
|
+
let source;
|
|
22889
|
+
try {
|
|
22890
|
+
source = fs7.lstatSync(filePath);
|
|
22891
|
+
} catch (error51) {
|
|
22892
|
+
if (error51.code === "ENOENT")
|
|
22893
|
+
continue;
|
|
22894
|
+
return "rejected";
|
|
22895
|
+
}
|
|
22896
|
+
if (!source.isFile())
|
|
22897
|
+
return "rejected";
|
|
20056
22898
|
const lockPath = lockPathFor(timelineDir, filename);
|
|
20057
22899
|
if (!acquireLock(lockPath))
|
|
22900
|
+
return "rejected";
|
|
22901
|
+
try {
|
|
22902
|
+
const lines = scanTimelineFile(filePath);
|
|
22903
|
+
if (!lines)
|
|
22904
|
+
return "rejected";
|
|
22905
|
+
if (lines.length === 0)
|
|
22906
|
+
continue;
|
|
22907
|
+
const latest = lines[lines.length - 1].entry;
|
|
22908
|
+
if (latest.system)
|
|
22909
|
+
return "missing";
|
|
22910
|
+
const updated = {
|
|
22911
|
+
...latest,
|
|
22912
|
+
messages: [...latest.messages],
|
|
22913
|
+
agent_responses: [...latest.agent_responses]
|
|
22914
|
+
};
|
|
22915
|
+
try {
|
|
22916
|
+
updater(updated);
|
|
22917
|
+
} catch {
|
|
22918
|
+
return "rejected";
|
|
22919
|
+
}
|
|
22920
|
+
const required2 = timelineLine(updated);
|
|
22921
|
+
if (!required2)
|
|
22922
|
+
return "rejected";
|
|
22923
|
+
return writeRequiredTimeline(filePath, [...lines.slice(0, -1), required2], required2) ? "updated" : "rejected";
|
|
22924
|
+
} catch {
|
|
22925
|
+
return "rejected";
|
|
22926
|
+
} finally {
|
|
22927
|
+
releaseLock(lockPath);
|
|
22928
|
+
}
|
|
22929
|
+
}
|
|
22930
|
+
return "missing";
|
|
22931
|
+
}
|
|
22932
|
+
function yieldToEventLoop() {
|
|
22933
|
+
return new Promise((resolve3) => setImmediate(resolve3));
|
|
22934
|
+
}
|
|
22935
|
+
async function sweepTimelineHistory(workingDirectoryBase, opts = {}) {
|
|
22936
|
+
const yieldAfterFile = opts.yieldAfterFile ?? (() => yieldToEventLoop());
|
|
22937
|
+
if (!opts.yieldAfterFile)
|
|
22938
|
+
await yieldToEventLoop();
|
|
22939
|
+
if (!isRealDirectory(workingDirectoryBase))
|
|
22940
|
+
return;
|
|
22941
|
+
let agentNames;
|
|
22942
|
+
try {
|
|
22943
|
+
agentNames = fs7.readdirSync(workingDirectoryBase).sort();
|
|
22944
|
+
} catch {
|
|
22945
|
+
return;
|
|
22946
|
+
}
|
|
22947
|
+
for (const agentName of agentNames) {
|
|
22948
|
+
const agentDir = join9(workingDirectoryBase, agentName);
|
|
22949
|
+
if (!isRealDirectory(agentDir))
|
|
20058
22950
|
continue;
|
|
22951
|
+
const timelineDir = join9(agentDir, ".context_timeline");
|
|
22952
|
+
if (!isRealDirectory(timelineDir))
|
|
22953
|
+
continue;
|
|
22954
|
+
let filenames;
|
|
20059
22955
|
try {
|
|
20060
|
-
|
|
22956
|
+
filenames = fs7.readdirSync(timelineDir).filter((name) => DATE_FILENAME_PATTERN.test(name)).sort();
|
|
22957
|
+
} catch {
|
|
22958
|
+
continue;
|
|
22959
|
+
}
|
|
22960
|
+
for (const filename of filenames) {
|
|
22961
|
+
const filePath = join9(timelineDir, filename);
|
|
22962
|
+
let source;
|
|
20061
22963
|
try {
|
|
20062
|
-
|
|
22964
|
+
source = fs7.lstatSync(filePath);
|
|
20063
22965
|
} catch {
|
|
20064
22966
|
continue;
|
|
20065
22967
|
}
|
|
20066
|
-
|
|
20067
|
-
`).filter(Boolean);
|
|
20068
|
-
if (lines.length === 0)
|
|
22968
|
+
if (!source.isFile())
|
|
20069
22969
|
continue;
|
|
20070
|
-
|
|
20071
|
-
|
|
20072
|
-
|
|
20073
|
-
|
|
20074
|
-
|
|
20075
|
-
|
|
20076
|
-
|
|
20077
|
-
|
|
20078
|
-
|
|
20079
|
-
|
|
20080
|
-
|
|
20081
|
-
|
|
20082
|
-
|
|
22970
|
+
try {
|
|
22971
|
+
const lockPath = lockPathFor(timelineDir, filename);
|
|
22972
|
+
if (acquireLock(lockPath)) {
|
|
22973
|
+
try {
|
|
22974
|
+
const lines = scanTimelineFile(filePath);
|
|
22975
|
+
if (lines)
|
|
22976
|
+
atomicReplaceTimeline(filePath, lines);
|
|
22977
|
+
} finally {
|
|
22978
|
+
releaseLock(lockPath);
|
|
22979
|
+
}
|
|
22980
|
+
}
|
|
22981
|
+
} catch {}
|
|
22982
|
+
await yieldAfterFile(filePath);
|
|
20083
22983
|
}
|
|
20084
22984
|
}
|
|
20085
|
-
return false;
|
|
20086
22985
|
}
|
|
20087
22986
|
function createTimelineEntry(fields) {
|
|
20088
22987
|
return {
|
|
@@ -20115,7 +23014,13 @@ function findResumableSession(rows, provider) {
|
|
|
20115
23014
|
return null;
|
|
20116
23015
|
}
|
|
20117
23016
|
// src/timeline/recorder.ts
|
|
20118
|
-
|
|
23017
|
+
var MAX_AGENT_RESPONSES = 5;
|
|
23018
|
+
function appendAgentResponse(entry, text2) {
|
|
23019
|
+
entry.agent_responses.push(text2);
|
|
23020
|
+
if (entry.agent_responses.length > MAX_AGENT_RESPONSES) {
|
|
23021
|
+
entry.agent_responses.splice(0, entry.agent_responses.length - MAX_AGENT_RESPONSES);
|
|
23022
|
+
}
|
|
23023
|
+
}
|
|
20119
23024
|
function createTimelineRecorder(opts) {
|
|
20120
23025
|
const now = opts.now ?? (() => new Date);
|
|
20121
23026
|
const dirFor = (agentId) => opts.timelineDirFor(agentId);
|
|
@@ -20126,29 +23031,27 @@ function createTimelineRecorder(opts) {
|
|
|
20126
23031
|
},
|
|
20127
23032
|
appendEntryForAgent(agentId, messages) {
|
|
20128
23033
|
const dir = dirFor(agentId);
|
|
20129
|
-
|
|
20130
|
-
|
|
20131
|
-
} catch {}
|
|
23034
|
+
if (!prepareTimelineDirectory(dir))
|
|
23035
|
+
return;
|
|
20132
23036
|
appendOrMergeEntry(dir, createTimelineEntry({
|
|
20133
23037
|
messages,
|
|
20134
23038
|
sessionId: sessionByAgent.get(agentId) ?? null,
|
|
20135
23039
|
provider: opts.providerFor?.(agentId) ?? null
|
|
20136
23040
|
}), now());
|
|
20137
23041
|
},
|
|
20138
|
-
appendResponseToLatest(agentId,
|
|
23042
|
+
appendResponseToLatest(agentId, text2) {
|
|
20139
23043
|
const dir = dirFor(agentId);
|
|
20140
|
-
|
|
20141
|
-
|
|
23044
|
+
if (!prepareTimelineDirectory(dir))
|
|
23045
|
+
return;
|
|
23046
|
+
const result = updateLatestEntryResult(dir, (entry2) => appendAgentResponse(entry2, text2), { now: now() });
|
|
23047
|
+
if (result === "updated" || result === "rejected")
|
|
20142
23048
|
return;
|
|
20143
|
-
try {
|
|
20144
|
-
mkdirSync5(dir, { recursive: true });
|
|
20145
|
-
} catch {}
|
|
20146
23049
|
const entry = createTimelineEntry({
|
|
20147
23050
|
messages: [],
|
|
20148
23051
|
sessionId: sessionByAgent.get(agentId) ?? null,
|
|
20149
23052
|
provider: opts.providerFor?.(agentId) ?? null
|
|
20150
23053
|
});
|
|
20151
|
-
entry
|
|
23054
|
+
appendAgentResponse(entry, text2);
|
|
20152
23055
|
appendEntry(dir, entry, now());
|
|
20153
23056
|
},
|
|
20154
23057
|
resumeSessionId(agentId, provider) {
|
|
@@ -20157,10 +23060,9 @@ function createTimelineRecorder(opts) {
|
|
|
20157
23060
|
},
|
|
20158
23061
|
forgetSession(agentId, barrierType = "reset_session") {
|
|
20159
23062
|
const dir = dirFor(agentId);
|
|
20160
|
-
try {
|
|
20161
|
-
mkdirSync5(dir, { recursive: true });
|
|
20162
|
-
} catch {}
|
|
20163
23063
|
sessionByAgent.delete(agentId);
|
|
23064
|
+
if (!prepareTimelineDirectory(dir))
|
|
23065
|
+
return;
|
|
20164
23066
|
const stamp = now();
|
|
20165
23067
|
appendEntry(dir, createSystemEntry(barrierType, stamp.toISOString()), stamp);
|
|
20166
23068
|
}
|
|
@@ -20168,13 +23070,13 @@ function createTimelineRecorder(opts) {
|
|
|
20168
23070
|
}
|
|
20169
23071
|
// src/discovery.ts
|
|
20170
23072
|
import * as path8 from "path";
|
|
20171
|
-
import * as
|
|
23073
|
+
import * as fs8 from "fs";
|
|
20172
23074
|
import { fileURLToPath } from "url";
|
|
20173
23075
|
var SELECTABLE_RUNTIMES = new Set(["claude", "codex", "opencode", "pi", "cursor"]);
|
|
20174
23076
|
function resolveAlookCliPath(moduleDir) {
|
|
20175
23077
|
const thisDir = moduleDir ?? path8.dirname(fileURLToPath(import.meta.url));
|
|
20176
23078
|
const target = path8.basename(thisDir) === "dist" ? path8.resolve(thisDir, "cli", "index.js") : path8.resolve(thisDir, "..", "scripts", "alook-shim.mjs");
|
|
20177
|
-
return
|
|
23079
|
+
return fs8.existsSync(target) ? target : null;
|
|
20178
23080
|
}
|
|
20179
23081
|
function deriveCliFallbackCandidates(cliPath) {
|
|
20180
23082
|
if (!cliPath)
|
|
@@ -20192,12 +23094,12 @@ function deriveCliFallbackCandidates(cliPath) {
|
|
|
20192
23094
|
}
|
|
20193
23095
|
function resolveAlookCliPathWithFallback(primary) {
|
|
20194
23096
|
const resolved = primary ?? resolveAlookCliPath();
|
|
20195
|
-
if (resolved &&
|
|
23097
|
+
if (resolved && fs8.existsSync(resolved))
|
|
20196
23098
|
return resolved;
|
|
20197
23099
|
if (resolved) {
|
|
20198
23100
|
const fallbacks = deriveCliFallbackCandidates(resolved);
|
|
20199
23101
|
for (const fallback of fallbacks) {
|
|
20200
|
-
if (
|
|
23102
|
+
if (fs8.existsSync(fallback))
|
|
20201
23103
|
return fallback;
|
|
20202
23104
|
}
|
|
20203
23105
|
}
|
|
@@ -20236,7 +23138,7 @@ async function getAvailableRuntimes() {
|
|
|
20236
23138
|
}
|
|
20237
23139
|
|
|
20238
23140
|
// src/drivers/piSdkDeps.ts
|
|
20239
|
-
import { readFileSync as
|
|
23141
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
20240
23142
|
import * as path9 from "path";
|
|
20241
23143
|
import { pathToFileURL } from "url";
|
|
20242
23144
|
var PI_SDK_PACKAGE_NAME2 = "@earendil-works/pi-coding-agent";
|
|
@@ -20246,7 +23148,7 @@ async function importPiSdkFromGlobalInstall() {
|
|
|
20246
23148
|
if (!dir) {
|
|
20247
23149
|
throw new Error(`${PI_SDK_PACKAGE_NAME2} not found — install it (e.g. \`npm install -g ${PI_SDK_PACKAGE_NAME2}\`) before launching a pi agent`);
|
|
20248
23150
|
}
|
|
20249
|
-
const pkg = JSON.parse(
|
|
23151
|
+
const pkg = JSON.parse(readFileSync4(path9.join(dir, "package.json"), "utf-8"));
|
|
20250
23152
|
const entry = pkg.exports?.["."]?.import ?? pkg.main ?? "./dist/index.js";
|
|
20251
23153
|
const entryPath = path9.join(dir, entry);
|
|
20252
23154
|
const barrel = await import(pathToFileURL(entryPath).href);
|
|
@@ -20319,7 +23221,7 @@ function createPiSdkDriverDeps(ctx, loadSdk = loadPiSdkModule) {
|
|
|
20319
23221
|
const bashTool = sdk.createBashToolDefinition(cwd, {
|
|
20320
23222
|
spawnHook: (spawnCtx) => ({ ...spawnCtx, env: { ...spawnCtx.env, ...spawnEnv } })
|
|
20321
23223
|
});
|
|
20322
|
-
const { session, sessionId } = await sdk.createAgentSession({
|
|
23224
|
+
const { session: session2, sessionId } = await sdk.createAgentSession({
|
|
20323
23225
|
cwd,
|
|
20324
23226
|
model,
|
|
20325
23227
|
thinkingLevel: opts.thinkingLevel,
|
|
@@ -20328,18 +23230,48 @@ function createPiSdkDriverDeps(ctx, loadSdk = loadPiSdkModule) {
|
|
|
20328
23230
|
sessionManager,
|
|
20329
23231
|
customTools: [bashTool]
|
|
20330
23232
|
});
|
|
20331
|
-
const resolvedSessionId = sessionId ??
|
|
23233
|
+
const resolvedSessionId = sessionId ?? session2.sessionId;
|
|
20332
23234
|
if (!resolvedSessionId)
|
|
20333
23235
|
throw new Error("pi SDK createAgentSession did not produce a sessionId");
|
|
20334
|
-
return { session, sessionId: resolvedSessionId };
|
|
23236
|
+
return { session: session2, sessionId: resolvedSessionId };
|
|
23237
|
+
}
|
|
23238
|
+
};
|
|
23239
|
+
}
|
|
23240
|
+
|
|
23241
|
+
// src/daemon/diagnosticsCommand.ts
|
|
23242
|
+
function reportUnavailable(options, reportId) {
|
|
23243
|
+
if (!options.reportDiagnosticFailure)
|
|
23244
|
+
return;
|
|
23245
|
+
try {
|
|
23246
|
+
Promise.resolve(options.reportDiagnosticFailure({
|
|
23247
|
+
reportId,
|
|
23248
|
+
failureCode: "diagnostics_unavailable"
|
|
23249
|
+
})).catch(() => {});
|
|
23250
|
+
} catch {}
|
|
23251
|
+
}
|
|
23252
|
+
function createDiagnosticsCommandListener(options) {
|
|
23253
|
+
return (command) => {
|
|
23254
|
+
if (command.type !== "diagnostics:collect")
|
|
23255
|
+
return;
|
|
23256
|
+
const handler = options.handleDiagnosticCommand;
|
|
23257
|
+
if (!handler) {
|
|
23258
|
+
reportUnavailable(options, command.reportId);
|
|
23259
|
+
return WS_CONTROL_COMMAND_CONSUMED;
|
|
23260
|
+
}
|
|
23261
|
+
try {
|
|
23262
|
+
Promise.resolve(handler(command)).catch(() => {
|
|
23263
|
+
reportUnavailable(options, command.reportId);
|
|
23264
|
+
});
|
|
23265
|
+
} catch {
|
|
23266
|
+
reportUnavailable(options, command.reportId);
|
|
20335
23267
|
}
|
|
23268
|
+
return WS_CONTROL_COMMAND_CONSUMED;
|
|
20336
23269
|
};
|
|
20337
23270
|
}
|
|
20338
23271
|
|
|
20339
23272
|
// src/daemon/createDaemon.ts
|
|
20340
23273
|
var WARMUP_BACKOFF_MS = [250, 500, 1000, 2000, 4000];
|
|
20341
23274
|
var WARMUP_CEILING_MS = 30000;
|
|
20342
|
-
var FSM_TRACE_MAX_BYTES = 8 * 1024 * 1024;
|
|
20343
23275
|
var RUNTIME_RAW_TRACE_MAX_BYTES = 8 * 1024 * 1024;
|
|
20344
23276
|
var RUNTIME_RAW_TRACE_AGENT_IDS_ENV = "ALOOK_RUNTIME_RAW_TRACE_AGENT_IDS";
|
|
20345
23277
|
var STATUS_WRITE_INTERVAL_MS = 5000;
|
|
@@ -20441,7 +23373,11 @@ function emitImplicitTypingStopOnSend(args) {
|
|
|
20441
23373
|
async function createDaemon(opts) {
|
|
20442
23374
|
const log = opts.logger ?? createLogger({ header: "@alook/daemon" });
|
|
20443
23375
|
const fallbackBase = (process.env.ALOOK_PROJECT_ROOT || `${homedir3()}/.alook`) + "/daemon";
|
|
20444
|
-
const
|
|
23376
|
+
const workingDirectoryBase = opts.workingDirectoryBase ?? fallbackBase;
|
|
23377
|
+
const workdirFor = (agentId) => `${workingDirectoryBase}/${agentId}`;
|
|
23378
|
+
sweepTimelineHistory(workingDirectoryBase).catch(() => {
|
|
23379
|
+
log.warn("timeline startup sweep failed");
|
|
23380
|
+
});
|
|
20445
23381
|
const resolvedCliPath = resolveAlookCliPathWithFallback(opts.agentCliPath);
|
|
20446
23382
|
const onRuntimeRawLine = createRuntimeRawLineTap({
|
|
20447
23383
|
traceDir: opts.fsmTraceDir,
|
|
@@ -20497,16 +23433,16 @@ async function createDaemon(opts) {
|
|
|
20497
23433
|
function reassertAgentActivity(agentId) {
|
|
20498
23434
|
const state = managerRef?.agentActivity(agentId);
|
|
20499
23435
|
if (state)
|
|
20500
|
-
|
|
23436
|
+
channel2.reportAgentActivity?.({ agentId, state });
|
|
20501
23437
|
}
|
|
20502
23438
|
function startTypingHeartbeat(agentId) {
|
|
20503
23439
|
stopTypingHeartbeat(agentId);
|
|
20504
23440
|
for (const channelId of typingTracker.snapshot(agentId)) {
|
|
20505
|
-
|
|
23441
|
+
channel2.reportAgentTyping?.({ agentId, channelId });
|
|
20506
23442
|
}
|
|
20507
23443
|
const timer = setInterval(() => {
|
|
20508
23444
|
for (const channelId of typingTracker.snapshot(agentId)) {
|
|
20509
|
-
|
|
23445
|
+
channel2.reportAgentTyping?.({ agentId, channelId });
|
|
20510
23446
|
}
|
|
20511
23447
|
reassertAgentActivity(agentId);
|
|
20512
23448
|
}, TYPING_HEARTBEAT_MS);
|
|
@@ -20516,7 +23452,7 @@ async function createDaemon(opts) {
|
|
|
20516
23452
|
function emitTypingStopsAndClear(agentId) {
|
|
20517
23453
|
stopTypingHeartbeat(agentId);
|
|
20518
23454
|
for (const channelId of typingTracker.snapshot(agentId)) {
|
|
20519
|
-
|
|
23455
|
+
channel2.reportAgentTypingStop?.({ agentId, channelId });
|
|
20520
23456
|
}
|
|
20521
23457
|
typingTracker.clear(agentId);
|
|
20522
23458
|
}
|
|
@@ -20581,11 +23517,11 @@ async function createDaemon(opts) {
|
|
|
20581
23517
|
headers: { "content-type": "application/json", authorization: `Bearer ${opts.machineKey}` },
|
|
20582
23518
|
body: JSON.stringify({ agentId })
|
|
20583
23519
|
});
|
|
20584
|
-
const
|
|
23520
|
+
const text2 = await res.text();
|
|
20585
23521
|
let json2 = {};
|
|
20586
|
-
if (
|
|
23522
|
+
if (text2) {
|
|
20587
23523
|
try {
|
|
20588
|
-
json2 = JSON.parse(
|
|
23524
|
+
json2 = JSON.parse(text2);
|
|
20589
23525
|
} catch {
|
|
20590
23526
|
json2 = {};
|
|
20591
23527
|
}
|
|
@@ -20594,7 +23530,7 @@ async function createDaemon(opts) {
|
|
|
20594
23530
|
if (res.status === 404) {
|
|
20595
23531
|
throw new UnknownBotError(agentId);
|
|
20596
23532
|
}
|
|
20597
|
-
throw new BotEnrollFailedError(agentId, new Error(json2.error ?? `enroll failed (${res.status})${
|
|
23533
|
+
throw new BotEnrollFailedError(agentId, new Error(json2.error ?? `enroll failed (${res.status})${text2 ? `: ${text2.slice(0, 512)}` : ""}`));
|
|
20598
23534
|
}
|
|
20599
23535
|
enrolledKeys.set(agentId, json2.runnerKey);
|
|
20600
23536
|
return json2.runnerKey;
|
|
@@ -20608,14 +23544,14 @@ async function createDaemon(opts) {
|
|
|
20608
23544
|
throw wrapped;
|
|
20609
23545
|
}
|
|
20610
23546
|
};
|
|
20611
|
-
const
|
|
23547
|
+
const channel2 = new WsControlChannel({
|
|
20612
23548
|
url: opts.serverWsUrl,
|
|
20613
23549
|
headers: { Authorization: `Bearer ${opts.machineKey}` },
|
|
20614
23550
|
webSocketFactory: opts.webSocketFactory,
|
|
20615
23551
|
onAuthRejected: opts.onAuthRejected,
|
|
20616
23552
|
logger: log.child("ws")
|
|
20617
23553
|
});
|
|
20618
|
-
channelRef =
|
|
23554
|
+
channelRef = channel2;
|
|
20619
23555
|
function handleBotFrame(cmd) {
|
|
20620
23556
|
switch (cmd.type) {
|
|
20621
23557
|
case "bot:added":
|
|
@@ -20656,6 +23592,31 @@ async function createDaemon(opts) {
|
|
|
20656
23592
|
}
|
|
20657
23593
|
}
|
|
20658
23594
|
let router = null;
|
|
23595
|
+
const diagnosticTrace = (() => {
|
|
23596
|
+
const overridePath = process.env.ALOOK_FSM_TRACE;
|
|
23597
|
+
if (overridePath) {
|
|
23598
|
+
return {
|
|
23599
|
+
source: null,
|
|
23600
|
+
onFsmTransition: (rec) => {
|
|
23601
|
+
try {
|
|
23602
|
+
appendFileSync2(overridePath, JSON.stringify(rec) + `
|
|
23603
|
+
`);
|
|
23604
|
+
} catch {}
|
|
23605
|
+
}
|
|
23606
|
+
};
|
|
23607
|
+
}
|
|
23608
|
+
if (!opts.fsmTraceDir)
|
|
23609
|
+
return { source: null };
|
|
23610
|
+
try {
|
|
23611
|
+
mkdirSync6(opts.fsmTraceDir, { recursive: true });
|
|
23612
|
+
} catch {}
|
|
23613
|
+
const source = createRotatingFileSink(`${opts.fsmTraceDir}/fsm-trace.jsonl`, DEFAULT_TRACE_FILE_MAX_BYTES);
|
|
23614
|
+
const sampler = createTraceSampler((rec) => source.write(JSON.stringify(rec)));
|
|
23615
|
+
return {
|
|
23616
|
+
source,
|
|
23617
|
+
onFsmTransition: (rec) => sampler.offer(rec)
|
|
23618
|
+
};
|
|
23619
|
+
})();
|
|
20659
23620
|
const manager = new AgentProcessManager({
|
|
20660
23621
|
driverFor: (agentId, runtimeConfig) => {
|
|
20661
23622
|
const requested = runtimeConfig?.runtime;
|
|
@@ -20690,9 +23651,9 @@ async function createDaemon(opts) {
|
|
|
20690
23651
|
};
|
|
20691
23652
|
},
|
|
20692
23653
|
tickIntervalMs: opts.tickIntervalMs ?? 2000,
|
|
20693
|
-
onAgentSession: (info) => void
|
|
23654
|
+
onAgentSession: (info) => void channel2.reportAgentSession(info),
|
|
20694
23655
|
onAgentActivity: (info) => {
|
|
20695
|
-
|
|
23656
|
+
channel2.reportAgentActivity?.(info);
|
|
20696
23657
|
if (info.state === "starting" || info.state === "running") {
|
|
20697
23658
|
if (!typingHeartbeats.has(info.agentId)) {
|
|
20698
23659
|
startTypingHeartbeat(info.agentId);
|
|
@@ -20704,30 +23665,7 @@ async function createDaemon(opts) {
|
|
|
20704
23665
|
onBotAuditEvent: (agentId, event, context) => emitBotAuditEvent(agentId, event, context),
|
|
20705
23666
|
onAgentLocallyStopped: (info) => router?.markLocallyStopped(info.agentId),
|
|
20706
23667
|
onRuntimeRawLine,
|
|
20707
|
-
...
|
|
20708
|
-
const overridePath = process.env.ALOOK_FSM_TRACE;
|
|
20709
|
-
if (overridePath) {
|
|
20710
|
-
return {
|
|
20711
|
-
onFsmTransition: (rec) => {
|
|
20712
|
-
try {
|
|
20713
|
-
appendFileSync3(overridePath, JSON.stringify(rec) + `
|
|
20714
|
-
`);
|
|
20715
|
-
} catch {}
|
|
20716
|
-
}
|
|
20717
|
-
};
|
|
20718
|
-
}
|
|
20719
|
-
if (opts.fsmTraceDir) {
|
|
20720
|
-
try {
|
|
20721
|
-
mkdirSync6(opts.fsmTraceDir, { recursive: true });
|
|
20722
|
-
} catch {}
|
|
20723
|
-
const sink = createRotatingFileSink(`${opts.fsmTraceDir}/fsm-trace.jsonl`, FSM_TRACE_MAX_BYTES);
|
|
20724
|
-
const sampler = createTraceSampler((rec) => sink.write(JSON.stringify(rec)));
|
|
20725
|
-
return {
|
|
20726
|
-
onFsmTransition: (rec) => sampler.offer(rec)
|
|
20727
|
-
};
|
|
20728
|
-
}
|
|
20729
|
-
return {};
|
|
20730
|
-
})(),
|
|
23668
|
+
...diagnosticTrace.onFsmTransition ? { onFsmTransition: diagnosticTrace.onFsmTransition } : {},
|
|
20731
23669
|
sdkDriverDepsFor: (ctx) => createPiSdkDriverDeps(ctx),
|
|
20732
23670
|
timeline: timeline2,
|
|
20733
23671
|
wakePromptFooter: "Use `alook inbox pull` to read your messages.",
|
|
@@ -20744,9 +23682,13 @@ async function createDaemon(opts) {
|
|
|
20744
23682
|
statusTimer = setInterval(writeStatus, STATUS_WRITE_INTERVAL_MS);
|
|
20745
23683
|
statusTimer.unref?.();
|
|
20746
23684
|
}
|
|
23685
|
+
opts.onDiagnosticSources?.({
|
|
23686
|
+
fsmTraceSource: diagnosticTrace.source,
|
|
23687
|
+
statusFilePath: opts.statusFilePath
|
|
23688
|
+
});
|
|
20747
23689
|
router = new AgentRouter({
|
|
20748
23690
|
manager,
|
|
20749
|
-
channel,
|
|
23691
|
+
channel: channel2,
|
|
20750
23692
|
runtimeReport: opts.runtimeReport,
|
|
20751
23693
|
hostname: opts.hostname,
|
|
20752
23694
|
platform: opts.platform,
|
|
@@ -20777,20 +23719,24 @@ async function createDaemon(opts) {
|
|
|
20777
23719
|
},
|
|
20778
23720
|
formatUnreadNoticeText: (notice) => `You have unread messages in channel ${notice.channel}.`
|
|
20779
23721
|
});
|
|
20780
|
-
|
|
23722
|
+
channel2.onCommand(createDiagnosticsCommandListener({
|
|
23723
|
+
handleDiagnosticCommand: opts.handleDiagnosticCommand,
|
|
23724
|
+
reportDiagnosticFailure: opts.reportDiagnosticFailure
|
|
23725
|
+
}));
|
|
23726
|
+
channel2.onCommand((cmd) => {
|
|
20781
23727
|
handleBotFrame(cmd);
|
|
20782
23728
|
});
|
|
20783
|
-
|
|
23729
|
+
channel2.onOpen(() => {
|
|
20784
23730
|
coldStartWarmup();
|
|
20785
23731
|
resyncPendingWakes();
|
|
20786
23732
|
});
|
|
20787
|
-
|
|
23733
|
+
channel2.connect();
|
|
20788
23734
|
await router.start();
|
|
20789
23735
|
return {
|
|
20790
|
-
isOpen: () =>
|
|
23736
|
+
isOpen: () => channel2.status === "open",
|
|
20791
23737
|
onOpen: (hook) => {
|
|
20792
|
-
|
|
20793
|
-
if (
|
|
23738
|
+
channel2.onOpen(hook);
|
|
23739
|
+
if (channel2.status === "open")
|
|
20794
23740
|
queueMicrotask(hook);
|
|
20795
23741
|
},
|
|
20796
23742
|
proxyUrl: proxy.url,
|
|
@@ -20800,7 +23746,7 @@ async function createDaemon(opts) {
|
|
|
20800
23746
|
}
|
|
20801
23747
|
if (statusTimer)
|
|
20802
23748
|
clearInterval(statusTimer);
|
|
20803
|
-
|
|
23749
|
+
channel2.close();
|
|
20804
23750
|
await proxy.close();
|
|
20805
23751
|
await manager.stopAll();
|
|
20806
23752
|
}
|