mcoda 0.1.78 → 0.1.80

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
@@ -35,6 +35,7 @@ mcoda docs pdr generate --workspace-root . --project WEB --rfp-path docs/rfp/web
35
35
  - Backlog: `mcoda backlog`, `mcoda task`
36
36
  - Jobs/telemetry: `mcoda jobs`, `mcoda tokens`, `mcoda telemetry`
37
37
  - Owner-local GPU jobs: `mcoda gpu list`, `mcoda gpu ops`, `mcoda job artifact upload|run|status|logs|events|artifacts|cancel|retry`
38
+ - Self-hosted agents: `mcoda self-hosted agent list`, `mcoda self-hosted agent details`, `mcoda self-hosted agent sync`
38
39
  - Agents: `mcoda test-agent`, `mcoda agent-run`
39
40
  - Updates: `mcoda update --check`
40
41
 
@@ -50,6 +51,18 @@ Environment variables are optional overrides for workspace settings:
50
51
  - `MCODA_TELEMETRY` set to `off` to disable telemetry.
51
52
  - `MCODA_STREAM_IO=1` to emit agent I/O lines to stderr.
52
53
 
54
+ ## Self-hosted mswarm agents
55
+
56
+ `mcoda self-hosted agent list` reads direct self-hosted agents and opt-in
57
+ load-balanced aliases from mswarm when the configured API key allows it. Direct
58
+ entries stay pinned to one server. Load-balanced aliases are saved as auto
59
+ routes and let mswarm choose an eligible upgraded node for the requested model
60
+ or capability.
61
+
62
+ Use direct slugs for rollback or pinned-server workloads. Use auto aliases only
63
+ when the product should allow mswarm to route around busy, drained, stale, or
64
+ incompatible nodes.
65
+
53
66
  ## Programmatic usage
