@mcoda/mswarm 0.1.76 → 0.1.79

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.md CHANGED
@@ -96,12 +96,69 @@ Keep discovery running but expose only allowlisted agents:
96
96
  mswarm node install <MSWARM_API_KEY> --no-expose-all
97
97
  ```
98
98
 
99
+ Set local scheduling capacity during install:
100
+
101
+ ```sh
102
+ mswarm node install <MSWARM_API_KEY> --max-concurrent-jobs 4 --max-concurrent-llm-jobs 2
103
+ ```
104
+
105
+ The node reports additive load telemetry in each heartbeat: runtime protocol
106
+ version, active and queued work, LLM/generic job concurrency, free slots, drain
107
+ state, recent failures, moving average latency, and a fingerprinted local agent
108
+ catalog revision. Existing gateways can ignore the new fields; the legacy
109
+ `capacity.active_jobs` and `capacity.queued_jobs` values are still present.
110
+
111
+ Use drain mode before maintenance so new scheduled work avoids the node while
112
+ existing in-flight jobs can finish:
113
+
114
+ ```sh
115
+ MSWARM_SELF_HOSTED_DRAIN_MODE=1 mswarm node run
116
+ ```
117
+
118
+ Detailed host metrics are off by default. If enabled by the node owner, the
119
+ heartbeat includes only coarse pressure telemetry such as CPU load ratio, RAM
120
+ bucket/usage ratio, GPU availability/count/CUDA support, and a coarse VRAM tier
121
+ with no exact memory values. It does not include process lists, usernames,
122
+ filesystem paths, environment variables, raw prompts, GPU names, driver
123
+ versions, serial numbers, or exact VRAM values.
124
+
99
125
  Use direct mode only when the node has a public HTTPS or tunnel URL:
100
126
 
101
127
  ```sh
102
128
  mswarm node install <MSWARM_API_KEY> --mode direct --direct-url https://node.example.com
103
129
  ```
104
130
 
131
+ ## Load-Balanced Routing
132
+
133
+ When an mswarm account has multiple upgraded self-hosted nodes, the hosted
134
+ control plane can expose synthetic `Auto load-balanced` catalog aliases for
135
+ matching local mcoda agents. Selecting an auto alias lets mswarm choose an
136
+ eligible node at request time based on tenant/API-key scope, model or capability
137
+ match, protocol compatibility, heartbeat freshness, drain state, active work,
138
+ and reservations.
139
+
140
+ This is additive to direct routing:
141
+
142
+ - Direct self-hosted slugs keep routing to their pinned node.
143
+ - Existing assignments are not migrated automatically.
144
+ - Older direct-only nodes still work as direct targets but are auto-ineligible
145
+ until they advertise load-balancer protocol, load telemetry, and catalog
146
+ fingerprint fields.
147
+ - Load-balanced aliases never require browser-visible node tokens, direct URLs,
148
+ invocation signing secrets, or API keys.
149
+
150
+ Use drain mode before maintenance so auto routing avoids the node while direct
151
+ operators can decide whether to keep or move pinned traffic:
152
+
153
+ ```sh
154
+ MSWARM_SELF_HOSTED_DRAIN_MODE=1 mswarm node run
155
+ ```
156
+
157
+ Rollback is done from the control plane or consuming product by switching the
158
+ assignment back to a direct slug or omitting load-balanced aliases during
159
+ catalog sync. Keep the node installed; direct routing does not depend on the
160
+ load-balancer protocol fields.
161
+
105
162
  ## Commands
106
163
 
107
164
  ```text
@@ -144,6 +201,42 @@ Jobs can additionally scope execution with:
144
201
  - `docdex.base_url`, `docdex.repo_root`, `docdex.repo_id`, and Docdex write/web/index flags
145
202
  - `policy.allow_tools`, `policy.allowed_tools`, `policy.denied_tools`, write/shell/destructive flags, `policy.max_runtime_ms`, and `policy.max_tool_calls`
146
203
 
