@thehammer/danx-dashboard-mcp 0.1.313 → 0.1.314
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/compaction-control.js +41 -12
- package/package.json +1 -1
|
@@ -9,7 +9,10 @@
|
|
|
9
9
|
* - the rest is written to ONE local file the danxbot plugin's `PreCompact` gate reads: `~/.config/danxbot/compaction/<sessionId>.json`. The gate never
|
|
10
10
|
* asks the network: Claude Code proposes a compaction before every model request.
|
|
11
11
|
*
|
|
12
|
-
* The file is `{v: 1, sessionId, control: {floorTokens, passAtTokens, windowTokens, releaseUntilMs, releaseId} | null, askedAt: string | null}`.
|
|
12
|
+
* The file is `{v: 1, sessionId, control: {floorTokens, passAtTokens, windowTokens, releaseUntilMs, releaseId, agents} | null, askedAt: string | null}`.
|
|
13
|
+
* DX-5218: `agents` holds each SUB-AGENT's own control by agent id, `{passAtTokens, ask, releaseUntilMs, releaseId}`: the sub-agent's own safety-valve size, its own
|
|
14
|
+
* request (the relay cannot show a sub-agent a request, so unlike the main agent's it stays in the file for the plugin to deliver to that agent) and its own
|
|
15
|
+
* single-use release. `sessionId` is the
|
|
13
16
|
* session the file was written for (the plugin refuses a file that names another); `windowTokens` is the context window the dashboard assumed for the session's
|
|
14
17
|
* model line (the plugin does not arm a session whose real window is smaller). `control: null` says the session is not under the handshake (the plugin disarms). `askedAt` is the relay's own memory of the last request it showed the agent, kept in the file so a restart
|
|
15
18
|
* of this server does not show it again; the plugin ignores it.
|
|
@@ -27,6 +30,20 @@ import { assertSessionIdSegment, pruneStaleSessionFiles } from "./session-connec
|
|
|
27
30
|
export const COMPACTION_ASK_MAX_CODE_POINTS = 1000;
|
|
28
31
|
const isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
29
32
|
const isCount = (v) => typeof v === "number" && Number.isInteger(v) && v >= 0;
|
|
33
|
+
const isTime = (v) => typeof v === "number" && Number.isFinite(v);
|
|
34
|
+
const isAsk = (a) => isRecord(a) && isCount(a.seq) && typeof a.at === "string" && a.at !== "" && typeof a.text === "string" && a.text.trim() !== "";
|
|
35
|
+
/** Why an ask / release pair (the main agent's, or a sub-agent's) cannot be read, or `null` when it can. */
|
|
36
|
+
function invalidAskAndRelease(c) {
|
|
37
|
+
if (c.ask !== null && !isAsk(c.ask))
|
|
38
|
+
return "ask must be null or {seq, at, text}";
|
|
39
|
+
if ((c.releaseUntilMs === null) !== (c.releaseId === null))
|
|
40
|
+
return "releaseUntilMs and releaseId are both set or both null";
|
|
41
|
+
if (c.releaseUntilMs !== null && !isTime(c.releaseUntilMs))
|
|
42
|
+
return "releaseUntilMs must be a number or null";
|
|
43
|
+
if (c.releaseId !== null && (typeof c.releaseId !== "string" || c.releaseId === ""))
|
|
44
|
+
return "releaseId must be a string or null";
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
30
47
|
/** Why a `compaction` frame's data cannot be read, or `null` when it can. */
|
|
31
48
|
export function invalidCompactionReason(value) {
|
|
32
49
|
if (!isRecord(value) || !("control" in value))
|
|
@@ -45,17 +62,22 @@ export function invalidCompactionReason(value) {
|
|
|
45
62
|
return "passAtTokens must be above floorTokens";
|
|
46
63
|
if (c.windowTokens <= c.passAtTokens)
|
|
47
64
|
return "windowTokens must be above passAtTokens";
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
65
|
+
const own = invalidAskAndRelease(c);
|
|
66
|
+
if (own !== null)
|
|
67
|
+
return own;
|
|
68
|
+
if (!isRecord(c.agents))
|
|
69
|
+
return "agents must be an object keyed by agent id";
|
|
70
|
+
for (const [id, a] of Object.entries(c.agents)) {
|
|
71
|
+
if (id === "")
|
|
72
|
+
return "agents has an empty agent id";
|
|
73
|
+
if (!isRecord(a))
|
|
74
|
+
return `agents.${id} is not an object`;
|
|
75
|
+
if (!isCount(a.passAtTokens))
|
|
76
|
+
return `agents.${id}.passAtTokens must be a whole number`;
|
|
77
|
+
const reason = invalidAskAndRelease(a);
|
|
78
|
+
if (reason !== null)
|
|
79
|
+
return `agents.${id}: ${reason}`;
|
|
52
80
|
}
|
|
53
|
-
if ((c.releaseUntilMs === null) !== (c.releaseId === null))
|
|
54
|
-
return "releaseUntilMs and releaseId are both set or both null";
|
|
55
|
-
if (c.releaseUntilMs !== null && !(typeof c.releaseUntilMs === "number" && Number.isFinite(c.releaseUntilMs)))
|
|
56
|
-
return "releaseUntilMs must be a number or null";
|
|
57
|
-
if (c.releaseId !== null && (typeof c.releaseId !== "string" || c.releaseId === ""))
|
|
58
|
-
return "releaseId must be a string or null";
|
|
59
81
|
return null;
|
|
60
82
|
}
|
|
61
83
|
/** The control of a valid frame's data (`invalidCompactionReason` is `null`). */
|
|
@@ -76,7 +98,14 @@ export function fileOf(control, askedAt, sessionId) {
|
|
|
76
98
|
sessionId,
|
|
77
99
|
control: control === null
|
|
78
100
|
? null
|
|
79
|
-
: {
|
|
101
|
+
: {
|
|
102
|
+
floorTokens: control.floorTokens,
|
|
103
|
+
passAtTokens: control.passAtTokens,
|
|
104
|
+
windowTokens: control.windowTokens,
|
|
105
|
+
releaseUntilMs: control.releaseUntilMs,
|
|
106
|
+
releaseId: control.releaseId,
|
|
107
|
+
agents: control.agents,
|
|
108
|
+
},
|
|
80
109
|
askedAt,
|
|
81
110
|
};
|
|
82
111
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thehammer/danx-dashboard-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.314",
|
|
4
4
|
"description": "Stdio MCP server fronting danxbot's dashboard API for agents (operator sessions and dispatched workers alike): the generic danxbot_api/danxbot_api_list/danxbot_api_spec tools reach any route the caller's credential may call, plus dedicated agent-specific tools (plan_connect, request_permission, attach_file, and danxbot_slack_reply) (DX-3465, PLN-11 R-25).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|