@prismer/runtime 2.0.5 → 2.0.6
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.cjs +58 -18
- package/dist/cli.js +58 -18
- package/dist/index.cjs +58 -18
- package/dist/index.d.cts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +58 -18
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -2268,7 +2268,7 @@ var require_package = __commonJS({
|
|
|
2268
2268
|
"package.json"(exports2, module2) {
|
|
2269
2269
|
module2.exports = {
|
|
2270
2270
|
name: "@prismer/runtime",
|
|
2271
|
-
version: "2.0.
|
|
2271
|
+
version: "2.0.6",
|
|
2272
2272
|
description: "Prismer Cloud daemon runtime \u2014 TS-only adapter host for hosted IM agents",
|
|
2273
2273
|
type: "module",
|
|
2274
2274
|
main: "dist/index.js",
|
|
@@ -12795,6 +12795,7 @@ var Runner = class extends import_node_events3.EventEmitter {
|
|
|
12795
12795
|
workspaceId = "";
|
|
12796
12796
|
wsConnected = false;
|
|
12797
12797
|
hostedAgents = /* @__PURE__ */ new Map();
|
|
12798
|
+
rejectedHostedAgentIds = /* @__PURE__ */ new Map();
|
|
12798
12799
|
runningTasks = /* @__PURE__ */ new Map();
|
|
12799
12800
|
lastTaskError;
|
|
12800
12801
|
heartbeatTimer;
|
|
@@ -13240,6 +13241,9 @@ var Runner = class extends import_node_events3.EventEmitter {
|
|
|
13240
13241
|
profilesByAgent.set(p.agent_im_user_id, list);
|
|
13241
13242
|
}
|
|
13242
13243
|
for (const a of agents) {
|
|
13244
|
+
if (this.rejectedHostedAgentIds.has(a.im_user_id)) {
|
|
13245
|
+
continue;
|
|
13246
|
+
}
|
|
13243
13247
|
let caps = [];
|
|
13244
13248
|
try {
|
|
13245
13249
|
caps = JSON.parse(a.capabilities);
|
|
@@ -13289,6 +13293,7 @@ var Runner = class extends import_node_events3.EventEmitter {
|
|
|
13289
13293
|
* Used to populate the `agents` list in agent.host.declare.
|
|
13290
13294
|
*/
|
|
13291
13295
|
setHostedAgent(agent) {
|
|
13296
|
+
this.rejectedHostedAgentIds.delete(agent.imUserId);
|
|
13292
13297
|
this.hostedAgents.set(agent.imUserId, {
|
|
13293
13298
|
imUserId: agent.imUserId,
|
|
13294
13299
|
name: agent.name,
|
|
@@ -13321,6 +13326,7 @@ var Runner = class extends import_node_events3.EventEmitter {
|
|
|
13321
13326
|
);
|
|
13322
13327
|
});
|
|
13323
13328
|
tx(payload);
|
|
13329
|
+
this.rejectedHostedAgentIds.delete(payload.imUserId);
|
|
13324
13330
|
this.loadAgentsFromDb();
|
|
13325
13331
|
if (this.wsConnected) this.sendDeclare();
|
|
13326
13332
|
return {
|
|
@@ -13568,6 +13574,7 @@ var Runner = class extends import_node_events3.EventEmitter {
|
|
|
13568
13574
|
}
|
|
13569
13575
|
async onHostAcked(payload) {
|
|
13570
13576
|
this.workspaceId = payload.workspaceId;
|
|
13577
|
+
const ownershipLockChanged = await this.applyHostAckOwnershipLock(payload);
|
|
13571
13578
|
void this.reportTransport().catch((err) => {
|
|
13572
13579
|
process.stderr.write(
|
|
13573
13580
|
`[daemon] transport-probe report failed: ${err.message}
|
|
@@ -13583,7 +13590,9 @@ var Runner = class extends import_node_events3.EventEmitter {
|
|
|
13583
13590
|
(err) => log7.error("Asset sync failed", err.message)
|
|
13584
13591
|
);
|
|
13585
13592
|
await this.ensureDropFolderRuntime(this.workspaceId);
|
|
13586
|
-
|
|
13593
|
+
const profilesToSync = payload.profilesToSync ?? [];
|
|
13594
|
+
const profilesToDelete = payload.profilesToDelete ?? [];
|
|
13595
|
+
for (const id of profilesToSync) {
|
|
13587
13596
|
try {
|
|
13588
13597
|
await this.servicePool.drop(id);
|
|
13589
13598
|
await this.syncProfileFromCloud(id);
|
|
@@ -13591,7 +13600,7 @@ var Runner = class extends import_node_events3.EventEmitter {
|
|
|
13591
13600
|
this.emit("sync-error", err);
|
|
13592
13601
|
}
|
|
13593
13602
|
}
|
|
13594
|
-
for (const id of
|
|
13603
|
+
for (const id of profilesToDelete) {
|
|
13595
13604
|
const row = this.db.prepare("SELECT agent_im_user_id FROM agent_profiles WHERE id = ?").get(id);
|
|
13596
13605
|
this.db.prepare("DELETE FROM agent_profiles WHERE id = ?").run(id);
|
|
13597
13606
|
if (row) {
|
|
@@ -13600,10 +13609,37 @@ var Runner = class extends import_node_events3.EventEmitter {
|
|
|
13600
13609
|
process.stderr.write(`[daemon] tombstone profile=${id}
|
|
13601
13610
|
`);
|
|
13602
13611
|
}
|
|
13603
|
-
if (
|
|
13604
|
-
if ((
|
|
13612
|
+
if (profilesToDelete.length) this.loadAgentsFromDb();
|
|
13613
|
+
if ((ownershipLockChanged || profilesToSync.length > 0 || profilesToDelete.length > 0) && this.wsConnected) {
|
|
13614
|
+
this.sendDeclare();
|
|
13615
|
+
}
|
|
13605
13616
|
this.emit("host-acked", payload);
|
|
13606
13617
|
}
|
|
13618
|
+
async applyHostAckOwnershipLock(payload) {
|
|
13619
|
+
const rejected = payload.rejectedAgents ?? [];
|
|
13620
|
+
if (rejected.length === 0) return false;
|
|
13621
|
+
let changed = false;
|
|
13622
|
+
for (const rejection of rejected) {
|
|
13623
|
+
if (!rejection?.imUserId) continue;
|
|
13624
|
+
const agentImUserId = rejection.imUserId;
|
|
13625
|
+
this.rejectedHostedAgentIds.set(agentImUserId, {
|
|
13626
|
+
...rejection,
|
|
13627
|
+
rejectedAt: Date.now()
|
|
13628
|
+
});
|
|
13629
|
+
const wasHosted = this.hostedAgents.delete(agentImUserId);
|
|
13630
|
+
const profiles = this.db.prepare("SELECT id FROM agent_profiles WHERE agent_im_user_id = ?").all(agentImUserId);
|
|
13631
|
+
const deleted = this.db.prepare("DELETE FROM agents WHERE im_user_id = ?").run(agentImUserId);
|
|
13632
|
+
await Promise.all(profiles.map((profile) => this.servicePool.drop(profile.id)));
|
|
13633
|
+
if (wasHosted || deleted.changes > 0) {
|
|
13634
|
+
changed = true;
|
|
13635
|
+
process.stderr.write(
|
|
13636
|
+
`[daemon] ownership rejected agent=${agentImUserId} reason=${rejection.reason} owner=${rejection.ownerDaemonId ?? "(unknown)"} \u2014 stop declaring locally
|
|
13637
|
+
`
|
|
13638
|
+
);
|
|
13639
|
+
}
|
|
13640
|
+
}
|
|
13641
|
+
return changed;
|
|
13642
|
+
}
|
|
13607
13643
|
async onTaskDispatch(payload, requestId) {
|
|
13608
13644
|
const targetDaemonId = readTargetDaemonId(payload);
|
|
13609
13645
|
if (targetDaemonId && targetDaemonId !== this.config.daemon_id) {
|
|
@@ -13886,18 +13922,22 @@ var Runner = class extends import_node_events3.EventEmitter {
|
|
|
13886
13922
|
const name = agent?.card?.name || agent?.displayName || agent?.username || profile.agentImUserId;
|
|
13887
13923
|
const now = Date.now();
|
|
13888
13924
|
const tx = this.db.transaction(() => {
|
|
13889
|
-
this.
|
|
13890
|
-
|
|
13891
|
-
|
|
13892
|
-
|
|
13893
|
-
|
|
13894
|
-
|
|
13895
|
-
|
|
13896
|
-
|
|
13897
|
-
|
|
13898
|
-
|
|
13899
|
-
|
|
13900
|
-
|
|
13925
|
+
if (this.rejectedHostedAgentIds.has(profile.agentImUserId)) {
|
|
13926
|
+
this.db.prepare("DELETE FROM agents WHERE im_user_id = ?").run(profile.agentImUserId);
|
|
13927
|
+
} else {
|
|
13928
|
+
this.db.prepare(
|
|
13929
|
+
`INSERT OR REPLACE INTO agents
|
|
13930
|
+
(im_user_id, workspace_id, name, adapter_name, capabilities, status, version, synced_at, dirty)
|
|
13931
|
+
VALUES (?, ?, ?, ?, ?, 'offline', 1, ?, 0)`
|
|
13932
|
+
).run(
|
|
13933
|
+
profile.agentImUserId,
|
|
13934
|
+
profile.workspaceId,
|
|
13935
|
+
name,
|
|
13936
|
+
profile.adapterName,
|
|
13937
|
+
JSON.stringify(capabilities),
|
|
13938
|
+
now
|
|
13939
|
+
);
|
|
13940
|
+
}
|
|
13901
13941
|
this.db.prepare(
|
|
13902
13942
|
`INSERT OR REPLACE INTO agent_profiles
|
|
13903
13943
|
(id, workspace_id, agent_im_user_id, adapter_name, name, config, version, synced_at, dirty, deleted_at)
|
|
@@ -16837,7 +16877,7 @@ async function readResponseError(res) {
|
|
|
16837
16877
|
|
|
16838
16878
|
// src/cli/index.ts
|
|
16839
16879
|
init_ui();
|
|
16840
|
-
var VERSION = "2.0.
|
|
16880
|
+
var VERSION = "2.0.6";
|
|
16841
16881
|
function buildProgram() {
|
|
16842
16882
|
const program = new import_commander20.Command("prismer").description("Prismer Cloud daemon CLI (TS-only).").version(VERSION);
|
|
16843
16883
|
program.addCommand(buildBannerCommand());
|
package/dist/cli.js
CHANGED
|
@@ -2245,7 +2245,7 @@ var require_package = __commonJS({
|
|
|
2245
2245
|
"package.json"(exports, module) {
|
|
2246
2246
|
module.exports = {
|
|
2247
2247
|
name: "@prismer/runtime",
|
|
2248
|
-
version: "2.0.
|
|
2248
|
+
version: "2.0.6",
|
|
2249
2249
|
description: "Prismer Cloud daemon runtime \u2014 TS-only adapter host for hosted IM agents",
|
|
2250
2250
|
type: "module",
|
|
2251
2251
|
main: "dist/index.js",
|
|
@@ -12778,6 +12778,7 @@ var Runner = class extends EventEmitter3 {
|
|
|
12778
12778
|
workspaceId = "";
|
|
12779
12779
|
wsConnected = false;
|
|
12780
12780
|
hostedAgents = /* @__PURE__ */ new Map();
|
|
12781
|
+
rejectedHostedAgentIds = /* @__PURE__ */ new Map();
|
|
12781
12782
|
runningTasks = /* @__PURE__ */ new Map();
|
|
12782
12783
|
lastTaskError;
|
|
12783
12784
|
heartbeatTimer;
|
|
@@ -13223,6 +13224,9 @@ var Runner = class extends EventEmitter3 {
|
|
|
13223
13224
|
profilesByAgent.set(p.agent_im_user_id, list);
|
|
13224
13225
|
}
|
|
13225
13226
|
for (const a of agents) {
|
|
13227
|
+
if (this.rejectedHostedAgentIds.has(a.im_user_id)) {
|
|
13228
|
+
continue;
|
|
13229
|
+
}
|
|
13226
13230
|
let caps = [];
|
|
13227
13231
|
try {
|
|
13228
13232
|
caps = JSON.parse(a.capabilities);
|
|
@@ -13272,6 +13276,7 @@ var Runner = class extends EventEmitter3 {
|
|
|
13272
13276
|
* Used to populate the `agents` list in agent.host.declare.
|
|
13273
13277
|
*/
|
|
13274
13278
|
setHostedAgent(agent) {
|
|
13279
|
+
this.rejectedHostedAgentIds.delete(agent.imUserId);
|
|
13275
13280
|
this.hostedAgents.set(agent.imUserId, {
|
|
13276
13281
|
imUserId: agent.imUserId,
|
|
13277
13282
|
name: agent.name,
|
|
@@ -13304,6 +13309,7 @@ var Runner = class extends EventEmitter3 {
|
|
|
13304
13309
|
);
|
|
13305
13310
|
});
|
|
13306
13311
|
tx(payload);
|
|
13312
|
+
this.rejectedHostedAgentIds.delete(payload.imUserId);
|
|
13307
13313
|
this.loadAgentsFromDb();
|
|
13308
13314
|
if (this.wsConnected) this.sendDeclare();
|
|
13309
13315
|
return {
|
|
@@ -13551,6 +13557,7 @@ var Runner = class extends EventEmitter3 {
|
|
|
13551
13557
|
}
|
|
13552
13558
|
async onHostAcked(payload) {
|
|
13553
13559
|
this.workspaceId = payload.workspaceId;
|
|
13560
|
+
const ownershipLockChanged = await this.applyHostAckOwnershipLock(payload);
|
|
13554
13561
|
void this.reportTransport().catch((err) => {
|
|
13555
13562
|
process.stderr.write(
|
|
13556
13563
|
`[daemon] transport-probe report failed: ${err.message}
|
|
@@ -13566,7 +13573,9 @@ var Runner = class extends EventEmitter3 {
|
|
|
13566
13573
|
(err) => log7.error("Asset sync failed", err.message)
|
|
13567
13574
|
);
|
|
13568
13575
|
await this.ensureDropFolderRuntime(this.workspaceId);
|
|
13569
|
-
|
|
13576
|
+
const profilesToSync = payload.profilesToSync ?? [];
|
|
13577
|
+
const profilesToDelete = payload.profilesToDelete ?? [];
|
|
13578
|
+
for (const id of profilesToSync) {
|
|
13570
13579
|
try {
|
|
13571
13580
|
await this.servicePool.drop(id);
|
|
13572
13581
|
await this.syncProfileFromCloud(id);
|
|
@@ -13574,7 +13583,7 @@ var Runner = class extends EventEmitter3 {
|
|
|
13574
13583
|
this.emit("sync-error", err);
|
|
13575
13584
|
}
|
|
13576
13585
|
}
|
|
13577
|
-
for (const id of
|
|
13586
|
+
for (const id of profilesToDelete) {
|
|
13578
13587
|
const row = this.db.prepare("SELECT agent_im_user_id FROM agent_profiles WHERE id = ?").get(id);
|
|
13579
13588
|
this.db.prepare("DELETE FROM agent_profiles WHERE id = ?").run(id);
|
|
13580
13589
|
if (row) {
|
|
@@ -13583,10 +13592,37 @@ var Runner = class extends EventEmitter3 {
|
|
|
13583
13592
|
process.stderr.write(`[daemon] tombstone profile=${id}
|
|
13584
13593
|
`);
|
|
13585
13594
|
}
|
|
13586
|
-
if (
|
|
13587
|
-
if ((
|
|
13595
|
+
if (profilesToDelete.length) this.loadAgentsFromDb();
|
|
13596
|
+
if ((ownershipLockChanged || profilesToSync.length > 0 || profilesToDelete.length > 0) && this.wsConnected) {
|
|
13597
|
+
this.sendDeclare();
|
|
13598
|
+
}
|
|
13588
13599
|
this.emit("host-acked", payload);
|
|
13589
13600
|
}
|
|
13601
|
+
async applyHostAckOwnershipLock(payload) {
|
|
13602
|
+
const rejected = payload.rejectedAgents ?? [];
|
|
13603
|
+
if (rejected.length === 0) return false;
|
|
13604
|
+
let changed = false;
|
|
13605
|
+
for (const rejection of rejected) {
|
|
13606
|
+
if (!rejection?.imUserId) continue;
|
|
13607
|
+
const agentImUserId = rejection.imUserId;
|
|
13608
|
+
this.rejectedHostedAgentIds.set(agentImUserId, {
|
|
13609
|
+
...rejection,
|
|
13610
|
+
rejectedAt: Date.now()
|
|
13611
|
+
});
|
|
13612
|
+
const wasHosted = this.hostedAgents.delete(agentImUserId);
|
|
13613
|
+
const profiles = this.db.prepare("SELECT id FROM agent_profiles WHERE agent_im_user_id = ?").all(agentImUserId);
|
|
13614
|
+
const deleted = this.db.prepare("DELETE FROM agents WHERE im_user_id = ?").run(agentImUserId);
|
|
13615
|
+
await Promise.all(profiles.map((profile) => this.servicePool.drop(profile.id)));
|
|
13616
|
+
if (wasHosted || deleted.changes > 0) {
|
|
13617
|
+
changed = true;
|
|
13618
|
+
process.stderr.write(
|
|
13619
|
+
`[daemon] ownership rejected agent=${agentImUserId} reason=${rejection.reason} owner=${rejection.ownerDaemonId ?? "(unknown)"} \u2014 stop declaring locally
|
|
13620
|
+
`
|
|
13621
|
+
);
|
|
13622
|
+
}
|
|
13623
|
+
}
|
|
13624
|
+
return changed;
|
|
13625
|
+
}
|
|
13590
13626
|
async onTaskDispatch(payload, requestId) {
|
|
13591
13627
|
const targetDaemonId = readTargetDaemonId(payload);
|
|
13592
13628
|
if (targetDaemonId && targetDaemonId !== this.config.daemon_id) {
|
|
@@ -13869,18 +13905,22 @@ var Runner = class extends EventEmitter3 {
|
|
|
13869
13905
|
const name = agent?.card?.name || agent?.displayName || agent?.username || profile.agentImUserId;
|
|
13870
13906
|
const now = Date.now();
|
|
13871
13907
|
const tx = this.db.transaction(() => {
|
|
13872
|
-
this.
|
|
13873
|
-
|
|
13874
|
-
|
|
13875
|
-
|
|
13876
|
-
|
|
13877
|
-
|
|
13878
|
-
|
|
13879
|
-
|
|
13880
|
-
|
|
13881
|
-
|
|
13882
|
-
|
|
13883
|
-
|
|
13908
|
+
if (this.rejectedHostedAgentIds.has(profile.agentImUserId)) {
|
|
13909
|
+
this.db.prepare("DELETE FROM agents WHERE im_user_id = ?").run(profile.agentImUserId);
|
|
13910
|
+
} else {
|
|
13911
|
+
this.db.prepare(
|
|
13912
|
+
`INSERT OR REPLACE INTO agents
|
|
13913
|
+
(im_user_id, workspace_id, name, adapter_name, capabilities, status, version, synced_at, dirty)
|
|
13914
|
+
VALUES (?, ?, ?, ?, ?, 'offline', 1, ?, 0)`
|
|
13915
|
+
).run(
|
|
13916
|
+
profile.agentImUserId,
|
|
13917
|
+
profile.workspaceId,
|
|
13918
|
+
name,
|
|
13919
|
+
profile.adapterName,
|
|
13920
|
+
JSON.stringify(capabilities),
|
|
13921
|
+
now
|
|
13922
|
+
);
|
|
13923
|
+
}
|
|
13884
13924
|
this.db.prepare(
|
|
13885
13925
|
`INSERT OR REPLACE INTO agent_profiles
|
|
13886
13926
|
(id, workspace_id, agent_im_user_id, adapter_name, name, config, version, synced_at, dirty, deleted_at)
|
|
@@ -16820,7 +16860,7 @@ async function readResponseError(res) {
|
|
|
16820
16860
|
|
|
16821
16861
|
// src/cli/index.ts
|
|
16822
16862
|
init_ui();
|
|
16823
|
-
var VERSION = "2.0.
|
|
16863
|
+
var VERSION = "2.0.6";
|
|
16824
16864
|
function buildProgram() {
|
|
16825
16865
|
const program = new Command20("prismer").description("Prismer Cloud daemon CLI (TS-only).").version(VERSION);
|
|
16826
16866
|
program.addCommand(buildBannerCommand());
|
package/dist/index.cjs
CHANGED
|
@@ -2657,7 +2657,7 @@ var require_package = __commonJS({
|
|
|
2657
2657
|
"package.json"(exports2, module2) {
|
|
2658
2658
|
module2.exports = {
|
|
2659
2659
|
name: "@prismer/runtime",
|
|
2660
|
-
version: "2.0.
|
|
2660
|
+
version: "2.0.6",
|
|
2661
2661
|
description: "Prismer Cloud daemon runtime \u2014 TS-only adapter host for hosted IM agents",
|
|
2662
2662
|
type: "module",
|
|
2663
2663
|
main: "dist/index.js",
|
|
@@ -11046,6 +11046,7 @@ var Runner = class extends import_node_events3.EventEmitter {
|
|
|
11046
11046
|
workspaceId = "";
|
|
11047
11047
|
wsConnected = false;
|
|
11048
11048
|
hostedAgents = /* @__PURE__ */ new Map();
|
|
11049
|
+
rejectedHostedAgentIds = /* @__PURE__ */ new Map();
|
|
11049
11050
|
runningTasks = /* @__PURE__ */ new Map();
|
|
11050
11051
|
lastTaskError;
|
|
11051
11052
|
heartbeatTimer;
|
|
@@ -11491,6 +11492,9 @@ var Runner = class extends import_node_events3.EventEmitter {
|
|
|
11491
11492
|
profilesByAgent.set(p.agent_im_user_id, list);
|
|
11492
11493
|
}
|
|
11493
11494
|
for (const a of agents) {
|
|
11495
|
+
if (this.rejectedHostedAgentIds.has(a.im_user_id)) {
|
|
11496
|
+
continue;
|
|
11497
|
+
}
|
|
11494
11498
|
let caps = [];
|
|
11495
11499
|
try {
|
|
11496
11500
|
caps = JSON.parse(a.capabilities);
|
|
@@ -11540,6 +11544,7 @@ var Runner = class extends import_node_events3.EventEmitter {
|
|
|
11540
11544
|
* Used to populate the `agents` list in agent.host.declare.
|
|
11541
11545
|
*/
|
|
11542
11546
|
setHostedAgent(agent) {
|
|
11547
|
+
this.rejectedHostedAgentIds.delete(agent.imUserId);
|
|
11543
11548
|
this.hostedAgents.set(agent.imUserId, {
|
|
11544
11549
|
imUserId: agent.imUserId,
|
|
11545
11550
|
name: agent.name,
|
|
@@ -11572,6 +11577,7 @@ var Runner = class extends import_node_events3.EventEmitter {
|
|
|
11572
11577
|
);
|
|
11573
11578
|
});
|
|
11574
11579
|
tx(payload);
|
|
11580
|
+
this.rejectedHostedAgentIds.delete(payload.imUserId);
|
|
11575
11581
|
this.loadAgentsFromDb();
|
|
11576
11582
|
if (this.wsConnected) this.sendDeclare();
|
|
11577
11583
|
return {
|
|
@@ -11819,6 +11825,7 @@ var Runner = class extends import_node_events3.EventEmitter {
|
|
|
11819
11825
|
}
|
|
11820
11826
|
async onHostAcked(payload) {
|
|
11821
11827
|
this.workspaceId = payload.workspaceId;
|
|
11828
|
+
const ownershipLockChanged = await this.applyHostAckOwnershipLock(payload);
|
|
11822
11829
|
void this.reportTransport().catch((err) => {
|
|
11823
11830
|
process.stderr.write(
|
|
11824
11831
|
`[daemon] transport-probe report failed: ${err.message}
|
|
@@ -11834,7 +11841,9 @@ var Runner = class extends import_node_events3.EventEmitter {
|
|
|
11834
11841
|
(err) => log7.error("Asset sync failed", err.message)
|
|
11835
11842
|
);
|
|
11836
11843
|
await this.ensureDropFolderRuntime(this.workspaceId);
|
|
11837
|
-
|
|
11844
|
+
const profilesToSync = payload.profilesToSync ?? [];
|
|
11845
|
+
const profilesToDelete = payload.profilesToDelete ?? [];
|
|
11846
|
+
for (const id of profilesToSync) {
|
|
11838
11847
|
try {
|
|
11839
11848
|
await this.servicePool.drop(id);
|
|
11840
11849
|
await this.syncProfileFromCloud(id);
|
|
@@ -11842,7 +11851,7 @@ var Runner = class extends import_node_events3.EventEmitter {
|
|
|
11842
11851
|
this.emit("sync-error", err);
|
|
11843
11852
|
}
|
|
11844
11853
|
}
|
|
11845
|
-
for (const id of
|
|
11854
|
+
for (const id of profilesToDelete) {
|
|
11846
11855
|
const row = this.db.prepare("SELECT agent_im_user_id FROM agent_profiles WHERE id = ?").get(id);
|
|
11847
11856
|
this.db.prepare("DELETE FROM agent_profiles WHERE id = ?").run(id);
|
|
11848
11857
|
if (row) {
|
|
@@ -11851,10 +11860,37 @@ var Runner = class extends import_node_events3.EventEmitter {
|
|
|
11851
11860
|
process.stderr.write(`[daemon] tombstone profile=${id}
|
|
11852
11861
|
`);
|
|
11853
11862
|
}
|
|
11854
|
-
if (
|
|
11855
|
-
if ((
|
|
11863
|
+
if (profilesToDelete.length) this.loadAgentsFromDb();
|
|
11864
|
+
if ((ownershipLockChanged || profilesToSync.length > 0 || profilesToDelete.length > 0) && this.wsConnected) {
|
|
11865
|
+
this.sendDeclare();
|
|
11866
|
+
}
|
|
11856
11867
|
this.emit("host-acked", payload);
|
|
11857
11868
|
}
|
|
11869
|
+
async applyHostAckOwnershipLock(payload) {
|
|
11870
|
+
const rejected = payload.rejectedAgents ?? [];
|
|
11871
|
+
if (rejected.length === 0) return false;
|
|
11872
|
+
let changed = false;
|
|
11873
|
+
for (const rejection of rejected) {
|
|
11874
|
+
if (!rejection?.imUserId) continue;
|
|
11875
|
+
const agentImUserId = rejection.imUserId;
|
|
11876
|
+
this.rejectedHostedAgentIds.set(agentImUserId, {
|
|
11877
|
+
...rejection,
|
|
11878
|
+
rejectedAt: Date.now()
|
|
11879
|
+
});
|
|
11880
|
+
const wasHosted = this.hostedAgents.delete(agentImUserId);
|
|
11881
|
+
const profiles = this.db.prepare("SELECT id FROM agent_profiles WHERE agent_im_user_id = ?").all(agentImUserId);
|
|
11882
|
+
const deleted = this.db.prepare("DELETE FROM agents WHERE im_user_id = ?").run(agentImUserId);
|
|
11883
|
+
await Promise.all(profiles.map((profile) => this.servicePool.drop(profile.id)));
|
|
11884
|
+
if (wasHosted || deleted.changes > 0) {
|
|
11885
|
+
changed = true;
|
|
11886
|
+
process.stderr.write(
|
|
11887
|
+
`[daemon] ownership rejected agent=${agentImUserId} reason=${rejection.reason} owner=${rejection.ownerDaemonId ?? "(unknown)"} \u2014 stop declaring locally
|
|
11888
|
+
`
|
|
11889
|
+
);
|
|
11890
|
+
}
|
|
11891
|
+
}
|
|
11892
|
+
return changed;
|
|
11893
|
+
}
|
|
11858
11894
|
async onTaskDispatch(payload, requestId) {
|
|
11859
11895
|
const targetDaemonId = readTargetDaemonId(payload);
|
|
11860
11896
|
if (targetDaemonId && targetDaemonId !== this.config.daemon_id) {
|
|
@@ -12137,18 +12173,22 @@ var Runner = class extends import_node_events3.EventEmitter {
|
|
|
12137
12173
|
const name = agent?.card?.name || agent?.displayName || agent?.username || profile.agentImUserId;
|
|
12138
12174
|
const now = Date.now();
|
|
12139
12175
|
const tx = this.db.transaction(() => {
|
|
12140
|
-
this.
|
|
12141
|
-
|
|
12142
|
-
|
|
12143
|
-
|
|
12144
|
-
|
|
12145
|
-
|
|
12146
|
-
|
|
12147
|
-
|
|
12148
|
-
|
|
12149
|
-
|
|
12150
|
-
|
|
12151
|
-
|
|
12176
|
+
if (this.rejectedHostedAgentIds.has(profile.agentImUserId)) {
|
|
12177
|
+
this.db.prepare("DELETE FROM agents WHERE im_user_id = ?").run(profile.agentImUserId);
|
|
12178
|
+
} else {
|
|
12179
|
+
this.db.prepare(
|
|
12180
|
+
`INSERT OR REPLACE INTO agents
|
|
12181
|
+
(im_user_id, workspace_id, name, adapter_name, capabilities, status, version, synced_at, dirty)
|
|
12182
|
+
VALUES (?, ?, ?, ?, ?, 'offline', 1, ?, 0)`
|
|
12183
|
+
).run(
|
|
12184
|
+
profile.agentImUserId,
|
|
12185
|
+
profile.workspaceId,
|
|
12186
|
+
name,
|
|
12187
|
+
profile.adapterName,
|
|
12188
|
+
JSON.stringify(capabilities),
|
|
12189
|
+
now
|
|
12190
|
+
);
|
|
12191
|
+
}
|
|
12152
12192
|
this.db.prepare(
|
|
12153
12193
|
`INSERT OR REPLACE INTO agent_profiles
|
|
12154
12194
|
(id, workspace_id, agent_im_user_id, adapter_name, name, config, version, synced_at, dirty, deleted_at)
|
|
@@ -17012,7 +17052,7 @@ async function readResponseError(res) {
|
|
|
17012
17052
|
|
|
17013
17053
|
// src/cli/index.ts
|
|
17014
17054
|
init_ui();
|
|
17015
|
-
var VERSION = "2.0.
|
|
17055
|
+
var VERSION = "2.0.6";
|
|
17016
17056
|
function buildProgram() {
|
|
17017
17057
|
const program = new import_commander20.Command("prismer").description("Prismer Cloud daemon CLI (TS-only).").version(VERSION);
|
|
17018
17058
|
program.addCommand(buildBannerCommand());
|
package/dist/index.d.cts
CHANGED
|
@@ -21,6 +21,11 @@ interface AgentHostDeclarePayload {
|
|
|
21
21
|
platform: 'darwin' | 'linux' | 'win32';
|
|
22
22
|
agents: HostedAgentDeclaration[];
|
|
23
23
|
}
|
|
24
|
+
interface RejectedHostedAgent {
|
|
25
|
+
imUserId: string;
|
|
26
|
+
reason: 'bound-to-other-daemon' | 'not-owned' | 'unknown';
|
|
27
|
+
ownerDaemonId?: string;
|
|
28
|
+
}
|
|
24
29
|
interface HostAckedPayload {
|
|
25
30
|
workspaceId: string;
|
|
26
31
|
syncCursor: {
|
|
@@ -32,6 +37,8 @@ interface HostAckedPayload {
|
|
|
32
37
|
/** Profile IDs the daemon declared but that no longer exist on the cloud
|
|
33
38
|
* (soft-deleted). The daemon should remove these from its local store. */
|
|
34
39
|
profilesToDelete: string[];
|
|
40
|
+
acceptedAgents?: string[];
|
|
41
|
+
rejectedAgents?: RejectedHostedAgent[];
|
|
35
42
|
}
|
|
36
43
|
interface AgentStatusChangedPayload {
|
|
37
44
|
agentImUserId: string;
|
|
@@ -2307,6 +2314,7 @@ declare class Runner extends EventEmitter {
|
|
|
2307
2314
|
private workspaceId;
|
|
2308
2315
|
private wsConnected;
|
|
2309
2316
|
private readonly hostedAgents;
|
|
2317
|
+
private readonly rejectedHostedAgentIds;
|
|
2310
2318
|
private readonly runningTasks;
|
|
2311
2319
|
private lastTaskError?;
|
|
2312
2320
|
private heartbeatTimer?;
|
|
@@ -2417,6 +2425,7 @@ declare class Runner extends EventEmitter {
|
|
|
2417
2425
|
*/
|
|
2418
2426
|
private onWebhookDispatch;
|
|
2419
2427
|
private onHostAcked;
|
|
2428
|
+
private applyHostAckOwnershipLock;
|
|
2420
2429
|
private onTaskDispatch;
|
|
2421
2430
|
private onTaskCancel;
|
|
2422
2431
|
private findMessageDispatchAgent;
|
|
@@ -2646,4 +2655,4 @@ declare const codexAdapter: AdapterDef;
|
|
|
2646
2655
|
declare function buildProgram(): Command;
|
|
2647
2656
|
declare function runCli(argv?: string[]): Promise<void>;
|
|
2648
2657
|
|
|
2649
|
-
export { type AcquireResult, type AdapterDef, type AdapterKind, AdapterRegistry, type AdapterService, type AgentChangedPayload, type AgentDispatchReplyAttachment, type AgentDispatchReplyPayload, type AgentDispatchReplyStatus, type AgentDispatchRequest, type AgentDispatchResponse, type AgentHostDeclarePayload, type AgentProfile, type AgentProfileChangedPayload, type AgentStatusChangedPayload, AssetCache, type AssetCacheOptions, type AssetChangedPayload, type AssetDispatchObservation, type AssetDispatchStrategy, type AssetRef, BUILTIN_ROLE_TEMPLATES, type CachedAsset, type ClaudeCodeConfig, CloudClient, type CloudClientOptions, CloudError, type CloudResponse, type CodexConfig, type Config, type ConfigPaths, ConfigSchema, type DispatchDeps, type Envelope, type FlushFn, type FlushResult, type HealthStatus, type HermesProfileConfig, type HostAckedPayload, type HostedAgentDeclaration, type IMAgentStatus, type IMWSMessage, type LocalDb, LocalServer, type LocalServerOptions, type LocalServerState, type MessageDispatchAgent, type MessageDispatchDeps, type MessageDispatchHandle, type MessageDispatchTaskInput, type NormalizedContent, type OpenClawProfileConfig, type PairOptions, type PairResult, type ParseClaim, ParseClaimController, type ParseClaimControllerOptions, type ParsedPrismerUri, type PrismerUriType, type RoleTemplate, Runner, type RunnerOptions, ServicePool, type SyncOperation, SyncQueue, type SyncQueueRow, type SyncResourceType, type SyncStatus, SyncWorker, type SyncWorkerOptions, TARGET_SCHEMA_VERSION, type TaskCancelPayload, type TaskDispatchContextEntry, type TaskDispatchProgressPayload, type TaskDispatchReplyPayload, type TaskDispatchRequestPayload, type TaskInput, type TaskResult, UriResolver, type UriResolverOptions, type UrlResolution, type ValidationResult, WS_CLOSE, type WorkspaceChangedPayload, type WorkspaceFileBinding, type WorkspaceFileChangedPayload, WorkspaceMirror, type WorkspaceMirrorOptions, WsClient, type WsClientOptions, buildProgram, claudeCodeAdapter, codexAdapter, composePrompt, configExists, currentSchemaVersion, deriveWsUrl, envelope, extractHttpUrls, getRoleTemplate, handleAgentMessageDispatch, handleDispatch, hermesAdapter, isDaemonId, listRoleTemplates, loadConfig, newDaemonId, nextBackoffMs, openLocalDb, openclawAdapter, pair, parseCodexOutput, parseUris, resolvePaths, runCli, runMigrations, saveConfig };
|
|
2658
|
+
export { type AcquireResult, type AdapterDef, type AdapterKind, AdapterRegistry, type AdapterService, type AgentChangedPayload, type AgentDispatchReplyAttachment, type AgentDispatchReplyPayload, type AgentDispatchReplyStatus, type AgentDispatchRequest, type AgentDispatchResponse, type AgentHostDeclarePayload, type AgentProfile, type AgentProfileChangedPayload, type AgentStatusChangedPayload, AssetCache, type AssetCacheOptions, type AssetChangedPayload, type AssetDispatchObservation, type AssetDispatchStrategy, type AssetRef, BUILTIN_ROLE_TEMPLATES, type CachedAsset, type ClaudeCodeConfig, CloudClient, type CloudClientOptions, CloudError, type CloudResponse, type CodexConfig, type Config, type ConfigPaths, ConfigSchema, type DispatchDeps, type Envelope, type FlushFn, type FlushResult, type HealthStatus, type HermesProfileConfig, type HostAckedPayload, type HostedAgentDeclaration, type IMAgentStatus, type IMWSMessage, type LocalDb, LocalServer, type LocalServerOptions, type LocalServerState, type MessageDispatchAgent, type MessageDispatchDeps, type MessageDispatchHandle, type MessageDispatchTaskInput, type NormalizedContent, type OpenClawProfileConfig, type PairOptions, type PairResult, type ParseClaim, ParseClaimController, type ParseClaimControllerOptions, type ParsedPrismerUri, type PrismerUriType, type RejectedHostedAgent, type RoleTemplate, Runner, type RunnerOptions, ServicePool, type SyncOperation, SyncQueue, type SyncQueueRow, type SyncResourceType, type SyncStatus, SyncWorker, type SyncWorkerOptions, TARGET_SCHEMA_VERSION, type TaskCancelPayload, type TaskDispatchContextEntry, type TaskDispatchProgressPayload, type TaskDispatchReplyPayload, type TaskDispatchRequestPayload, type TaskInput, type TaskResult, UriResolver, type UriResolverOptions, type UrlResolution, type ValidationResult, WS_CLOSE, type WorkspaceChangedPayload, type WorkspaceFileBinding, type WorkspaceFileChangedPayload, WorkspaceMirror, type WorkspaceMirrorOptions, WsClient, type WsClientOptions, buildProgram, claudeCodeAdapter, codexAdapter, composePrompt, configExists, currentSchemaVersion, deriveWsUrl, envelope, extractHttpUrls, getRoleTemplate, handleAgentMessageDispatch, handleDispatch, hermesAdapter, isDaemonId, listRoleTemplates, loadConfig, newDaemonId, nextBackoffMs, openLocalDb, openclawAdapter, pair, parseCodexOutput, parseUris, resolvePaths, runCli, runMigrations, saveConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -21,6 +21,11 @@ interface AgentHostDeclarePayload {
|
|
|
21
21
|
platform: 'darwin' | 'linux' | 'win32';
|
|
22
22
|
agents: HostedAgentDeclaration[];
|
|
23
23
|
}
|
|
24
|
+
interface RejectedHostedAgent {
|
|
25
|
+
imUserId: string;
|
|
26
|
+
reason: 'bound-to-other-daemon' | 'not-owned' | 'unknown';
|
|
27
|
+
ownerDaemonId?: string;
|
|
28
|
+
}
|
|
24
29
|
interface HostAckedPayload {
|
|
25
30
|
workspaceId: string;
|
|
26
31
|
syncCursor: {
|
|
@@ -32,6 +37,8 @@ interface HostAckedPayload {
|
|
|
32
37
|
/** Profile IDs the daemon declared but that no longer exist on the cloud
|
|
33
38
|
* (soft-deleted). The daemon should remove these from its local store. */
|
|
34
39
|
profilesToDelete: string[];
|
|
40
|
+
acceptedAgents?: string[];
|
|
41
|
+
rejectedAgents?: RejectedHostedAgent[];
|
|
35
42
|
}
|
|
36
43
|
interface AgentStatusChangedPayload {
|
|
37
44
|
agentImUserId: string;
|
|
@@ -2307,6 +2314,7 @@ declare class Runner extends EventEmitter {
|
|
|
2307
2314
|
private workspaceId;
|
|
2308
2315
|
private wsConnected;
|
|
2309
2316
|
private readonly hostedAgents;
|
|
2317
|
+
private readonly rejectedHostedAgentIds;
|
|
2310
2318
|
private readonly runningTasks;
|
|
2311
2319
|
private lastTaskError?;
|
|
2312
2320
|
private heartbeatTimer?;
|
|
@@ -2417,6 +2425,7 @@ declare class Runner extends EventEmitter {
|
|
|
2417
2425
|
*/
|
|
2418
2426
|
private onWebhookDispatch;
|
|
2419
2427
|
private onHostAcked;
|
|
2428
|
+
private applyHostAckOwnershipLock;
|
|
2420
2429
|
private onTaskDispatch;
|
|
2421
2430
|
private onTaskCancel;
|
|
2422
2431
|
private findMessageDispatchAgent;
|
|
@@ -2646,4 +2655,4 @@ declare const codexAdapter: AdapterDef;
|
|
|
2646
2655
|
declare function buildProgram(): Command;
|
|
2647
2656
|
declare function runCli(argv?: string[]): Promise<void>;
|
|
2648
2657
|
|
|
2649
|
-
export { type AcquireResult, type AdapterDef, type AdapterKind, AdapterRegistry, type AdapterService, type AgentChangedPayload, type AgentDispatchReplyAttachment, type AgentDispatchReplyPayload, type AgentDispatchReplyStatus, type AgentDispatchRequest, type AgentDispatchResponse, type AgentHostDeclarePayload, type AgentProfile, type AgentProfileChangedPayload, type AgentStatusChangedPayload, AssetCache, type AssetCacheOptions, type AssetChangedPayload, type AssetDispatchObservation, type AssetDispatchStrategy, type AssetRef, BUILTIN_ROLE_TEMPLATES, type CachedAsset, type ClaudeCodeConfig, CloudClient, type CloudClientOptions, CloudError, type CloudResponse, type CodexConfig, type Config, type ConfigPaths, ConfigSchema, type DispatchDeps, type Envelope, type FlushFn, type FlushResult, type HealthStatus, type HermesProfileConfig, type HostAckedPayload, type HostedAgentDeclaration, type IMAgentStatus, type IMWSMessage, type LocalDb, LocalServer, type LocalServerOptions, type LocalServerState, type MessageDispatchAgent, type MessageDispatchDeps, type MessageDispatchHandle, type MessageDispatchTaskInput, type NormalizedContent, type OpenClawProfileConfig, type PairOptions, type PairResult, type ParseClaim, ParseClaimController, type ParseClaimControllerOptions, type ParsedPrismerUri, type PrismerUriType, type RoleTemplate, Runner, type RunnerOptions, ServicePool, type SyncOperation, SyncQueue, type SyncQueueRow, type SyncResourceType, type SyncStatus, SyncWorker, type SyncWorkerOptions, TARGET_SCHEMA_VERSION, type TaskCancelPayload, type TaskDispatchContextEntry, type TaskDispatchProgressPayload, type TaskDispatchReplyPayload, type TaskDispatchRequestPayload, type TaskInput, type TaskResult, UriResolver, type UriResolverOptions, type UrlResolution, type ValidationResult, WS_CLOSE, type WorkspaceChangedPayload, type WorkspaceFileBinding, type WorkspaceFileChangedPayload, WorkspaceMirror, type WorkspaceMirrorOptions, WsClient, type WsClientOptions, buildProgram, claudeCodeAdapter, codexAdapter, composePrompt, configExists, currentSchemaVersion, deriveWsUrl, envelope, extractHttpUrls, getRoleTemplate, handleAgentMessageDispatch, handleDispatch, hermesAdapter, isDaemonId, listRoleTemplates, loadConfig, newDaemonId, nextBackoffMs, openLocalDb, openclawAdapter, pair, parseCodexOutput, parseUris, resolvePaths, runCli, runMigrations, saveConfig };
|
|
2658
|
+
export { type AcquireResult, type AdapterDef, type AdapterKind, AdapterRegistry, type AdapterService, type AgentChangedPayload, type AgentDispatchReplyAttachment, type AgentDispatchReplyPayload, type AgentDispatchReplyStatus, type AgentDispatchRequest, type AgentDispatchResponse, type AgentHostDeclarePayload, type AgentProfile, type AgentProfileChangedPayload, type AgentStatusChangedPayload, AssetCache, type AssetCacheOptions, type AssetChangedPayload, type AssetDispatchObservation, type AssetDispatchStrategy, type AssetRef, BUILTIN_ROLE_TEMPLATES, type CachedAsset, type ClaudeCodeConfig, CloudClient, type CloudClientOptions, CloudError, type CloudResponse, type CodexConfig, type Config, type ConfigPaths, ConfigSchema, type DispatchDeps, type Envelope, type FlushFn, type FlushResult, type HealthStatus, type HermesProfileConfig, type HostAckedPayload, type HostedAgentDeclaration, type IMAgentStatus, type IMWSMessage, type LocalDb, LocalServer, type LocalServerOptions, type LocalServerState, type MessageDispatchAgent, type MessageDispatchDeps, type MessageDispatchHandle, type MessageDispatchTaskInput, type NormalizedContent, type OpenClawProfileConfig, type PairOptions, type PairResult, type ParseClaim, ParseClaimController, type ParseClaimControllerOptions, type ParsedPrismerUri, type PrismerUriType, type RejectedHostedAgent, type RoleTemplate, Runner, type RunnerOptions, ServicePool, type SyncOperation, SyncQueue, type SyncQueueRow, type SyncResourceType, type SyncStatus, SyncWorker, type SyncWorkerOptions, TARGET_SCHEMA_VERSION, type TaskCancelPayload, type TaskDispatchContextEntry, type TaskDispatchProgressPayload, type TaskDispatchReplyPayload, type TaskDispatchRequestPayload, type TaskInput, type TaskResult, UriResolver, type UriResolverOptions, type UrlResolution, type ValidationResult, WS_CLOSE, type WorkspaceChangedPayload, type WorkspaceFileBinding, type WorkspaceFileChangedPayload, WorkspaceMirror, type WorkspaceMirrorOptions, WsClient, type WsClientOptions, buildProgram, claudeCodeAdapter, codexAdapter, composePrompt, configExists, currentSchemaVersion, deriveWsUrl, envelope, extractHttpUrls, getRoleTemplate, handleAgentMessageDispatch, handleDispatch, hermesAdapter, isDaemonId, listRoleTemplates, loadConfig, newDaemonId, nextBackoffMs, openLocalDb, openclawAdapter, pair, parseCodexOutput, parseUris, resolvePaths, runCli, runMigrations, saveConfig };
|
package/dist/index.js
CHANGED
|
@@ -2633,7 +2633,7 @@ var require_package = __commonJS({
|
|
|
2633
2633
|
"package.json"(exports, module) {
|
|
2634
2634
|
module.exports = {
|
|
2635
2635
|
name: "@prismer/runtime",
|
|
2636
|
-
version: "2.0.
|
|
2636
|
+
version: "2.0.6",
|
|
2637
2637
|
description: "Prismer Cloud daemon runtime \u2014 TS-only adapter host for hosted IM agents",
|
|
2638
2638
|
type: "module",
|
|
2639
2639
|
main: "dist/index.js",
|
|
@@ -10971,6 +10971,7 @@ var Runner = class extends EventEmitter3 {
|
|
|
10971
10971
|
workspaceId = "";
|
|
10972
10972
|
wsConnected = false;
|
|
10973
10973
|
hostedAgents = /* @__PURE__ */ new Map();
|
|
10974
|
+
rejectedHostedAgentIds = /* @__PURE__ */ new Map();
|
|
10974
10975
|
runningTasks = /* @__PURE__ */ new Map();
|
|
10975
10976
|
lastTaskError;
|
|
10976
10977
|
heartbeatTimer;
|
|
@@ -11416,6 +11417,9 @@ var Runner = class extends EventEmitter3 {
|
|
|
11416
11417
|
profilesByAgent.set(p.agent_im_user_id, list);
|
|
11417
11418
|
}
|
|
11418
11419
|
for (const a of agents) {
|
|
11420
|
+
if (this.rejectedHostedAgentIds.has(a.im_user_id)) {
|
|
11421
|
+
continue;
|
|
11422
|
+
}
|
|
11419
11423
|
let caps = [];
|
|
11420
11424
|
try {
|
|
11421
11425
|
caps = JSON.parse(a.capabilities);
|
|
@@ -11465,6 +11469,7 @@ var Runner = class extends EventEmitter3 {
|
|
|
11465
11469
|
* Used to populate the `agents` list in agent.host.declare.
|
|
11466
11470
|
*/
|
|
11467
11471
|
setHostedAgent(agent) {
|
|
11472
|
+
this.rejectedHostedAgentIds.delete(agent.imUserId);
|
|
11468
11473
|
this.hostedAgents.set(agent.imUserId, {
|
|
11469
11474
|
imUserId: agent.imUserId,
|
|
11470
11475
|
name: agent.name,
|
|
@@ -11497,6 +11502,7 @@ var Runner = class extends EventEmitter3 {
|
|
|
11497
11502
|
);
|
|
11498
11503
|
});
|
|
11499
11504
|
tx(payload);
|
|
11505
|
+
this.rejectedHostedAgentIds.delete(payload.imUserId);
|
|
11500
11506
|
this.loadAgentsFromDb();
|
|
11501
11507
|
if (this.wsConnected) this.sendDeclare();
|
|
11502
11508
|
return {
|
|
@@ -11744,6 +11750,7 @@ var Runner = class extends EventEmitter3 {
|
|
|
11744
11750
|
}
|
|
11745
11751
|
async onHostAcked(payload) {
|
|
11746
11752
|
this.workspaceId = payload.workspaceId;
|
|
11753
|
+
const ownershipLockChanged = await this.applyHostAckOwnershipLock(payload);
|
|
11747
11754
|
void this.reportTransport().catch((err) => {
|
|
11748
11755
|
process.stderr.write(
|
|
11749
11756
|
`[daemon] transport-probe report failed: ${err.message}
|
|
@@ -11759,7 +11766,9 @@ var Runner = class extends EventEmitter3 {
|
|
|
11759
11766
|
(err) => log7.error("Asset sync failed", err.message)
|
|
11760
11767
|
);
|
|
11761
11768
|
await this.ensureDropFolderRuntime(this.workspaceId);
|
|
11762
|
-
|
|
11769
|
+
const profilesToSync = payload.profilesToSync ?? [];
|
|
11770
|
+
const profilesToDelete = payload.profilesToDelete ?? [];
|
|
11771
|
+
for (const id of profilesToSync) {
|
|
11763
11772
|
try {
|
|
11764
11773
|
await this.servicePool.drop(id);
|
|
11765
11774
|
await this.syncProfileFromCloud(id);
|
|
@@ -11767,7 +11776,7 @@ var Runner = class extends EventEmitter3 {
|
|
|
11767
11776
|
this.emit("sync-error", err);
|
|
11768
11777
|
}
|
|
11769
11778
|
}
|
|
11770
|
-
for (const id of
|
|
11779
|
+
for (const id of profilesToDelete) {
|
|
11771
11780
|
const row = this.db.prepare("SELECT agent_im_user_id FROM agent_profiles WHERE id = ?").get(id);
|
|
11772
11781
|
this.db.prepare("DELETE FROM agent_profiles WHERE id = ?").run(id);
|
|
11773
11782
|
if (row) {
|
|
@@ -11776,10 +11785,37 @@ var Runner = class extends EventEmitter3 {
|
|
|
11776
11785
|
process.stderr.write(`[daemon] tombstone profile=${id}
|
|
11777
11786
|
`);
|
|
11778
11787
|
}
|
|
11779
|
-
if (
|
|
11780
|
-
if ((
|
|
11788
|
+
if (profilesToDelete.length) this.loadAgentsFromDb();
|
|
11789
|
+
if ((ownershipLockChanged || profilesToSync.length > 0 || profilesToDelete.length > 0) && this.wsConnected) {
|
|
11790
|
+
this.sendDeclare();
|
|
11791
|
+
}
|
|
11781
11792
|
this.emit("host-acked", payload);
|
|
11782
11793
|
}
|
|
11794
|
+
async applyHostAckOwnershipLock(payload) {
|
|
11795
|
+
const rejected = payload.rejectedAgents ?? [];
|
|
11796
|
+
if (rejected.length === 0) return false;
|
|
11797
|
+
let changed = false;
|
|
11798
|
+
for (const rejection of rejected) {
|
|
11799
|
+
if (!rejection?.imUserId) continue;
|
|
11800
|
+
const agentImUserId = rejection.imUserId;
|
|
11801
|
+
this.rejectedHostedAgentIds.set(agentImUserId, {
|
|
11802
|
+
...rejection,
|
|
11803
|
+
rejectedAt: Date.now()
|
|
11804
|
+
});
|
|
11805
|
+
const wasHosted = this.hostedAgents.delete(agentImUserId);
|
|
11806
|
+
const profiles = this.db.prepare("SELECT id FROM agent_profiles WHERE agent_im_user_id = ?").all(agentImUserId);
|
|
11807
|
+
const deleted = this.db.prepare("DELETE FROM agents WHERE im_user_id = ?").run(agentImUserId);
|
|
11808
|
+
await Promise.all(profiles.map((profile) => this.servicePool.drop(profile.id)));
|
|
11809
|
+
if (wasHosted || deleted.changes > 0) {
|
|
11810
|
+
changed = true;
|
|
11811
|
+
process.stderr.write(
|
|
11812
|
+
`[daemon] ownership rejected agent=${agentImUserId} reason=${rejection.reason} owner=${rejection.ownerDaemonId ?? "(unknown)"} \u2014 stop declaring locally
|
|
11813
|
+
`
|
|
11814
|
+
);
|
|
11815
|
+
}
|
|
11816
|
+
}
|
|
11817
|
+
return changed;
|
|
11818
|
+
}
|
|
11783
11819
|
async onTaskDispatch(payload, requestId) {
|
|
11784
11820
|
const targetDaemonId = readTargetDaemonId(payload);
|
|
11785
11821
|
if (targetDaemonId && targetDaemonId !== this.config.daemon_id) {
|
|
@@ -12062,18 +12098,22 @@ var Runner = class extends EventEmitter3 {
|
|
|
12062
12098
|
const name = agent?.card?.name || agent?.displayName || agent?.username || profile.agentImUserId;
|
|
12063
12099
|
const now = Date.now();
|
|
12064
12100
|
const tx = this.db.transaction(() => {
|
|
12065
|
-
this.
|
|
12066
|
-
|
|
12067
|
-
|
|
12068
|
-
|
|
12069
|
-
|
|
12070
|
-
|
|
12071
|
-
|
|
12072
|
-
|
|
12073
|
-
|
|
12074
|
-
|
|
12075
|
-
|
|
12076
|
-
|
|
12101
|
+
if (this.rejectedHostedAgentIds.has(profile.agentImUserId)) {
|
|
12102
|
+
this.db.prepare("DELETE FROM agents WHERE im_user_id = ?").run(profile.agentImUserId);
|
|
12103
|
+
} else {
|
|
12104
|
+
this.db.prepare(
|
|
12105
|
+
`INSERT OR REPLACE INTO agents
|
|
12106
|
+
(im_user_id, workspace_id, name, adapter_name, capabilities, status, version, synced_at, dirty)
|
|
12107
|
+
VALUES (?, ?, ?, ?, ?, 'offline', 1, ?, 0)`
|
|
12108
|
+
).run(
|
|
12109
|
+
profile.agentImUserId,
|
|
12110
|
+
profile.workspaceId,
|
|
12111
|
+
name,
|
|
12112
|
+
profile.adapterName,
|
|
12113
|
+
JSON.stringify(capabilities),
|
|
12114
|
+
now
|
|
12115
|
+
);
|
|
12116
|
+
}
|
|
12077
12117
|
this.db.prepare(
|
|
12078
12118
|
`INSERT OR REPLACE INTO agent_profiles
|
|
12079
12119
|
(id, workspace_id, agent_im_user_id, adapter_name, name, config, version, synced_at, dirty, deleted_at)
|
|
@@ -16944,7 +16984,7 @@ async function readResponseError(res) {
|
|
|
16944
16984
|
|
|
16945
16985
|
// src/cli/index.ts
|
|
16946
16986
|
init_ui();
|
|
16947
|
-
var VERSION = "2.0.
|
|
16987
|
+
var VERSION = "2.0.6";
|
|
16948
16988
|
function buildProgram() {
|
|
16949
16989
|
const program = new Command20("prismer").description("Prismer Cloud daemon CLI (TS-only).").version(VERSION);
|
|
16950
16990
|
program.addCommand(buildBannerCommand());
|