204
+ ## Owner-Local Generic GPU Jobs
205
+
206
+ mswarm can also expose a separate owner-local generic job plane for trusted GPU
207
+ and package workloads such as Blender rendering, CUDA package jobs, ffmpeg CUDA
208
+ jobs, and Python GPU jobs. This path is separate from the OpenAI-compatible LLM
209
+ execution path and is disabled by default.
210
+
211
+ Enable it only on a trusted local node:
212
+
213
+ ```sh
214
+ MSWARM_SELF_HOSTED_GENERIC_JOBS_ENABLED=1 \
215
+ MSWARM_SELF_HOSTED_DIRECT_HOST=127.0.0.1 \
216
+ MSWARM_SELF_HOSTED_INVOCATION_SIGNING_SECRET=<local-secret> \
217
+ mswarm node run --enable-generic-jobs
218
+ ```
219
+
220
+ The generic job endpoints require scoped HMAC tokens or the owner-local signing
221
+ secret. They expose capability discovery, artifact upload, lifecycle status,
222
+ logs, events, cancellation, retry, and an ops summary for queue/usage/quota
223
+ inspection. Use `mcoda gpu list`, `mcoda gpu ops`, and the GPU-aware
224
+ `mcoda job artifact upload|run|status|logs|events|artifacts|cancel|retry`
225
+ commands to operate the local node.
226
+
227
+ Do not expose the node signing secret to browsers or untrusted tenants.
228
+ Production scheduling should issue short-lived scoped tokens from a control
229
+ plane; owner-local direct use is for a trusted operator on the node.
230
+
147
231
  ## Environment
148
232
 
149
233
  `MSWARM_API_KEY` can replace `--api-key` during legacy `setup`, but the preferred flow is `mswarm node install <MSWARM_API_KEY>` or `mswarm node install --api-key-stdin` so the key is never exported into the shell environment. `MSWARM_GATEWAY_BASE_URL` overrides the gateway. The default discovery mode is `mcoda`, so the node reads `mcoda agent list --json --refresh-health`; set `MSWARM_SELF_HOSTED_DISCOVERY_MODE=ollama` only for raw Ollama fallback discovery. `MSWARM_SELF_HOSTED_EXPOSURE_POLICY=none` disables default exposure while keeping allowlists/blocklists available. `MSWARM_SELF_HOSTED_REQUEST_TIMEOUT_MS` controls short gateway and inventory requests; self-hosted execution jobs default to one hour and can be overridden with `MSWARM_SELF_HOSTED_JOB_TIMEOUT_MS` or `--job-timeout-ms` during install.
234
+
235
+ Load-balancer telemetry controls:
236
+
237
+ - `MSWARM_SELF_HOSTED_MAX_CONCURRENT_JOBS`: overall advertised job capacity, default `1`
238
+ - `MSWARM_SELF_HOSTED_MAX_CONCURRENT_LLM_JOBS`: LLM/Codali capacity, default matches overall capacity
239
+ - `MSWARM_SELF_HOSTED_GENERIC_JOB_MAX_CONCURRENCY`: generic job capacity, default `1`
240
+ - `MSWARM_SELF_HOSTED_DRAIN_MODE=1`: report zero free slots for maintenance
241
+ - `MSWARM_SELF_HOSTED_LOAD_REPORTING_ENABLED=0`: fall back to legacy heartbeat capacity shape
242
+ - `MSWARM_SELF_HOSTED_HARDWARE_TELEMETRY_ENABLED=1`: opt in to coarse pressure telemetry
@@ -8,9 +8,57 @@ export interface SelfHostedInvocationTokenClaims {
8
8
  iat: number;
9
9
  exp: number;
10
10
  }
11
+ export interface SelfHostedGenericJobTokenClaims {
12
+ node_id: string;
13
+ job_id: string;
14
+ request_id: string;
15
+ schema_version: string;
16
+ job_type: string;
17
+ deadline_at: string;
18
+ scope: "self_hosted.generic_job.invoke";
19
+ allowed_runner_ids?: string[];
20
+ capability_names?: string[];
21
+ policy_id?: string;
22
+ policy_version?: string;
23
+ capability_lease_id?: string;
24
+ capability_snapshot_id?: string;
25
+ iat: number;
26
+ exp: number;
27
+ }
28
+ export interface SelfHostedCapabilityTokenClaims {
29
+ node_id: string;
30
+ deadline_at: string;
31
+ scope: "self_hosted.capabilities.read";
32
+ iat: number;
33
+ exp: number;
34
+ nonce?: string;
35
+ }
36
+ export interface SelfHostedGenericJobOpsTokenClaims {
37
+ node_id: string;
38
+ deadline_at: string;
39
+ scope: "self_hosted.generic_job.ops.read";
40
+ iat: number;
41
+ exp: number;
42
+ nonce?: string;
43
+ }
11
44
  export declare function verifySelfHostedInvocationToken(input: {
12
45
  token: string;
13
46
  secret: string;
14
47
  nowSeconds?: number;
15
48
  }): SelfHostedInvocationTokenClaims;
