@alook/daemon 0.1.18 → 0.1.19
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/cli/index.js +82 -24
- package/dist/index.js +29 -21
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -17736,6 +17736,7 @@ __export(exports_community_schema, {
|
|
|
17736
17736
|
communityServerFolderItem: () => communityServerFolderItem,
|
|
17737
17737
|
communityServerFolder: () => communityServerFolder,
|
|
17738
17738
|
communityServer: () => communityServer,
|
|
17739
|
+
communityReadStateRevision: () => communityReadStateRevision,
|
|
17739
17740
|
communityReadState: () => communityReadState,
|
|
17740
17741
|
communityReaction: () => communityReaction,
|
|
17741
17742
|
communityPin: () => communityPin,
|
|
@@ -17900,6 +17901,10 @@ var communityReadState = sqliteTable("community_read_state", {
|
|
|
17900
17901
|
lastReadMessageId: text("last_read_message_id"),
|
|
17901
17902
|
lastReadSeq: integer2("last_read_seq").notNull().default(0)
|
|
17902
17903
|
}, (t) => [index("idx_read_state_user").on(t.userId)]);
|
|
17904
|
+
var communityReadStateRevision = sqliteTable("community_read_state_revision", {
|
|
17905
|
+
userId: text("user_id").primaryKey().references(() => user.id, { onDelete: "cascade" }),
|
|
17906
|
+
revision: integer2("revision").notNull().default(0)
|
|
17907
|
+
});
|
|
17903
17908
|
var communityReaction = sqliteTable("community_reaction", {
|
|
17904
17909
|
id: text("id").primaryKey().$defaultFn(() => nanoid3()),
|
|
17905
17910
|
messageId: text("message_id").notNull().references(() => communityMessage.id, { onDelete: "cascade" }),
|
|
@@ -18493,6 +18498,24 @@ var communityUnreadBumpSchema = exports_external.strictObject({
|
|
|
18493
18498
|
railChannelId: string4.optional(),
|
|
18494
18499
|
isMention: exports_external.boolean().optional()
|
|
18495
18500
|
});
|
|
18501
|
+
var readStateEnvelopeFields = {
|
|
18502
|
+
revision: exports_external.number().int().positive(),
|
|
18503
|
+
inboxChanged: exports_external.literal(true)
|
|
18504
|
+
};
|
|
18505
|
+
var communityReadStateAdvancedSchema = exports_external.strictObject({
|
|
18506
|
+
type: exports_external.literal("community:read_state.advanced"),
|
|
18507
|
+
...readStateEnvelopeFields
|
|
18508
|
+
});
|
|
18509
|
+
var communityInboxChangedSchema = exports_external.strictObject({
|
|
18510
|
+
type: exports_external.literal("community:inbox.changed"),
|
|
18511
|
+
...readStateEnvelopeFields,
|
|
18512
|
+
reason: exports_external.enum([
|
|
18513
|
+
"read_all",
|
|
18514
|
+
"mention_read_all",
|
|
18515
|
+
"mention_dismiss",
|
|
18516
|
+
"notification_policy"
|
|
18517
|
+
])
|
|
18518
|
+
});
|
|
18496
18519
|
var communityPresenceUpdateSchema = exports_external.strictObject({
|
|
18497
18520
|
type: exports_external.literal("community:presence.update"),
|
|
18498
18521
|
userId: string4,
|
|
@@ -18588,6 +18611,8 @@ var CommunityWsEventDiscriminatedSchema = exports_external.discriminatedUnion("t
|
|
|
18588
18611
|
communityInviteCreateSchema,
|
|
18589
18612
|
communityMentionCreateSchema,
|
|
18590
18613
|
communityUnreadBumpSchema,
|
|
18614
|
+
communityReadStateAdvancedSchema,
|
|
18615
|
+
communityInboxChangedSchema,
|
|
18591
18616
|
communityPresenceUpdateSchema,
|
|
18592
18617
|
communityStatusUpdateSchema,
|
|
18593
18618
|
communityMachineCreatedSchema,
|
|
@@ -18632,6 +18657,8 @@ var WS_EVENTS = {
|
|
|
18632
18657
|
INVITE_CREATE: "community:invite.create",
|
|
18633
18658
|
MENTION_CREATE: "community:mention.create",
|
|
18634
18659
|
UNREAD_BUMP: "community:unread.bump",
|
|
18660
|
+
READ_STATE_ADVANCED: "community:read_state.advanced",
|
|
18661
|
+
INBOX_CHANGED: "community:inbox.changed",
|
|
18635
18662
|
PRESENCE_UPDATE: "community:presence.update",
|
|
18636
18663
|
STATUS_UPDATE: "community:status.update",
|
|
18637
18664
|
MACHINE_CREATED: "community:machine.created",
|
|
@@ -27781,6 +27808,9 @@ class AgentProcessManager {
|
|
|
27781
27808
|
snapshot() {
|
|
27782
27809
|
return this.state;
|
|
27783
27810
|
}
|
|
27811
|
+
runningAgentCount() {
|
|
27812
|
+
return this.sessions.size;
|
|
27813
|
+
}
|
|
27784
27814
|
auditContext(agentId) {
|
|
27785
27815
|
return {
|
|
27786
27816
|
sessionId: this.liveSessions.get(agentId) ?? null,
|
|
@@ -28902,6 +28932,7 @@ Then read @memory.md and your .context_timeline for durable context, and pull `
|
|
|
28902
28932
|
class AgentRouter {
|
|
28903
28933
|
opts;
|
|
28904
28934
|
running = new Set;
|
|
28935
|
+
nextWakeAdmissionOrdinal = 1;
|
|
28905
28936
|
runtimes = new Map;
|
|
28906
28937
|
pendingResend = false;
|
|
28907
28938
|
scheduleResend;
|
|
@@ -29062,7 +29093,7 @@ class AgentRouter {
|
|
|
29062
29093
|
this.opts.typingTracker?.add(cmd.agentId, channelScope);
|
|
29063
29094
|
const text2 = (this.opts.formatUnreadNoticeText ?? defaultFormatUnreadNoticeText)(cmd.unreadNotice);
|
|
29064
29095
|
const producedEffect = this.opts.manager.deliver(cmd.agentId, {
|
|
29065
|
-
id: `${cmd.agentId}:wake:${cmd.unreadNotice.channel}:${cmd.unreadNotice.latestSeq}`,
|
|
29096
|
+
id: `${cmd.agentId}:wake:${cmd.unreadNotice.channel}:${cmd.unreadNotice.latestSeq}:admission:${this.nextWakeAdmissionOrdinal++}`,
|
|
29066
29097
|
seq: cmd.unreadNotice.latestSeq,
|
|
29067
29098
|
text: text2
|
|
29068
29099
|
});
|
|
@@ -31054,6 +31085,7 @@ async function createDaemon(opts) {
|
|
|
31054
31085
|
typingTracker.clear(agentId);
|
|
31055
31086
|
}
|
|
31056
31087
|
const botsById = new Map;
|
|
31088
|
+
let botCacheReady = false;
|
|
31057
31089
|
async function listMyBotsHttp() {
|
|
31058
31090
|
const res = await fetch(`${opts.serverUrl}/api/community/daemon/bots`, {
|
|
31059
31091
|
method: "GET",
|
|
@@ -31064,22 +31096,26 @@ async function createDaemon(opts) {
|
|
|
31064
31096
|
const json2 = await res.json();
|
|
31065
31097
|
return json2.bots ?? [];
|
|
31066
31098
|
}
|
|
31099
|
+
function replaceBotCache(bots) {
|
|
31100
|
+
botsById.clear();
|
|
31101
|
+
for (const b of bots) {
|
|
31102
|
+
botsById.set(b.id, {
|
|
31103
|
+
name: b.name,
|
|
31104
|
+
discriminator: b.discriminator,
|
|
31105
|
+
description: b.description,
|
|
31106
|
+
ownerName: b.ownerName,
|
|
31107
|
+
ownerDiscriminator: b.ownerDiscriminator
|
|
31108
|
+
});
|
|
31109
|
+
}
|
|
31110
|
+
botCacheReady = true;
|
|
31111
|
+
}
|
|
31067
31112
|
async function coldStartWarmup() {
|
|
31068
31113
|
const start = Date.now();
|
|
31069
31114
|
let attempt = 0;
|
|
31070
31115
|
while (Date.now() - start < WARMUP_CEILING_MS) {
|
|
31071
31116
|
try {
|
|
31072
31117
|
const bots = await listMyBotsHttp();
|
|
31073
|
-
|
|
31074
|
-
for (const b of bots) {
|
|
31075
|
-
botsById.set(b.id, {
|
|
31076
|
-
name: b.name,
|
|
31077
|
-
discriminator: b.discriminator,
|
|
31078
|
-
description: b.description,
|
|
31079
|
-
ownerName: b.ownerName,
|
|
31080
|
-
ownerDiscriminator: b.ownerDiscriminator
|
|
31081
|
-
});
|
|
31082
|
-
}
|
|
31118
|
+
replaceBotCache(bots);
|
|
31083
31119
|
log2.info("cold-start bot-cache warmup succeeded", { bots: bots.length, attempt });
|
|
31084
31120
|
return;
|
|
31085
31121
|
} catch {
|
|
@@ -31300,7 +31336,14 @@ async function createDaemon(opts) {
|
|
|
31300
31336
|
const statusPath = opts.statusFilePath;
|
|
31301
31337
|
const writeStatus = () => {
|
|
31302
31338
|
const nowMs = Date.now();
|
|
31303
|
-
writeStatusFile(statusPath, {
|
|
31339
|
+
writeStatusFile(statusPath, {
|
|
31340
|
+
writtenAt: nowMs,
|
|
31341
|
+
agentSummary: {
|
|
31342
|
+
total: botCacheReady ? botsById.size : null,
|
|
31343
|
+
running: manager.runningAgentCount()
|
|
31344
|
+
},
|
|
31345
|
+
agents: manager.statusProjection(nowMs)
|
|
31346
|
+
});
|
|
31304
31347
|
};
|
|
31305
31348
|
writeStatus();
|
|
31306
31349
|
statusTimer = setInterval(writeStatus, STATUS_WRITE_INTERVAL_MS);
|
|
@@ -31325,15 +31368,7 @@ async function createDaemon(opts) {
|
|
|
31325
31368
|
if (!botsById.has(agentId)) {
|
|
31326
31369
|
try {
|
|
31327
31370
|
const bots = await listMyBotsHttp();
|
|
31328
|
-
|
|
31329
|
-
botsById.set(b.id, {
|
|
31330
|
-
name: b.name,
|
|
31331
|
-
discriminator: b.discriminator,
|
|
31332
|
-
description: b.description,
|
|
31333
|
-
ownerName: b.ownerName,
|
|
31334
|
-
ownerDiscriminator: b.ownerDiscriminator
|
|
31335
|
-
});
|
|
31336
|
-
}
|
|
31371
|
+
replaceBotCache(bots);
|
|
31337
31372
|
} catch {}
|
|
31338
31373
|
}
|
|
31339
31374
|
if (!botsById.has(agentId)) {
|
|
@@ -33649,8 +33684,13 @@ function daemonList(opts) {
|
|
|
33649
33684
|
if (alive && statusPath) {
|
|
33650
33685
|
const s = daemonStatusFromFile(statusPath, now);
|
|
33651
33686
|
if (s.found) {
|
|
33652
|
-
|
|
33653
|
-
|
|
33687
|
+
if (s.agentSummary) {
|
|
33688
|
+
agents = s.agentSummary.total;
|
|
33689
|
+
running = s.agentSummary.running;
|
|
33690
|
+
} else {
|
|
33691
|
+
agents = s.agents.length;
|
|
33692
|
+
running = s.agents.filter((a) => a.derivedActivity === "running").length;
|
|
33693
|
+
}
|
|
33654
33694
|
lastActiveMs = daemonLastActiveMs(s, now);
|
|
33655
33695
|
}
|
|
33656
33696
|
}
|
|
@@ -33665,7 +33705,24 @@ function daemonList(opts) {
|
|
|
33665
33705
|
return results;
|
|
33666
33706
|
}
|
|
33667
33707
|
var STATUS_STALE_MS = 20000;
|
|
33668
|
-
var MISSING_STATUS = {
|
|
33708
|
+
var MISSING_STATUS = {
|
|
33709
|
+
found: false,
|
|
33710
|
+
ageMs: null,
|
|
33711
|
+
freshness: "missing",
|
|
33712
|
+
writtenAt: null,
|
|
33713
|
+
agentSummary: null,
|
|
33714
|
+
agents: []
|
|
33715
|
+
};
|
|
33716
|
+
function validAgentSummary(value) {
|
|
33717
|
+
if (!value || typeof value !== "object")
|
|
33718
|
+
return null;
|
|
33719
|
+
const summary = value;
|
|
33720
|
+
const validTotal = summary.total === null || Number.isInteger(summary.total) && summary.total >= 0;
|
|
33721
|
+
const validRunning = Number.isInteger(summary.running) && summary.running >= 0;
|
|
33722
|
+
if (!validTotal || !validRunning)
|
|
33723
|
+
return null;
|
|
33724
|
+
return { total: summary.total, running: summary.running };
|
|
33725
|
+
}
|
|
33669
33726
|
function daemonStatusFromFile(statusPath, nowMs) {
|
|
33670
33727
|
if (!fs12.existsSync(statusPath))
|
|
33671
33728
|
return MISSING_STATUS;
|
|
@@ -33677,6 +33734,7 @@ function daemonStatusFromFile(statusPath, nowMs) {
|
|
|
33677
33734
|
ageMs,
|
|
33678
33735
|
freshness: ageMs <= STATUS_STALE_MS ? "fresh" : "stale",
|
|
33679
33736
|
writtenAt: snap.writtenAt,
|
|
33737
|
+
agentSummary: validAgentSummary(snap.agentSummary),
|
|
33680
33738
|
agents: Array.isArray(snap.agents) ? snap.agents : []
|
|
33681
33739
|
};
|
|
33682
33740
|
} catch {
|
package/dist/index.js
CHANGED
|
@@ -8025,6 +8025,9 @@ class AgentProcessManager {
|
|
|
8025
8025
|
snapshot() {
|
|
8026
8026
|
return this.state;
|
|
8027
8027
|
}
|
|
8028
|
+
runningAgentCount() {
|
|
8029
|
+
return this.sessions.size;
|
|
8030
|
+
}
|
|
8028
8031
|
auditContext(agentId) {
|
|
8029
8032
|
return {
|
|
8030
8033
|
sessionId: this.liveSessions.get(agentId) ?? null,
|
|
@@ -25814,6 +25817,7 @@ Then read @memory.md and your .context_timeline for durable context, and pull `
|
|
|
25814
25817
|
class AgentRouter {
|
|
25815
25818
|
opts;
|
|
25816
25819
|
running = new Set;
|
|
25820
|
+
nextWakeAdmissionOrdinal = 1;
|
|
25817
25821
|
runtimes = new Map;
|
|
25818
25822
|
pendingResend = false;
|
|
25819
25823
|
scheduleResend;
|
|
@@ -25974,7 +25978,7 @@ class AgentRouter {
|
|
|
25974
25978
|
this.opts.typingTracker?.add(cmd.agentId, channelScope);
|
|
25975
25979
|
const text2 = (this.opts.formatUnreadNoticeText ?? defaultFormatUnreadNoticeText)(cmd.unreadNotice);
|
|
25976
25980
|
const producedEffect = this.opts.manager.deliver(cmd.agentId, {
|
|
25977
|
-
id: `${cmd.agentId}:wake:${cmd.unreadNotice.channel}:${cmd.unreadNotice.latestSeq}`,
|
|
25981
|
+
id: `${cmd.agentId}:wake:${cmd.unreadNotice.channel}:${cmd.unreadNotice.latestSeq}:admission:${this.nextWakeAdmissionOrdinal++}`,
|
|
25978
25982
|
seq: cmd.unreadNotice.latestSeq,
|
|
25979
25983
|
text: text2
|
|
25980
25984
|
});
|
|
@@ -29309,6 +29313,7 @@ async function createDaemon(opts) {
|
|
|
29309
29313
|
typingTracker.clear(agentId);
|
|
29310
29314
|
}
|
|
29311
29315
|
const botsById = new Map;
|
|
29316
|
+
let botCacheReady = false;
|
|
29312
29317
|
async function listMyBotsHttp() {
|
|
29313
29318
|
const res = await fetch(`${opts.serverUrl}/api/community/daemon/bots`, {
|
|
29314
29319
|
method: "GET",
|
|
@@ -29319,22 +29324,26 @@ async function createDaemon(opts) {
|
|
|
29319
29324
|
const json2 = await res.json();
|
|
29320
29325
|
return json2.bots ?? [];
|
|
29321
29326
|
}
|
|
29327
|
+
function replaceBotCache(bots) {
|
|
29328
|
+
botsById.clear();
|
|
29329
|
+
for (const b of bots) {
|
|
29330
|
+
botsById.set(b.id, {
|
|
29331
|
+
name: b.name,
|
|
29332
|
+
discriminator: b.discriminator,
|
|
29333
|
+
description: b.description,
|
|
29334
|
+
ownerName: b.ownerName,
|
|
29335
|
+
ownerDiscriminator: b.ownerDiscriminator
|
|
29336
|
+
});
|
|
29337
|
+
}
|
|
29338
|
+
botCacheReady = true;
|
|
29339
|
+
}
|
|
29322
29340
|
async function coldStartWarmup() {
|
|
29323
29341
|
const start = Date.now();
|
|
29324
29342
|
let attempt = 0;
|
|
29325
29343
|
while (Date.now() - start < WARMUP_CEILING_MS) {
|
|
29326
29344
|
try {
|
|
29327
29345
|
const bots = await listMyBotsHttp();
|
|
29328
|
-
|
|
29329
|
-
for (const b of bots) {
|
|
29330
|
-
botsById.set(b.id, {
|
|
29331
|
-
name: b.name,
|
|
29332
|
-
discriminator: b.discriminator,
|
|
29333
|
-
description: b.description,
|
|
29334
|
-
ownerName: b.ownerName,
|
|
29335
|
-
ownerDiscriminator: b.ownerDiscriminator
|
|
29336
|
-
});
|
|
29337
|
-
}
|
|
29346
|
+
replaceBotCache(bots);
|
|
29338
29347
|
log.info("cold-start bot-cache warmup succeeded", { bots: bots.length, attempt });
|
|
29339
29348
|
return;
|
|
29340
29349
|
} catch {
|
|
@@ -29555,7 +29564,14 @@ async function createDaemon(opts) {
|
|
|
29555
29564
|
const statusPath = opts.statusFilePath;
|
|
29556
29565
|
const writeStatus = () => {
|
|
29557
29566
|
const nowMs = Date.now();
|
|
29558
|
-
writeStatusFile(statusPath, {
|
|
29567
|
+
writeStatusFile(statusPath, {
|
|
29568
|
+
writtenAt: nowMs,
|
|
29569
|
+
agentSummary: {
|
|
29570
|
+
total: botCacheReady ? botsById.size : null,
|
|
29571
|
+
running: manager.runningAgentCount()
|
|
29572
|
+
},
|
|
29573
|
+
agents: manager.statusProjection(nowMs)
|
|
29574
|
+
});
|
|
29559
29575
|
};
|
|
29560
29576
|
writeStatus();
|
|
29561
29577
|
statusTimer = setInterval(writeStatus, STATUS_WRITE_INTERVAL_MS);
|
|
@@ -29580,15 +29596,7 @@ async function createDaemon(opts) {
|
|
|
29580
29596
|
if (!botsById.has(agentId)) {
|
|
29581
29597
|
try {
|
|
29582
29598
|
const bots = await listMyBotsHttp();
|
|
29583
|
-
|
|
29584
|
-
botsById.set(b.id, {
|
|
29585
|
-
name: b.name,
|
|
29586
|
-
discriminator: b.discriminator,
|
|
29587
|
-
description: b.description,
|
|
29588
|
-
ownerName: b.ownerName,
|
|
29589
|
-
ownerDiscriminator: b.ownerDiscriminator
|
|
29590
|
-
});
|
|
29591
|
-
}
|
|
29599
|
+
replaceBotCache(bots);
|
|
29592
29600
|
} catch {}
|
|
29593
29601
|
}
|
|
29594
29602
|
if (!botsById.has(agentId)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alook/daemon",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.19",
|
|
4
4
|
"description": "Alook agent daemon — host-side runtime backend, process manager, credential proxy, and control plane.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://github.com/alookai/alook#readme",
|