@ryubyte/dsh-a2a 0.1.4 → 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/README.en.md +45 -19
- package/README.md +28 -14
- package/lib/client.js +601 -443
- package/lib/index.js +267 -19
- package/lib/types/a2a-config.d.ts +23 -1
- package/lib/types/a2a-config.d.ts.map +1 -1
- package/lib/types/client/dashboard.css.d.ts +20 -0
- package/lib/types/client/dashboard.css.d.ts.map +1 -0
- package/lib/types/client/index.d.ts +4 -0
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/dashboard.d.ts +20 -0
- package/lib/types/dashboard.d.ts.map +1 -1
- package/lib/types/index.d.ts +18 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/server.d.ts +33 -1
- package/lib/types/server.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/a2a-config.ts +54 -5
- package/src/client/dashboard.css.ts +295 -0
- package/src/client/index.ts +669 -265
- package/src/dashboard.ts +39 -0
- package/src/index.ts +202 -21
- package/src/server.ts +67 -1
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { homedir, networkInterfaces } from "node:os";
|
|
2
3
|
import { dirname, join } from "node:path";
|
|
3
|
-
import { homedir } from "node:os";
|
|
4
4
|
//#region src/protocol.ts
|
|
5
5
|
/**
|
|
6
6
|
* A2A (Agent2Agent) Protocol v1.0 — TypeScript type definitions.
|
|
@@ -575,6 +575,7 @@ var A2AServer = class {
|
|
|
575
575
|
options;
|
|
576
576
|
store;
|
|
577
577
|
card;
|
|
578
|
+
/** JSON-RPC route path. Mutable: `updateCard` can move it at runtime. */
|
|
578
579
|
endpointPath;
|
|
579
580
|
execute;
|
|
580
581
|
listeners = /* @__PURE__ */ new Set();
|
|
@@ -595,6 +596,14 @@ var A2AServer = class {
|
|
|
595
596
|
*/
|
|
596
597
|
setBaseUrl(baseUrl) {
|
|
597
598
|
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
599
|
+
this.rebuildInterfaceUrls();
|
|
600
|
+
}
|
|
601
|
+
/** The base URL currently advertised in the AgentCard. */
|
|
602
|
+
getBaseUrl() {
|
|
603
|
+
return this.baseUrl;
|
|
604
|
+
}
|
|
605
|
+
/** Rebuild the advertised interface URL(s) from the current baseUrl + path. */
|
|
606
|
+
rebuildInterfaceUrls() {
|
|
598
607
|
this.card.supportedInterfaces = this.card.supportedInterfaces.map((iface) => ({
|
|
599
608
|
...iface,
|
|
600
609
|
url: `${this.baseUrl}${this.endpointPath}`
|
|
@@ -619,6 +628,43 @@ var A2AServer = class {
|
|
|
619
628
|
get authConfigured() {
|
|
620
629
|
return Boolean(this.options.authToken);
|
|
621
630
|
}
|
|
631
|
+
/**
|
|
632
|
+
* Update the advertised identity (name/description/version/baseUrl/
|
|
633
|
+
* endpointPath/skills) at runtime, in place. Mirrors setBaseUrl/setAuthToken:
|
|
634
|
+
* mutates `this.options` and the existing `this.card` object's properties —
|
|
635
|
+
* never reassigns `this.card`, so the route handler closure that reads
|
|
636
|
+
* `server.card` per request keeps seeing the live card.
|
|
637
|
+
*
|
|
638
|
+
* Returns `{ endpointChanged }`: when the JSON-RPC path moved, the caller
|
|
639
|
+
* (which owns route registration) must re-register routes on the new path —
|
|
640
|
+
* `updateCard` only mutates the advertised URL, not the live HTTP routes.
|
|
641
|
+
*/
|
|
642
|
+
updateCard(patch) {
|
|
643
|
+
let endpointChanged = false;
|
|
644
|
+
if (patch.agentName !== void 0) {
|
|
645
|
+
this.options.agentName = patch.agentName;
|
|
646
|
+
this.card.name = patch.agentName;
|
|
647
|
+
}
|
|
648
|
+
if (patch.agentDescription !== void 0) {
|
|
649
|
+
this.options.agentDescription = patch.agentDescription;
|
|
650
|
+
this.card.description = patch.agentDescription;
|
|
651
|
+
}
|
|
652
|
+
if (patch.agentVersion !== void 0) {
|
|
653
|
+
this.options.agentVersion = patch.agentVersion;
|
|
654
|
+
this.card.version = patch.agentVersion;
|
|
655
|
+
}
|
|
656
|
+
if (patch.skills !== void 0) {
|
|
657
|
+
this.options.skills = patch.skills;
|
|
658
|
+
this.card.skills = patch.skills;
|
|
659
|
+
}
|
|
660
|
+
if (patch.endpointPath !== void 0 && patch.endpointPath !== this.endpointPath) {
|
|
661
|
+
this.endpointPath = patch.endpointPath || "/a2a";
|
|
662
|
+
endpointChanged = true;
|
|
663
|
+
}
|
|
664
|
+
if (patch.baseUrl !== void 0) this.baseUrl = patch.baseUrl.replace(/\/$/, "");
|
|
665
|
+
if (patch.baseUrl !== void 0 || endpointChanged) this.rebuildInterfaceUrls();
|
|
666
|
+
return { endpointChanged };
|
|
667
|
+
}
|
|
622
668
|
buildCard() {
|
|
623
669
|
const iface = {
|
|
624
670
|
url: `${this.baseUrl.replace(/\/$/, "")}${this.endpointPath}`,
|
|
@@ -1398,6 +1444,29 @@ var DashboardRegistry = class {
|
|
|
1398
1444
|
ok: false,
|
|
1399
1445
|
message: "server-status is not wired (server mode not mounted)"
|
|
1400
1446
|
};
|
|
1447
|
+
case "set-server-identity":
|
|
1448
|
+
if (!this.hooks.setServerIdentity) return {
|
|
1449
|
+
ok: false,
|
|
1450
|
+
message: "set-server-identity is not wired (server not mounted)"
|
|
1451
|
+
};
|
|
1452
|
+
return this.hooks.setServerIdentity({
|
|
1453
|
+
agentName: payload?.agentName,
|
|
1454
|
+
agentDescription: payload?.agentDescription,
|
|
1455
|
+
agentVersion: payload?.agentVersion,
|
|
1456
|
+
baseUrl: payload?.baseUrl,
|
|
1457
|
+
endpointPath: payload?.endpointPath,
|
|
1458
|
+
skills: payload?.skills
|
|
1459
|
+
});
|
|
1460
|
+
case "update-agent":
|
|
1461
|
+
if (!this.hooks.updateAgent) return {
|
|
1462
|
+
ok: false,
|
|
1463
|
+
message: "update-agent is not wired (client mode not mounted)"
|
|
1464
|
+
};
|
|
1465
|
+
return this.hooks.updateAgent(target, {
|
|
1466
|
+
timeoutMs: typeof payload?.timeoutMs === "number" ? payload.timeoutMs : void 0,
|
|
1467
|
+
mapSkills: typeof payload?.mapSkills === "boolean" ? payload.mapSkills : void 0,
|
|
1468
|
+
bearerToken: payload?.bearerToken || void 0
|
|
1469
|
+
});
|
|
1401
1470
|
default: return {
|
|
1402
1471
|
ok: false,
|
|
1403
1472
|
message: `unknown action ${action}`
|
|
@@ -1479,6 +1548,30 @@ function profileNameFromArgv() {
|
|
|
1479
1548
|
}
|
|
1480
1549
|
}
|
|
1481
1550
|
/**
|
|
1551
|
+
* Best-effort profile-name fallback for launchers that resolve a profile
|
|
1552
|
+
* WITHOUT writing `--profile` back into argv.
|
|
1553
|
+
*
|
|
1554
|
+
* The dsh `web` subcommand is a hardcoded alias for `--profile web`: the
|
|
1555
|
+
* launcher resolves the name internally and boots the web profile, but the
|
|
1556
|
+
* process argv keeps the original tokens (`node …/dsh web [flags]`) — there
|
|
1557
|
+
* is no `--profile` flag and no environment variable naming the profile. So
|
|
1558
|
+
* when {@link profileNameFromArgv} finds nothing, check whether the first
|
|
1559
|
+
* non-flag token after argv[0] is a known dsh subcommand alias:
|
|
1560
|
+
*
|
|
1561
|
+
* - `web` → boot profile `web` (alias, never followed by a name)
|
|
1562
|
+
* - `--profile <n>` → already handled above
|
|
1563
|
+
* - anything else → unknown/not a profile alias (e.g. `plugin`, which
|
|
1564
|
+
* is a management mode, not a boot; returns undefined)
|
|
1565
|
+
*
|
|
1566
|
+
* Returns undefined when argv carries no recognizable alias, letting the
|
|
1567
|
+
* caller fall through to the cwd-based resolution steps.
|
|
1568
|
+
*/
|
|
1569
|
+
function profileNameFromDshAlias() {
|
|
1570
|
+
const argv = process.argv ?? [];
|
|
1571
|
+
if (argv.includes("--profile") || argv.some((a) => a.startsWith("--profile="))) return void 0;
|
|
1572
|
+
if (argv[2] === "web") return "web";
|
|
1573
|
+
}
|
|
1574
|
+
/**
|
|
1482
1575
|
* Resolve the a2a.json path for the current process, without depending on
|
|
1483
1576
|
* the launch directory. The plugin must work no matter where `dsh` was
|
|
1484
1577
|
* started from (dsh does NOT chdir into the profile directory), so this
|
|
@@ -1488,7 +1581,9 @@ function profileNameFromArgv() {
|
|
|
1488
1581
|
*
|
|
1489
1582
|
* Order:
|
|
1490
1583
|
* 0. `$DSH_HOME/profiles/<argv --profile>/a2a.json` — the active profile
|
|
1491
|
-
* as named on the command line (most authoritative; works from ANY cwd)
|
|
1584
|
+
* as named on the command line (most authoritative; works from ANY cwd).
|
|
1585
|
+
* Also matches the `dsh web` alias, which boots profile `web` without
|
|
1586
|
+
* writing `--profile` into argv.
|
|
1492
1587
|
* 1. `cwd/a2a.json` — explicit when launched inside a profile dir
|
|
1493
1588
|
* 2. outward from cwd: the nearest ancestor holding `a2a.json` — covers
|
|
1494
1589
|
* launching from e.g. a repo checkout whose parent chain includes the
|
|
@@ -1506,7 +1601,7 @@ function resolveConfigPath() {
|
|
|
1506
1601
|
const cwd = process.cwd();
|
|
1507
1602
|
const home = process.env.DSH_HOME ?? join(homedir(), ".dsh");
|
|
1508
1603
|
const base = cwd.split(/[\\/]/).pop() ?? "";
|
|
1509
|
-
const profileName = profileNameFromArgv();
|
|
1604
|
+
const profileName = profileNameFromArgv() ?? profileNameFromDshAlias();
|
|
1510
1605
|
if (profileName && profileName !== "." && profileName !== ".." && !profileName.includes("/") && !profileName.includes("\\")) {
|
|
1511
1606
|
const argvFile = join(home, "profiles", profileName, A2A_CONFIG_FILENAME);
|
|
1512
1607
|
if (existsSync(argvFile)) return argvFile;
|
|
@@ -1525,6 +1620,7 @@ function resolveConfigPath() {
|
|
|
1525
1620
|
if (base && existsSync(profileFile)) return profileFile;
|
|
1526
1621
|
const globalFile = join(home, A2A_CONFIG_FILENAME);
|
|
1527
1622
|
if (existsSync(globalFile)) return globalFile;
|
|
1623
|
+
if (profileName && profileName !== "." && profileName !== ".." && !profileName.includes("/") && !profileName.includes("\\")) return join(home, "profiles", profileName, A2A_CONFIG_FILENAME);
|
|
1528
1624
|
return cwdFile;
|
|
1529
1625
|
}
|
|
1530
1626
|
/** Read the persisted config (empty object when absent or unreadable). */
|
|
@@ -1976,6 +2072,53 @@ function apply(ctx, config = {}) {
|
|
|
1976
2072
|
ok: true,
|
|
1977
2073
|
message: `agent ${connectionId} removed`
|
|
1978
2074
|
};
|
|
2075
|
+
},
|
|
2076
|
+
updateAgent: async (connectionId, patch) => {
|
|
2077
|
+
const entry = live.get(connectionId);
|
|
2078
|
+
const snap = dashboard.snapshot().outbound.find((o) => o.connectionId === connectionId);
|
|
2079
|
+
const name = entry?.name ?? snap?.name;
|
|
2080
|
+
const url = entry?.agentCardUrl ?? snap?.agentCardUrl;
|
|
2081
|
+
entry?.configured ?? snap?.configured;
|
|
2082
|
+
if (!name || !url) return {
|
|
2083
|
+
ok: false,
|
|
2084
|
+
message: `connection ${connectionId} not found`
|
|
2085
|
+
};
|
|
2086
|
+
const found = findInitial({
|
|
2087
|
+
name,
|
|
2088
|
+
agentCardUrl: url
|
|
2089
|
+
});
|
|
2090
|
+
if (!found) return {
|
|
2091
|
+
ok: false,
|
|
2092
|
+
message: "only saved (configured) agents can be edited"
|
|
2093
|
+
};
|
|
2094
|
+
if (patch.timeoutMs !== void 0) found.item.timeoutMs = patch.timeoutMs;
|
|
2095
|
+
if (patch.mapSkills !== void 0) found.item.mapSkills = patch.mapSkills;
|
|
2096
|
+
if (patch.bearerToken !== void 0) found.item.bearerToken = patch.bearerToken || void 0;
|
|
2097
|
+
persistAgents();
|
|
2098
|
+
const item = found.item;
|
|
2099
|
+
if (item.enabled === false) return {
|
|
2100
|
+
ok: true,
|
|
2101
|
+
message: `agent ${connectionId} updated (config kept, still disabled)`
|
|
2102
|
+
};
|
|
2103
|
+
if (entry) {
|
|
2104
|
+
entry.disposeAll();
|
|
2105
|
+
live.delete(connectionId);
|
|
2106
|
+
}
|
|
2107
|
+
dashboard.setAgentState(connectionId, "reconnecting");
|
|
2108
|
+
const newId = await connect(item.name, item.agentCardUrl, item.configured, {
|
|
2109
|
+
bearerToken: item.bearerToken,
|
|
2110
|
+
timeoutMs: item.timeoutMs,
|
|
2111
|
+
mapSkills: item.mapSkills
|
|
2112
|
+
});
|
|
2113
|
+
if (!newId) return {
|
|
2114
|
+
ok: false,
|
|
2115
|
+
message: `update of ${connectionId} failed to reconnect`
|
|
2116
|
+
};
|
|
2117
|
+
dashboard.removeAgent(connectionId);
|
|
2118
|
+
return {
|
|
2119
|
+
ok: true,
|
|
2120
|
+
message: `agent ${connectionId} updated as ${newId} (saved to ${configPath})`
|
|
2121
|
+
};
|
|
1979
2122
|
}
|
|
1980
2123
|
});
|
|
1981
2124
|
ctx.effect(() => {
|
|
@@ -2008,15 +2151,19 @@ function apply(ctx, config = {}) {
|
|
|
2008
2151
|
}, "a2a: client tools");
|
|
2009
2152
|
});
|
|
2010
2153
|
}
|
|
2011
|
-
|
|
2154
|
+
{
|
|
2012
2155
|
const store = new TaskStore();
|
|
2013
2156
|
const taskPeer = /* @__PURE__ */ new Map();
|
|
2014
2157
|
const pendingSettled = /* @__PURE__ */ new Set();
|
|
2015
2158
|
ctx.inject(["webServer"], (ctx) => {
|
|
2016
2159
|
ctx.effect(() => {
|
|
2017
2160
|
const webServer = ctx.webServer;
|
|
2018
|
-
const baseUrl = mergedConfig.baseUrl ??
|
|
2161
|
+
const baseUrl = mergedConfig.baseUrl ?? inferBaseUrl(webServer.host, webServer.port);
|
|
2019
2162
|
const endpointPath = mergedConfig.endpointPath ?? DEFAULT_ENDPOINT;
|
|
2163
|
+
if (mergedConfig.baseUrl) try {
|
|
2164
|
+
const pinnedPort = new URL(mergedConfig.baseUrl).port;
|
|
2165
|
+
if (pinnedPort && Number(pinnedPort) !== webServer.port) logger?.warn?.(`[a2a] pinned baseUrl ${mergedConfig.baseUrl} port ${pinnedPort} != listen port ${webServer.port}; remote callers may be unreachable. Clear baseUrl in settings to auto-infer.`);
|
|
2166
|
+
} catch {}
|
|
2020
2167
|
let execute = mergedConfig.execute;
|
|
2021
2168
|
let executorKind = execute ? "custom" : "none";
|
|
2022
2169
|
let disposeExecutor;
|
|
@@ -2073,7 +2220,7 @@ function apply(ctx, config = {}) {
|
|
|
2073
2220
|
} else pendingSettled.add(taskId);
|
|
2074
2221
|
}
|
|
2075
2222
|
}, store);
|
|
2076
|
-
let enabled =
|
|
2223
|
+
let enabled = wantsServer;
|
|
2077
2224
|
let disposers = [];
|
|
2078
2225
|
const registerRoutes = () => {
|
|
2079
2226
|
disposers.push(webServer.register({
|
|
@@ -2126,19 +2273,23 @@ function apply(ctx, config = {}) {
|
|
|
2126
2273
|
for (const d of disposers) d();
|
|
2127
2274
|
disposers = [];
|
|
2128
2275
|
};
|
|
2129
|
-
|
|
2130
|
-
|
|
2276
|
+
if (enabled) {
|
|
2277
|
+
registerRoutes();
|
|
2278
|
+
logger?.info?.(`[a2a] A2A server mounted: AgentCard at ${baseUrl}/.well-known/agent-card.json, JSON-RPC at ${server.endpointPath}`);
|
|
2279
|
+
} else logger?.info?.("[a2a] A2A server ready but not serving (enable via settings)");
|
|
2131
2280
|
const serverCard = () => ({
|
|
2132
|
-
baseUrl,
|
|
2281
|
+
baseUrl: server.getBaseUrl(),
|
|
2133
2282
|
agentName: server.card.name,
|
|
2134
2283
|
agentDescription: server.card.description,
|
|
2135
2284
|
agentVersion: server.card.version,
|
|
2136
|
-
|
|
2137
|
-
|
|
2285
|
+
endpointPath: server.endpointPath,
|
|
2286
|
+
endpoint: `${server.getBaseUrl()}${server.endpointPath}`,
|
|
2287
|
+
agentCardUrl: `${server.getBaseUrl()}/.well-known/agent-card.json`,
|
|
2138
2288
|
skills: (server.card.skills ?? []).map((s) => ({
|
|
2139
2289
|
id: s.id,
|
|
2140
2290
|
name: s.name,
|
|
2141
|
-
description: s.description
|
|
2291
|
+
description: s.description,
|
|
2292
|
+
tags: s.tags
|
|
2142
2293
|
})),
|
|
2143
2294
|
customExecutor: Boolean(mergedConfig.execute),
|
|
2144
2295
|
executor: executorKind,
|
|
@@ -2154,17 +2305,63 @@ function apply(ctx, config = {}) {
|
|
|
2154
2305
|
registerRoutes();
|
|
2155
2306
|
enabled = true;
|
|
2156
2307
|
logger?.info?.("[a2a] A2A server enabled");
|
|
2308
|
+
} else {
|
|
2309
|
+
unregisterRoutes();
|
|
2310
|
+
enabled = false;
|
|
2311
|
+
logger?.info?.("[a2a] A2A server disabled");
|
|
2312
|
+
}
|
|
2313
|
+
const next = loadConfig();
|
|
2314
|
+
next.server = {
|
|
2315
|
+
...next.server ?? {},
|
|
2316
|
+
enabled
|
|
2317
|
+
};
|
|
2318
|
+
const res = saveConfig(next);
|
|
2319
|
+
if (!res.ok) {
|
|
2320
|
+
logger?.error?.(`[a2a] failed to persist server.enabled to ${res.path}: ${res.message}`);
|
|
2321
|
+
return {
|
|
2322
|
+
ok: false,
|
|
2323
|
+
message: `applied in-memory but failed to save: ${res.message}`
|
|
2324
|
+
};
|
|
2325
|
+
}
|
|
2326
|
+
return {
|
|
2327
|
+
ok: true,
|
|
2328
|
+
message: enable ? "A2A server enabled" : "A2A server disabled"
|
|
2329
|
+
};
|
|
2330
|
+
},
|
|
2331
|
+
setServerIdentity: async (patch) => {
|
|
2332
|
+
const clearBaseUrl = patch.baseUrl === "";
|
|
2333
|
+
const cardPatch = clearBaseUrl ? {
|
|
2334
|
+
...patch,
|
|
2335
|
+
baseUrl: void 0
|
|
2336
|
+
} : patch;
|
|
2337
|
+
const { endpointChanged } = server.updateCard(cardPatch);
|
|
2338
|
+
if (clearBaseUrl) server.setBaseUrl(inferBaseUrl(webServer.host, webServer.port));
|
|
2339
|
+
if (endpointChanged && enabled) {
|
|
2340
|
+
unregisterRoutes();
|
|
2341
|
+
registerRoutes();
|
|
2342
|
+
}
|
|
2343
|
+
const next = loadConfig();
|
|
2344
|
+
const s = { ...next.server ?? {} };
|
|
2345
|
+
if (patch.agentName !== void 0) s.agentName = patch.agentName;
|
|
2346
|
+
if (patch.agentDescription !== void 0) s.agentDescription = patch.agentDescription;
|
|
2347
|
+
if (patch.agentVersion !== void 0) s.agentVersion = patch.agentVersion;
|
|
2348
|
+
if (clearBaseUrl) delete s.baseUrl;
|
|
2349
|
+
else if (patch.baseUrl !== void 0) s.baseUrl = patch.baseUrl;
|
|
2350
|
+
if (patch.endpointPath !== void 0) s.endpointPath = patch.endpointPath;
|
|
2351
|
+
if (patch.skills !== void 0) s.skills = patch.skills;
|
|
2352
|
+
next.server = s;
|
|
2353
|
+
const res = saveConfig(next);
|
|
2354
|
+
if (!res.ok) {
|
|
2355
|
+
logger?.error?.(`[a2a] failed to persist server identity to ${res.path}: ${res.message}`);
|
|
2157
2356
|
return {
|
|
2158
|
-
ok:
|
|
2159
|
-
message:
|
|
2357
|
+
ok: false,
|
|
2358
|
+
message: `applied in-memory but failed to save: ${res.message}`
|
|
2160
2359
|
};
|
|
2161
2360
|
}
|
|
2162
|
-
|
|
2163
|
-
enabled = false;
|
|
2164
|
-
logger?.info?.("[a2a] A2A server disabled");
|
|
2361
|
+
logger?.info?.(`[a2a] server identity updated (saved to ${res.path})`);
|
|
2165
2362
|
return {
|
|
2166
2363
|
ok: true,
|
|
2167
|
-
message:
|
|
2364
|
+
message: `已更新对外服务 (saved to ${res.path})`
|
|
2168
2365
|
};
|
|
2169
2366
|
},
|
|
2170
2367
|
setServerAuthToken: async (token) => {
|
|
@@ -2281,6 +2478,57 @@ function inboundSessionCwd(configPath) {
|
|
|
2281
2478
|
return process.cwd();
|
|
2282
2479
|
}
|
|
2283
2480
|
}
|
|
2481
|
+
/**
|
|
2482
|
+
* Derive the public base URL advertised in the AgentCard from the real wire
|
|
2483
|
+
* listen address, when the operator did not pin `baseUrl` in config.
|
|
2484
|
+
*
|
|
2485
|
+
* The A2A AgentCard must carry a URL a REMOTE caller can reach. When the web
|
|
2486
|
+
* server binds only loopback (`127.0.0.1`), that address is correct. But when
|
|
2487
|
+
* it binds every interface (`0.0.0.0`), advertising `127.0.0.1` is wrong for
|
|
2488
|
+
* every non-local caller — it points at the caller's own loopback. In that
|
|
2489
|
+
* case pick the machine's best-known LAN address (the primary non-loopback
|
|
2490
|
+
* IPv4 of the interface that routes to the default gateway), and only fall
|
|
2491
|
+
* back to loopback when no such address exists. IPv6 link-local is skipped
|
|
2492
|
+
* (not reachable without a scope id).
|
|
2493
|
+
*
|
|
2494
|
+
* @param host - the web server's configured bind host ('127.0.0.1' | '0.0.0.0').
|
|
2495
|
+
* @param port - the OS-assigned (or configured) listen port.
|
|
2496
|
+
* @returns a scheme+host+port URL for Agents to call back into this DSH.
|
|
2497
|
+
*/
|
|
2498
|
+
function inferBaseUrl(host, port) {
|
|
2499
|
+
return `http://${host === "0.0.0.0" ? primaryLanAddress() ?? "127.0.0.1" : host || "127.0.0.1"}:${port}`;
|
|
2500
|
+
}
|
|
2501
|
+
/**
|
|
2502
|
+
* Best single LAN IPv4 for this machine: the address of the non-loopback
|
|
2503
|
+
* interface whose route reaches the default gateway (the address a remote
|
|
2504
|
+
* peer on the same subnet would use to reach us). Returns undefined when the
|
|
2505
|
+
* machine has no non-loopback IPv4 (e.g. offline / containers).
|
|
2506
|
+
*
|
|
2507
|
+
* Prefers IPv4 (A2A URLs here are v4-style), skips link-local (169.254.0.0/16)
|
|
2508
|
+
* and CGNAT (100.64.0.0/10) ranges, which are useless to advertise.
|
|
2509
|
+
*/
|
|
2510
|
+
function primaryLanAddress() {
|
|
2511
|
+
try {
|
|
2512
|
+
const ifaces = networkInterfaces();
|
|
2513
|
+
let candidate;
|
|
2514
|
+
for (const name of Object.keys(ifaces)) {
|
|
2515
|
+
const addrs = ifaces[name] ?? [];
|
|
2516
|
+
for (const a of addrs) {
|
|
2517
|
+
if (a.family !== "IPv4" || a.internal) continue;
|
|
2518
|
+
const ip = a.address;
|
|
2519
|
+
if (ip.startsWith("169.254.")) continue;
|
|
2520
|
+
const first = Number(ip.split(".")[0]);
|
|
2521
|
+
const second = Number(ip.split(".")[1]);
|
|
2522
|
+
if (first === 100 && second >= 64 && second <= 127) continue;
|
|
2523
|
+
if (!candidate) candidate = ip;
|
|
2524
|
+
if (name === "en0" || name === "eth0" || name === "ens3" || name === "ens5") return ip;
|
|
2525
|
+
}
|
|
2526
|
+
}
|
|
2527
|
+
return candidate;
|
|
2528
|
+
} catch {
|
|
2529
|
+
return;
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2284
2532
|
/** Drain the request body from a Node IncomingMessage. */
|
|
2285
2533
|
async function readBody(req) {
|
|
2286
2534
|
return new Promise((resolve, reject) => {
|
|
@@ -2321,4 +2569,4 @@ function toServerReq(req) {
|
|
|
2321
2569
|
};
|
|
2322
2570
|
}
|
|
2323
2571
|
//#endregion
|
|
2324
|
-
export { A2AClient, A2AError, A2AServer, A2A_ERROR_CODES, A2A_METHODS, DashboardRegistry, Role, TaskState, TaskStore, apply, createDshAgentExecutor, defaultExecutor, defaultSkills, fetchAgentCard, getSharedRegistry, inject, isTerminal, name, notConfiguredExecutor, registerAgentTools, shellExecutor };
|
|
2572
|
+
export { A2AClient, A2AError, A2AServer, A2A_ERROR_CODES, A2A_METHODS, DashboardRegistry, Role, TaskState, TaskStore, apply, createDshAgentExecutor, defaultExecutor, defaultSkills, fetchAgentCard, getSharedRegistry, inferBaseUrl, inject, isTerminal, name, notConfiguredExecutor, registerAgentTools, shellExecutor };
|
|
@@ -68,6 +68,26 @@ export interface PersistedA2AConfig {
|
|
|
68
68
|
* guessing from cwd's basename.
|
|
69
69
|
*/
|
|
70
70
|
export declare function profileNameFromArgv(): string | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* Best-effort profile-name fallback for launchers that resolve a profile
|
|
73
|
+
* WITHOUT writing `--profile` back into argv.
|
|
74
|
+
*
|
|
75
|
+
* The dsh `web` subcommand is a hardcoded alias for `--profile web`: the
|
|
76
|
+
* launcher resolves the name internally and boots the web profile, but the
|
|
77
|
+
* process argv keeps the original tokens (`node …/dsh web [flags]`) — there
|
|
78
|
+
* is no `--profile` flag and no environment variable naming the profile. So
|
|
79
|
+
* when {@link profileNameFromArgv} finds nothing, check whether the first
|
|
80
|
+
* non-flag token after argv[0] is a known dsh subcommand alias:
|
|
81
|
+
*
|
|
82
|
+
* - `web` → boot profile `web` (alias, never followed by a name)
|
|
83
|
+
* - `--profile <n>` → already handled above
|
|
84
|
+
* - anything else → unknown/not a profile alias (e.g. `plugin`, which
|
|
85
|
+
* is a management mode, not a boot; returns undefined)
|
|
86
|
+
*
|
|
87
|
+
* Returns undefined when argv carries no recognizable alias, letting the
|
|
88
|
+
* caller fall through to the cwd-based resolution steps.
|
|
89
|
+
*/
|
|
90
|
+
export declare function profileNameFromDshAlias(): string | undefined;
|
|
71
91
|
/**
|
|
72
92
|
* Resolve the a2a.json path for the current process, without depending on
|
|
73
93
|
* the launch directory. The plugin must work no matter where `dsh` was
|
|
@@ -78,7 +98,9 @@ export declare function profileNameFromArgv(): string | undefined;
|
|
|
78
98
|
*
|
|
79
99
|
* Order:
|
|
80
100
|
* 0. `$DSH_HOME/profiles/<argv --profile>/a2a.json` — the active profile
|
|
81
|
-
* as named on the command line (most authoritative; works from ANY cwd)
|
|
101
|
+
* as named on the command line (most authoritative; works from ANY cwd).
|
|
102
|
+
* Also matches the `dsh web` alias, which boots profile `web` without
|
|
103
|
+
* writing `--profile` into argv.
|
|
82
104
|
* 1. `cwd/a2a.json` — explicit when launched inside a profile dir
|
|
83
105
|
* 2. outward from cwd: the nearest ancestor holding `a2a.json` — covers
|
|
84
106
|
* launching from e.g. a repo checkout whose parent chain includes the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"a2a-config.d.ts","sourceRoot":"","sources":["../../src/a2a-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,eAAO,MAAM,mBAAmB,aAAa,CAAC;AAE9C,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,0DAA0D;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACzG;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAChC,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,SAAS,CAaxD;AAED
|
|
1
|
+
{"version":3,"file":"a2a-config.d.ts","sourceRoot":"","sources":["../../src/a2a-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,eAAO,MAAM,mBAAmB,aAAa,CAAC;AAE9C,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,0DAA0D;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACzG;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAChC,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,SAAS,CAaxD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,GAAG,SAAS,CAW5D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAoD1C;AAED,0EAA0E;AAC1E,wBAAgB,UAAU,IAAI,kBAAkB,CAW/C;AAED,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,MAAM,EAAE,kBAAkB,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAatG;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,kBAAkB,GAAG,eAAe,CAmBpG"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-a2a — dashboard stylesheet.
|
|
3
|
+
*
|
|
4
|
+
* The browser half is a compiled bundle (not a dynamic cordis plugin), so it
|
|
5
|
+
* injects its own stylesheet the same way first-party DSH client UI packages
|
|
6
|
+
* do: a single idempotent <style> tag, styled entirely with the product's
|
|
7
|
+
* `--dsw-alias-*` design tokens (so light/dark themes and future token
|
|
8
|
+
* changes apply automatically), plus `@media` queries for narrow windows.
|
|
9
|
+
*
|
|
10
|
+
* Class names are prefixed with `a2a-` to avoid collisions with product or
|
|
11
|
+
* third-party styles.
|
|
12
|
+
*/
|
|
13
|
+
export declare const DASHBOARD_CSS_ID = "@ryubyte/dsh-a2a/dashboard.css";
|
|
14
|
+
/**
|
|
15
|
+
* Idempotently inject the dashboard stylesheet into <head>. Returns a
|
|
16
|
+
* disposer that removes the tag; safe to call repeatedly (a second call is a
|
|
17
|
+
* no-op and returns a no-op disposer).
|
|
18
|
+
*/
|
|
19
|
+
export declare function injectDashboardStyles(): () => void;
|
|
20
|
+
//# sourceMappingURL=dashboard.css.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard.css.d.ts","sourceRoot":"","sources":["../../../src/client/dashboard.css.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,gBAAgB,mCAAmC,CAAC;AAmQjE;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,IAAI,CAiBlD"}
|
|
@@ -8,6 +8,10 @@
|
|
|
8
8
|
* The data and the controls live behind the host's `/a2a/api` routes
|
|
9
9
|
* (served by the node half on the same webserver); the browser half is a
|
|
10
10
|
* thin read/write client with no protocol knowledge.
|
|
11
|
+
*
|
|
12
|
+
* Styling: a single idempotent stylesheet (dashboard.css.ts) built entirely
|
|
13
|
+
* on the product's `--dsw-alias-*` design tokens, so light/dark themes and
|
|
14
|
+
* narrow-window layouts follow the DSH shell. No inline styles.
|
|
11
15
|
*/
|
|
12
16
|
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
|
|
13
17
|
import type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAE5E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAsC,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAG9E,0DAA0D;AAC1D,eAAO,MAAM,MAAM,UAAY,CAAC;AAEhC,wBAAgB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAyB9C;AA8DD,KAAK,YAAY,GAAG,YAAY,CAAC,kBAAkB,CAAC,CAAC;AA+FrD,qDAAqD;AACrD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CA8UnE"}
|
package/lib/types/dashboard.d.ts
CHANGED
|
@@ -105,6 +105,26 @@ export interface DashboardControlHooks {
|
|
|
105
105
|
serverStatus?: () => ControlResult;
|
|
106
106
|
/** Runtime-remove an outbound agent by its connection id. */
|
|
107
107
|
removeAgent?: (connectionId: string) => Promise<ControlResult>;
|
|
108
|
+
/** Update the outbound-server identity (AgentCard) at runtime (persisted). */
|
|
109
|
+
setServerIdentity?: (patch: {
|
|
110
|
+
agentName?: string;
|
|
111
|
+
agentDescription?: string;
|
|
112
|
+
agentVersion?: string;
|
|
113
|
+
baseUrl?: string;
|
|
114
|
+
endpointPath?: string;
|
|
115
|
+
skills?: Array<{
|
|
116
|
+
id: string;
|
|
117
|
+
name: string;
|
|
118
|
+
description: string;
|
|
119
|
+
tags?: string[];
|
|
120
|
+
}>;
|
|
121
|
+
}) => Promise<ControlResult>;
|
|
122
|
+
/** Update a saved outbound agent's advanced fields, reconnecting to apply. */
|
|
123
|
+
updateAgent?: (connectionId: string, patch: {
|
|
124
|
+
timeoutMs?: number;
|
|
125
|
+
mapSkills?: boolean;
|
|
126
|
+
bearerToken?: string;
|
|
127
|
+
}) => Promise<ControlResult>;
|
|
108
128
|
}
|
|
109
129
|
/** Registry of live A2A connections, both directions. */
|
|
110
130
|
export declare class DashboardRegistry {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/dashboard.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/dashboard.ts"],"names":[],"mappings":"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"}
|
package/lib/types/index.d.ts
CHANGED
|
@@ -125,4 +125,22 @@ export declare const name = "a2a";
|
|
|
125
125
|
*/
|
|
126
126
|
export declare const inject: readonly ["webServer", "tools"];
|
|
127
127
|
export declare function apply(ctx: Context, config?: A2APluginConfig): void;
|
|
128
|
+
/**
|
|
129
|
+
* Derive the public base URL advertised in the AgentCard from the real wire
|
|
130
|
+
* listen address, when the operator did not pin `baseUrl` in config.
|
|
131
|
+
*
|
|
132
|
+
* The A2A AgentCard must carry a URL a REMOTE caller can reach. When the web
|
|
133
|
+
* server binds only loopback (`127.0.0.1`), that address is correct. But when
|
|
134
|
+
* it binds every interface (`0.0.0.0`), advertising `127.0.0.1` is wrong for
|
|
135
|
+
* every non-local caller — it points at the caller's own loopback. In that
|
|
136
|
+
* case pick the machine's best-known LAN address (the primary non-loopback
|
|
137
|
+
* IPv4 of the interface that routes to the default gateway), and only fall
|
|
138
|
+
* back to loopback when no such address exists. IPv6 link-local is skipped
|
|
139
|
+
* (not reachable without a scope id).
|
|
140
|
+
*
|
|
141
|
+
* @param host - the web server's configured bind host ('127.0.0.1' | '0.0.0.0').
|
|
142
|
+
* @param port - the OS-assigned (or configured) listen port.
|
|
143
|
+
* @returns a scheme+host+port URL for Agents to call back into this DSH.
|
|
144
|
+
*/
|
|
145
|
+
export declare function inferBaseUrl(host: string, port: number): string;
|
|
128
146
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/types/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/lib/types/server.d.ts
CHANGED
|
@@ -14,6 +14,19 @@ import type { AgentCard, AgentSkill, Message, Part, Task } from './protocol.js';
|
|
|
14
14
|
import { TaskState } from './protocol.js';
|
|
15
15
|
export interface ServerSkill extends AgentSkill {
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Runtime-editable slice of the advertised AgentCard identity. Every field is
|
|
19
|
+
* optional; only the provided ones change. Applied in place by
|
|
20
|
+
* {@link A2AServer.updateCard} (mirrors setBaseUrl/setAuthToken).
|
|
21
|
+
*/
|
|
22
|
+
export interface CardIdentityPatch {
|
|
23
|
+
agentName?: string;
|
|
24
|
+
agentDescription?: string;
|
|
25
|
+
agentVersion?: string;
|
|
26
|
+
baseUrl?: string;
|
|
27
|
+
endpointPath?: string;
|
|
28
|
+
skills?: ServerSkill[];
|
|
29
|
+
}
|
|
17
30
|
export interface ServerOptions {
|
|
18
31
|
/** Public base URL (scheme + host + optional prefix) where this DSH is exposed. */
|
|
19
32
|
baseUrl: string;
|
|
@@ -94,7 +107,8 @@ export declare class A2AServer {
|
|
|
94
107
|
readonly options: ServerOptions;
|
|
95
108
|
readonly store: TaskStore;
|
|
96
109
|
readonly card: AgentCard;
|
|
97
|
-
|
|
110
|
+
/** JSON-RPC route path. Mutable: `updateCard` can move it at runtime. */
|
|
111
|
+
endpointPath: string;
|
|
98
112
|
private execute;
|
|
99
113
|
private listeners;
|
|
100
114
|
private baseUrl;
|
|
@@ -106,6 +120,10 @@ export declare class A2AServer {
|
|
|
106
120
|
* address is known (e.g. ephemeral port). Mutates `card` in place.
|
|
107
121
|
*/
|
|
108
122
|
setBaseUrl(baseUrl: string): void;
|
|
123
|
+
/** The base URL currently advertised in the AgentCard. */
|
|
124
|
+
getBaseUrl(): string;
|
|
125
|
+
/** Rebuild the advertised interface URL(s) from the current baseUrl + path. */
|
|
126
|
+
private rebuildInterfaceUrls;
|
|
109
127
|
/**
|
|
110
128
|
* Set or clear the shared bearer token that gates the inbound endpoint at
|
|
111
129
|
* runtime. Rebuilds the AgentCard so the `bearerAuth` security scheme is
|
|
@@ -116,6 +134,20 @@ export declare class A2AServer {
|
|
|
116
134
|
setAuthToken(token?: string): void;
|
|
117
135
|
/** Whether the inbound endpoint is currently token-gated. */
|
|
118
136
|
get authConfigured(): boolean;
|
|
137
|
+
/**
|
|
138
|
+
* Update the advertised identity (name/description/version/baseUrl/
|
|
139
|
+
* endpointPath/skills) at runtime, in place. Mirrors setBaseUrl/setAuthToken:
|
|
140
|
+
* mutates `this.options` and the existing `this.card` object's properties —
|
|
141
|
+
* never reassigns `this.card`, so the route handler closure that reads
|
|
142
|
+
* `server.card` per request keeps seeing the live card.
|
|
143
|
+
*
|
|
144
|
+
* Returns `{ endpointChanged }`: when the JSON-RPC path moved, the caller
|
|
145
|
+
* (which owns route registration) must re-register routes on the new path —
|
|
146
|
+
* `updateCard` only mutates the advertised URL, not the live HTTP routes.
|
|
147
|
+
*/
|
|
148
|
+
updateCard(patch: CardIdentityPatch): {
|
|
149
|
+
endpointChanged: boolean;
|
|
150
|
+
};
|
|
119
151
|
private buildCard;
|
|
120
152
|
/** True when the request carries the configured bearer token. */
|
|
121
153
|
private authorized;
|