@khorsheed/dsh-room 0.1.1 → 0.2.0
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/CHANGELOG.md +9 -0
- package/README.en.md +9 -8
- package/README.i18n.yaml +2 -2
- package/README.md +9 -8
- package/lib/client.js +1007 -340
- package/lib/index.js +88 -12
- package/lib/{journal-CuRnWk66.js → journal-BWL3-i0s.js} +27 -0
- package/lib/tool.js +63 -11
- package/lib/typert.host.js +161 -26
- package/lib/typert.remote-client.d.ts +2 -0
- package/lib/typert.remote-client.js +142 -22
- package/lib/types/client/RoomActivityDock.d.ts +19 -0
- package/lib/types/client/RoomActivityDock.js +105 -0
- package/lib/types/client/RoomComposer.d.ts +1 -1
- package/lib/types/client/RoomComposer.js +3 -3
- package/lib/types/client/RoomPlanTab.d.ts +15 -0
- package/lib/types/client/RoomPlanTab.js +13 -0
- package/lib/types/client/RoomPlanView.d.ts +3 -2
- package/lib/types/client/RoomPlanView.js +5 -6
- package/lib/types/client/executions.d.ts +50 -0
- package/lib/types/client/executions.js +70 -0
- package/lib/types/client/index.d.ts +1 -1
- package/lib/types/client/index.js +33 -1
- package/lib/types/client/locales.d.ts +50 -0
- package/lib/types/client/locales.js +50 -0
- package/lib/types/client/preset-visibility.d.ts +3 -3
- package/lib/types/client/preset-visibility.js +2 -2
- package/lib/types/client/slots.d.ts +6 -1
- package/lib/types/dispatch.js +30 -6
- package/lib/types/index.d.ts +5 -0
- package/lib/types/index.js +42 -7
- package/lib/types/journal.d.ts +1 -1
- package/lib/types/journal.js +27 -1
- package/lib/types/tool-definition.d.ts +56 -0
- package/lib/types/tool-definition.js +393 -0
- package/lib/types/tool.d.ts +37 -49
- package/lib/types/tool.js +47 -381
- package/lib/types/types.d.ts +28 -0
- package/package.json +8 -7
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as memberId, c as pendingInstructions, d as rosterStaleSince, f as replayDeliveries, i as isRoomLog, l as previousCursor, n as ROOM_EVENT_TYPES, o as parseMentions, r as coordinatorMember, s as parseRelayDirective, t as MAIN_AGENT_MEMBER, u as replay } from "./journal-
|
|
1
|
+
import { a as memberId, c as pendingInstructions, d as rosterStaleSince, f as replayDeliveries, i as isRoomLog, l as previousCursor, n as ROOM_EVENT_TYPES, o as parseMentions, r as coordinatorMember, s as parseRelayDirective, t as MAIN_AGENT_MEMBER, u as replay } from "./journal-BWL3-i0s.js";
|
|
2
2
|
import { createHash, randomUUID } from "node:crypto";
|
|
3
3
|
import { SessionId } from "@deepseek-ai/dsh-session";
|
|
4
4
|
import { createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
@@ -1218,6 +1218,14 @@ var DispatchEngine = class {
|
|
|
1218
1218
|
const error = "Execution outcome is unknown after restart; reconcile before retrying";
|
|
1219
1219
|
return {
|
|
1220
1220
|
...state,
|
|
1221
|
+
...state.executions === void 0 ? {} : { executions: state.executions.map((execution) => {
|
|
1222
|
+
const active = execution.runId === void 0 ? [...this.inFlight.values()].includes(`${sessionId} ${execution.memberId}`) : this.scheduled.has(`${sessionId}:${execution.runId}`);
|
|
1223
|
+
return execution.state === "running" && !active ? {
|
|
1224
|
+
...execution,
|
|
1225
|
+
state: "failed",
|
|
1226
|
+
error
|
|
1227
|
+
} : execution;
|
|
1228
|
+
}) },
|
|
1221
1229
|
...state.deliveries === void 0 ? {} : { deliveries: state.deliveries.map((row) => row.status === "queued" && closedGoal(state, row.plan?.goalId) ? {
|
|
1222
1230
|
...row,
|
|
1223
1231
|
status: "cancelled"
|
|
@@ -1318,7 +1326,8 @@ var DispatchEngine = class {
|
|
|
1318
1326
|
member: memberName,
|
|
1319
1327
|
state: "running",
|
|
1320
1328
|
startedAt,
|
|
1321
|
-
runId
|
|
1329
|
+
runId,
|
|
1330
|
+
...member.kind === "main-agent" ? { childSessionId: room.id } : member.childSessionId === void 0 ? {} : { childSessionId: member.childSessionId }
|
|
1322
1331
|
});
|
|
1323
1332
|
await this.hooks.admitted?.(room, options.dispatchSeq);
|
|
1324
1333
|
await this.ctx.sessions.flush(room);
|
|
@@ -1326,7 +1335,7 @@ var DispatchEngine = class {
|
|
|
1326
1335
|
};
|
|
1327
1336
|
let outcome;
|
|
1328
1337
|
try {
|
|
1329
|
-
outcome = member.kind === "main-agent" ? await this.runMainAgent(room, member, cursor, text, await admitted(), options.relayIds ?? []) : await this.runCliMember(room, member, cursor, text, admitted, options.relayIds ?? [], submitted);
|
|
1338
|
+
outcome = member.kind === "main-agent" ? await this.runMainAgent(room, member, cursor, text, await admitted(), options.relayIds ?? []) : await this.runCliMember(room, member, cursor, text, admitted, options.relayIds ?? [], submitted, runId);
|
|
1330
1339
|
} catch (error) {
|
|
1331
1340
|
this.ctx.logger.warn(`room: dispatch to "${memberName}" failed: ${String(error)}`);
|
|
1332
1341
|
outcome = {
|
|
@@ -1409,7 +1418,7 @@ var DispatchEngine = class {
|
|
|
1409
1418
|
return { state: "done" };
|
|
1410
1419
|
}
|
|
1411
1420
|
/** CLI member turn: facade start (first round) or resume, then the speech mirror. */
|
|
1412
|
-
async runCliMember(room, member, cursor, text, admitted, relayIds, submitted) {
|
|
1421
|
+
async runCliMember(room, member, cursor, text, admitted, relayIds, submitted, runId) {
|
|
1413
1422
|
const facade = probeLocalAgent(this.ctx);
|
|
1414
1423
|
if (facade === void 0) {
|
|
1415
1424
|
this.ctx.logger.warn(`room: cannot dispatch to "${member.name}": local-agent facade unavailable`);
|
|
@@ -1418,9 +1427,23 @@ var DispatchEngine = class {
|
|
|
1418
1427
|
const provider = member.provider ?? "";
|
|
1419
1428
|
let startedAt;
|
|
1420
1429
|
const controlled = facade.supportsMemberConfiguration?.(provider) === true;
|
|
1421
|
-
const admission =
|
|
1422
|
-
|
|
1423
|
-
|
|
1430
|
+
const admission = {
|
|
1431
|
+
...controlled ? { onAdmitted: async () => {
|
|
1432
|
+
startedAt = await admitted();
|
|
1433
|
+
} } : {},
|
|
1434
|
+
onProgress: (event) => {
|
|
1435
|
+
if (event.kind !== "settled") return;
|
|
1436
|
+
if (room.snapshotEvents().filter((row) => row.type === "room/run-state" && row.data.runId === runId).at(-1)?.type !== "room/run-state") return;
|
|
1437
|
+
const total = event.usage?.totalTokens ?? (event.usage === void 0 ? void 0 : event.usage.inputTokens + event.usage.outputTokens);
|
|
1438
|
+
room.append("room/execution-metadata", {
|
|
1439
|
+
runId,
|
|
1440
|
+
...event.observedModel === void 0 ? {} : { model: event.observedModel },
|
|
1441
|
+
...event.observedEffort === void 0 ? {} : { effort: event.observedEffort },
|
|
1442
|
+
...total === void 0 || !Number.isFinite(total) || total < 0 ? {} : { tokens: total }
|
|
1443
|
+
});
|
|
1444
|
+
this.ctx.sessions.flush(room).catch((error) => this.ctx.logger.warn(`room: execution metadata flush failed: ${String(error)}`));
|
|
1445
|
+
}
|
|
1446
|
+
};
|
|
1424
1447
|
if (!controlled) startedAt = await admitted();
|
|
1425
1448
|
const { prompt, carried } = assemblePrompt(room, member, cursor, text, relayIds);
|
|
1426
1449
|
const prepared = member.childSessionId !== void 0 && facade.isPreparedMember?.(member.childSessionId) === true;
|
|
@@ -1433,14 +1456,14 @@ var DispatchEngine = class {
|
|
|
1433
1456
|
}) : member.childSessionId === void 0 ? facade.start(room.id, provider, [{
|
|
1434
1457
|
type: "text",
|
|
1435
1458
|
text: prompt
|
|
1436
|
-
}],
|
|
1459
|
+
}], {
|
|
1437
1460
|
...admission,
|
|
1438
1461
|
...member.model === void 0 ? {} : { model: member.model },
|
|
1439
1462
|
...member.cwd === void 0 ? {} : { cwd: member.cwd }
|
|
1440
1463
|
}) : facade.resume(room.id, provider, member.childSessionId, [{
|
|
1441
1464
|
type: "text",
|
|
1442
1465
|
text: prompt
|
|
1443
|
-
}],
|
|
1466
|
+
}], {
|
|
1444
1467
|
...admission,
|
|
1445
1468
|
...member.cwd === void 0 ? {} : { cwd: member.cwd }
|
|
1446
1469
|
});
|
|
@@ -1533,8 +1556,8 @@ var DispatchEngine = class {
|
|
|
1533
1556
|
* room host half: the `room` Typert Remote service. (The `room_invite` /
|
|
1534
1557
|
* `room_task` / `room_message` model tools left this package's profile-root
|
|
1535
1558
|
* registration in the M4' tool-row split — their definition factories live
|
|
1536
|
-
* in ./tool.ts and the
|
|
1537
|
-
* inside agent-preset compositions.) The room's entire state is the session's `room/*` custom-event
|
|
1559
|
+
* in ./tool-definition.ts and the package's own `./tool` composition entry
|
|
1560
|
+
* mounts them inside agent-preset compositions.) The room's entire state is the session's `room/*` custom-event
|
|
1538
1561
|
* journal (log-only events — persistence and reload-replay come free, the
|
|
1539
1562
|
* model never sees them, and harnesses without this plugin replay the session
|
|
1540
1563
|
* safely); every read folds the journal through the pure replay, and every
|
|
@@ -1637,6 +1660,7 @@ let RoomService = (() => {
|
|
|
1637
1660
|
let _closeTask_decorators;
|
|
1638
1661
|
let _setGoal_decorators;
|
|
1639
1662
|
let _cancel_decorators;
|
|
1663
|
+
let _cancelChild_decorators;
|
|
1640
1664
|
return class RoomService extends _classSuper {
|
|
1641
1665
|
static {
|
|
1642
1666
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
@@ -1657,6 +1681,7 @@ let RoomService = (() => {
|
|
|
1657
1681
|
_closeTask_decorators = [Remote("closeTask")];
|
|
1658
1682
|
_setGoal_decorators = [Remote("setGoal")];
|
|
1659
1683
|
_cancel_decorators = [Remote("cancel")];
|
|
1684
|
+
_cancelChild_decorators = [Remote("cancelChild")];
|
|
1660
1685
|
__esDecorate(this, null, _isRoom_decorators, {
|
|
1661
1686
|
kind: "method",
|
|
1662
1687
|
name: "isRoom",
|
|
@@ -1844,6 +1869,17 @@ let RoomService = (() => {
|
|
|
1844
1869
|
},
|
|
1845
1870
|
metadata: _metadata
|
|
1846
1871
|
}, null, _instanceExtraInitializers);
|
|
1872
|
+
__esDecorate(this, null, _cancelChild_decorators, {
|
|
1873
|
+
kind: "method",
|
|
1874
|
+
name: "cancelChild",
|
|
1875
|
+
static: false,
|
|
1876
|
+
private: false,
|
|
1877
|
+
access: {
|
|
1878
|
+
has: (obj) => "cancelChild" in obj,
|
|
1879
|
+
get: (obj) => obj.cancelChild
|
|
1880
|
+
},
|
|
1881
|
+
metadata: _metadata
|
|
1882
|
+
}, null, _instanceExtraInitializers);
|
|
1847
1883
|
if (_metadata) Object.defineProperty(this, Symbol.metadata, {
|
|
1848
1884
|
enumerable: true,
|
|
1849
1885
|
configurable: true,
|
|
@@ -3197,8 +3233,15 @@ let RoomService = (() => {
|
|
|
3197
3233
|
ok: false,
|
|
3198
3234
|
error: { code: "member-not-found" }
|
|
3199
3235
|
};
|
|
3236
|
+
const expected = loaded.state.runs.find((entry) => entry.member === request.name && entry.state === "running");
|
|
3237
|
+
if (request.expectedRunId !== void 0 && expected?.runId !== request.expectedRunId || request.expectedStartedAt !== void 0 && expected?.startedAt !== request.expectedStartedAt) return {
|
|
3238
|
+
ok: true,
|
|
3239
|
+
value: { cancelled: false }
|
|
3240
|
+
};
|
|
3200
3241
|
const facade = probeLocalAgent(this.ctx);
|
|
3201
|
-
|
|
3242
|
+
const native = member.kind === "main-agent" && expected !== void 0 ? this.ctx.agents.get(loaded.session.id) : void 0;
|
|
3243
|
+
if (native !== void 0) native.cancel({ kind: "user" });
|
|
3244
|
+
if (native !== void 0 || (facade !== void 0 && member.childSessionId !== void 0 ? facade.cancel(member.childSessionId) : false)) {
|
|
3202
3245
|
const running = loaded.state.runs.find((entry) => entry.member === request.name && entry.state === "running");
|
|
3203
3246
|
if (running === void 0) return {
|
|
3204
3247
|
ok: true,
|
|
@@ -3208,6 +3251,7 @@ let RoomService = (() => {
|
|
|
3208
3251
|
member: request.name,
|
|
3209
3252
|
state: "cancelled",
|
|
3210
3253
|
startedAt: running.startedAt,
|
|
3254
|
+
elapsedMs: Math.max(0, Date.now() - running.startedAt),
|
|
3211
3255
|
...running.runId === void 0 ? {} : { runId: running.runId }
|
|
3212
3256
|
});
|
|
3213
3257
|
for (const task of loaded.state.tasks) if (task.member === request.name && task.status === "in_progress" && (running.runId === void 0 || task.deliveryId === running.runId)) loaded.session.append("room/task-updated", {
|
|
@@ -3225,6 +3269,38 @@ let RoomService = (() => {
|
|
|
3225
3269
|
value: { cancelled: false }
|
|
3226
3270
|
};
|
|
3227
3271
|
}
|
|
3272
|
+
/** Native descendant controls share the host's continuation and cancellation channels. */
|
|
3273
|
+
async cancelChild(request) {
|
|
3274
|
+
const loaded = await this.ensureLive(request.sessionId);
|
|
3275
|
+
if (!loaded.ok) return {
|
|
3276
|
+
ok: false,
|
|
3277
|
+
error: loaded.error
|
|
3278
|
+
};
|
|
3279
|
+
const target = this.ctx.sessions.get(request.childSessionId);
|
|
3280
|
+
const seen = /* @__PURE__ */ new Set([request.childSessionId]);
|
|
3281
|
+
let parent = target?.header.parentSession;
|
|
3282
|
+
while (parent !== void 0 && parent !== request.sessionId && !seen.has(parent)) {
|
|
3283
|
+
seen.add(parent);
|
|
3284
|
+
parent = this.ctx.sessions.get(parent)?.header.parentSession;
|
|
3285
|
+
}
|
|
3286
|
+
if (!target || target.id === request.sessionId || parent !== request.sessionId) return {
|
|
3287
|
+
ok: true,
|
|
3288
|
+
value: { cancelled: false }
|
|
3289
|
+
};
|
|
3290
|
+
const facadeHit = probeLocalAgent(this.ctx)?.cancel(target.id) ?? false;
|
|
3291
|
+
const agent = this.ctx.agents.get(target.id);
|
|
3292
|
+
if (agent) {
|
|
3293
|
+
this.ctx.get("subagents")?.interrupt(target.id, {
|
|
3294
|
+
kind: "user",
|
|
3295
|
+
parentSessionId: target.header.parentSession
|
|
3296
|
+
});
|
|
3297
|
+
agent.cancel({ kind: "user" });
|
|
3298
|
+
}
|
|
3299
|
+
return {
|
|
3300
|
+
ok: true,
|
|
3301
|
+
value: { cancelled: facadeHit || agent !== void 0 }
|
|
3302
|
+
};
|
|
3303
|
+
}
|
|
3228
3304
|
};
|
|
3229
3305
|
})();
|
|
3230
3306
|
//#endregion
|
|
@@ -68,6 +68,7 @@ const ROOM_EVENT_TYPES = [
|
|
|
68
68
|
"room/dispatch",
|
|
69
69
|
"room/speech",
|
|
70
70
|
"room/run-state",
|
|
71
|
+
"room/execution-metadata",
|
|
71
72
|
"room/relay",
|
|
72
73
|
"room/relay-resolved",
|
|
73
74
|
"room/task-added",
|
|
@@ -144,6 +145,7 @@ function replay(events) {
|
|
|
144
145
|
const tasks = [];
|
|
145
146
|
const taskById = /* @__PURE__ */ new Map();
|
|
146
147
|
const runs = /* @__PURE__ */ new Map();
|
|
148
|
+
const executions = /* @__PURE__ */ new Map();
|
|
147
149
|
let goal;
|
|
148
150
|
let coordinator;
|
|
149
151
|
for (const event of events) switch (event.type) {
|
|
@@ -185,6 +187,10 @@ function replay(events) {
|
|
|
185
187
|
},
|
|
186
188
|
...event.data.childSessionId === void 0 ? {} : { childSessionId: event.data.childSessionId }
|
|
187
189
|
};
|
|
190
|
+
for (const [id, execution] of executions) if (execution.memberId === member.id && execution.childSessionId === void 0 && patched.childSessionId !== void 0) executions.set(id, {
|
|
191
|
+
...execution,
|
|
192
|
+
childSessionId: patched.childSessionId
|
|
193
|
+
});
|
|
188
194
|
const rename = event.data.rename;
|
|
189
195
|
if (rename === void 0 || rename === member.name || byName.has(rename)) {
|
|
190
196
|
byName.set(member.name, patched);
|
|
@@ -310,7 +316,27 @@ function replay(events) {
|
|
|
310
316
|
goal = text === "" ? void 0 : text;
|
|
311
317
|
break;
|
|
312
318
|
}
|
|
319
|
+
case "room/execution-metadata": {
|
|
320
|
+
const previous = executions.get(event.data.runId);
|
|
321
|
+
if (previous) executions.set(previous.id, {
|
|
322
|
+
...previous,
|
|
323
|
+
...event.data
|
|
324
|
+
});
|
|
325
|
+
break;
|
|
326
|
+
}
|
|
313
327
|
case "room/run-state": {
|
|
328
|
+
const member = byName.get(event.data.member);
|
|
329
|
+
const id = event.data.runId ?? `legacy:${member?.id ?? event.data.member}:${event.data.startedAt}`;
|
|
330
|
+
const previous = executions.get(id);
|
|
331
|
+
executions.set(id, {
|
|
332
|
+
id,
|
|
333
|
+
...member?.id === void 0 ? {} : { memberId: member.id },
|
|
334
|
+
...member?.childSessionId === void 0 ? {} : { childSessionId: member.childSessionId },
|
|
335
|
+
...member?.provider === void 0 ? {} : { provider: member.provider },
|
|
336
|
+
...previous,
|
|
337
|
+
...event.data,
|
|
338
|
+
...event.data.state === "running" || event.data.elapsedMs !== void 0 ? {} : { elapsedMs: Math.max(0, event.time - event.data.startedAt) }
|
|
339
|
+
});
|
|
314
340
|
const current = runs.get(event.data.member);
|
|
315
341
|
if (event.data.state !== "running" && event.data.runId !== void 0 && current?.runId !== void 0 && current.runId !== event.data.runId) break;
|
|
316
342
|
runs.set(event.data.member, {
|
|
@@ -331,6 +357,7 @@ function replay(events) {
|
|
|
331
357
|
members,
|
|
332
358
|
relays,
|
|
333
359
|
tasks,
|
|
360
|
+
...executions.size === 0 ? {} : { executions: [...executions.values()] },
|
|
334
361
|
...plan === void 0 ? {} : { plan },
|
|
335
362
|
...deliveries.length === 0 ? {} : { deliveries },
|
|
336
363
|
runs: [...runs.values()],
|
package/lib/tool.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { i as isRoomLog, r as coordinatorMember } from "./journal-
|
|
1
|
+
import { i as isRoomLog, r as coordinatorMember } from "./journal-BWL3-i0s.js";
|
|
2
2
|
import { defineTool } from "@deepseek-ai/dsh-tools";
|
|
3
|
-
//#region lib/types/tool.js
|
|
3
|
+
//#region lib/types/tool-definition.js
|
|
4
4
|
/**
|
|
5
5
|
* The room's model-facing tool DEFINITIONS, `room_invite`, `room_task`, and
|
|
6
6
|
* `room_message`: the main
|
|
@@ -18,14 +18,18 @@ import { defineTool } from "@deepseek-ai/dsh-tools";
|
|
|
18
18
|
* a message to a member through the same engine path as the human's
|
|
19
19
|
* `@member text`, minus the user bubble (the caller is the room's own agent).
|
|
20
20
|
*
|
|
21
|
-
* Since the tool-row split (M4') the core
|
|
22
|
-
*
|
|
23
|
-
* which mounts
|
|
24
|
-
* never at the profile root). The definitions
|
|
25
|
-
* UNTAGGED — the registering
|
|
26
|
-
* (AGENTS.md § Tool origin tagging — the owner is whichever
|
|
27
|
-
* the row).
|
|
28
|
-
*
|
|
21
|
+
* Since the tool-row split (M4') the core never REGISTERS these tools: the
|
|
22
|
+
* factories are consumed by the package's `./tool` subpath row
|
|
23
|
+
* ({@link file://./tool.ts}), which mounts them inside agent-preset
|
|
24
|
+
* compositions (session-granted, never at the profile root). The definitions
|
|
25
|
+
* are therefore returned UNTAGGED — the registering row applies its own
|
|
26
|
+
* tool-origin tag (AGENTS.md § Tool origin tagging — the owner is whichever
|
|
27
|
+
* package mounts the row).
|
|
28
|
+
*
|
|
29
|
+
* Internal module: not on the package's exports map (consumers reach it only
|
|
30
|
+
* through `./src/*`).
|
|
31
|
+
*
|
|
32
|
+
* @module @khorsheed/dsh-room
|
|
29
33
|
*/
|
|
30
34
|
/**
|
|
31
35
|
* Build the room_invite tool definition bound to the room service.
|
|
@@ -347,4 +351,52 @@ function roomPlanTool(backend) {
|
|
|
347
351
|
});
|
|
348
352
|
}
|
|
349
353
|
//#endregion
|
|
350
|
-
|
|
354
|
+
//#region lib/types/tool.js
|
|
355
|
+
const PACKAGE_NAME = "@khorsheed/dsh-room";
|
|
356
|
+
/**
|
|
357
|
+
* Tag the model-visible tools with their origin (AGENTS.md § Tool origin
|
|
358
|
+
* tagging; seam S12): the capability catalog reads this `Symbol.for`-keyed
|
|
359
|
+
* tag back through `ctx.tools.get()`, so the room tools attribute to THIS
|
|
360
|
+
* package (the row the preset mounts), not to the service core. The tag is
|
|
361
|
+
* host-side only and never travels on the model wire. Generic form (not
|
|
362
|
+
* `typeof defineTool`, which trips typert TS2321).
|
|
363
|
+
*/
|
|
364
|
+
const definePluginTool = (def) => Object.assign(def, { [Symbol.for("dsh.tool.origin")]: {
|
|
365
|
+
channel: "plugin",
|
|
366
|
+
owner: PACKAGE_NAME
|
|
367
|
+
} });
|
|
368
|
+
/** Cordis plugin name used by loader diagnostics. */
|
|
369
|
+
const name = "room-tool";
|
|
370
|
+
/**
|
|
371
|
+
* The `room` core is a declared inject (the owning-family companion
|
|
372
|
+
* exception to the community-service probe rule): a preset's standing scope
|
|
373
|
+
* mounts at registry-activation time, BEFORE the profile's later bundle rows
|
|
374
|
+
* provide the core, so a one-shot ctx.get probe at apply saw ABSENT there and
|
|
375
|
+
* nothing re-ran the row (rc.1 boot order; 3080 production 2026-09-27). The
|
|
376
|
+
* declared inject pends the row until the core provides, then the body
|
|
377
|
+
* applies. The tools registry still joins through deferred injection so its
|
|
378
|
+
* mount order cannot strand the registrations.
|
|
379
|
+
*/
|
|
380
|
+
const inject = ["room"];
|
|
381
|
+
/**
|
|
382
|
+
* Plugin body: register the room tools. The declared `room` inject pends the
|
|
383
|
+
* row until the core provides, so mount order can no longer strand it; the
|
|
384
|
+
* in-body guard stays as the defensive direct-call path.
|
|
385
|
+
* @param ctx - Cordis context (the preset's agent-plane mount).
|
|
386
|
+
*/
|
|
387
|
+
function apply(ctx) {
|
|
388
|
+
const service = ctx.get("room");
|
|
389
|
+
if (service === void 0) {
|
|
390
|
+
ctx.logger.info(`${name}: the global room service is absent — the room tools are not registered`);
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
ctx.inject(["tools"], (toolsCtx) => {
|
|
394
|
+
if (typeof service.commandPlan === "function") toolsCtx.effect(() => toolsCtx.tools.register(definePluginTool(roomPlanTool(service))), "room-tool: room_plan tool");
|
|
395
|
+
if (typeof service.readRoomContext === "function") toolsCtx.effect(() => toolsCtx.tools.register(definePluginTool(roomReadTool(service))), "room-tool: room_read tool");
|
|
396
|
+
toolsCtx.effect(() => toolsCtx.tools.register(definePluginTool(roomInviteTool(service))), "room-tool: room_invite tool");
|
|
397
|
+
toolsCtx.effect(() => toolsCtx.tools.register(definePluginTool(roomTaskTool(service))), "room-tool: room_task tool");
|
|
398
|
+
toolsCtx.effect(() => toolsCtx.tools.register(definePluginTool(roomMessageTool(service))), "room-tool: room_message tool");
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
//#endregion
|
|
402
|
+
export { apply, inject, name };
|