54
67
  ```ts
55
68
  import { McodaEntrypoint } from "mcoda";
@@ -1 +1 @@
1
- {"version":3,"file":"SelfHostedCommands.d.ts","sourceRoot":"","sources":["../../../src/commands/self-hosted/SelfHostedCommands.ts"],"names":[],"mappings":"AA6NA,qBAAa,kBAAkB;WAChB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CA8FhD"}
1
+ {"version":3,"file":"SelfHostedCommands.d.ts","sourceRoot":"","sources":["../../../src/commands/self-hosted/SelfHostedCommands.ts"],"names":[],"mappings":"AAyOA,qBAAa,kBAAkB;WAChB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAkGhD"}
@@ -7,6 +7,7 @@ Subcommands:
7
7
  --provider <NAME> Filter by provider (mcoda|ollama)
8
8
  --limit <N> Limit returned agents
9
9
  --include-unreachable Include unreachable agents in the catalog result
10
+ --include-load-balanced Include auto-routed load-balanced self-hosted aliases
10
11
  --max-cost-per-1m-token <N>
11
12
  Exclude agents above the given cost_per_million
12
13
  --sorted-by-catalog-rating
@@ -14,9 +15,11 @@ Subcommands:
14
15
  --min-context <N> Require at least this context window
15
16
  --min-reasoning <N> Require at least this reasoning rating
16
17
  agent details <SLUG> Show a single mswarm self-hosted agent (supports --json)
18
+ --include-load-balanced Allow details for auto-routed aliases
17
19
  agent sync Sync self-hosted agents into the local mcoda registry
18
20
  --provider <NAME> Filter by provider before syncing
19
21
  --include-unreachable Sync unreachable agents too
22
+ --include-load-balanced Sync auto-routed load-balanced aliases too
20
23
  --limit <N> Limit synced agents
21
24
  --prune Remove previously synced self-hosted agents missing from the current catalog result
22
25
  --agent-slug-prefix <P> Override the local managed-agent slug prefix
@@ -104,6 +107,7 @@ const resolveNonNegativeNumber = (value, label) => {
104
107
  const formatNumber = (value) => value === undefined || Number.isNaN(value) ? "-" : String(value);
105
108
  const formatCapabilities = (capabilities) => capabilities && capabilities.length > 0 ? capabilities.join(",") : "-";
106
109
  const formatBoolean = (value) => value === undefined ? "-" : value ? "yes" : "no";
110
+ const agentRoutingMode = (agent) => agent.load_balanced ? "auto" : "direct";
107
111
  const pad = (value, width) => value.padEnd(width, " ");
108
112
  const renderTable = (headers, rows) => {
109
113
  const widths = headers.map((header, columnIndex) => Math.max(header.length, ...rows.map((row) => row[columnIndex]?.length ?? 0)));
@@ -122,6 +126,7 @@ const printAgentList = (agents) => {
122
126
  }
123
127
  const headers = [
124
128
  "REMOTE SLUG",
129
+ "ROUTE",
125
130
  "PROVIDER",
126
131
  "ADAPTER",
127
132
  "MODEL",
@@ -136,6 +141,7 @@ const printAgentList = (agents) => {
136
141
  ];
137
142
  const rows = agents.map((agent) => [
138
143
  agent.remote_slug ?? agent.slug,
144
+ agentRoutingMode(agent),
139
145
  agent.provider,
140
146
  agent.adapter ?? "-",
141
147
  agent.default_model,
@@ -155,6 +161,8 @@ const printAgentDetails = (agent) => {
155
161
  const entries = [
156
162
  ["Slug", agent.slug],
157
163
  ["Remote slug", agent.remote_slug ?? "-"],
164
+ ["Route", agentRoutingMode(agent)],
165
+ ["Load-balanced group", agent.load_balanced_group_id ?? "-"],
158
166
  ["Provider", agent.provider],
159
167
  ["Adapter", agent.adapter ?? "-"],
160
168
  ["Source agent", agent.source_agent_slug ?? "-"],
@@ -170,6 +178,7 @@ const printAgentDetails = (agent) => {
170
178
  ["Supports tools", formatBoolean(agent.supports_tools)],
171
179
  ["Supports reasoning", formatBoolean(agent.supports_reasoning)],
172
180
  ["Health", agent.health_status ?? "-"],
181
+ ["Members", formatNumber(agent.member_count)],
173
182
  ["Capabilities", formatCapabilities(agent.capabilities)],
174
183
  ];
175
184
  const labelWidth = Math.max(...entries.map(([label]) => label.length));
@@ -187,11 +196,12 @@ const printSyncSummary = (summary) => {
187
196
  record.remoteSlug,
188
197
  record.localSlug,
189
198
  record.action,
199
+ record.routingMode ?? "-",
190
200
  record.provider,
191
201
  record.defaultModel,
192
202
  ]);
193
203
  // eslint-disable-next-line no-console
194
- console.log(renderTable(["REMOTE SLUG", "LOCAL SLUG", "ACTION", "PROVIDER", "MODEL"], rows));
204
+ console.log(renderTable(["REMOTE SLUG", "LOCAL SLUG", "ACTION", "ROUTE", "PROVIDER", "MODEL"], rows));
195
205
  };
196
206
  export class SelfHostedCommands {
197
207
  static async run(argv) {
@@ -227,6 +237,7 @@ export class SelfHostedCommands {
227
237
  provider: resolveString(parsed.flags.provider),
228
238
  limit: resolvePositiveInt(parsed.flags.limit, "--limit"),
229
239
  includeUnreachable: Boolean(parsed.flags["include-unreachable"]),
240
+ includeLoadBalanced: Boolean(parsed.flags["include-load-balanced"]),
230
241
  maxCostPerMillion: resolveNonNegativeNumber(parsed.flags["max-cost-per-1m-token"], "--max-cost-per-1m-token"),
231
242
  minContextWindow: resolvePositiveInt(parsed.flags["min-context"], "--min-context"),
232
243
  minReasoningRating: resolveNonNegativeNumber(parsed.flags["min-reasoning"], "--min-reasoning"),
@@ -246,7 +257,9 @@ export class SelfHostedCommands {
246
257
  if (!slug) {
247
258
  throw new Error("Usage: mcoda self-hosted agent details <SLUG> [--json]");
248
259
  }
249
- const agent = await api.getSelfHostedAgent(slug);
260
+ const agent = await api.getSelfHostedAgent(slug, {
261
+ includeLoadBalanced: Boolean(parsed.flags["include-load-balanced"]),
262
+ });
250
263
  if (parsed.flags.json) {
251
264
  // eslint-disable-next-line no-console
252
265
  console.log(JSON.stringify(agent, null, 2));
@@ -261,6 +274,7 @@ export class SelfHostedCommands {
261
274
  provider: resolveString(parsed.flags.provider),
262
275
  limit: resolvePositiveInt(parsed.flags.limit, "--limit"),
263
276
  includeUnreachable: Boolean(parsed.flags["include-unreachable"]),
277
+ includeLoadBalanced: Boolean(parsed.flags["include-load-balanced"]),
264
278
  pruneMissing: Boolean(parsed.flags.prune),
265
279
  });
266
280
  if (parsed.flags.json) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcoda",
3
- "version": "0.1.78",
3
+ "version": "0.1.80",
4
4
  "description": "Local-first CLI for planning, documentation, and execution workflows with agent assistance.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -47,12 +47,12 @@
47
47
  },
48
48
  "dependencies": {
49
49
  "yaml": "^2.4.2",
50
- "@mcoda/core": "0.1.78",
51
- "@mcoda/shared": "0.1.78"
50
+ "@mcoda/shared": "0.1.80",
51
+ "@mcoda/core": "0.1.80"
52
52
  },
53
53
  "devDependencies": {
54
- "@mcoda/integrations": "0.1.78",
55
- "@mcoda/db": "0.1.78"
54
+ "@mcoda/db": "0.1.80",
55
+ "@mcoda/integrations": "0.1.80"
56
56
  },
57
57
  "scripts": {
58
58
  "build": "tsc -p tsconfig.json",