@alook/cli 0.0.149 → 0.0.150
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2610 -366
- package/dist/session-runner.js +2304 -156
- package/package.json +6 -6
package/dist/session-runner.js
CHANGED
|
@@ -12,10 +12,45 @@ var __export = (target, all) => {
|
|
|
12
12
|
set: __exportSetter.bind(all, name)
|
|
13
13
|
});
|
|
14
14
|
};
|
|
15
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
16
|
+
|
|
17
|
+
// ../../node_modules/.pnpm/nanoid@5.1.16/node_modules/nanoid/url-alphabet/index.js
|
|
18
|
+
var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
|
|
19
|
+
|
|
20
|
+
// ../../node_modules/.pnpm/nanoid@5.1.16/node_modules/nanoid/index.js
|
|
21
|
+
import { webcrypto as crypto2 } from "node:crypto";
|
|
22
|
+
function fillPool(bytes) {
|
|
23
|
+
if (bytes < 0)
|
|
24
|
+
throw new RangeError("Wrong ID size");
|
|
25
|
+
try {
|
|
26
|
+
if (!pool || pool.length < bytes) {
|
|
27
|
+
pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
|
|
28
|
+
crypto2.getRandomValues(pool);
|
|
29
|
+
poolOffset = 0;
|
|
30
|
+
} else if (poolOffset + bytes > pool.length) {
|
|
31
|
+
crypto2.getRandomValues(pool);
|
|
32
|
+
poolOffset = 0;
|
|
33
|
+
}
|
|
34
|
+
} catch (e) {
|
|
35
|
+
pool = undefined;
|
|
36
|
+
throw e;
|
|
37
|
+
}
|
|
38
|
+
poolOffset += bytes;
|
|
39
|
+
}
|
|
40
|
+
function nanoid3(size = 21) {
|
|
41
|
+
fillPool(size |= 0);
|
|
42
|
+
let id = "";
|
|
43
|
+
for (let i = poolOffset - size;i < poolOffset; i++) {
|
|
44
|
+
id += urlAlphabet[pool[i] & 63];
|
|
45
|
+
}
|
|
46
|
+
return id;
|
|
47
|
+
}
|
|
48
|
+
var POOL_SIZE_MULTIPLIER = 128, pool, poolOffset;
|
|
49
|
+
var init_nanoid = () => {};
|
|
15
50
|
|
|
16
51
|
// daemon/session-runner.ts
|
|
17
52
|
import { mkdir, writeFile, rm, rename } from "fs/promises";
|
|
18
|
-
import { mkdirSync as
|
|
53
|
+
import { mkdirSync as mkdirSync5 } from "fs";
|
|
19
54
|
import path from "path";
|
|
20
55
|
|
|
21
56
|
// ../shared/src/constants.ts
|
|
@@ -63,6 +98,7 @@ var TERMINAL_ISSUE_STATUSES = [
|
|
|
63
98
|
];
|
|
64
99
|
var POLL_INTERVAL_MS = Number(process.env.POLL_INTERVAL_MS) || 3000;
|
|
65
100
|
var OFFLINE_THRESHOLD_MS = Number(process.env.OFFLINE_THRESHOLD_MS) || 30000;
|
|
101
|
+
var COMMUNITY_MACHINE_PAIR_TOKEN_TTL_MS = 15 * 60000;
|
|
66
102
|
var EVENT_POLL_INTERVAL_MS = Number(process.env.EVENT_POLL_INTERVAL_MS) || 2000;
|
|
67
103
|
var MeetingStatus = {
|
|
68
104
|
PENDING: "pending",
|
|
@@ -76,9 +112,16 @@ var TERMINAL_MEETING_STATUSES = [
|
|
|
76
112
|
MeetingStatus.COMPLETED,
|
|
77
113
|
MeetingStatus.FAILED
|
|
78
114
|
];
|
|
115
|
+
var COMMUNITY_BOT_NAME_MIN = 1;
|
|
116
|
+
var COMMUNITY_BOT_NAME_MAX = 32;
|
|
117
|
+
var COMMUNITY_BOT_DESCRIPTION_MAX = 1024;
|
|
118
|
+
var COMMUNITY_BOT_IMAGE_URL_MAX = 2048;
|
|
79
119
|
var DEV_WEB_URL = process.env.ALOOK_SERVER_URL || "http://localhost:3000";
|
|
80
120
|
var DEV_WS_DO_URL = process.env.DEV_WS_DO_URL || "http://localhost:8789";
|
|
81
121
|
var DEV_EMAIL_WORKER_URL = process.env.DEV_EMAIL_WORKER_URL || "http://localhost:8787";
|
|
122
|
+
// ../shared/src/constants/community.ts
|
|
123
|
+
var MAX_ATTACHMENT_SIZE_BYTES = 25 * 1024 * 1024;
|
|
124
|
+
var MAX_SERVER_ICON_SIZE_BYTES = 5 * 1024 * 1024;
|
|
82
125
|
// ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
|
|
83
126
|
var exports_external = {};
|
|
84
127
|
__export(exports_external, {
|
|
@@ -14843,7 +14886,126 @@ var CreateThreadRequestSchema = exports_external.object({
|
|
|
14843
14886
|
content: exports_external.string().optional().default(""),
|
|
14844
14887
|
attachment_ids: exports_external.array(exports_external.string()).optional()
|
|
14845
14888
|
});
|
|
14846
|
-
|
|
14889
|
+
var COMMUNITY_RUNTIME_ID_MAX = 64;
|
|
14890
|
+
var COMMUNITY_RUNTIME_VERSION_MAX = 64;
|
|
14891
|
+
var COMMUNITY_RUNTIME_LIST_MAX = 64;
|
|
14892
|
+
var RUNTIME_ID_RE = /^[A-Za-z0-9._@/-]+$/;
|
|
14893
|
+
var CommunityMachineRuntimeSchema = exports_external.object({
|
|
14894
|
+
id: exports_external.string().min(1).max(COMMUNITY_RUNTIME_ID_MAX).regex(RUNTIME_ID_RE, "invalid runtime id charset"),
|
|
14895
|
+
version: exports_external.string().max(COMMUNITY_RUNTIME_VERSION_MAX).optional(),
|
|
14896
|
+
status: exports_external.enum(["healthy", "unhealthy"]).catch("healthy").default("healthy"),
|
|
14897
|
+
lastError: exports_external.string().max(128).optional(),
|
|
14898
|
+
lastErrorAt: exports_external.string().optional()
|
|
14899
|
+
});
|
|
14900
|
+
var CommunityMachineRuntimeListSchema = exports_external.array(CommunityMachineRuntimeSchema).max(COMMUNITY_RUNTIME_LIST_MAX).transform((list) => {
|
|
14901
|
+
const seen = new Set;
|
|
14902
|
+
const out = [];
|
|
14903
|
+
for (const r of list) {
|
|
14904
|
+
if (seen.has(r.id))
|
|
14905
|
+
continue;
|
|
14906
|
+
seen.add(r.id);
|
|
14907
|
+
out.push(r);
|
|
14908
|
+
}
|
|
14909
|
+
return out;
|
|
14910
|
+
});
|
|
14911
|
+
var CommunityMachineSummarySchema = exports_external.object({
|
|
14912
|
+
id: exports_external.string(),
|
|
14913
|
+
hostname: exports_external.string(),
|
|
14914
|
+
displayName: exports_external.string(),
|
|
14915
|
+
platform: exports_external.string(),
|
|
14916
|
+
arch: exports_external.string(),
|
|
14917
|
+
osRelease: exports_external.string(),
|
|
14918
|
+
daemonVersion: exports_external.string(),
|
|
14919
|
+
lastSeenAt: exports_external.string().nullable(),
|
|
14920
|
+
status: exports_external.enum(["online", "offline"]),
|
|
14921
|
+
availableRuntimes: exports_external.array(CommunityMachineRuntimeSchema).default([]),
|
|
14922
|
+
lastRuntimeError: exports_external.object({
|
|
14923
|
+
requested: exports_external.string(),
|
|
14924
|
+
available: exports_external.array(exports_external.string()),
|
|
14925
|
+
at: exports_external.string()
|
|
14926
|
+
}).optional(),
|
|
14927
|
+
createdAt: exports_external.string(),
|
|
14928
|
+
updatedAt: exports_external.string()
|
|
14929
|
+
});
|
|
14930
|
+
var HostReadyMessageSchema = exports_external.object({
|
|
14931
|
+
type: exports_external.literal("ready"),
|
|
14932
|
+
runtimeReport: CommunityMachineRuntimeListSchema,
|
|
14933
|
+
runningAgents: exports_external.array(exports_external.string()).default([]),
|
|
14934
|
+
hostname: exports_external.string().optional(),
|
|
14935
|
+
platform: exports_external.string().optional(),
|
|
14936
|
+
arch: exports_external.string().optional(),
|
|
14937
|
+
osRelease: exports_external.string().optional(),
|
|
14938
|
+
daemonVersion: exports_external.string().optional()
|
|
14939
|
+
});
|
|
14940
|
+
var CommunityDaemonReadySchema = exports_external.object({
|
|
14941
|
+
runtimeReport: CommunityMachineRuntimeListSchema.optional(),
|
|
14942
|
+
runningAgents: exports_external.array(exports_external.string()).default([]),
|
|
14943
|
+
hostname: exports_external.string().optional(),
|
|
14944
|
+
os: exports_external.string().optional(),
|
|
14945
|
+
arch: exports_external.string().optional(),
|
|
14946
|
+
osRelease: exports_external.string().optional(),
|
|
14947
|
+
daemonVersion: exports_external.string().optional()
|
|
14948
|
+
});
|
|
14949
|
+
var SessionErrorFrameSchema = exports_external.object({
|
|
14950
|
+
type: exports_external.literal("session.error"),
|
|
14951
|
+
code: exports_external.enum(["runtime_not_available"]),
|
|
14952
|
+
agentId: exports_external.string().optional(),
|
|
14953
|
+
payload: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
|
|
14954
|
+
});
|
|
14955
|
+
var CommunityPairTokenResponseSchema = exports_external.object({
|
|
14956
|
+
tokenId: exports_external.string(),
|
|
14957
|
+
expiresAt: exports_external.string()
|
|
14958
|
+
});
|
|
14959
|
+
var CommunityDaemonActivateRequestSchema = exports_external.object({
|
|
14960
|
+
hostname: exports_external.string(),
|
|
14961
|
+
platform: exports_external.string(),
|
|
14962
|
+
arch: exports_external.string(),
|
|
14963
|
+
osRelease: exports_external.string().optional(),
|
|
14964
|
+
daemonVersion: exports_external.string().optional(),
|
|
14965
|
+
runtimeReport: CommunityMachineRuntimeListSchema.optional()
|
|
14966
|
+
});
|
|
14967
|
+
var CommunityDaemonActivateResponseSchema = exports_external.object({
|
|
14968
|
+
credential: exports_external.string(),
|
|
14969
|
+
machineId: exports_external.string(),
|
|
14970
|
+
expiresAt: exports_external.string().nullable()
|
|
14971
|
+
});
|
|
14972
|
+
var CommunityDaemonEnrollAgentRequestSchema = exports_external.object({
|
|
14973
|
+
agentId: exports_external.string().min(1).max(128)
|
|
14974
|
+
});
|
|
14975
|
+
var CommunityDaemonEnrollAgentResponseSchema = exports_external.object({
|
|
14976
|
+
runnerKey: exports_external.string(),
|
|
14977
|
+
expiresAt: exports_external.string().nullable()
|
|
14978
|
+
});
|
|
14979
|
+
var BotImageUrlSchema = exports_external.string().max(COMMUNITY_BOT_IMAGE_URL_MAX).refine((v) => v.startsWith("https://") || v.startsWith("avatar:"), {
|
|
14980
|
+
message: "image must be an https URL or an avatar: config"
|
|
14981
|
+
});
|
|
14982
|
+
var CommunityBotCreateRequestSchema = exports_external.object({
|
|
14983
|
+
name: exports_external.string().trim().min(COMMUNITY_BOT_NAME_MIN).max(COMMUNITY_BOT_NAME_MAX),
|
|
14984
|
+
description: exports_external.string().max(COMMUNITY_BOT_DESCRIPTION_MAX).optional(),
|
|
14985
|
+
machineId: exports_external.string().min(1),
|
|
14986
|
+
runtime: exports_external.string().min(1),
|
|
14987
|
+
image: BotImageUrlSchema.optional()
|
|
14988
|
+
});
|
|
14989
|
+
var CommunityBotPatchRequestSchema = exports_external.object({
|
|
14990
|
+
name: exports_external.string().trim().min(COMMUNITY_BOT_NAME_MIN).max(COMMUNITY_BOT_NAME_MAX).optional(),
|
|
14991
|
+
description: exports_external.string().max(COMMUNITY_BOT_DESCRIPTION_MAX).optional(),
|
|
14992
|
+
image: BotImageUrlSchema.nullable().optional()
|
|
14993
|
+
}).refine((v) => v.name !== undefined || v.description !== undefined || v.image !== undefined, {
|
|
14994
|
+
message: "at least one field must be provided"
|
|
14995
|
+
});
|
|
14996
|
+
var CommunityBotAddToServerRequestSchema = exports_external.object({
|
|
14997
|
+
botId: exports_external.string().min(1)
|
|
14998
|
+
});
|
|
14999
|
+
var CommunityDaemonSendAsBotRequestSchema = exports_external.object({
|
|
15000
|
+
target: exports_external.enum(["channel", "dm"]),
|
|
15001
|
+
targetId: exports_external.string().min(1),
|
|
15002
|
+
content: exports_external.string().max(4000),
|
|
15003
|
+
replyToId: exports_external.string().optional(),
|
|
15004
|
+
mentionType: exports_external.enum(["everyone", "here", "user"]).optional(),
|
|
15005
|
+
embeds: exports_external.array(exports_external.unknown()).optional(),
|
|
15006
|
+
attachments: exports_external.array(exports_external.unknown()).optional()
|
|
15007
|
+
});
|
|
15008
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/entity.js
|
|
14847
15009
|
var entityKind = Symbol.for("drizzle:entityKind");
|
|
14848
15010
|
var hasOwnEntityKind = Symbol.for("drizzle:hasOwnEntityKind");
|
|
14849
15011
|
function is(value, type) {
|
|
@@ -14868,10 +15030,10 @@ function is(value, type) {
|
|
|
14868
15030
|
return false;
|
|
14869
15031
|
}
|
|
14870
15032
|
|
|
14871
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15033
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/table.utils.js
|
|
14872
15034
|
var TableName = Symbol.for("drizzle:Name");
|
|
14873
15035
|
|
|
14874
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15036
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/table.js
|
|
14875
15037
|
var Schema = Symbol.for("drizzle:Schema");
|
|
14876
15038
|
var Columns = Symbol.for("drizzle:Columns");
|
|
14877
15039
|
var ExtraConfigColumns = Symbol.for("drizzle:ExtraConfigColumns");
|
|
@@ -14909,7 +15071,7 @@ class Table {
|
|
|
14909
15071
|
}
|
|
14910
15072
|
}
|
|
14911
15073
|
|
|
14912
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15074
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/column.js
|
|
14913
15075
|
class Column {
|
|
14914
15076
|
constructor(table, config2) {
|
|
14915
15077
|
this.table = table;
|
|
@@ -14959,7 +15121,7 @@ class Column {
|
|
|
14959
15121
|
}
|
|
14960
15122
|
}
|
|
14961
15123
|
|
|
14962
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15124
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/column-builder.js
|
|
14963
15125
|
class ColumnBuilder {
|
|
14964
15126
|
static [entityKind] = "ColumnBuilder";
|
|
14965
15127
|
config;
|
|
@@ -15015,17 +15177,17 @@ class ColumnBuilder {
|
|
|
15015
15177
|
}
|
|
15016
15178
|
}
|
|
15017
15179
|
|
|
15018
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15180
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/tracing-utils.js
|
|
15019
15181
|
function iife(fn, ...args) {
|
|
15020
15182
|
return fn(...args);
|
|
15021
15183
|
}
|
|
15022
15184
|
|
|
15023
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15185
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/pg-core/unique-constraint.js
|
|
15024
15186
|
function uniqueKeyName(table, columns) {
|
|
15025
15187
|
return `${table[TableName]}_${columns.join("_")}_unique`;
|
|
15026
15188
|
}
|
|
15027
15189
|
|
|
15028
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15190
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/pg-core/columns/common.js
|
|
15029
15191
|
class PgColumn extends Column {
|
|
15030
15192
|
constructor(table, config2) {
|
|
15031
15193
|
if (!config2.uniqueName) {
|
|
@@ -15074,7 +15236,7 @@ class ExtraConfigColumn extends PgColumn {
|
|
|
15074
15236
|
}
|
|
15075
15237
|
}
|
|
15076
15238
|
|
|
15077
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15239
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/pg-core/columns/enum.js
|
|
15078
15240
|
class PgEnumObjectColumn extends PgColumn {
|
|
15079
15241
|
static [entityKind] = "PgEnumObjectColumn";
|
|
15080
15242
|
enum;
|
|
@@ -15104,7 +15266,7 @@ class PgEnumColumn extends PgColumn {
|
|
|
15104
15266
|
}
|
|
15105
15267
|
}
|
|
15106
15268
|
|
|
15107
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15269
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/subquery.js
|
|
15108
15270
|
class Subquery {
|
|
15109
15271
|
static [entityKind] = "Subquery";
|
|
15110
15272
|
constructor(sql, fields, alias, isWith = false, usedTables = []) {
|
|
@@ -15119,10 +15281,10 @@ class Subquery {
|
|
|
15119
15281
|
}
|
|
15120
15282
|
}
|
|
15121
15283
|
|
|
15122
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15284
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/version.js
|
|
15123
15285
|
var version2 = "0.45.2";
|
|
15124
15286
|
|
|
15125
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15287
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/tracing.js
|
|
15126
15288
|
var otel;
|
|
15127
15289
|
var rawTracer;
|
|
15128
15290
|
var tracer = {
|
|
@@ -15149,10 +15311,10 @@ var tracer = {
|
|
|
15149
15311
|
}
|
|
15150
15312
|
};
|
|
15151
15313
|
|
|
15152
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15314
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/view-common.js
|
|
15153
15315
|
var ViewBaseConfig = Symbol.for("drizzle:ViewBaseConfig");
|
|
15154
15316
|
|
|
15155
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15317
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sql/sql.js
|
|
15156
15318
|
function isSQLWrapper(value) {
|
|
15157
15319
|
return value !== null && value !== undefined && typeof value.getSQL === "function";
|
|
15158
15320
|
}
|
|
@@ -15512,7 +15674,7 @@ Subquery.prototype.getSQL = function() {
|
|
|
15512
15674
|
return new SQL([this]);
|
|
15513
15675
|
};
|
|
15514
15676
|
|
|
15515
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15677
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/utils.js
|
|
15516
15678
|
function getColumnNameAndConfig(a, b) {
|
|
15517
15679
|
return {
|
|
15518
15680
|
name: typeof a === "string" && a.length > 0 ? a : "",
|
|
@@ -15521,7 +15683,7 @@ function getColumnNameAndConfig(a, b) {
|
|
|
15521
15683
|
}
|
|
15522
15684
|
var textDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder;
|
|
15523
15685
|
|
|
15524
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15686
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/foreign-keys.js
|
|
15525
15687
|
class ForeignKeyBuilder {
|
|
15526
15688
|
static [entityKind] = "SQLiteForeignKeyBuilder";
|
|
15527
15689
|
reference;
|
|
@@ -15589,7 +15751,7 @@ function foreignKey(config2) {
|
|
|
15589
15751
|
return new ForeignKeyBuilder(mappedConfig);
|
|
15590
15752
|
}
|
|
15591
15753
|
|
|
15592
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15754
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/unique-constraint.js
|
|
15593
15755
|
function uniqueKeyName2(table, columns) {
|
|
15594
15756
|
return `${table[TableName]}_${columns.join("_")}_unique`;
|
|
15595
15757
|
}
|
|
@@ -15634,7 +15796,7 @@ class UniqueConstraint {
|
|
|
15634
15796
|
}
|
|
15635
15797
|
}
|
|
15636
15798
|
|
|
15637
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15799
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/columns/common.js
|
|
15638
15800
|
class SQLiteColumnBuilder extends ColumnBuilder {
|
|
15639
15801
|
static [entityKind] = "SQLiteColumnBuilder";
|
|
15640
15802
|
foreignKeyConfigs = [];
|
|
@@ -15685,7 +15847,7 @@ class SQLiteColumn extends Column {
|
|
|
15685
15847
|
static [entityKind] = "SQLiteColumn";
|
|
15686
15848
|
}
|
|
15687
15849
|
|
|
15688
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15850
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/columns/blob.js
|
|
15689
15851
|
class SQLiteBigIntBuilder extends SQLiteColumnBuilder {
|
|
15690
15852
|
static [entityKind] = "SQLiteBigIntBuilder";
|
|
15691
15853
|
constructor(name) {
|
|
@@ -15773,7 +15935,7 @@ function blob(a, b) {
|
|
|
15773
15935
|
return new SQLiteBlobBufferBuilder(name);
|
|
15774
15936
|
}
|
|
15775
15937
|
|
|
15776
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15938
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/columns/custom.js
|
|
15777
15939
|
class SQLiteCustomColumnBuilder extends SQLiteColumnBuilder {
|
|
15778
15940
|
static [entityKind] = "SQLiteCustomColumnBuilder";
|
|
15779
15941
|
constructor(name, fieldConfig, customTypeParams) {
|
|
@@ -15814,7 +15976,7 @@ function customType(customTypeParams) {
|
|
|
15814
15976
|
};
|
|
15815
15977
|
}
|
|
15816
15978
|
|
|
15817
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15979
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/columns/integer.js
|
|
15818
15980
|
class SQLiteBaseIntegerBuilder extends SQLiteColumnBuilder {
|
|
15819
15981
|
static [entityKind] = "SQLiteBaseIntegerBuilder";
|
|
15820
15982
|
constructor(name, dataType, columnType) {
|
|
@@ -15916,7 +16078,7 @@ function integer2(a, b) {
|
|
|
15916
16078
|
return new SQLiteIntegerBuilder(name);
|
|
15917
16079
|
}
|
|
15918
16080
|
|
|
15919
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
16081
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/columns/numeric.js
|
|
15920
16082
|
class SQLiteNumericBuilder extends SQLiteColumnBuilder {
|
|
15921
16083
|
static [entityKind] = "SQLiteNumericBuilder";
|
|
15922
16084
|
constructor(name) {
|
|
@@ -15986,7 +16148,7 @@ function numeric(a, b) {
|
|
|
15986
16148
|
return mode === "number" ? new SQLiteNumericNumberBuilder(name) : mode === "bigint" ? new SQLiteNumericBigIntBuilder(name) : new SQLiteNumericBuilder(name);
|
|
15987
16149
|
}
|
|
15988
16150
|
|
|
15989
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
16151
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/columns/real.js
|
|
15990
16152
|
class SQLiteRealBuilder extends SQLiteColumnBuilder {
|
|
15991
16153
|
static [entityKind] = "SQLiteRealBuilder";
|
|
15992
16154
|
constructor(name) {
|
|
@@ -16007,7 +16169,7 @@ function real(name) {
|
|
|
16007
16169
|
return new SQLiteRealBuilder(name ?? "");
|
|
16008
16170
|
}
|
|
16009
16171
|
|
|
16010
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
16172
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/columns/text.js
|
|
16011
16173
|
class SQLiteTextBuilder extends SQLiteColumnBuilder {
|
|
16012
16174
|
static [entityKind] = "SQLiteTextBuilder";
|
|
16013
16175
|
constructor(name, config2) {
|
|
@@ -16062,7 +16224,7 @@ function text(a, b = {}) {
|
|
|
16062
16224
|
return new SQLiteTextBuilder(name, config2);
|
|
16063
16225
|
}
|
|
16064
16226
|
|
|
16065
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
16227
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/columns/all.js
|
|
16066
16228
|
function getSQLiteColumnBuilders() {
|
|
16067
16229
|
return {
|
|
16068
16230
|
blob,
|
|
@@ -16074,7 +16236,7 @@ function getSQLiteColumnBuilders() {
|
|
|
16074
16236
|
};
|
|
16075
16237
|
}
|
|
16076
16238
|
|
|
16077
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
16239
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/table.js
|
|
16078
16240
|
var InlineForeignKeys = Symbol.for("drizzle:SQLiteInlineForeignKeys");
|
|
16079
16241
|
|
|
16080
16242
|
class SQLiteTable extends Table {
|
|
@@ -16108,7 +16270,7 @@ var sqliteTable = (name, columns, extraConfig) => {
|
|
|
16108
16270
|
return sqliteTableBase(name, columns, extraConfig);
|
|
16109
16271
|
};
|
|
16110
16272
|
|
|
16111
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
16273
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/indexes.js
|
|
16112
16274
|
class IndexBuilderOn {
|
|
16113
16275
|
constructor(name, unique2) {
|
|
16114
16276
|
this.name = name;
|
|
@@ -16150,8 +16312,11 @@ class Index {
|
|
|
16150
16312
|
function index(name) {
|
|
16151
16313
|
return new IndexBuilderOn(name, false);
|
|
16152
16314
|
}
|
|
16315
|
+
function uniqueIndex(name) {
|
|
16316
|
+
return new IndexBuilderOn(name, true);
|
|
16317
|
+
}
|
|
16153
16318
|
|
|
16154
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
16319
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260702.1_@opentelemetry+api@1.9.1_@typ_9f1a3370d3c5742dfd96aef86d667915/node_modules/drizzle-orm/sqlite-core/primary-keys.js
|
|
16155
16320
|
function primaryKey(...config2) {
|
|
16156
16321
|
if (config2[0].columns) {
|
|
16157
16322
|
return new PrimaryKeyBuilder(config2[0].columns, config2[0].name);
|
|
@@ -16186,44 +16351,45 @@ class PrimaryKey {
|
|
|
16186
16351
|
}
|
|
16187
16352
|
}
|
|
16188
16353
|
|
|
16189
|
-
// ../../node_modules/.pnpm/nanoid@5.1.15/node_modules/nanoid/index.js
|
|
16190
|
-
import { webcrypto as crypto } from "node:crypto";
|
|
16191
|
-
|
|
16192
|
-
// ../../node_modules/.pnpm/nanoid@5.1.15/node_modules/nanoid/url-alphabet/index.js
|
|
16193
|
-
var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
|
|
16194
|
-
|
|
16195
|
-
// ../../node_modules/.pnpm/nanoid@5.1.15/node_modules/nanoid/index.js
|
|
16196
|
-
var POOL_SIZE_MULTIPLIER = 128;
|
|
16197
|
-
var pool;
|
|
16198
|
-
var poolOffset;
|
|
16199
|
-
function fillPool(bytes) {
|
|
16200
|
-
if (bytes < 0)
|
|
16201
|
-
throw new RangeError("Wrong ID size");
|
|
16202
|
-
try {
|
|
16203
|
-
if (!pool || pool.length < bytes) {
|
|
16204
|
-
pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
|
|
16205
|
-
crypto.getRandomValues(pool);
|
|
16206
|
-
poolOffset = 0;
|
|
16207
|
-
} else if (poolOffset + bytes > pool.length) {
|
|
16208
|
-
crypto.getRandomValues(pool);
|
|
16209
|
-
poolOffset = 0;
|
|
16210
|
-
}
|
|
16211
|
-
} catch (e) {
|
|
16212
|
-
pool = undefined;
|
|
16213
|
-
throw e;
|
|
16214
|
-
}
|
|
16215
|
-
poolOffset += bytes;
|
|
16216
|
-
}
|
|
16217
|
-
function nanoid3(size = 21) {
|
|
16218
|
-
fillPool(size |= 0);
|
|
16219
|
-
let id = "";
|
|
16220
|
-
for (let i = poolOffset - size;i < poolOffset; i++) {
|
|
16221
|
-
id += urlAlphabet[pool[i] & 63];
|
|
16222
|
-
}
|
|
16223
|
-
return id;
|
|
16224
|
-
}
|
|
16225
|
-
|
|
16226
16354
|
// ../shared/src/db/schema.ts
|
|
16355
|
+
var exports_schema = {};
|
|
16356
|
+
__export(exports_schema, {
|
|
16357
|
+
workspaceInvite: () => workspaceInvite,
|
|
16358
|
+
workspaceFileRequest: () => workspaceFileRequest,
|
|
16359
|
+
workspace: () => workspace,
|
|
16360
|
+
verification: () => verification,
|
|
16361
|
+
user: () => user,
|
|
16362
|
+
taskMessage: () => taskMessage,
|
|
16363
|
+
session: () => session,
|
|
16364
|
+
messageFlag: () => messageFlag,
|
|
16365
|
+
message: () => message,
|
|
16366
|
+
member: () => member,
|
|
16367
|
+
meetingSession: () => meetingSession,
|
|
16368
|
+
machineToken: () => machineToken,
|
|
16369
|
+
machine: () => machine,
|
|
16370
|
+
issueComment: () => issueComment,
|
|
16371
|
+
issue: () => issue2,
|
|
16372
|
+
inboxUnread: () => inboxUnread,
|
|
16373
|
+
emails: () => emails,
|
|
16374
|
+
conversationReadState: () => conversationReadState,
|
|
16375
|
+
conversationMap: () => conversationMap,
|
|
16376
|
+
conversation: () => conversation,
|
|
16377
|
+
channel: () => channel,
|
|
16378
|
+
calendarEvent: () => calendarEvent,
|
|
16379
|
+
artifact: () => artifact,
|
|
16380
|
+
agentWhitelist: () => agentWhitelist,
|
|
16381
|
+
agentTaskQueue: () => agentTaskQueue,
|
|
16382
|
+
agentSkill: () => agentSkill,
|
|
16383
|
+
agentSidebarOrder: () => agentSidebarOrder,
|
|
16384
|
+
agentRuntime: () => agentRuntime,
|
|
16385
|
+
agentPin: () => agentPin,
|
|
16386
|
+
agentLink: () => agentLink,
|
|
16387
|
+
agentEmailAccount: () => agentEmailAccount,
|
|
16388
|
+
agentAccess: () => agentAccess,
|
|
16389
|
+
agent: () => agent,
|
|
16390
|
+
account: () => account
|
|
16391
|
+
});
|
|
16392
|
+
init_nanoid();
|
|
16227
16393
|
var user = sqliteTable("user", {
|
|
16228
16394
|
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
16229
16395
|
name: text("name").notNull().default(""),
|
|
@@ -16231,8 +16397,12 @@ var user = sqliteTable("user", {
|
|
|
16231
16397
|
emailVerified: integer2("emailVerified", { mode: "boolean" }),
|
|
16232
16398
|
image: text("image"),
|
|
16233
16399
|
createdAt: text("createdAt").notNull().$defaultFn(() => new Date().toISOString()),
|
|
16234
|
-
updatedAt: text("updatedAt").notNull().$defaultFn(() => new Date().toISOString())
|
|
16235
|
-
})
|
|
16400
|
+
updatedAt: text("updatedAt").notNull().$defaultFn(() => new Date().toISOString()),
|
|
16401
|
+
isBot: integer2("isBot", { mode: "boolean" }).notNull().default(false),
|
|
16402
|
+
ownerUserId: text("ownerUserId"),
|
|
16403
|
+
deletedAt: text("deletedAt"),
|
|
16404
|
+
discriminator: text("discriminator").notNull().default("0000")
|
|
16405
|
+
}, (t) => [index("idx_user_ownerUserId_isBot").on(t.ownerUserId, t.isBot)]);
|
|
16236
16406
|
var session = sqliteTable("session", {
|
|
16237
16407
|
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
16238
16408
|
userId: text("userId").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
@@ -16768,6 +16938,353 @@ var inboxUnread = sqliteTable("inbox_unread", {
|
|
|
16768
16938
|
unique("inbox_unread_conv_user").on(t.conversationId, t.userId),
|
|
16769
16939
|
index("idx_inbox_unread_user_ws").on(t.userId, t.workspaceId, t.taskType, t.completedAt)
|
|
16770
16940
|
]);
|
|
16941
|
+
|
|
16942
|
+
// ../shared/src/db/community-schema.ts
|
|
16943
|
+
var exports_community_schema = {};
|
|
16944
|
+
__export(exports_community_schema, {
|
|
16945
|
+
communityUserProfile: () => communityUserProfile,
|
|
16946
|
+
communityServerMember: () => communityServerMember,
|
|
16947
|
+
communityServerInvite: () => communityServerInvite,
|
|
16948
|
+
communityServerFolderItem: () => communityServerFolderItem,
|
|
16949
|
+
communityServerFolder: () => communityServerFolder,
|
|
16950
|
+
communityServer: () => communityServer,
|
|
16951
|
+
communityReadState: () => communityReadState,
|
|
16952
|
+
communityReaction: () => communityReaction,
|
|
16953
|
+
communityPin: () => communityPin,
|
|
16954
|
+
communityNotificationSetting: () => communityNotificationSetting,
|
|
16955
|
+
communityMessage: () => communityMessage,
|
|
16956
|
+
communityMention: () => communityMention,
|
|
16957
|
+
communityInboxDismissal: () => communityInboxDismissal,
|
|
16958
|
+
communityFriendship: () => communityFriendship,
|
|
16959
|
+
communityDmConversation: () => communityDmConversation,
|
|
16960
|
+
communityChannel: () => communityChannel,
|
|
16961
|
+
communityCategory: () => communityCategory,
|
|
16962
|
+
communityBotApprovalRequest: () => communityBotApprovalRequest,
|
|
16963
|
+
communityAuditLog: () => communityAuditLog,
|
|
16964
|
+
communityAttachment: () => communityAttachment
|
|
16965
|
+
});
|
|
16966
|
+
init_nanoid();
|
|
16967
|
+
var communityServer = sqliteTable("community_server", {
|
|
16968
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
16969
|
+
name: text("name").notNull(),
|
|
16970
|
+
description: text("description").default(""),
|
|
16971
|
+
icon: text("icon"),
|
|
16972
|
+
ownerId: text("owner_id").notNull().references(() => user.id, { onDelete: "restrict" }),
|
|
16973
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
16974
|
+
});
|
|
16975
|
+
var communityCategory = sqliteTable("community_category", {
|
|
16976
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
16977
|
+
serverId: text("server_id").notNull().references(() => communityServer.id, { onDelete: "cascade" }),
|
|
16978
|
+
name: text("name").notNull(),
|
|
16979
|
+
position: integer2("position").default(0),
|
|
16980
|
+
private: integer2("private").default(0),
|
|
16981
|
+
creatorId: text("creator_id").references(() => user.id, { onDelete: "set null" })
|
|
16982
|
+
}, (t) => [unique("uq_category_server_name").on(t.serverId, t.name)]);
|
|
16983
|
+
var communityChannel = sqliteTable("community_channel", {
|
|
16984
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
16985
|
+
serverId: text("server_id").notNull().references(() => communityServer.id, { onDelete: "cascade" }),
|
|
16986
|
+
categoryId: text("category_id").references(() => communityCategory.id, {
|
|
16987
|
+
onDelete: "set null"
|
|
16988
|
+
}),
|
|
16989
|
+
name: text("name").notNull(),
|
|
16990
|
+
type: text("type").notNull().default("text"),
|
|
16991
|
+
topic: text("topic").default(""),
|
|
16992
|
+
position: integer2("position").default(0),
|
|
16993
|
+
forumTags: text("forum_tags"),
|
|
16994
|
+
parentChannelId: text("parent_channel_id").references(() => communityChannel.id, {
|
|
16995
|
+
onDelete: "cascade"
|
|
16996
|
+
}),
|
|
16997
|
+
creatorId: text("creator_id").references(() => user.id, { onDelete: "set null" }),
|
|
16998
|
+
messageCount: integer2("message_count").default(0),
|
|
16999
|
+
archived: integer2("archived").default(0),
|
|
17000
|
+
parentMessageId: text("parent_message_id"),
|
|
17001
|
+
lastMessageAt: text("last_message_at"),
|
|
17002
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17003
|
+
}, (t) => [
|
|
17004
|
+
index("idx_channel_server_position").on(t.serverId, t.position),
|
|
17005
|
+
index("idx_channel_server_last_message").on(t.serverId, t.lastMessageAt),
|
|
17006
|
+
index("idx_channel_parent").on(t.parentChannelId)
|
|
17007
|
+
]);
|
|
17008
|
+
var communityDmConversation = sqliteTable("community_dm_conversation", {
|
|
17009
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17010
|
+
user1Id: text("user1_id").references(() => user.id, { onDelete: "set null" }),
|
|
17011
|
+
user2Id: text("user2_id").references(() => user.id, { onDelete: "set null" }),
|
|
17012
|
+
lastMessageAt: text("last_message_at"),
|
|
17013
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17014
|
+
}, (t) => [
|
|
17015
|
+
unique("uq_dm_conversation_users").on(t.user1Id, t.user2Id),
|
|
17016
|
+
index("idx_dm_conversation_user1_last_message").on(t.user1Id, t.lastMessageAt),
|
|
17017
|
+
index("idx_dm_conversation_user2_last_message").on(t.user2Id, t.lastMessageAt)
|
|
17018
|
+
]);
|
|
17019
|
+
var communityMessage = sqliteTable("community_message", {
|
|
17020
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17021
|
+
authorId: text("author_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17022
|
+
content: text("content").notNull().default(""),
|
|
17023
|
+
type: text("type").notNull().default("default"),
|
|
17024
|
+
mentionType: text("mention_type"),
|
|
17025
|
+
replyToId: text("reply_to_id"),
|
|
17026
|
+
embeds: text("embeds"),
|
|
17027
|
+
flags: integer2("flags").default(0),
|
|
17028
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
17029
|
+
channelId: text("channel_id").references(() => communityChannel.id, {
|
|
17030
|
+
onDelete: "cascade"
|
|
17031
|
+
}),
|
|
17032
|
+
dmConversationId: text("dm_conversation_id").references(() => communityDmConversation.id, { onDelete: "cascade" })
|
|
17033
|
+
}, (t) => [
|
|
17034
|
+
index("idx_message_channel_created").on(t.channelId, t.createdAt),
|
|
17035
|
+
index("idx_message_channel_mention_created").on(t.channelId, t.mentionType, t.createdAt),
|
|
17036
|
+
index("idx_message_dm_created").on(t.dmConversationId, t.createdAt)
|
|
17037
|
+
]);
|
|
17038
|
+
var communityServerMember = sqliteTable("community_server_member", {
|
|
17039
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17040
|
+
serverId: text("server_id").notNull().references(() => communityServer.id, { onDelete: "cascade" }),
|
|
17041
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17042
|
+
role: text("role").default("member"),
|
|
17043
|
+
nickname: text("nickname"),
|
|
17044
|
+
railOrder: integer2("rail_order").default(0),
|
|
17045
|
+
joinedAt: text("joined_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17046
|
+
}, (t) => [
|
|
17047
|
+
unique("uq_server_member_server_user").on(t.serverId, t.userId),
|
|
17048
|
+
index("idx_server_member_user").on(t.userId),
|
|
17049
|
+
index("idx_server_member_user_rail_order").on(t.userId, t.railOrder)
|
|
17050
|
+
]);
|
|
17051
|
+
var communityServerFolder = sqliteTable("community_server_folder", {
|
|
17052
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17053
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17054
|
+
name: text("name").notNull(),
|
|
17055
|
+
position: integer2("position").default(0)
|
|
17056
|
+
}, (t) => [index("idx_server_folder_user_position").on(t.userId, t.position)]);
|
|
17057
|
+
var communityServerFolderItem = sqliteTable("community_server_folder_item", {
|
|
17058
|
+
folderId: text("folder_id").notNull().references(() => communityServerFolder.id, { onDelete: "cascade" }),
|
|
17059
|
+
serverId: text("server_id").notNull().references(() => communityServer.id, { onDelete: "cascade" }),
|
|
17060
|
+
position: integer2("position").default(0)
|
|
17061
|
+
}, (t) => [
|
|
17062
|
+
primaryKey({ columns: [t.folderId, t.serverId] }),
|
|
17063
|
+
index("idx_server_folder_item_folder_position").on(t.folderId, t.position)
|
|
17064
|
+
]);
|
|
17065
|
+
var communityServerInvite = sqliteTable("community_server_invite", {
|
|
17066
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17067
|
+
serverId: text("server_id").notNull().references(() => communityServer.id, { onDelete: "cascade" }),
|
|
17068
|
+
createdBy: text("created_by").references(() => user.id, { onDelete: "set null" }),
|
|
17069
|
+
token: text("token").unique().notNull().$defaultFn(() => nanoid3(10)),
|
|
17070
|
+
maxUses: integer2("max_uses"),
|
|
17071
|
+
uses: integer2("uses").default(0),
|
|
17072
|
+
expiresAt: text("expires_at"),
|
|
17073
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17074
|
+
});
|
|
17075
|
+
var communityFriendship = sqliteTable("community_friendship", {
|
|
17076
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17077
|
+
requesterId: text("requester_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17078
|
+
addresseeId: text("addressee_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17079
|
+
status: text("status").notNull().default("pending"),
|
|
17080
|
+
blockerId: text("blocker_id"),
|
|
17081
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
17082
|
+
updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17083
|
+
}, (t) => [
|
|
17084
|
+
unique("uq_friendship_requester_addressee").on(t.requesterId, t.addresseeId),
|
|
17085
|
+
index("idx_friendship_addressee_status").on(t.addresseeId, t.status),
|
|
17086
|
+
index("idx_friendship_requester_status").on(t.requesterId, t.status)
|
|
17087
|
+
]);
|
|
17088
|
+
var communityReadState = sqliteTable("community_read_state", {
|
|
17089
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17090
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17091
|
+
channelId: text("channel_id").references(() => communityChannel.id, {
|
|
17092
|
+
onDelete: "cascade"
|
|
17093
|
+
}),
|
|
17094
|
+
dmConversationId: text("dm_conversation_id").references(() => communityDmConversation.id, { onDelete: "cascade" }),
|
|
17095
|
+
lastReadAt: text("last_read_at").notNull(),
|
|
17096
|
+
lastReadMessageId: text("last_read_message_id")
|
|
17097
|
+
}, (t) => [index("idx_read_state_user").on(t.userId)]);
|
|
17098
|
+
var communityReaction = sqliteTable("community_reaction", {
|
|
17099
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17100
|
+
messageId: text("message_id").notNull().references(() => communityMessage.id, { onDelete: "cascade" }),
|
|
17101
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17102
|
+
emoji: text("emoji").notNull(),
|
|
17103
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17104
|
+
}, (t) => [
|
|
17105
|
+
unique("uq_reaction_message_user_emoji").on(t.messageId, t.userId, t.emoji),
|
|
17106
|
+
index("idx_reaction_message").on(t.messageId)
|
|
17107
|
+
]);
|
|
17108
|
+
var communityAttachment = sqliteTable("community_attachment", {
|
|
17109
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17110
|
+
messageId: text("message_id").notNull().references(() => communityMessage.id, { onDelete: "cascade" }),
|
|
17111
|
+
filename: text("filename").notNull(),
|
|
17112
|
+
url: text("url").notNull(),
|
|
17113
|
+
contentType: text("content_type"),
|
|
17114
|
+
size: integer2("size"),
|
|
17115
|
+
width: integer2("width"),
|
|
17116
|
+
height: integer2("height"),
|
|
17117
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17118
|
+
}, (t) => [index("idx_attachment_message").on(t.messageId)]);
|
|
17119
|
+
var communityPin = sqliteTable("community_pin", {
|
|
17120
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17121
|
+
channelId: text("channel_id").notNull().references(() => communityChannel.id, { onDelete: "cascade" }),
|
|
17122
|
+
messageId: text("message_id").notNull().references(() => communityMessage.id, { onDelete: "cascade" }),
|
|
17123
|
+
pinnedBy: text("pinned_by").references(() => user.id, { onDelete: "set null" }),
|
|
17124
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17125
|
+
}, (t) => [
|
|
17126
|
+
unique("uq_pin_channel_message").on(t.channelId, t.messageId),
|
|
17127
|
+
index("idx_pin_channel").on(t.channelId)
|
|
17128
|
+
]);
|
|
17129
|
+
var communityMention = sqliteTable("community_mention", {
|
|
17130
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17131
|
+
messageId: text("message_id").notNull().references(() => communityMessage.id, { onDelete: "cascade" }),
|
|
17132
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17133
|
+
kind: text("kind").notNull().default("mention"),
|
|
17134
|
+
read: integer2("read").default(0)
|
|
17135
|
+
}, (t) => [
|
|
17136
|
+
index("idx_mention_user_read").on(t.userId, t.read),
|
|
17137
|
+
index("idx_mention_message").on(t.messageId)
|
|
17138
|
+
]);
|
|
17139
|
+
var communityUserProfile = sqliteTable("community_user_profile", {
|
|
17140
|
+
userId: text("user_id").primaryKey().references(() => user.id, { onDelete: "cascade" }),
|
|
17141
|
+
aboutMe: text("about_me").default(""),
|
|
17142
|
+
bannerColor: text("banner_color")
|
|
17143
|
+
});
|
|
17144
|
+
var communityNotificationSetting = sqliteTable("community_notification_setting", {
|
|
17145
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17146
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17147
|
+
serverId: text("server_id").references(() => communityServer.id, {
|
|
17148
|
+
onDelete: "cascade"
|
|
17149
|
+
}),
|
|
17150
|
+
channelId: text("channel_id").references(() => communityChannel.id, {
|
|
17151
|
+
onDelete: "cascade"
|
|
17152
|
+
}),
|
|
17153
|
+
level: text("level").notNull().default("all")
|
|
17154
|
+
}, (t) => [index("idx_notification_setting_user").on(t.userId)]);
|
|
17155
|
+
var communityAuditLog = sqliteTable("community_audit_log", {
|
|
17156
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17157
|
+
serverId: text("server_id").references(() => communityServer.id, {
|
|
17158
|
+
onDelete: "cascade"
|
|
17159
|
+
}),
|
|
17160
|
+
actorId: text("actor_id").references(() => user.id, { onDelete: "set null" }),
|
|
17161
|
+
action: text("action").notNull(),
|
|
17162
|
+
targetType: text("target_type").notNull(),
|
|
17163
|
+
targetId: text("target_id").notNull(),
|
|
17164
|
+
changes: text("changes"),
|
|
17165
|
+
reason: text("reason"),
|
|
17166
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17167
|
+
}, (t) => [
|
|
17168
|
+
index("idx_audit_log_server_created").on(t.serverId, t.createdAt),
|
|
17169
|
+
index("idx_audit_log_server_action").on(t.serverId, t.action),
|
|
17170
|
+
index("idx_audit_log_actor_created").on(t.actorId, t.createdAt)
|
|
17171
|
+
]);
|
|
17172
|
+
var communityBotApprovalRequest = sqliteTable("community_bot_approval_request", {
|
|
17173
|
+
id: text("id").primaryKey().$defaultFn(() => "bar_" + nanoid3()),
|
|
17174
|
+
botId: text("bot_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17175
|
+
kind: text("kind").notNull(),
|
|
17176
|
+
serverId: text("server_id").references(() => communityServer.id, {
|
|
17177
|
+
onDelete: "cascade"
|
|
17178
|
+
}),
|
|
17179
|
+
requestedByUserId: text("requested_by_user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17180
|
+
dmMessageId: text("dm_message_id").notNull().references(() => communityMessage.id, { onDelete: "cascade" }),
|
|
17181
|
+
status: text("status").notNull().default("pending"),
|
|
17182
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
17183
|
+
resolvedAt: text("resolved_at")
|
|
17184
|
+
}, (t) => [index("idx_community_bot_approval_bot").on(t.botId, t.status)]);
|
|
17185
|
+
var communityInboxDismissal = sqliteTable("community_inbox_dismissal", {
|
|
17186
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17187
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17188
|
+
eventKey: text("event_key").notNull(),
|
|
17189
|
+
dismissedAt: text("dismissed_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17190
|
+
}, (t) => [
|
|
17191
|
+
unique("uq_inbox_dismissal_user_event").on(t.userId, t.eventKey),
|
|
17192
|
+
index("idx_inbox_dismissal_user").on(t.userId)
|
|
17193
|
+
]);
|
|
17194
|
+
|
|
17195
|
+
// ../shared/src/db/community-machine-schema.ts
|
|
17196
|
+
var exports_community_machine_schema = {};
|
|
17197
|
+
__export(exports_community_machine_schema, {
|
|
17198
|
+
communityMachineToken: () => communityMachineToken,
|
|
17199
|
+
communityMachineCredential: () => communityMachineCredential,
|
|
17200
|
+
communityMachine: () => communityMachine,
|
|
17201
|
+
communityBotBinding: () => communityBotBinding,
|
|
17202
|
+
communityAgentRunnerKey: () => communityAgentRunnerKey
|
|
17203
|
+
});
|
|
17204
|
+
init_nanoid();
|
|
17205
|
+
var communityMachineToken = sqliteTable("community_machine_token", {
|
|
17206
|
+
id: text("id").primaryKey().$defaultFn(() => "cmt_" + nanoid3(32)),
|
|
17207
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17208
|
+
machineId: text("machine_id"),
|
|
17209
|
+
status: text("status").notNull().default("pending"),
|
|
17210
|
+
expiresAt: text("expires_at").notNull(),
|
|
17211
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
17212
|
+
lastUsedAt: text("last_used_at")
|
|
17213
|
+
}, (t) => [
|
|
17214
|
+
index("idx_community_machine_token_user_status").on(t.userId, t.status),
|
|
17215
|
+
uniqueIndex("uq_community_machine_token_user_pending").on(t.userId).where(sql`status = 'pending'`)
|
|
17216
|
+
]);
|
|
17217
|
+
var communityMachine = sqliteTable("community_machine", {
|
|
17218
|
+
id: text("id").primaryKey().$defaultFn(() => "cm_" + nanoid3()),
|
|
17219
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17220
|
+
displayName: text("display_name").notNull().default(""),
|
|
17221
|
+
hostname: text("hostname").notNull().default(""),
|
|
17222
|
+
platform: text("platform").notNull().default(""),
|
|
17223
|
+
arch: text("arch").notNull().default(""),
|
|
17224
|
+
osRelease: text("os_release").notNull().default(""),
|
|
17225
|
+
daemonVersion: text("daemon_version").notNull().default(""),
|
|
17226
|
+
metadata: text("metadata"),
|
|
17227
|
+
availableRuntimes: text("available_runtimes", { mode: "json" }).$type().notNull().default([]),
|
|
17228
|
+
status: text("status").notNull().default("offline"),
|
|
17229
|
+
lastSeenAt: text("last_seen_at"),
|
|
17230
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
17231
|
+
updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17232
|
+
}, (t) => [
|
|
17233
|
+
index("idx_community_machine_user_last_seen").on(t.userId, t.lastSeenAt),
|
|
17234
|
+
index("idx_community_machine_user_updated").on(t.userId, t.updatedAt),
|
|
17235
|
+
index("idx_community_machine_user_status").on(t.userId, t.status)
|
|
17236
|
+
]);
|
|
17237
|
+
var communityMachineCredential = sqliteTable("community_machine_credential", {
|
|
17238
|
+
id: text("id").primaryKey().$defaultFn(() => "cmkid_" + nanoid3()),
|
|
17239
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17240
|
+
machineId: text("machine_id").notNull().references(() => communityMachine.id, { onDelete: "cascade" }),
|
|
17241
|
+
credentialHash: text("credential_hash").notNull().unique(),
|
|
17242
|
+
doName: text("do_name").notNull().unique(),
|
|
17243
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
17244
|
+
lastUsedAt: text("last_used_at"),
|
|
17245
|
+
revokedAt: text("revoked_at")
|
|
17246
|
+
}, (t) => [
|
|
17247
|
+
index("idx_community_machine_credential_user").on(t.userId),
|
|
17248
|
+
index("idx_community_machine_credential_machine").on(t.machineId)
|
|
17249
|
+
]);
|
|
17250
|
+
var communityBotBinding = sqliteTable("community_bot_binding", {
|
|
17251
|
+
userId: text("user_id").primaryKey().references(() => user.id, { onDelete: "cascade" }),
|
|
17252
|
+
machineId: text("machine_id").notNull().references(() => communityMachine.id, { onDelete: "restrict" }),
|
|
17253
|
+
runtime: text("runtime").notNull(),
|
|
17254
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17255
|
+
}, (t) => [index("idx_community_bot_binding_machine").on(t.machineId)]);
|
|
17256
|
+
var communityAgentRunnerKey = sqliteTable("community_agent_runner_key", {
|
|
17257
|
+
id: text("id").primaryKey().$defaultFn(() => "crkid_" + nanoid3()),
|
|
17258
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17259
|
+
machineId: text("machine_id").notNull().references(() => communityMachine.id, { onDelete: "cascade" }),
|
|
17260
|
+
agentId: text("agent_id").notNull(),
|
|
17261
|
+
runnerKeyHash: text("runner_key_hash").notNull().unique(),
|
|
17262
|
+
doName: text("do_name").notNull().unique(),
|
|
17263
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
17264
|
+
revokedAt: text("revoked_at")
|
|
17265
|
+
}, (t) => [
|
|
17266
|
+
index("idx_community_agent_runner_key_machine_agent").on(t.machineId, t.agentId)
|
|
17267
|
+
]);
|
|
17268
|
+
|
|
17269
|
+
// ../shared/src/db/index.ts
|
|
17270
|
+
var allSchema = { ...exports_schema, ...exports_community_schema, ...exports_community_machine_schema };
|
|
17271
|
+
// ../shared/src/db/queries/user.ts
|
|
17272
|
+
var publicUserColumns = {
|
|
17273
|
+
id: user.id,
|
|
17274
|
+
name: user.name,
|
|
17275
|
+
email: user.email,
|
|
17276
|
+
emailVerified: user.emailVerified,
|
|
17277
|
+
image: user.image,
|
|
17278
|
+
createdAt: user.createdAt,
|
|
17279
|
+
updatedAt: user.updatedAt,
|
|
17280
|
+
discriminator: user.discriminator
|
|
17281
|
+
};
|
|
17282
|
+
var internalUserColumns = {
|
|
17283
|
+
...publicUserColumns,
|
|
17284
|
+
isBot: user.isBot,
|
|
17285
|
+
ownerUserId: user.ownerUserId,
|
|
17286
|
+
deletedAt: user.deletedAt
|
|
17287
|
+
};
|
|
16771
17288
|
// ../shared/src/db/queries/task.ts
|
|
16772
17289
|
var DEFAULT_STALE_SECONDS = Number(process.env.ALOOK_STALE_DISPATCH_TIMEOUT_S) || 20;
|
|
16773
17290
|
var DEFAULT_STALE_RUNNING_SECONDS = Number(process.env.ALOOK_STALE_RUNNING_TIMEOUT_S) || 3600;
|
|
@@ -16793,6 +17310,109 @@ var RESERVED_HANDLES = new Set([
|
|
|
16793
17310
|
function toAlookAddress(h) {
|
|
16794
17311
|
return `${h}${DOMAIN}`;
|
|
16795
17312
|
}
|
|
17313
|
+
// ../shared/src/logger.ts
|
|
17314
|
+
var LEVELS = {
|
|
17315
|
+
debug: 0,
|
|
17316
|
+
info: 1,
|
|
17317
|
+
warn: 2,
|
|
17318
|
+
error: 3,
|
|
17319
|
+
silent: 4
|
|
17320
|
+
};
|
|
17321
|
+
|
|
17322
|
+
class Logger {
|
|
17323
|
+
service;
|
|
17324
|
+
level;
|
|
17325
|
+
pretty;
|
|
17326
|
+
fields;
|
|
17327
|
+
constructor(opts, fields) {
|
|
17328
|
+
this.service = opts.service;
|
|
17329
|
+
this.level = LEVELS[opts.level ?? "info"];
|
|
17330
|
+
this.pretty = opts.pretty ?? false;
|
|
17331
|
+
this.fields = fields ?? {};
|
|
17332
|
+
}
|
|
17333
|
+
debug(msg, ctx) {
|
|
17334
|
+
this.write("debug", msg, ctx);
|
|
17335
|
+
}
|
|
17336
|
+
info(msg, ctx) {
|
|
17337
|
+
this.write("info", msg, ctx);
|
|
17338
|
+
}
|
|
17339
|
+
warn(msg, ctx) {
|
|
17340
|
+
this.write("warn", msg, ctx);
|
|
17341
|
+
}
|
|
17342
|
+
error(msg, ctx) {
|
|
17343
|
+
this.write("error", msg, ctx);
|
|
17344
|
+
}
|
|
17345
|
+
child(fields) {
|
|
17346
|
+
const merged = { ...this.fields, ...fields };
|
|
17347
|
+
const child = new Logger({ service: this.service, level: this.levelName(), pretty: this.pretty }, merged);
|
|
17348
|
+
return child;
|
|
17349
|
+
}
|
|
17350
|
+
levelName() {
|
|
17351
|
+
for (const [name, num] of Object.entries(LEVELS)) {
|
|
17352
|
+
if (num === this.level)
|
|
17353
|
+
return name;
|
|
17354
|
+
}
|
|
17355
|
+
return "info";
|
|
17356
|
+
}
|
|
17357
|
+
write(level, msg, ctx) {
|
|
17358
|
+
if (LEVELS[level] < this.level)
|
|
17359
|
+
return;
|
|
17360
|
+
const entry = {
|
|
17361
|
+
level,
|
|
17362
|
+
msg,
|
|
17363
|
+
service: this.service,
|
|
17364
|
+
...this.fields,
|
|
17365
|
+
...ctx,
|
|
17366
|
+
ts: new Date().toISOString()
|
|
17367
|
+
};
|
|
17368
|
+
for (const [k, v] of Object.entries(entry)) {
|
|
17369
|
+
if (v instanceof Error) {
|
|
17370
|
+
entry[k] = { message: v.message, stack: v.stack };
|
|
17371
|
+
}
|
|
17372
|
+
}
|
|
17373
|
+
let line;
|
|
17374
|
+
if (this.pretty) {
|
|
17375
|
+
const ts = entry.ts.replace("T", " ").replace("Z", "");
|
|
17376
|
+
const lvl = entry.level.toUpperCase().padEnd(5);
|
|
17377
|
+
const pairs = Object.entries(entry).filter(([k]) => k !== "level" && k !== "msg" && k !== "service" && k !== "ts").map(([k, v]) => `${k}=${typeof v === "object" ? JSON.stringify(v) : v}`).join(" ");
|
|
17378
|
+
line = `${ts} ${lvl} [${entry.service}] ${entry.msg}${pairs ? " " + pairs : ""}`;
|
|
17379
|
+
} else {
|
|
17380
|
+
line = JSON.stringify(entry);
|
|
17381
|
+
}
|
|
17382
|
+
if (level === "error") {
|
|
17383
|
+
console.error(line);
|
|
17384
|
+
} else {
|
|
17385
|
+
console.log(line);
|
|
17386
|
+
}
|
|
17387
|
+
}
|
|
17388
|
+
}
|
|
17389
|
+
function createLogger(opts) {
|
|
17390
|
+
return new Logger(opts);
|
|
17391
|
+
}
|
|
17392
|
+
|
|
17393
|
+
// ../shared/src/db/queries/community/channel.ts
|
|
17394
|
+
var log = createLogger({ service: "community-queries" });
|
|
17395
|
+
var CHANNEL_COLUMNS = {
|
|
17396
|
+
id: communityChannel.id,
|
|
17397
|
+
serverId: communityChannel.serverId,
|
|
17398
|
+
categoryId: communityChannel.categoryId,
|
|
17399
|
+
name: communityChannel.name,
|
|
17400
|
+
type: communityChannel.type,
|
|
17401
|
+
topic: communityChannel.topic,
|
|
17402
|
+
position: communityChannel.position,
|
|
17403
|
+
forumTags: communityChannel.forumTags,
|
|
17404
|
+
parentChannelId: communityChannel.parentChannelId,
|
|
17405
|
+
creatorId: communityChannel.creatorId,
|
|
17406
|
+
messageCount: communityChannel.messageCount,
|
|
17407
|
+
archived: communityChannel.archived,
|
|
17408
|
+
parentMessageId: communityChannel.parentMessageId,
|
|
17409
|
+
lastMessageAt: communityChannel.lastMessageAt,
|
|
17410
|
+
createdAt: communityChannel.createdAt
|
|
17411
|
+
};
|
|
17412
|
+
// ../shared/src/db/queries/community/message.ts
|
|
17413
|
+
var log2 = createLogger({ service: "community-queries" });
|
|
17414
|
+
// ../shared/src/db/queries/community/search.ts
|
|
17415
|
+
var FTS_KEYWORDS = new Set(["and", "or", "not", "near"]);
|
|
16796
17416
|
// ../shared/src/mode.ts
|
|
16797
17417
|
function isLocalUrl(url2) {
|
|
16798
17418
|
try {
|
|
@@ -16972,7 +17592,7 @@ import { createInterface } from "readline";
|
|
|
16972
17592
|
import { execSync } from "child_process";
|
|
16973
17593
|
|
|
16974
17594
|
// lib/logger.ts
|
|
16975
|
-
var
|
|
17595
|
+
var LEVELS2 = {
|
|
16976
17596
|
debug: 0,
|
|
16977
17597
|
info: 1,
|
|
16978
17598
|
warn: 2,
|
|
@@ -17018,12 +17638,12 @@ class Logger2 {
|
|
|
17018
17638
|
module;
|
|
17019
17639
|
constructor(opts = {}) {
|
|
17020
17640
|
const envLevel = process.env.ALOOK_LOG_LEVEL;
|
|
17021
|
-
this.level =
|
|
17641
|
+
this.level = LEVELS2[opts.level ?? envLevel ?? "info"];
|
|
17022
17642
|
this.color = useColor();
|
|
17023
17643
|
this.module = opts.module;
|
|
17024
17644
|
}
|
|
17025
17645
|
setLevel(level) {
|
|
17026
|
-
this.level =
|
|
17646
|
+
this.level = LEVELS2[level];
|
|
17027
17647
|
}
|
|
17028
17648
|
child(module) {
|
|
17029
17649
|
const child = new Logger2({ level: this.levelName(), module });
|
|
@@ -17042,14 +17662,14 @@ class Logger2 {
|
|
|
17042
17662
|
this.write("error", msg, args);
|
|
17043
17663
|
}
|
|
17044
17664
|
levelName() {
|
|
17045
|
-
for (const [name, num] of Object.entries(
|
|
17665
|
+
for (const [name, num] of Object.entries(LEVELS2)) {
|
|
17046
17666
|
if (num === this.level)
|
|
17047
17667
|
return name;
|
|
17048
17668
|
}
|
|
17049
17669
|
return "info";
|
|
17050
17670
|
}
|
|
17051
17671
|
write(level, msg, args) {
|
|
17052
|
-
if (
|
|
17672
|
+
if (LEVELS2[level] < this.level)
|
|
17053
17673
|
return;
|
|
17054
17674
|
const ts = timestamp();
|
|
17055
17675
|
const label = LABELS[level];
|
|
@@ -17070,7 +17690,7 @@ class Logger2 {
|
|
|
17070
17690
|
if (a instanceof Error) {
|
|
17071
17691
|
dest.write(` ${a.message}
|
|
17072
17692
|
`);
|
|
17073
|
-
if (a.stack && this.level <=
|
|
17693
|
+
if (a.stack && this.level <= LEVELS2.debug) {
|
|
17074
17694
|
dest.write(` ${a.stack}
|
|
17075
17695
|
`);
|
|
17076
17696
|
}
|
|
@@ -17089,10 +17709,10 @@ class Logger2 {
|
|
|
17089
17709
|
function createLogger2(opts) {
|
|
17090
17710
|
return new Logger2(opts);
|
|
17091
17711
|
}
|
|
17092
|
-
var
|
|
17712
|
+
var log3 = createLogger2();
|
|
17093
17713
|
|
|
17094
17714
|
// daemon/kill-tree.ts
|
|
17095
|
-
var
|
|
17715
|
+
var log4 = createLogger2({ module: "kill-tree" });
|
|
17096
17716
|
function killGraceMs() {
|
|
17097
17717
|
return Number(process.env.ALOOK_KILL_GRACE_MS) || 2000;
|
|
17098
17718
|
}
|
|
@@ -17146,7 +17766,7 @@ async function killProcessTree(pid, opts) {
|
|
|
17146
17766
|
await new Promise((r) => setTimeout(r, POLL_MS));
|
|
17147
17767
|
}
|
|
17148
17768
|
if (isAlive(pid)) {
|
|
17149
|
-
|
|
17769
|
+
log4.warn(`pid=${pid} survived SIGTERM after ${graceMs}ms — escalating to SIGKILL`);
|
|
17150
17770
|
signalTree(pid, "SIGKILL");
|
|
17151
17771
|
}
|
|
17152
17772
|
}
|
|
@@ -17155,41 +17775,157 @@ async function killProcessTree(pid, opts) {
|
|
|
17155
17775
|
class ClaudeBackend {
|
|
17156
17776
|
cliPath;
|
|
17157
17777
|
name = "claude";
|
|
17778
|
+
lifecycle = { kind: "persistent", stdin: "gated", inFlightWake: "queue" };
|
|
17779
|
+
busyDeliveryMode = "gated";
|
|
17780
|
+
supportsStdinNotification = true;
|
|
17158
17781
|
constructor(cliPath) {
|
|
17159
17782
|
this.cliPath = cliPath;
|
|
17160
17783
|
}
|
|
17161
|
-
|
|
17162
|
-
|
|
17163
|
-
|
|
17164
|
-
|
|
17165
|
-
|
|
17166
|
-
|
|
17167
|
-
|
|
17168
|
-
"
|
|
17169
|
-
|
|
17170
|
-
];
|
|
17171
|
-
|
|
17172
|
-
|
|
17173
|
-
|
|
17174
|
-
|
|
17175
|
-
|
|
17176
|
-
|
|
17177
|
-
|
|
17178
|
-
|
|
17179
|
-
|
|
17180
|
-
|
|
17181
|
-
|
|
17182
|
-
|
|
17183
|
-
|
|
17184
|
-
|
|
17185
|
-
|
|
17186
|
-
|
|
17187
|
-
|
|
17188
|
-
|
|
17189
|
-
|
|
17190
|
-
|
|
17191
|
-
|
|
17192
|
-
|
|
17784
|
+
parseLine(line) {
|
|
17785
|
+
if (!line.trim())
|
|
17786
|
+
return [];
|
|
17787
|
+
let event;
|
|
17788
|
+
try {
|
|
17789
|
+
event = JSON.parse(line);
|
|
17790
|
+
} catch {
|
|
17791
|
+
return [{ kind: "log", content: line, level: "debug" }];
|
|
17792
|
+
}
|
|
17793
|
+
const events = [];
|
|
17794
|
+
const eventType = event.type;
|
|
17795
|
+
switch (eventType) {
|
|
17796
|
+
case "assistant": {
|
|
17797
|
+
const message2 = event.message;
|
|
17798
|
+
if (!message2)
|
|
17799
|
+
break;
|
|
17800
|
+
const content = message2.content;
|
|
17801
|
+
if (!Array.isArray(content))
|
|
17802
|
+
break;
|
|
17803
|
+
for (const block of content) {
|
|
17804
|
+
if (block.type === "text") {
|
|
17805
|
+
events.push({ kind: "text", text: block.text || "" });
|
|
17806
|
+
} else if (block.type === "thinking") {
|
|
17807
|
+
events.push({ kind: "thinking", text: block.text || "" });
|
|
17808
|
+
} else if (block.type === "tool_use") {
|
|
17809
|
+
events.push({ kind: "tool_call", name: block.name || "", input: block.input, callId: block.id });
|
|
17810
|
+
}
|
|
17811
|
+
}
|
|
17812
|
+
break;
|
|
17813
|
+
}
|
|
17814
|
+
case "result": {
|
|
17815
|
+
const result = event.result;
|
|
17816
|
+
const isError = event.is_error;
|
|
17817
|
+
if (isError) {
|
|
17818
|
+
events.push({ kind: "error", message: result || "unknown error" });
|
|
17819
|
+
}
|
|
17820
|
+
const resultSessionId = event.session_id;
|
|
17821
|
+
events.push({ kind: "turn_end", sessionId: resultSessionId || undefined });
|
|
17822
|
+
const usage = event.usage;
|
|
17823
|
+
if (usage || event.total_cost_usd != null) {
|
|
17824
|
+
events.push({
|
|
17825
|
+
kind: "telemetry",
|
|
17826
|
+
name: "token_usage",
|
|
17827
|
+
source: "claude_result_usage",
|
|
17828
|
+
usageKind: "per_turn",
|
|
17829
|
+
attrs: {
|
|
17830
|
+
inputTokens: usage?.input_tokens,
|
|
17831
|
+
outputTokens: usage?.output_tokens,
|
|
17832
|
+
cachedInputTokens: usage?.cache_read_input_tokens,
|
|
17833
|
+
cacheCreationInputTokens: usage?.cache_creation_input_tokens,
|
|
17834
|
+
totalCostUsd: event.total_cost_usd,
|
|
17835
|
+
durationMs: event.duration_ms,
|
|
17836
|
+
durationApiMs: event.duration_api_ms,
|
|
17837
|
+
numTurns: event.num_turns,
|
|
17838
|
+
resultSubtype: event.subtype,
|
|
17839
|
+
resultIsError: event.is_error,
|
|
17840
|
+
serviceTier: usage?.service_tier
|
|
17841
|
+
}
|
|
17842
|
+
});
|
|
17843
|
+
}
|
|
17844
|
+
break;
|
|
17845
|
+
}
|
|
17846
|
+
case "tool_result": {
|
|
17847
|
+
const toolUseId = event.tool_use_id;
|
|
17848
|
+
const content = event.content;
|
|
17849
|
+
events.push({ kind: "tool_output", callId: toolUseId, output: content });
|
|
17850
|
+
break;
|
|
17851
|
+
}
|
|
17852
|
+
case "system": {
|
|
17853
|
+
const subtype = event.subtype;
|
|
17854
|
+
if (subtype === "init") {
|
|
17855
|
+
const sid = event.session_id;
|
|
17856
|
+
events.push({ kind: "session_init", sessionId: sid || "" });
|
|
17857
|
+
} else if (subtype === "context_pruning" || subtype === "compaction") {
|
|
17858
|
+
events.push({ kind: "compaction_started" });
|
|
17859
|
+
} else if (subtype === "compaction_finished" || subtype === "context_pruning_finished") {
|
|
17860
|
+
events.push({ kind: "compaction_finished" });
|
|
17861
|
+
} else if (subtype === "status" || subtype === "stream_event") {
|
|
17862
|
+
events.push({
|
|
17863
|
+
kind: "internal_progress",
|
|
17864
|
+
source: "claude_system",
|
|
17865
|
+
itemType: subtype,
|
|
17866
|
+
payloadBytes: line.length
|
|
17867
|
+
});
|
|
17868
|
+
}
|
|
17869
|
+
break;
|
|
17870
|
+
}
|
|
17871
|
+
case "control_request": {
|
|
17872
|
+
const requestId = event.request_id;
|
|
17873
|
+
if (requestId) {
|
|
17874
|
+
events.push({ kind: "permission_request", requestId, payload: event.payload });
|
|
17875
|
+
}
|
|
17876
|
+
break;
|
|
17877
|
+
}
|
|
17878
|
+
default: {
|
|
17879
|
+
events.push({ kind: "log", content: line, level: "debug" });
|
|
17880
|
+
}
|
|
17881
|
+
}
|
|
17882
|
+
return events;
|
|
17883
|
+
}
|
|
17884
|
+
encodeStdinMessage(text2, mode, opts) {
|
|
17885
|
+
const msg = {
|
|
17886
|
+
type: "user",
|
|
17887
|
+
message: {
|
|
17888
|
+
role: "user",
|
|
17889
|
+
content: [{ type: "text", text: text2 }]
|
|
17890
|
+
}
|
|
17891
|
+
};
|
|
17892
|
+
if (opts?.sessionId) {
|
|
17893
|
+
msg.session_id = opts.sessionId;
|
|
17894
|
+
}
|
|
17895
|
+
return JSON.stringify(msg);
|
|
17896
|
+
}
|
|
17897
|
+
execute(prompt, options) {
|
|
17898
|
+
const useStdinPrompt = options.steeringEnabled === true;
|
|
17899
|
+
const args = [];
|
|
17900
|
+
if (!useStdinPrompt) {
|
|
17901
|
+
args.push("-p", prompt);
|
|
17902
|
+
}
|
|
17903
|
+
args.push("--output-format", "stream-json", "--verbose", "--permission-mode", "bypassPermissions");
|
|
17904
|
+
if (useStdinPrompt) {
|
|
17905
|
+
args.push("--input-format", "stream-json");
|
|
17906
|
+
}
|
|
17907
|
+
if (options.model) {
|
|
17908
|
+
args.push("--model", options.model);
|
|
17909
|
+
}
|
|
17910
|
+
if (options.maxTurns) {
|
|
17911
|
+
args.push("--max-turns", String(options.maxTurns));
|
|
17912
|
+
}
|
|
17913
|
+
if (options.resumeSessionId) {
|
|
17914
|
+
args.push("--resume", options.resumeSessionId);
|
|
17915
|
+
}
|
|
17916
|
+
const proc = spawn(this.cliPath, args, {
|
|
17917
|
+
cwd: options.cwd,
|
|
17918
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
17919
|
+
env: { ...process.env, ...options.env },
|
|
17920
|
+
shell: process.platform === "win32",
|
|
17921
|
+
windowsHide: true,
|
|
17922
|
+
detached: process.platform !== "win32"
|
|
17923
|
+
});
|
|
17924
|
+
if (!proc.pid) {
|
|
17925
|
+
const error51 = `Failed to start ${this.cliPath}: binary not found or not executable. Is 'claude' installed and on PATH?`;
|
|
17926
|
+
const failedResult = { status: "failed", output: "", error: error51, durationMs: 0, sessionId: "" };
|
|
17927
|
+
const emptyMessages = { [Symbol.asyncIterator]() {
|
|
17928
|
+
return { async next() {
|
|
17193
17929
|
return { value: undefined, done: true };
|
|
17194
17930
|
} };
|
|
17195
17931
|
} };
|
|
@@ -17224,15 +17960,58 @@ class ClaudeBackend {
|
|
|
17224
17960
|
r();
|
|
17225
17961
|
}
|
|
17226
17962
|
};
|
|
17963
|
+
const parsedEventQueue = [];
|
|
17964
|
+
let parsedEventResolve = null;
|
|
17965
|
+
let parsedEventDone = false;
|
|
17966
|
+
const pushParsedEvent = (evt) => {
|
|
17967
|
+
parsedEventQueue.push(evt);
|
|
17968
|
+
if (parsedEventResolve) {
|
|
17969
|
+
const r = parsedEventResolve;
|
|
17970
|
+
parsedEventResolve = null;
|
|
17971
|
+
r();
|
|
17972
|
+
}
|
|
17973
|
+
};
|
|
17974
|
+
const stdinWriteQueue = [];
|
|
17975
|
+
let stdinDraining = false;
|
|
17976
|
+
const enqueueStdinWrite = (data) => {
|
|
17977
|
+
stdinWriteQueue.push(data);
|
|
17978
|
+
drainStdinQueue();
|
|
17979
|
+
};
|
|
17980
|
+
const drainStdinQueue = () => {
|
|
17981
|
+
if (stdinDraining)
|
|
17982
|
+
return;
|
|
17983
|
+
stdinDraining = true;
|
|
17984
|
+
while (stdinWriteQueue.length > 0) {
|
|
17985
|
+
const line = stdinWriteQueue.shift();
|
|
17986
|
+
try {
|
|
17987
|
+
proc.stdin?.write(line + `
|
|
17988
|
+
`);
|
|
17989
|
+
} catch {}
|
|
17990
|
+
}
|
|
17991
|
+
stdinDraining = false;
|
|
17992
|
+
};
|
|
17227
17993
|
const resultPromise = new Promise((resolve) => {
|
|
17228
17994
|
const stderrChunks = [];
|
|
17229
17995
|
proc.stderr?.on("data", (chunk) => {
|
|
17230
17996
|
stderrChunks.push(chunk.toString());
|
|
17231
17997
|
});
|
|
17232
17998
|
const rl = createInterface({ input: proc.stdout });
|
|
17999
|
+
if (useStdinPrompt) {
|
|
18000
|
+
const initialMsg = JSON.stringify({
|
|
18001
|
+
type: "user",
|
|
18002
|
+
message: {
|
|
18003
|
+
role: "user",
|
|
18004
|
+
content: [{ type: "text", text: prompt }]
|
|
18005
|
+
}
|
|
18006
|
+
});
|
|
18007
|
+
enqueueStdinWrite(initialMsg);
|
|
18008
|
+
}
|
|
17233
18009
|
rl.on("line", (line) => {
|
|
17234
18010
|
if (!line.trim())
|
|
17235
18011
|
return;
|
|
18012
|
+
const parsed = this.parseLine(line);
|
|
18013
|
+
for (const pe of parsed)
|
|
18014
|
+
pushParsedEvent(pe);
|
|
17236
18015
|
let event;
|
|
17237
18016
|
try {
|
|
17238
18017
|
event = JSON.parse(line);
|
|
@@ -17278,6 +18057,13 @@ class ClaudeBackend {
|
|
|
17278
18057
|
resultStatus = "failed";
|
|
17279
18058
|
lastError = result || "unknown error";
|
|
17280
18059
|
}
|
|
18060
|
+
if (useStdinPrompt) {
|
|
18061
|
+
setTimeout(() => {
|
|
18062
|
+
try {
|
|
18063
|
+
proc.stdin?.end();
|
|
18064
|
+
} catch {}
|
|
18065
|
+
}, 100);
|
|
18066
|
+
}
|
|
17281
18067
|
break;
|
|
17282
18068
|
}
|
|
17283
18069
|
case "tool_result": {
|
|
@@ -17302,7 +18088,7 @@ class ClaudeBackend {
|
|
|
17302
18088
|
break;
|
|
17303
18089
|
}
|
|
17304
18090
|
case "control_request": {
|
|
17305
|
-
handleControlRequest(proc, event);
|
|
18091
|
+
handleControlRequest(proc, event, enqueueStdinWrite);
|
|
17306
18092
|
break;
|
|
17307
18093
|
}
|
|
17308
18094
|
default: {
|
|
@@ -17319,11 +18105,17 @@ class ClaudeBackend {
|
|
|
17319
18105
|
lastError = `spawn error: ${err.message}`;
|
|
17320
18106
|
resolveSessionId(lastSessionId);
|
|
17321
18107
|
messageDone = true;
|
|
18108
|
+
parsedEventDone = true;
|
|
17322
18109
|
if (messageResolve) {
|
|
17323
18110
|
const r = messageResolve;
|
|
17324
18111
|
messageResolve = null;
|
|
17325
18112
|
r();
|
|
17326
18113
|
}
|
|
18114
|
+
if (parsedEventResolve) {
|
|
18115
|
+
const r = parsedEventResolve;
|
|
18116
|
+
parsedEventResolve = null;
|
|
18117
|
+
r();
|
|
18118
|
+
}
|
|
17327
18119
|
resolve({
|
|
17328
18120
|
status: "failed",
|
|
17329
18121
|
output: "",
|
|
@@ -17346,11 +18138,17 @@ class ClaudeBackend {
|
|
|
17346
18138
|
}
|
|
17347
18139
|
resolveSessionId(lastSessionId);
|
|
17348
18140
|
messageDone = true;
|
|
18141
|
+
parsedEventDone = true;
|
|
17349
18142
|
if (messageResolve) {
|
|
17350
18143
|
const r = messageResolve;
|
|
17351
18144
|
messageResolve = null;
|
|
17352
18145
|
r();
|
|
17353
18146
|
}
|
|
18147
|
+
if (parsedEventResolve) {
|
|
18148
|
+
const r = parsedEventResolve;
|
|
18149
|
+
parsedEventResolve = null;
|
|
18150
|
+
r();
|
|
18151
|
+
}
|
|
17354
18152
|
resolve({
|
|
17355
18153
|
status: resultStatus,
|
|
17356
18154
|
output: lastOutput,
|
|
@@ -17377,10 +18175,47 @@ class ClaudeBackend {
|
|
|
17377
18175
|
};
|
|
17378
18176
|
}
|
|
17379
18177
|
};
|
|
17380
|
-
|
|
18178
|
+
const parsedEvents = {
|
|
18179
|
+
[Symbol.asyncIterator]() {
|
|
18180
|
+
return {
|
|
18181
|
+
async next() {
|
|
18182
|
+
while (parsedEventQueue.length === 0 && !parsedEventDone) {
|
|
18183
|
+
await new Promise((resolve) => {
|
|
18184
|
+
parsedEventResolve = resolve;
|
|
18185
|
+
});
|
|
18186
|
+
}
|
|
18187
|
+
if (parsedEventQueue.length > 0) {
|
|
18188
|
+
return { value: parsedEventQueue.shift(), done: false };
|
|
18189
|
+
}
|
|
18190
|
+
return { value: undefined, done: true };
|
|
18191
|
+
}
|
|
18192
|
+
};
|
|
18193
|
+
}
|
|
18194
|
+
};
|
|
18195
|
+
const send = (text2, mode) => {
|
|
18196
|
+
const encoded = this.encodeStdinMessage(text2, mode, { sessionId: lastSessionId || undefined });
|
|
18197
|
+
if (!encoded)
|
|
18198
|
+
return { ok: false, reason: "encoding failed" };
|
|
18199
|
+
if (!proc.stdin || proc.stdin.destroyed)
|
|
18200
|
+
return { ok: false, reason: "stdin closed" };
|
|
18201
|
+
enqueueStdinWrite(encoded);
|
|
18202
|
+
return { ok: true };
|
|
18203
|
+
};
|
|
18204
|
+
const descriptor = {
|
|
18205
|
+
lifecycle: this.lifecycle,
|
|
18206
|
+
busyDeliveryMode: this.busyDeliveryMode,
|
|
18207
|
+
supportsStdinNotification: this.supportsStdinNotification
|
|
18208
|
+
};
|
|
18209
|
+
const closeStdin = () => {
|
|
18210
|
+
try {
|
|
18211
|
+
if (proc.stdin && !proc.stdin.destroyed)
|
|
18212
|
+
proc.stdin.end();
|
|
18213
|
+
} catch {}
|
|
18214
|
+
};
|
|
18215
|
+
return { pid: proc.pid, messages, parsedEvents, sessionId: sessionIdPromise, result: resultPromise, send, closeStdin, descriptor };
|
|
17381
18216
|
}
|
|
17382
18217
|
}
|
|
17383
|
-
function handleControlRequest(proc, event) {
|
|
18218
|
+
function handleControlRequest(proc, event, enqueueStdinWrite) {
|
|
17384
18219
|
const requestId = event.request_id;
|
|
17385
18220
|
if (!requestId)
|
|
17386
18221
|
return;
|
|
@@ -17409,10 +18244,14 @@ function handleControlRequest(proc, event) {
|
|
|
17409
18244
|
}
|
|
17410
18245
|
}
|
|
17411
18246
|
});
|
|
17412
|
-
|
|
17413
|
-
|
|
18247
|
+
if (enqueueStdinWrite) {
|
|
18248
|
+
enqueueStdinWrite(approval);
|
|
18249
|
+
} else {
|
|
18250
|
+
try {
|
|
18251
|
+
proc.stdin?.write(approval + `
|
|
17414
18252
|
`);
|
|
17415
|
-
|
|
18253
|
+
} catch {}
|
|
18254
|
+
}
|
|
17416
18255
|
}
|
|
17417
18256
|
|
|
17418
18257
|
// daemon/agent/codex.ts
|
|
@@ -17444,9 +18283,196 @@ function extractThreadID(response) {
|
|
|
17444
18283
|
class CodexBackend {
|
|
17445
18284
|
cliPath;
|
|
17446
18285
|
name = "codex";
|
|
18286
|
+
lifecycle = { kind: "persistent", stdin: "direct", inFlightWake: "steer" };
|
|
18287
|
+
busyDeliveryMode = "direct";
|
|
18288
|
+
supportsStdinNotification = true;
|
|
18289
|
+
_rpcId = 0;
|
|
17447
18290
|
constructor(cliPath) {
|
|
17448
18291
|
this.cliPath = cliPath;
|
|
17449
18292
|
}
|
|
18293
|
+
parseLine(line) {
|
|
18294
|
+
if (!line.trim())
|
|
18295
|
+
return [];
|
|
18296
|
+
let msg;
|
|
18297
|
+
try {
|
|
18298
|
+
msg = JSON.parse(line);
|
|
18299
|
+
} catch {
|
|
18300
|
+
return [{ kind: "log", content: line, level: "debug" }];
|
|
18301
|
+
}
|
|
18302
|
+
if (msg.id !== undefined && !msg.method)
|
|
18303
|
+
return [];
|
|
18304
|
+
if (msg.id !== undefined && msg.method)
|
|
18305
|
+
return [];
|
|
18306
|
+
if (!msg.method)
|
|
18307
|
+
return [{ kind: "log", content: line, level: "debug" }];
|
|
18308
|
+
const method = msg.method;
|
|
18309
|
+
const params = msg.params || {};
|
|
18310
|
+
if (method === "codex/event") {
|
|
18311
|
+
return this.parseLegacyEvent(params);
|
|
18312
|
+
}
|
|
18313
|
+
const events = [];
|
|
18314
|
+
switch (method) {
|
|
18315
|
+
case "turn/started":
|
|
18316
|
+
break;
|
|
18317
|
+
case "turn/completed": {
|
|
18318
|
+
const turn = params.turn;
|
|
18319
|
+
const status = turn?.status || params.status || "";
|
|
18320
|
+
if (status === "error" || status === "failed") {
|
|
18321
|
+
const turnErr = turn?.error;
|
|
18322
|
+
events.push({ kind: "error", message: turnErr?.message || "codex turn failed" });
|
|
18323
|
+
}
|
|
18324
|
+
events.push({ kind: "turn_end" });
|
|
18325
|
+
break;
|
|
18326
|
+
}
|
|
18327
|
+
case "error": {
|
|
18328
|
+
const errObj = params.error;
|
|
18329
|
+
const errMsg = errObj?.message || params.message || "";
|
|
18330
|
+
const willRetry = params.willRetry === true;
|
|
18331
|
+
if (errMsg && !willRetry) {
|
|
18332
|
+
events.push({ kind: "error", message: errMsg });
|
|
18333
|
+
}
|
|
18334
|
+
break;
|
|
18335
|
+
}
|
|
18336
|
+
case "thread/status/changed": {
|
|
18337
|
+
const statusObj = params.status;
|
|
18338
|
+
const statusType = typeof statusObj === "object" && statusObj !== null ? statusObj.type || "" : statusObj || "";
|
|
18339
|
+
if (statusType === "idle") {
|
|
18340
|
+
events.push({ kind: "turn_end" });
|
|
18341
|
+
}
|
|
18342
|
+
break;
|
|
18343
|
+
}
|
|
18344
|
+
case "item/started": {
|
|
18345
|
+
const item = params.item;
|
|
18346
|
+
if (!item)
|
|
18347
|
+
break;
|
|
18348
|
+
const itemType = item.type;
|
|
18349
|
+
if (itemType === "commandExecution" || itemType === "fileChange") {
|
|
18350
|
+
events.push({
|
|
18351
|
+
kind: "tool_call",
|
|
18352
|
+
name: itemType === "commandExecution" ? "exec_command" : "patch_apply",
|
|
18353
|
+
callId: item.id,
|
|
18354
|
+
input: item
|
|
18355
|
+
});
|
|
18356
|
+
} else if (itemType === "mcpToolCall") {
|
|
18357
|
+
events.push({
|
|
18358
|
+
kind: "tool_call",
|
|
18359
|
+
name: `mcp_${item.name || "tool"}`,
|
|
18360
|
+
callId: item.id,
|
|
18361
|
+
input: item
|
|
18362
|
+
});
|
|
18363
|
+
} else if (itemType === "webSearch") {
|
|
18364
|
+
events.push({
|
|
18365
|
+
kind: "tool_call",
|
|
18366
|
+
name: "web_search",
|
|
18367
|
+
callId: item.id,
|
|
18368
|
+
input: item
|
|
18369
|
+
});
|
|
18370
|
+
} else if (itemType === "collabAgentToolCall") {
|
|
18371
|
+
events.push({
|
|
18372
|
+
kind: "tool_call",
|
|
18373
|
+
name: "collab_agent",
|
|
18374
|
+
callId: item.id,
|
|
18375
|
+
input: item
|
|
18376
|
+
});
|
|
18377
|
+
} else if (itemType === "contextCompaction") {
|
|
18378
|
+
events.push({ kind: "compaction_started" });
|
|
18379
|
+
}
|
|
18380
|
+
break;
|
|
18381
|
+
}
|
|
18382
|
+
case "item/completed": {
|
|
18383
|
+
const item = params.item;
|
|
18384
|
+
if (!item)
|
|
18385
|
+
break;
|
|
18386
|
+
const itemType = item.type;
|
|
18387
|
+
if (itemType === "commandExecution") {
|
|
18388
|
+
events.push({ kind: "tool_output", callId: item.id, output: item.aggregatedOutput || "" });
|
|
18389
|
+
} else if (itemType === "fileChange") {
|
|
18390
|
+
events.push({ kind: "tool_output", callId: item.id, output: "" });
|
|
18391
|
+
} else if (itemType === "mcpToolCall") {
|
|
18392
|
+
events.push({ kind: "tool_output", callId: item.id, name: `mcp_${item.name || "tool"}`, output: item.output || "" });
|
|
18393
|
+
} else if (itemType === "agentMessage") {
|
|
18394
|
+
const flatText = item.text;
|
|
18395
|
+
if (flatText) {
|
|
18396
|
+
events.push({ kind: "text", text: flatText });
|
|
18397
|
+
} else {
|
|
18398
|
+
const content = item.content;
|
|
18399
|
+
if (Array.isArray(content)) {
|
|
18400
|
+
for (const block of content) {
|
|
18401
|
+
if ((block.type === "output_text" || block.type === "text") && block.text) {
|
|
18402
|
+
events.push({ kind: "text", text: block.text });
|
|
18403
|
+
}
|
|
18404
|
+
}
|
|
18405
|
+
}
|
|
18406
|
+
}
|
|
18407
|
+
} else if (itemType === "reasoning") {
|
|
18408
|
+
events.push({ kind: "thinking", text: item.text || "" });
|
|
18409
|
+
} else if (itemType === "contextCompaction") {
|
|
18410
|
+
events.push({ kind: "compaction_finished" });
|
|
18411
|
+
}
|
|
18412
|
+
break;
|
|
18413
|
+
}
|
|
18414
|
+
case "item/agentMessage/delta": {
|
|
18415
|
+
const delta = params.delta;
|
|
18416
|
+
if (delta)
|
|
18417
|
+
events.push({ kind: "text", text: delta });
|
|
18418
|
+
break;
|
|
18419
|
+
}
|
|
18420
|
+
default:
|
|
18421
|
+
events.push({ kind: "log", content: JSON.stringify(msg), level: "debug" });
|
|
18422
|
+
}
|
|
18423
|
+
return events;
|
|
18424
|
+
}
|
|
18425
|
+
parseLegacyEvent(params) {
|
|
18426
|
+
const eventType = params.type;
|
|
18427
|
+
if (!eventType)
|
|
18428
|
+
return [];
|
|
18429
|
+
const events = [];
|
|
18430
|
+
switch (eventType) {
|
|
18431
|
+
case "agent_message": {
|
|
18432
|
+
const text2 = params.text || params.message || "";
|
|
18433
|
+
if (text2)
|
|
18434
|
+
events.push({ kind: "text", text: text2 });
|
|
18435
|
+
break;
|
|
18436
|
+
}
|
|
18437
|
+
case "exec_command_begin":
|
|
18438
|
+
events.push({ kind: "tool_call", name: "exec_command", callId: params.id, input: params });
|
|
18439
|
+
break;
|
|
18440
|
+
case "exec_command_end":
|
|
18441
|
+
events.push({ kind: "tool_output", callId: params.id, output: params.output || "" });
|
|
18442
|
+
break;
|
|
18443
|
+
case "patch_apply_begin":
|
|
18444
|
+
events.push({ kind: "tool_call", name: "patch_apply", callId: params.id, input: params });
|
|
18445
|
+
break;
|
|
18446
|
+
case "patch_apply_end":
|
|
18447
|
+
events.push({ kind: "tool_output", callId: params.id, output: params.output || "" });
|
|
18448
|
+
break;
|
|
18449
|
+
case "task_complete":
|
|
18450
|
+
events.push({ kind: "turn_end" });
|
|
18451
|
+
break;
|
|
18452
|
+
case "turn_aborted":
|
|
18453
|
+
events.push({ kind: "turn_end" });
|
|
18454
|
+
break;
|
|
18455
|
+
default:
|
|
18456
|
+
break;
|
|
18457
|
+
}
|
|
18458
|
+
return events;
|
|
18459
|
+
}
|
|
18460
|
+
encodeStdinMessage(text2, mode, opts) {
|
|
18461
|
+
const threadId = opts?.threadId;
|
|
18462
|
+
if (!threadId)
|
|
18463
|
+
return null;
|
|
18464
|
+
const id = opts?.requestId ?? ++this._rpcId;
|
|
18465
|
+
const method = mode === "busy" ? "turn/steer" : "turn/start";
|
|
18466
|
+
return JSON.stringify({
|
|
18467
|
+
jsonrpc: "2.0",
|
|
18468
|
+
id,
|
|
18469
|
+
method,
|
|
18470
|
+
params: {
|
|
18471
|
+
threadId,
|
|
18472
|
+
input: [{ type: "text", text: text2 }]
|
|
18473
|
+
}
|
|
18474
|
+
});
|
|
18475
|
+
}
|
|
17450
18476
|
execute(prompt, options) {
|
|
17451
18477
|
const proc = spawn2(this.cliPath, ["app-server", "--listen", "stdio://", "--config", "sandbox_mode=danger-full-access"], {
|
|
17452
18478
|
cwd: options.cwd,
|
|
@@ -17495,6 +18521,9 @@ class CodexBackend {
|
|
|
17495
18521
|
const messageQueue = [];
|
|
17496
18522
|
let messageResolve = null;
|
|
17497
18523
|
let messageDone = false;
|
|
18524
|
+
const parsedEventQueue = [];
|
|
18525
|
+
let parsedEventResolve = null;
|
|
18526
|
+
let parsedEventDone = false;
|
|
17498
18527
|
const pushMessage = (msg) => {
|
|
17499
18528
|
messageQueue.push(msg);
|
|
17500
18529
|
if (messageResolve) {
|
|
@@ -17503,6 +18532,14 @@ class CodexBackend {
|
|
|
17503
18532
|
r();
|
|
17504
18533
|
}
|
|
17505
18534
|
};
|
|
18535
|
+
const pushParsedEvent = (evt) => {
|
|
18536
|
+
parsedEventQueue.push(evt);
|
|
18537
|
+
if (parsedEventResolve) {
|
|
18538
|
+
const r = parsedEventResolve;
|
|
18539
|
+
parsedEventResolve = null;
|
|
18540
|
+
r();
|
|
18541
|
+
}
|
|
18542
|
+
};
|
|
17506
18543
|
const writeStdin = (data) => {
|
|
17507
18544
|
try {
|
|
17508
18545
|
proc.stdin?.write(data + `
|
|
@@ -17535,17 +18572,20 @@ class CodexBackend {
|
|
|
17535
18572
|
if (msg && !turnError)
|
|
17536
18573
|
turnError = msg;
|
|
17537
18574
|
};
|
|
18575
|
+
const steeringKeepAlive = options.steeringEnabled === true;
|
|
17538
18576
|
const triggerTurnDone = (aborted2) => {
|
|
17539
18577
|
if (turnDoneTriggered)
|
|
17540
18578
|
return;
|
|
17541
18579
|
turnDoneTriggered = true;
|
|
17542
18580
|
resultStatus = aborted2 ? "aborted" : "completed";
|
|
17543
|
-
|
|
17544
|
-
|
|
17545
|
-
|
|
17546
|
-
|
|
17547
|
-
|
|
17548
|
-
|
|
18581
|
+
if (!steeringKeepAlive) {
|
|
18582
|
+
try {
|
|
18583
|
+
proc.stdin?.end();
|
|
18584
|
+
} catch {}
|
|
18585
|
+
try {
|
|
18586
|
+
proc.kill("SIGTERM");
|
|
18587
|
+
} catch {}
|
|
18588
|
+
}
|
|
17549
18589
|
};
|
|
17550
18590
|
const handleServerRequest = (msg) => {
|
|
17551
18591
|
const method = msg.method;
|
|
@@ -17766,6 +18806,9 @@ class CodexBackend {
|
|
|
17766
18806
|
rl.on("line", (line) => {
|
|
17767
18807
|
if (!line.trim())
|
|
17768
18808
|
return;
|
|
18809
|
+
const parsed = this.parseLine(line);
|
|
18810
|
+
for (const pe of parsed)
|
|
18811
|
+
pushParsedEvent(pe);
|
|
17769
18812
|
let msg;
|
|
17770
18813
|
try {
|
|
17771
18814
|
msg = JSON.parse(line);
|
|
@@ -17852,11 +18895,17 @@ class CodexBackend {
|
|
|
17852
18895
|
closeAllPending("spawn error");
|
|
17853
18896
|
resolveSessionId(sessionId);
|
|
17854
18897
|
messageDone = true;
|
|
18898
|
+
parsedEventDone = true;
|
|
17855
18899
|
if (messageResolve) {
|
|
17856
18900
|
const r = messageResolve;
|
|
17857
18901
|
messageResolve = null;
|
|
17858
18902
|
r();
|
|
17859
18903
|
}
|
|
18904
|
+
if (parsedEventResolve) {
|
|
18905
|
+
const r = parsedEventResolve;
|
|
18906
|
+
parsedEventResolve = null;
|
|
18907
|
+
r();
|
|
18908
|
+
}
|
|
17860
18909
|
resolve({
|
|
17861
18910
|
status: "failed",
|
|
17862
18911
|
output: "",
|
|
@@ -17886,11 +18935,17 @@ class CodexBackend {
|
|
|
17886
18935
|
}
|
|
17887
18936
|
resolveSessionId(sessionId);
|
|
17888
18937
|
messageDone = true;
|
|
18938
|
+
parsedEventDone = true;
|
|
17889
18939
|
if (messageResolve) {
|
|
17890
18940
|
const r = messageResolve;
|
|
17891
18941
|
messageResolve = null;
|
|
17892
18942
|
r();
|
|
17893
18943
|
}
|
|
18944
|
+
if (parsedEventResolve) {
|
|
18945
|
+
const r = parsedEventResolve;
|
|
18946
|
+
parsedEventResolve = null;
|
|
18947
|
+
r();
|
|
18948
|
+
}
|
|
17894
18949
|
resolve({
|
|
17895
18950
|
status: resultStatus,
|
|
17896
18951
|
output: lastOutput,
|
|
@@ -17917,7 +18972,44 @@ class CodexBackend {
|
|
|
17917
18972
|
};
|
|
17918
18973
|
}
|
|
17919
18974
|
};
|
|
17920
|
-
|
|
18975
|
+
const parsedEvents = {
|
|
18976
|
+
[Symbol.asyncIterator]() {
|
|
18977
|
+
return {
|
|
18978
|
+
async next() {
|
|
18979
|
+
while (parsedEventQueue.length === 0 && !parsedEventDone) {
|
|
18980
|
+
await new Promise((resolve) => {
|
|
18981
|
+
parsedEventResolve = resolve;
|
|
18982
|
+
});
|
|
18983
|
+
}
|
|
18984
|
+
if (parsedEventQueue.length > 0) {
|
|
18985
|
+
return { value: parsedEventQueue.shift(), done: false };
|
|
18986
|
+
}
|
|
18987
|
+
return { value: undefined, done: true };
|
|
18988
|
+
}
|
|
18989
|
+
};
|
|
18990
|
+
}
|
|
18991
|
+
};
|
|
18992
|
+
const send = (text2, mode) => {
|
|
18993
|
+
if (!proc.stdin || proc.stdin.destroyed)
|
|
18994
|
+
return { ok: false, reason: "stdin closed" };
|
|
18995
|
+
const encoded = this.encodeStdinMessage(text2, mode, { threadId: sessionId, requestId: ++requestId });
|
|
18996
|
+
if (!encoded)
|
|
18997
|
+
return { ok: false, reason: "encoding failed (no threadId)" };
|
|
18998
|
+
writeStdin(encoded);
|
|
18999
|
+
return { ok: true };
|
|
19000
|
+
};
|
|
19001
|
+
const descriptor = {
|
|
19002
|
+
lifecycle: this.lifecycle,
|
|
19003
|
+
busyDeliveryMode: this.busyDeliveryMode,
|
|
19004
|
+
supportsStdinNotification: this.supportsStdinNotification
|
|
19005
|
+
};
|
|
19006
|
+
const closeStdin = () => {
|
|
19007
|
+
try {
|
|
19008
|
+
if (proc.stdin && !proc.stdin.destroyed)
|
|
19009
|
+
proc.stdin.end();
|
|
19010
|
+
} catch {}
|
|
19011
|
+
};
|
|
19012
|
+
return { pid: proc.pid, messages, parsedEvents, sessionId: sessionIdPromise, result: resultPromise, send, closeStdin, descriptor };
|
|
17921
19013
|
}
|
|
17922
19014
|
}
|
|
17923
19015
|
|
|
@@ -17927,9 +19019,102 @@ import { createInterface as createInterface3 } from "readline";
|
|
|
17927
19019
|
class OpenCodeBackend {
|
|
17928
19020
|
cliPath;
|
|
17929
19021
|
name = "opencode";
|
|
19022
|
+
lifecycle = { kind: "per_turn", inFlightWake: "coalesce_into_pending" };
|
|
19023
|
+
busyDeliveryMode = "none";
|
|
19024
|
+
supportsStdinNotification = false;
|
|
17930
19025
|
constructor(cliPath) {
|
|
17931
19026
|
this.cliPath = cliPath;
|
|
17932
19027
|
}
|
|
19028
|
+
parseLine(line) {
|
|
19029
|
+
if (!line.trim())
|
|
19030
|
+
return [];
|
|
19031
|
+
let event;
|
|
19032
|
+
try {
|
|
19033
|
+
event = JSON.parse(line);
|
|
19034
|
+
} catch {
|
|
19035
|
+
return [{ kind: "log", content: line, level: "debug" }];
|
|
19036
|
+
}
|
|
19037
|
+
const events = [];
|
|
19038
|
+
const eventType = event.type;
|
|
19039
|
+
const part = event.part;
|
|
19040
|
+
const eventSessionId = event.sessionID || event.session_id;
|
|
19041
|
+
switch (eventType) {
|
|
19042
|
+
case "session": {
|
|
19043
|
+
const sessionId = event.session_id;
|
|
19044
|
+
if (sessionId)
|
|
19045
|
+
events.push({ kind: "session_init", sessionId });
|
|
19046
|
+
break;
|
|
19047
|
+
}
|
|
19048
|
+
case "message": {
|
|
19049
|
+
const role = event.role;
|
|
19050
|
+
const content = event.content;
|
|
19051
|
+
if (role === "assistant" && content) {
|
|
19052
|
+
events.push({ kind: "text", text: content });
|
|
19053
|
+
}
|
|
19054
|
+
break;
|
|
19055
|
+
}
|
|
19056
|
+
case "text": {
|
|
19057
|
+
const text2 = part?.text || event.content || "";
|
|
19058
|
+
if (text2)
|
|
19059
|
+
events.push({ kind: "text", text: text2 });
|
|
19060
|
+
break;
|
|
19061
|
+
}
|
|
19062
|
+
case "thinking": {
|
|
19063
|
+
const content = part?.thinking || event.content || "";
|
|
19064
|
+
events.push({ kind: "thinking", text: content });
|
|
19065
|
+
break;
|
|
19066
|
+
}
|
|
19067
|
+
case "tool_call":
|
|
19068
|
+
events.push({
|
|
19069
|
+
kind: "tool_call",
|
|
19070
|
+
name: event.name || part?.name || "",
|
|
19071
|
+
callId: event.call_id || part?.id || "",
|
|
19072
|
+
input: event.input || part?.input
|
|
19073
|
+
});
|
|
19074
|
+
break;
|
|
19075
|
+
case "tool_result":
|
|
19076
|
+
events.push({
|
|
19077
|
+
kind: "tool_output",
|
|
19078
|
+
callId: event.call_id || part?.id || "",
|
|
19079
|
+
output: event.output || part?.output || ""
|
|
19080
|
+
});
|
|
19081
|
+
break;
|
|
19082
|
+
case "error": {
|
|
19083
|
+
const content = event.message || event.content || part?.error || "";
|
|
19084
|
+
events.push({ kind: "error", message: content });
|
|
19085
|
+
events.push({ kind: "turn_end" });
|
|
19086
|
+
break;
|
|
19087
|
+
}
|
|
19088
|
+
case "step_start":
|
|
19089
|
+
break;
|
|
19090
|
+
case "step_finish": {
|
|
19091
|
+
const reason = part?.reason;
|
|
19092
|
+
if (reason === "stop" || reason === "end_turn") {
|
|
19093
|
+
events.push({ kind: "turn_end" });
|
|
19094
|
+
}
|
|
19095
|
+
break;
|
|
19096
|
+
}
|
|
19097
|
+
case "done":
|
|
19098
|
+
case "complete": {
|
|
19099
|
+
const status = event.status;
|
|
19100
|
+
if (status === "error" || status === "failed") {
|
|
19101
|
+
const output = event.output;
|
|
19102
|
+
events.push({ kind: "error", message: output || "task failed" });
|
|
19103
|
+
}
|
|
19104
|
+
events.push({ kind: "turn_end" });
|
|
19105
|
+
break;
|
|
19106
|
+
}
|
|
19107
|
+
default:
|
|
19108
|
+
events.push({ kind: "log", content: line, level: "debug" });
|
|
19109
|
+
}
|
|
19110
|
+
if (eventSessionId && events.length > 0 && events[0].kind !== "session_init") {
|
|
19111
|
+
events.unshift({ kind: "session_init", sessionId: eventSessionId });
|
|
19112
|
+
}
|
|
19113
|
+
return events;
|
|
19114
|
+
}
|
|
19115
|
+
encodeStdinMessage() {
|
|
19116
|
+
return null;
|
|
19117
|
+
}
|
|
17933
19118
|
execute(prompt, options) {
|
|
17934
19119
|
const args = ["run", "--format", "json", "--dir", options.cwd];
|
|
17935
19120
|
if (options.model) {
|
|
@@ -17987,6 +19172,9 @@ class OpenCodeBackend {
|
|
|
17987
19172
|
const messageQueue = [];
|
|
17988
19173
|
let messageResolve = null;
|
|
17989
19174
|
let messageDone = false;
|
|
19175
|
+
const parsedEventQueue = [];
|
|
19176
|
+
let parsedEventResolve = null;
|
|
19177
|
+
let parsedEventDone = false;
|
|
17990
19178
|
const pushMessage = (msg) => {
|
|
17991
19179
|
messageQueue.push(msg);
|
|
17992
19180
|
if (messageResolve) {
|
|
@@ -17995,6 +19183,14 @@ class OpenCodeBackend {
|
|
|
17995
19183
|
r();
|
|
17996
19184
|
}
|
|
17997
19185
|
};
|
|
19186
|
+
const pushParsedEvent = (evt) => {
|
|
19187
|
+
parsedEventQueue.push(evt);
|
|
19188
|
+
if (parsedEventResolve) {
|
|
19189
|
+
const r = parsedEventResolve;
|
|
19190
|
+
parsedEventResolve = null;
|
|
19191
|
+
r();
|
|
19192
|
+
}
|
|
19193
|
+
};
|
|
17998
19194
|
const resultPromise = new Promise((resolve) => {
|
|
17999
19195
|
const stderrChunks = [];
|
|
18000
19196
|
proc.stderr?.on("data", (chunk) => {
|
|
@@ -18004,6 +19200,9 @@ class OpenCodeBackend {
|
|
|
18004
19200
|
rl.on("line", (line) => {
|
|
18005
19201
|
if (!line.trim())
|
|
18006
19202
|
return;
|
|
19203
|
+
const parsed = this.parseLine(line);
|
|
19204
|
+
for (const pe of parsed)
|
|
19205
|
+
pushParsedEvent(pe);
|
|
18007
19206
|
let event;
|
|
18008
19207
|
try {
|
|
18009
19208
|
event = JSON.parse(line);
|
|
@@ -18115,11 +19314,17 @@ class OpenCodeBackend {
|
|
|
18115
19314
|
lastError = `spawn error: ${err.message}`;
|
|
18116
19315
|
resolveSessionId(lastSessionId);
|
|
18117
19316
|
messageDone = true;
|
|
19317
|
+
parsedEventDone = true;
|
|
18118
19318
|
if (messageResolve) {
|
|
18119
19319
|
const r = messageResolve;
|
|
18120
19320
|
messageResolve = null;
|
|
18121
19321
|
r();
|
|
18122
19322
|
}
|
|
19323
|
+
if (parsedEventResolve) {
|
|
19324
|
+
const r = parsedEventResolve;
|
|
19325
|
+
parsedEventResolve = null;
|
|
19326
|
+
r();
|
|
19327
|
+
}
|
|
18123
19328
|
resolve({
|
|
18124
19329
|
status: "failed",
|
|
18125
19330
|
output: "",
|
|
@@ -18144,11 +19349,17 @@ class OpenCodeBackend {
|
|
|
18144
19349
|
}
|
|
18145
19350
|
resolveSessionId(lastSessionId);
|
|
18146
19351
|
messageDone = true;
|
|
19352
|
+
parsedEventDone = true;
|
|
18147
19353
|
if (messageResolve) {
|
|
18148
19354
|
const r = messageResolve;
|
|
18149
19355
|
messageResolve = null;
|
|
18150
19356
|
r();
|
|
18151
19357
|
}
|
|
19358
|
+
if (parsedEventResolve) {
|
|
19359
|
+
const r = parsedEventResolve;
|
|
19360
|
+
parsedEventResolve = null;
|
|
19361
|
+
r();
|
|
19362
|
+
}
|
|
18152
19363
|
resolve({
|
|
18153
19364
|
status: resultStatus,
|
|
18154
19365
|
output: lastOutput,
|
|
@@ -18175,7 +19386,32 @@ class OpenCodeBackend {
|
|
|
18175
19386
|
};
|
|
18176
19387
|
}
|
|
18177
19388
|
};
|
|
18178
|
-
|
|
19389
|
+
const parsedEvents = {
|
|
19390
|
+
[Symbol.asyncIterator]() {
|
|
19391
|
+
return {
|
|
19392
|
+
async next() {
|
|
19393
|
+
while (parsedEventQueue.length === 0 && !parsedEventDone) {
|
|
19394
|
+
await new Promise((resolve) => {
|
|
19395
|
+
parsedEventResolve = resolve;
|
|
19396
|
+
});
|
|
19397
|
+
}
|
|
19398
|
+
if (parsedEventQueue.length > 0) {
|
|
19399
|
+
return { value: parsedEventQueue.shift(), done: false };
|
|
19400
|
+
}
|
|
19401
|
+
return { value: undefined, done: true };
|
|
19402
|
+
}
|
|
19403
|
+
};
|
|
19404
|
+
}
|
|
19405
|
+
};
|
|
19406
|
+
const send = () => {
|
|
19407
|
+
return { ok: false, reason: "unsupported" };
|
|
19408
|
+
};
|
|
19409
|
+
const descriptor = {
|
|
19410
|
+
lifecycle: this.lifecycle,
|
|
19411
|
+
busyDeliveryMode: this.busyDeliveryMode,
|
|
19412
|
+
supportsStdinNotification: this.supportsStdinNotification
|
|
19413
|
+
};
|
|
19414
|
+
return { pid: proc.pid, messages, parsedEvents, sessionId: sessionIdPromise, result: resultPromise, send, descriptor };
|
|
18179
19415
|
}
|
|
18180
19416
|
}
|
|
18181
19417
|
|
|
@@ -18658,7 +19894,7 @@ function releaseLock(lockPath) {
|
|
|
18658
19894
|
}
|
|
18659
19895
|
|
|
18660
19896
|
// daemon/execenv/timeline.ts
|
|
18661
|
-
var
|
|
19897
|
+
var log5 = createLogger2({ module: "timeline" });
|
|
18662
19898
|
function readJsonl(filePath) {
|
|
18663
19899
|
let content;
|
|
18664
19900
|
try {
|
|
@@ -18727,7 +19963,7 @@ async function initEntryAsync(timelineDir, entry) {
|
|
|
18727
19963
|
acquired = acquireLock(lockPath);
|
|
18728
19964
|
}
|
|
18729
19965
|
if (!acquired) {
|
|
18730
|
-
|
|
19966
|
+
log5.debug(`Timeline initEntry: could not acquire lock for ${filename}`);
|
|
18731
19967
|
return;
|
|
18732
19968
|
}
|
|
18733
19969
|
try {
|
|
@@ -18737,7 +19973,7 @@ async function initEntryAsync(timelineDir, entry) {
|
|
|
18737
19973
|
releaseLock(lockPath);
|
|
18738
19974
|
}
|
|
18739
19975
|
} catch (err) {
|
|
18740
|
-
|
|
19976
|
+
log5.debug("Timeline initEntry failed", err);
|
|
18741
19977
|
}
|
|
18742
19978
|
}
|
|
18743
19979
|
function updateEntry(timelineDir, taskId, updater) {
|
|
@@ -18747,7 +19983,7 @@ function updateEntry(timelineDir, taskId, updater) {
|
|
|
18747
19983
|
try {
|
|
18748
19984
|
const acquired = acquireLock(lockPath);
|
|
18749
19985
|
if (!acquired) {
|
|
18750
|
-
|
|
19986
|
+
log5.debug(`Timeline updateEntry: lock held for ${filename}, skipping`);
|
|
18751
19987
|
continue;
|
|
18752
19988
|
}
|
|
18753
19989
|
try {
|
|
@@ -18780,10 +20016,10 @@ function updateEntry(timelineDir, taskId, updater) {
|
|
|
18780
20016
|
releaseLock(lockPath);
|
|
18781
20017
|
}
|
|
18782
20018
|
} catch (err) {
|
|
18783
|
-
|
|
20019
|
+
log5.debug(`Timeline updateEntry failed for ${filename}`, err);
|
|
18784
20020
|
}
|
|
18785
20021
|
}
|
|
18786
|
-
|
|
20022
|
+
log5.debug(`Timeline updateEntry: task_id ${taskId} not found in last 7 days`);
|
|
18787
20023
|
}
|
|
18788
20024
|
function createTimelineEntry(taskId, prompt, type, sessionId, pid, provider, contextKey, detailedLog) {
|
|
18789
20025
|
return {
|
|
@@ -18818,7 +20054,7 @@ function findResumableSessionByContextKey(timelineDir, contextKey, provider) {
|
|
|
18818
20054
|
// daemon/execenv/steering.ts
|
|
18819
20055
|
import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync3, readFileSync as readFileSync3, unlinkSync as unlinkSync2, readdirSync, statSync as statSync2 } from "fs";
|
|
18820
20056
|
import { join as join5 } from "path";
|
|
18821
|
-
var
|
|
20057
|
+
var log6 = createLogger2({ module: "steering" });
|
|
18822
20058
|
var INTENT_DIR_NAME = ".kill_intents";
|
|
18823
20059
|
var INTENT_STALE_MS = 10 * 60 * 1000;
|
|
18824
20060
|
function intentFilePath(baseDir, taskId) {
|
|
@@ -18840,6 +20076,636 @@ function clearKillIntent(baseDir, taskId) {
|
|
|
18840
20076
|
} catch {}
|
|
18841
20077
|
}
|
|
18842
20078
|
|
|
20079
|
+
// daemon/steering/mailbox.ts
|
|
20080
|
+
import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync4, readFileSync as readFileSync4, renameSync as renameSync2, readdirSync as readdirSync2, unlinkSync as unlinkSync3, rmSync, existsSync as existsSync2, watch } from "fs";
|
|
20081
|
+
import { join as join6 } from "path";
|
|
20082
|
+
var log7 = createLogger2({ module: "mailbox" });
|
|
20083
|
+
function inboxDir(baseDir, contextKey) {
|
|
20084
|
+
const safeKey = contextKey.replace(/[^a-zA-Z0-9_:-]/g, "_");
|
|
20085
|
+
return join6(baseDir, ".steering", safeKey, "inbox");
|
|
20086
|
+
}
|
|
20087
|
+
function ackDir(baseDir, contextKey) {
|
|
20088
|
+
const safeKey = contextKey.replace(/[^a-zA-Z0-9_:-]/g, "_");
|
|
20089
|
+
return join6(baseDir, ".steering", safeKey, "ack");
|
|
20090
|
+
}
|
|
20091
|
+
function steeringDir(baseDir, contextKey) {
|
|
20092
|
+
const safeKey = contextKey.replace(/[^a-zA-Z0-9_:-]/g, "_");
|
|
20093
|
+
return join6(baseDir, ".steering", safeKey);
|
|
20094
|
+
}
|
|
20095
|
+
function readSteerMessage(filePath) {
|
|
20096
|
+
try {
|
|
20097
|
+
const content = readFileSync4(filePath, "utf-8");
|
|
20098
|
+
return JSON.parse(content);
|
|
20099
|
+
} catch {
|
|
20100
|
+
return null;
|
|
20101
|
+
}
|
|
20102
|
+
}
|
|
20103
|
+
function writeAck(baseDir, contextKey, seq) {
|
|
20104
|
+
const ack = ackDir(baseDir, contextKey);
|
|
20105
|
+
mkdirSync4(ack, { recursive: true });
|
|
20106
|
+
writeFileSync4(join6(ack, `${seq}.ack`), "");
|
|
20107
|
+
}
|
|
20108
|
+
function writeNack(baseDir, contextKey, seq, reason) {
|
|
20109
|
+
const ack = ackDir(baseDir, contextKey);
|
|
20110
|
+
mkdirSync4(ack, { recursive: true });
|
|
20111
|
+
writeFileSync4(join6(ack, `${seq}.nack`), JSON.stringify({ reason }));
|
|
20112
|
+
}
|
|
20113
|
+
function cleanupInboxFile(baseDir, contextKey, seq) {
|
|
20114
|
+
try {
|
|
20115
|
+
unlinkSync3(join6(inboxDir(baseDir, contextKey), `${seq}.json`));
|
|
20116
|
+
} catch {}
|
|
20117
|
+
}
|
|
20118
|
+
function cleanupSteeringDir(baseDir, contextKey) {
|
|
20119
|
+
const dir = steeringDir(baseDir, contextKey);
|
|
20120
|
+
try {
|
|
20121
|
+
rmSync(dir, { recursive: true, force: true });
|
|
20122
|
+
} catch {}
|
|
20123
|
+
}
|
|
20124
|
+
function watchInbox(baseDir, contextKey, onMessage) {
|
|
20125
|
+
const inbox = inboxDir(baseDir, contextKey);
|
|
20126
|
+
mkdirSync4(inbox, { recursive: true });
|
|
20127
|
+
const seen = new Set;
|
|
20128
|
+
let stopped = false;
|
|
20129
|
+
const scan = () => {
|
|
20130
|
+
if (stopped)
|
|
20131
|
+
return;
|
|
20132
|
+
try {
|
|
20133
|
+
const files = readdirSync2(inbox).filter((f) => f.endsWith(".json") && !f.endsWith(".tmp")).sort();
|
|
20134
|
+
for (const file2 of files) {
|
|
20135
|
+
if (seen.has(file2))
|
|
20136
|
+
continue;
|
|
20137
|
+
const seq = file2.replace(/\.json$/, "");
|
|
20138
|
+
const srcPath = join6(inbox, file2);
|
|
20139
|
+
const claimPath = join6(inbox, `${seq}.processing`);
|
|
20140
|
+
try {
|
|
20141
|
+
renameSync2(srcPath, claimPath);
|
|
20142
|
+
} catch {
|
|
20143
|
+
continue;
|
|
20144
|
+
}
|
|
20145
|
+
seen.add(file2);
|
|
20146
|
+
const msg = readSteerMessage(claimPath);
|
|
20147
|
+
try {
|
|
20148
|
+
unlinkSync3(claimPath);
|
|
20149
|
+
} catch {}
|
|
20150
|
+
if (msg) {
|
|
20151
|
+
onMessage(seq, msg);
|
|
20152
|
+
}
|
|
20153
|
+
}
|
|
20154
|
+
} catch {}
|
|
20155
|
+
};
|
|
20156
|
+
scan();
|
|
20157
|
+
let watcher = null;
|
|
20158
|
+
try {
|
|
20159
|
+
watcher = watch(inbox, () => {
|
|
20160
|
+
if (!stopped)
|
|
20161
|
+
scan();
|
|
20162
|
+
});
|
|
20163
|
+
} catch {
|
|
20164
|
+
log7.debug("fs.watch failed, relying on polling only");
|
|
20165
|
+
}
|
|
20166
|
+
const pollTimer = setInterval(scan, 200);
|
|
20167
|
+
return {
|
|
20168
|
+
stop() {
|
|
20169
|
+
stopped = true;
|
|
20170
|
+
clearInterval(pollTimer);
|
|
20171
|
+
watcher?.close();
|
|
20172
|
+
}
|
|
20173
|
+
};
|
|
20174
|
+
}
|
|
20175
|
+
|
|
20176
|
+
// daemon/steering/turnState.ts
|
|
20177
|
+
class RuntimeTurnState {
|
|
20178
|
+
currentTurnId = null;
|
|
20179
|
+
steeringGateActive = false;
|
|
20180
|
+
get isInTurn() {
|
|
20181
|
+
return this.currentTurnId !== null;
|
|
20182
|
+
}
|
|
20183
|
+
get turnId() {
|
|
20184
|
+
return this.currentTurnId;
|
|
20185
|
+
}
|
|
20186
|
+
get canSteerBusy() {
|
|
20187
|
+
return Boolean(this.currentTurnId && !this.steeringGateActive);
|
|
20188
|
+
}
|
|
20189
|
+
markTurnStarted(turnId) {
|
|
20190
|
+
if (turnId !== undefined && turnId !== null) {
|
|
20191
|
+
this.currentTurnId = turnId;
|
|
20192
|
+
}
|
|
20193
|
+
this.steeringGateActive = false;
|
|
20194
|
+
}
|
|
20195
|
+
adoptTurnId(turnId) {
|
|
20196
|
+
this.currentTurnId = turnId;
|
|
20197
|
+
}
|
|
20198
|
+
markToolBoundary() {
|
|
20199
|
+
this.steeringGateActive = true;
|
|
20200
|
+
}
|
|
20201
|
+
markProgress() {
|
|
20202
|
+
this.steeringGateActive = false;
|
|
20203
|
+
}
|
|
20204
|
+
markTurnCompleted() {
|
|
20205
|
+
this.currentTurnId = null;
|
|
20206
|
+
this.steeringGateActive = false;
|
|
20207
|
+
}
|
|
20208
|
+
reset() {
|
|
20209
|
+
this.currentTurnId = null;
|
|
20210
|
+
this.steeringGateActive = false;
|
|
20211
|
+
}
|
|
20212
|
+
}
|
|
20213
|
+
|
|
20214
|
+
// daemon/steering/apmStateMachine.ts
|
|
20215
|
+
var MAX_APM_GATED_STEERING_EVENTS = 12;
|
|
20216
|
+
function createInitialApmState() {
|
|
20217
|
+
return {
|
|
20218
|
+
isIdle: false,
|
|
20219
|
+
expectedTerminationReason: null,
|
|
20220
|
+
phase: "idle",
|
|
20221
|
+
outstandingToolUses: 0,
|
|
20222
|
+
compacting: false,
|
|
20223
|
+
toolBoundaryFlushDisabled: false,
|
|
20224
|
+
lastFlushReason: null,
|
|
20225
|
+
recentEvents: [],
|
|
20226
|
+
pendingMessages: []
|
|
20227
|
+
};
|
|
20228
|
+
}
|
|
20229
|
+
function reduceApmGatedToolUse(state, input) {
|
|
20230
|
+
if (input.kind === "tool_call") {
|
|
20231
|
+
return {
|
|
20232
|
+
nextState: {
|
|
20233
|
+
...state,
|
|
20234
|
+
isIdle: false,
|
|
20235
|
+
phase: "tool_wait",
|
|
20236
|
+
outstandingToolUses: state.outstandingToolUses + 1
|
|
20237
|
+
},
|
|
20238
|
+
hadOutstandingToolUse: state.outstandingToolUses > 0,
|
|
20239
|
+
shouldFlushToolBatch: false
|
|
20240
|
+
};
|
|
20241
|
+
}
|
|
20242
|
+
const hadOutstandingToolUse = state.outstandingToolUses > 0;
|
|
20243
|
+
const outstandingToolUses = Math.max(0, state.outstandingToolUses - 1);
|
|
20244
|
+
return {
|
|
20245
|
+
nextState: {
|
|
20246
|
+
...state,
|
|
20247
|
+
isIdle: false,
|
|
20248
|
+
phase: "tool_boundary",
|
|
20249
|
+
outstandingToolUses
|
|
20250
|
+
},
|
|
20251
|
+
hadOutstandingToolUse,
|
|
20252
|
+
shouldFlushToolBatch: hadOutstandingToolUse && outstandingToolUses === 0
|
|
20253
|
+
};
|
|
20254
|
+
}
|
|
20255
|
+
function reduceApmGatedCompaction(state, input) {
|
|
20256
|
+
if (input.kind === "compaction_started") {
|
|
20257
|
+
return { nextState: { ...state, isIdle: false, phase: "compacting", compacting: true } };
|
|
20258
|
+
}
|
|
20259
|
+
if (input.kind === "compaction_interrupted") {
|
|
20260
|
+
return { nextState: { ...state, isIdle: false, compacting: false } };
|
|
20261
|
+
}
|
|
20262
|
+
return {
|
|
20263
|
+
nextState: { ...state, isIdle: false, phase: "assistant_continuation", compacting: false }
|
|
20264
|
+
};
|
|
20265
|
+
}
|
|
20266
|
+
function reduceApmGatedFlushReadiness(state, input) {
|
|
20267
|
+
if (!input.isGated)
|
|
20268
|
+
return { shouldNotify: false, blockedReason: "non_gated", effects: [] };
|
|
20269
|
+
if (!input.hasSession)
|
|
20270
|
+
return { shouldNotify: false, blockedReason: "missing_session", effects: [] };
|
|
20271
|
+
if (input.inboxLength === 0)
|
|
20272
|
+
return { shouldNotify: false, blockedReason: "empty_inbox", effects: [] };
|
|
20273
|
+
if (state.toolBoundaryFlushDisabled) {
|
|
20274
|
+
return { shouldNotify: false, blockedReason: "tool_boundary_flush_disabled", effects: [] };
|
|
20275
|
+
}
|
|
20276
|
+
if (state.compacting)
|
|
20277
|
+
return { shouldNotify: false, blockedReason: "compacting", effects: [] };
|
|
20278
|
+
if (state.outstandingToolUses > 0) {
|
|
20279
|
+
return { shouldNotify: false, blockedReason: "outstanding_tool_uses", effects: [] };
|
|
20280
|
+
}
|
|
20281
|
+
return {
|
|
20282
|
+
shouldNotify: true,
|
|
20283
|
+
blockedReason: null,
|
|
20284
|
+
effects: [{ kind: "notify_stdin", reason: input.reason, stdinMode: "busy", clauseId: "SMR-002" }]
|
|
20285
|
+
};
|
|
20286
|
+
}
|
|
20287
|
+
function reduceApmGatedTurnEnd(state, input = {}) {
|
|
20288
|
+
const shouldDeliverQueuedMessages = Boolean(input.inboxLength && input.inboxLength > 0 && input.supportsStdinNotification && input.hasSession);
|
|
20289
|
+
return {
|
|
20290
|
+
nextState: {
|
|
20291
|
+
...state,
|
|
20292
|
+
isIdle: !shouldDeliverQueuedMessages,
|
|
20293
|
+
phase: "idle",
|
|
20294
|
+
outstandingToolUses: 0,
|
|
20295
|
+
compacting: false,
|
|
20296
|
+
pendingMessages: shouldDeliverQueuedMessages ? state.pendingMessages : []
|
|
20297
|
+
},
|
|
20298
|
+
effects: shouldDeliverQueuedMessages ? [{ kind: "deliver_stdin", reason: "turn_end", stdinMode: "idle", clauseId: "SMR-002" }] : []
|
|
20299
|
+
};
|
|
20300
|
+
}
|
|
20301
|
+
function reduceApmGatedError(state, input = {}) {
|
|
20302
|
+
const shouldDisableToolBoundaryFlush = input.disableToolBoundaryFlush === true;
|
|
20303
|
+
return {
|
|
20304
|
+
nextState: {
|
|
20305
|
+
...state,
|
|
20306
|
+
phase: "error",
|
|
20307
|
+
compacting: false,
|
|
20308
|
+
toolBoundaryFlushDisabled: state.toolBoundaryFlushDisabled || shouldDisableToolBoundaryFlush
|
|
20309
|
+
},
|
|
20310
|
+
shouldDisableToolBoundaryFlush
|
|
20311
|
+
};
|
|
20312
|
+
}
|
|
20313
|
+
function reduceApmGatedRecentEvent(state, input) {
|
|
20314
|
+
const summary = `${input.event}:${state.phase}:tools=${state.outstandingToolUses}:compact=${state.compacting}`;
|
|
20315
|
+
return {
|
|
20316
|
+
nextState: {
|
|
20317
|
+
...state,
|
|
20318
|
+
recentEvents: [...state.recentEvents, summary].slice(-MAX_APM_GATED_STEERING_EVENTS)
|
|
20319
|
+
}
|
|
20320
|
+
};
|
|
20321
|
+
}
|
|
20322
|
+
function reduceApmGatedEnqueue(state, message2) {
|
|
20323
|
+
return {
|
|
20324
|
+
nextState: {
|
|
20325
|
+
...state,
|
|
20326
|
+
pendingMessages: [...state.pendingMessages, message2]
|
|
20327
|
+
}
|
|
20328
|
+
};
|
|
20329
|
+
}
|
|
20330
|
+
function reduceApmStalledRecoveryTermination(state, input) {
|
|
20331
|
+
if (input.inboxLength === 0) {
|
|
20332
|
+
return { nextState: state, shouldTerminate: false, alreadyRecovering: false, blockedReason: "empty_inbox" };
|
|
20333
|
+
}
|
|
20334
|
+
if (state.expectedTerminationReason === "stalled_recovery") {
|
|
20335
|
+
return { nextState: state, shouldTerminate: false, alreadyRecovering: true, blockedReason: null };
|
|
20336
|
+
}
|
|
20337
|
+
const supportsStdinNotification = input.busyDeliveryMode !== "none";
|
|
20338
|
+
const directStdinRuntime = supportsStdinNotification && input.busyDeliveryMode === "direct";
|
|
20339
|
+
const canRestartDirectStdinProcess = directStdinRuntime && input.hasSession && (state.outstandingToolUses === 0 || input.hasDirectStdinRecoveryEvidence);
|
|
20340
|
+
const canRestartStalledProcess = !supportsStdinNotification || canRestartDirectStdinProcess;
|
|
20341
|
+
if (!canRestartStalledProcess) {
|
|
20342
|
+
return {
|
|
20343
|
+
nextState: state,
|
|
20344
|
+
shouldTerminate: false,
|
|
20345
|
+
alreadyRecovering: false,
|
|
20346
|
+
blockedReason: "runtime_not_restartable"
|
|
20347
|
+
};
|
|
20348
|
+
}
|
|
20349
|
+
if (input.staleForMs < input.staleThresholdMs && !input.runtimeProgressIsStale) {
|
|
20350
|
+
return {
|
|
20351
|
+
nextState: state,
|
|
20352
|
+
shouldTerminate: false,
|
|
20353
|
+
alreadyRecovering: false,
|
|
20354
|
+
blockedReason: "runtime_progress_recent"
|
|
20355
|
+
};
|
|
20356
|
+
}
|
|
20357
|
+
return {
|
|
20358
|
+
nextState: { ...state, expectedTerminationReason: "stalled_recovery" },
|
|
20359
|
+
shouldTerminate: true,
|
|
20360
|
+
alreadyRecovering: false,
|
|
20361
|
+
blockedReason: null
|
|
20362
|
+
};
|
|
20363
|
+
}
|
|
20364
|
+
function reduceApmStartupTimeoutTermination(state, input) {
|
|
20365
|
+
if (input.hasRuntimeProgressEvent) {
|
|
20366
|
+
return { nextState: state, shouldTerminate: false, blockedReason: "runtime_progress_started" };
|
|
20367
|
+
}
|
|
20368
|
+
return {
|
|
20369
|
+
nextState: { ...state, isIdle: false, expectedTerminationReason: "startup_timeout" },
|
|
20370
|
+
shouldTerminate: true,
|
|
20371
|
+
blockedReason: null
|
|
20372
|
+
};
|
|
20373
|
+
}
|
|
20374
|
+
|
|
20375
|
+
// daemon/steering/notificationState.ts
|
|
20376
|
+
function inboxNoticeMessageIdentity(message2) {
|
|
20377
|
+
const seq = typeof message2.seq === "number" && Number.isFinite(message2.seq) && message2.seq > 0 ? Math.floor(message2.seq) : null;
|
|
20378
|
+
if (seq !== null)
|
|
20379
|
+
return `s:${seq}`;
|
|
20380
|
+
const id = typeof message2.message_id === "string" && message2.message_id.length > 0 ? message2.message_id : typeof message2.id === "string" && message2.id.length > 0 ? message2.id : "";
|
|
20381
|
+
return id.length > 0 ? `m:${id}` : "";
|
|
20382
|
+
}
|
|
20383
|
+
class RuntimeNotificationState {
|
|
20384
|
+
pendingCountValue = 0;
|
|
20385
|
+
timerValue = null;
|
|
20386
|
+
lastNoticeFingerprint = null;
|
|
20387
|
+
lastNoticeSessionId = null;
|
|
20388
|
+
lastEncodeFailedFingerprint = null;
|
|
20389
|
+
lastEncodeFailedSessionId = null;
|
|
20390
|
+
contributedIdentities = new Set;
|
|
20391
|
+
contributionSessionId = null;
|
|
20392
|
+
get pendingCount() {
|
|
20393
|
+
return this.pendingCountValue;
|
|
20394
|
+
}
|
|
20395
|
+
isDuplicateNotice(fingerprint, sessionId) {
|
|
20396
|
+
if (fingerprint.length === 0)
|
|
20397
|
+
return false;
|
|
20398
|
+
return this.lastNoticeFingerprint === fingerprint && this.lastNoticeSessionId === sessionId;
|
|
20399
|
+
}
|
|
20400
|
+
recordNoticeWritten(fingerprint, sessionId, messages = []) {
|
|
20401
|
+
this.lastNoticeFingerprint = fingerprint;
|
|
20402
|
+
this.lastNoticeSessionId = sessionId;
|
|
20403
|
+
this.lastEncodeFailedFingerprint = null;
|
|
20404
|
+
this.lastEncodeFailedSessionId = null;
|
|
20405
|
+
this.ensureContributionSession(sessionId);
|
|
20406
|
+
for (const message2 of messages) {
|
|
20407
|
+
const identity = inboxNoticeMessageIdentity(message2);
|
|
20408
|
+
if (identity.length > 0)
|
|
20409
|
+
this.contributedIdentities.add(identity);
|
|
20410
|
+
}
|
|
20411
|
+
}
|
|
20412
|
+
recordNoticeEncodeFailed(fingerprint, sessionId) {
|
|
20413
|
+
if (fingerprint.length === 0)
|
|
20414
|
+
return;
|
|
20415
|
+
this.lastEncodeFailedFingerprint = fingerprint;
|
|
20416
|
+
this.lastEncodeFailedSessionId = sessionId;
|
|
20417
|
+
}
|
|
20418
|
+
isDuplicateEncodeFailedNotice(fingerprint, sessionId) {
|
|
20419
|
+
if (fingerprint.length === 0)
|
|
20420
|
+
return false;
|
|
20421
|
+
return this.lastEncodeFailedFingerprint === fingerprint && this.lastEncodeFailedSessionId === sessionId;
|
|
20422
|
+
}
|
|
20423
|
+
filterUncontributedMessages(messages, sessionId) {
|
|
20424
|
+
if (this.contributionSessionId !== sessionId)
|
|
20425
|
+
return messages;
|
|
20426
|
+
return messages.filter((m) => {
|
|
20427
|
+
const identity = inboxNoticeMessageIdentity(m);
|
|
20428
|
+
return identity.length === 0 || !this.contributedIdentities.has(identity);
|
|
20429
|
+
});
|
|
20430
|
+
}
|
|
20431
|
+
add(count = 1) {
|
|
20432
|
+
this.pendingCountValue += count;
|
|
20433
|
+
}
|
|
20434
|
+
schedule(callback, delayMs) {
|
|
20435
|
+
if (this.timerValue)
|
|
20436
|
+
return false;
|
|
20437
|
+
this.timerValue = setTimeout(() => {
|
|
20438
|
+
this.timerValue = null;
|
|
20439
|
+
callback();
|
|
20440
|
+
}, delayMs);
|
|
20441
|
+
this.timerValue.unref?.();
|
|
20442
|
+
return true;
|
|
20443
|
+
}
|
|
20444
|
+
takePendingAndClearTimer() {
|
|
20445
|
+
const count = this.pendingCountValue;
|
|
20446
|
+
this.pendingCountValue = 0;
|
|
20447
|
+
if (this.timerValue) {
|
|
20448
|
+
clearTimeout(this.timerValue);
|
|
20449
|
+
this.timerValue = null;
|
|
20450
|
+
}
|
|
20451
|
+
return count;
|
|
20452
|
+
}
|
|
20453
|
+
ensureContributionSession(sessionId) {
|
|
20454
|
+
if (this.contributionSessionId !== sessionId) {
|
|
20455
|
+
this.contributionSessionId = sessionId;
|
|
20456
|
+
this.contributedIdentities = new Set;
|
|
20457
|
+
}
|
|
20458
|
+
}
|
|
20459
|
+
}
|
|
20460
|
+
|
|
20461
|
+
// daemon/steering/progressState.ts
|
|
20462
|
+
class RuntimeProgressState {
|
|
20463
|
+
lastEventAt;
|
|
20464
|
+
lastEventKind = null;
|
|
20465
|
+
_staleSince = null;
|
|
20466
|
+
_isStale = false;
|
|
20467
|
+
constructor(now = Date.now()) {
|
|
20468
|
+
this.lastEventAt = now;
|
|
20469
|
+
}
|
|
20470
|
+
get isStale() {
|
|
20471
|
+
return this._isStale;
|
|
20472
|
+
}
|
|
20473
|
+
get staleSince() {
|
|
20474
|
+
return this._staleSince;
|
|
20475
|
+
}
|
|
20476
|
+
get lastActivity() {
|
|
20477
|
+
return this.lastEventAt;
|
|
20478
|
+
}
|
|
20479
|
+
ageMs(nowMs = Date.now()) {
|
|
20480
|
+
return nowMs - this.lastEventAt;
|
|
20481
|
+
}
|
|
20482
|
+
recordRealEvent(kind, now = Date.now()) {
|
|
20483
|
+
this.lastEventAt = now;
|
|
20484
|
+
this.lastEventKind = kind;
|
|
20485
|
+
this._isStale = false;
|
|
20486
|
+
this._staleSince = null;
|
|
20487
|
+
}
|
|
20488
|
+
recordInternalProgress(kind, now = Date.now()) {
|
|
20489
|
+
this.lastEventAt = now;
|
|
20490
|
+
this.lastEventKind = kind;
|
|
20491
|
+
}
|
|
20492
|
+
markStale(now = Date.now()) {
|
|
20493
|
+
if (this._isStale)
|
|
20494
|
+
return;
|
|
20495
|
+
this._isStale = true;
|
|
20496
|
+
this._staleSince = now;
|
|
20497
|
+
}
|
|
20498
|
+
shouldMarkStale(thresholdMs, now = Date.now()) {
|
|
20499
|
+
if (this._isStale)
|
|
20500
|
+
return false;
|
|
20501
|
+
return this.ageMs(now) > thresholdMs;
|
|
20502
|
+
}
|
|
20503
|
+
processEvent(event, now = Date.now()) {
|
|
20504
|
+
switch (event.kind) {
|
|
20505
|
+
case "text":
|
|
20506
|
+
case "tool_call":
|
|
20507
|
+
case "tool_output":
|
|
20508
|
+
case "turn_end":
|
|
20509
|
+
case "session_init":
|
|
20510
|
+
case "error":
|
|
20511
|
+
this.recordRealEvent(event.kind, now);
|
|
20512
|
+
break;
|
|
20513
|
+
case "internal_progress":
|
|
20514
|
+
case "compaction_started":
|
|
20515
|
+
case "compaction_finished":
|
|
20516
|
+
case "telemetry":
|
|
20517
|
+
case "thinking":
|
|
20518
|
+
this.recordInternalProgress(event.kind, now);
|
|
20519
|
+
break;
|
|
20520
|
+
default:
|
|
20521
|
+
this.recordInternalProgress(event.kind, now);
|
|
20522
|
+
}
|
|
20523
|
+
}
|
|
20524
|
+
}
|
|
20525
|
+
|
|
20526
|
+
// daemon/steering/errorDiagnostics.ts
|
|
20527
|
+
var ACTION_BY_CLASS = {
|
|
20528
|
+
RateLimitError: "retry_backoff",
|
|
20529
|
+
AuthError: "abort",
|
|
20530
|
+
NotFoundError: "report",
|
|
20531
|
+
ModelConfigError: "abort",
|
|
20532
|
+
TimeoutError: "retry",
|
|
20533
|
+
ProviderConnectionError: "retry_jitter",
|
|
20534
|
+
ProviderStreamError: "retry",
|
|
20535
|
+
ProviderServerError: "retry",
|
|
20536
|
+
ProviderApiError: "report",
|
|
20537
|
+
RuntimeError: "report"
|
|
20538
|
+
};
|
|
20539
|
+
var EXPLICIT_TOKEN_RE = /\b([A-Z][A-Za-z0-9_]*(?:Error|Exception))\b/;
|
|
20540
|
+
var EXPLICIT_TOKEN_MAP = {
|
|
20541
|
+
RateLimitError: "RateLimitError",
|
|
20542
|
+
TooManyRequestsError: "RateLimitError",
|
|
20543
|
+
AuthenticationError: "AuthError",
|
|
20544
|
+
AuthorizationError: "AuthError",
|
|
20545
|
+
PermissionError: "AuthError",
|
|
20546
|
+
NotFoundError: "NotFoundError",
|
|
20547
|
+
ModelNotFoundError: "ModelConfigError",
|
|
20548
|
+
TimeoutError: "TimeoutError",
|
|
20549
|
+
ConnectionError: "ProviderConnectionError",
|
|
20550
|
+
APIConnectionError: "ProviderConnectionError",
|
|
20551
|
+
StreamError: "ProviderStreamError",
|
|
20552
|
+
InternalServerError: "ProviderServerError",
|
|
20553
|
+
APIError: "ProviderApiError",
|
|
20554
|
+
BadRequestError: "ProviderApiError"
|
|
20555
|
+
};
|
|
20556
|
+
function extractHttpStatus(message2) {
|
|
20557
|
+
const labeled = /\b(?:HTTP|status(?:\s+code)?|API\s+Error)[:\s]+([45]\d{2})\b/i.exec(message2);
|
|
20558
|
+
if (labeled)
|
|
20559
|
+
return Number(labeled[1]);
|
|
20560
|
+
const semantic = /\b([45]\d{2})\s+(?:Unauthorized|Forbidden|Not Found|Too Many Requests|Internal Server Error|Bad Gateway|Service Unavailable|Gateway Timeout)\b/i.exec(message2);
|
|
20561
|
+
return semantic ? Number(semantic[1]) : null;
|
|
20562
|
+
}
|
|
20563
|
+
var AUTH_ACTION_REQUIRED_PATTERNS = [
|
|
20564
|
+
/access token could not be refreshed/i,
|
|
20565
|
+
/\btoken_(?:revoked|invalidated)\b/i,
|
|
20566
|
+
/refresh token was already used/i,
|
|
20567
|
+
/access token.*invalidated/i,
|
|
20568
|
+
/authentication token has been invalidated/i,
|
|
20569
|
+
/logged out or signed in to another account/i,
|
|
20570
|
+
/not logged in/i,
|
|
20571
|
+
/not signed in/i,
|
|
20572
|
+
/login required/i,
|
|
20573
|
+
/log in first/i,
|
|
20574
|
+
/please log in/i,
|
|
20575
|
+
/authentication failed/i,
|
|
20576
|
+
/auth(?:entication)? failed/i,
|
|
20577
|
+
/authentication timed out/i,
|
|
20578
|
+
/missing (?:api )?token/i,
|
|
20579
|
+
/no (?:api )?token/i,
|
|
20580
|
+
/missing credentials/i,
|
|
20581
|
+
/credentials? not found/i,
|
|
20582
|
+
/invalid api key/i,
|
|
20583
|
+
/api key (?:is )?not set/i,
|
|
20584
|
+
/token revoked/i,
|
|
20585
|
+
/refresh token expired/i,
|
|
20586
|
+
/session expired/i,
|
|
20587
|
+
/unauthorized/i,
|
|
20588
|
+
/forbidden/i,
|
|
20589
|
+
/invalid.?token/i
|
|
20590
|
+
];
|
|
20591
|
+
var RATE_LIMIT_PATTERNS = [
|
|
20592
|
+
/too many requests/i,
|
|
20593
|
+
/rate.?limit/i,
|
|
20594
|
+
/quota.?exceeded/i,
|
|
20595
|
+
/overloaded/i
|
|
20596
|
+
];
|
|
20597
|
+
var MODEL_CONFIG_PATTERNS = [
|
|
20598
|
+
/model.?not.?(?:found|supported|available)/i,
|
|
20599
|
+
/invalid.?model/i,
|
|
20600
|
+
/does not exist/i
|
|
20601
|
+
];
|
|
20602
|
+
var TIMEOUT_PATTERNS = [
|
|
20603
|
+
/timeout/i,
|
|
20604
|
+
/ETIMEDOUT/,
|
|
20605
|
+
/timed.?out/i,
|
|
20606
|
+
/deadline.?exceeded/i
|
|
20607
|
+
];
|
|
20608
|
+
var CONNECTION_PATTERNS = [
|
|
20609
|
+
/ECONNREFUSED/,
|
|
20610
|
+
/ECONNRESET/,
|
|
20611
|
+
/ENETUNREACH/,
|
|
20612
|
+
/EHOSTUNREACH/,
|
|
20613
|
+
/EAI_AGAIN/,
|
|
20614
|
+
/ENOTFOUND/,
|
|
20615
|
+
/connection.?refused/i,
|
|
20616
|
+
/connection.?reset/i,
|
|
20617
|
+
/network.?error/i,
|
|
20618
|
+
/Unable to connect to API/i
|
|
20619
|
+
];
|
|
20620
|
+
var STREAM_PATTERNS = [
|
|
20621
|
+
/stream.?error/i,
|
|
20622
|
+
/stream closed before response/i,
|
|
20623
|
+
/error decoding response body/i,
|
|
20624
|
+
/premature.?close/i,
|
|
20625
|
+
/aborted/i
|
|
20626
|
+
];
|
|
20627
|
+
var SERVER_PATTERNS = [
|
|
20628
|
+
/internal.?server/i,
|
|
20629
|
+
/bad.?gateway/i,
|
|
20630
|
+
/service.?unavailable/i
|
|
20631
|
+
];
|
|
20632
|
+
function classifyByExplicitToken(message2) {
|
|
20633
|
+
const match = EXPLICIT_TOKEN_RE.exec(message2);
|
|
20634
|
+
if (!match)
|
|
20635
|
+
return null;
|
|
20636
|
+
const token = match[1];
|
|
20637
|
+
return EXPLICIT_TOKEN_MAP[token] ?? null;
|
|
20638
|
+
}
|
|
20639
|
+
function classifyByHttpStatus(httpStatus) {
|
|
20640
|
+
if (httpStatus === 429)
|
|
20641
|
+
return "RateLimitError";
|
|
20642
|
+
if (httpStatus === 401 || httpStatus === 403)
|
|
20643
|
+
return "AuthError";
|
|
20644
|
+
if (httpStatus === 404)
|
|
20645
|
+
return "NotFoundError";
|
|
20646
|
+
if (httpStatus >= 500)
|
|
20647
|
+
return "ProviderServerError";
|
|
20648
|
+
return "ProviderApiError";
|
|
20649
|
+
}
|
|
20650
|
+
function classifyByTextPatterns(message2) {
|
|
20651
|
+
for (const pat of RATE_LIMIT_PATTERNS) {
|
|
20652
|
+
if (pat.test(message2))
|
|
20653
|
+
return "RateLimitError";
|
|
20654
|
+
}
|
|
20655
|
+
for (const pat of AUTH_ACTION_REQUIRED_PATTERNS) {
|
|
20656
|
+
if (pat.test(message2))
|
|
20657
|
+
return "AuthError";
|
|
20658
|
+
}
|
|
20659
|
+
for (const pat of MODEL_CONFIG_PATTERNS) {
|
|
20660
|
+
if (pat.test(message2))
|
|
20661
|
+
return "ModelConfigError";
|
|
20662
|
+
}
|
|
20663
|
+
for (const pat of TIMEOUT_PATTERNS) {
|
|
20664
|
+
if (pat.test(message2))
|
|
20665
|
+
return "TimeoutError";
|
|
20666
|
+
}
|
|
20667
|
+
for (const pat of CONNECTION_PATTERNS) {
|
|
20668
|
+
if (pat.test(message2))
|
|
20669
|
+
return "ProviderConnectionError";
|
|
20670
|
+
}
|
|
20671
|
+
for (const pat of STREAM_PATTERNS) {
|
|
20672
|
+
if (pat.test(message2))
|
|
20673
|
+
return "ProviderStreamError";
|
|
20674
|
+
}
|
|
20675
|
+
for (const pat of SERVER_PATTERNS) {
|
|
20676
|
+
if (pat.test(message2))
|
|
20677
|
+
return "ProviderServerError";
|
|
20678
|
+
}
|
|
20679
|
+
return null;
|
|
20680
|
+
}
|
|
20681
|
+
function classifyRuntimeError(message2, httpStatus) {
|
|
20682
|
+
const byToken = classifyByExplicitToken(message2);
|
|
20683
|
+
if (byToken) {
|
|
20684
|
+
return { errorClass: byToken, action: ACTION_BY_CLASS[byToken], reason: message2 };
|
|
20685
|
+
}
|
|
20686
|
+
const status = httpStatus ?? extractHttpStatus(message2);
|
|
20687
|
+
if (status !== null && status !== undefined) {
|
|
20688
|
+
const cls = classifyByHttpStatus(status);
|
|
20689
|
+
return { errorClass: cls, action: ACTION_BY_CLASS[cls], reason: message2 };
|
|
20690
|
+
}
|
|
20691
|
+
const byPattern = classifyByTextPatterns(message2);
|
|
20692
|
+
if (byPattern) {
|
|
20693
|
+
return { errorClass: byPattern, action: ACTION_BY_CLASS[byPattern], reason: message2 };
|
|
20694
|
+
}
|
|
20695
|
+
return { errorClass: "RuntimeError", action: "report", reason: message2 };
|
|
20696
|
+
}
|
|
20697
|
+
function scrubDiagnosticText(text2) {
|
|
20698
|
+
let scrubbed = text2;
|
|
20699
|
+
scrubbed = scrubbed.replace(/sk-ant-[a-zA-Z0-9_-]+/g, "sk-ant-***");
|
|
20700
|
+
scrubbed = scrubbed.replace(/sk-proj-[a-zA-Z0-9_-]+/g, "sk-proj-***");
|
|
20701
|
+
scrubbed = scrubbed.replace(/sk-[a-zA-Z0-9_-]{20,}/g, "sk-***");
|
|
20702
|
+
scrubbed = scrubbed.replace(/Bearer\s+[a-zA-Z0-9._-]+/gi, "Bearer ***");
|
|
20703
|
+
scrubbed = scrubbed.replace(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g, "***@***.***");
|
|
20704
|
+
scrubbed = scrubbed.replace(/:\/\/[^:@\s]+:[^@\s]+@/g, "://***:***@");
|
|
20705
|
+
scrubbed = scrubbed.replace(/\/(?:Users|home)\/[a-zA-Z0-9._-]+/g, "/***");
|
|
20706
|
+
return scrubbed;
|
|
20707
|
+
}
|
|
20708
|
+
|
|
18843
20709
|
// daemon/prompt.ts
|
|
18844
20710
|
var DM_RESPONSE_NOTICE = "Reply with `alook sync send-dm` — that's the only thing the user sees; your task output and reasoning are not shown." + " Talk to them at milestones like a colleague would, and don't end your turn without sending what they need." + " If this task will take more than 30 seconds, send a quick ack first so the user knows you're on it." + " IMPORTANT: If you were working on a previous task before this message arrived, do NOT silently drop it. After handling this message, return to any prior unfinished work and report the result to the user.";
|
|
18845
20711
|
var EMAIL_NOTICE = "This task was triggered by an incoming email. Reply to the sender via email — use the email sending tool to respond." + " If you need more information or confirmation, email them and then exit." + " Do not wait — when they reply, a new task will be triggered automatically and you will be woken up with their response." + " IMPORTANT: Do not let this email interrupt any task you were previously working on. After handling this email, return to your original task and make sure it reaches completion.";
|
|
@@ -18935,7 +20801,7 @@ function buildPrompt(task, attachments) {
|
|
|
18935
20801
|
}
|
|
18936
20802
|
|
|
18937
20803
|
// daemon/session-runner.ts
|
|
18938
|
-
var
|
|
20804
|
+
var log8 = createLogger2({ module: "session-runner" });
|
|
18939
20805
|
var ATTACHMENTS_BASE = tempDir("alook-attachments");
|
|
18940
20806
|
async function writeMarkerFile(workspacesRoot, marker) {
|
|
18941
20807
|
const dir = path.join(workspacesRoot, ".pending_completions");
|
|
@@ -18983,20 +20849,20 @@ async function reportToServer(fn, markerData, workspacesRoot) {
|
|
|
18983
20849
|
} catch (e) {
|
|
18984
20850
|
lastErr = e;
|
|
18985
20851
|
if (isClientError(e)) {
|
|
18986
|
-
|
|
20852
|
+
log8.info(`server report for task ${markerData.taskId}: task already in terminal state (${e})`);
|
|
18987
20853
|
return;
|
|
18988
20854
|
}
|
|
18989
20855
|
if (attempt < RETRY_DELAYS.length && isRetryableError(e)) {
|
|
18990
|
-
|
|
20856
|
+
log8.debug(`server report attempt ${attempt + 1} failed for task ${markerData.taskId}, retrying in ${RETRY_DELAYS[attempt]}ms`);
|
|
18991
20857
|
await new Promise((r) => setTimeout(r, RETRY_DELAYS[attempt]));
|
|
18992
20858
|
}
|
|
18993
20859
|
}
|
|
18994
20860
|
}
|
|
18995
|
-
|
|
20861
|
+
log8.warn(`server report failed for task ${markerData.taskId} after retries, writing marker: ${lastErr}`);
|
|
18996
20862
|
try {
|
|
18997
20863
|
await writeMarkerFile(workspacesRoot, markerData);
|
|
18998
20864
|
} catch (writeErr) {
|
|
18999
|
-
|
|
20865
|
+
log8.error(`marker write also failed for task ${markerData.taskId}: ${writeErr}`);
|
|
19000
20866
|
}
|
|
19001
20867
|
}
|
|
19002
20868
|
function sanitizeFilename(name) {
|
|
@@ -19027,12 +20893,12 @@ async function downloadAttachments(client, token, workspaceId, taskId, attachmen
|
|
|
19027
20893
|
}
|
|
19028
20894
|
async function runSession(input) {
|
|
19029
20895
|
const { task, provider, cliPath, model, serverURL, token, workspacesRoot, agentTimeout, messageInactivityTimeout } = input;
|
|
19030
|
-
|
|
20896
|
+
log8.info(`starting (task=${task.id}, type=${task.type}, agent=${task.agentId}, provider=${provider}, model=${model || "default"})`);
|
|
19031
20897
|
const client = new DaemonClient(serverURL);
|
|
19032
20898
|
const backend = createBackend(provider, cliPath);
|
|
19033
20899
|
const agentBaseDir = path.join(workspacesRoot, task.workspaceId, task.agentId, "workdir");
|
|
19034
20900
|
const timelineDir = path.join(agentBaseDir, ".context_timeline").replace(/\\/g, "/");
|
|
19035
|
-
|
|
20901
|
+
mkdirSync5(timelineDir, { recursive: true });
|
|
19036
20902
|
await initEntryAsync(timelineDir, createTimelineEntry(task.id, task.prompt, task.type, undefined, process.pid, provider, task.contextKey, input.logFilePath));
|
|
19037
20903
|
const { workDir, env } = prepare({ workspacesRoot, token }, task);
|
|
19038
20904
|
let killed = false;
|
|
@@ -19050,16 +20916,22 @@ async function runSession(input) {
|
|
|
19050
20916
|
try {
|
|
19051
20917
|
await client.reportMessages(token, task.id, batch);
|
|
19052
20918
|
} catch (e) {
|
|
19053
|
-
|
|
20919
|
+
log8.debug("message report failed", e);
|
|
19054
20920
|
}
|
|
19055
20921
|
};
|
|
20922
|
+
let mailboxWatcher = null;
|
|
20923
|
+
let stalledRecoveryTimer;
|
|
19056
20924
|
const onKill = async () => {
|
|
19057
20925
|
if (killed)
|
|
19058
20926
|
return;
|
|
19059
20927
|
killed = true;
|
|
19060
|
-
|
|
20928
|
+
log8.info(`killed by signal (messages=${seq}, tools=${toolCount})`);
|
|
20929
|
+
if (mailboxWatcher)
|
|
20930
|
+
mailboxWatcher.stop();
|
|
20931
|
+
if (stalledRecoveryTimer)
|
|
20932
|
+
clearInterval(stalledRecoveryTimer);
|
|
19061
20933
|
if (agentPid !== undefined) {
|
|
19062
|
-
|
|
20934
|
+
log8.info(`killing inner agent group (pid=${agentPid})`);
|
|
19063
20935
|
await killProcessTree(agentPid);
|
|
19064
20936
|
}
|
|
19065
20937
|
if (flushTimer)
|
|
@@ -19102,14 +20974,14 @@ async function runSession(input) {
|
|
|
19102
20974
|
const attachmentIds = task.context?.attachment_ids ?? [];
|
|
19103
20975
|
let attachments;
|
|
19104
20976
|
if (attachmentIds.length > 0) {
|
|
19105
|
-
|
|
20977
|
+
log8.info(`downloading ${attachmentIds.length} attachment(s)`);
|
|
19106
20978
|
try {
|
|
19107
20979
|
attachments = await downloadAttachments(client, token, task.workspaceId, task.id, attachmentIds);
|
|
19108
|
-
|
|
20980
|
+
log8.info(`attachments ready (${attachments.length} file(s))`);
|
|
19109
20981
|
} catch (e) {
|
|
19110
20982
|
await cleanupAttachments(task.id);
|
|
19111
20983
|
const errMsg = `failed to download attachments: ${e}`;
|
|
19112
|
-
|
|
20984
|
+
log8.error(errMsg);
|
|
19113
20985
|
updateEntry(timelineDir, task.id, (entry) => {
|
|
19114
20986
|
entry.pid = null;
|
|
19115
20987
|
entry.status = "failed";
|
|
@@ -19126,32 +20998,301 @@ async function runSession(input) {
|
|
|
19126
20998
|
const prompt = input.promptOverride ?? buildPrompt(task, attachments);
|
|
19127
20999
|
const resumeSessionId = task.contextKey ? findResumableSessionByContextKey(timelineDir, task.contextKey, provider) ?? undefined : undefined;
|
|
19128
21000
|
if (resumeSessionId) {
|
|
19129
|
-
|
|
21001
|
+
log8.info(`resuming session ${resumeSessionId} (context_key: ${task.contextKey})`);
|
|
19130
21002
|
}
|
|
19131
21003
|
const session2 = backend.execute(prompt, {
|
|
19132
21004
|
cwd: workDir,
|
|
19133
21005
|
model: model || undefined,
|
|
19134
21006
|
env,
|
|
19135
21007
|
timeout: agentTimeout,
|
|
19136
|
-
resumeSessionId
|
|
21008
|
+
resumeSessionId,
|
|
21009
|
+
steeringEnabled: input.steeringEnabled
|
|
19137
21010
|
});
|
|
19138
21011
|
agentPid = session2.pid;
|
|
19139
21012
|
if (killed) {
|
|
19140
21013
|
if (agentPid !== undefined) {
|
|
19141
|
-
|
|
21014
|
+
log8.info(`kill landed during spawn — reaping inner agent group (pid=${agentPid})`);
|
|
19142
21015
|
await killProcessTree(agentPid);
|
|
19143
21016
|
}
|
|
19144
21017
|
process.exit(1);
|
|
19145
21018
|
}
|
|
19146
21019
|
const earlySessionId = await session2.sessionId;
|
|
19147
|
-
|
|
19148
|
-
|
|
21020
|
+
log8.info(`agent started (pid=${agentPid ?? "unknown"}, session=${earlySessionId})`);
|
|
21021
|
+
log8.info(JSON.stringify({ role: "user", type: "text", content: prompt }));
|
|
19149
21022
|
updateEntry(timelineDir, task.id, (entry) => {
|
|
19150
21023
|
entry.session_id = earlySessionId || null;
|
|
19151
21024
|
if (earlySessionId)
|
|
19152
21025
|
entry.agent_started = true;
|
|
19153
21026
|
});
|
|
19154
21027
|
flushTimer = setInterval(flushMessages, FLUSH_INTERVAL_MS);
|
|
21028
|
+
const turnState = new RuntimeTurnState;
|
|
21029
|
+
let apmState = createInitialApmState();
|
|
21030
|
+
const notificationState = new RuntimeNotificationState;
|
|
21031
|
+
const progressState = new RuntimeProgressState;
|
|
21032
|
+
const pendingSteeredTasks = new Set;
|
|
21033
|
+
const pendingAcks = [];
|
|
21034
|
+
let hasReceivedProgressEvent = false;
|
|
21035
|
+
if (input.steeringEnabled && input.steeringMailboxDir && task.contextKey) {
|
|
21036
|
+
const descriptor = session2.descriptor;
|
|
21037
|
+
const STALLED_THRESHOLD_MS = 120000;
|
|
21038
|
+
const STALLED_CHECK_INTERVAL_MS = 30000;
|
|
21039
|
+
if (session2.parsedEvents) {
|
|
21040
|
+
const parsedIter = session2.parsedEvents[Symbol.asyncIterator]();
|
|
21041
|
+
const consumeParsedEvents = async () => {
|
|
21042
|
+
try {
|
|
21043
|
+
while (!killed) {
|
|
21044
|
+
const { value: event, done } = await parsedIter.next();
|
|
21045
|
+
if (done)
|
|
21046
|
+
break;
|
|
21047
|
+
hasReceivedProgressEvent = true;
|
|
21048
|
+
progressState.processEvent(event);
|
|
21049
|
+
const recentResult = reduceApmGatedRecentEvent(apmState, { event: event.kind });
|
|
21050
|
+
apmState = recentResult.nextState;
|
|
21051
|
+
if (event.kind === "error") {
|
|
21052
|
+
const classified = classifyRuntimeError(event.message);
|
|
21053
|
+
log8.info(`steering: error classified as ${classified.errorClass}: ${scrubDiagnosticText(event.message)}`);
|
|
21054
|
+
const errResult = reduceApmGatedError(apmState, { disableToolBoundaryFlush: true });
|
|
21055
|
+
apmState = errResult.nextState;
|
|
21056
|
+
}
|
|
21057
|
+
switch (event.kind) {
|
|
21058
|
+
case "tool_call":
|
|
21059
|
+
case "thinking":
|
|
21060
|
+
case "compaction_started":
|
|
21061
|
+
turnState.markToolBoundary();
|
|
21062
|
+
break;
|
|
21063
|
+
case "text":
|
|
21064
|
+
case "tool_output":
|
|
21065
|
+
case "compaction_finished":
|
|
21066
|
+
turnState.markProgress();
|
|
21067
|
+
break;
|
|
21068
|
+
}
|
|
21069
|
+
switch (event.kind) {
|
|
21070
|
+
case "session_init":
|
|
21071
|
+
turnState.markTurnStarted(event.sessionId);
|
|
21072
|
+
break;
|
|
21073
|
+
case "text":
|
|
21074
|
+
if (!turnState.isInTurn)
|
|
21075
|
+
turnState.markTurnStarted();
|
|
21076
|
+
break;
|
|
21077
|
+
case "tool_call": {
|
|
21078
|
+
if (!turnState.isInTurn)
|
|
21079
|
+
turnState.markTurnStarted();
|
|
21080
|
+
const result2 = reduceApmGatedToolUse(apmState, { kind: "tool_call" });
|
|
21081
|
+
apmState = result2.nextState;
|
|
21082
|
+
break;
|
|
21083
|
+
}
|
|
21084
|
+
case "tool_output": {
|
|
21085
|
+
const result2 = reduceApmGatedToolUse(apmState, { kind: "tool_output" });
|
|
21086
|
+
apmState = result2.nextState;
|
|
21087
|
+
if (result2.shouldFlushToolBatch && session2.send && apmState.pendingMessages.length > 0) {
|
|
21088
|
+
const readiness = reduceApmGatedFlushReadiness(apmState, {
|
|
21089
|
+
isGated: descriptor?.busyDeliveryMode === "gated",
|
|
21090
|
+
hasSession: !!earlySessionId,
|
|
21091
|
+
inboxLength: apmState.pendingMessages.length,
|
|
21092
|
+
reason: "tool_batch_complete"
|
|
21093
|
+
});
|
|
21094
|
+
if (readiness.shouldNotify) {
|
|
21095
|
+
let allSent = true;
|
|
21096
|
+
for (const msg of apmState.pendingMessages) {
|
|
21097
|
+
const sendResult = session2.send(msg, "busy");
|
|
21098
|
+
if (!sendResult.ok) {
|
|
21099
|
+
allSent = false;
|
|
21100
|
+
break;
|
|
21101
|
+
}
|
|
21102
|
+
}
|
|
21103
|
+
if (allSent) {
|
|
21104
|
+
apmState = { ...apmState, pendingMessages: [] };
|
|
21105
|
+
for (const ack of pendingAcks) {
|
|
21106
|
+
notificationState.recordNoticeWritten(String(ack.seq), ack.sessionId, [{ id: String(ack.seq) }]);
|
|
21107
|
+
writeAck(agentBaseDir, task.contextKey, ack.seq);
|
|
21108
|
+
}
|
|
21109
|
+
pendingAcks.length = 0;
|
|
21110
|
+
}
|
|
21111
|
+
}
|
|
21112
|
+
}
|
|
21113
|
+
break;
|
|
21114
|
+
}
|
|
21115
|
+
case "compaction_started":
|
|
21116
|
+
case "compaction_finished": {
|
|
21117
|
+
const result2 = reduceApmGatedCompaction(apmState, { kind: event.kind });
|
|
21118
|
+
apmState = result2.nextState;
|
|
21119
|
+
if (event.kind === "compaction_finished" && session2.send && apmState.pendingMessages.length > 0) {
|
|
21120
|
+
const readiness = reduceApmGatedFlushReadiness(apmState, {
|
|
21121
|
+
isGated: descriptor?.busyDeliveryMode === "gated",
|
|
21122
|
+
hasSession: !!earlySessionId,
|
|
21123
|
+
inboxLength: apmState.pendingMessages.length,
|
|
21124
|
+
reason: "compaction_finished"
|
|
21125
|
+
});
|
|
21126
|
+
if (readiness.shouldNotify) {
|
|
21127
|
+
let allSent = true;
|
|
21128
|
+
for (const msg of apmState.pendingMessages) {
|
|
21129
|
+
const sendResult = session2.send(msg, "busy");
|
|
21130
|
+
if (!sendResult.ok) {
|
|
21131
|
+
allSent = false;
|
|
21132
|
+
break;
|
|
21133
|
+
}
|
|
21134
|
+
}
|
|
21135
|
+
if (allSent) {
|
|
21136
|
+
apmState = { ...apmState, pendingMessages: [] };
|
|
21137
|
+
for (const ack of pendingAcks) {
|
|
21138
|
+
notificationState.recordNoticeWritten(String(ack.seq), ack.sessionId, [{ id: String(ack.seq) }]);
|
|
21139
|
+
writeAck(agentBaseDir, task.contextKey, ack.seq);
|
|
21140
|
+
}
|
|
21141
|
+
pendingAcks.length = 0;
|
|
21142
|
+
}
|
|
21143
|
+
}
|
|
21144
|
+
}
|
|
21145
|
+
break;
|
|
21146
|
+
}
|
|
21147
|
+
case "turn_end": {
|
|
21148
|
+
const result2 = reduceApmGatedTurnEnd(apmState, {
|
|
21149
|
+
inboxLength: apmState.pendingMessages.length,
|
|
21150
|
+
supportsStdinNotification: descriptor?.supportsStdinNotification,
|
|
21151
|
+
hasSession: !!earlySessionId
|
|
21152
|
+
});
|
|
21153
|
+
apmState = result2.nextState;
|
|
21154
|
+
let flushedOk = false;
|
|
21155
|
+
for (const eff of result2.effects) {
|
|
21156
|
+
if (eff.kind === "deliver_stdin" && session2.send) {
|
|
21157
|
+
let allSent = true;
|
|
21158
|
+
for (const msg of apmState.pendingMessages) {
|
|
21159
|
+
const sendResult = session2.send(msg, eff.stdinMode);
|
|
21160
|
+
if (!sendResult.ok) {
|
|
21161
|
+
log8.warn("steering: send failed during turn_end flush", { reason: sendResult.reason });
|
|
21162
|
+
allSent = false;
|
|
21163
|
+
break;
|
|
21164
|
+
}
|
|
21165
|
+
}
|
|
21166
|
+
if (allSent) {
|
|
21167
|
+
apmState = { ...apmState, pendingMessages: [] };
|
|
21168
|
+
flushedOk = true;
|
|
21169
|
+
}
|
|
21170
|
+
}
|
|
21171
|
+
}
|
|
21172
|
+
if (flushedOk && pendingAcks.length > 0) {
|
|
21173
|
+
for (const ack of pendingAcks) {
|
|
21174
|
+
notificationState.recordNoticeWritten(String(ack.seq), ack.sessionId, [{ id: String(ack.seq) }]);
|
|
21175
|
+
writeAck(agentBaseDir, task.contextKey, ack.seq);
|
|
21176
|
+
}
|
|
21177
|
+
pendingAcks.length = 0;
|
|
21178
|
+
}
|
|
21179
|
+
if (flushedOk || apmState.pendingMessages.length === 0) {
|
|
21180
|
+
for (const steeredId of pendingSteeredTasks) {
|
|
21181
|
+
client.completeTask(token, steeredId, { output: "" }).catch((e) => {
|
|
21182
|
+
log8.debug(`steering: failed to complete steered task ${steeredId}`, e);
|
|
21183
|
+
});
|
|
21184
|
+
}
|
|
21185
|
+
pendingSteeredTasks.clear();
|
|
21186
|
+
}
|
|
21187
|
+
turnState.markTurnCompleted();
|
|
21188
|
+
break;
|
|
21189
|
+
}
|
|
21190
|
+
}
|
|
21191
|
+
}
|
|
21192
|
+
} catch (err) {
|
|
21193
|
+
log8.warn("steering: consumeParsedEvents error", { err: err instanceof Error ? err.message : String(err) });
|
|
21194
|
+
}
|
|
21195
|
+
};
|
|
21196
|
+
consumeParsedEvents().catch((err) => {
|
|
21197
|
+
log8.error("steering: consumeParsedEvents unhandled error", { err: err instanceof Error ? err.message : String(err) });
|
|
21198
|
+
});
|
|
21199
|
+
}
|
|
21200
|
+
stalledRecoveryTimer = setInterval(() => {
|
|
21201
|
+
if (killed)
|
|
21202
|
+
return;
|
|
21203
|
+
if (!hasReceivedProgressEvent) {
|
|
21204
|
+
const startupResult = reduceApmStartupTimeoutTermination(apmState, {
|
|
21205
|
+
hasRuntimeProgressEvent: hasReceivedProgressEvent
|
|
21206
|
+
});
|
|
21207
|
+
apmState = startupResult.nextState;
|
|
21208
|
+
if (startupResult.shouldTerminate) {
|
|
21209
|
+
log8.warn("steering: startup timeout — no progress events received, killing agent");
|
|
21210
|
+
if (agentPid !== undefined)
|
|
21211
|
+
killProcessTree(agentPid);
|
|
21212
|
+
return;
|
|
21213
|
+
}
|
|
21214
|
+
}
|
|
21215
|
+
const staleForMs = progressState.ageMs();
|
|
21216
|
+
if (staleForMs > STALLED_THRESHOLD_MS && !progressState.isStale) {
|
|
21217
|
+
progressState.markStale();
|
|
21218
|
+
}
|
|
21219
|
+
const stalledResult = reduceApmStalledRecoveryTermination(apmState, {
|
|
21220
|
+
inboxLength: apmState.pendingMessages.length,
|
|
21221
|
+
staleForMs,
|
|
21222
|
+
staleThresholdMs: STALLED_THRESHOLD_MS,
|
|
21223
|
+
runtimeProgressIsStale: progressState.isStale,
|
|
21224
|
+
hasSession: !!earlySessionId,
|
|
21225
|
+
busyDeliveryMode: descriptor?.busyDeliveryMode ?? "none",
|
|
21226
|
+
hasDirectStdinRecoveryEvidence: false
|
|
21227
|
+
});
|
|
21228
|
+
apmState = stalledResult.nextState;
|
|
21229
|
+
if (stalledResult.shouldTerminate) {
|
|
21230
|
+
log8.warn(`steering: stalled recovery — agent stale for ${(staleForMs / 1000).toFixed(1)}s with ${apmState.pendingMessages.length} pending messages, killing`);
|
|
21231
|
+
if (agentPid !== undefined)
|
|
21232
|
+
killProcessTree(agentPid);
|
|
21233
|
+
}
|
|
21234
|
+
}, STALLED_CHECK_INTERVAL_MS);
|
|
21235
|
+
mailboxWatcher = watchInbox(agentBaseDir, task.contextKey, (seq2, message2) => {
|
|
21236
|
+
const sessionId = earlySessionId || "";
|
|
21237
|
+
if (notificationState.isDuplicateNotice(String(seq2), sessionId)) {
|
|
21238
|
+
writeAck(agentBaseDir, task.contextKey, seq2);
|
|
21239
|
+
cleanupInboxFile(agentBaseDir, task.contextKey, seq2);
|
|
21240
|
+
return;
|
|
21241
|
+
}
|
|
21242
|
+
const busyMode = session2.descriptor?.busyDeliveryMode;
|
|
21243
|
+
let delivered = false;
|
|
21244
|
+
if (busyMode === "direct" && session2.send) {
|
|
21245
|
+
const result2 = session2.send(message2.text, turnState.isInTurn ? "busy" : "idle");
|
|
21246
|
+
if (result2.ok) {
|
|
21247
|
+
notificationState.recordNoticeWritten(String(seq2), sessionId, [{ id: String(seq2) }]);
|
|
21248
|
+
writeAck(agentBaseDir, task.contextKey, seq2);
|
|
21249
|
+
delivered = true;
|
|
21250
|
+
} else {
|
|
21251
|
+
writeNack(agentBaseDir, task.contextKey, seq2, result2.reason || "send failed");
|
|
21252
|
+
}
|
|
21253
|
+
} else if (busyMode === "gated") {
|
|
21254
|
+
const enqueueResult = reduceApmGatedEnqueue(apmState, message2.text);
|
|
21255
|
+
apmState = enqueueResult.nextState;
|
|
21256
|
+
if (turnState.canSteerBusy && session2.send && apmState.pendingMessages.length > 0) {
|
|
21257
|
+
const readiness = reduceApmGatedFlushReadiness(apmState, {
|
|
21258
|
+
isGated: true,
|
|
21259
|
+
hasSession: !!earlySessionId,
|
|
21260
|
+
inboxLength: apmState.pendingMessages.length,
|
|
21261
|
+
reason: "enqueue"
|
|
21262
|
+
});
|
|
21263
|
+
if (readiness.shouldNotify) {
|
|
21264
|
+
let allSent = true;
|
|
21265
|
+
for (const msg of apmState.pendingMessages) {
|
|
21266
|
+
const sendResult = session2.send(msg, "busy");
|
|
21267
|
+
if (!sendResult.ok) {
|
|
21268
|
+
allSent = false;
|
|
21269
|
+
break;
|
|
21270
|
+
}
|
|
21271
|
+
}
|
|
21272
|
+
if (allSent) {
|
|
21273
|
+
apmState = { ...apmState, pendingMessages: [] };
|
|
21274
|
+
}
|
|
21275
|
+
}
|
|
21276
|
+
}
|
|
21277
|
+
if (apmState.pendingMessages.length === 0) {
|
|
21278
|
+
notificationState.recordNoticeWritten(String(seq2), sessionId, [{ id: String(seq2) }]);
|
|
21279
|
+
writeAck(agentBaseDir, task.contextKey, seq2);
|
|
21280
|
+
} else {
|
|
21281
|
+
pendingAcks.push({ seq: seq2, sessionId });
|
|
21282
|
+
}
|
|
21283
|
+
delivered = true;
|
|
21284
|
+
} else {
|
|
21285
|
+
writeNack(agentBaseDir, task.contextKey, seq2, "unsupported backend");
|
|
21286
|
+
}
|
|
21287
|
+
if (delivered && message2.taskId) {
|
|
21288
|
+
pendingSteeredTasks.add(message2.taskId);
|
|
21289
|
+
client.startTask(token, message2.taskId).catch((e) => {
|
|
21290
|
+
log8.debug(`steering: failed to start steered task ${message2.taskId}`, e);
|
|
21291
|
+
});
|
|
21292
|
+
}
|
|
21293
|
+
cleanupInboxFile(agentBaseDir, task.contextKey, seq2);
|
|
21294
|
+
});
|
|
21295
|
+
}
|
|
19155
21296
|
const INACTIVITY_TIMEOUT_MS = messageInactivityTimeout ?? 5 * 60 * 1000;
|
|
19156
21297
|
let inactivityTimedOut = false;
|
|
19157
21298
|
try {
|
|
@@ -19167,7 +21308,7 @@ async function runSession(input) {
|
|
|
19167
21308
|
]) : next);
|
|
19168
21309
|
if (raceResult === "timeout") {
|
|
19169
21310
|
inactivityTimedOut = true;
|
|
19170
|
-
|
|
21311
|
+
log8.warn(`message inactivity timeout (${INACTIVITY_TIMEOUT_MS / 1000}s) — killing agent`);
|
|
19171
21312
|
if (session2.pid !== undefined) {
|
|
19172
21313
|
await killProcessTree(session2.pid);
|
|
19173
21314
|
}
|
|
@@ -19182,9 +21323,9 @@ async function runSession(input) {
|
|
|
19182
21323
|
if (msg.type === "tool-use")
|
|
19183
21324
|
toolCount++;
|
|
19184
21325
|
if (msg.type === "tool-result" && msg.output && msg.output.length > 500) {
|
|
19185
|
-
|
|
21326
|
+
log8.info(JSON.stringify({ role: "assistant", ...msg, output: msg.output.slice(0, 500) + `... (${msg.output.length} chars)` }));
|
|
19186
21327
|
} else {
|
|
19187
|
-
|
|
21328
|
+
log8.info(JSON.stringify({ role: "assistant", ...msg }));
|
|
19188
21329
|
}
|
|
19189
21330
|
if (msg.type === "status" || msg.type === "log")
|
|
19190
21331
|
continue;
|
|
@@ -19223,6 +21364,13 @@ async function runSession(input) {
|
|
|
19223
21364
|
result.status = "failed";
|
|
19224
21365
|
result.error = `message inactivity timeout (no messages for ${INACTIVITY_TIMEOUT_MS / 1000}s)`;
|
|
19225
21366
|
}
|
|
21367
|
+
if (stalledRecoveryTimer)
|
|
21368
|
+
clearInterval(stalledRecoveryTimer);
|
|
21369
|
+
if (mailboxWatcher) {
|
|
21370
|
+
mailboxWatcher.stop();
|
|
21371
|
+
if (task.contextKey)
|
|
21372
|
+
cleanupSteeringDir(agentBaseDir, task.contextKey);
|
|
21373
|
+
}
|
|
19226
21374
|
await cleanupAttachments(task.id);
|
|
19227
21375
|
if (result.status === "completed") {
|
|
19228
21376
|
updateEntry(timelineDir, task.id, (entry) => {
|
|
@@ -19245,18 +21393,18 @@ async function runSession(input) {
|
|
|
19245
21393
|
body.session_id = result.sessionId;
|
|
19246
21394
|
await reportToServer(() => client.completeTask(token, task.id, body), { taskId: task.id, type: "complete", payload: body, token, serverURL, createdAt: new Date().toISOString() }, workspacesRoot);
|
|
19247
21395
|
const dur = (result.durationMs / 1000).toFixed(1);
|
|
19248
|
-
|
|
21396
|
+
log8.info(`completed (duration=${dur}s, messages=${seq}, tools=${toolCount})`);
|
|
19249
21397
|
} else {
|
|
19250
21398
|
const errorMsg = result.error || "agent exited unexpectedly";
|
|
19251
21399
|
await reportToServer(() => client.failTask(token, task.id, errorMsg), { taskId: task.id, type: "fail", payload: { error: errorMsg }, token, serverURL, createdAt: new Date().toISOString() }, workspacesRoot);
|
|
19252
21400
|
const dur = (result.durationMs / 1000).toFixed(1);
|
|
19253
|
-
|
|
21401
|
+
log8.info(`failed (duration=${dur}s, messages=${seq}, tools=${toolCount}) — ${result.error}`);
|
|
19254
21402
|
}
|
|
19255
21403
|
}
|
|
19256
21404
|
async function main() {
|
|
19257
21405
|
const encoded = process.argv[2];
|
|
19258
21406
|
if (!encoded) {
|
|
19259
|
-
|
|
21407
|
+
log8.error("session-runner: missing base64-encoded input argument");
|
|
19260
21408
|
process.exit(1);
|
|
19261
21409
|
}
|
|
19262
21410
|
let input;
|
|
@@ -19264,14 +21412,14 @@ async function main() {
|
|
|
19264
21412
|
const json2 = Buffer.from(encoded, "base64").toString("utf-8");
|
|
19265
21413
|
input = JSON.parse(json2);
|
|
19266
21414
|
} catch (e) {
|
|
19267
|
-
|
|
21415
|
+
log8.error("session-runner: failed to parse input", e);
|
|
19268
21416
|
process.exit(1);
|
|
19269
21417
|
}
|
|
19270
21418
|
const client = new DaemonClient(input.serverURL);
|
|
19271
21419
|
try {
|
|
19272
21420
|
await runSession(input);
|
|
19273
21421
|
} catch (e) {
|
|
19274
|
-
|
|
21422
|
+
log8.error(`session-runner: unhandled error for task ${input.task.id}`, e);
|
|
19275
21423
|
await cleanupAttachments(input.task.id);
|
|
19276
21424
|
const timelineDir = path.join(input.workspacesRoot, input.task.workspaceId, input.task.agentId, "workdir", ".context_timeline").replace(/\\/g, "/");
|
|
19277
21425
|
updateEntry(timelineDir, input.task.id, (entry) => {
|