@camstack/server 1.1.25 → 1.1.27
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/api/core/hwaccel.router.js +63 -40
- package/dist/api/trpc/generated-cap-mounts.js +2 -1
- package/dist/api/trpc/generated-cap-routers.js +687 -582
- package/dist/api/trpc/trpc.router.js +5 -4
- package/dist/core/addon/addon-registry.service.js +26 -7
- package/dist/core/agent/agent-registry.service.js +82 -8
- package/dist/core/moleculer/moleculer.service.js +8 -6
- package/package.json +1 -1
|
@@ -4,16 +4,16 @@ exports.createHwAccelRouter = createHwAccelRouter;
|
|
|
4
4
|
/**
|
|
5
5
|
* Hwaccel router — fixed core API (not a capability).
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
7
|
+
* Repointed (S3 consolidation) onto the `platform-probe` capability — the SOLE
|
|
8
|
+
* cross-node-pinnable hwaccel surface — instead of the retired `$hwaccel`
|
|
9
|
+
* Moleculer service. The hub-local instance is resolved via
|
|
10
|
+
* `capabilityRegistry.getSingleton('platform-probe')`; any other cluster node
|
|
11
|
+
* via `moleculer.createCapabilityProxy('platform-probe', nodeId)` (the same
|
|
12
|
+
* node-routing the codegen'd cap routers use). Used by the admin UI pipeline /
|
|
13
|
+
* NodeDetail pages to show which hardware backend each node will use.
|
|
12
14
|
*
|
|
13
|
-
*
|
|
14
|
-
* `
|
|
15
|
-
* (hub + forked worker + remote agent) registers `$hwaccel` at
|
|
16
|
-
* bootstrap, so any reachable nodeId works.
|
|
15
|
+
* The tRPC input/output shapes are UNCHANGED for clients (`{prefer}` in,
|
|
16
|
+
* `{preferred, rationale}` out) — no SDK break.
|
|
17
17
|
*/
|
|
18
18
|
const zod_1 = require("zod");
|
|
19
19
|
const trpc_middleware_js_1 = require("../trpc/trpc.middleware.js");
|
|
@@ -33,33 +33,69 @@ const HwAccelPreferSchema = zod_1.z
|
|
|
33
33
|
.union([HwAccelBackendSchema, zod_1.z.literal('none')])
|
|
34
34
|
.nullable()
|
|
35
35
|
.optional();
|
|
36
|
+
// `preferred` is a plain string array (not the decode-backend enum) to match
|
|
37
|
+
// the `platform-probe` cap's own resolution schema: the resolver only ever
|
|
38
|
+
// emits decode backends, but a narrow enum would reject any future addition and
|
|
39
|
+
// force a cast at the cap boundary.
|
|
36
40
|
const HwAccelResolutionSchema = zod_1.z.object({
|
|
37
|
-
preferred: zod_1.z.array(
|
|
41
|
+
preferred: zod_1.z.array(zod_1.z.string()).readonly(),
|
|
38
42
|
rationale: zod_1.z.string(),
|
|
39
43
|
});
|
|
40
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Resolve hwaccel on a specific cluster node through the `platform-probe` cap
|
|
46
|
+
* proxy. `createCapabilityProxy` returns `Record<string, (params) =>
|
|
47
|
+
* Promise<unknown>> | null`; rather than casting that to the provider type
|
|
48
|
+
* (the webrtc-session mount does — repo rule forbids it), we call the proxy's
|
|
49
|
+
* `resolveHwAccel` and narrow its result through the cap's Zod OUTPUT schema.
|
|
50
|
+
* A missing proxy (node unreachable), a missing method, a malformed response,
|
|
51
|
+
* or a thrown call all degrade to an EXPLAINED empty list rather than
|
|
52
|
+
* corrupting the typed API surface.
|
|
53
|
+
*/
|
|
54
|
+
async function resolveHwAccelOnNode(moleculer, nodeId, prefer) {
|
|
55
|
+
const proxy = moleculer?.createCapabilityProxy('platform-probe', nodeId) ?? null;
|
|
56
|
+
const resolveFn = proxy?.['resolveHwAccel'];
|
|
57
|
+
if (!resolveFn) {
|
|
58
|
+
return { preferred: [], rationale: `node ${nodeId} unreachable` };
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
const raw = await resolveFn({ prefer });
|
|
62
|
+
const parsed = HwAccelResolutionSchema.safeParse(raw);
|
|
63
|
+
if (!parsed.success) {
|
|
64
|
+
return { preferred: [], rationale: `invalid probe response from ${nodeId}` };
|
|
65
|
+
}
|
|
66
|
+
return parsed.data;
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
70
|
+
return { preferred: [], rationale: `resolve failed: ${msg}` };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function listAvailableNodeIds(moleculer) {
|
|
74
|
+
const broker = moleculer?.broker ?? null;
|
|
75
|
+
if (!broker)
|
|
76
|
+
return [];
|
|
77
|
+
const withRegistry = broker;
|
|
78
|
+
return withRegistry.registry.getNodeList({ onlyAvailable: true }).map((n) => n.id);
|
|
79
|
+
}
|
|
80
|
+
function createHwAccelRouter(capabilityRegistry, moleculer) {
|
|
41
81
|
return (0, trpc_middleware_js_1.trpcRouter)({
|
|
42
|
-
/** Probe the current hub process. */
|
|
82
|
+
/** Probe the current hub process via the local `platform-probe` singleton. */
|
|
43
83
|
resolve: trpc_middleware_js_1.adminProcedure
|
|
44
84
|
.input(zod_1.z.object({ prefer: HwAccelPreferSchema }).optional())
|
|
45
85
|
.output(HwAccelResolutionSchema)
|
|
46
86
|
.query(async ({ input }) => {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
87
|
+
const provider = capabilityRegistry?.getSingleton('platform-probe') ?? null;
|
|
88
|
+
if (!provider) {
|
|
89
|
+
return { preferred: [], rationale: 'platform-probe capability not available' };
|
|
90
|
+
}
|
|
91
|
+
return provider.resolveHwAccel({ prefer: input?.prefer ?? null });
|
|
51
92
|
}),
|
|
52
93
|
/** Probe a specific node in the cluster — used by per-agent UI cards. */
|
|
53
94
|
resolveForNode: trpc_middleware_js_1.adminProcedure
|
|
54
95
|
.input(zod_1.z.object({ nodeId: zod_1.z.string(), prefer: HwAccelPreferSchema }))
|
|
55
96
|
.output(HwAccelResolutionSchema)
|
|
56
97
|
.query(async ({ input }) => {
|
|
57
|
-
|
|
58
|
-
throw new Error('Moleculer broker not available');
|
|
59
|
-
const params = { prefer: input.prefer ?? null };
|
|
60
|
-
return broker.call('$hwaccel.resolve', params, {
|
|
61
|
-
nodeID: input.nodeId,
|
|
62
|
-
});
|
|
98
|
+
return resolveHwAccelOnNode(moleculer, input.nodeId, input.prefer ?? null);
|
|
63
99
|
}),
|
|
64
100
|
/** List every node currently reachable and the hwaccel each resolves to. */
|
|
65
101
|
resolveAll: trpc_middleware_js_1.adminProcedure
|
|
@@ -68,24 +104,11 @@ function createHwAccelRouter(broker) {
|
|
|
68
104
|
resolution: HwAccelResolutionSchema,
|
|
69
105
|
})))
|
|
70
106
|
.query(async () => {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
try {
|
|
77
|
-
const resolution = (await broker.call('$hwaccel.resolve', { prefer: null }, { nodeID: n.id }));
|
|
78
|
-
return { nodeId: n.id, resolution };
|
|
79
|
-
}
|
|
80
|
-
catch (err) {
|
|
81
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
82
|
-
return {
|
|
83
|
-
nodeId: n.id,
|
|
84
|
-
resolution: { preferred: [], rationale: `resolve failed: ${msg}` },
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
}));
|
|
88
|
-
return results;
|
|
107
|
+
const nodeIds = listAvailableNodeIds(moleculer);
|
|
108
|
+
return Promise.all(nodeIds.map(async (nodeId) => ({
|
|
109
|
+
nodeId,
|
|
110
|
+
resolution: await resolveHwAccelOnNode(moleculer, nodeId, null),
|
|
111
|
+
})));
|
|
89
112
|
}),
|
|
90
113
|
});
|
|
91
114
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// AUTO-GENERATED by scripts/generate-cap-mounts.ts — DO NOT EDIT
|
|
3
3
|
// Re-run: npx tsx scripts/generate-cap-mounts.ts
|
|
4
4
|
//
|
|
5
|
-
// Mounted:
|
|
5
|
+
// Mounted: 131 Skipped (legacy): 6
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.LEGACY_SHAPE_SKIP = void 0;
|
|
8
8
|
exports.mountAllCaps = mountAllCaps;
|
|
@@ -294,6 +294,7 @@ function mountAllCaps(services) {
|
|
|
294
294
|
return entries[0]?.[1] ?? null;
|
|
295
295
|
}, remoteCapProxy),
|
|
296
296
|
osd: (0, generated_cap_routers_js_1.createCapRouter_osd)((_ctx) => (0, cap_mount_helpers_js_1.requireDeviceScoped)(reg, 'osd'), remoteCapProxy),
|
|
297
|
+
petFeeder: (0, generated_cap_routers_js_1.createCapRouter_petFeeder)((_ctx) => (0, cap_mount_helpers_js_1.requireDeviceScoped)(reg, 'pet-feeder'), remoteCapProxy),
|
|
297
298
|
pipelineAnalytics: (0, generated_cap_routers_js_1.createCapRouter_pipelineAnalytics)((_ctx) => reg?.getSingleton('pipeline-analytics') ?? null, remoteCapProxy),
|
|
298
299
|
pipelineExecutor: (0, generated_cap_routers_js_1.createCapRouter_pipelineExecutor)((_ctx) => reg?.getSingleton('pipeline-executor') ??
|
|
299
300
|
null, remoteCapProxy),
|