49
+ export declare function verifySelfHostedGenericJobToken(input: {
50
+ token: string;
51
+ secret: string;
52
+ nowSeconds?: number;
53
+ }): SelfHostedGenericJobTokenClaims;
54
+ export declare function verifySelfHostedCapabilityToken(input: {
55
+ token: string;
56
+ secret: string;
57
+ nowSeconds?: number;
58
+ }): SelfHostedCapabilityTokenClaims;
59
+ export declare function verifySelfHostedGenericJobOpsToken(input: {
60
+ token: string;
61
+ secret: string;
62
+ nowSeconds?: number;
63
+ }): SelfHostedGenericJobOpsTokenClaims;
16
64
  //# sourceMappingURL=invocation-token.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"invocation-token.d.ts","sourceRoot":"","sources":["../src/invocation-token.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,+BAA+B;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,oBAAoB,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAuBD,wBAAgB,+BAA+B,CAAC,KAAK,EAAE;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,+BAA+B,CAqClC"}
1
+ {"version":3,"file":"invocation-token.d.ts","sourceRoot":"","sources":["../src/invocation-token.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,+BAA+B;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,oBAAoB,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,+BAA+B;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,gCAAgC,CAAC;IACxC,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,+BAA+B;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,+BAA+B,CAAC;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kCAAkC;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,kCAAkC,CAAC;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAuBD,wBAAgB,+BAA+B,CAAC,KAAK,EAAE;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,+BAA+B,CAqClC;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,+BAA+B,CAsClC;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,+BAA+B,CAkClC;AAED,wBAAgB,kCAAkC,CAAC,KAAK,EAAE;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,kCAAkC,CAkCrC"}
@@ -54,4 +54,113 @@ export function verifySelfHostedInvocationToken(input) {
54
54
  requireText(payload.model, "model");
55
55
  return payload;
56
56
  }
57
+ export function verifySelfHostedGenericJobToken(input) {
58
+ const secret = requireText(input.secret, "self_hosted_invocation_secret");
59
+ const token = requireText(input.token, "token");
60
+ const parts = token.split(".");
61
+ if (parts.length !== 3) {
62
+ throw new Error("self_hosted_generic_job_token_invalid");
63
+ }
64
+ const signingInput = `${parts[0]}.${parts[1]}`;
65
+ const expected = signHmacSha256(signingInput, secret);
66
+ const expectedBuffer = Buffer.from(expected);
67
+ const actualBuffer = Buffer.from(parts[2] || "");
68
+ if (expectedBuffer.length !== actualBuffer.length || !crypto.timingSafeEqual(expectedBuffer, actualBuffer)) {
69
+ throw new Error("self_hosted_generic_job_token_invalid");
70
+ }
71
+ let payload;
72
+ try {
73
+ payload = JSON.parse(base64UrlDecode(parts[1]).toString("utf8"));
74
+ }
75
+ catch {
76
+ throw new Error("self_hosted_generic_job_token_invalid");
77
+ }
78
+ const nowSeconds = Math.floor(input.nowSeconds ?? Date.now() / 1000);
79
+ if (payload.scope !== "self_hosted.generic_job.invoke") {
80
+ throw new Error("self_hosted_generic_job_token_scope_denied");
81
+ }
82
+ if (!payload.exp || payload.exp < nowSeconds) {
83
+ throw new Error("self_hosted_generic_job_token_expired");
84
+ }
85
+ const deadlineMs = Date.parse(payload.deadline_at);
86
+ if (!Number.isFinite(deadlineMs) || deadlineMs < nowSeconds * 1000) {
87
+ throw new Error("self_hosted_generic_job_token_expired");
88
+ }
89
+ requireText(payload.node_id, "node_id");
90
+ requireText(payload.job_id, "job_id");
91
+ requireText(payload.request_id, "request_id");
92
+ requireText(payload.schema_version, "schema_version");
93
+ requireText(payload.job_type, "job_type");
94
+ return payload;
95
+ }
96
+ export function verifySelfHostedCapabilityToken(input) {
97
+ const secret = requireText(input.secret, "self_hosted_invocation_secret");
98
+ const token = requireText(input.token, "token");
99
+ const parts = token.split(".");
100
+ if (parts.length !== 3) {
101
+ throw new Error("self_hosted_capability_token_invalid");
102
+ }
103
+ const signingInput = `${parts[0]}.${parts[1]}`;
104
+ const expected = signHmacSha256(signingInput, secret);
105
+ const expectedBuffer = Buffer.from(expected);
106
+ const actualBuffer = Buffer.from(parts[2] || "");
107
+ if (expectedBuffer.length !== actualBuffer.length || !crypto.timingSafeEqual(expectedBuffer, actualBuffer)) {
108
+ throw new Error("self_hosted_capability_token_invalid");
109
+ }
110
+ let payload;
111
+ try {
112
+ payload = JSON.parse(base64UrlDecode(parts[1]).toString("utf8"));
113
+ }
114
+ catch {
115
+ throw new Error("self_hosted_capability_token_invalid");
116
+ }
117
+ const nowSeconds = Math.floor(input.nowSeconds ?? Date.now() / 1000);
118
+ if (payload.scope !== "self_hosted.capabilities.read") {
119
+ throw new Error("self_hosted_capability_token_scope_denied");
120
+ }
121
+ if (!payload.exp || payload.exp < nowSeconds) {
122
+ throw new Error("self_hosted_capability_token_expired");
123
+ }
124
+ const deadlineMs = Date.parse(payload.deadline_at);
125
+ if (!Number.isFinite(deadlineMs) || deadlineMs < nowSeconds * 1000) {
126
+ throw new Error("self_hosted_capability_token_expired");
127
+ }
128
+ requireText(payload.node_id, "node_id");
129
+ return payload;
130
+ }
131
+ export function verifySelfHostedGenericJobOpsToken(input) {
132
+ const secret = requireText(input.secret, "self_hosted_invocation_secret");
133
+ const token = requireText(input.token, "token");
134
+ const parts = token.split(".");
135
+ if (parts.length !== 3) {
136
+ throw new Error("self_hosted_generic_job_ops_token_invalid");
137
+ }
138
+ const signingInput = `${parts[0]}.${parts[1]}`;
139
+ const expected = signHmacSha256(signingInput, secret);
140
+ const expectedBuffer = Buffer.from(expected);
141
+ const actualBuffer = Buffer.from(parts[2] || "");
142
+ if (expectedBuffer.length !== actualBuffer.length || !crypto.timingSafeEqual(expectedBuffer, actualBuffer)) {
143
+ throw new Error("self_hosted_generic_job_ops_token_invalid");
144
+ }
145
+ let payload;
146
+ try {
147
+ payload = JSON.parse(base64UrlDecode(parts[1]).toString("utf8"));
148
+ }
149
+ catch {
150
+ throw new Error("self_hosted_generic_job_ops_token_invalid");
151
+ }
152
+ const nowSeconds = Math.floor(input.nowSeconds ?? Date.now() / 1000);
153
+ if (payload.scope !== "self_hosted.generic_job.ops.read") {
154
+ throw new Error("self_hosted_generic_job_ops_token_scope_denied");
155
+ }
156
+ if (!payload.exp || payload.exp < nowSeconds) {
157
+ throw new Error("self_hosted_generic_job_ops_token_expired");
158
+ }
159
+ const deadlineMs = Date.parse(payload.deadline_at);
160
+ if (!Number.isFinite(deadlineMs) || deadlineMs < nowSeconds * 1000) {
161
+ throw new Error("self_hosted_generic_job_ops_token_expired");
162
+ }
163
+ requireText(payload.node_id, "node_id");
164
+ return payload;
165
+ }
57
166
  //# sourceMappingURL=invocation-token.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"invocation-token.js","sourceRoot":"","sources":["../src/invocation-token.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"invocation-token.js","sourceRoot":"","sources":["../src/invocation-token.ts"],"names":[],"mappings":"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"}
package/dist/runtime.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { MswarmCodaliExecutor } from "./codali-executor.js";
2
+ import { type MswarmArtifactStoreDescriptor, type MswarmGenericJobValidationIssue, type MswarmJobEvent, type MswarmJobRequest, type MswarmJobResult, type MswarmNodeCapabilitySnapshot, type MswarmOutputSpec, type MswarmPublicCapabilityProjection, type MswarmRegisteredArtifact, type MswarmSandboxProfile, type MswarmSignedCapabilityPayload } from "@mcoda/shared";
2
3
  export type FetchLike = typeof fetch;
3
4
  export type SelfHostedDiscoveryMode = "mcoda" | "ollama";
4
5
  export type SelfHostedRelayMode = "outbound" | "direct";
@@ -7,6 +8,7 @@ export type CommandRunner = (command: string, args: string[], options: {
7
8
  timeoutMs: number;
8
9
  maxBuffer: number;
9
10
  input?: string;
11
+ signal?: AbortSignal;
10
12
  }) => Promise<{
11
13
  stdout: string;
12
14
  stderr: string;
@@ -65,6 +67,7 @@ export interface SelfHostedNodeConfig {
65
67
  ollamaBaseUrl: string;
66
68
  statePath: string;
67
69
  runtimeTokenPath: string;
70
+ artifactStorePath?: string;
68
71
  invocationSigningSecret?: string | null;
69
72
  listenHost: string;
70
73
  listenPort: number;
@@ -72,6 +75,15 @@ export interface SelfHostedNodeConfig {
72
75
  heartbeatIntervalSeconds: number;
73
76
  requestTimeoutMs: number;
74
77
  jobTimeoutMs: number;
78
+ maxConcurrentJobs?: number;
79
+ maxConcurrentLlmJobs?: number;
80
+ genericJobsEnabled: boolean;
81
+ genericJobTimeoutMs: number;
82
+ genericJobMaxConcurrency: number;
83
+ capabilityProbeTimeoutMs?: number;
84
+ drainMode?: boolean;
85
+ loadReportingEnabled?: boolean;
86
+ hardwareTelemetryEnabled?: boolean;
75
87
  exposeAllModels: boolean;
76
88
  modelAllowlist: string[];
77
89
  modelBlocklist: string[];
@@ -83,6 +95,7 @@ export interface SelfHostedNodeState {
83
95
  machine_fingerprint?: string;
84
96
  direct_base_url?: string | null;
85
97
  runtime_token?: string;
98
+ artifact_store_path?: string;
86
99
  config_version?: number;
87
100
  heartbeat_interval_seconds?: number;
88
101
  heartbeat_timeout_seconds?: number;
@@ -96,6 +109,15 @@ export interface SelfHostedNodeState {
96
109
  node_version?: string;
97
110
  request_timeout_ms?: number;
98
111
  job_timeout_ms?: number;
112
+ max_concurrent_jobs?: number;
113
+ max_concurrent_llm_jobs?: number;
114
+ generic_jobs_enabled?: boolean;
115
+ generic_job_timeout_ms?: number;
116
+ generic_job_max_concurrency?: number;
117
+ capability_probe_timeout_ms?: number;
118
+ drain_mode?: boolean;
119
+ load_reporting_enabled?: boolean;
120
+ hardware_telemetry_enabled?: boolean;
99
121
  expose_all_models?: boolean;
100
122
  exposure_policy?: SelfHostedExposurePolicy;
101
123
  model_allowlist?: string[];
@@ -110,6 +132,7 @@ export interface SelfHostedOwnerSetupConfig {
110
132
  discoveryMode: SelfHostedDiscoveryMode;
111
133
  statePath: string;
112
134
  runtimeTokenPath: string;
135
+ artifactStorePath?: string;
113
136
  machineIdPath: string;
114
137
  mcodaBin: string;
115
138
  mcodaListArgs: string[];
@@ -118,6 +141,15 @@ export interface SelfHostedOwnerSetupConfig {
118
141
  heartbeatIntervalSeconds: number;
119
142
  requestTimeoutMs: number;
120
143
  jobTimeoutMs: number;
144
+ maxConcurrentJobs: number;
145
+ maxConcurrentLlmJobs: number;
146
+ genericJobsEnabled: boolean;
147
+ genericJobTimeoutMs: number;
148
+ genericJobMaxConcurrency: number;
149
+ capabilityProbeTimeoutMs?: number;
150
+ drainMode: boolean;
151
+ loadReportingEnabled: boolean;
152
+ hardwareTelemetryEnabled: boolean;
121
153
  exposeAllModels: boolean;
122
154
  modelAllowlist: string[];
123
155
  modelBlocklist: string[];
@@ -216,10 +248,17 @@ export interface SelfHostedNodeInvocationJob {
216
248
  max_tool_calls?: number;
217
249
  };
218
250
  }
251
+ export interface SelfHostedGenericNodeJob {
252
+ job_id: string;
253
+ request_id: string;
254
+ node_id: string;
255
+ job: MswarmJobRequest;
256
+ }
219
257
  export interface SelfHostedNodeInvocationResult {
220
258
  job_id: string;
221
259
  request_id: string;
222
260
  status: "success" | "failed";
261
+ pre_start_failure?: boolean;
223
262
  openai_response?: Record<string, unknown>;
224
263
  stream_events?: Record<string, unknown>[];
225
264
  progress_events?: Record<string, unknown>[];
@@ -234,6 +273,14 @@ export interface SelfHostedNodeInvocationResult {
234
273
  export interface SelfHostedJobExecutionOptions {
235
274
  onOpenAIChunk?: (chunk: Record<string, unknown>) => void | Promise<void>;
236
275
  onProgress?: (event: Record<string, unknown>) => void | Promise<void>;
276
+ onStarted?: (event: {
277
+ job_id: string;
278
+ request_id: string;
279
+ node_id: string;
280
+ agent_slug: string;
281
+ source_agent_slug?: string | null;
282
+ model?: string | null;
283
+ }) => void | Promise<void>;
237
284
  /**
238
285
  * Per-invocation owner key attached by the mswarm execution envelope for
239
286
  * encrypted Docdex access. This must never be read from local model/provider
@@ -241,6 +288,74 @@ export interface SelfHostedJobExecutionOptions {
241
288
  */
242
289
  attachedMswarmApiKey?: string;
243
290
  }
291
+ export interface MswarmGenericJobRunnerContext {
292
+ job: MswarmJobRequest;
293
+ signal: AbortSignal;
294
+ emitEvent: (event: Omit<MswarmJobEvent, "job_id" | "sequence" | "timestamp">) => Promise<void>;
295
+ artifacts: MswarmGenericJobArtifactContext;
296
+ sandbox: MswarmSandboxProfile;
297
+ }
298
+ export interface MswarmGenericJobRunner {
299
+ readonly id: string;
300
+ run(context: MswarmGenericJobRunnerContext): Promise<MswarmJobResult>;
301
+ }
302
+ export interface MswarmGenericJobArtifactContext {
303
+ store: MswarmArtifactStoreDescriptor;
304
+ workDir: string;
305
+ inputDir: string;
306
+ outputDir: string;
307
+ registeredInputs: MswarmRegisteredArtifact[];
308
+ outputSpecs: MswarmOutputSpec[];
309
+ sandbox: MswarmSandboxProfile;
310
+ }
311
+ export interface MswarmGenericJobArtifactStore {
312
+ prepareJobWorkspace(jobId: string, job: MswarmJobRequest): Promise<MswarmGenericJobArtifactContext>;
313
+ collectOutputs(context: MswarmGenericJobArtifactContext, jobId: string): Promise<MswarmRegisteredArtifact[]>;
314
+ }
315
+ export interface MswarmGenericJobExecutionOptions {
316
+ signal?: AbortSignal;
317
+ onEvent?: (event: MswarmJobEvent) => void | Promise<void>;
318
+ }
319
+ export interface MswarmGenericJobExecutionResult {
320
+ job_id: string;
321
+ request_id: string;
322
+ status: MswarmJobResult["status"];
323
+ result: MswarmJobResult;
324
+ events: MswarmJobEvent[];
325
+ validation_issues?: MswarmGenericJobValidationIssue[];
326
+ timing: {
327
+ local_latency_ms: number;
328
+ };
329
+ }
330
+ export type SelfHostedRuntimeExecutionClass = "chat" | "agentic" | "generic_job";
331
+ export interface SelfHostedRuntimeExecutionClassCapacity {
332
+ max_concurrency: number;
333
+ active_jobs: number;
334
+ queued_jobs: number;
335
+ free_slots: number;
336
+ }
337
+ export interface SelfHostedRuntimeLoadTelemetry {
338
+ runtime_protocol_version: number;
339
+ load_balancer_protocol_version: number;
340
+ catalog_metadata_version: number;
341
+ catalog_fingerprint: string;
342
+ max_concurrency: number;
343
+ max_concurrent_llm_jobs: number;
344
+ max_concurrent_generic_jobs: number;
345
+ active_jobs: number;
346
+ queued_jobs: number;
347
+ free_slots: number;
348
+ drain_mode: boolean;
349
+ execution_class_capacity: Record<SelfHostedRuntimeExecutionClass, SelfHostedRuntimeExecutionClassCapacity>;
350
+ avg_latency_ms: number | null;
351
+ recent_failure_count: number;
352
+ recent_failures: Array<{
353
+ execution_class: SelfHostedRuntimeExecutionClass;
354
+ code: string;
355
+ at: string;
356
+ }>;
357
+ hardware_pressure?: Record<string, unknown>;
358
+ }
244
359
  export interface SelfHostedNodeHeartbeatResult {
245
360
  enrolled: boolean;
246
361
  status: "online" | "degraded";
@@ -248,6 +363,7 @@ export interface SelfHostedNodeHeartbeatResult {
248
363
  discovery_source: "mcoda" | "ollama";
249
364
  mcoda_agent_count?: number;
250
365
  ollama_version?: string | null;
366
+ capacity?: SelfHostedRuntimeLoadTelemetry;
251
367
  heartbeat_response: unknown;
252
368
  }
253
369
  export interface SelfHostedNodeDaemonHandle {
@@ -412,6 +528,40 @@ export declare class OllamaClient {
412
528
  raw: unknown;
413
529
  }>;
414
530
  }
531
+ export declare class MswarmLocalArtifactStore implements MswarmGenericJobArtifactStore {
532
+ private readonly rootDir;
533
+ private readonly now;
534
+ constructor(input?: {
535
+ rootDir?: string;
536
+ now?: () => Date;
537
+ });
538
+ prepareJobWorkspace(jobId: string, job: MswarmJobRequest): Promise<MswarmGenericJobArtifactContext>;
539
+ collectOutputs(context: MswarmGenericJobArtifactContext, jobId: string): Promise<MswarmRegisteredArtifact[]>;
540
+ private registerInput;
541
+ private collectDeclaredOutput;
542
+ private collectOutputDirectory;
543
+ private collectOutputFile;
544
+ }
545
+ export declare class MswarmTestEchoRunner implements MswarmGenericJobRunner {
546
+ readonly id = "test.echo";
547
+ run(context: MswarmGenericJobRunnerContext): Promise<MswarmJobResult>;
548
+ }
549
+ export declare class MswarmBlenderRenderRunner implements MswarmGenericJobRunner {
550
+ readonly id = "blender.render";
551
+ private readonly runner;
552
+ constructor(runner?: CommandRunner);
553
+ run(context: MswarmGenericJobRunnerContext): Promise<MswarmJobResult>;
554
+ }
555
+ export declare class MswarmCudaPackageRunner implements MswarmGenericJobRunner {
556
+ readonly id = "cuda.package";
557
+ private readonly runner;
558
+ constructor(runner?: CommandRunner);
559
+ run(context: MswarmGenericJobRunnerContext): Promise<MswarmJobResult>;
560
+ }
561
+ export declare function genericJobCapabilityMismatch(job: MswarmJobRequest, snapshot: MswarmNodeCapabilitySnapshot): {
562
+ code: string;
563
+ message: string;
564
+ } | null;
415
565
  export declare class McodaLocalAgentExecutor {
416
566
  private readonly command;
417
567
  private readonly timeoutMs;
@@ -457,6 +607,12 @@ export declare class MswarmSelfHostedNodeClient {
457
607
  postJobResult(runtimeToken: string, jobId: string, payload: SelfHostedNodeInvocationResult & {
458
608
  node_id: string;
459
609
  }): Promise<unknown>;
610
+ postJobStart(runtimeToken: string, jobId: string, payload: {
611
+ node_id: string;
612
+ agent_slug?: string | null;
613
+ source_agent_slug?: string | null;
614
+ model?: string | null;
615
+ }): Promise<unknown>;
460
616
  postJobEvents(runtimeToken: string, jobId: string, payload: {
461
617
  node_id: string;
462
618
  stream_events?: Record<string, unknown>[];
@@ -471,6 +627,15 @@ export declare class SelfHostedNodeRuntime {
471
627
  private readonly codaliExecutor;
472
628
  private readonly ollama;
473
629
  private readonly jobOllama;
630
+ private readonly genericRunners;
631
+ private readonly artifactStore;
632
+ private readonly capabilityRunner;
633
+ private activeLlmJobs;
634
+ private activeGenericJobs;
635
+ private queuedLlmJobs;
636
+ private queuedGenericJobs;
637
+ private readonly latencySamplesMs;
638
+ private readonly recentFailures;
474
639
  constructor(config: SelfHostedNodeConfig, deps?: {
475
640
  gateway?: MswarmSelfHostedNodeClient;
476
641
  mcoda?: McodaAgentInventoryClient;
@@ -478,7 +643,18 @@ export declare class SelfHostedNodeRuntime {
478
643
  codaliExecutor?: MswarmCodaliExecutor;
479
644
  ollama?: OllamaClient;
480
645
  fetchImpl?: FetchLike;
646
+ genericRunners?: MswarmGenericJobRunner[];
647
+ artifactStore?: MswarmGenericJobArtifactStore;
648
+ capabilityRunner?: CommandRunner;
481
649
  });
650
+ updateLocalQueueTelemetry(input: {
651
+ llmQueuedJobs?: number;
652
+ genericQueuedJobs?: number;
653
+ }): void;
654
+ private beginExecutionTelemetry;
655
+ private finishExecutionTelemetry;
656
+ private averageLatencyMs;
657
+ private buildLoadTelemetry;
482
658
  static setup(setupConfig: SelfHostedOwnerSetupConfig, deps?: {
483
659
  gateway?: MswarmSelfHostedNodeClient;
484
660
  mcoda?: McodaAgentInventoryClient;
@@ -486,14 +662,21 @@ export declare class SelfHostedNodeRuntime {
486
662
  codaliExecutor?: MswarmCodaliExecutor;
487
663
  ollama?: OllamaClient;
488
664
  fetchImpl?: FetchLike;
665
+ genericRunners?: MswarmGenericJobRunner[];
666
+ artifactStore?: MswarmGenericJobArtifactStore;
667
+ capabilityRunner?: CommandRunner;
489
668
  }): Promise<SelfHostedNodeSetupResult>;
490
669
  private discoverModels;
670
+ probeCapabilities(): Promise<MswarmNodeCapabilitySnapshot>;
671
+ publicCapabilityProjection(): Promise<MswarmPublicCapabilityProjection>;
672
+ buildCapabilityHeartbeatPayload(runtimeToken: string): Promise<MswarmSignedCapabilityPayload>;
491
673
  ensureEnrolled(): Promise<{
492
674
  runtimeToken: string;
493
675
  state: SelfHostedNodeState;
494
676
  enrolled: boolean;
495
677
  }>;
496
678
  private resolveMcodaAgentForJob;
679
+ executeGenericJob(envelope: SelfHostedGenericNodeJob, options?: MswarmGenericJobExecutionOptions): Promise<MswarmGenericJobExecutionResult>;
497
680
  executeJob(job: SelfHostedNodeInvocationJob, options?: SelfHostedJobExecutionOptions): Promise<SelfHostedNodeInvocationResult>;
498
681
  runOnce(): Promise<SelfHostedNodeHeartbeatResult>;
499
682
  notifyUninstall(input?: {