@alook/cli 0.0.149 → 0.0.151
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 +2754 -464
- package/dist/session-runner.js +2445 -254
- 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,24 @@ var TERMINAL_MEETING_STATUSES = [
|
|
|
76
112
|
MeetingStatus.COMPLETED,
|
|
77
113
|
MeetingStatus.FAILED
|
|
78
114
|
];
|
|
79
|
-
var
|
|
80
|
-
var
|
|
81
|
-
var
|
|
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;
|
|
119
|
+
var DEV_PORTS = {
|
|
120
|
+
web: 3000,
|
|
121
|
+
emailWorker: 8787,
|
|
122
|
+
wsDo: 8789,
|
|
123
|
+
wakeWorker: 8790
|
|
124
|
+
};
|
|
125
|
+
var DEV_WEB_URL = process.env.ALOOK_SERVER_URL || `http://localhost:${DEV_PORTS.web}`;
|
|
126
|
+
var DEV_WS_DO_URL = process.env.DEV_WS_DO_URL || `http://localhost:${DEV_PORTS.wsDo}`;
|
|
127
|
+
var DEV_EMAIL_WORKER_URL = process.env.DEV_EMAIL_WORKER_URL || `http://localhost:${DEV_PORTS.emailWorker}`;
|
|
128
|
+
var DEV_WAKE_WORKER_URL = process.env.DEV_WAKE_WORKER_URL || `http://localhost:${DEV_PORTS.wakeWorker}`;
|
|
129
|
+
// ../shared/src/constants/community.ts
|
|
130
|
+
var MAX_MESSAGE_CONTENT_LENGTH = 4000;
|
|
131
|
+
var MAX_ATTACHMENT_SIZE_BYTES = 25 * 1024 * 1024;
|
|
132
|
+
var MAX_SERVER_ICON_SIZE_BYTES = 5 * 1024 * 1024;
|
|
82
133
|
// ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
|
|
83
134
|
var exports_external = {};
|
|
84
135
|
__export(exports_external, {
|
|
@@ -14843,7 +14894,149 @@ var CreateThreadRequestSchema = exports_external.object({
|
|
|
14843
14894
|
content: exports_external.string().optional().default(""),
|
|
14844
14895
|
attachment_ids: exports_external.array(exports_external.string()).optional()
|
|
14845
14896
|
});
|
|
14846
|
-
|
|
14897
|
+
var COMMUNITY_RUNTIME_ID_MAX = 64;
|
|
14898
|
+
var COMMUNITY_RUNTIME_VERSION_MAX = 64;
|
|
14899
|
+
var COMMUNITY_RUNTIME_LIST_MAX = 64;
|
|
14900
|
+
var RUNTIME_ID_RE = /^[A-Za-z0-9._@/-]+$/;
|
|
14901
|
+
var CommunityMachineRuntimeSchema = exports_external.object({
|
|
14902
|
+
id: exports_external.string().min(1).max(COMMUNITY_RUNTIME_ID_MAX).regex(RUNTIME_ID_RE, "invalid runtime id charset"),
|
|
14903
|
+
version: exports_external.string().max(COMMUNITY_RUNTIME_VERSION_MAX).optional(),
|
|
14904
|
+
status: exports_external.enum(["healthy", "unhealthy"]).catch("healthy").default("healthy"),
|
|
14905
|
+
lastError: exports_external.string().max(128).optional(),
|
|
14906
|
+
lastErrorAt: exports_external.string().optional()
|
|
14907
|
+
});
|
|
14908
|
+
var CommunityMachineRuntimeListSchema = exports_external.array(CommunityMachineRuntimeSchema).max(COMMUNITY_RUNTIME_LIST_MAX).transform((list) => {
|
|
14909
|
+
const seen = new Set;
|
|
14910
|
+
const out = [];
|
|
14911
|
+
for (const r of list) {
|
|
14912
|
+
if (seen.has(r.id))
|
|
14913
|
+
continue;
|
|
14914
|
+
seen.add(r.id);
|
|
14915
|
+
out.push(r);
|
|
14916
|
+
}
|
|
14917
|
+
return out;
|
|
14918
|
+
});
|
|
14919
|
+
var CommunityMachineSummarySchema = exports_external.object({
|
|
14920
|
+
id: exports_external.string(),
|
|
14921
|
+
hostname: exports_external.string(),
|
|
14922
|
+
displayName: exports_external.string(),
|
|
14923
|
+
platform: exports_external.string(),
|
|
14924
|
+
arch: exports_external.string(),
|
|
14925
|
+
osRelease: exports_external.string(),
|
|
14926
|
+
daemonVersion: exports_external.string(),
|
|
14927
|
+
lastSeenAt: exports_external.string().nullable(),
|
|
14928
|
+
status: exports_external.enum(["online", "offline"]),
|
|
14929
|
+
availableRuntimes: exports_external.array(CommunityMachineRuntimeSchema).default([]),
|
|
14930
|
+
lastRuntimeError: exports_external.object({
|
|
14931
|
+
requested: exports_external.string(),
|
|
14932
|
+
available: exports_external.array(exports_external.string()),
|
|
14933
|
+
at: exports_external.string()
|
|
14934
|
+
}).optional(),
|
|
14935
|
+
createdAt: exports_external.string(),
|
|
14936
|
+
updatedAt: exports_external.string()
|
|
14937
|
+
});
|
|
14938
|
+
var HostReadyMessageSchema = exports_external.object({
|
|
14939
|
+
type: exports_external.literal("ready"),
|
|
14940
|
+
runtimeReport: CommunityMachineRuntimeListSchema,
|
|
14941
|
+
runningAgents: exports_external.array(exports_external.string()).default([]),
|
|
14942
|
+
hostname: exports_external.string().optional(),
|
|
14943
|
+
platform: exports_external.string().optional(),
|
|
14944
|
+
arch: exports_external.string().optional(),
|
|
14945
|
+
osRelease: exports_external.string().optional(),
|
|
14946
|
+
daemonVersion: exports_external.string().optional()
|
|
14947
|
+
});
|
|
14948
|
+
var CommunityDaemonReadySchema = exports_external.object({
|
|
14949
|
+
runtimeReport: CommunityMachineRuntimeListSchema.optional(),
|
|
14950
|
+
runningAgents: exports_external.array(exports_external.string()).default([]),
|
|
14951
|
+
hostname: exports_external.string().optional(),
|
|
14952
|
+
os: exports_external.string().optional(),
|
|
14953
|
+
arch: exports_external.string().optional(),
|
|
14954
|
+
osRelease: exports_external.string().optional(),
|
|
14955
|
+
daemonVersion: exports_external.string().optional()
|
|
14956
|
+
});
|
|
14957
|
+
var SessionErrorFrameSchema = exports_external.object({
|
|
14958
|
+
type: exports_external.literal("session.error"),
|
|
14959
|
+
code: exports_external.enum(["runtime_not_available"]),
|
|
14960
|
+
agentId: exports_external.string().optional(),
|
|
14961
|
+
payload: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
|
|
14962
|
+
});
|
|
14963
|
+
var CommunityPairTokenResponseSchema = exports_external.object({
|
|
14964
|
+
tokenId: exports_external.string(),
|
|
14965
|
+
expiresAt: exports_external.string()
|
|
14966
|
+
});
|
|
14967
|
+
var CommunityDaemonActivateRequestSchema = exports_external.object({
|
|
14968
|
+
hostname: exports_external.string(),
|
|
14969
|
+
platform: exports_external.string(),
|
|
14970
|
+
arch: exports_external.string(),
|
|
14971
|
+
osRelease: exports_external.string().optional(),
|
|
14972
|
+
daemonVersion: exports_external.string().optional(),
|
|
14973
|
+
runtimeReport: CommunityMachineRuntimeListSchema.optional()
|
|
14974
|
+
});
|
|
14975
|
+
var CommunityDaemonActivateResponseSchema = exports_external.object({
|
|
14976
|
+
credential: exports_external.string(),
|
|
14977
|
+
machineId: exports_external.string(),
|
|
14978
|
+
expiresAt: exports_external.string().nullable()
|
|
14979
|
+
});
|
|
14980
|
+
var CommunityDaemonEnrollAgentRequestSchema = exports_external.object({
|
|
14981
|
+
agentId: exports_external.string().min(1).max(128)
|
|
14982
|
+
});
|
|
14983
|
+
var CommunityDaemonEnrollAgentResponseSchema = exports_external.object({
|
|
14984
|
+
runnerKey: exports_external.string(),
|
|
14985
|
+
expiresAt: exports_external.string().nullable()
|
|
14986
|
+
});
|
|
14987
|
+
var BotImageUrlSchema = exports_external.string().max(COMMUNITY_BOT_IMAGE_URL_MAX).refine((v) => v.startsWith("https://") || v.startsWith("avatar:"), {
|
|
14988
|
+
message: "image must be an https URL or an avatar: config"
|
|
14989
|
+
});
|
|
14990
|
+
var CommunityBotCreateRequestSchema = exports_external.object({
|
|
14991
|
+
name: exports_external.string().trim().min(COMMUNITY_BOT_NAME_MIN).max(COMMUNITY_BOT_NAME_MAX),
|
|
14992
|
+
description: exports_external.string().max(COMMUNITY_BOT_DESCRIPTION_MAX).optional(),
|
|
14993
|
+
machineId: exports_external.string().min(1),
|
|
14994
|
+
runtime: exports_external.string().min(1),
|
|
14995
|
+
image: BotImageUrlSchema.optional()
|
|
14996
|
+
});
|
|
14997
|
+
var CommunityBotPatchRequestSchema = exports_external.object({
|
|
14998
|
+
name: exports_external.string().trim().min(COMMUNITY_BOT_NAME_MIN).max(COMMUNITY_BOT_NAME_MAX).optional(),
|
|
14999
|
+
description: exports_external.string().max(COMMUNITY_BOT_DESCRIPTION_MAX).optional(),
|
|
15000
|
+
image: BotImageUrlSchema.nullable().optional()
|
|
15001
|
+
}).refine((v) => v.name !== undefined || v.description !== undefined || v.image !== undefined, {
|
|
15002
|
+
message: "at least one field must be provided"
|
|
15003
|
+
});
|
|
15004
|
+
var CommunityBotAddToServerRequestSchema = exports_external.object({
|
|
15005
|
+
botId: exports_external.string().min(1)
|
|
15006
|
+
});
|
|
15007
|
+
var CommunityAgentMessageContentSchema = exports_external.object({ text: exports_external.string().min(1).max(MAX_MESSAGE_CONTENT_LENGTH) }).catchall(exports_external.unknown());
|
|
15008
|
+
var CommunityAgentSeqSchema = exports_external.number().int().min(0);
|
|
15009
|
+
var CommunityAgentPositiveSeqSchema = exports_external.number().int().min(1);
|
|
15010
|
+
var CommunityAgentCursorSchema = exports_external.object({
|
|
15011
|
+
channel: exports_external.string().min(1),
|
|
15012
|
+
seq: CommunityAgentPositiveSeqSchema
|
|
15013
|
+
});
|
|
15014
|
+
var CommunityAgentSendRequestSchema = exports_external.object({
|
|
15015
|
+
channel: exports_external.string().min(1),
|
|
15016
|
+
content: CommunityAgentMessageContentSchema,
|
|
15017
|
+
seenUpToSeq: CommunityAgentSeqSchema.optional()
|
|
15018
|
+
});
|
|
15019
|
+
var CommunityAgentInboxPullRequestSchema = exports_external.object({
|
|
15020
|
+
max: exports_external.number().int().min(1).max(200).optional()
|
|
15021
|
+
});
|
|
15022
|
+
var CommunityAgentAckRequestSchema = exports_external.object({
|
|
15023
|
+
cursors: exports_external.array(CommunityAgentCursorSchema).min(1)
|
|
15024
|
+
});
|
|
15025
|
+
var CommunityAgentReadRequestSchema = exports_external.object({
|
|
15026
|
+
channel: exports_external.string().min(1),
|
|
15027
|
+
before: CommunityAgentSeqSchema.optional(),
|
|
15028
|
+
after: CommunityAgentSeqSchema.optional(),
|
|
15029
|
+
around: CommunityAgentSeqSchema.optional(),
|
|
15030
|
+
limit: exports_external.number().int().min(1).max(200).optional()
|
|
15031
|
+
}).refine((v) => [v.before, v.after, v.around].filter((x) => x !== undefined).length <= 1, { message: "at most one of before/after/around may be supplied" });
|
|
15032
|
+
var CommunityAgentResolveRequestSchema = exports_external.object({
|
|
15033
|
+
channel: exports_external.string().min(1),
|
|
15034
|
+
seq: CommunityAgentSeqSchema
|
|
15035
|
+
});
|
|
15036
|
+
var CommunityAgentListChannelsRequestSchema = exports_external.object({
|
|
15037
|
+
server: exports_external.string().min(1).optional()
|
|
15038
|
+
});
|
|
15039
|
+
// ../../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
15040
|
var entityKind = Symbol.for("drizzle:entityKind");
|
|
14848
15041
|
var hasOwnEntityKind = Symbol.for("drizzle:hasOwnEntityKind");
|
|
14849
15042
|
function is(value, type) {
|
|
@@ -14868,48 +15061,7 @@ function is(value, type) {
|
|
|
14868
15061
|
return false;
|
|
14869
15062
|
}
|
|
14870
15063
|
|
|
14871
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
14872
|
-
var TableName = Symbol.for("drizzle:Name");
|
|
14873
|
-
|
|
14874
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/table.js
|
|
14875
|
-
var Schema = Symbol.for("drizzle:Schema");
|
|
14876
|
-
var Columns = Symbol.for("drizzle:Columns");
|
|
14877
|
-
var ExtraConfigColumns = Symbol.for("drizzle:ExtraConfigColumns");
|
|
14878
|
-
var OriginalName = Symbol.for("drizzle:OriginalName");
|
|
14879
|
-
var BaseName = Symbol.for("drizzle:BaseName");
|
|
14880
|
-
var IsAlias = Symbol.for("drizzle:IsAlias");
|
|
14881
|
-
var ExtraConfigBuilder = Symbol.for("drizzle:ExtraConfigBuilder");
|
|
14882
|
-
var IsDrizzleTable = Symbol.for("drizzle:IsDrizzleTable");
|
|
14883
|
-
|
|
14884
|
-
class Table {
|
|
14885
|
-
static [entityKind] = "Table";
|
|
14886
|
-
static Symbol = {
|
|
14887
|
-
Name: TableName,
|
|
14888
|
-
Schema,
|
|
14889
|
-
OriginalName,
|
|
14890
|
-
Columns,
|
|
14891
|
-
ExtraConfigColumns,
|
|
14892
|
-
BaseName,
|
|
14893
|
-
IsAlias,
|
|
14894
|
-
ExtraConfigBuilder
|
|
14895
|
-
};
|
|
14896
|
-
[TableName];
|
|
14897
|
-
[OriginalName];
|
|
14898
|
-
[Schema];
|
|
14899
|
-
[Columns];
|
|
14900
|
-
[ExtraConfigColumns];
|
|
14901
|
-
[BaseName];
|
|
14902
|
-
[IsAlias] = false;
|
|
14903
|
-
[IsDrizzleTable] = true;
|
|
14904
|
-
[ExtraConfigBuilder] = undefined;
|
|
14905
|
-
constructor(name, schema, baseName) {
|
|
14906
|
-
this[TableName] = this[OriginalName] = name;
|
|
14907
|
-
this[Schema] = schema;
|
|
14908
|
-
this[BaseName] = baseName;
|
|
14909
|
-
}
|
|
14910
|
-
}
|
|
14911
|
-
|
|
14912
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260621.1_@opentelemetry+api@1.9.1_@typ_093d71d59478de43c1b72877af7be041/node_modules/drizzle-orm/column.js
|
|
15064
|
+
// ../../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
15065
|
class Column {
|
|
14914
15066
|
constructor(table, config2) {
|
|
14915
15067
|
this.table = table;
|
|
@@ -14959,7 +15111,7 @@ class Column {
|
|
|
14959
15111
|
}
|
|
14960
15112
|
}
|
|
14961
15113
|
|
|
14962
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15114
|
+
// ../../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
15115
|
class ColumnBuilder {
|
|
14964
15116
|
static [entityKind] = "ColumnBuilder";
|
|
14965
15117
|
config;
|
|
@@ -15015,17 +15167,20 @@ class ColumnBuilder {
|
|
|
15015
15167
|
}
|
|
15016
15168
|
}
|
|
15017
15169
|
|
|
15018
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15170
|
+
// ../../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
|
|
15171
|
+
var TableName = Symbol.for("drizzle:Name");
|
|
15172
|
+
|
|
15173
|
+
// ../../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
15174
|
function iife(fn, ...args) {
|
|
15020
15175
|
return fn(...args);
|
|
15021
15176
|
}
|
|
15022
15177
|
|
|
15023
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15178
|
+
// ../../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
15179
|
function uniqueKeyName(table, columns) {
|
|
15025
15180
|
return `${table[TableName]}_${columns.join("_")}_unique`;
|
|
15026
15181
|
}
|
|
15027
15182
|
|
|
15028
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15183
|
+
// ../../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
15184
|
class PgColumn extends Column {
|
|
15030
15185
|
constructor(table, config2) {
|
|
15031
15186
|
if (!config2.uniqueName) {
|
|
@@ -15074,7 +15229,7 @@ class ExtraConfigColumn extends PgColumn {
|
|
|
15074
15229
|
}
|
|
15075
15230
|
}
|
|
15076
15231
|
|
|
15077
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15232
|
+
// ../../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
15233
|
class PgEnumObjectColumn extends PgColumn {
|
|
15079
15234
|
static [entityKind] = "PgEnumObjectColumn";
|
|
15080
15235
|
enum;
|
|
@@ -15104,7 +15259,7 @@ class PgEnumColumn extends PgColumn {
|
|
|
15104
15259
|
}
|
|
15105
15260
|
}
|
|
15106
15261
|
|
|
15107
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15262
|
+
// ../../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
15263
|
class Subquery {
|
|
15109
15264
|
static [entityKind] = "Subquery";
|
|
15110
15265
|
constructor(sql, fields, alias, isWith = false, usedTables = []) {
|
|
@@ -15119,10 +15274,10 @@ class Subquery {
|
|
|
15119
15274
|
}
|
|
15120
15275
|
}
|
|
15121
15276
|
|
|
15122
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15277
|
+
// ../../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
15278
|
var version2 = "0.45.2";
|
|
15124
15279
|
|
|
15125
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15280
|
+
// ../../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
15281
|
var otel;
|
|
15127
15282
|
var rawTracer;
|
|
15128
15283
|
var tracer = {
|
|
@@ -15149,10 +15304,48 @@ var tracer = {
|
|
|
15149
15304
|
}
|
|
15150
15305
|
};
|
|
15151
15306
|
|
|
15152
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15307
|
+
// ../../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
15308
|
var ViewBaseConfig = Symbol.for("drizzle:ViewBaseConfig");
|
|
15154
15309
|
|
|
15155
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15310
|
+
// ../../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
|
|
15311
|
+
var Schema = Symbol.for("drizzle:Schema");
|
|
15312
|
+
var Columns = Symbol.for("drizzle:Columns");
|
|
15313
|
+
var ExtraConfigColumns = Symbol.for("drizzle:ExtraConfigColumns");
|
|
15314
|
+
var OriginalName = Symbol.for("drizzle:OriginalName");
|
|
15315
|
+
var BaseName = Symbol.for("drizzle:BaseName");
|
|
15316
|
+
var IsAlias = Symbol.for("drizzle:IsAlias");
|
|
15317
|
+
var ExtraConfigBuilder = Symbol.for("drizzle:ExtraConfigBuilder");
|
|
15318
|
+
var IsDrizzleTable = Symbol.for("drizzle:IsDrizzleTable");
|
|
15319
|
+
|
|
15320
|
+
class Table {
|
|
15321
|
+
static [entityKind] = "Table";
|
|
15322
|
+
static Symbol = {
|
|
15323
|
+
Name: TableName,
|
|
15324
|
+
Schema,
|
|
15325
|
+
OriginalName,
|
|
15326
|
+
Columns,
|
|
15327
|
+
ExtraConfigColumns,
|
|
15328
|
+
BaseName,
|
|
15329
|
+
IsAlias,
|
|
15330
|
+
ExtraConfigBuilder
|
|
15331
|
+
};
|
|
15332
|
+
[TableName];
|
|
15333
|
+
[OriginalName];
|
|
15334
|
+
[Schema];
|
|
15335
|
+
[Columns];
|
|
15336
|
+
[ExtraConfigColumns];
|
|
15337
|
+
[BaseName];
|
|
15338
|
+
[IsAlias] = false;
|
|
15339
|
+
[IsDrizzleTable] = true;
|
|
15340
|
+
[ExtraConfigBuilder] = undefined;
|
|
15341
|
+
constructor(name, schema, baseName) {
|
|
15342
|
+
this[TableName] = this[OriginalName] = name;
|
|
15343
|
+
this[Schema] = schema;
|
|
15344
|
+
this[BaseName] = baseName;
|
|
15345
|
+
}
|
|
15346
|
+
}
|
|
15347
|
+
|
|
15348
|
+
// ../../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
15349
|
function isSQLWrapper(value) {
|
|
15157
15350
|
return value !== null && value !== undefined && typeof value.getSQL === "function";
|
|
15158
15351
|
}
|
|
@@ -15512,7 +15705,7 @@ Subquery.prototype.getSQL = function() {
|
|
|
15512
15705
|
return new SQL([this]);
|
|
15513
15706
|
};
|
|
15514
15707
|
|
|
15515
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15708
|
+
// ../../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
15709
|
function getColumnNameAndConfig(a, b) {
|
|
15517
15710
|
return {
|
|
15518
15711
|
name: typeof a === "string" && a.length > 0 ? a : "",
|
|
@@ -15521,7 +15714,32 @@ function getColumnNameAndConfig(a, b) {
|
|
|
15521
15714
|
}
|
|
15522
15715
|
var textDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder;
|
|
15523
15716
|
|
|
15524
|
-
//
|
|
15717
|
+
// ../shared/src/db/community-schema.ts
|
|
15718
|
+
var exports_community_schema = {};
|
|
15719
|
+
__export(exports_community_schema, {
|
|
15720
|
+
communityUserProfile: () => communityUserProfile,
|
|
15721
|
+
communityServerMember: () => communityServerMember,
|
|
15722
|
+
communityServerInvite: () => communityServerInvite,
|
|
15723
|
+
communityServerFolderItem: () => communityServerFolderItem,
|
|
15724
|
+
communityServerFolder: () => communityServerFolder,
|
|
15725
|
+
communityServer: () => communityServer,
|
|
15726
|
+
communityReadState: () => communityReadState,
|
|
15727
|
+
communityReaction: () => communityReaction,
|
|
15728
|
+
communityPin: () => communityPin,
|
|
15729
|
+
communityNotificationSetting: () => communityNotificationSetting,
|
|
15730
|
+
communityMessageSeq: () => communityMessageSeq,
|
|
15731
|
+
communityMessage: () => communityMessage,
|
|
15732
|
+
communityMention: () => communityMention,
|
|
15733
|
+
communityFriendship: () => communityFriendship,
|
|
15734
|
+
communityDmConversation: () => communityDmConversation,
|
|
15735
|
+
communityChannel: () => communityChannel,
|
|
15736
|
+
communityCategory: () => communityCategory,
|
|
15737
|
+
communityBotApprovalRequest: () => communityBotApprovalRequest,
|
|
15738
|
+
communityAuditLog: () => communityAuditLog,
|
|
15739
|
+
communityAttachment: () => communityAttachment
|
|
15740
|
+
});
|
|
15741
|
+
|
|
15742
|
+
// ../../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
15743
|
class ForeignKeyBuilder {
|
|
15526
15744
|
static [entityKind] = "SQLiteForeignKeyBuilder";
|
|
15527
15745
|
reference;
|
|
@@ -15589,7 +15807,7 @@ function foreignKey(config2) {
|
|
|
15589
15807
|
return new ForeignKeyBuilder(mappedConfig);
|
|
15590
15808
|
}
|
|
15591
15809
|
|
|
15592
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15810
|
+
// ../../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
15811
|
function uniqueKeyName2(table, columns) {
|
|
15594
15812
|
return `${table[TableName]}_${columns.join("_")}_unique`;
|
|
15595
15813
|
}
|
|
@@ -15634,7 +15852,7 @@ class UniqueConstraint {
|
|
|
15634
15852
|
}
|
|
15635
15853
|
}
|
|
15636
15854
|
|
|
15637
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15855
|
+
// ../../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
15856
|
class SQLiteColumnBuilder extends ColumnBuilder {
|
|
15639
15857
|
static [entityKind] = "SQLiteColumnBuilder";
|
|
15640
15858
|
foreignKeyConfigs = [];
|
|
@@ -15685,7 +15903,7 @@ class SQLiteColumn extends Column {
|
|
|
15685
15903
|
static [entityKind] = "SQLiteColumn";
|
|
15686
15904
|
}
|
|
15687
15905
|
|
|
15688
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15906
|
+
// ../../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
15907
|
class SQLiteBigIntBuilder extends SQLiteColumnBuilder {
|
|
15690
15908
|
static [entityKind] = "SQLiteBigIntBuilder";
|
|
15691
15909
|
constructor(name) {
|
|
@@ -15773,7 +15991,7 @@ function blob(a, b) {
|
|
|
15773
15991
|
return new SQLiteBlobBufferBuilder(name);
|
|
15774
15992
|
}
|
|
15775
15993
|
|
|
15776
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
15994
|
+
// ../../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
15995
|
class SQLiteCustomColumnBuilder extends SQLiteColumnBuilder {
|
|
15778
15996
|
static [entityKind] = "SQLiteCustomColumnBuilder";
|
|
15779
15997
|
constructor(name, fieldConfig, customTypeParams) {
|
|
@@ -15814,7 +16032,7 @@ function customType(customTypeParams) {
|
|
|
15814
16032
|
};
|
|
15815
16033
|
}
|
|
15816
16034
|
|
|
15817
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
16035
|
+
// ../../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
16036
|
class SQLiteBaseIntegerBuilder extends SQLiteColumnBuilder {
|
|
15819
16037
|
static [entityKind] = "SQLiteBaseIntegerBuilder";
|
|
15820
16038
|
constructor(name, dataType, columnType) {
|
|
@@ -15916,7 +16134,7 @@ function integer2(a, b) {
|
|
|
15916
16134
|
return new SQLiteIntegerBuilder(name);
|
|
15917
16135
|
}
|
|
15918
16136
|
|
|
15919
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
16137
|
+
// ../../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
16138
|
class SQLiteNumericBuilder extends SQLiteColumnBuilder {
|
|
15921
16139
|
static [entityKind] = "SQLiteNumericBuilder";
|
|
15922
16140
|
constructor(name) {
|
|
@@ -15986,7 +16204,7 @@ function numeric(a, b) {
|
|
|
15986
16204
|
return mode === "number" ? new SQLiteNumericNumberBuilder(name) : mode === "bigint" ? new SQLiteNumericBigIntBuilder(name) : new SQLiteNumericBuilder(name);
|
|
15987
16205
|
}
|
|
15988
16206
|
|
|
15989
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
16207
|
+
// ../../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
16208
|
class SQLiteRealBuilder extends SQLiteColumnBuilder {
|
|
15991
16209
|
static [entityKind] = "SQLiteRealBuilder";
|
|
15992
16210
|
constructor(name) {
|
|
@@ -16007,7 +16225,7 @@ function real(name) {
|
|
|
16007
16225
|
return new SQLiteRealBuilder(name ?? "");
|
|
16008
16226
|
}
|
|
16009
16227
|
|
|
16010
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
16228
|
+
// ../../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
16229
|
class SQLiteTextBuilder extends SQLiteColumnBuilder {
|
|
16012
16230
|
static [entityKind] = "SQLiteTextBuilder";
|
|
16013
16231
|
constructor(name, config2) {
|
|
@@ -16062,7 +16280,7 @@ function text(a, b = {}) {
|
|
|
16062
16280
|
return new SQLiteTextBuilder(name, config2);
|
|
16063
16281
|
}
|
|
16064
16282
|
|
|
16065
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
16283
|
+
// ../../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
16284
|
function getSQLiteColumnBuilders() {
|
|
16067
16285
|
return {
|
|
16068
16286
|
blob,
|
|
@@ -16074,7 +16292,7 @@ function getSQLiteColumnBuilders() {
|
|
|
16074
16292
|
};
|
|
16075
16293
|
}
|
|
16076
16294
|
|
|
16077
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
16295
|
+
// ../../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
16296
|
var InlineForeignKeys = Symbol.for("drizzle:SQLiteInlineForeignKeys");
|
|
16079
16297
|
|
|
16080
16298
|
class SQLiteTable extends Table {
|
|
@@ -16108,7 +16326,7 @@ var sqliteTable = (name, columns, extraConfig) => {
|
|
|
16108
16326
|
return sqliteTableBase(name, columns, extraConfig);
|
|
16109
16327
|
};
|
|
16110
16328
|
|
|
16111
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
16329
|
+
// ../../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
16330
|
class IndexBuilderOn {
|
|
16113
16331
|
constructor(name, unique2) {
|
|
16114
16332
|
this.name = name;
|
|
@@ -16150,8 +16368,11 @@ class Index {
|
|
|
16150
16368
|
function index(name) {
|
|
16151
16369
|
return new IndexBuilderOn(name, false);
|
|
16152
16370
|
}
|
|
16371
|
+
function uniqueIndex(name) {
|
|
16372
|
+
return new IndexBuilderOn(name, true);
|
|
16373
|
+
}
|
|
16153
16374
|
|
|
16154
|
-
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.
|
|
16375
|
+
// ../../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
16376
|
function primaryKey(...config2) {
|
|
16156
16377
|
if (config2[0].columns) {
|
|
16157
16378
|
return new PrimaryKeyBuilder(config2[0].columns, config2[0].name);
|
|
@@ -16186,44 +16407,48 @@ class PrimaryKey {
|
|
|
16186
16407
|
}
|
|
16187
16408
|
}
|
|
16188
16409
|
|
|
16189
|
-
//
|
|
16190
|
-
|
|
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
|
-
}
|
|
16410
|
+
// ../shared/src/db/community-schema.ts
|
|
16411
|
+
init_nanoid();
|
|
16225
16412
|
|
|
16226
16413
|
// ../shared/src/db/schema.ts
|
|
16414
|
+
var exports_schema = {};
|
|
16415
|
+
__export(exports_schema, {
|
|
16416
|
+
workspaceInvite: () => workspaceInvite,
|
|
16417
|
+
workspaceFileRequest: () => workspaceFileRequest,
|
|
16418
|
+
workspace: () => workspace,
|
|
16419
|
+
verification: () => verification,
|
|
16420
|
+
user: () => user,
|
|
16421
|
+
taskMessage: () => taskMessage,
|
|
16422
|
+
session: () => session,
|
|
16423
|
+
messageFlag: () => messageFlag,
|
|
16424
|
+
message: () => message,
|
|
16425
|
+
member: () => member,
|
|
16426
|
+
meetingSession: () => meetingSession,
|
|
16427
|
+
machineToken: () => machineToken,
|
|
16428
|
+
machine: () => machine,
|
|
16429
|
+
issueComment: () => issueComment,
|
|
16430
|
+
issue: () => issue2,
|
|
16431
|
+
inboxUnread: () => inboxUnread,
|
|
16432
|
+
emails: () => emails,
|
|
16433
|
+
conversationReadState: () => conversationReadState,
|
|
16434
|
+
conversationMap: () => conversationMap,
|
|
16435
|
+
conversation: () => conversation,
|
|
16436
|
+
channel: () => channel,
|
|
16437
|
+
calendarEvent: () => calendarEvent,
|
|
16438
|
+
artifact: () => artifact,
|
|
16439
|
+
agentWhitelist: () => agentWhitelist,
|
|
16440
|
+
agentTaskQueue: () => agentTaskQueue,
|
|
16441
|
+
agentSkill: () => agentSkill,
|
|
16442
|
+
agentSidebarOrder: () => agentSidebarOrder,
|
|
16443
|
+
agentRuntime: () => agentRuntime,
|
|
16444
|
+
agentPin: () => agentPin,
|
|
16445
|
+
agentLink: () => agentLink,
|
|
16446
|
+
agentEmailAccount: () => agentEmailAccount,
|
|
16447
|
+
agentAccess: () => agentAccess,
|
|
16448
|
+
agent: () => agent,
|
|
16449
|
+
account: () => account
|
|
16450
|
+
});
|
|
16451
|
+
init_nanoid();
|
|
16227
16452
|
var user = sqliteTable("user", {
|
|
16228
16453
|
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
16229
16454
|
name: text("name").notNull().default(""),
|
|
@@ -16231,8 +16456,12 @@ var user = sqliteTable("user", {
|
|
|
16231
16456
|
emailVerified: integer2("emailVerified", { mode: "boolean" }),
|
|
16232
16457
|
image: text("image"),
|
|
16233
16458
|
createdAt: text("createdAt").notNull().$defaultFn(() => new Date().toISOString()),
|
|
16234
|
-
updatedAt: text("updatedAt").notNull().$defaultFn(() => new Date().toISOString())
|
|
16235
|
-
})
|
|
16459
|
+
updatedAt: text("updatedAt").notNull().$defaultFn(() => new Date().toISOString()),
|
|
16460
|
+
isBot: integer2("isBot", { mode: "boolean" }).notNull().default(false),
|
|
16461
|
+
ownerUserId: text("ownerUserId"),
|
|
16462
|
+
deletedAt: text("deletedAt"),
|
|
16463
|
+
discriminator: text("discriminator").notNull().default("0000")
|
|
16464
|
+
}, (t) => [index("idx_user_ownerUserId_isBot").on(t.ownerUserId, t.isBot)]);
|
|
16236
16465
|
var session = sqliteTable("session", {
|
|
16237
16466
|
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
16238
16467
|
userId: text("userId").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
@@ -16768,84 +16997,518 @@ var inboxUnread = sqliteTable("inbox_unread", {
|
|
|
16768
16997
|
unique("inbox_unread_conv_user").on(t.conversationId, t.userId),
|
|
16769
16998
|
index("idx_inbox_unread_user_ws").on(t.userId, t.workspaceId, t.taskType, t.completedAt)
|
|
16770
16999
|
]);
|
|
16771
|
-
|
|
16772
|
-
|
|
16773
|
-
var
|
|
16774
|
-
|
|
16775
|
-
|
|
16776
|
-
|
|
16777
|
-
"
|
|
16778
|
-
"
|
|
16779
|
-
"
|
|
16780
|
-
|
|
16781
|
-
|
|
16782
|
-
"
|
|
16783
|
-
"
|
|
16784
|
-
"
|
|
16785
|
-
"
|
|
16786
|
-
"
|
|
16787
|
-
"
|
|
16788
|
-
|
|
16789
|
-
|
|
16790
|
-
"
|
|
16791
|
-
"
|
|
17000
|
+
|
|
17001
|
+
// ../shared/src/db/community-schema.ts
|
|
17002
|
+
var communityServer = sqliteTable("community_server", {
|
|
17003
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17004
|
+
name: text("name").notNull(),
|
|
17005
|
+
description: text("description").default(""),
|
|
17006
|
+
icon: text("icon"),
|
|
17007
|
+
ownerId: text("owner_id").notNull().references(() => user.id, { onDelete: "restrict" }),
|
|
17008
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17009
|
+
});
|
|
17010
|
+
var communityCategory = sqliteTable("community_category", {
|
|
17011
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17012
|
+
serverId: text("server_id").notNull().references(() => communityServer.id, { onDelete: "cascade" }),
|
|
17013
|
+
name: text("name").notNull(),
|
|
17014
|
+
position: integer2("position").default(0),
|
|
17015
|
+
private: integer2("private").default(0),
|
|
17016
|
+
creatorId: text("creator_id").references(() => user.id, { onDelete: "set null" })
|
|
17017
|
+
}, (t) => [unique("uq_category_server_name").on(t.serverId, t.name)]);
|
|
17018
|
+
var communityChannel = sqliteTable("community_channel", {
|
|
17019
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17020
|
+
serverId: text("server_id").notNull().references(() => communityServer.id, { onDelete: "cascade" }),
|
|
17021
|
+
categoryId: text("category_id").references(() => communityCategory.id, {
|
|
17022
|
+
onDelete: "set null"
|
|
17023
|
+
}),
|
|
17024
|
+
name: text("name").notNull(),
|
|
17025
|
+
type: text("type").notNull().default("text"),
|
|
17026
|
+
topic: text("topic").default(""),
|
|
17027
|
+
position: integer2("position").default(0),
|
|
17028
|
+
forumTags: text("forum_tags"),
|
|
17029
|
+
parentChannelId: text("parent_channel_id").references(() => communityChannel.id, {
|
|
17030
|
+
onDelete: "cascade"
|
|
17031
|
+
}),
|
|
17032
|
+
creatorId: text("creator_id").references(() => user.id, { onDelete: "set null" }),
|
|
17033
|
+
messageCount: integer2("message_count").default(0),
|
|
17034
|
+
archived: integer2("archived").default(0),
|
|
17035
|
+
parentMessageId: text("parent_message_id"),
|
|
17036
|
+
lastMessageAt: text("last_message_at"),
|
|
17037
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17038
|
+
}, (t) => [
|
|
17039
|
+
index("idx_channel_server_position").on(t.serverId, t.position),
|
|
17040
|
+
index("idx_channel_server_last_message").on(t.serverId, t.lastMessageAt),
|
|
17041
|
+
index("idx_channel_parent").on(t.parentChannelId)
|
|
16792
17042
|
]);
|
|
16793
|
-
|
|
16794
|
-
|
|
16795
|
-
}
|
|
16796
|
-
|
|
16797
|
-
|
|
16798
|
-
|
|
16799
|
-
|
|
16800
|
-
|
|
16801
|
-
|
|
16802
|
-
|
|
16803
|
-
|
|
16804
|
-
|
|
16805
|
-
|
|
16806
|
-
|
|
16807
|
-
|
|
16808
|
-
|
|
16809
|
-
|
|
16810
|
-
|
|
16811
|
-
|
|
16812
|
-
|
|
16813
|
-
|
|
16814
|
-
|
|
16815
|
-
|
|
16816
|
-
}
|
|
16817
|
-
|
|
16818
|
-
|
|
16819
|
-
|
|
16820
|
-
|
|
16821
|
-
|
|
16822
|
-
|
|
16823
|
-
|
|
16824
|
-
|
|
16825
|
-
|
|
16826
|
-
|
|
16827
|
-
|
|
16828
|
-
|
|
16829
|
-
|
|
16830
|
-
|
|
16831
|
-
|
|
16832
|
-
|
|
16833
|
-
|
|
16834
|
-
|
|
16835
|
-
|
|
16836
|
-
|
|
16837
|
-
|
|
16838
|
-
|
|
16839
|
-
|
|
16840
|
-
|
|
16841
|
-
|
|
16842
|
-
|
|
16843
|
-
}
|
|
16844
|
-
|
|
16845
|
-
|
|
16846
|
-
|
|
16847
|
-
|
|
16848
|
-
|
|
17043
|
+
var communityDmConversation = sqliteTable("community_dm_conversation", {
|
|
17044
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17045
|
+
user1Id: text("user1_id").references(() => user.id, { onDelete: "set null" }),
|
|
17046
|
+
user2Id: text("user2_id").references(() => user.id, { onDelete: "set null" }),
|
|
17047
|
+
lastMessageAt: text("last_message_at"),
|
|
17048
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17049
|
+
}, (t) => [
|
|
17050
|
+
unique("uq_dm_conversation_users").on(t.user1Id, t.user2Id),
|
|
17051
|
+
index("idx_dm_conversation_user1_last_message").on(t.user1Id, t.lastMessageAt),
|
|
17052
|
+
index("idx_dm_conversation_user2_last_message").on(t.user2Id, t.lastMessageAt)
|
|
17053
|
+
]);
|
|
17054
|
+
var communityMessage = sqliteTable("community_message", {
|
|
17055
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17056
|
+
authorId: text("author_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17057
|
+
content: text("content").notNull().default(""),
|
|
17058
|
+
type: text("type").notNull().default("default"),
|
|
17059
|
+
mentionType: text("mention_type"),
|
|
17060
|
+
replyToId: text("reply_to_id"),
|
|
17061
|
+
embeds: text("embeds"),
|
|
17062
|
+
flags: integer2("flags").default(0),
|
|
17063
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
17064
|
+
channelId: text("channel_id").references(() => communityChannel.id, {
|
|
17065
|
+
onDelete: "cascade"
|
|
17066
|
+
}),
|
|
17067
|
+
dmConversationId: text("dm_conversation_id").references(() => communityDmConversation.id, { onDelete: "cascade" }),
|
|
17068
|
+
seq: integer2("seq").notNull().default(0)
|
|
17069
|
+
}, (t) => [
|
|
17070
|
+
index("idx_message_channel_created").on(t.channelId, t.createdAt),
|
|
17071
|
+
index("idx_message_channel_mention_created").on(t.channelId, t.mentionType, t.createdAt),
|
|
17072
|
+
index("idx_message_dm_created").on(t.dmConversationId, t.createdAt)
|
|
17073
|
+
]);
|
|
17074
|
+
var communityMessageSeq = sqliteTable("community_message_seq", {
|
|
17075
|
+
scopeKey: text("scope_key").primaryKey(),
|
|
17076
|
+
nextSeq: integer2("next_seq").notNull()
|
|
17077
|
+
});
|
|
17078
|
+
var communityServerMember = sqliteTable("community_server_member", {
|
|
17079
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17080
|
+
serverId: text("server_id").notNull().references(() => communityServer.id, { onDelete: "cascade" }),
|
|
17081
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17082
|
+
role: text("role").default("member"),
|
|
17083
|
+
nickname: text("nickname"),
|
|
17084
|
+
railOrder: integer2("rail_order").default(0),
|
|
17085
|
+
joinedAt: text("joined_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17086
|
+
}, (t) => [
|
|
17087
|
+
unique("uq_server_member_server_user").on(t.serverId, t.userId),
|
|
17088
|
+
index("idx_server_member_user").on(t.userId),
|
|
17089
|
+
index("idx_server_member_user_rail_order").on(t.userId, t.railOrder)
|
|
17090
|
+
]);
|
|
17091
|
+
var communityServerFolder = sqliteTable("community_server_folder", {
|
|
17092
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17093
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17094
|
+
name: text("name").notNull(),
|
|
17095
|
+
position: integer2("position").default(0)
|
|
17096
|
+
}, (t) => [index("idx_server_folder_user_position").on(t.userId, t.position)]);
|
|
17097
|
+
var communityServerFolderItem = sqliteTable("community_server_folder_item", {
|
|
17098
|
+
folderId: text("folder_id").notNull().references(() => communityServerFolder.id, { onDelete: "cascade" }),
|
|
17099
|
+
serverId: text("server_id").notNull().references(() => communityServer.id, { onDelete: "cascade" }),
|
|
17100
|
+
position: integer2("position").default(0)
|
|
17101
|
+
}, (t) => [
|
|
17102
|
+
primaryKey({ columns: [t.folderId, t.serverId] }),
|
|
17103
|
+
index("idx_server_folder_item_folder_position").on(t.folderId, t.position)
|
|
17104
|
+
]);
|
|
17105
|
+
var communityServerInvite = sqliteTable("community_server_invite", {
|
|
17106
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17107
|
+
serverId: text("server_id").notNull().references(() => communityServer.id, { onDelete: "cascade" }),
|
|
17108
|
+
createdBy: text("created_by").references(() => user.id, { onDelete: "set null" }),
|
|
17109
|
+
token: text("token").unique().notNull().$defaultFn(() => nanoid3(10)),
|
|
17110
|
+
maxUses: integer2("max_uses"),
|
|
17111
|
+
uses: integer2("uses").default(0),
|
|
17112
|
+
expiresAt: text("expires_at"),
|
|
17113
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17114
|
+
});
|
|
17115
|
+
var communityFriendship = sqliteTable("community_friendship", {
|
|
17116
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17117
|
+
requesterId: text("requester_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17118
|
+
addresseeId: text("addressee_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17119
|
+
status: text("status").notNull().default("pending"),
|
|
17120
|
+
blockerId: text("blocker_id"),
|
|
17121
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
17122
|
+
updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17123
|
+
}, (t) => [
|
|
17124
|
+
unique("uq_friendship_requester_addressee").on(t.requesterId, t.addresseeId),
|
|
17125
|
+
index("idx_friendship_addressee_status").on(t.addresseeId, t.status),
|
|
17126
|
+
index("idx_friendship_requester_status").on(t.requesterId, t.status)
|
|
17127
|
+
]);
|
|
17128
|
+
var communityReadState = sqliteTable("community_read_state", {
|
|
17129
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17130
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17131
|
+
channelId: text("channel_id").references(() => communityChannel.id, {
|
|
17132
|
+
onDelete: "cascade"
|
|
17133
|
+
}),
|
|
17134
|
+
dmConversationId: text("dm_conversation_id").references(() => communityDmConversation.id, { onDelete: "cascade" }),
|
|
17135
|
+
lastReadAt: text("last_read_at").notNull(),
|
|
17136
|
+
lastReadMessageId: text("last_read_message_id"),
|
|
17137
|
+
lastReadSeq: integer2("last_read_seq").notNull().default(0)
|
|
17138
|
+
}, (t) => [index("idx_read_state_user").on(t.userId)]);
|
|
17139
|
+
var communityReaction = sqliteTable("community_reaction", {
|
|
17140
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17141
|
+
messageId: text("message_id").notNull().references(() => communityMessage.id, { onDelete: "cascade" }),
|
|
17142
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17143
|
+
emoji: text("emoji").notNull(),
|
|
17144
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17145
|
+
}, (t) => [
|
|
17146
|
+
unique("uq_reaction_message_user_emoji").on(t.messageId, t.userId, t.emoji),
|
|
17147
|
+
index("idx_reaction_message").on(t.messageId)
|
|
17148
|
+
]);
|
|
17149
|
+
var communityAttachment = sqliteTable("community_attachment", {
|
|
17150
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17151
|
+
messageId: text("message_id").notNull().references(() => communityMessage.id, { onDelete: "cascade" }),
|
|
17152
|
+
filename: text("filename").notNull(),
|
|
17153
|
+
url: text("url").notNull(),
|
|
17154
|
+
contentType: text("content_type"),
|
|
17155
|
+
size: integer2("size"),
|
|
17156
|
+
width: integer2("width"),
|
|
17157
|
+
height: integer2("height"),
|
|
17158
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17159
|
+
}, (t) => [index("idx_attachment_message").on(t.messageId)]);
|
|
17160
|
+
var communityPin = sqliteTable("community_pin", {
|
|
17161
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17162
|
+
channelId: text("channel_id").notNull().references(() => communityChannel.id, { onDelete: "cascade" }),
|
|
17163
|
+
messageId: text("message_id").notNull().references(() => communityMessage.id, { onDelete: "cascade" }),
|
|
17164
|
+
pinnedBy: text("pinned_by").references(() => user.id, { onDelete: "set null" }),
|
|
17165
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17166
|
+
}, (t) => [
|
|
17167
|
+
unique("uq_pin_channel_message").on(t.channelId, t.messageId),
|
|
17168
|
+
index("idx_pin_channel").on(t.channelId)
|
|
17169
|
+
]);
|
|
17170
|
+
var communityMention = sqliteTable("community_mention", {
|
|
17171
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17172
|
+
messageId: text("message_id").notNull().references(() => communityMessage.id, { onDelete: "cascade" }),
|
|
17173
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17174
|
+
kind: text("kind").notNull().default("mention"),
|
|
17175
|
+
read: integer2("read").default(0)
|
|
17176
|
+
}, (t) => [
|
|
17177
|
+
index("idx_mention_user_read").on(t.userId, t.read),
|
|
17178
|
+
index("idx_mention_message").on(t.messageId)
|
|
17179
|
+
]);
|
|
17180
|
+
var communityUserProfile = sqliteTable("community_user_profile", {
|
|
17181
|
+
userId: text("user_id").primaryKey().references(() => user.id, { onDelete: "cascade" }),
|
|
17182
|
+
aboutMe: text("about_me").default(""),
|
|
17183
|
+
bannerColor: text("banner_color")
|
|
17184
|
+
});
|
|
17185
|
+
var communityNotificationSetting = sqliteTable("community_notification_setting", {
|
|
17186
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17187
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17188
|
+
serverId: text("server_id").references(() => communityServer.id, {
|
|
17189
|
+
onDelete: "cascade"
|
|
17190
|
+
}),
|
|
17191
|
+
channelId: text("channel_id").references(() => communityChannel.id, {
|
|
17192
|
+
onDelete: "cascade"
|
|
17193
|
+
}),
|
|
17194
|
+
level: text("level").notNull().default("all")
|
|
17195
|
+
}, (t) => [index("idx_notification_setting_user").on(t.userId)]);
|
|
17196
|
+
var communityAuditLog = sqliteTable("community_audit_log", {
|
|
17197
|
+
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17198
|
+
serverId: text("server_id").references(() => communityServer.id, {
|
|
17199
|
+
onDelete: "cascade"
|
|
17200
|
+
}),
|
|
17201
|
+
actorId: text("actor_id").references(() => user.id, { onDelete: "set null" }),
|
|
17202
|
+
action: text("action").notNull(),
|
|
17203
|
+
targetType: text("target_type").notNull(),
|
|
17204
|
+
targetId: text("target_id").notNull(),
|
|
17205
|
+
changes: text("changes"),
|
|
17206
|
+
reason: text("reason"),
|
|
17207
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17208
|
+
}, (t) => [
|
|
17209
|
+
index("idx_audit_log_server_created").on(t.serverId, t.createdAt),
|
|
17210
|
+
index("idx_audit_log_server_action").on(t.serverId, t.action),
|
|
17211
|
+
index("idx_audit_log_actor_created").on(t.actorId, t.createdAt)
|
|
17212
|
+
]);
|
|
17213
|
+
var communityBotApprovalRequest = sqliteTable("community_bot_approval_request", {
|
|
17214
|
+
id: text("id").primaryKey().$defaultFn(() => "bar_" + nanoid3()),
|
|
17215
|
+
botId: text("bot_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17216
|
+
kind: text("kind").notNull(),
|
|
17217
|
+
serverId: text("server_id").references(() => communityServer.id, {
|
|
17218
|
+
onDelete: "cascade"
|
|
17219
|
+
}),
|
|
17220
|
+
requestedByUserId: text("requested_by_user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17221
|
+
dmMessageId: text("dm_message_id").notNull().references(() => communityMessage.id, { onDelete: "cascade" }),
|
|
17222
|
+
status: text("status").notNull().default("pending"),
|
|
17223
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
17224
|
+
resolvedAt: text("resolved_at")
|
|
17225
|
+
}, (t) => [index("idx_community_bot_approval_bot").on(t.botId, t.status)]);
|
|
17226
|
+
|
|
17227
|
+
// ../shared/src/logger.ts
|
|
17228
|
+
var LEVELS = {
|
|
17229
|
+
debug: 0,
|
|
17230
|
+
info: 1,
|
|
17231
|
+
warn: 2,
|
|
17232
|
+
error: 3,
|
|
17233
|
+
silent: 4
|
|
17234
|
+
};
|
|
17235
|
+
|
|
17236
|
+
class Logger {
|
|
17237
|
+
service;
|
|
17238
|
+
level;
|
|
17239
|
+
pretty;
|
|
17240
|
+
fields;
|
|
17241
|
+
constructor(opts, fields) {
|
|
17242
|
+
this.service = opts.service;
|
|
17243
|
+
this.level = LEVELS[opts.level ?? "info"];
|
|
17244
|
+
this.pretty = opts.pretty ?? false;
|
|
17245
|
+
this.fields = fields ?? {};
|
|
17246
|
+
}
|
|
17247
|
+
debug(msg, ctx) {
|
|
17248
|
+
this.write("debug", msg, ctx);
|
|
17249
|
+
}
|
|
17250
|
+
info(msg, ctx) {
|
|
17251
|
+
this.write("info", msg, ctx);
|
|
17252
|
+
}
|
|
17253
|
+
warn(msg, ctx) {
|
|
17254
|
+
this.write("warn", msg, ctx);
|
|
17255
|
+
}
|
|
17256
|
+
error(msg, ctx) {
|
|
17257
|
+
this.write("error", msg, ctx);
|
|
17258
|
+
}
|
|
17259
|
+
child(fields) {
|
|
17260
|
+
const merged = { ...this.fields, ...fields };
|
|
17261
|
+
const child = new Logger({ service: this.service, level: this.levelName(), pretty: this.pretty }, merged);
|
|
17262
|
+
return child;
|
|
17263
|
+
}
|
|
17264
|
+
levelName() {
|
|
17265
|
+
for (const [name, num] of Object.entries(LEVELS)) {
|
|
17266
|
+
if (num === this.level)
|
|
17267
|
+
return name;
|
|
17268
|
+
}
|
|
17269
|
+
return "info";
|
|
17270
|
+
}
|
|
17271
|
+
write(level, msg, ctx) {
|
|
17272
|
+
if (LEVELS[level] < this.level)
|
|
17273
|
+
return;
|
|
17274
|
+
const entry = {
|
|
17275
|
+
level,
|
|
17276
|
+
msg,
|
|
17277
|
+
service: this.service,
|
|
17278
|
+
...this.fields,
|
|
17279
|
+
...ctx,
|
|
17280
|
+
ts: new Date().toISOString()
|
|
17281
|
+
};
|
|
17282
|
+
for (const [k, v] of Object.entries(entry)) {
|
|
17283
|
+
if (v instanceof Error) {
|
|
17284
|
+
entry[k] = { message: v.message, stack: v.stack };
|
|
17285
|
+
}
|
|
17286
|
+
}
|
|
17287
|
+
let line;
|
|
17288
|
+
if (this.pretty) {
|
|
17289
|
+
const ts = entry.ts.replace("T", " ").replace("Z", "");
|
|
17290
|
+
const lvl = entry.level.toUpperCase().padEnd(5);
|
|
17291
|
+
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(" ");
|
|
17292
|
+
line = `${ts} ${lvl} [${entry.service}] ${entry.msg}${pairs ? " " + pairs : ""}`;
|
|
17293
|
+
} else {
|
|
17294
|
+
line = JSON.stringify(entry);
|
|
17295
|
+
}
|
|
17296
|
+
if (level === "error") {
|
|
17297
|
+
console.error(line);
|
|
17298
|
+
} else {
|
|
17299
|
+
console.log(line);
|
|
17300
|
+
}
|
|
17301
|
+
}
|
|
17302
|
+
}
|
|
17303
|
+
function createLogger(opts) {
|
|
17304
|
+
return new Logger(opts);
|
|
17305
|
+
}
|
|
17306
|
+
|
|
17307
|
+
// ../shared/src/db/queries/community/message.ts
|
|
17308
|
+
var log = createLogger({ service: "community-queries" });
|
|
17309
|
+
|
|
17310
|
+
// ../shared/src/db/community-machine-schema.ts
|
|
17311
|
+
var exports_community_machine_schema = {};
|
|
17312
|
+
__export(exports_community_machine_schema, {
|
|
17313
|
+
communityMachineToken: () => communityMachineToken,
|
|
17314
|
+
communityMachineCredential: () => communityMachineCredential,
|
|
17315
|
+
communityMachine: () => communityMachine,
|
|
17316
|
+
communityBotBinding: () => communityBotBinding,
|
|
17317
|
+
communityAgentRunnerKey: () => communityAgentRunnerKey
|
|
17318
|
+
});
|
|
17319
|
+
init_nanoid();
|
|
17320
|
+
var communityMachineToken = sqliteTable("community_machine_token", {
|
|
17321
|
+
id: text("id").primaryKey().$defaultFn(() => "cmt_" + nanoid3(32)),
|
|
17322
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17323
|
+
machineId: text("machine_id"),
|
|
17324
|
+
status: text("status").notNull().default("pending"),
|
|
17325
|
+
expiresAt: text("expires_at").notNull(),
|
|
17326
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
17327
|
+
lastUsedAt: text("last_used_at")
|
|
17328
|
+
}, (t) => [
|
|
17329
|
+
index("idx_community_machine_token_user_status").on(t.userId, t.status),
|
|
17330
|
+
uniqueIndex("uq_community_machine_token_user_pending").on(t.userId).where(sql`status = 'pending'`)
|
|
17331
|
+
]);
|
|
17332
|
+
var communityMachine = sqliteTable("community_machine", {
|
|
17333
|
+
id: text("id").primaryKey().$defaultFn(() => "cm_" + nanoid3()),
|
|
17334
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17335
|
+
displayName: text("display_name").notNull().default(""),
|
|
17336
|
+
hostname: text("hostname").notNull().default(""),
|
|
17337
|
+
platform: text("platform").notNull().default(""),
|
|
17338
|
+
arch: text("arch").notNull().default(""),
|
|
17339
|
+
osRelease: text("os_release").notNull().default(""),
|
|
17340
|
+
daemonVersion: text("daemon_version").notNull().default(""),
|
|
17341
|
+
metadata: text("metadata"),
|
|
17342
|
+
availableRuntimes: text("available_runtimes", { mode: "json" }).$type().notNull().default([]),
|
|
17343
|
+
status: text("status").notNull().default("offline"),
|
|
17344
|
+
lastSeenAt: text("last_seen_at"),
|
|
17345
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
17346
|
+
updatedAt: text("updated_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17347
|
+
}, (t) => [
|
|
17348
|
+
index("idx_community_machine_user_last_seen").on(t.userId, t.lastSeenAt),
|
|
17349
|
+
index("idx_community_machine_user_updated").on(t.userId, t.updatedAt),
|
|
17350
|
+
index("idx_community_machine_user_status").on(t.userId, t.status)
|
|
17351
|
+
]);
|
|
17352
|
+
var communityMachineCredential = sqliteTable("community_machine_credential", {
|
|
17353
|
+
id: text("id").primaryKey().$defaultFn(() => "cmkid_" + nanoid3()),
|
|
17354
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17355
|
+
machineId: text("machine_id").notNull().references(() => communityMachine.id, { onDelete: "cascade" }),
|
|
17356
|
+
credentialHash: text("credential_hash").notNull().unique(),
|
|
17357
|
+
doName: text("do_name").notNull().unique(),
|
|
17358
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
17359
|
+
lastUsedAt: text("last_used_at"),
|
|
17360
|
+
revokedAt: text("revoked_at")
|
|
17361
|
+
}, (t) => [
|
|
17362
|
+
index("idx_community_machine_credential_user").on(t.userId),
|
|
17363
|
+
index("idx_community_machine_credential_machine").on(t.machineId)
|
|
17364
|
+
]);
|
|
17365
|
+
var communityBotBinding = sqliteTable("community_bot_binding", {
|
|
17366
|
+
userId: text("user_id").primaryKey().references(() => user.id, { onDelete: "cascade" }),
|
|
17367
|
+
machineId: text("machine_id").notNull().references(() => communityMachine.id, { onDelete: "restrict" }),
|
|
17368
|
+
runtime: text("runtime").notNull(),
|
|
17369
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString())
|
|
17370
|
+
}, (t) => [index("idx_community_bot_binding_machine").on(t.machineId)]);
|
|
17371
|
+
var communityAgentRunnerKey = sqliteTable("community_agent_runner_key", {
|
|
17372
|
+
id: text("id").primaryKey().$defaultFn(() => "crkid_" + nanoid3()),
|
|
17373
|
+
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
|
17374
|
+
machineId: text("machine_id").notNull().references(() => communityMachine.id, { onDelete: "cascade" }),
|
|
17375
|
+
agentId: text("agent_id").notNull(),
|
|
17376
|
+
runnerKeyHash: text("runner_key_hash").notNull().unique(),
|
|
17377
|
+
doName: text("do_name").notNull().unique(),
|
|
17378
|
+
createdAt: text("created_at").notNull().$defaultFn(() => new Date().toISOString()),
|
|
17379
|
+
revokedAt: text("revoked_at")
|
|
17380
|
+
}, (t) => [
|
|
17381
|
+
index("idx_community_agent_runner_key_machine_agent").on(t.machineId, t.agentId)
|
|
17382
|
+
]);
|
|
17383
|
+
|
|
17384
|
+
// ../shared/src/db/queries/community/agent-inbox.ts
|
|
17385
|
+
var AGENT_MESSAGE_COLUMNS = {
|
|
17386
|
+
id: communityMessage.id,
|
|
17387
|
+
authorId: communityMessage.authorId,
|
|
17388
|
+
content: communityMessage.content,
|
|
17389
|
+
createdAt: communityMessage.createdAt,
|
|
17390
|
+
channelId: communityMessage.channelId,
|
|
17391
|
+
dmConversationId: communityMessage.dmConversationId,
|
|
17392
|
+
seq: communityMessage.seq
|
|
17393
|
+
};
|
|
17394
|
+
// ../shared/src/db/index.ts
|
|
17395
|
+
var allSchema = { ...exports_schema, ...exports_community_schema, ...exports_community_machine_schema };
|
|
17396
|
+
// ../shared/src/db/queries/user.ts
|
|
17397
|
+
var publicUserColumns = {
|
|
17398
|
+
id: user.id,
|
|
17399
|
+
name: user.name,
|
|
17400
|
+
email: user.email,
|
|
17401
|
+
emailVerified: user.emailVerified,
|
|
17402
|
+
image: user.image,
|
|
17403
|
+
createdAt: user.createdAt,
|
|
17404
|
+
updatedAt: user.updatedAt,
|
|
17405
|
+
discriminator: user.discriminator
|
|
17406
|
+
};
|
|
17407
|
+
var internalUserColumns = {
|
|
17408
|
+
...publicUserColumns,
|
|
17409
|
+
isBot: user.isBot,
|
|
17410
|
+
ownerUserId: user.ownerUserId,
|
|
17411
|
+
deletedAt: user.deletedAt
|
|
17412
|
+
};
|
|
17413
|
+
// ../shared/src/db/queries/task.ts
|
|
17414
|
+
var DEFAULT_STALE_SECONDS = Number(process.env.ALOOK_STALE_DISPATCH_TIMEOUT_S) || 20;
|
|
17415
|
+
var DEFAULT_STALE_RUNNING_SECONDS = Number(process.env.ALOOK_STALE_RUNNING_TIMEOUT_S) || 3600;
|
|
17416
|
+
// ../shared/src/utils/email.ts
|
|
17417
|
+
var DOMAIN = `@${process.env.ALOOK_DOMAIN || "alook.ai"}`;
|
|
17418
|
+
var RESERVED_HANDLES = new Set([
|
|
17419
|
+
"no-reply",
|
|
17420
|
+
"noreply",
|
|
17421
|
+
"admin",
|
|
17422
|
+
"support",
|
|
17423
|
+
"help",
|
|
17424
|
+
"info",
|
|
17425
|
+
"postmaster",
|
|
17426
|
+
"abuse",
|
|
17427
|
+
"security",
|
|
17428
|
+
"mailer-daemon",
|
|
17429
|
+
"root",
|
|
17430
|
+
"webmaster",
|
|
17431
|
+
"hostmaster",
|
|
17432
|
+
"system",
|
|
17433
|
+
"alook"
|
|
17434
|
+
]);
|
|
17435
|
+
function toAlookAddress(h) {
|
|
17436
|
+
return `${h}${DOMAIN}`;
|
|
17437
|
+
}
|
|
17438
|
+
// ../shared/src/db/queries/community/channel.ts
|
|
17439
|
+
var log2 = createLogger({ service: "community-queries" });
|
|
17440
|
+
var CHANNEL_COLUMNS = {
|
|
17441
|
+
id: communityChannel.id,
|
|
17442
|
+
serverId: communityChannel.serverId,
|
|
17443
|
+
categoryId: communityChannel.categoryId,
|
|
17444
|
+
name: communityChannel.name,
|
|
17445
|
+
type: communityChannel.type,
|
|
17446
|
+
topic: communityChannel.topic,
|
|
17447
|
+
position: communityChannel.position,
|
|
17448
|
+
forumTags: communityChannel.forumTags,
|
|
17449
|
+
parentChannelId: communityChannel.parentChannelId,
|
|
17450
|
+
creatorId: communityChannel.creatorId,
|
|
17451
|
+
messageCount: communityChannel.messageCount,
|
|
17452
|
+
archived: communityChannel.archived,
|
|
17453
|
+
parentMessageId: communityChannel.parentMessageId,
|
|
17454
|
+
lastMessageAt: communityChannel.lastMessageAt,
|
|
17455
|
+
createdAt: communityChannel.createdAt
|
|
17456
|
+
};
|
|
17457
|
+
// ../shared/src/db/queries/community/search.ts
|
|
17458
|
+
var FTS_KEYWORDS = new Set(["and", "or", "not", "near"]);
|
|
17459
|
+
// ../shared/src/mode.ts
|
|
17460
|
+
function isLocalUrl(url2) {
|
|
17461
|
+
try {
|
|
17462
|
+
const { hostname: hostname3 } = new URL(url2);
|
|
17463
|
+
return ["localhost", "127.0.0.1", "0.0.0.0"].includes(hostname3);
|
|
17464
|
+
} catch {
|
|
17465
|
+
return false;
|
|
17466
|
+
}
|
|
17467
|
+
}
|
|
17468
|
+
function hasWindow() {
|
|
17469
|
+
return typeof globalThis !== "undefined" && "window" in globalThis;
|
|
17470
|
+
}
|
|
17471
|
+
function isTauri() {
|
|
17472
|
+
return hasWindow() && typeof window !== "undefined" && "__TAURI__" in window;
|
|
17473
|
+
}
|
|
17474
|
+
function isMobile() {
|
|
17475
|
+
if (!isTauri())
|
|
17476
|
+
return false;
|
|
17477
|
+
const ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
|
|
17478
|
+
return /(android|iphone|ipad|ipod)/i.test(ua);
|
|
17479
|
+
}
|
|
17480
|
+
function resolveMode(signals) {
|
|
17481
|
+
if (signals.tauri || isTauri()) {
|
|
17482
|
+
if (signals.tauriPlatform === "mobile" || isMobile())
|
|
17483
|
+
return "mobile";
|
|
17484
|
+
return "desktop";
|
|
17485
|
+
}
|
|
17486
|
+
if (signals.nodeEnv === "development" && !signals.cmdPrefix)
|
|
17487
|
+
return "dev";
|
|
17488
|
+
if (signals.serverUrl && !signals.cmdPrefix && signals.nodeEnv !== "production" && isLocalUrl(signals.serverUrl))
|
|
17489
|
+
return "dev";
|
|
17490
|
+
if (signals.cmdPrefix)
|
|
17491
|
+
return "app";
|
|
17492
|
+
if (signals.hostname && ["localhost", "127.0.0.1"].includes(signals.hostname))
|
|
17493
|
+
return "app";
|
|
17494
|
+
return "production";
|
|
17495
|
+
}
|
|
17496
|
+
function cliCommand(mode) {
|
|
17497
|
+
switch (mode) {
|
|
17498
|
+
case "dev":
|
|
17499
|
+
return "pnpm dev:cli";
|
|
17500
|
+
case "app":
|
|
17501
|
+
return "npx @alook/app cli";
|
|
17502
|
+
case "desktop":
|
|
17503
|
+
case "mobile":
|
|
17504
|
+
case "production":
|
|
17505
|
+
return "npx @alook/cli";
|
|
17506
|
+
}
|
|
17507
|
+
}
|
|
17508
|
+
// daemon/client.ts
|
|
17509
|
+
class DaemonClient {
|
|
17510
|
+
baseURL;
|
|
17511
|
+
constructor(baseURL) {
|
|
16849
17512
|
this.baseURL = baseURL;
|
|
16850
17513
|
}
|
|
16851
17514
|
async request(method, path, token, body) {
|
|
@@ -16972,7 +17635,7 @@ import { createInterface } from "readline";
|
|
|
16972
17635
|
import { execSync } from "child_process";
|
|
16973
17636
|
|
|
16974
17637
|
// lib/logger.ts
|
|
16975
|
-
var
|
|
17638
|
+
var LEVELS2 = {
|
|
16976
17639
|
debug: 0,
|
|
16977
17640
|
info: 1,
|
|
16978
17641
|
warn: 2,
|
|
@@ -17018,12 +17681,12 @@ class Logger2 {
|
|
|
17018
17681
|
module;
|
|
17019
17682
|
constructor(opts = {}) {
|
|
17020
17683
|
const envLevel = process.env.ALOOK_LOG_LEVEL;
|
|
17021
|
-
this.level =
|
|
17684
|
+
this.level = LEVELS2[opts.level ?? envLevel ?? "info"];
|
|
17022
17685
|
this.color = useColor();
|
|
17023
17686
|
this.module = opts.module;
|
|
17024
17687
|
}
|
|
17025
17688
|
setLevel(level) {
|
|
17026
|
-
this.level =
|
|
17689
|
+
this.level = LEVELS2[level];
|
|
17027
17690
|
}
|
|
17028
17691
|
child(module) {
|
|
17029
17692
|
const child = new Logger2({ level: this.levelName(), module });
|
|
@@ -17042,14 +17705,14 @@ class Logger2 {
|
|
|
17042
17705
|
this.write("error", msg, args);
|
|
17043
17706
|
}
|
|
17044
17707
|
levelName() {
|
|
17045
|
-
for (const [name, num] of Object.entries(
|
|
17708
|
+
for (const [name, num] of Object.entries(LEVELS2)) {
|
|
17046
17709
|
if (num === this.level)
|
|
17047
17710
|
return name;
|
|
17048
17711
|
}
|
|
17049
17712
|
return "info";
|
|
17050
17713
|
}
|
|
17051
17714
|
write(level, msg, args) {
|
|
17052
|
-
if (
|
|
17715
|
+
if (LEVELS2[level] < this.level)
|
|
17053
17716
|
return;
|
|
17054
17717
|
const ts = timestamp();
|
|
17055
17718
|
const label = LABELS[level];
|
|
@@ -17070,7 +17733,7 @@ class Logger2 {
|
|
|
17070
17733
|
if (a instanceof Error) {
|
|
17071
17734
|
dest.write(` ${a.message}
|
|
17072
17735
|
`);
|
|
17073
|
-
if (a.stack && this.level <=
|
|
17736
|
+
if (a.stack && this.level <= LEVELS2.debug) {
|
|
17074
17737
|
dest.write(` ${a.stack}
|
|
17075
17738
|
`);
|
|
17076
17739
|
}
|
|
@@ -17089,10 +17752,10 @@ class Logger2 {
|
|
|
17089
17752
|
function createLogger2(opts) {
|
|
17090
17753
|
return new Logger2(opts);
|
|
17091
17754
|
}
|
|
17092
|
-
var
|
|
17755
|
+
var log3 = createLogger2();
|
|
17093
17756
|
|
|
17094
17757
|
// daemon/kill-tree.ts
|
|
17095
|
-
var
|
|
17758
|
+
var log4 = createLogger2({ module: "kill-tree" });
|
|
17096
17759
|
function killGraceMs() {
|
|
17097
17760
|
return Number(process.env.ALOOK_KILL_GRACE_MS) || 2000;
|
|
17098
17761
|
}
|
|
@@ -17146,7 +17809,7 @@ async function killProcessTree(pid, opts) {
|
|
|
17146
17809
|
await new Promise((r) => setTimeout(r, POLL_MS));
|
|
17147
17810
|
}
|
|
17148
17811
|
if (isAlive(pid)) {
|
|
17149
|
-
|
|
17812
|
+
log4.warn(`pid=${pid} survived SIGTERM after ${graceMs}ms — escalating to SIGKILL`);
|
|
17150
17813
|
signalTree(pid, "SIGKILL");
|
|
17151
17814
|
}
|
|
17152
17815
|
}
|
|
@@ -17155,19 +17818,135 @@ async function killProcessTree(pid, opts) {
|
|
|
17155
17818
|
class ClaudeBackend {
|
|
17156
17819
|
cliPath;
|
|
17157
17820
|
name = "claude";
|
|
17821
|
+
lifecycle = { kind: "persistent", stdin: "gated", inFlightWake: "queue" };
|
|
17822
|
+
busyDeliveryMode = "gated";
|
|
17823
|
+
supportsStdinNotification = true;
|
|
17158
17824
|
constructor(cliPath) {
|
|
17159
17825
|
this.cliPath = cliPath;
|
|
17160
17826
|
}
|
|
17827
|
+
parseLine(line) {
|
|
17828
|
+
if (!line.trim())
|
|
17829
|
+
return [];
|
|
17830
|
+
let event;
|
|
17831
|
+
try {
|
|
17832
|
+
event = JSON.parse(line);
|
|
17833
|
+
} catch {
|
|
17834
|
+
return [{ kind: "log", content: line, level: "debug" }];
|
|
17835
|
+
}
|
|
17836
|
+
const events = [];
|
|
17837
|
+
const eventType = event.type;
|
|
17838
|
+
switch (eventType) {
|
|
17839
|
+
case "assistant": {
|
|
17840
|
+
const message2 = event.message;
|
|
17841
|
+
if (!message2)
|
|
17842
|
+
break;
|
|
17843
|
+
const content = message2.content;
|
|
17844
|
+
if (!Array.isArray(content))
|
|
17845
|
+
break;
|
|
17846
|
+
for (const block of content) {
|
|
17847
|
+
if (block.type === "text") {
|
|
17848
|
+
events.push({ kind: "text", text: block.text || "" });
|
|
17849
|
+
} else if (block.type === "thinking") {
|
|
17850
|
+
events.push({ kind: "thinking", text: block.text || "" });
|
|
17851
|
+
} else if (block.type === "tool_use") {
|
|
17852
|
+
events.push({ kind: "tool_call", name: block.name || "", input: block.input, callId: block.id });
|
|
17853
|
+
}
|
|
17854
|
+
}
|
|
17855
|
+
break;
|
|
17856
|
+
}
|
|
17857
|
+
case "result": {
|
|
17858
|
+
const result = event.result;
|
|
17859
|
+
const isError = event.is_error;
|
|
17860
|
+
if (isError) {
|
|
17861
|
+
events.push({ kind: "error", message: result || "unknown error" });
|
|
17862
|
+
}
|
|
17863
|
+
const resultSessionId = event.session_id;
|
|
17864
|
+
events.push({ kind: "turn_end", sessionId: resultSessionId || undefined });
|
|
17865
|
+
const usage = event.usage;
|
|
17866
|
+
if (usage || event.total_cost_usd != null) {
|
|
17867
|
+
events.push({
|
|
17868
|
+
kind: "telemetry",
|
|
17869
|
+
name: "token_usage",
|
|
17870
|
+
source: "claude_result_usage",
|
|
17871
|
+
usageKind: "per_turn",
|
|
17872
|
+
attrs: {
|
|
17873
|
+
inputTokens: usage?.input_tokens,
|
|
17874
|
+
outputTokens: usage?.output_tokens,
|
|
17875
|
+
cachedInputTokens: usage?.cache_read_input_tokens,
|
|
17876
|
+
cacheCreationInputTokens: usage?.cache_creation_input_tokens,
|
|
17877
|
+
totalCostUsd: event.total_cost_usd,
|
|
17878
|
+
durationMs: event.duration_ms,
|
|
17879
|
+
durationApiMs: event.duration_api_ms,
|
|
17880
|
+
numTurns: event.num_turns,
|
|
17881
|
+
resultSubtype: event.subtype,
|
|
17882
|
+
resultIsError: event.is_error,
|
|
17883
|
+
serviceTier: usage?.service_tier
|
|
17884
|
+
}
|
|
17885
|
+
});
|
|
17886
|
+
}
|
|
17887
|
+
break;
|
|
17888
|
+
}
|
|
17889
|
+
case "tool_result": {
|
|
17890
|
+
const toolUseId = event.tool_use_id;
|
|
17891
|
+
const content = event.content;
|
|
17892
|
+
events.push({ kind: "tool_output", callId: toolUseId, output: content });
|
|
17893
|
+
break;
|
|
17894
|
+
}
|
|
17895
|
+
case "system": {
|
|
17896
|
+
const subtype = event.subtype;
|
|
17897
|
+
if (subtype === "init") {
|
|
17898
|
+
const sid = event.session_id;
|
|
17899
|
+
events.push({ kind: "session_init", sessionId: sid || "" });
|
|
17900
|
+
} else if (subtype === "context_pruning" || subtype === "compaction") {
|
|
17901
|
+
events.push({ kind: "compaction_started" });
|
|
17902
|
+
} else if (subtype === "compaction_finished" || subtype === "context_pruning_finished") {
|
|
17903
|
+
events.push({ kind: "compaction_finished" });
|
|
17904
|
+
} else if (subtype === "status" || subtype === "stream_event") {
|
|
17905
|
+
events.push({
|
|
17906
|
+
kind: "internal_progress",
|
|
17907
|
+
source: "claude_system",
|
|
17908
|
+
itemType: subtype,
|
|
17909
|
+
payloadBytes: line.length
|
|
17910
|
+
});
|
|
17911
|
+
}
|
|
17912
|
+
break;
|
|
17913
|
+
}
|
|
17914
|
+
case "control_request": {
|
|
17915
|
+
const requestId = event.request_id;
|
|
17916
|
+
if (requestId) {
|
|
17917
|
+
events.push({ kind: "permission_request", requestId, payload: event.payload });
|
|
17918
|
+
}
|
|
17919
|
+
break;
|
|
17920
|
+
}
|
|
17921
|
+
default: {
|
|
17922
|
+
events.push({ kind: "log", content: line, level: "debug" });
|
|
17923
|
+
}
|
|
17924
|
+
}
|
|
17925
|
+
return events;
|
|
17926
|
+
}
|
|
17927
|
+
encodeStdinMessage(text2, mode, opts) {
|
|
17928
|
+
const msg = {
|
|
17929
|
+
type: "user",
|
|
17930
|
+
message: {
|
|
17931
|
+
role: "user",
|
|
17932
|
+
content: [{ type: "text", text: text2 }]
|
|
17933
|
+
}
|
|
17934
|
+
};
|
|
17935
|
+
if (opts?.sessionId) {
|
|
17936
|
+
msg.session_id = opts.sessionId;
|
|
17937
|
+
}
|
|
17938
|
+
return JSON.stringify(msg);
|
|
17939
|
+
}
|
|
17161
17940
|
execute(prompt, options) {
|
|
17162
|
-
const
|
|
17163
|
-
|
|
17164
|
-
|
|
17165
|
-
"
|
|
17166
|
-
|
|
17167
|
-
|
|
17168
|
-
|
|
17169
|
-
"
|
|
17170
|
-
|
|
17941
|
+
const useStdinPrompt = options.steeringEnabled === true;
|
|
17942
|
+
const args = [];
|
|
17943
|
+
if (!useStdinPrompt) {
|
|
17944
|
+
args.push("-p", prompt);
|
|
17945
|
+
}
|
|
17946
|
+
args.push("--output-format", "stream-json", "--verbose", "--permission-mode", "bypassPermissions");
|
|
17947
|
+
if (useStdinPrompt) {
|
|
17948
|
+
args.push("--input-format", "stream-json");
|
|
17949
|
+
}
|
|
17171
17950
|
if (options.model) {
|
|
17172
17951
|
args.push("--model", options.model);
|
|
17173
17952
|
}
|
|
@@ -17224,15 +18003,58 @@ class ClaudeBackend {
|
|
|
17224
18003
|
r();
|
|
17225
18004
|
}
|
|
17226
18005
|
};
|
|
18006
|
+
const parsedEventQueue = [];
|
|
18007
|
+
let parsedEventResolve = null;
|
|
18008
|
+
let parsedEventDone = false;
|
|
18009
|
+
const pushParsedEvent = (evt) => {
|
|
18010
|
+
parsedEventQueue.push(evt);
|
|
18011
|
+
if (parsedEventResolve) {
|
|
18012
|
+
const r = parsedEventResolve;
|
|
18013
|
+
parsedEventResolve = null;
|
|
18014
|
+
r();
|
|
18015
|
+
}
|
|
18016
|
+
};
|
|
18017
|
+
const stdinWriteQueue = [];
|
|
18018
|
+
let stdinDraining = false;
|
|
18019
|
+
const enqueueStdinWrite = (data) => {
|
|
18020
|
+
stdinWriteQueue.push(data);
|
|
18021
|
+
drainStdinQueue();
|
|
18022
|
+
};
|
|
18023
|
+
const drainStdinQueue = () => {
|
|
18024
|
+
if (stdinDraining)
|
|
18025
|
+
return;
|
|
18026
|
+
stdinDraining = true;
|
|
18027
|
+
while (stdinWriteQueue.length > 0) {
|
|
18028
|
+
const line = stdinWriteQueue.shift();
|
|
18029
|
+
try {
|
|
18030
|
+
proc.stdin?.write(line + `
|
|
18031
|
+
`);
|
|
18032
|
+
} catch {}
|
|
18033
|
+
}
|
|
18034
|
+
stdinDraining = false;
|
|
18035
|
+
};
|
|
17227
18036
|
const resultPromise = new Promise((resolve) => {
|
|
17228
18037
|
const stderrChunks = [];
|
|
17229
18038
|
proc.stderr?.on("data", (chunk) => {
|
|
17230
18039
|
stderrChunks.push(chunk.toString());
|
|
17231
18040
|
});
|
|
17232
18041
|
const rl = createInterface({ input: proc.stdout });
|
|
18042
|
+
if (useStdinPrompt) {
|
|
18043
|
+
const initialMsg = JSON.stringify({
|
|
18044
|
+
type: "user",
|
|
18045
|
+
message: {
|
|
18046
|
+
role: "user",
|
|
18047
|
+
content: [{ type: "text", text: prompt }]
|
|
18048
|
+
}
|
|
18049
|
+
});
|
|
18050
|
+
enqueueStdinWrite(initialMsg);
|
|
18051
|
+
}
|
|
17233
18052
|
rl.on("line", (line) => {
|
|
17234
18053
|
if (!line.trim())
|
|
17235
18054
|
return;
|
|
18055
|
+
const parsed = this.parseLine(line);
|
|
18056
|
+
for (const pe of parsed)
|
|
18057
|
+
pushParsedEvent(pe);
|
|
17236
18058
|
let event;
|
|
17237
18059
|
try {
|
|
17238
18060
|
event = JSON.parse(line);
|
|
@@ -17278,6 +18100,13 @@ class ClaudeBackend {
|
|
|
17278
18100
|
resultStatus = "failed";
|
|
17279
18101
|
lastError = result || "unknown error";
|
|
17280
18102
|
}
|
|
18103
|
+
if (useStdinPrompt) {
|
|
18104
|
+
setTimeout(() => {
|
|
18105
|
+
try {
|
|
18106
|
+
proc.stdin?.end();
|
|
18107
|
+
} catch {}
|
|
18108
|
+
}, 100);
|
|
18109
|
+
}
|
|
17281
18110
|
break;
|
|
17282
18111
|
}
|
|
17283
18112
|
case "tool_result": {
|
|
@@ -17302,7 +18131,7 @@ class ClaudeBackend {
|
|
|
17302
18131
|
break;
|
|
17303
18132
|
}
|
|
17304
18133
|
case "control_request": {
|
|
17305
|
-
handleControlRequest(proc, event);
|
|
18134
|
+
handleControlRequest(proc, event, enqueueStdinWrite);
|
|
17306
18135
|
break;
|
|
17307
18136
|
}
|
|
17308
18137
|
default: {
|
|
@@ -17319,11 +18148,17 @@ class ClaudeBackend {
|
|
|
17319
18148
|
lastError = `spawn error: ${err.message}`;
|
|
17320
18149
|
resolveSessionId(lastSessionId);
|
|
17321
18150
|
messageDone = true;
|
|
18151
|
+
parsedEventDone = true;
|
|
17322
18152
|
if (messageResolve) {
|
|
17323
18153
|
const r = messageResolve;
|
|
17324
18154
|
messageResolve = null;
|
|
17325
18155
|
r();
|
|
17326
18156
|
}
|
|
18157
|
+
if (parsedEventResolve) {
|
|
18158
|
+
const r = parsedEventResolve;
|
|
18159
|
+
parsedEventResolve = null;
|
|
18160
|
+
r();
|
|
18161
|
+
}
|
|
17327
18162
|
resolve({
|
|
17328
18163
|
status: "failed",
|
|
17329
18164
|
output: "",
|
|
@@ -17346,11 +18181,17 @@ class ClaudeBackend {
|
|
|
17346
18181
|
}
|
|
17347
18182
|
resolveSessionId(lastSessionId);
|
|
17348
18183
|
messageDone = true;
|
|
18184
|
+
parsedEventDone = true;
|
|
17349
18185
|
if (messageResolve) {
|
|
17350
18186
|
const r = messageResolve;
|
|
17351
18187
|
messageResolve = null;
|
|
17352
18188
|
r();
|
|
17353
18189
|
}
|
|
18190
|
+
if (parsedEventResolve) {
|
|
18191
|
+
const r = parsedEventResolve;
|
|
18192
|
+
parsedEventResolve = null;
|
|
18193
|
+
r();
|
|
18194
|
+
}
|
|
17354
18195
|
resolve({
|
|
17355
18196
|
status: resultStatus,
|
|
17356
18197
|
output: lastOutput,
|
|
@@ -17377,10 +18218,47 @@ class ClaudeBackend {
|
|
|
17377
18218
|
};
|
|
17378
18219
|
}
|
|
17379
18220
|
};
|
|
17380
|
-
|
|
18221
|
+
const parsedEvents = {
|
|
18222
|
+
[Symbol.asyncIterator]() {
|
|
18223
|
+
return {
|
|
18224
|
+
async next() {
|
|
18225
|
+
while (parsedEventQueue.length === 0 && !parsedEventDone) {
|
|
18226
|
+
await new Promise((resolve) => {
|
|
18227
|
+
parsedEventResolve = resolve;
|
|
18228
|
+
});
|
|
18229
|
+
}
|
|
18230
|
+
if (parsedEventQueue.length > 0) {
|
|
18231
|
+
return { value: parsedEventQueue.shift(), done: false };
|
|
18232
|
+
}
|
|
18233
|
+
return { value: undefined, done: true };
|
|
18234
|
+
}
|
|
18235
|
+
};
|
|
18236
|
+
}
|
|
18237
|
+
};
|
|
18238
|
+
const send = (text2, mode) => {
|
|
18239
|
+
const encoded = this.encodeStdinMessage(text2, mode, { sessionId: lastSessionId || undefined });
|
|
18240
|
+
if (!encoded)
|
|
18241
|
+
return { ok: false, reason: "encoding failed" };
|
|
18242
|
+
if (!proc.stdin || proc.stdin.destroyed)
|
|
18243
|
+
return { ok: false, reason: "stdin closed" };
|
|
18244
|
+
enqueueStdinWrite(encoded);
|
|
18245
|
+
return { ok: true };
|
|
18246
|
+
};
|
|
18247
|
+
const descriptor = {
|
|
18248
|
+
lifecycle: this.lifecycle,
|
|
18249
|
+
busyDeliveryMode: this.busyDeliveryMode,
|
|
18250
|
+
supportsStdinNotification: this.supportsStdinNotification
|
|
18251
|
+
};
|
|
18252
|
+
const closeStdin = () => {
|
|
18253
|
+
try {
|
|
18254
|
+
if (proc.stdin && !proc.stdin.destroyed)
|
|
18255
|
+
proc.stdin.end();
|
|
18256
|
+
} catch {}
|
|
18257
|
+
};
|
|
18258
|
+
return { pid: proc.pid, messages, parsedEvents, sessionId: sessionIdPromise, result: resultPromise, send, closeStdin, descriptor };
|
|
17381
18259
|
}
|
|
17382
18260
|
}
|
|
17383
|
-
function handleControlRequest(proc, event) {
|
|
18261
|
+
function handleControlRequest(proc, event, enqueueStdinWrite) {
|
|
17384
18262
|
const requestId = event.request_id;
|
|
17385
18263
|
if (!requestId)
|
|
17386
18264
|
return;
|
|
@@ -17409,10 +18287,14 @@ function handleControlRequest(proc, event) {
|
|
|
17409
18287
|
}
|
|
17410
18288
|
}
|
|
17411
18289
|
});
|
|
17412
|
-
|
|
17413
|
-
|
|
18290
|
+
if (enqueueStdinWrite) {
|
|
18291
|
+
enqueueStdinWrite(approval);
|
|
18292
|
+
} else {
|
|
18293
|
+
try {
|
|
18294
|
+
proc.stdin?.write(approval + `
|
|
17414
18295
|
`);
|
|
17415
|
-
|
|
18296
|
+
} catch {}
|
|
18297
|
+
}
|
|
17416
18298
|
}
|
|
17417
18299
|
|
|
17418
18300
|
// daemon/agent/codex.ts
|
|
@@ -17444,9 +18326,196 @@ function extractThreadID(response) {
|
|
|
17444
18326
|
class CodexBackend {
|
|
17445
18327
|
cliPath;
|
|
17446
18328
|
name = "codex";
|
|
18329
|
+
lifecycle = { kind: "persistent", stdin: "direct", inFlightWake: "steer" };
|
|
18330
|
+
busyDeliveryMode = "direct";
|
|
18331
|
+
supportsStdinNotification = true;
|
|
18332
|
+
_rpcId = 0;
|
|
17447
18333
|
constructor(cliPath) {
|
|
17448
18334
|
this.cliPath = cliPath;
|
|
17449
18335
|
}
|
|
18336
|
+
parseLine(line) {
|
|
18337
|
+
if (!line.trim())
|
|
18338
|
+
return [];
|
|
18339
|
+
let msg;
|
|
18340
|
+
try {
|
|
18341
|
+
msg = JSON.parse(line);
|
|
18342
|
+
} catch {
|
|
18343
|
+
return [{ kind: "log", content: line, level: "debug" }];
|
|
18344
|
+
}
|
|
18345
|
+
if (msg.id !== undefined && !msg.method)
|
|
18346
|
+
return [];
|
|
18347
|
+
if (msg.id !== undefined && msg.method)
|
|
18348
|
+
return [];
|
|
18349
|
+
if (!msg.method)
|
|
18350
|
+
return [{ kind: "log", content: line, level: "debug" }];
|
|
18351
|
+
const method = msg.method;
|
|
18352
|
+
const params = msg.params || {};
|
|
18353
|
+
if (method === "codex/event") {
|
|
18354
|
+
return this.parseLegacyEvent(params);
|
|
18355
|
+
}
|
|
18356
|
+
const events = [];
|
|
18357
|
+
switch (method) {
|
|
18358
|
+
case "turn/started":
|
|
18359
|
+
break;
|
|
18360
|
+
case "turn/completed": {
|
|
18361
|
+
const turn = params.turn;
|
|
18362
|
+
const status = turn?.status || params.status || "";
|
|
18363
|
+
if (status === "error" || status === "failed") {
|
|
18364
|
+
const turnErr = turn?.error;
|
|
18365
|
+
events.push({ kind: "error", message: turnErr?.message || "codex turn failed" });
|
|
18366
|
+
}
|
|
18367
|
+
events.push({ kind: "turn_end" });
|
|
18368
|
+
break;
|
|
18369
|
+
}
|
|
18370
|
+
case "error": {
|
|
18371
|
+
const errObj = params.error;
|
|
18372
|
+
const errMsg = errObj?.message || params.message || "";
|
|
18373
|
+
const willRetry = params.willRetry === true;
|
|
18374
|
+
if (errMsg && !willRetry) {
|
|
18375
|
+
events.push({ kind: "error", message: errMsg });
|
|
18376
|
+
}
|
|
18377
|
+
break;
|
|
18378
|
+
}
|
|
18379
|
+
case "thread/status/changed": {
|
|
18380
|
+
const statusObj = params.status;
|
|
18381
|
+
const statusType = typeof statusObj === "object" && statusObj !== null ? statusObj.type || "" : statusObj || "";
|
|
18382
|
+
if (statusType === "idle") {
|
|
18383
|
+
events.push({ kind: "turn_end" });
|
|
18384
|
+
}
|
|
18385
|
+
break;
|
|
18386
|
+
}
|
|
18387
|
+
case "item/started": {
|
|
18388
|
+
const item = params.item;
|
|
18389
|
+
if (!item)
|
|
18390
|
+
break;
|
|
18391
|
+
const itemType = item.type;
|
|
18392
|
+
if (itemType === "commandExecution" || itemType === "fileChange") {
|
|
18393
|
+
events.push({
|
|
18394
|
+
kind: "tool_call",
|
|
18395
|
+
name: itemType === "commandExecution" ? "exec_command" : "patch_apply",
|
|
18396
|
+
callId: item.id,
|
|
18397
|
+
input: item
|
|
18398
|
+
});
|
|
18399
|
+
} else if (itemType === "mcpToolCall") {
|
|
18400
|
+
events.push({
|
|
18401
|
+
kind: "tool_call",
|
|
18402
|
+
name: `mcp_${item.name || "tool"}`,
|
|
18403
|
+
callId: item.id,
|
|
18404
|
+
input: item
|
|
18405
|
+
});
|
|
18406
|
+
} else if (itemType === "webSearch") {
|
|
18407
|
+
events.push({
|
|
18408
|
+
kind: "tool_call",
|
|
18409
|
+
name: "web_search",
|
|
18410
|
+
callId: item.id,
|
|
18411
|
+
input: item
|
|
18412
|
+
});
|
|
18413
|
+
} else if (itemType === "collabAgentToolCall") {
|
|
18414
|
+
events.push({
|
|
18415
|
+
kind: "tool_call",
|
|
18416
|
+
name: "collab_agent",
|
|
18417
|
+
callId: item.id,
|
|
18418
|
+
input: item
|
|
18419
|
+
});
|
|
18420
|
+
} else if (itemType === "contextCompaction") {
|
|
18421
|
+
events.push({ kind: "compaction_started" });
|
|
18422
|
+
}
|
|
18423
|
+
break;
|
|
18424
|
+
}
|
|
18425
|
+
case "item/completed": {
|
|
18426
|
+
const item = params.item;
|
|
18427
|
+
if (!item)
|
|
18428
|
+
break;
|
|
18429
|
+
const itemType = item.type;
|
|
18430
|
+
if (itemType === "commandExecution") {
|
|
18431
|
+
events.push({ kind: "tool_output", callId: item.id, output: item.aggregatedOutput || "" });
|
|
18432
|
+
} else if (itemType === "fileChange") {
|
|
18433
|
+
events.push({ kind: "tool_output", callId: item.id, output: "" });
|
|
18434
|
+
} else if (itemType === "mcpToolCall") {
|
|
18435
|
+
events.push({ kind: "tool_output", callId: item.id, name: `mcp_${item.name || "tool"}`, output: item.output || "" });
|
|
18436
|
+
} else if (itemType === "agentMessage") {
|
|
18437
|
+
const flatText = item.text;
|
|
18438
|
+
if (flatText) {
|
|
18439
|
+
events.push({ kind: "text", text: flatText });
|
|
18440
|
+
} else {
|
|
18441
|
+
const content = item.content;
|
|
18442
|
+
if (Array.isArray(content)) {
|
|
18443
|
+
for (const block of content) {
|
|
18444
|
+
if ((block.type === "output_text" || block.type === "text") && block.text) {
|
|
18445
|
+
events.push({ kind: "text", text: block.text });
|
|
18446
|
+
}
|
|
18447
|
+
}
|
|
18448
|
+
}
|
|
18449
|
+
}
|
|
18450
|
+
} else if (itemType === "reasoning") {
|
|
18451
|
+
events.push({ kind: "thinking", text: item.text || "" });
|
|
18452
|
+
} else if (itemType === "contextCompaction") {
|
|
18453
|
+
events.push({ kind: "compaction_finished" });
|
|
18454
|
+
}
|
|
18455
|
+
break;
|
|
18456
|
+
}
|
|
18457
|
+
case "item/agentMessage/delta": {
|
|
18458
|
+
const delta = params.delta;
|
|
18459
|
+
if (delta)
|
|
18460
|
+
events.push({ kind: "text", text: delta });
|
|
18461
|
+
break;
|
|
18462
|
+
}
|
|
18463
|
+
default:
|
|
18464
|
+
events.push({ kind: "log", content: JSON.stringify(msg), level: "debug" });
|
|
18465
|
+
}
|
|
18466
|
+
return events;
|
|
18467
|
+
}
|
|
18468
|
+
parseLegacyEvent(params) {
|
|
18469
|
+
const eventType = params.type;
|
|
18470
|
+
if (!eventType)
|
|
18471
|
+
return [];
|
|
18472
|
+
const events = [];
|
|
18473
|
+
switch (eventType) {
|
|
18474
|
+
case "agent_message": {
|
|
18475
|
+
const text2 = params.text || params.message || "";
|
|
18476
|
+
if (text2)
|
|
18477
|
+
events.push({ kind: "text", text: text2 });
|
|
18478
|
+
break;
|
|
18479
|
+
}
|
|
18480
|
+
case "exec_command_begin":
|
|
18481
|
+
events.push({ kind: "tool_call", name: "exec_command", callId: params.id, input: params });
|
|
18482
|
+
break;
|
|
18483
|
+
case "exec_command_end":
|
|
18484
|
+
events.push({ kind: "tool_output", callId: params.id, output: params.output || "" });
|
|
18485
|
+
break;
|
|
18486
|
+
case "patch_apply_begin":
|
|
18487
|
+
events.push({ kind: "tool_call", name: "patch_apply", callId: params.id, input: params });
|
|
18488
|
+
break;
|
|
18489
|
+
case "patch_apply_end":
|
|
18490
|
+
events.push({ kind: "tool_output", callId: params.id, output: params.output || "" });
|
|
18491
|
+
break;
|
|
18492
|
+
case "task_complete":
|
|
18493
|
+
events.push({ kind: "turn_end" });
|
|
18494
|
+
break;
|
|
18495
|
+
case "turn_aborted":
|
|
18496
|
+
events.push({ kind: "turn_end" });
|
|
18497
|
+
break;
|
|
18498
|
+
default:
|
|
18499
|
+
break;
|
|
18500
|
+
}
|
|
18501
|
+
return events;
|
|
18502
|
+
}
|
|
18503
|
+
encodeStdinMessage(text2, mode, opts) {
|
|
18504
|
+
const threadId = opts?.threadId;
|
|
18505
|
+
if (!threadId)
|
|
18506
|
+
return null;
|
|
18507
|
+
const id = opts?.requestId ?? ++this._rpcId;
|
|
18508
|
+
const method = mode === "busy" ? "turn/steer" : "turn/start";
|
|
18509
|
+
return JSON.stringify({
|
|
18510
|
+
jsonrpc: "2.0",
|
|
18511
|
+
id,
|
|
18512
|
+
method,
|
|
18513
|
+
params: {
|
|
18514
|
+
threadId,
|
|
18515
|
+
input: [{ type: "text", text: text2 }]
|
|
18516
|
+
}
|
|
18517
|
+
});
|
|
18518
|
+
}
|
|
17450
18519
|
execute(prompt, options) {
|
|
17451
18520
|
const proc = spawn2(this.cliPath, ["app-server", "--listen", "stdio://", "--config", "sandbox_mode=danger-full-access"], {
|
|
17452
18521
|
cwd: options.cwd,
|
|
@@ -17495,6 +18564,9 @@ class CodexBackend {
|
|
|
17495
18564
|
const messageQueue = [];
|
|
17496
18565
|
let messageResolve = null;
|
|
17497
18566
|
let messageDone = false;
|
|
18567
|
+
const parsedEventQueue = [];
|
|
18568
|
+
let parsedEventResolve = null;
|
|
18569
|
+
let parsedEventDone = false;
|
|
17498
18570
|
const pushMessage = (msg) => {
|
|
17499
18571
|
messageQueue.push(msg);
|
|
17500
18572
|
if (messageResolve) {
|
|
@@ -17503,6 +18575,14 @@ class CodexBackend {
|
|
|
17503
18575
|
r();
|
|
17504
18576
|
}
|
|
17505
18577
|
};
|
|
18578
|
+
const pushParsedEvent = (evt) => {
|
|
18579
|
+
parsedEventQueue.push(evt);
|
|
18580
|
+
if (parsedEventResolve) {
|
|
18581
|
+
const r = parsedEventResolve;
|
|
18582
|
+
parsedEventResolve = null;
|
|
18583
|
+
r();
|
|
18584
|
+
}
|
|
18585
|
+
};
|
|
17506
18586
|
const writeStdin = (data) => {
|
|
17507
18587
|
try {
|
|
17508
18588
|
proc.stdin?.write(data + `
|
|
@@ -17535,17 +18615,20 @@ class CodexBackend {
|
|
|
17535
18615
|
if (msg && !turnError)
|
|
17536
18616
|
turnError = msg;
|
|
17537
18617
|
};
|
|
18618
|
+
const steeringKeepAlive = options.steeringEnabled === true;
|
|
17538
18619
|
const triggerTurnDone = (aborted2) => {
|
|
17539
18620
|
if (turnDoneTriggered)
|
|
17540
18621
|
return;
|
|
17541
18622
|
turnDoneTriggered = true;
|
|
17542
18623
|
resultStatus = aborted2 ? "aborted" : "completed";
|
|
17543
|
-
|
|
17544
|
-
|
|
17545
|
-
|
|
17546
|
-
|
|
17547
|
-
|
|
17548
|
-
|
|
18624
|
+
if (!steeringKeepAlive) {
|
|
18625
|
+
try {
|
|
18626
|
+
proc.stdin?.end();
|
|
18627
|
+
} catch {}
|
|
18628
|
+
try {
|
|
18629
|
+
proc.kill("SIGTERM");
|
|
18630
|
+
} catch {}
|
|
18631
|
+
}
|
|
17549
18632
|
};
|
|
17550
18633
|
const handleServerRequest = (msg) => {
|
|
17551
18634
|
const method = msg.method;
|
|
@@ -17766,6 +18849,9 @@ class CodexBackend {
|
|
|
17766
18849
|
rl.on("line", (line) => {
|
|
17767
18850
|
if (!line.trim())
|
|
17768
18851
|
return;
|
|
18852
|
+
const parsed = this.parseLine(line);
|
|
18853
|
+
for (const pe of parsed)
|
|
18854
|
+
pushParsedEvent(pe);
|
|
17769
18855
|
let msg;
|
|
17770
18856
|
try {
|
|
17771
18857
|
msg = JSON.parse(line);
|
|
@@ -17852,11 +18938,17 @@ class CodexBackend {
|
|
|
17852
18938
|
closeAllPending("spawn error");
|
|
17853
18939
|
resolveSessionId(sessionId);
|
|
17854
18940
|
messageDone = true;
|
|
18941
|
+
parsedEventDone = true;
|
|
17855
18942
|
if (messageResolve) {
|
|
17856
18943
|
const r = messageResolve;
|
|
17857
18944
|
messageResolve = null;
|
|
17858
18945
|
r();
|
|
17859
18946
|
}
|
|
18947
|
+
if (parsedEventResolve) {
|
|
18948
|
+
const r = parsedEventResolve;
|
|
18949
|
+
parsedEventResolve = null;
|
|
18950
|
+
r();
|
|
18951
|
+
}
|
|
17860
18952
|
resolve({
|
|
17861
18953
|
status: "failed",
|
|
17862
18954
|
output: "",
|
|
@@ -17886,11 +18978,17 @@ class CodexBackend {
|
|
|
17886
18978
|
}
|
|
17887
18979
|
resolveSessionId(sessionId);
|
|
17888
18980
|
messageDone = true;
|
|
18981
|
+
parsedEventDone = true;
|
|
17889
18982
|
if (messageResolve) {
|
|
17890
18983
|
const r = messageResolve;
|
|
17891
18984
|
messageResolve = null;
|
|
17892
18985
|
r();
|
|
17893
18986
|
}
|
|
18987
|
+
if (parsedEventResolve) {
|
|
18988
|
+
const r = parsedEventResolve;
|
|
18989
|
+
parsedEventResolve = null;
|
|
18990
|
+
r();
|
|
18991
|
+
}
|
|
17894
18992
|
resolve({
|
|
17895
18993
|
status: resultStatus,
|
|
17896
18994
|
output: lastOutput,
|
|
@@ -17906,18 +19004,55 @@ class CodexBackend {
|
|
|
17906
19004
|
async next() {
|
|
17907
19005
|
while (messageQueue.length === 0 && !messageDone) {
|
|
17908
19006
|
await new Promise((resolve) => {
|
|
17909
|
-
messageResolve = resolve;
|
|
19007
|
+
messageResolve = resolve;
|
|
19008
|
+
});
|
|
19009
|
+
}
|
|
19010
|
+
if (messageQueue.length > 0) {
|
|
19011
|
+
return { value: messageQueue.shift(), done: false };
|
|
19012
|
+
}
|
|
19013
|
+
return { value: undefined, done: true };
|
|
19014
|
+
}
|
|
19015
|
+
};
|
|
19016
|
+
}
|
|
19017
|
+
};
|
|
19018
|
+
const parsedEvents = {
|
|
19019
|
+
[Symbol.asyncIterator]() {
|
|
19020
|
+
return {
|
|
19021
|
+
async next() {
|
|
19022
|
+
while (parsedEventQueue.length === 0 && !parsedEventDone) {
|
|
19023
|
+
await new Promise((resolve) => {
|
|
19024
|
+
parsedEventResolve = resolve;
|
|
17910
19025
|
});
|
|
17911
19026
|
}
|
|
17912
|
-
if (
|
|
17913
|
-
return { value:
|
|
19027
|
+
if (parsedEventQueue.length > 0) {
|
|
19028
|
+
return { value: parsedEventQueue.shift(), done: false };
|
|
17914
19029
|
}
|
|
17915
19030
|
return { value: undefined, done: true };
|
|
17916
19031
|
}
|
|
17917
19032
|
};
|
|
17918
19033
|
}
|
|
17919
19034
|
};
|
|
17920
|
-
|
|
19035
|
+
const send = (text2, mode) => {
|
|
19036
|
+
if (!proc.stdin || proc.stdin.destroyed)
|
|
19037
|
+
return { ok: false, reason: "stdin closed" };
|
|
19038
|
+
const encoded = this.encodeStdinMessage(text2, mode, { threadId: sessionId, requestId: ++requestId });
|
|
19039
|
+
if (!encoded)
|
|
19040
|
+
return { ok: false, reason: "encoding failed (no threadId)" };
|
|
19041
|
+
writeStdin(encoded);
|
|
19042
|
+
return { ok: true };
|
|
19043
|
+
};
|
|
19044
|
+
const descriptor = {
|
|
19045
|
+
lifecycle: this.lifecycle,
|
|
19046
|
+
busyDeliveryMode: this.busyDeliveryMode,
|
|
19047
|
+
supportsStdinNotification: this.supportsStdinNotification
|
|
19048
|
+
};
|
|
19049
|
+
const closeStdin = () => {
|
|
19050
|
+
try {
|
|
19051
|
+
if (proc.stdin && !proc.stdin.destroyed)
|
|
19052
|
+
proc.stdin.end();
|
|
19053
|
+
} catch {}
|
|
19054
|
+
};
|
|
19055
|
+
return { pid: proc.pid, messages, parsedEvents, sessionId: sessionIdPromise, result: resultPromise, send, closeStdin, descriptor };
|
|
17921
19056
|
}
|
|
17922
19057
|
}
|
|
17923
19058
|
|
|
@@ -17927,9 +19062,102 @@ import { createInterface as createInterface3 } from "readline";
|
|
|
17927
19062
|
class OpenCodeBackend {
|
|
17928
19063
|
cliPath;
|
|
17929
19064
|
name = "opencode";
|
|
19065
|
+
lifecycle = { kind: "per_turn", inFlightWake: "coalesce_into_pending" };
|
|
19066
|
+
busyDeliveryMode = "none";
|
|
19067
|
+
supportsStdinNotification = false;
|
|
17930
19068
|
constructor(cliPath) {
|
|
17931
19069
|
this.cliPath = cliPath;
|
|
17932
19070
|
}
|
|
19071
|
+
parseLine(line) {
|
|
19072
|
+
if (!line.trim())
|
|
19073
|
+
return [];
|
|
19074
|
+
let event;
|
|
19075
|
+
try {
|
|
19076
|
+
event = JSON.parse(line);
|
|
19077
|
+
} catch {
|
|
19078
|
+
return [{ kind: "log", content: line, level: "debug" }];
|
|
19079
|
+
}
|
|
19080
|
+
const events = [];
|
|
19081
|
+
const eventType = event.type;
|
|
19082
|
+
const part = event.part;
|
|
19083
|
+
const eventSessionId = event.sessionID || event.session_id;
|
|
19084
|
+
switch (eventType) {
|
|
19085
|
+
case "session": {
|
|
19086
|
+
const sessionId = event.session_id;
|
|
19087
|
+
if (sessionId)
|
|
19088
|
+
events.push({ kind: "session_init", sessionId });
|
|
19089
|
+
break;
|
|
19090
|
+
}
|
|
19091
|
+
case "message": {
|
|
19092
|
+
const role = event.role;
|
|
19093
|
+
const content = event.content;
|
|
19094
|
+
if (role === "assistant" && content) {
|
|
19095
|
+
events.push({ kind: "text", text: content });
|
|
19096
|
+
}
|
|
19097
|
+
break;
|
|
19098
|
+
}
|
|
19099
|
+
case "text": {
|
|
19100
|
+
const text2 = part?.text || event.content || "";
|
|
19101
|
+
if (text2)
|
|
19102
|
+
events.push({ kind: "text", text: text2 });
|
|
19103
|
+
break;
|
|
19104
|
+
}
|
|
19105
|
+
case "thinking": {
|
|
19106
|
+
const content = part?.thinking || event.content || "";
|
|
19107
|
+
events.push({ kind: "thinking", text: content });
|
|
19108
|
+
break;
|
|
19109
|
+
}
|
|
19110
|
+
case "tool_call":
|
|
19111
|
+
events.push({
|
|
19112
|
+
kind: "tool_call",
|
|
19113
|
+
name: event.name || part?.name || "",
|
|
19114
|
+
callId: event.call_id || part?.id || "",
|
|
19115
|
+
input: event.input || part?.input
|
|
19116
|
+
});
|
|
19117
|
+
break;
|
|
19118
|
+
case "tool_result":
|
|
19119
|
+
events.push({
|
|
19120
|
+
kind: "tool_output",
|
|
19121
|
+
callId: event.call_id || part?.id || "",
|
|
19122
|
+
output: event.output || part?.output || ""
|
|
19123
|
+
});
|
|
19124
|
+
break;
|
|
19125
|
+
case "error": {
|
|
19126
|
+
const content = event.message || event.content || part?.error || "";
|
|
19127
|
+
events.push({ kind: "error", message: content });
|
|
19128
|
+
events.push({ kind: "turn_end" });
|
|
19129
|
+
break;
|
|
19130
|
+
}
|
|
19131
|
+
case "step_start":
|
|
19132
|
+
break;
|
|
19133
|
+
case "step_finish": {
|
|
19134
|
+
const reason = part?.reason;
|
|
19135
|
+
if (reason === "stop" || reason === "end_turn") {
|
|
19136
|
+
events.push({ kind: "turn_end" });
|
|
19137
|
+
}
|
|
19138
|
+
break;
|
|
19139
|
+
}
|
|
19140
|
+
case "done":
|
|
19141
|
+
case "complete": {
|
|
19142
|
+
const status = event.status;
|
|
19143
|
+
if (status === "error" || status === "failed") {
|
|
19144
|
+
const output = event.output;
|
|
19145
|
+
events.push({ kind: "error", message: output || "task failed" });
|
|
19146
|
+
}
|
|
19147
|
+
events.push({ kind: "turn_end" });
|
|
19148
|
+
break;
|
|
19149
|
+
}
|
|
19150
|
+
default:
|
|
19151
|
+
events.push({ kind: "log", content: line, level: "debug" });
|
|
19152
|
+
}
|
|
19153
|
+
if (eventSessionId && events.length > 0 && events[0].kind !== "session_init") {
|
|
19154
|
+
events.unshift({ kind: "session_init", sessionId: eventSessionId });
|
|
19155
|
+
}
|
|
19156
|
+
return events;
|
|
19157
|
+
}
|
|
19158
|
+
encodeStdinMessage() {
|
|
19159
|
+
return null;
|
|
19160
|
+
}
|
|
17933
19161
|
execute(prompt, options) {
|
|
17934
19162
|
const args = ["run", "--format", "json", "--dir", options.cwd];
|
|
17935
19163
|
if (options.model) {
|
|
@@ -17987,6 +19215,9 @@ class OpenCodeBackend {
|
|
|
17987
19215
|
const messageQueue = [];
|
|
17988
19216
|
let messageResolve = null;
|
|
17989
19217
|
let messageDone = false;
|
|
19218
|
+
const parsedEventQueue = [];
|
|
19219
|
+
let parsedEventResolve = null;
|
|
19220
|
+
let parsedEventDone = false;
|
|
17990
19221
|
const pushMessage = (msg) => {
|
|
17991
19222
|
messageQueue.push(msg);
|
|
17992
19223
|
if (messageResolve) {
|
|
@@ -17995,6 +19226,14 @@ class OpenCodeBackend {
|
|
|
17995
19226
|
r();
|
|
17996
19227
|
}
|
|
17997
19228
|
};
|
|
19229
|
+
const pushParsedEvent = (evt) => {
|
|
19230
|
+
parsedEventQueue.push(evt);
|
|
19231
|
+
if (parsedEventResolve) {
|
|
19232
|
+
const r = parsedEventResolve;
|
|
19233
|
+
parsedEventResolve = null;
|
|
19234
|
+
r();
|
|
19235
|
+
}
|
|
19236
|
+
};
|
|
17998
19237
|
const resultPromise = new Promise((resolve) => {
|
|
17999
19238
|
const stderrChunks = [];
|
|
18000
19239
|
proc.stderr?.on("data", (chunk) => {
|
|
@@ -18004,6 +19243,9 @@ class OpenCodeBackend {
|
|
|
18004
19243
|
rl.on("line", (line) => {
|
|
18005
19244
|
if (!line.trim())
|
|
18006
19245
|
return;
|
|
19246
|
+
const parsed = this.parseLine(line);
|
|
19247
|
+
for (const pe of parsed)
|
|
19248
|
+
pushParsedEvent(pe);
|
|
18007
19249
|
let event;
|
|
18008
19250
|
try {
|
|
18009
19251
|
event = JSON.parse(line);
|
|
@@ -18115,11 +19357,17 @@ class OpenCodeBackend {
|
|
|
18115
19357
|
lastError = `spawn error: ${err.message}`;
|
|
18116
19358
|
resolveSessionId(lastSessionId);
|
|
18117
19359
|
messageDone = true;
|
|
19360
|
+
parsedEventDone = true;
|
|
18118
19361
|
if (messageResolve) {
|
|
18119
19362
|
const r = messageResolve;
|
|
18120
19363
|
messageResolve = null;
|
|
18121
19364
|
r();
|
|
18122
19365
|
}
|
|
19366
|
+
if (parsedEventResolve) {
|
|
19367
|
+
const r = parsedEventResolve;
|
|
19368
|
+
parsedEventResolve = null;
|
|
19369
|
+
r();
|
|
19370
|
+
}
|
|
18123
19371
|
resolve({
|
|
18124
19372
|
status: "failed",
|
|
18125
19373
|
output: "",
|
|
@@ -18144,11 +19392,17 @@ class OpenCodeBackend {
|
|
|
18144
19392
|
}
|
|
18145
19393
|
resolveSessionId(lastSessionId);
|
|
18146
19394
|
messageDone = true;
|
|
19395
|
+
parsedEventDone = true;
|
|
18147
19396
|
if (messageResolve) {
|
|
18148
19397
|
const r = messageResolve;
|
|
18149
19398
|
messageResolve = null;
|
|
18150
19399
|
r();
|
|
18151
19400
|
}
|
|
19401
|
+
if (parsedEventResolve) {
|
|
19402
|
+
const r = parsedEventResolve;
|
|
19403
|
+
parsedEventResolve = null;
|
|
19404
|
+
r();
|
|
19405
|
+
}
|
|
18152
19406
|
resolve({
|
|
18153
19407
|
status: resultStatus,
|
|
18154
19408
|
output: lastOutput,
|
|
@@ -18175,7 +19429,32 @@ class OpenCodeBackend {
|
|
|
18175
19429
|
};
|
|
18176
19430
|
}
|
|
18177
19431
|
};
|
|
18178
|
-
|
|
19432
|
+
const parsedEvents = {
|
|
19433
|
+
[Symbol.asyncIterator]() {
|
|
19434
|
+
return {
|
|
19435
|
+
async next() {
|
|
19436
|
+
while (parsedEventQueue.length === 0 && !parsedEventDone) {
|
|
19437
|
+
await new Promise((resolve) => {
|
|
19438
|
+
parsedEventResolve = resolve;
|
|
19439
|
+
});
|
|
19440
|
+
}
|
|
19441
|
+
if (parsedEventQueue.length > 0) {
|
|
19442
|
+
return { value: parsedEventQueue.shift(), done: false };
|
|
19443
|
+
}
|
|
19444
|
+
return { value: undefined, done: true };
|
|
19445
|
+
}
|
|
19446
|
+
};
|
|
19447
|
+
}
|
|
19448
|
+
};
|
|
19449
|
+
const send = () => {
|
|
19450
|
+
return { ok: false, reason: "unsupported" };
|
|
19451
|
+
};
|
|
19452
|
+
const descriptor = {
|
|
19453
|
+
lifecycle: this.lifecycle,
|
|
19454
|
+
busyDeliveryMode: this.busyDeliveryMode,
|
|
19455
|
+
supportsStdinNotification: this.supportsStdinNotification
|
|
19456
|
+
};
|
|
19457
|
+
return { pid: proc.pid, messages, parsedEvents, sessionId: sessionIdPromise, result: resultPromise, send, descriptor };
|
|
18179
19458
|
}
|
|
18180
19459
|
}
|
|
18181
19460
|
|
|
@@ -18658,7 +19937,7 @@ function releaseLock(lockPath) {
|
|
|
18658
19937
|
}
|
|
18659
19938
|
|
|
18660
19939
|
// daemon/execenv/timeline.ts
|
|
18661
|
-
var
|
|
19940
|
+
var log5 = createLogger2({ module: "timeline" });
|
|
18662
19941
|
function readJsonl(filePath) {
|
|
18663
19942
|
let content;
|
|
18664
19943
|
try {
|
|
@@ -18727,7 +20006,7 @@ async function initEntryAsync(timelineDir, entry) {
|
|
|
18727
20006
|
acquired = acquireLock(lockPath);
|
|
18728
20007
|
}
|
|
18729
20008
|
if (!acquired) {
|
|
18730
|
-
|
|
20009
|
+
log5.debug(`Timeline initEntry: could not acquire lock for ${filename}`);
|
|
18731
20010
|
return;
|
|
18732
20011
|
}
|
|
18733
20012
|
try {
|
|
@@ -18737,7 +20016,7 @@ async function initEntryAsync(timelineDir, entry) {
|
|
|
18737
20016
|
releaseLock(lockPath);
|
|
18738
20017
|
}
|
|
18739
20018
|
} catch (err) {
|
|
18740
|
-
|
|
20019
|
+
log5.debug("Timeline initEntry failed", err);
|
|
18741
20020
|
}
|
|
18742
20021
|
}
|
|
18743
20022
|
function updateEntry(timelineDir, taskId, updater) {
|
|
@@ -18747,7 +20026,7 @@ function updateEntry(timelineDir, taskId, updater) {
|
|
|
18747
20026
|
try {
|
|
18748
20027
|
const acquired = acquireLock(lockPath);
|
|
18749
20028
|
if (!acquired) {
|
|
18750
|
-
|
|
20029
|
+
log5.debug(`Timeline updateEntry: lock held for ${filename}, skipping`);
|
|
18751
20030
|
continue;
|
|
18752
20031
|
}
|
|
18753
20032
|
try {
|
|
@@ -18780,10 +20059,10 @@ function updateEntry(timelineDir, taskId, updater) {
|
|
|
18780
20059
|
releaseLock(lockPath);
|
|
18781
20060
|
}
|
|
18782
20061
|
} catch (err) {
|
|
18783
|
-
|
|
20062
|
+
log5.debug(`Timeline updateEntry failed for ${filename}`, err);
|
|
18784
20063
|
}
|
|
18785
20064
|
}
|
|
18786
|
-
|
|
20065
|
+
log5.debug(`Timeline updateEntry: task_id ${taskId} not found in last 7 days`);
|
|
18787
20066
|
}
|
|
18788
20067
|
function createTimelineEntry(taskId, prompt, type, sessionId, pid, provider, contextKey, detailedLog) {
|
|
18789
20068
|
return {
|
|
@@ -18818,7 +20097,7 @@ function findResumableSessionByContextKey(timelineDir, contextKey, provider) {
|
|
|
18818
20097
|
// daemon/execenv/steering.ts
|
|
18819
20098
|
import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync3, readFileSync as readFileSync3, unlinkSync as unlinkSync2, readdirSync, statSync as statSync2 } from "fs";
|
|
18820
20099
|
import { join as join5 } from "path";
|
|
18821
|
-
var
|
|
20100
|
+
var log6 = createLogger2({ module: "steering" });
|
|
18822
20101
|
var INTENT_DIR_NAME = ".kill_intents";
|
|
18823
20102
|
var INTENT_STALE_MS = 10 * 60 * 1000;
|
|
18824
20103
|
function intentFilePath(baseDir, taskId) {
|
|
@@ -18840,6 +20119,636 @@ function clearKillIntent(baseDir, taskId) {
|
|
|
18840
20119
|
} catch {}
|
|
18841
20120
|
}
|
|
18842
20121
|
|
|
20122
|
+
// daemon/steering/mailbox.ts
|
|
20123
|
+
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";
|
|
20124
|
+
import { join as join6 } from "path";
|
|
20125
|
+
var log7 = createLogger2({ module: "mailbox" });
|
|
20126
|
+
function inboxDir(baseDir, contextKey) {
|
|
20127
|
+
const safeKey = contextKey.replace(/[^a-zA-Z0-9_:-]/g, "_");
|
|
20128
|
+
return join6(baseDir, ".steering", safeKey, "inbox");
|
|
20129
|
+
}
|
|
20130
|
+
function ackDir(baseDir, contextKey) {
|
|
20131
|
+
const safeKey = contextKey.replace(/[^a-zA-Z0-9_:-]/g, "_");
|
|
20132
|
+
return join6(baseDir, ".steering", safeKey, "ack");
|
|
20133
|
+
}
|
|
20134
|
+
function steeringDir(baseDir, contextKey) {
|
|
20135
|
+
const safeKey = contextKey.replace(/[^a-zA-Z0-9_:-]/g, "_");
|
|
20136
|
+
return join6(baseDir, ".steering", safeKey);
|
|
20137
|
+
}
|
|
20138
|
+
function readSteerMessage(filePath) {
|
|
20139
|
+
try {
|
|
20140
|
+
const content = readFileSync4(filePath, "utf-8");
|
|
20141
|
+
return JSON.parse(content);
|
|
20142
|
+
} catch {
|
|
20143
|
+
return null;
|
|
20144
|
+
}
|
|
20145
|
+
}
|
|
20146
|
+
function writeAck(baseDir, contextKey, seq) {
|
|
20147
|
+
const ack = ackDir(baseDir, contextKey);
|
|
20148
|
+
mkdirSync4(ack, { recursive: true });
|
|
20149
|
+
writeFileSync4(join6(ack, `${seq}.ack`), "");
|
|
20150
|
+
}
|
|
20151
|
+
function writeNack(baseDir, contextKey, seq, reason) {
|
|
20152
|
+
const ack = ackDir(baseDir, contextKey);
|
|
20153
|
+
mkdirSync4(ack, { recursive: true });
|
|
20154
|
+
writeFileSync4(join6(ack, `${seq}.nack`), JSON.stringify({ reason }));
|
|
20155
|
+
}
|
|
20156
|
+
function cleanupInboxFile(baseDir, contextKey, seq) {
|
|
20157
|
+
try {
|
|
20158
|
+
unlinkSync3(join6(inboxDir(baseDir, contextKey), `${seq}.json`));
|
|
20159
|
+
} catch {}
|
|
20160
|
+
}
|
|
20161
|
+
function cleanupSteeringDir(baseDir, contextKey) {
|
|
20162
|
+
const dir = steeringDir(baseDir, contextKey);
|
|
20163
|
+
try {
|
|
20164
|
+
rmSync(dir, { recursive: true, force: true });
|
|
20165
|
+
} catch {}
|
|
20166
|
+
}
|
|
20167
|
+
function watchInbox(baseDir, contextKey, onMessage) {
|
|
20168
|
+
const inbox = inboxDir(baseDir, contextKey);
|
|
20169
|
+
mkdirSync4(inbox, { recursive: true });
|
|
20170
|
+
const seen = new Set;
|
|
20171
|
+
let stopped = false;
|
|
20172
|
+
const scan = () => {
|
|
20173
|
+
if (stopped)
|
|
20174
|
+
return;
|
|
20175
|
+
try {
|
|
20176
|
+
const files = readdirSync2(inbox).filter((f) => f.endsWith(".json") && !f.endsWith(".tmp")).sort();
|
|
20177
|
+
for (const file2 of files) {
|
|
20178
|
+
if (seen.has(file2))
|
|
20179
|
+
continue;
|
|
20180
|
+
const seq = file2.replace(/\.json$/, "");
|
|
20181
|
+
const srcPath = join6(inbox, file2);
|
|
20182
|
+
const claimPath = join6(inbox, `${seq}.processing`);
|
|
20183
|
+
try {
|
|
20184
|
+
renameSync2(srcPath, claimPath);
|
|
20185
|
+
} catch {
|
|
20186
|
+
continue;
|
|
20187
|
+
}
|
|
20188
|
+
seen.add(file2);
|
|
20189
|
+
const msg = readSteerMessage(claimPath);
|
|
20190
|
+
try {
|
|
20191
|
+
unlinkSync3(claimPath);
|
|
20192
|
+
} catch {}
|
|
20193
|
+
if (msg) {
|
|
20194
|
+
onMessage(seq, msg);
|
|
20195
|
+
}
|
|
20196
|
+
}
|
|
20197
|
+
} catch {}
|
|
20198
|
+
};
|
|
20199
|
+
scan();
|
|
20200
|
+
let watcher = null;
|
|
20201
|
+
try {
|
|
20202
|
+
watcher = watch(inbox, () => {
|
|
20203
|
+
if (!stopped)
|
|
20204
|
+
scan();
|
|
20205
|
+
});
|
|
20206
|
+
} catch {
|
|
20207
|
+
log7.debug("fs.watch failed, relying on polling only");
|
|
20208
|
+
}
|
|
20209
|
+
const pollTimer = setInterval(scan, 200);
|
|
20210
|
+
return {
|
|
20211
|
+
stop() {
|
|
20212
|
+
stopped = true;
|
|
20213
|
+
clearInterval(pollTimer);
|
|
20214
|
+
watcher?.close();
|
|
20215
|
+
}
|
|
20216
|
+
};
|
|
20217
|
+
}
|
|
20218
|
+
|
|
20219
|
+
// daemon/steering/turnState.ts
|
|
20220
|
+
class RuntimeTurnState {
|
|
20221
|
+
currentTurnId = null;
|
|
20222
|
+
steeringGateActive = false;
|
|
20223
|
+
get isInTurn() {
|
|
20224
|
+
return this.currentTurnId !== null;
|
|
20225
|
+
}
|
|
20226
|
+
get turnId() {
|
|
20227
|
+
return this.currentTurnId;
|
|
20228
|
+
}
|
|
20229
|
+
get canSteerBusy() {
|
|
20230
|
+
return Boolean(this.currentTurnId && !this.steeringGateActive);
|
|
20231
|
+
}
|
|
20232
|
+
markTurnStarted(turnId) {
|
|
20233
|
+
if (turnId !== undefined && turnId !== null) {
|
|
20234
|
+
this.currentTurnId = turnId;
|
|
20235
|
+
}
|
|
20236
|
+
this.steeringGateActive = false;
|
|
20237
|
+
}
|
|
20238
|
+
adoptTurnId(turnId) {
|
|
20239
|
+
this.currentTurnId = turnId;
|
|
20240
|
+
}
|
|
20241
|
+
markToolBoundary() {
|
|
20242
|
+
this.steeringGateActive = true;
|
|
20243
|
+
}
|
|
20244
|
+
markProgress() {
|
|
20245
|
+
this.steeringGateActive = false;
|
|
20246
|
+
}
|
|
20247
|
+
markTurnCompleted() {
|
|
20248
|
+
this.currentTurnId = null;
|
|
20249
|
+
this.steeringGateActive = false;
|
|
20250
|
+
}
|
|
20251
|
+
reset() {
|
|
20252
|
+
this.currentTurnId = null;
|
|
20253
|
+
this.steeringGateActive = false;
|
|
20254
|
+
}
|
|
20255
|
+
}
|
|
20256
|
+
|
|
20257
|
+
// daemon/steering/apmStateMachine.ts
|
|
20258
|
+
var MAX_APM_GATED_STEERING_EVENTS = 12;
|
|
20259
|
+
function createInitialApmState() {
|
|
20260
|
+
return {
|
|
20261
|
+
isIdle: false,
|
|
20262
|
+
expectedTerminationReason: null,
|
|
20263
|
+
phase: "idle",
|
|
20264
|
+
outstandingToolUses: 0,
|
|
20265
|
+
compacting: false,
|
|
20266
|
+
toolBoundaryFlushDisabled: false,
|
|
20267
|
+
lastFlushReason: null,
|
|
20268
|
+
recentEvents: [],
|
|
20269
|
+
pendingMessages: []
|
|
20270
|
+
};
|
|
20271
|
+
}
|
|
20272
|
+
function reduceApmGatedToolUse(state, input) {
|
|
20273
|
+
if (input.kind === "tool_call") {
|
|
20274
|
+
return {
|
|
20275
|
+
nextState: {
|
|
20276
|
+
...state,
|
|
20277
|
+
isIdle: false,
|
|
20278
|
+
phase: "tool_wait",
|
|
20279
|
+
outstandingToolUses: state.outstandingToolUses + 1
|
|
20280
|
+
},
|
|
20281
|
+
hadOutstandingToolUse: state.outstandingToolUses > 0,
|
|
20282
|
+
shouldFlushToolBatch: false
|
|
20283
|
+
};
|
|
20284
|
+
}
|
|
20285
|
+
const hadOutstandingToolUse = state.outstandingToolUses > 0;
|
|
20286
|
+
const outstandingToolUses = Math.max(0, state.outstandingToolUses - 1);
|
|
20287
|
+
return {
|
|
20288
|
+
nextState: {
|
|
20289
|
+
...state,
|
|
20290
|
+
isIdle: false,
|
|
20291
|
+
phase: "tool_boundary",
|
|
20292
|
+
outstandingToolUses
|
|
20293
|
+
},
|
|
20294
|
+
hadOutstandingToolUse,
|
|
20295
|
+
shouldFlushToolBatch: hadOutstandingToolUse && outstandingToolUses === 0
|
|
20296
|
+
};
|
|
20297
|
+
}
|
|
20298
|
+
function reduceApmGatedCompaction(state, input) {
|
|
20299
|
+
if (input.kind === "compaction_started") {
|
|
20300
|
+
return { nextState: { ...state, isIdle: false, phase: "compacting", compacting: true } };
|
|
20301
|
+
}
|
|
20302
|
+
if (input.kind === "compaction_interrupted") {
|
|
20303
|
+
return { nextState: { ...state, isIdle: false, compacting: false } };
|
|
20304
|
+
}
|
|
20305
|
+
return {
|
|
20306
|
+
nextState: { ...state, isIdle: false, phase: "assistant_continuation", compacting: false }
|
|
20307
|
+
};
|
|
20308
|
+
}
|
|
20309
|
+
function reduceApmGatedFlushReadiness(state, input) {
|
|
20310
|
+
if (!input.isGated)
|
|
20311
|
+
return { shouldNotify: false, blockedReason: "non_gated", effects: [] };
|
|
20312
|
+
if (!input.hasSession)
|
|
20313
|
+
return { shouldNotify: false, blockedReason: "missing_session", effects: [] };
|
|
20314
|
+
if (input.inboxLength === 0)
|
|
20315
|
+
return { shouldNotify: false, blockedReason: "empty_inbox", effects: [] };
|
|
20316
|
+
if (state.toolBoundaryFlushDisabled) {
|
|
20317
|
+
return { shouldNotify: false, blockedReason: "tool_boundary_flush_disabled", effects: [] };
|
|
20318
|
+
}
|
|
20319
|
+
if (state.compacting)
|
|
20320
|
+
return { shouldNotify: false, blockedReason: "compacting", effects: [] };
|
|
20321
|
+
if (state.outstandingToolUses > 0) {
|
|
20322
|
+
return { shouldNotify: false, blockedReason: "outstanding_tool_uses", effects: [] };
|
|
20323
|
+
}
|
|
20324
|
+
return {
|
|
20325
|
+
shouldNotify: true,
|
|
20326
|
+
blockedReason: null,
|
|
20327
|
+
effects: [{ kind: "notify_stdin", reason: input.reason, stdinMode: "busy", clauseId: "SMR-002" }]
|
|
20328
|
+
};
|
|
20329
|
+
}
|
|
20330
|
+
function reduceApmGatedTurnEnd(state, input = {}) {
|
|
20331
|
+
const shouldDeliverQueuedMessages = Boolean(input.inboxLength && input.inboxLength > 0 && input.supportsStdinNotification && input.hasSession);
|
|
20332
|
+
return {
|
|
20333
|
+
nextState: {
|
|
20334
|
+
...state,
|
|
20335
|
+
isIdle: !shouldDeliverQueuedMessages,
|
|
20336
|
+
phase: "idle",
|
|
20337
|
+
outstandingToolUses: 0,
|
|
20338
|
+
compacting: false,
|
|
20339
|
+
pendingMessages: shouldDeliverQueuedMessages ? state.pendingMessages : []
|
|
20340
|
+
},
|
|
20341
|
+
effects: shouldDeliverQueuedMessages ? [{ kind: "deliver_stdin", reason: "turn_end", stdinMode: "idle", clauseId: "SMR-002" }] : []
|
|
20342
|
+
};
|
|
20343
|
+
}
|
|
20344
|
+
function reduceApmGatedError(state, input = {}) {
|
|
20345
|
+
const shouldDisableToolBoundaryFlush = input.disableToolBoundaryFlush === true;
|
|
20346
|
+
return {
|
|
20347
|
+
nextState: {
|
|
20348
|
+
...state,
|
|
20349
|
+
phase: "error",
|
|
20350
|
+
compacting: false,
|
|
20351
|
+
toolBoundaryFlushDisabled: state.toolBoundaryFlushDisabled || shouldDisableToolBoundaryFlush
|
|
20352
|
+
},
|
|
20353
|
+
shouldDisableToolBoundaryFlush
|
|
20354
|
+
};
|
|
20355
|
+
}
|
|
20356
|
+
function reduceApmGatedRecentEvent(state, input) {
|
|
20357
|
+
const summary = `${input.event}:${state.phase}:tools=${state.outstandingToolUses}:compact=${state.compacting}`;
|
|
20358
|
+
return {
|
|
20359
|
+
nextState: {
|
|
20360
|
+
...state,
|
|
20361
|
+
recentEvents: [...state.recentEvents, summary].slice(-MAX_APM_GATED_STEERING_EVENTS)
|
|
20362
|
+
}
|
|
20363
|
+
};
|
|
20364
|
+
}
|
|
20365
|
+
function reduceApmGatedEnqueue(state, message2) {
|
|
20366
|
+
return {
|
|
20367
|
+
nextState: {
|
|
20368
|
+
...state,
|
|
20369
|
+
pendingMessages: [...state.pendingMessages, message2]
|
|
20370
|
+
}
|
|
20371
|
+
};
|
|
20372
|
+
}
|
|
20373
|
+
function reduceApmStalledRecoveryTermination(state, input) {
|
|
20374
|
+
if (input.inboxLength === 0) {
|
|
20375
|
+
return { nextState: state, shouldTerminate: false, alreadyRecovering: false, blockedReason: "empty_inbox" };
|
|
20376
|
+
}
|
|
20377
|
+
if (state.expectedTerminationReason === "stalled_recovery") {
|
|
20378
|
+
return { nextState: state, shouldTerminate: false, alreadyRecovering: true, blockedReason: null };
|
|
20379
|
+
}
|
|
20380
|
+
const supportsStdinNotification = input.busyDeliveryMode !== "none";
|
|
20381
|
+
const directStdinRuntime = supportsStdinNotification && input.busyDeliveryMode === "direct";
|
|
20382
|
+
const canRestartDirectStdinProcess = directStdinRuntime && input.hasSession && (state.outstandingToolUses === 0 || input.hasDirectStdinRecoveryEvidence);
|
|
20383
|
+
const canRestartStalledProcess = !supportsStdinNotification || canRestartDirectStdinProcess;
|
|
20384
|
+
if (!canRestartStalledProcess) {
|
|
20385
|
+
return {
|
|
20386
|
+
nextState: state,
|
|
20387
|
+
shouldTerminate: false,
|
|
20388
|
+
alreadyRecovering: false,
|
|
20389
|
+
blockedReason: "runtime_not_restartable"
|
|
20390
|
+
};
|
|
20391
|
+
}
|
|
20392
|
+
if (input.staleForMs < input.staleThresholdMs && !input.runtimeProgressIsStale) {
|
|
20393
|
+
return {
|
|
20394
|
+
nextState: state,
|
|
20395
|
+
shouldTerminate: false,
|
|
20396
|
+
alreadyRecovering: false,
|
|
20397
|
+
blockedReason: "runtime_progress_recent"
|
|
20398
|
+
};
|
|
20399
|
+
}
|
|
20400
|
+
return {
|
|
20401
|
+
nextState: { ...state, expectedTerminationReason: "stalled_recovery" },
|
|
20402
|
+
shouldTerminate: true,
|
|
20403
|
+
alreadyRecovering: false,
|
|
20404
|
+
blockedReason: null
|
|
20405
|
+
};
|
|
20406
|
+
}
|
|
20407
|
+
function reduceApmStartupTimeoutTermination(state, input) {
|
|
20408
|
+
if (input.hasRuntimeProgressEvent) {
|
|
20409
|
+
return { nextState: state, shouldTerminate: false, blockedReason: "runtime_progress_started" };
|
|
20410
|
+
}
|
|
20411
|
+
return {
|
|
20412
|
+
nextState: { ...state, isIdle: false, expectedTerminationReason: "startup_timeout" },
|
|
20413
|
+
shouldTerminate: true,
|
|
20414
|
+
blockedReason: null
|
|
20415
|
+
};
|
|
20416
|
+
}
|
|
20417
|
+
|
|
20418
|
+
// daemon/steering/notificationState.ts
|
|
20419
|
+
function inboxNoticeMessageIdentity(message2) {
|
|
20420
|
+
const seq = typeof message2.seq === "number" && Number.isFinite(message2.seq) && message2.seq > 0 ? Math.floor(message2.seq) : null;
|
|
20421
|
+
if (seq !== null)
|
|
20422
|
+
return `s:${seq}`;
|
|
20423
|
+
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 : "";
|
|
20424
|
+
return id.length > 0 ? `m:${id}` : "";
|
|
20425
|
+
}
|
|
20426
|
+
class RuntimeNotificationState {
|
|
20427
|
+
pendingCountValue = 0;
|
|
20428
|
+
timerValue = null;
|
|
20429
|
+
lastNoticeFingerprint = null;
|
|
20430
|
+
lastNoticeSessionId = null;
|
|
20431
|
+
lastEncodeFailedFingerprint = null;
|
|
20432
|
+
lastEncodeFailedSessionId = null;
|
|
20433
|
+
contributedIdentities = new Set;
|
|
20434
|
+
contributionSessionId = null;
|
|
20435
|
+
get pendingCount() {
|
|
20436
|
+
return this.pendingCountValue;
|
|
20437
|
+
}
|
|
20438
|
+
isDuplicateNotice(fingerprint, sessionId) {
|
|
20439
|
+
if (fingerprint.length === 0)
|
|
20440
|
+
return false;
|
|
20441
|
+
return this.lastNoticeFingerprint === fingerprint && this.lastNoticeSessionId === sessionId;
|
|
20442
|
+
}
|
|
20443
|
+
recordNoticeWritten(fingerprint, sessionId, messages = []) {
|
|
20444
|
+
this.lastNoticeFingerprint = fingerprint;
|
|
20445
|
+
this.lastNoticeSessionId = sessionId;
|
|
20446
|
+
this.lastEncodeFailedFingerprint = null;
|
|
20447
|
+
this.lastEncodeFailedSessionId = null;
|
|
20448
|
+
this.ensureContributionSession(sessionId);
|
|
20449
|
+
for (const message2 of messages) {
|
|
20450
|
+
const identity = inboxNoticeMessageIdentity(message2);
|
|
20451
|
+
if (identity.length > 0)
|
|
20452
|
+
this.contributedIdentities.add(identity);
|
|
20453
|
+
}
|
|
20454
|
+
}
|
|
20455
|
+
recordNoticeEncodeFailed(fingerprint, sessionId) {
|
|
20456
|
+
if (fingerprint.length === 0)
|
|
20457
|
+
return;
|
|
20458
|
+
this.lastEncodeFailedFingerprint = fingerprint;
|
|
20459
|
+
this.lastEncodeFailedSessionId = sessionId;
|
|
20460
|
+
}
|
|
20461
|
+
isDuplicateEncodeFailedNotice(fingerprint, sessionId) {
|
|
20462
|
+
if (fingerprint.length === 0)
|
|
20463
|
+
return false;
|
|
20464
|
+
return this.lastEncodeFailedFingerprint === fingerprint && this.lastEncodeFailedSessionId === sessionId;
|
|
20465
|
+
}
|
|
20466
|
+
filterUncontributedMessages(messages, sessionId) {
|
|
20467
|
+
if (this.contributionSessionId !== sessionId)
|
|
20468
|
+
return messages;
|
|
20469
|
+
return messages.filter((m) => {
|
|
20470
|
+
const identity = inboxNoticeMessageIdentity(m);
|
|
20471
|
+
return identity.length === 0 || !this.contributedIdentities.has(identity);
|
|
20472
|
+
});
|
|
20473
|
+
}
|
|
20474
|
+
add(count = 1) {
|
|
20475
|
+
this.pendingCountValue += count;
|
|
20476
|
+
}
|
|
20477
|
+
schedule(callback, delayMs) {
|
|
20478
|
+
if (this.timerValue)
|
|
20479
|
+
return false;
|
|
20480
|
+
this.timerValue = setTimeout(() => {
|
|
20481
|
+
this.timerValue = null;
|
|
20482
|
+
callback();
|
|
20483
|
+
}, delayMs);
|
|
20484
|
+
this.timerValue.unref?.();
|
|
20485
|
+
return true;
|
|
20486
|
+
}
|
|
20487
|
+
takePendingAndClearTimer() {
|
|
20488
|
+
const count = this.pendingCountValue;
|
|
20489
|
+
this.pendingCountValue = 0;
|
|
20490
|
+
if (this.timerValue) {
|
|
20491
|
+
clearTimeout(this.timerValue);
|
|
20492
|
+
this.timerValue = null;
|
|
20493
|
+
}
|
|
20494
|
+
return count;
|
|
20495
|
+
}
|
|
20496
|
+
ensureContributionSession(sessionId) {
|
|
20497
|
+
if (this.contributionSessionId !== sessionId) {
|
|
20498
|
+
this.contributionSessionId = sessionId;
|
|
20499
|
+
this.contributedIdentities = new Set;
|
|
20500
|
+
}
|
|
20501
|
+
}
|
|
20502
|
+
}
|
|
20503
|
+
|
|
20504
|
+
// daemon/steering/progressState.ts
|
|
20505
|
+
class RuntimeProgressState {
|
|
20506
|
+
lastEventAt;
|
|
20507
|
+
lastEventKind = null;
|
|
20508
|
+
_staleSince = null;
|
|
20509
|
+
_isStale = false;
|
|
20510
|
+
constructor(now = Date.now()) {
|
|
20511
|
+
this.lastEventAt = now;
|
|
20512
|
+
}
|
|
20513
|
+
get isStale() {
|
|
20514
|
+
return this._isStale;
|
|
20515
|
+
}
|
|
20516
|
+
get staleSince() {
|
|
20517
|
+
return this._staleSince;
|
|
20518
|
+
}
|
|
20519
|
+
get lastActivity() {
|
|
20520
|
+
return this.lastEventAt;
|
|
20521
|
+
}
|
|
20522
|
+
ageMs(nowMs = Date.now()) {
|
|
20523
|
+
return nowMs - this.lastEventAt;
|
|
20524
|
+
}
|
|
20525
|
+
recordRealEvent(kind, now = Date.now()) {
|
|
20526
|
+
this.lastEventAt = now;
|
|
20527
|
+
this.lastEventKind = kind;
|
|
20528
|
+
this._isStale = false;
|
|
20529
|
+
this._staleSince = null;
|
|
20530
|
+
}
|
|
20531
|
+
recordInternalProgress(kind, now = Date.now()) {
|
|
20532
|
+
this.lastEventAt = now;
|
|
20533
|
+
this.lastEventKind = kind;
|
|
20534
|
+
}
|
|
20535
|
+
markStale(now = Date.now()) {
|
|
20536
|
+
if (this._isStale)
|
|
20537
|
+
return;
|
|
20538
|
+
this._isStale = true;
|
|
20539
|
+
this._staleSince = now;
|
|
20540
|
+
}
|
|
20541
|
+
shouldMarkStale(thresholdMs, now = Date.now()) {
|
|
20542
|
+
if (this._isStale)
|
|
20543
|
+
return false;
|
|
20544
|
+
return this.ageMs(now) > thresholdMs;
|
|
20545
|
+
}
|
|
20546
|
+
processEvent(event, now = Date.now()) {
|
|
20547
|
+
switch (event.kind) {
|
|
20548
|
+
case "text":
|
|
20549
|
+
case "tool_call":
|
|
20550
|
+
case "tool_output":
|
|
20551
|
+
case "turn_end":
|
|
20552
|
+
case "session_init":
|
|
20553
|
+
case "error":
|
|
20554
|
+
this.recordRealEvent(event.kind, now);
|
|
20555
|
+
break;
|
|
20556
|
+
case "internal_progress":
|
|
20557
|
+
case "compaction_started":
|
|
20558
|
+
case "compaction_finished":
|
|
20559
|
+
case "telemetry":
|
|
20560
|
+
case "thinking":
|
|
20561
|
+
this.recordInternalProgress(event.kind, now);
|
|
20562
|
+
break;
|
|
20563
|
+
default:
|
|
20564
|
+
this.recordInternalProgress(event.kind, now);
|
|
20565
|
+
}
|
|
20566
|
+
}
|
|
20567
|
+
}
|
|
20568
|
+
|
|
20569
|
+
// daemon/steering/errorDiagnostics.ts
|
|
20570
|
+
var ACTION_BY_CLASS = {
|
|
20571
|
+
RateLimitError: "retry_backoff",
|
|
20572
|
+
AuthError: "abort",
|
|
20573
|
+
NotFoundError: "report",
|
|
20574
|
+
ModelConfigError: "abort",
|
|
20575
|
+
TimeoutError: "retry",
|
|
20576
|
+
ProviderConnectionError: "retry_jitter",
|
|
20577
|
+
ProviderStreamError: "retry",
|
|
20578
|
+
ProviderServerError: "retry",
|
|
20579
|
+
ProviderApiError: "report",
|
|
20580
|
+
RuntimeError: "report"
|
|
20581
|
+
};
|
|
20582
|
+
var EXPLICIT_TOKEN_RE = /\b([A-Z][A-Za-z0-9_]*(?:Error|Exception))\b/;
|
|
20583
|
+
var EXPLICIT_TOKEN_MAP = {
|
|
20584
|
+
RateLimitError: "RateLimitError",
|
|
20585
|
+
TooManyRequestsError: "RateLimitError",
|
|
20586
|
+
AuthenticationError: "AuthError",
|
|
20587
|
+
AuthorizationError: "AuthError",
|
|
20588
|
+
PermissionError: "AuthError",
|
|
20589
|
+
NotFoundError: "NotFoundError",
|
|
20590
|
+
ModelNotFoundError: "ModelConfigError",
|
|
20591
|
+
TimeoutError: "TimeoutError",
|
|
20592
|
+
ConnectionError: "ProviderConnectionError",
|
|
20593
|
+
APIConnectionError: "ProviderConnectionError",
|
|
20594
|
+
StreamError: "ProviderStreamError",
|
|
20595
|
+
InternalServerError: "ProviderServerError",
|
|
20596
|
+
APIError: "ProviderApiError",
|
|
20597
|
+
BadRequestError: "ProviderApiError"
|
|
20598
|
+
};
|
|
20599
|
+
function extractHttpStatus(message2) {
|
|
20600
|
+
const labeled = /\b(?:HTTP|status(?:\s+code)?|API\s+Error)[:\s]+([45]\d{2})\b/i.exec(message2);
|
|
20601
|
+
if (labeled)
|
|
20602
|
+
return Number(labeled[1]);
|
|
20603
|
+
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);
|
|
20604
|
+
return semantic ? Number(semantic[1]) : null;
|
|
20605
|
+
}
|
|
20606
|
+
var AUTH_ACTION_REQUIRED_PATTERNS = [
|
|
20607
|
+
/access token could not be refreshed/i,
|
|
20608
|
+
/\btoken_(?:revoked|invalidated)\b/i,
|
|
20609
|
+
/refresh token was already used/i,
|
|
20610
|
+
/access token.*invalidated/i,
|
|
20611
|
+
/authentication token has been invalidated/i,
|
|
20612
|
+
/logged out or signed in to another account/i,
|
|
20613
|
+
/not logged in/i,
|
|
20614
|
+
/not signed in/i,
|
|
20615
|
+
/login required/i,
|
|
20616
|
+
/log in first/i,
|
|
20617
|
+
/please log in/i,
|
|
20618
|
+
/authentication failed/i,
|
|
20619
|
+
/auth(?:entication)? failed/i,
|
|
20620
|
+
/authentication timed out/i,
|
|
20621
|
+
/missing (?:api )?token/i,
|
|
20622
|
+
/no (?:api )?token/i,
|
|
20623
|
+
/missing credentials/i,
|
|
20624
|
+
/credentials? not found/i,
|
|
20625
|
+
/invalid api key/i,
|
|
20626
|
+
/api key (?:is )?not set/i,
|
|
20627
|
+
/token revoked/i,
|
|
20628
|
+
/refresh token expired/i,
|
|
20629
|
+
/session expired/i,
|
|
20630
|
+
/unauthorized/i,
|
|
20631
|
+
/forbidden/i,
|
|
20632
|
+
/invalid.?token/i
|
|
20633
|
+
];
|
|
20634
|
+
var RATE_LIMIT_PATTERNS = [
|
|
20635
|
+
/too many requests/i,
|
|
20636
|
+
/rate.?limit/i,
|
|
20637
|
+
/quota.?exceeded/i,
|
|
20638
|
+
/overloaded/i
|
|
20639
|
+
];
|
|
20640
|
+
var MODEL_CONFIG_PATTERNS = [
|
|
20641
|
+
/model.?not.?(?:found|supported|available)/i,
|
|
20642
|
+
/invalid.?model/i,
|
|
20643
|
+
/does not exist/i
|
|
20644
|
+
];
|
|
20645
|
+
var TIMEOUT_PATTERNS = [
|
|
20646
|
+
/timeout/i,
|
|
20647
|
+
/ETIMEDOUT/,
|
|
20648
|
+
/timed.?out/i,
|
|
20649
|
+
/deadline.?exceeded/i
|
|
20650
|
+
];
|
|
20651
|
+
var CONNECTION_PATTERNS = [
|
|
20652
|
+
/ECONNREFUSED/,
|
|
20653
|
+
/ECONNRESET/,
|
|
20654
|
+
/ENETUNREACH/,
|
|
20655
|
+
/EHOSTUNREACH/,
|
|
20656
|
+
/EAI_AGAIN/,
|
|
20657
|
+
/ENOTFOUND/,
|
|
20658
|
+
/connection.?refused/i,
|
|
20659
|
+
/connection.?reset/i,
|
|
20660
|
+
/network.?error/i,
|
|
20661
|
+
/Unable to connect to API/i
|
|
20662
|
+
];
|
|
20663
|
+
var STREAM_PATTERNS = [
|
|
20664
|
+
/stream.?error/i,
|
|
20665
|
+
/stream closed before response/i,
|
|
20666
|
+
/error decoding response body/i,
|
|
20667
|
+
/premature.?close/i,
|
|
20668
|
+
/aborted/i
|
|
20669
|
+
];
|
|
20670
|
+
var SERVER_PATTERNS = [
|
|
20671
|
+
/internal.?server/i,
|
|
20672
|
+
/bad.?gateway/i,
|
|
20673
|
+
/service.?unavailable/i
|
|
20674
|
+
];
|
|
20675
|
+
function classifyByExplicitToken(message2) {
|
|
20676
|
+
const match = EXPLICIT_TOKEN_RE.exec(message2);
|
|
20677
|
+
if (!match)
|
|
20678
|
+
return null;
|
|
20679
|
+
const token = match[1];
|
|
20680
|
+
return EXPLICIT_TOKEN_MAP[token] ?? null;
|
|
20681
|
+
}
|
|
20682
|
+
function classifyByHttpStatus(httpStatus) {
|
|
20683
|
+
if (httpStatus === 429)
|
|
20684
|
+
return "RateLimitError";
|
|
20685
|
+
if (httpStatus === 401 || httpStatus === 403)
|
|
20686
|
+
return "AuthError";
|
|
20687
|
+
if (httpStatus === 404)
|
|
20688
|
+
return "NotFoundError";
|
|
20689
|
+
if (httpStatus >= 500)
|
|
20690
|
+
return "ProviderServerError";
|
|
20691
|
+
return "ProviderApiError";
|
|
20692
|
+
}
|
|
20693
|
+
function classifyByTextPatterns(message2) {
|
|
20694
|
+
for (const pat of RATE_LIMIT_PATTERNS) {
|
|
20695
|
+
if (pat.test(message2))
|
|
20696
|
+
return "RateLimitError";
|
|
20697
|
+
}
|
|
20698
|
+
for (const pat of AUTH_ACTION_REQUIRED_PATTERNS) {
|
|
20699
|
+
if (pat.test(message2))
|
|
20700
|
+
return "AuthError";
|
|
20701
|
+
}
|
|
20702
|
+
for (const pat of MODEL_CONFIG_PATTERNS) {
|
|
20703
|
+
if (pat.test(message2))
|
|
20704
|
+
return "ModelConfigError";
|
|
20705
|
+
}
|
|
20706
|
+
for (const pat of TIMEOUT_PATTERNS) {
|
|
20707
|
+
if (pat.test(message2))
|
|
20708
|
+
return "TimeoutError";
|
|
20709
|
+
}
|
|
20710
|
+
for (const pat of CONNECTION_PATTERNS) {
|
|
20711
|
+
if (pat.test(message2))
|
|
20712
|
+
return "ProviderConnectionError";
|
|
20713
|
+
}
|
|
20714
|
+
for (const pat of STREAM_PATTERNS) {
|
|
20715
|
+
if (pat.test(message2))
|
|
20716
|
+
return "ProviderStreamError";
|
|
20717
|
+
}
|
|
20718
|
+
for (const pat of SERVER_PATTERNS) {
|
|
20719
|
+
if (pat.test(message2))
|
|
20720
|
+
return "ProviderServerError";
|
|
20721
|
+
}
|
|
20722
|
+
return null;
|
|
20723
|
+
}
|
|
20724
|
+
function classifyRuntimeError(message2, httpStatus) {
|
|
20725
|
+
const byToken = classifyByExplicitToken(message2);
|
|
20726
|
+
if (byToken) {
|
|
20727
|
+
return { errorClass: byToken, action: ACTION_BY_CLASS[byToken], reason: message2 };
|
|
20728
|
+
}
|
|
20729
|
+
const status = httpStatus ?? extractHttpStatus(message2);
|
|
20730
|
+
if (status !== null && status !== undefined) {
|
|
20731
|
+
const cls = classifyByHttpStatus(status);
|
|
20732
|
+
return { errorClass: cls, action: ACTION_BY_CLASS[cls], reason: message2 };
|
|
20733
|
+
}
|
|
20734
|
+
const byPattern = classifyByTextPatterns(message2);
|
|
20735
|
+
if (byPattern) {
|
|
20736
|
+
return { errorClass: byPattern, action: ACTION_BY_CLASS[byPattern], reason: message2 };
|
|
20737
|
+
}
|
|
20738
|
+
return { errorClass: "RuntimeError", action: "report", reason: message2 };
|
|
20739
|
+
}
|
|
20740
|
+
function scrubDiagnosticText(text2) {
|
|
20741
|
+
let scrubbed = text2;
|
|
20742
|
+
scrubbed = scrubbed.replace(/sk-ant-[a-zA-Z0-9_-]+/g, "sk-ant-***");
|
|
20743
|
+
scrubbed = scrubbed.replace(/sk-proj-[a-zA-Z0-9_-]+/g, "sk-proj-***");
|
|
20744
|
+
scrubbed = scrubbed.replace(/sk-[a-zA-Z0-9_-]{20,}/g, "sk-***");
|
|
20745
|
+
scrubbed = scrubbed.replace(/Bearer\s+[a-zA-Z0-9._-]+/gi, "Bearer ***");
|
|
20746
|
+
scrubbed = scrubbed.replace(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g, "***@***.***");
|
|
20747
|
+
scrubbed = scrubbed.replace(/:\/\/[^:@\s]+:[^@\s]+@/g, "://***:***@");
|
|
20748
|
+
scrubbed = scrubbed.replace(/\/(?:Users|home)\/[a-zA-Z0-9._-]+/g, "/***");
|
|
20749
|
+
return scrubbed;
|
|
20750
|
+
}
|
|
20751
|
+
|
|
18843
20752
|
// daemon/prompt.ts
|
|
18844
20753
|
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
20754
|
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 +20844,7 @@ function buildPrompt(task, attachments) {
|
|
|
18935
20844
|
}
|
|
18936
20845
|
|
|
18937
20846
|
// daemon/session-runner.ts
|
|
18938
|
-
var
|
|
20847
|
+
var log8 = createLogger2({ module: "session-runner" });
|
|
18939
20848
|
var ATTACHMENTS_BASE = tempDir("alook-attachments");
|
|
18940
20849
|
async function writeMarkerFile(workspacesRoot, marker) {
|
|
18941
20850
|
const dir = path.join(workspacesRoot, ".pending_completions");
|
|
@@ -18983,20 +20892,20 @@ async function reportToServer(fn, markerData, workspacesRoot) {
|
|
|
18983
20892
|
} catch (e) {
|
|
18984
20893
|
lastErr = e;
|
|
18985
20894
|
if (isClientError(e)) {
|
|
18986
|
-
|
|
20895
|
+
log8.info(`server report for task ${markerData.taskId}: task already in terminal state (${e})`);
|
|
18987
20896
|
return;
|
|
18988
20897
|
}
|
|
18989
20898
|
if (attempt < RETRY_DELAYS.length && isRetryableError(e)) {
|
|
18990
|
-
|
|
20899
|
+
log8.debug(`server report attempt ${attempt + 1} failed for task ${markerData.taskId}, retrying in ${RETRY_DELAYS[attempt]}ms`);
|
|
18991
20900
|
await new Promise((r) => setTimeout(r, RETRY_DELAYS[attempt]));
|
|
18992
20901
|
}
|
|
18993
20902
|
}
|
|
18994
20903
|
}
|
|
18995
|
-
|
|
20904
|
+
log8.warn(`server report failed for task ${markerData.taskId} after retries, writing marker: ${lastErr}`);
|
|
18996
20905
|
try {
|
|
18997
20906
|
await writeMarkerFile(workspacesRoot, markerData);
|
|
18998
20907
|
} catch (writeErr) {
|
|
18999
|
-
|
|
20908
|
+
log8.error(`marker write also failed for task ${markerData.taskId}: ${writeErr}`);
|
|
19000
20909
|
}
|
|
19001
20910
|
}
|
|
19002
20911
|
function sanitizeFilename(name) {
|
|
@@ -19027,12 +20936,12 @@ async function downloadAttachments(client, token, workspaceId, taskId, attachmen
|
|
|
19027
20936
|
}
|
|
19028
20937
|
async function runSession(input) {
|
|
19029
20938
|
const { task, provider, cliPath, model, serverURL, token, workspacesRoot, agentTimeout, messageInactivityTimeout } = input;
|
|
19030
|
-
|
|
20939
|
+
log8.info(`starting (task=${task.id}, type=${task.type}, agent=${task.agentId}, provider=${provider}, model=${model || "default"})`);
|
|
19031
20940
|
const client = new DaemonClient(serverURL);
|
|
19032
20941
|
const backend = createBackend(provider, cliPath);
|
|
19033
20942
|
const agentBaseDir = path.join(workspacesRoot, task.workspaceId, task.agentId, "workdir");
|
|
19034
20943
|
const timelineDir = path.join(agentBaseDir, ".context_timeline").replace(/\\/g, "/");
|
|
19035
|
-
|
|
20944
|
+
mkdirSync5(timelineDir, { recursive: true });
|
|
19036
20945
|
await initEntryAsync(timelineDir, createTimelineEntry(task.id, task.prompt, task.type, undefined, process.pid, provider, task.contextKey, input.logFilePath));
|
|
19037
20946
|
const { workDir, env } = prepare({ workspacesRoot, token }, task);
|
|
19038
20947
|
let killed = false;
|
|
@@ -19050,16 +20959,22 @@ async function runSession(input) {
|
|
|
19050
20959
|
try {
|
|
19051
20960
|
await client.reportMessages(token, task.id, batch);
|
|
19052
20961
|
} catch (e) {
|
|
19053
|
-
|
|
20962
|
+
log8.debug("message report failed", e);
|
|
19054
20963
|
}
|
|
19055
20964
|
};
|
|
20965
|
+
let mailboxWatcher = null;
|
|
20966
|
+
let stalledRecoveryTimer;
|
|
19056
20967
|
const onKill = async () => {
|
|
19057
20968
|
if (killed)
|
|
19058
20969
|
return;
|
|
19059
20970
|
killed = true;
|
|
19060
|
-
|
|
20971
|
+
log8.info(`killed by signal (messages=${seq}, tools=${toolCount})`);
|
|
20972
|
+
if (mailboxWatcher)
|
|
20973
|
+
mailboxWatcher.stop();
|
|
20974
|
+
if (stalledRecoveryTimer)
|
|
20975
|
+
clearInterval(stalledRecoveryTimer);
|
|
19061
20976
|
if (agentPid !== undefined) {
|
|
19062
|
-
|
|
20977
|
+
log8.info(`killing inner agent group (pid=${agentPid})`);
|
|
19063
20978
|
await killProcessTree(agentPid);
|
|
19064
20979
|
}
|
|
19065
20980
|
if (flushTimer)
|
|
@@ -19102,14 +21017,14 @@ async function runSession(input) {
|
|
|
19102
21017
|
const attachmentIds = task.context?.attachment_ids ?? [];
|
|
19103
21018
|
let attachments;
|
|
19104
21019
|
if (attachmentIds.length > 0) {
|
|
19105
|
-
|
|
21020
|
+
log8.info(`downloading ${attachmentIds.length} attachment(s)`);
|
|
19106
21021
|
try {
|
|
19107
21022
|
attachments = await downloadAttachments(client, token, task.workspaceId, task.id, attachmentIds);
|
|
19108
|
-
|
|
21023
|
+
log8.info(`attachments ready (${attachments.length} file(s))`);
|
|
19109
21024
|
} catch (e) {
|
|
19110
21025
|
await cleanupAttachments(task.id);
|
|
19111
21026
|
const errMsg = `failed to download attachments: ${e}`;
|
|
19112
|
-
|
|
21027
|
+
log8.error(errMsg);
|
|
19113
21028
|
updateEntry(timelineDir, task.id, (entry) => {
|
|
19114
21029
|
entry.pid = null;
|
|
19115
21030
|
entry.status = "failed";
|
|
@@ -19126,32 +21041,301 @@ async function runSession(input) {
|
|
|
19126
21041
|
const prompt = input.promptOverride ?? buildPrompt(task, attachments);
|
|
19127
21042
|
const resumeSessionId = task.contextKey ? findResumableSessionByContextKey(timelineDir, task.contextKey, provider) ?? undefined : undefined;
|
|
19128
21043
|
if (resumeSessionId) {
|
|
19129
|
-
|
|
21044
|
+
log8.info(`resuming session ${resumeSessionId} (context_key: ${task.contextKey})`);
|
|
19130
21045
|
}
|
|
19131
21046
|
const session2 = backend.execute(prompt, {
|
|
19132
21047
|
cwd: workDir,
|
|
19133
21048
|
model: model || undefined,
|
|
19134
21049
|
env,
|
|
19135
21050
|
timeout: agentTimeout,
|
|
19136
|
-
resumeSessionId
|
|
21051
|
+
resumeSessionId,
|
|
21052
|
+
steeringEnabled: input.steeringEnabled
|
|
19137
21053
|
});
|
|
19138
21054
|
agentPid = session2.pid;
|
|
19139
21055
|
if (killed) {
|
|
19140
21056
|
if (agentPid !== undefined) {
|
|
19141
|
-
|
|
21057
|
+
log8.info(`kill landed during spawn — reaping inner agent group (pid=${agentPid})`);
|
|
19142
21058
|
await killProcessTree(agentPid);
|
|
19143
21059
|
}
|
|
19144
21060
|
process.exit(1);
|
|
19145
21061
|
}
|
|
19146
21062
|
const earlySessionId = await session2.sessionId;
|
|
19147
|
-
|
|
19148
|
-
|
|
21063
|
+
log8.info(`agent started (pid=${agentPid ?? "unknown"}, session=${earlySessionId})`);
|
|
21064
|
+
log8.info(JSON.stringify({ role: "user", type: "text", content: prompt }));
|
|
19149
21065
|
updateEntry(timelineDir, task.id, (entry) => {
|
|
19150
21066
|
entry.session_id = earlySessionId || null;
|
|
19151
21067
|
if (earlySessionId)
|
|
19152
21068
|
entry.agent_started = true;
|
|
19153
21069
|
});
|
|
19154
21070
|
flushTimer = setInterval(flushMessages, FLUSH_INTERVAL_MS);
|
|
21071
|
+
const turnState = new RuntimeTurnState;
|
|
21072
|
+
let apmState = createInitialApmState();
|
|
21073
|
+
const notificationState = new RuntimeNotificationState;
|
|
21074
|
+
const progressState = new RuntimeProgressState;
|
|
21075
|
+
const pendingSteeredTasks = new Set;
|
|
21076
|
+
const pendingAcks = [];
|
|
21077
|
+
let hasReceivedProgressEvent = false;
|
|
21078
|
+
if (input.steeringEnabled && input.steeringMailboxDir && task.contextKey) {
|
|
21079
|
+
const descriptor = session2.descriptor;
|
|
21080
|
+
const STALLED_THRESHOLD_MS = 120000;
|
|
21081
|
+
const STALLED_CHECK_INTERVAL_MS = 30000;
|
|
21082
|
+
if (session2.parsedEvents) {
|
|
21083
|
+
const parsedIter = session2.parsedEvents[Symbol.asyncIterator]();
|
|
21084
|
+
const consumeParsedEvents = async () => {
|
|
21085
|
+
try {
|
|
21086
|
+
while (!killed) {
|
|
21087
|
+
const { value: event, done } = await parsedIter.next();
|
|
21088
|
+
if (done)
|
|
21089
|
+
break;
|
|
21090
|
+
hasReceivedProgressEvent = true;
|
|
21091
|
+
progressState.processEvent(event);
|
|
21092
|
+
const recentResult = reduceApmGatedRecentEvent(apmState, { event: event.kind });
|
|
21093
|
+
apmState = recentResult.nextState;
|
|
21094
|
+
if (event.kind === "error") {
|
|
21095
|
+
const classified = classifyRuntimeError(event.message);
|
|
21096
|
+
log8.info(`steering: error classified as ${classified.errorClass}: ${scrubDiagnosticText(event.message)}`);
|
|
21097
|
+
const errResult = reduceApmGatedError(apmState, { disableToolBoundaryFlush: true });
|
|
21098
|
+
apmState = errResult.nextState;
|
|
21099
|
+
}
|
|
21100
|
+
switch (event.kind) {
|
|
21101
|
+
case "tool_call":
|
|
21102
|
+
case "thinking":
|
|
21103
|
+
case "compaction_started":
|
|
21104
|
+
turnState.markToolBoundary();
|
|
21105
|
+
break;
|
|
21106
|
+
case "text":
|
|
21107
|
+
case "tool_output":
|
|
21108
|
+
case "compaction_finished":
|
|
21109
|
+
turnState.markProgress();
|
|
21110
|
+
break;
|
|
21111
|
+
}
|
|
21112
|
+
switch (event.kind) {
|
|
21113
|
+
case "session_init":
|
|
21114
|
+
turnState.markTurnStarted(event.sessionId);
|
|
21115
|
+
break;
|
|
21116
|
+
case "text":
|
|
21117
|
+
if (!turnState.isInTurn)
|
|
21118
|
+
turnState.markTurnStarted();
|
|
21119
|
+
break;
|
|
21120
|
+
case "tool_call": {
|
|
21121
|
+
if (!turnState.isInTurn)
|
|
21122
|
+
turnState.markTurnStarted();
|
|
21123
|
+
const result2 = reduceApmGatedToolUse(apmState, { kind: "tool_call" });
|
|
21124
|
+
apmState = result2.nextState;
|
|
21125
|
+
break;
|
|
21126
|
+
}
|
|
21127
|
+
case "tool_output": {
|
|
21128
|
+
const result2 = reduceApmGatedToolUse(apmState, { kind: "tool_output" });
|
|
21129
|
+
apmState = result2.nextState;
|
|
21130
|
+
if (result2.shouldFlushToolBatch && session2.send && apmState.pendingMessages.length > 0) {
|
|
21131
|
+
const readiness = reduceApmGatedFlushReadiness(apmState, {
|
|
21132
|
+
isGated: descriptor?.busyDeliveryMode === "gated",
|
|
21133
|
+
hasSession: !!earlySessionId,
|
|
21134
|
+
inboxLength: apmState.pendingMessages.length,
|
|
21135
|
+
reason: "tool_batch_complete"
|
|
21136
|
+
});
|
|
21137
|
+
if (readiness.shouldNotify) {
|
|
21138
|
+
let allSent = true;
|
|
21139
|
+
for (const msg of apmState.pendingMessages) {
|
|
21140
|
+
const sendResult = session2.send(msg, "busy");
|
|
21141
|
+
if (!sendResult.ok) {
|
|
21142
|
+
allSent = false;
|
|
21143
|
+
break;
|
|
21144
|
+
}
|
|
21145
|
+
}
|
|
21146
|
+
if (allSent) {
|
|
21147
|
+
apmState = { ...apmState, pendingMessages: [] };
|
|
21148
|
+
for (const ack of pendingAcks) {
|
|
21149
|
+
notificationState.recordNoticeWritten(String(ack.seq), ack.sessionId, [{ id: String(ack.seq) }]);
|
|
21150
|
+
writeAck(agentBaseDir, task.contextKey, ack.seq);
|
|
21151
|
+
}
|
|
21152
|
+
pendingAcks.length = 0;
|
|
21153
|
+
}
|
|
21154
|
+
}
|
|
21155
|
+
}
|
|
21156
|
+
break;
|
|
21157
|
+
}
|
|
21158
|
+
case "compaction_started":
|
|
21159
|
+
case "compaction_finished": {
|
|
21160
|
+
const result2 = reduceApmGatedCompaction(apmState, { kind: event.kind });
|
|
21161
|
+
apmState = result2.nextState;
|
|
21162
|
+
if (event.kind === "compaction_finished" && session2.send && apmState.pendingMessages.length > 0) {
|
|
21163
|
+
const readiness = reduceApmGatedFlushReadiness(apmState, {
|
|
21164
|
+
isGated: descriptor?.busyDeliveryMode === "gated",
|
|
21165
|
+
hasSession: !!earlySessionId,
|
|
21166
|
+
inboxLength: apmState.pendingMessages.length,
|
|
21167
|
+
reason: "compaction_finished"
|
|
21168
|
+
});
|
|
21169
|
+
if (readiness.shouldNotify) {
|
|
21170
|
+
let allSent = true;
|
|
21171
|
+
for (const msg of apmState.pendingMessages) {
|
|
21172
|
+
const sendResult = session2.send(msg, "busy");
|
|
21173
|
+
if (!sendResult.ok) {
|
|
21174
|
+
allSent = false;
|
|
21175
|
+
break;
|
|
21176
|
+
}
|
|
21177
|
+
}
|
|
21178
|
+
if (allSent) {
|
|
21179
|
+
apmState = { ...apmState, pendingMessages: [] };
|
|
21180
|
+
for (const ack of pendingAcks) {
|
|
21181
|
+
notificationState.recordNoticeWritten(String(ack.seq), ack.sessionId, [{ id: String(ack.seq) }]);
|
|
21182
|
+
writeAck(agentBaseDir, task.contextKey, ack.seq);
|
|
21183
|
+
}
|
|
21184
|
+
pendingAcks.length = 0;
|
|
21185
|
+
}
|
|
21186
|
+
}
|
|
21187
|
+
}
|
|
21188
|
+
break;
|
|
21189
|
+
}
|
|
21190
|
+
case "turn_end": {
|
|
21191
|
+
const result2 = reduceApmGatedTurnEnd(apmState, {
|
|
21192
|
+
inboxLength: apmState.pendingMessages.length,
|
|
21193
|
+
supportsStdinNotification: descriptor?.supportsStdinNotification,
|
|
21194
|
+
hasSession: !!earlySessionId
|
|
21195
|
+
});
|
|
21196
|
+
apmState = result2.nextState;
|
|
21197
|
+
let flushedOk = false;
|
|
21198
|
+
for (const eff of result2.effects) {
|
|
21199
|
+
if (eff.kind === "deliver_stdin" && session2.send) {
|
|
21200
|
+
let allSent = true;
|
|
21201
|
+
for (const msg of apmState.pendingMessages) {
|
|
21202
|
+
const sendResult = session2.send(msg, eff.stdinMode);
|
|
21203
|
+
if (!sendResult.ok) {
|
|
21204
|
+
log8.warn("steering: send failed during turn_end flush", { reason: sendResult.reason });
|
|
21205
|
+
allSent = false;
|
|
21206
|
+
break;
|
|
21207
|
+
}
|
|
21208
|
+
}
|
|
21209
|
+
if (allSent) {
|
|
21210
|
+
apmState = { ...apmState, pendingMessages: [] };
|
|
21211
|
+
flushedOk = true;
|
|
21212
|
+
}
|
|
21213
|
+
}
|
|
21214
|
+
}
|
|
21215
|
+
if (flushedOk && pendingAcks.length > 0) {
|
|
21216
|
+
for (const ack of pendingAcks) {
|
|
21217
|
+
notificationState.recordNoticeWritten(String(ack.seq), ack.sessionId, [{ id: String(ack.seq) }]);
|
|
21218
|
+
writeAck(agentBaseDir, task.contextKey, ack.seq);
|
|
21219
|
+
}
|
|
21220
|
+
pendingAcks.length = 0;
|
|
21221
|
+
}
|
|
21222
|
+
if (flushedOk || apmState.pendingMessages.length === 0) {
|
|
21223
|
+
for (const steeredId of pendingSteeredTasks) {
|
|
21224
|
+
client.completeTask(token, steeredId, { output: "" }).catch((e) => {
|
|
21225
|
+
log8.debug(`steering: failed to complete steered task ${steeredId}`, e);
|
|
21226
|
+
});
|
|
21227
|
+
}
|
|
21228
|
+
pendingSteeredTasks.clear();
|
|
21229
|
+
}
|
|
21230
|
+
turnState.markTurnCompleted();
|
|
21231
|
+
break;
|
|
21232
|
+
}
|
|
21233
|
+
}
|
|
21234
|
+
}
|
|
21235
|
+
} catch (err) {
|
|
21236
|
+
log8.warn("steering: consumeParsedEvents error", { err: err instanceof Error ? err.message : String(err) });
|
|
21237
|
+
}
|
|
21238
|
+
};
|
|
21239
|
+
consumeParsedEvents().catch((err) => {
|
|
21240
|
+
log8.error("steering: consumeParsedEvents unhandled error", { err: err instanceof Error ? err.message : String(err) });
|
|
21241
|
+
});
|
|
21242
|
+
}
|
|
21243
|
+
stalledRecoveryTimer = setInterval(() => {
|
|
21244
|
+
if (killed)
|
|
21245
|
+
return;
|
|
21246
|
+
if (!hasReceivedProgressEvent) {
|
|
21247
|
+
const startupResult = reduceApmStartupTimeoutTermination(apmState, {
|
|
21248
|
+
hasRuntimeProgressEvent: hasReceivedProgressEvent
|
|
21249
|
+
});
|
|
21250
|
+
apmState = startupResult.nextState;
|
|
21251
|
+
if (startupResult.shouldTerminate) {
|
|
21252
|
+
log8.warn("steering: startup timeout — no progress events received, killing agent");
|
|
21253
|
+
if (agentPid !== undefined)
|
|
21254
|
+
killProcessTree(agentPid);
|
|
21255
|
+
return;
|
|
21256
|
+
}
|
|
21257
|
+
}
|
|
21258
|
+
const staleForMs = progressState.ageMs();
|
|
21259
|
+
if (staleForMs > STALLED_THRESHOLD_MS && !progressState.isStale) {
|
|
21260
|
+
progressState.markStale();
|
|
21261
|
+
}
|
|
21262
|
+
const stalledResult = reduceApmStalledRecoveryTermination(apmState, {
|
|
21263
|
+
inboxLength: apmState.pendingMessages.length,
|
|
21264
|
+
staleForMs,
|
|
21265
|
+
staleThresholdMs: STALLED_THRESHOLD_MS,
|
|
21266
|
+
runtimeProgressIsStale: progressState.isStale,
|
|
21267
|
+
hasSession: !!earlySessionId,
|
|
21268
|
+
busyDeliveryMode: descriptor?.busyDeliveryMode ?? "none",
|
|
21269
|
+
hasDirectStdinRecoveryEvidence: false
|
|
21270
|
+
});
|
|
21271
|
+
apmState = stalledResult.nextState;
|
|
21272
|
+
if (stalledResult.shouldTerminate) {
|
|
21273
|
+
log8.warn(`steering: stalled recovery — agent stale for ${(staleForMs / 1000).toFixed(1)}s with ${apmState.pendingMessages.length} pending messages, killing`);
|
|
21274
|
+
if (agentPid !== undefined)
|
|
21275
|
+
killProcessTree(agentPid);
|
|
21276
|
+
}
|
|
21277
|
+
}, STALLED_CHECK_INTERVAL_MS);
|
|
21278
|
+
mailboxWatcher = watchInbox(agentBaseDir, task.contextKey, (seq2, message2) => {
|
|
21279
|
+
const sessionId = earlySessionId || "";
|
|
21280
|
+
if (notificationState.isDuplicateNotice(String(seq2), sessionId)) {
|
|
21281
|
+
writeAck(agentBaseDir, task.contextKey, seq2);
|
|
21282
|
+
cleanupInboxFile(agentBaseDir, task.contextKey, seq2);
|
|
21283
|
+
return;
|
|
21284
|
+
}
|
|
21285
|
+
const busyMode = session2.descriptor?.busyDeliveryMode;
|
|
21286
|
+
let delivered = false;
|
|
21287
|
+
if (busyMode === "direct" && session2.send) {
|
|
21288
|
+
const result2 = session2.send(message2.text, turnState.isInTurn ? "busy" : "idle");
|
|
21289
|
+
if (result2.ok) {
|
|
21290
|
+
notificationState.recordNoticeWritten(String(seq2), sessionId, [{ id: String(seq2) }]);
|
|
21291
|
+
writeAck(agentBaseDir, task.contextKey, seq2);
|
|
21292
|
+
delivered = true;
|
|
21293
|
+
} else {
|
|
21294
|
+
writeNack(agentBaseDir, task.contextKey, seq2, result2.reason || "send failed");
|
|
21295
|
+
}
|
|
21296
|
+
} else if (busyMode === "gated") {
|
|
21297
|
+
const enqueueResult = reduceApmGatedEnqueue(apmState, message2.text);
|
|
21298
|
+
apmState = enqueueResult.nextState;
|
|
21299
|
+
if (turnState.canSteerBusy && session2.send && apmState.pendingMessages.length > 0) {
|
|
21300
|
+
const readiness = reduceApmGatedFlushReadiness(apmState, {
|
|
21301
|
+
isGated: true,
|
|
21302
|
+
hasSession: !!earlySessionId,
|
|
21303
|
+
inboxLength: apmState.pendingMessages.length,
|
|
21304
|
+
reason: "enqueue"
|
|
21305
|
+
});
|
|
21306
|
+
if (readiness.shouldNotify) {
|
|
21307
|
+
let allSent = true;
|
|
21308
|
+
for (const msg of apmState.pendingMessages) {
|
|
21309
|
+
const sendResult = session2.send(msg, "busy");
|
|
21310
|
+
if (!sendResult.ok) {
|
|
21311
|
+
allSent = false;
|
|
21312
|
+
break;
|
|
21313
|
+
}
|
|
21314
|
+
}
|
|
21315
|
+
if (allSent) {
|
|
21316
|
+
apmState = { ...apmState, pendingMessages: [] };
|
|
21317
|
+
}
|
|
21318
|
+
}
|
|
21319
|
+
}
|
|
21320
|
+
if (apmState.pendingMessages.length === 0) {
|
|
21321
|
+
notificationState.recordNoticeWritten(String(seq2), sessionId, [{ id: String(seq2) }]);
|
|
21322
|
+
writeAck(agentBaseDir, task.contextKey, seq2);
|
|
21323
|
+
} else {
|
|
21324
|
+
pendingAcks.push({ seq: seq2, sessionId });
|
|
21325
|
+
}
|
|
21326
|
+
delivered = true;
|
|
21327
|
+
} else {
|
|
21328
|
+
writeNack(agentBaseDir, task.contextKey, seq2, "unsupported backend");
|
|
21329
|
+
}
|
|
21330
|
+
if (delivered && message2.taskId) {
|
|
21331
|
+
pendingSteeredTasks.add(message2.taskId);
|
|
21332
|
+
client.startTask(token, message2.taskId).catch((e) => {
|
|
21333
|
+
log8.debug(`steering: failed to start steered task ${message2.taskId}`, e);
|
|
21334
|
+
});
|
|
21335
|
+
}
|
|
21336
|
+
cleanupInboxFile(agentBaseDir, task.contextKey, seq2);
|
|
21337
|
+
});
|
|
21338
|
+
}
|
|
19155
21339
|
const INACTIVITY_TIMEOUT_MS = messageInactivityTimeout ?? 5 * 60 * 1000;
|
|
19156
21340
|
let inactivityTimedOut = false;
|
|
19157
21341
|
try {
|
|
@@ -19167,7 +21351,7 @@ async function runSession(input) {
|
|
|
19167
21351
|
]) : next);
|
|
19168
21352
|
if (raceResult === "timeout") {
|
|
19169
21353
|
inactivityTimedOut = true;
|
|
19170
|
-
|
|
21354
|
+
log8.warn(`message inactivity timeout (${INACTIVITY_TIMEOUT_MS / 1000}s) — killing agent`);
|
|
19171
21355
|
if (session2.pid !== undefined) {
|
|
19172
21356
|
await killProcessTree(session2.pid);
|
|
19173
21357
|
}
|
|
@@ -19182,9 +21366,9 @@ async function runSession(input) {
|
|
|
19182
21366
|
if (msg.type === "tool-use")
|
|
19183
21367
|
toolCount++;
|
|
19184
21368
|
if (msg.type === "tool-result" && msg.output && msg.output.length > 500) {
|
|
19185
|
-
|
|
21369
|
+
log8.info(JSON.stringify({ role: "assistant", ...msg, output: msg.output.slice(0, 500) + `... (${msg.output.length} chars)` }));
|
|
19186
21370
|
} else {
|
|
19187
|
-
|
|
21371
|
+
log8.info(JSON.stringify({ role: "assistant", ...msg }));
|
|
19188
21372
|
}
|
|
19189
21373
|
if (msg.type === "status" || msg.type === "log")
|
|
19190
21374
|
continue;
|
|
@@ -19223,6 +21407,13 @@ async function runSession(input) {
|
|
|
19223
21407
|
result.status = "failed";
|
|
19224
21408
|
result.error = `message inactivity timeout (no messages for ${INACTIVITY_TIMEOUT_MS / 1000}s)`;
|
|
19225
21409
|
}
|
|
21410
|
+
if (stalledRecoveryTimer)
|
|
21411
|
+
clearInterval(stalledRecoveryTimer);
|
|
21412
|
+
if (mailboxWatcher) {
|
|
21413
|
+
mailboxWatcher.stop();
|
|
21414
|
+
if (task.contextKey)
|
|
21415
|
+
cleanupSteeringDir(agentBaseDir, task.contextKey);
|
|
21416
|
+
}
|
|
19226
21417
|
await cleanupAttachments(task.id);
|
|
19227
21418
|
if (result.status === "completed") {
|
|
19228
21419
|
updateEntry(timelineDir, task.id, (entry) => {
|
|
@@ -19245,18 +21436,18 @@ async function runSession(input) {
|
|
|
19245
21436
|
body.session_id = result.sessionId;
|
|
19246
21437
|
await reportToServer(() => client.completeTask(token, task.id, body), { taskId: task.id, type: "complete", payload: body, token, serverURL, createdAt: new Date().toISOString() }, workspacesRoot);
|
|
19247
21438
|
const dur = (result.durationMs / 1000).toFixed(1);
|
|
19248
|
-
|
|
21439
|
+
log8.info(`completed (duration=${dur}s, messages=${seq}, tools=${toolCount})`);
|
|
19249
21440
|
} else {
|
|
19250
21441
|
const errorMsg = result.error || "agent exited unexpectedly";
|
|
19251
21442
|
await reportToServer(() => client.failTask(token, task.id, errorMsg), { taskId: task.id, type: "fail", payload: { error: errorMsg }, token, serverURL, createdAt: new Date().toISOString() }, workspacesRoot);
|
|
19252
21443
|
const dur = (result.durationMs / 1000).toFixed(1);
|
|
19253
|
-
|
|
21444
|
+
log8.info(`failed (duration=${dur}s, messages=${seq}, tools=${toolCount}) — ${result.error}`);
|
|
19254
21445
|
}
|
|
19255
21446
|
}
|
|
19256
21447
|
async function main() {
|
|
19257
21448
|
const encoded = process.argv[2];
|
|
19258
21449
|
if (!encoded) {
|
|
19259
|
-
|
|
21450
|
+
log8.error("session-runner: missing base64-encoded input argument");
|
|
19260
21451
|
process.exit(1);
|
|
19261
21452
|
}
|
|
19262
21453
|
let input;
|
|
@@ -19264,14 +21455,14 @@ async function main() {
|
|
|
19264
21455
|
const json2 = Buffer.from(encoded, "base64").toString("utf-8");
|
|
19265
21456
|
input = JSON.parse(json2);
|
|
19266
21457
|
} catch (e) {
|
|
19267
|
-
|
|
21458
|
+
log8.error("session-runner: failed to parse input", e);
|
|
19268
21459
|
process.exit(1);
|
|
19269
21460
|
}
|
|
19270
21461
|
const client = new DaemonClient(input.serverURL);
|
|
19271
21462
|
try {
|
|
19272
21463
|
await runSession(input);
|
|
19273
21464
|
} catch (e) {
|
|
19274
|
-
|
|
21465
|
+
log8.error(`session-runner: unhandled error for task ${input.task.id}`, e);
|
|
19275
21466
|
await cleanupAttachments(input.task.id);
|
|
19276
21467
|
const timelineDir = path.join(input.workspacesRoot, input.task.workspaceId, input.task.agentId, "workdir", ".context_timeline").replace(/\\/g, "/");
|
|
19277
21468
|
updateEntry(timelineDir, input.task.id, (entry) => {
|