@aiwg/cli 2026.10.0 → 2026.10.3
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/agentic/code/providers/capability-matrix.yaml +270 -0
- package/agentic/code/providers/model-capabilities.v1.json +3091 -24
- package/bin/aiwg.mjs +86 -21
- package/dist/src/a2a/codecs.js +9 -0
- package/dist/src/artifacts/corpus-tools/vision-extract.js +105 -15
- package/dist/src/artifacts/repair.js +9 -4
- package/dist/src/channel/manager.mjs +59 -10
- package/dist/src/cli/child-process-result.js +40 -0
- package/dist/src/cli/env.js +38 -16
- package/dist/src/cli/flag-parsing.js +236 -0
- package/dist/src/cli/handlers/decision.js +297 -2
- package/dist/src/cli/handlers/diagnose.js +9 -2
- package/dist/src/cli/handlers/feedback.js +14 -5
- package/dist/src/cli/handlers/init.js +245 -30
- package/dist/src/cli/handlers/mc.js +23 -0
- package/dist/src/cli/handlers/models.js +69 -6
- package/dist/src/cli/handlers/ralph.js +3 -0
- package/dist/src/cli/handlers/refresh.js +16 -0
- package/dist/src/cli/handlers/regenerate.js +14 -0
- package/dist/src/cli/handlers/runtime-info.js +24 -9
- package/dist/src/cli/handlers/script-runner.js +16 -6
- package/dist/src/cli/handlers/session.js +396 -62
- package/dist/src/cli/handlers/sessions.js +146 -40
- package/dist/src/cli/handlers/setup-manifest.js +439 -39
- package/dist/src/cli/handlers/setup.js +139 -39
- package/dist/src/cli/handlers/subcommands.js +3 -1
- package/dist/src/cli/handlers/team.js +18 -8
- package/dist/src/cli/handlers/use.js +13 -0
- package/dist/src/cli/handlers/utilities.js +106 -23
- package/dist/src/cli/prompt-utils.js +72 -0
- package/dist/src/cli/provider-resolution.js +11 -0
- package/dist/src/config/aiwg-config.js +268 -4
- package/dist/src/config/cli.js +146 -19
- package/dist/src/config/dispatch-thresholds-runtime.mjs +38 -0
- package/dist/src/config/project-artifacts-health.mjs +14 -3
- package/dist/src/config/user-config.js +36 -10
- package/dist/src/decision/adapters/jev.js +80 -28
- package/dist/src/decision/ask.js +352 -0
- package/dist/src/decision/driver.js +4 -0
- package/dist/src/decision/entry.js +38 -6
- package/dist/src/decision/heldout/collector.js +10 -1
- package/dist/src/decision/index.js +3 -0
- package/dist/src/decision/interop.js +60 -8
- package/dist/src/decision/jev-credentials.js +121 -0
- package/dist/src/decision/ledger.js +839 -0
- package/dist/src/decision/validate.js +6 -3
- package/dist/src/effects/dispatch-verifier.js +252 -0
- package/dist/src/effects/index.js +1 -0
- package/dist/src/features/installer.js +2 -2
- package/dist/src/flow/graph-metadata.js +5 -0
- package/dist/src/gates/providers/loader.js +3 -1
- package/dist/src/installation/manager-command.mjs +1 -1
- package/dist/src/installation/manager.mjs +17 -2
- package/dist/src/lint/runner.js +2 -2
- package/dist/src/mcp/adapters/codex-runtime.js +360 -56
- package/dist/src/mcp/cli.mjs +587 -77
- package/dist/src/mcp/config-file.mjs +279 -0
- package/dist/src/mcp/config-layers.mjs +348 -0
- package/dist/src/mcp/credentials.mjs +484 -0
- package/dist/src/mcp/grok-build-config.mjs +16 -26
- package/dist/src/mcp/helpers.mjs +106 -2
- package/dist/src/mcp/omp-config.mjs +50 -29
- package/dist/src/mcp/profiles.js +97 -23
- package/dist/src/mcp/profiles.mjs +99 -27
- package/dist/src/mcp/registry.js +264 -57
- package/dist/src/mcp/registry.mjs +198 -45
- package/dist/src/mcp/server.mjs +403 -20
- package/dist/src/mcp/toml-string.mjs +9 -0
- package/dist/src/mcp/toml-strip-mcp.mjs +135 -0
- package/dist/src/mcp/tool-filters.mjs +357 -0
- package/dist/src/mcp/tools/agentic-sandbox.mjs +3 -1
- package/dist/src/mcp/tools/decision.mjs +58 -0
- package/dist/src/mcp/tools/orchestration.mjs +38 -0
- package/dist/src/mcp/tools/subsystems.mjs +39 -8
- package/dist/src/mcp/tools/worker-invoke.mjs +1539 -0
- package/dist/src/mcp/tools/worker-shell-control.mjs +258 -0
- package/dist/src/mcp/tools/worker-stdin-runtime.mjs +79 -0
- package/dist/src/memory/project-registry.js +2 -2
- package/dist/src/mission-protocol/codecs.js +639 -1
- package/dist/src/mission-protocol/types.js +110 -0
- package/dist/src/mission-protocol/worker-status.js +2 -0
- package/dist/src/models/config-loader.js +70 -13
- package/dist/src/models/grok-build-models.js +93 -41
- package/dist/src/models/model-capabilities.v1.json +3091 -24
- package/dist/src/models/model-discovery.js +862 -63
- package/dist/src/models/provider-policy.js +625 -11
- package/dist/src/models/qualification-digest.mjs +17 -0
- package/dist/src/models/resolver.js +259 -0
- package/dist/src/models/worker-direct-readiness.js +529 -0
- package/dist/src/models/worker-dispatch-offer.js +169 -0
- package/dist/src/models/worker-health-readiness.js +131 -0
- package/dist/src/models/worker-installation.mjs +879 -0
- package/dist/src/models/wrapper-route.js +18 -0
- package/dist/src/ops/registry.js +9 -14
- package/dist/src/plugins/standalone-packager.js +4 -3
- package/dist/src/process/bounded-child-process.mjs +387 -0
- package/dist/src/process/cli-command.mjs +75 -0
- package/dist/src/providers/capability-matrix.js +8 -0
- package/dist/src/providers/capability-matrix.yaml +270 -0
- package/dist/src/providers/grok-build-headless.js +43 -21
- package/dist/src/providers/provider-definitions.js +9 -1
- package/dist/src/providers/provider-definitions.mjs +9 -2
- package/dist/src/serve/executor-registry.js +16 -24
- package/dist/src/serve/fleet-mission-conductor.js +9 -0
- package/dist/src/serve/mission-conductor.js +9 -0
- package/dist/src/serve/shared-host-scheduler.js +2 -0
- package/dist/src/serve/worker-invocation.js +538 -0
- package/dist/src/serve/worker-stdin-frame.mjs +107 -0
- package/dist/src/sessions/adapter-registry.js +45 -0
- package/dist/src/sessions/adapters/generic.js +37 -3
- package/dist/src/sessions/adapters/grokbot-locator.js +111 -0
- package/dist/src/sessions/adapters/grokbot.js +423 -24
- package/dist/src/sessions/adapters/muse-workspace-scan.js +108 -0
- package/dist/src/sessions/adapters/muse.js +68 -29
- package/dist/src/sessions/adapters/pi.js +1 -0
- package/dist/src/sessions/batch-contracts.js +13 -1
- package/dist/src/sessions/batch-import.js +23 -42
- package/dist/src/sessions/candidates.js +47 -11
- package/dist/src/sessions/contracts.js +35 -0
- package/dist/src/sessions/coverage-preflight.js +134 -0
- package/dist/src/sessions/discovery.js +3 -0
- package/dist/src/sessions/grok-build-cli.js +67 -5
- package/dist/src/sessions/importer.js +24 -8
- package/dist/src/sessions/index.js +2 -0
- package/dist/src/sessions/repository.js +54 -13
- package/dist/src/sessions/workspace-discovery.js +99 -37
- package/dist/src/skills/adapters/clawhub.js +10 -8
- package/dist/src/skills/adapters/openclaw.js +10 -7
- package/dist/src/smiths/context-pipeline/parallelism-section.js +192 -3
- package/dist/src/smiths/context-pipeline/workspace-context.js +116 -9
- package/dist/src/smiths/hook-bridge/codex-translator.js +6 -5
- package/dist/src/smiths/mcpsmith/example.js +1 -1
- package/dist/src/smiths/toolsmith/runtime-discovery.mjs +10 -14
- package/dist/src/storage/backends/logseq.js +68 -7
- package/dist/src/storage/fortemi-qualification-receipt.js +2 -2
- package/dist/src/testing/generators/test-code-generator.js +57 -30
- package/dist/src/uhp/client.js +11 -1
- package/dist/src/uhp/mission.js +5 -0
- package/dist/src/update/checker.mjs +5 -5
- package/dist/src/update/notifier.mjs +54 -2
- package/dist/src/writing/fidelity.js +18 -1
- package/package.json +18 -1
- package/schemas/mission-v1.schema.json +2429 -0
- package/schemas/models/model-catalog.v1.schema.json +301 -0
- package/schemas/models/model-config-compatibility.v1.schema.json +281 -0
- package/schemas/models/model-policy.v1.schema.json +14 -0
- package/schemas/models/provider-model-capabilities.v1.schema.json +1066 -0
- package/tools/_resolve-impl.mjs +39 -0
- package/tools/agents/deploy-agents.mjs +15 -2
- package/tools/agents/providers/base.mjs +63 -43
- package/tools/agents/providers/grokbot.mjs +11 -12
- package/tools/agents/providers/hermes.mjs +6 -3
- package/tools/agents/providers/omp.mjs +5 -2
- package/tools/agents/providers/openclaw-translator.mjs +19 -5
- package/tools/providers/deepseek-harness-transport.mjs +358 -0
- package/tools/providers/omp-transport.mjs +192 -0
- package/tools/ralph-external/lib/claude-adapter.mjs +389 -0
- package/tools/ralph-external/lib/codex-adapter.mjs +432 -0
- package/tools/ralph-external/lib/deepseek-harness-adapter.mjs +397 -0
- package/tools/ralph-external/lib/factory-adapter.mjs +503 -0
- package/tools/ralph-external/lib/muse-adapter.mjs +364 -0
- package/tools/ralph-external/lib/omp-adapter.mjs +315 -0
- package/tools/ralph-external/lib/opencode-adapter.mjs +575 -0
- package/tools/ralph-external/lib/openhuman-adapter.mjs +75 -0
- package/tools/ralph-external/lib/pi-adapter.mjs +333 -0
- package/tools/ralph-external/lib/provider-adapter.mjs +690 -0
- package/tools/ralph-external/lib/worker-health.mjs +439 -0
- package/vscode-extension/schemas/aiwg.config.v1.json +1953 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Direct-worker dispatch opt-in offer (#3050).
|
|
3
|
+
*
|
|
4
|
+
* `parallelism.worker_dispatch` is off by default (#1359) and nothing told a
|
|
5
|
+
* user it exists, showed whether their machine could use it, or offered to
|
|
6
|
+
* turn it on. This module is the single shared place that decides whether
|
|
7
|
+
* any setup surface should offer it, and renders the matching prompt/hint
|
|
8
|
+
* text — every surface (`aiwg init`, `aiwg setup project`, `aiwg regenerate`,
|
|
9
|
+
* `aiwg refresh`, `aiwg doctor --probe-workers`) calls it instead of growing
|
|
10
|
+
* its own copy.
|
|
11
|
+
*
|
|
12
|
+
* Detection is presence-only: each known worker-CLI executable (from the
|
|
13
|
+
* shipped provider capability registry's `workerAdapter` /
|
|
14
|
+
* `workerHealthAdapter` process invocations — the same provider ->
|
|
15
|
+
* executable mapping `resolveDirectBinding()` in `worker-direct-readiness.ts`
|
|
16
|
+
* resolves bindings from) is checked for a match on `PATH` only. No process
|
|
17
|
+
* is spawned and no network call is made. This is deliberately narrower
|
|
18
|
+
* than `worker-direct-readiness.ts`'s version probes
|
|
19
|
+
* (`probeDirectWorkerVersion` / `boundedVersionProbe`), which spawn
|
|
20
|
+
* `<executable> ...versionArgv` and are opt-in behind `--probe-workers`;
|
|
21
|
+
* the offer only needs to know a CLI is present, so it never pays that cost
|
|
22
|
+
* or crosses that trust boundary.
|
|
23
|
+
*/
|
|
24
|
+
import { accessSync, constants as fsConstants, statSync } from 'node:fs';
|
|
25
|
+
import { delimiter, join } from 'node:path';
|
|
26
|
+
import { loadProviderModelCapabilities } from './provider-policy.js';
|
|
27
|
+
/**
|
|
28
|
+
* The one command every hint/prompt points at to flip the setting on — this
|
|
29
|
+
* is also the real re-enable path after a decline: enabling dispatch
|
|
30
|
+
* directly always clears the offer (see {@link evaluateWorkerDispatchOffer}),
|
|
31
|
+
* so there is no separate "undo the decline" command to document.
|
|
32
|
+
*/
|
|
33
|
+
export const WORKER_DISPATCH_ENABLE_COMMAND = 'aiwg config set --project parallelism.worker_dispatch true';
|
|
34
|
+
/** Readiness check shared by setup hints and dispatch refusals. */
|
|
35
|
+
export const WORKER_DISPATCH_READINESS_COMMAND = 'aiwg doctor --probe-workers';
|
|
36
|
+
/**
|
|
37
|
+
* Dotted config path a decline is recorded at. A setup/onboarding
|
|
38
|
+
* preference, not worker policy — kept out of `parallelism`, which is a
|
|
39
|
+
* frozen contract fragment (B-OG-29, #3050 review).
|
|
40
|
+
*/
|
|
41
|
+
export const WORKER_DISPATCH_DECLINE_FIELD = 'setup.worker_dispatch_offer';
|
|
42
|
+
/** Minimum number of distinct detected worker CLIs before any surface offers. */
|
|
43
|
+
const MIN_DETECTED_FOR_OFFER = 2;
|
|
44
|
+
/**
|
|
45
|
+
* Presence-only PATH check for one executable name: no spawn, no network.
|
|
46
|
+
* Requires a regular file (symlinks are followed by `statSync`) before the
|
|
47
|
+
* execute-permission check — an `X_OK` search-permission bit also succeeds
|
|
48
|
+
* for a directory, so without this a directory on `PATH` that merely shares
|
|
49
|
+
* a worker CLI's name would count as installed (#3050 review item 8).
|
|
50
|
+
*/
|
|
51
|
+
function executableOnPath(name, pathEnv) {
|
|
52
|
+
const dirs = (pathEnv ?? '').split(delimiter).filter(Boolean);
|
|
53
|
+
const candidates = process.platform === 'win32' ? [`${name}.exe`, `${name}.cmd`, `${name}.bat`, name] : [name];
|
|
54
|
+
return dirs.some(dir => candidates.some(candidate => {
|
|
55
|
+
const target = join(dir, candidate);
|
|
56
|
+
try {
|
|
57
|
+
if (!statSync(target).isFile())
|
|
58
|
+
return false;
|
|
59
|
+
accessSync(target, fsConstants.X_OK);
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}));
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Every known worker-CLI executable name declared by the shipped capability
|
|
69
|
+
* registry, deduplicated and sorted. Mirrors the same provider -> executable
|
|
70
|
+
* mapping `worker-direct-readiness.ts`'s `resolveDirectBinding()` resolves
|
|
71
|
+
* at dispatch time (`workerAdapter` falling back to `workerHealthAdapter`),
|
|
72
|
+
* so this list can never drift from what the resolver would actually bind.
|
|
73
|
+
*/
|
|
74
|
+
export function knownWorkerCliExecutables(registry = loadProviderModelCapabilities()) {
|
|
75
|
+
const names = new Set();
|
|
76
|
+
for (const provider of Object.values(registry.providers)) {
|
|
77
|
+
const adapter = provider.workerAdapter ?? provider.workerHealthAdapter;
|
|
78
|
+
if (adapter?.invocation.kind === 'process')
|
|
79
|
+
names.add(adapter.invocation.executable);
|
|
80
|
+
}
|
|
81
|
+
return [...names].sort();
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Which known worker CLIs are present on `PATH` right now. Presence-only:
|
|
85
|
+
* never spawns a process and never makes a network call. `registry` and
|
|
86
|
+
* `pathEnv` are both injectable so callers (and tests) never depend on
|
|
87
|
+
* whichever CLIs happen to be installed on the running host.
|
|
88
|
+
*/
|
|
89
|
+
export function detectInstalledWorkerClis(options = {}) {
|
|
90
|
+
const executables = knownWorkerCliExecutables(options.registry);
|
|
91
|
+
const pathEnv = options.pathEnv ?? process.env.PATH;
|
|
92
|
+
return executables.filter(executable => executableOnPath(executable, pathEnv));
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Should any setup surface offer or hint turning `worker_dispatch` on?
|
|
96
|
+
* `false` whenever it is already on, or the offer was previously declined
|
|
97
|
+
* (`setup.worker_dispatch_offer === 'declined'`) — a user who said no is
|
|
98
|
+
* not asked again on every run (#3050 item 3). Otherwise `true` once two or
|
|
99
|
+
* more known worker CLIs are detected.
|
|
100
|
+
*
|
|
101
|
+
* `parallelism` and `setup` are deliberately separate parameters, not one
|
|
102
|
+
* merged config object: `parallelism` is the frozen worker-policy contract
|
|
103
|
+
* fragment (B-OG-29) and must never gain fields for setup preferences; the
|
|
104
|
+
* decline itself lives in `setup`, a plain onboarding-preferences block.
|
|
105
|
+
*/
|
|
106
|
+
export function evaluateWorkerDispatchOffer(parallelism, setup, detected) {
|
|
107
|
+
if (parallelism?.worker_dispatch === true)
|
|
108
|
+
return { shouldOffer: false, detected };
|
|
109
|
+
if (setup?.worker_dispatch_offer === 'declined')
|
|
110
|
+
return { shouldOffer: false, detected };
|
|
111
|
+
return { shouldOffer: detected.length >= MIN_DETECTED_FOR_OFFER, detected };
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* One-line interactive yes/no question naming the detected CLIs. Callers
|
|
115
|
+
* MUST default the answer to `false` (no) — see #3050's "never enable
|
|
116
|
+
* without an explicit yes" constraint.
|
|
117
|
+
*/
|
|
118
|
+
export function workerDispatchOfferQuestion(detected) {
|
|
119
|
+
return ` Detected worker CLIs (${detected.join(', ')}). Enable direct worker dispatch so AIWG `
|
|
120
|
+
+ `can dispatch tasks to them directly, using their own accounts' quota? [y/N]: `;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* One-line non-interactive / regenerate / refresh / doctor hint. Never
|
|
124
|
+
* prompts and never changes anything by itself — it only names the enable
|
|
125
|
+
* command and the readiness check that confirms the CLIs are actually
|
|
126
|
+
* launchable.
|
|
127
|
+
*/
|
|
128
|
+
export function workerDispatchOfferHint(detected) {
|
|
129
|
+
return `Direct worker dispatch is off; detected worker CLIs: ${detected.join(', ')}. `
|
|
130
|
+
+ `Enable with \`${WORKER_DISPATCH_ENABLE_COMMAND}\` (then check readiness with \`${WORKER_DISPATCH_READINESS_COMMAND}\`).`;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Accepted values for the `--worker-dispatch` argument (#3062). Only
|
|
134
|
+
* `aiwg init` and `aiwg setup project` accept this argument directly — it
|
|
135
|
+
* answers the same question `askWorkerDispatchOffer`/`applyInteractivePrompts`
|
|
136
|
+
* would otherwise ask interactively, so those two commands can be run
|
|
137
|
+
* headless without leaving the offer unanswerable.
|
|
138
|
+
*/
|
|
139
|
+
export const WORKER_DISPATCH_ARG_VALUES = ['enable', 'decline'];
|
|
140
|
+
/**
|
|
141
|
+
* Parse a raw `--worker-dispatch` flag value. `undefined` in means the flag
|
|
142
|
+
* was not given at all (not an error — the question is still asked/hinted
|
|
143
|
+
* as before). Any other value that isn't exactly `enable`/`decline` throws,
|
|
144
|
+
* naming the accepted values; callers should map that to a non-zero exit.
|
|
145
|
+
*
|
|
146
|
+
* This is accepted even when fewer than two worker CLIs are detected — an
|
|
147
|
+
* explicit `--worker-dispatch` choice is honored regardless of the
|
|
148
|
+
* presence-only CLI detection `evaluateWorkerDispatchOffer` otherwise gates
|
|
149
|
+
* the interactive question/hint on.
|
|
150
|
+
*/
|
|
151
|
+
export function parseWorkerDispatchArg(raw) {
|
|
152
|
+
if (raw === undefined)
|
|
153
|
+
return undefined;
|
|
154
|
+
if (!WORKER_DISPATCH_ARG_VALUES.includes(raw)) {
|
|
155
|
+
throw new Error(`--worker-dispatch must be one of: ${WORKER_DISPATCH_ARG_VALUES.join(', ')} (got ${JSON.stringify(raw)})`);
|
|
156
|
+
}
|
|
157
|
+
return raw;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Hint variant for the two surfaces (`aiwg init`, `aiwg setup project`) that
|
|
161
|
+
* accept `--worker-dispatch` directly (#3062): same base hint, plus the
|
|
162
|
+
* argument itself, so a headless run without a terminal and without the
|
|
163
|
+
* argument names both the config command and the argument that would have
|
|
164
|
+
* answered the question directly.
|
|
165
|
+
*/
|
|
166
|
+
export function workerDispatchOfferHintWithArg(detected) {
|
|
167
|
+
return `${workerDispatchOfferHint(detected)} Or pass --worker-dispatch enable|decline to this command directly.`;
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=worker-dispatch-offer.js.map
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/** Offline S1 health readiness projection; never launch authority or a probe. */
|
|
2
|
+
import { validateParallelismConfig, resolveWorkerGroupInstallation, workerConfigDigest } from '../config/aiwg-config.js';
|
|
3
|
+
import { assertWorkerHealthQualification } from './provider-policy.js';
|
|
4
|
+
import { resolveWorkerPlan } from './resolver.js';
|
|
5
|
+
import { resolveWorkerEffectiveHealth } from '../serve/worker-invocation.js';
|
|
6
|
+
const repairAction = (code, pointer) => {
|
|
7
|
+
if (pointer === '/worker/observedAt')
|
|
8
|
+
return 'refresh-worker-catalog';
|
|
9
|
+
if (code === 'OG_EFFORT_DENIED')
|
|
10
|
+
return 'select-qualified-effort';
|
|
11
|
+
if (code === 'OG_MODEL_UNAPPROVED')
|
|
12
|
+
return 'review-model-policy-and-freshness';
|
|
13
|
+
if (code === 'OG_PIN_MISMATCH')
|
|
14
|
+
return 'review-exact-wrapper-pin';
|
|
15
|
+
if (code === 'OG_BUDGET_UNMEASURABLE')
|
|
16
|
+
return 'qualify-budget-enforcement';
|
|
17
|
+
if (code === 'OG_ADAPTER_UNQUALIFIED')
|
|
18
|
+
return 'qualify-installation-and-profile';
|
|
19
|
+
return 'review-worker-configuration';
|
|
20
|
+
};
|
|
21
|
+
export function diagnoseWorkerHealthReadiness(snapshot, request) {
|
|
22
|
+
const p = snapshot.config.parallelism;
|
|
23
|
+
const report = { enabled: p?.worker_dispatch === true,
|
|
24
|
+
ready: true, contextDigest: null, findings: [], thresholds: [] };
|
|
25
|
+
const add = (finding) => { report.findings.push(finding); };
|
|
26
|
+
if (!report.enabled) {
|
|
27
|
+
add({ code: 'WORKER_HEALTH_DISABLED', status: 'info', pointer: '/parallelism/worker_dispatch',
|
|
28
|
+
message: 'Group dispatch is disabled; legacy execution has no worker health readiness requirement.',
|
|
29
|
+
nextAction: 'none', role: null });
|
|
30
|
+
return report;
|
|
31
|
+
}
|
|
32
|
+
report.contextDigest = workerConfigDigest({ context: request.context, modelDigests: snapshot.modelDigests });
|
|
33
|
+
const errors = validateParallelismConfig(p);
|
|
34
|
+
if (errors.length) {
|
|
35
|
+
report.ready = false;
|
|
36
|
+
for (const message of errors)
|
|
37
|
+
add({ code: 'OG_CONFIG_REFERENCE', status: 'error',
|
|
38
|
+
pointer: '/parallelism', message, nextAction: 'review-worker-configuration', role: null });
|
|
39
|
+
return report;
|
|
40
|
+
}
|
|
41
|
+
if (p?.worker_mode === 'managed') {
|
|
42
|
+
add({ code: 'WORKER_HEALTH_MANAGED_DEFERRED', status: 'info', pointer: '/parallelism/worker_mode',
|
|
43
|
+
message: 'Managed admission and health enforcement are deferred to S2+; this check covers direct readiness.',
|
|
44
|
+
nextAction: 'use-direct-checkpoint', role: null });
|
|
45
|
+
return report;
|
|
46
|
+
}
|
|
47
|
+
const enabledGroups = Object.values(p?.groups ?? {});
|
|
48
|
+
const required = new Set(enabledGroups.flatMap(group => group.requiredRoles ?? []));
|
|
49
|
+
const roles = new Set([...Object.keys(snapshot.models.defaults.workerSelection?.roleGuidance ?? {}), ...required]);
|
|
50
|
+
if (!roles.size) {
|
|
51
|
+
report.ready = false;
|
|
52
|
+
add({ code: 'OG_CONFIG_REFERENCE', status: 'error', pointer: '/defaults/workerSelection/roleGuidance',
|
|
53
|
+
message: 'No worker role guidance is configured; onboarding cannot offer a qualified route.',
|
|
54
|
+
nextAction: 'configure-role-guidance', role: null });
|
|
55
|
+
}
|
|
56
|
+
const installations = new Set(enabledGroups.flatMap(group => group.members.filter(member => member.enabled !== false).map(member => member.cli)));
|
|
57
|
+
for (const cli of installations) {
|
|
58
|
+
if (!p?.clis?.[cli]?.quotaScope)
|
|
59
|
+
add({ code: 'WORKER_QUOTA_SCOPE_UNKNOWN', status: 'warn', role: null,
|
|
60
|
+
pointer: `/parallelism/clis/${cli}/quotaScope`,
|
|
61
|
+
message: 'No explicit quota/account correlation scope; shared aliases cannot establish independent upstream capacity.',
|
|
62
|
+
nextAction: 'configure-qualified-quota-scope' });
|
|
63
|
+
}
|
|
64
|
+
for (const role of roles) {
|
|
65
|
+
const plan = resolveWorkerPlan(snapshot, { ...request, role: role });
|
|
66
|
+
const isRequired = required.has(role);
|
|
67
|
+
const diagnostics = [...plan.diagnostics, ...plan.exclusions.flatMap(item => item.diagnostics)];
|
|
68
|
+
const seen = new Set();
|
|
69
|
+
for (const diagnostic of diagnostics) {
|
|
70
|
+
const key = `${diagnostic.code}:${diagnostic.pointer}:${diagnostic.message}`;
|
|
71
|
+
if (seen.has(key))
|
|
72
|
+
continue;
|
|
73
|
+
seen.add(key);
|
|
74
|
+
add({ ...diagnostic, status: diagnostic.blocking === false ? 'info' : 'warn', role,
|
|
75
|
+
nextAction: repairAction(diagnostic.code, diagnostic.pointer) });
|
|
76
|
+
}
|
|
77
|
+
if (!plan.selected) {
|
|
78
|
+
if (isRequired)
|
|
79
|
+
report.ready = false;
|
|
80
|
+
add({ code: 'WORKER_ROLE_NOT_READY', status: isRequired ? 'error' : 'warn', role,
|
|
81
|
+
pointer: `/defaults/workerSelection/roleGuidance/${role}`,
|
|
82
|
+
message: `${isRequired ? 'Required' : 'Optional'} role has no qualified route; request-time launch remains blocked.`,
|
|
83
|
+
nextAction: 'qualify-role-route' });
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const tuple = plan.selected;
|
|
87
|
+
try {
|
|
88
|
+
const { adapter } = resolveWorkerGroupInstallation(p, tuple.cli, snapshot.registry);
|
|
89
|
+
const profile = adapter.invocationProfiles[tuple.profile];
|
|
90
|
+
const binding = snapshot.installations[tuple.cli];
|
|
91
|
+
const model = snapshot.catalog.discovery?.instances?.[tuple.cli]?.models.find(row => row.id === tuple.model || row.apiModelId === tuple.model);
|
|
92
|
+
assertWorkerHealthQualification(profile, { profileRef: tuple.profile, cliVersion: binding.cliVersion,
|
|
93
|
+
accountScope: binding.accountScope, inferenceProvider: tuple.inferenceProvider, model: model?.apiModelId ?? tuple.model, effort: tuple.effort });
|
|
94
|
+
const nativeSteps = profile.controls.stepCap?.support === 'native';
|
|
95
|
+
if (p?.health?.requireStepCap && !nativeSteps) {
|
|
96
|
+
if (isRequired)
|
|
97
|
+
report.ready = false;
|
|
98
|
+
add({ code: 'WORKER_STEP_CAP_NOT_READY', status: isRequired ? 'error' : 'warn', role,
|
|
99
|
+
pointer: '/parallelism/health/requireStepCap',
|
|
100
|
+
message: 'Required step cap lacks native enforcement or qualified runtime pre-step admission evidence.',
|
|
101
|
+
nextAction: 'qualify-step-enforcement' });
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
// External admission needs runtime gate evidence; a config declaration alone cannot prove it.
|
|
105
|
+
const health = resolveWorkerEffectiveHealth(p?.health, { role, effort: tuple.effort,
|
|
106
|
+
modelKey: tuple.modelKey, profileRef: tuple.profile, wallSeconds: plan.ceilings.wallSeconds ?? 1800,
|
|
107
|
+
stepEnforcement: nativeSteps ? 'native' : 'unavailable' });
|
|
108
|
+
report.thresholds.push({ role, group: tuple.group, member: tuple.member, health });
|
|
109
|
+
if (!profile.health || profile.health.handshake !== 'semantic' || profile.health.coverage !== 'full') {
|
|
110
|
+
add({ code: 'WORKER_HEALTH_DEGRADED', status: 'warn', role,
|
|
111
|
+
pointer: `/parallelism/clis/${tuple.cli}/invocationProfile`,
|
|
112
|
+
message: 'Profile has degraded or unobserved health coverage; progress and stop evidence may be unavailable.',
|
|
113
|
+
nextAction: 'qualify-health-signals' });
|
|
114
|
+
}
|
|
115
|
+
add({ code: 'WORKER_ROLE_ELIGIBLE', status: 'ok', role,
|
|
116
|
+
pointer: `/defaults/workerSelection/roleGuidance/${role}`,
|
|
117
|
+
message: 'Policy route is eligible; launch still requires current installation and task qualification.',
|
|
118
|
+
nextAction: 'resolve-current-task' });
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
if (isRequired)
|
|
122
|
+
report.ready = false;
|
|
123
|
+
add({ code: 'WORKER_HEALTH_UNQUALIFIED', status: isRequired ? 'error' : 'warn', role,
|
|
124
|
+
pointer: `/parallelism/clis/${tuple.cli}/invocationProfile`,
|
|
125
|
+
message: 'Health profile scope or effective settings are invalid; requalify the exact version/account/model/effort.',
|
|
126
|
+
nextAction: 'qualify-health-signals' });
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return report;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=worker-health-readiness.js.map
|