@agentconnect.md/daemon 1.0.0-rc.60 → 1.0.0-rc.62
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 +95 -61
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7595,7 +7595,7 @@ function cachedRuntimeNames(root) {
|
|
|
7595
7595
|
}
|
|
7596
7596
|
/**
|
|
7597
7597
|
* Runtime versions (registry id -> `version`) read from the local cache. Used to
|
|
7598
|
-
* stamp the `facts/
|
|
7598
|
+
* stamp each entry of the `facts/daemon-runtimes` snapshot the daemon reports.
|
|
7599
7599
|
* Entries with no `version` are omitted (callers fall back to ''). `{}` when no
|
|
7600
7600
|
* cached registry doc exists.
|
|
7601
7601
|
*/
|
|
@@ -13254,6 +13254,74 @@ const SessionHistoryPage = object({
|
|
|
13254
13254
|
nextCursor: string().optional()
|
|
13255
13255
|
});
|
|
13256
13256
|
//#endregion
|
|
13257
|
+
//#region ../protocol/dist/frames/telemetry.js
|
|
13258
|
+
/**
|
|
13259
|
+
* Telemetry & facts (D→C) — protocol §7.
|
|
13260
|
+
*
|
|
13261
|
+
* The dashboard's real-time source. `event/session` is the converged milestone
|
|
13262
|
+
* feed (NOT the message stream); `facts/daemon-runtimes` is the observed runtime
|
|
13263
|
+
* capability feed; `heartbeat` drives the watchdog.
|
|
13264
|
+
*/
|
|
13265
|
+
const Heartbeat = object({
|
|
13266
|
+
load: object({
|
|
13267
|
+
cpu: number(),
|
|
13268
|
+
mem: number(),
|
|
13269
|
+
agents: number().int()
|
|
13270
|
+
}),
|
|
13271
|
+
health: _enum(["ok", "degraded"]),
|
|
13272
|
+
activeSessions: number().int(),
|
|
13273
|
+
degradedScopes: array(string()).default([])
|
|
13274
|
+
});
|
|
13275
|
+
/** Converged session lifecycle milestone — protocol §7.2. NOT the message stream. */
|
|
13276
|
+
const EventSession = object({
|
|
13277
|
+
sessionId: string().uuid(),
|
|
13278
|
+
agentId: string().uuid(),
|
|
13279
|
+
launchId: string().uuid(),
|
|
13280
|
+
phase: _enum([
|
|
13281
|
+
"start",
|
|
13282
|
+
"plan",
|
|
13283
|
+
"problem",
|
|
13284
|
+
"end"
|
|
13285
|
+
]),
|
|
13286
|
+
link: string().optional(),
|
|
13287
|
+
summary: string().optional(),
|
|
13288
|
+
ts: string().datetime()
|
|
13289
|
+
});
|
|
13290
|
+
/**
|
|
13291
|
+
* Per-session token-usage report — D→C EVT. The daemon meters usage from the
|
|
13292
|
+
* agent's ACP stream and reports the session's CUMULATIVE snapshot (latest-wins)
|
|
13293
|
+
* so the CP can persist it for the console's historical usage aggregates. This is
|
|
13294
|
+
* dashboard metadata (token counts + cost), never the message stream. Idempotent
|
|
13295
|
+
* by `sessionId`: re-sending the same snapshot is a no-op upsert on the CP.
|
|
13296
|
+
*/
|
|
13297
|
+
const UsageReport = object({
|
|
13298
|
+
sessionId: string(),
|
|
13299
|
+
agentId: string().uuid(),
|
|
13300
|
+
platform: string().optional(),
|
|
13301
|
+
channel: string().optional(),
|
|
13302
|
+
lastActivityAt: string(),
|
|
13303
|
+
usage: SessionUsage
|
|
13304
|
+
});
|
|
13305
|
+
/**
|
|
13306
|
+
* Observed capabilities of an installed runtime — protocol §7.3. The element
|
|
13307
|
+
* type of the `facts/daemon-runtimes` snapshot. As a standalone per-runtime
|
|
13308
|
+
* frame (`facts/runtime-profile`, upsert-only) it is DEPRECATED: current
|
|
13309
|
+
* daemons report the full snapshot instead; the CP keeps accepting the old
|
|
13310
|
+
* frame from older daemons.
|
|
13311
|
+
*/
|
|
13312
|
+
const FactsRuntimeProfile = object({
|
|
13313
|
+
runtime: string(),
|
|
13314
|
+
version: string(),
|
|
13315
|
+
models: array(string()),
|
|
13316
|
+
contextWindow: number().int().optional(),
|
|
13317
|
+
acpSupport: _enum([
|
|
13318
|
+
"full",
|
|
13319
|
+
"partial",
|
|
13320
|
+
"none"
|
|
13321
|
+
]),
|
|
13322
|
+
toolCalling: boolean()
|
|
13323
|
+
});
|
|
13324
|
+
//#endregion
|
|
13257
13325
|
//#region ../protocol/dist/frame.js
|
|
13258
13326
|
/**
|
|
13259
13327
|
* The single source of truth for the wire: `type` string → payload zod schema.
|
|
@@ -13271,16 +13339,7 @@ const FRAME_SCHEMAS = {
|
|
|
13271
13339
|
"auth/ok": AuthOk,
|
|
13272
13340
|
register: RegisterReq,
|
|
13273
13341
|
"register/ok": RegisterOk,
|
|
13274
|
-
heartbeat:
|
|
13275
|
-
load: object({
|
|
13276
|
-
cpu: number(),
|
|
13277
|
-
mem: number(),
|
|
13278
|
-
agents: number().int()
|
|
13279
|
-
}),
|
|
13280
|
-
health: _enum(["ok", "degraded"]),
|
|
13281
|
-
activeSessions: number().int(),
|
|
13282
|
-
degradedScopes: array(string()).default([])
|
|
13283
|
-
}),
|
|
13342
|
+
heartbeat: Heartbeat,
|
|
13284
13343
|
"agent/launch": AgentLaunch,
|
|
13285
13344
|
"agent/launched": AgentLaunched,
|
|
13286
13345
|
"agent/stop": AgentStop,
|
|
@@ -13306,40 +13365,10 @@ const FRAME_SCHEMAS = {
|
|
|
13306
13365
|
"secrets/renew": SecretsRenew,
|
|
13307
13366
|
"secrets/revoke": SecretsRevoke,
|
|
13308
13367
|
"scope-attestation": ScopeAttestation,
|
|
13309
|
-
"event/session":
|
|
13310
|
-
|
|
13311
|
-
|
|
13312
|
-
|
|
13313
|
-
phase: _enum([
|
|
13314
|
-
"start",
|
|
13315
|
-
"plan",
|
|
13316
|
-
"problem",
|
|
13317
|
-
"end"
|
|
13318
|
-
]),
|
|
13319
|
-
link: string().optional(),
|
|
13320
|
-
summary: string().optional(),
|
|
13321
|
-
ts: string().datetime()
|
|
13322
|
-
}),
|
|
13323
|
-
"usage/report": object({
|
|
13324
|
-
sessionId: string(),
|
|
13325
|
-
agentId: string().uuid(),
|
|
13326
|
-
platform: string().optional(),
|
|
13327
|
-
channel: string().optional(),
|
|
13328
|
-
lastActivityAt: string(),
|
|
13329
|
-
usage: SessionUsage
|
|
13330
|
-
}),
|
|
13331
|
-
"facts/runtime-profile": object({
|
|
13332
|
-
runtime: string(),
|
|
13333
|
-
version: string(),
|
|
13334
|
-
models: array(string()),
|
|
13335
|
-
contextWindow: number().int().optional(),
|
|
13336
|
-
acpSupport: _enum([
|
|
13337
|
-
"full",
|
|
13338
|
-
"partial",
|
|
13339
|
-
"none"
|
|
13340
|
-
]),
|
|
13341
|
-
toolCalling: boolean()
|
|
13342
|
-
}),
|
|
13368
|
+
"event/session": EventSession,
|
|
13369
|
+
"usage/report": UsageReport,
|
|
13370
|
+
"facts/runtime-profile": FactsRuntimeProfile,
|
|
13371
|
+
"facts/daemon-runtimes": object({ runtimes: array(FactsRuntimeProfile) }),
|
|
13343
13372
|
"session/list": SessionListReq,
|
|
13344
13373
|
"session/list/page": SessionListPage,
|
|
13345
13374
|
"session/history": SessionHistoryReq,
|
|
@@ -13434,6 +13463,7 @@ discriminatedUnion("type", [
|
|
|
13434
13463
|
frame("event/session", FRAME_SCHEMAS["event/session"]),
|
|
13435
13464
|
frame("usage/report", FRAME_SCHEMAS["usage/report"]),
|
|
13436
13465
|
frame("facts/runtime-profile", FRAME_SCHEMAS["facts/runtime-profile"]),
|
|
13466
|
+
frame("facts/daemon-runtimes", FRAME_SCHEMAS["facts/daemon-runtimes"]),
|
|
13437
13467
|
frame("session/list", FRAME_SCHEMAS["session/list"]),
|
|
13438
13468
|
frame("session/list/page", FRAME_SCHEMAS["session/list/page"]),
|
|
13439
13469
|
frame("session/history", FRAME_SCHEMAS["session/history"]),
|
|
@@ -81880,13 +81910,14 @@ async function probeRuntime(id, rt, cwd, opts = {}) {
|
|
|
81880
81910
|
return host.modelOptions();
|
|
81881
81911
|
};
|
|
81882
81912
|
try {
|
|
81883
|
-
const
|
|
81884
|
-
|
|
81913
|
+
const opt = await Promise.race([run(), timeout]);
|
|
81914
|
+
const models = (opt?.models ?? []).filter((m) => m !== "default");
|
|
81915
|
+
opts.log?.info(`probe: ${id} ok (models: ${models.length ? models.join(", ") : "none advertised"})`);
|
|
81885
81916
|
return {
|
|
81886
81917
|
runtime: id,
|
|
81887
81918
|
ok: true,
|
|
81888
|
-
models
|
|
81889
|
-
currentModel:
|
|
81919
|
+
models,
|
|
81920
|
+
currentModel: opt?.current
|
|
81890
81921
|
};
|
|
81891
81922
|
} catch (err) {
|
|
81892
81923
|
const error = err.message;
|
|
@@ -82136,17 +82167,19 @@ var CpClient = class {
|
|
|
82136
82167
|
this.heartbeatMs = ok.heartbeatSec > 0 ? ok.heartbeatSec * 1e3 : this.deps.heartbeatDefaultMs;
|
|
82137
82168
|
this.armHeartbeat();
|
|
82138
82169
|
this.deps.log.info(`cp: READY (epoch=${this.sessionEpoch}, routingEpoch=${this.routingEpoch})`);
|
|
82139
|
-
|
|
82170
|
+
this.emitDaemonRuntimes(this.deps.runtimeProfiles());
|
|
82140
82171
|
this.deps.onReady?.();
|
|
82141
82172
|
}
|
|
82142
82173
|
/**
|
|
82143
|
-
* Push
|
|
82144
|
-
*
|
|
82145
|
-
*
|
|
82174
|
+
* Push the full runtime snapshot (D→C `facts/daemon-runtimes` EVT,
|
|
82175
|
+
* fire-and-forget) — sent on each register and again when a probe sweep
|
|
82176
|
+
* completes. REPLACE semantics on the CP: it reconciles the daemon's stored
|
|
82177
|
+
* runtime list to exactly this snapshot, pruning runtimes that are no longer
|
|
82178
|
+
* installed. No-op unless READY/DRAINING.
|
|
82146
82179
|
*/
|
|
82147
|
-
|
|
82180
|
+
emitDaemonRuntimes(runtimes) {
|
|
82148
82181
|
if (this.state !== "READY" && this.state !== "DRAINING") return;
|
|
82149
|
-
this.transport?.send(encode(buildEnvelope("facts/
|
|
82182
|
+
this.transport?.send(encode(buildEnvelope("facts/daemon-runtimes", { runtimes })));
|
|
82150
82183
|
}
|
|
82151
82184
|
/**
|
|
82152
82185
|
* Report a session's cumulative token usage (D→C `usage/report` EVT,
|
|
@@ -83900,8 +83933,9 @@ var Daemon = class Daemon {
|
|
|
83900
83933
|
this.cpClient.start();
|
|
83901
83934
|
this.log.info(`cp: connecting to ${url}…`);
|
|
83902
83935
|
}
|
|
83903
|
-
/** Build the current
|
|
83904
|
-
* models learned by the
|
|
83936
|
+
/** Build the current profile entry for a runtime (one element of the
|
|
83937
|
+
* `facts/daemon-runtimes` snapshot), folding in any models learned by the
|
|
83938
|
+
* probe sweep. */
|
|
83905
83939
|
runtimeProfileFor(id) {
|
|
83906
83940
|
return {
|
|
83907
83941
|
runtime: id,
|
|
@@ -83916,8 +83950,8 @@ var Daemon = class Daemon {
|
|
|
83916
83950
|
static PROBE_TTL_MS = 5 * 6e4;
|
|
83917
83951
|
/**
|
|
83918
83952
|
* Probe every installed runtime in the background (launch → initialize →
|
|
83919
|
-
* session/new → read models → tear down), then emit
|
|
83920
|
-
*
|
|
83953
|
+
* session/new → read models → tear down), then emit one `facts/daemon-runtimes`
|
|
83954
|
+
* snapshot once the whole sweep completes so the CP replaces its runtime list.
|
|
83921
83955
|
*
|
|
83922
83956
|
* Triggered on each CP (re)connect. Deduped while in flight; skipped (with a
|
|
83923
83957
|
* cached re-emit) when the last sweep is still fresh, so a reconnect storm can't
|
|
@@ -83930,7 +83964,7 @@ var Daemon = class Daemon {
|
|
|
83930
83964
|
if (ids.length === 0) return;
|
|
83931
83965
|
if (this.probing) return;
|
|
83932
83966
|
if (this.lastProbeAtMs > 0 && Date.now() - this.lastProbeAtMs < Daemon.PROBE_TTL_MS) {
|
|
83933
|
-
|
|
83967
|
+
this.cpClient?.emitDaemonRuntimes(ids.map((id) => this.runtimeProfileFor(id)));
|
|
83934
83968
|
return;
|
|
83935
83969
|
}
|
|
83936
83970
|
this.probing = true;
|
|
@@ -83941,7 +83975,7 @@ var Daemon = class Daemon {
|
|
|
83941
83975
|
this.lastProbeAtMs = Date.now();
|
|
83942
83976
|
const okCount = results.filter((r) => r.ok).length;
|
|
83943
83977
|
this.log.info(`probe: sweep complete — ${okCount}/${results.length} runtime(s) reachable`);
|
|
83944
|
-
|
|
83978
|
+
this.cpClient?.emitDaemonRuntimes(ids.map((id) => this.runtimeProfileFor(id)));
|
|
83945
83979
|
} catch (err) {
|
|
83946
83980
|
this.log.warn(`probe: sweep failed: ${formatErr(err)}`);
|
|
83947
83981
|
} finally {
|