@the-open-engine/zeroshot 6.38.0 → 6.39.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/cli/event-copy.js +8 -7
- package/cli/event-copy.ts +12 -0
- package/cli/index.js +7 -31
- package/cli/json-export.js +61 -64
- package/cli/json-export.ts +112 -0
- package/cli/message-formatter-utils.js +68 -56
- package/cli/message-formatter-utils.ts +121 -0
- package/cli/message-formatters-normal.js +124 -259
- package/cli/message-formatters-normal.ts +250 -0
- package/cli/message-formatters-watch.js +81 -84
- package/cli/message-formatters-watch.ts +189 -0
- package/lib/agent-cli-provider/adapters/codex.d.ts.map +1 -1
- package/lib/agent-cli-provider/adapters/codex.js +3 -1
- package/lib/agent-cli-provider/adapters/codex.js.map +1 -1
- package/lib/cluster/generated/protocol-schema.cjs +1 -1
- package/lib/cluster/generated/protocol-schema.mjs +1 -1
- package/lib/cluster/generated/protocol.d.cts +8 -0
- package/lib/cluster/generated/protocol.d.mts +8 -0
- package/lib/cluster/generated/protocol.d.ts +8 -0
- package/lib/clusters-registry.d.ts +23 -0
- package/lib/clusters-registry.js +17 -29
- package/lib/completion.d.ts +12 -0
- package/lib/completion.js +84 -94
- package/lib/compose-utils.d.ts +32 -0
- package/lib/compose-utils.js +57 -72
- package/lib/detached-startup.d.ts +83 -0
- package/lib/detached-startup.js +231 -302
- package/lib/docker-config.d.ts +43 -0
- package/lib/docker-config.js +150 -325
- package/lib/docker-env-auth.d.ts +17 -0
- package/lib/docker-env-auth.js +75 -0
- package/lib/git-remote-utils.d.ts +48 -0
- package/lib/git-remote-utils.js +147 -213
- package/lib/id-detector.d.ts +15 -0
- package/lib/id-detector.js +37 -41
- package/lib/path-check.d.ts +30 -0
- package/lib/path-check.js +42 -45
- package/lib/process-liveness.d.ts +16 -0
- package/lib/process-liveness.js +19 -12
- package/lib/provider-credential-path.d.ts +16 -0
- package/lib/provider-credential-path.js +31 -29
- package/lib/provider-defaults.d.ts +30 -0
- package/lib/provider-defaults.js +47 -42
- package/lib/provider-detection.d.ts +11 -0
- package/lib/provider-detection.js +91 -54
- package/lib/provider-names.d.ts +38 -0
- package/lib/provider-names.js +56 -64
- package/lib/repo-settings.d.ts +28 -0
- package/lib/repo-settings.js +83 -59
- package/lib/run-mode.d.ts +21 -0
- package/lib/run-mode.js +21 -20
- package/lib/run-plan.d.ts +28 -0
- package/lib/run-plan.js +17 -16
- package/lib/settings/claude-auth.d.ts +35 -0
- package/lib/settings/claude-auth.js +30 -47
- package/lib/settings-defaults.d.ts +20 -0
- package/lib/settings-defaults.js +149 -0
- package/lib/settings-error.d.ts +7 -0
- package/lib/settings-error.js +8 -0
- package/lib/settings-issue-providers.d.ts +10 -0
- package/lib/settings-issue-providers.js +12 -0
- package/lib/settings-models.d.ts +22 -0
- package/lib/settings-models.js +93 -0
- package/lib/settings-storage.d.ts +23 -0
- package/lib/settings-storage.js +205 -0
- package/lib/settings-validation.d.ts +7 -0
- package/lib/settings-validation.js +182 -0
- package/lib/settings.d.ts +29 -0
- package/lib/settings.js +41 -736
- package/lib/setup-apply-types.d.ts +66 -0
- package/lib/setup-apply-types.js +2 -0
- package/lib/setup-apply.d.ts +39 -0
- package/lib/setup-apply.js +267 -264
- package/lib/setup-journal.d.ts +41 -0
- package/lib/setup-journal.js +119 -76
- package/lib/setup-plan-types.d.ts +102 -0
- package/lib/setup-plan-types.js +2 -0
- package/lib/setup-plan.d.ts +30 -0
- package/lib/setup-plan.js +300 -324
- package/lib/setup-undo.d.ts +44 -0
- package/lib/setup-undo.js +61 -74
- package/lib/start-cluster-config.d.ts +26 -0
- package/lib/start-cluster-config.js +56 -0
- package/lib/start-cluster-environment.d.ts +40 -0
- package/lib/start-cluster-environment.js +134 -0
- package/lib/start-cluster-run-options.d.ts +53 -0
- package/lib/start-cluster-run-options.js +147 -0
- package/lib/start-cluster.d.ts +64 -0
- package/lib/start-cluster.js +98 -454
- package/lib/stream-json-parser.d.ts +17 -0
- package/lib/stream-json-parser.js +51 -52
- package/npm-shrinkwrap.json +2 -2
- package/package.json +12 -6
- package/scripts/postinstall.js +27 -0
- package/scripts/rust-distribution.js +23 -14
- package/src/agent/agent-command-proofs-context.js +35 -45
- package/src/agent/agent-command-proofs-context.ts +87 -0
- package/src/agent/agent-config-settings.js +19 -0
- package/src/agent/agent-config-settings.ts +41 -0
- package/src/agent/agent-config.js +122 -231
- package/src/agent/agent-config.ts +285 -0
- package/src/agent/agent-context-builder.js +38 -273
- package/src/agent/agent-context-builder.ts +51 -0
- package/src/agent/agent-context-environment-sections.js +105 -0
- package/src/agent/agent-context-environment-sections.ts +134 -0
- package/src/agent/agent-context-packs.js +165 -0
- package/src/agent/agent-context-packs.ts +296 -0
- package/src/agent/agent-context-prompt-sections.js +100 -0
- package/src/agent/agent-context-prompt-sections.ts +148 -0
- package/src/agent/agent-context-sections.js +25 -334
- package/src/agent/agent-context-sections.ts +36 -0
- package/src/agent/agent-context-sources.js +96 -149
- package/src/agent/agent-context-sources.ts +253 -0
- package/src/agent/agent-context-types.js +2 -0
- package/src/agent/agent-context-types.ts +132 -0
- package/src/agent/agent-context-validation-sections.js +73 -0
- package/src/agent/agent-context-validation-sections.ts +129 -0
- package/src/agent/agent-input-injector.js +99 -118
- package/src/agent/agent-input-injector.ts +195 -0
- package/src/agent/agent-liveness-poll.js +74 -78
- package/src/agent/agent-liveness-poll.ts +163 -0
- package/src/agent/agent-quality-gate-schema.js +77 -86
- package/src/agent/agent-quality-gate-schema.ts +135 -0
- package/src/agent/agent-quality-gates-context.js +44 -50
- package/src/agent/agent-quality-gates-context.ts +91 -0
- package/src/agent/agent-stuck-detector.js +171 -239
- package/src/agent/agent-stuck-detector.ts +288 -0
- package/src/agent/agent-trigger-evaluator.js +29 -46
- package/src/agent/agent-trigger-evaluator.ts +98 -0
- package/src/agent/context-metrics.js +110 -141
- package/src/agent/context-metrics.ts +261 -0
- package/src/agent/context-pack-builder.js +72 -358
- package/src/agent/context-pack-builder.ts +105 -0
- package/src/agent/context-pack-core.js +70 -0
- package/src/agent/context-pack-core.ts +96 -0
- package/src/agent/context-pack-selection.js +119 -0
- package/src/agent/context-pack-selection.ts +187 -0
- package/src/agent/context-pack-truncation.js +139 -0
- package/src/agent/context-pack-truncation.ts +208 -0
- package/src/agent/context-pack-types.js +2 -0
- package/src/agent/context-pack-types.ts +98 -0
- package/src/agent/context-replay-policy.js +30 -39
- package/src/agent/context-replay-policy.ts +71 -0
- package/src/agent/critical-agent-policy.js +6 -10
- package/src/agent/critical-agent-policy.ts +20 -0
- package/src/agent/guidance-queue.js +74 -87
- package/src/agent/guidance-queue.ts +166 -0
- package/src/agent/output-extraction-error-detail.js +45 -0
- package/src/agent/output-extraction-error-detail.ts +49 -0
- package/src/agent/output-extraction-failures.js +125 -0
- package/src/agent/output-extraction-failures.ts +149 -0
- package/src/agent/output-extraction-json.js +234 -0
- package/src/agent/output-extraction-json.ts +235 -0
- package/src/agent/output-extraction-pi.js +124 -0
- package/src/agent/output-extraction-pi.ts +137 -0
- package/src/agent/output-extraction-types.js +2 -0
- package/src/agent/output-extraction-types.ts +49 -0
- package/src/agent/output-extraction.js +17 -617
- package/src/agent/output-extraction.ts +30 -0
- package/src/agent/output-reformatter-errors.js +83 -0
- package/src/agent/output-reformatter-errors.ts +106 -0
- package/src/agent/output-reformatter-types.js +2 -0
- package/src/agent/output-reformatter-types.ts +86 -0
- package/src/agent/output-reformatter.js +140 -185
- package/src/agent/output-reformatter.ts +238 -0
- package/src/agent/pi-terminal-lifecycle-types.js +2 -0
- package/src/agent/pi-terminal-lifecycle-types.ts +41 -0
- package/src/agent/pi-terminal-lifecycle.js +186 -206
- package/src/agent/pi-terminal-lifecycle.ts +297 -0
- package/src/agent/provider-control-plane.js +22 -21
- package/src/agent/provider-control-plane.ts +52 -0
- package/src/agent/provider-terminal-failure-types.js +2 -0
- package/src/agent/provider-terminal-failure-types.ts +60 -0
- package/src/agent/provider-terminal-failure.js +194 -191
- package/src/agent/provider-terminal-failure.ts +262 -0
- package/src/agent/rate-limit-backoff.js +31 -74
- package/src/agent/rate-limit-backoff.ts +71 -0
- package/src/agent/schema-utils.js +85 -125
- package/src/agent/schema-utils.ts +148 -0
- package/src/agent/structured-output-error.js +34 -33
- package/src/agent/structured-output-error.ts +105 -0
- package/src/agent/validation-platform.js +27 -27
- package/src/agent/validation-platform.ts +49 -0
- package/src/agent-cli-provider/adapters/codex.ts +3 -1
- package/src/attach/attach-client.js +232 -405
- package/src/attach/attach-client.ts +300 -0
- package/src/attach/attach-server-cleanup.js +43 -0
- package/src/attach/attach-server-cleanup.ts +39 -0
- package/src/attach/attach-server-clients.js +117 -0
- package/src/attach/attach-server-clients.ts +122 -0
- package/src/attach/attach-server-events.js +38 -0
- package/src/attach/attach-server-events.ts +36 -0
- package/src/attach/attach-server-pty.js +45 -0
- package/src/attach/attach-server-pty.ts +64 -0
- package/src/attach/attach-server-runtime.js +73 -0
- package/src/attach/attach-server-runtime.ts +62 -0
- package/src/attach/attach-server-socket.js +28 -0
- package/src/attach/attach-server-socket.ts +23 -0
- package/src/attach/attach-server-types.js +2 -0
- package/src/attach/attach-server-types.ts +82 -0
- package/src/attach/attach-server.js +106 -523
- package/src/attach/attach-server.ts +158 -0
- package/src/attach/index.js +18 -35
- package/src/attach/index.ts +18 -0
- package/src/attach/protocol.js +95 -184
- package/src/attach/protocol.ts +181 -0
- package/src/attach/ring-buffer.js +76 -102
- package/src/attach/ring-buffer.ts +109 -0
- package/src/attach/send-input.js +64 -75
- package/src/attach/send-input.ts +94 -0
- package/src/attach/socket-discovery.js +164 -218
- package/src/attach/socket-discovery.ts +230 -0
- package/src/attach/socket-paths.js +42 -61
- package/src/attach/socket-paths.ts +81 -0
- package/src/claude-credentials.js +51 -54
- package/src/claude-credentials.ts +89 -0
- package/src/cluster/generated/protocol-schema.ts +1 -1
- package/src/cluster/generated/protocol.ts +2 -1
- package/src/command-proofs.js +110 -141
- package/src/command-proofs.ts +216 -0
- package/src/config-router.js +81 -73
- package/src/config-router.ts +131 -0
- package/src/copy-worker.js +53 -29
- package/src/copy-worker.ts +75 -0
- package/src/darwin-keychain-boundary.js +80 -111
- package/src/darwin-keychain-boundary.ts +148 -0
- package/src/guidance-topics.js +4 -5
- package/src/guidance-topics.ts +10 -0
- package/src/input-helpers.js +33 -54
- package/src/input-helpers.ts +58 -0
- package/src/ledger-sequence.js +45 -48
- package/src/ledger-sequence.ts +63 -0
- package/src/legacy-lib/clusters-registry.ts +40 -0
- package/src/legacy-lib/completion.ts +148 -0
- package/src/legacy-lib/compose-utils.ts +102 -0
- package/src/legacy-lib/detached-startup.ts +449 -0
- package/src/legacy-lib/docker-config.ts +282 -0
- package/src/legacy-lib/docker-env-auth.ts +116 -0
- package/src/legacy-lib/git-remote-utils.ts +244 -0
- package/src/legacy-lib/id-detector.ts +57 -0
- package/src/legacy-lib/js-yaml.d.ts +3 -0
- package/src/legacy-lib/omelette.d.ts +15 -0
- package/src/legacy-lib/path-check.ts +89 -0
- package/src/legacy-lib/process-liveness.ts +36 -0
- package/src/legacy-lib/provider-credential-path.ts +57 -0
- package/src/legacy-lib/provider-defaults.ts +114 -0
- package/src/legacy-lib/provider-detection.ts +67 -0
- package/src/legacy-lib/provider-names.ts +126 -0
- package/src/legacy-lib/repo-settings.ts +88 -0
- package/src/legacy-lib/run-mode.ts +58 -0
- package/src/legacy-lib/run-plan.ts +49 -0
- package/src/legacy-lib/settings/claude-auth.ts +80 -0
- package/src/legacy-lib/settings-defaults.ts +212 -0
- package/src/legacy-lib/settings-error.ts +8 -0
- package/src/legacy-lib/settings-issue-providers.ts +18 -0
- package/src/legacy-lib/settings-models.ts +124 -0
- package/src/legacy-lib/settings-storage.ts +277 -0
- package/src/legacy-lib/settings-validation.ts +220 -0
- package/src/legacy-lib/settings.ts +87 -0
- package/src/legacy-lib/setup-apply-types.ts +70 -0
- package/src/legacy-lib/setup-apply.ts +456 -0
- package/src/legacy-lib/setup-journal.ts +185 -0
- package/src/legacy-lib/setup-plan-types.ts +96 -0
- package/src/legacy-lib/setup-plan.ts +500 -0
- package/src/legacy-lib/setup-undo.ts +142 -0
- package/src/legacy-lib/start-cluster-config.ts +124 -0
- package/src/legacy-lib/start-cluster-environment.ts +165 -0
- package/src/legacy-lib/start-cluster-run-options.ts +279 -0
- package/src/legacy-lib/start-cluster.ts +237 -0
- package/src/legacy-lib/stream-json-parser.ts +88 -0
- package/src/message-buffer.js +55 -71
- package/src/message-buffer.ts +107 -0
- package/src/message-bus-bridge.js +92 -133
- package/src/message-bus-bridge.ts +149 -0
- package/src/name-generator-shared.js +220 -0
- package/src/name-generator-shared.ts +231 -0
- package/src/name-generator.js +8 -217
- package/src/name-generator.ts +27 -0
- package/src/omp-blob-root.js +83 -64
- package/src/omp-blob-root.ts +116 -0
- package/src/omp-config-overlay.js +65 -38
- package/src/omp-config-overlay.ts +110 -0
- package/src/omp-execution-fingerprint.js +38 -43
- package/src/omp-execution-fingerprint.ts +92 -0
- package/src/omp-session-limits.js +10 -15
- package/src/omp-session-limits.ts +53 -0
- package/src/omp-session-partition.js +2 -2
- package/src/omp-session-verifier.js +1 -1
- package/src/orchestrator.js +19 -4
- package/src/providers/anthropic/index.js +3 -1
- package/src/providers/anthropic/index.ts +13 -0
- package/src/providers/capabilities.js +19 -27
- package/src/providers/capabilities.ts +44 -0
- package/src/providers/google/index.js +3 -1
- package/src/providers/google/index.ts +13 -0
- package/src/providers/openai/index.js +3 -1
- package/src/providers/openai/index.ts +13 -0
- package/src/providers/opencode/index.js +3 -1
- package/src/providers/opencode/index.ts +13 -0
- package/src/quality-gates.js +67 -127
- package/src/quality-gates.ts +149 -0
- package/src/repo-settings-access.js +40 -0
- package/src/repo-settings-access.ts +64 -0
- package/src/schemas/sub-cluster.js +127 -183
- package/src/schemas/sub-cluster.ts +238 -0
- package/src/state-snapshot-normalization.js +224 -0
- package/src/state-snapshot-normalization.ts +222 -0
- package/src/state-snapshot.js +192 -359
- package/src/state-snapshot.ts +291 -0
- package/src/state-snapshotter.js +118 -130
- package/src/state-snapshotter.ts +167 -0
- package/src/sub-cluster-wrapper.js +4 -13
- package/src/task-run-model-args.js +87 -124
- package/src/task-run-model-args.ts +204 -0
- package/src/task-runner.js +5 -25
- package/src/task-runner.ts +28 -0
- package/src/task-startup-error.js +73 -58
- package/src/task-startup-error.ts +126 -0
- package/src/template-validation/consensus-gate-contracts.js +2 -0
- package/src/template-validation/consensus-gate-contracts.ts +70 -0
- package/src/template-validation/consensus-gate-scenarios.js +76 -0
- package/src/template-validation/consensus-gate-scenarios.ts +130 -0
- package/src/template-validation/consensus-gate-stage.js +34 -0
- package/src/template-validation/consensus-gate-stage.ts +56 -0
- package/src/template-validation/random-topology-contracts.js +2 -0
- package/src/template-validation/random-topology-contracts.ts +54 -0
- package/src/template-validation/random-topology-dispatch.js +25 -0
- package/src/template-validation/random-topology-dispatch.ts +33 -0
- package/src/template-validation/random-topology-message-loop.js +53 -0
- package/src/template-validation/random-topology-message-loop.ts +73 -0
- package/src/template-validation/random-topology-operations.js +79 -0
- package/src/template-validation/random-topology-operations.ts +101 -0
- package/src/template-validation/random-topology-runtime.js +25 -0
- package/src/template-validation/random-topology-runtime.ts +43 -0
- package/src/template-validation/random-topology-scenario.js +52 -0
- package/src/template-validation/random-topology-scenario.ts +57 -0
- package/src/template-validation/random-topology-schema.js +159 -0
- package/src/template-validation/random-topology-schema.ts +190 -0
- package/src/template-validation/random-topology-state.js +28 -0
- package/src/template-validation/random-topology-state.ts +30 -0
- package/src/template-validation/random-topology-trigger-evaluation.js +45 -0
- package/src/template-validation/random-topology-trigger-evaluation.ts +65 -0
- package/src/template-validation/random-topology-trigger.js +75 -0
- package/src/template-validation/random-topology-trigger.ts +88 -0
- package/src/template-validation/report-formatter.js +40 -46
- package/src/template-validation/report-formatter.ts +101 -0
- package/src/template-validation/simulate-consensus-gates.js +111 -302
- package/src/template-validation/simulate-consensus-gates.ts +196 -0
- package/src/template-validation/simulate-random-topology.js +26 -519
- package/src/template-validation/simulate-random-topology.ts +57 -0
- package/src/template-validation/simulate-two-stage-validation.js +41 -265
- package/src/template-validation/simulate-two-stage-validation.ts +55 -0
- package/src/template-validation/simulation-agent-runtime.js +25 -0
- package/src/template-validation/simulation-agent-runtime.ts +40 -0
- package/src/template-validation/simulation-agent.js +29 -0
- package/src/template-validation/simulation-agent.ts +73 -0
- package/src/template-validation/simulation-runtime.js +34 -0
- package/src/template-validation/simulation-runtime.ts +72 -0
- package/src/template-validation/two-stage-contracts.js +2 -0
- package/src/template-validation/two-stage-contracts.ts +41 -0
- package/src/template-validation/two-stage-inputs.js +21 -0
- package/src/template-validation/two-stage-inputs.ts +29 -0
- package/src/template-validation/two-stage-results.js +30 -0
- package/src/template-validation/two-stage-results.ts +40 -0
- package/src/template-validation/two-stage-scenario.js +86 -0
- package/src/template-validation/two-stage-scenario.ts +120 -0
- package/src/worktree-claude-config.js +182 -220
- package/src/worktree-claude-config.ts +272 -0
- package/src/worktree-tooling-env.js +103 -125
- package/src/worktree-tooling-env.ts +142 -0
- package/task-lib/completion.js +2 -3
- package/task-lib/completion.ts +9 -0
- package/task-lib/config.js +1 -4
- package/task-lib/config.ts +11 -0
- package/task-lib/name-generator.js +4 -226
- package/task-lib/name-generator.ts +11 -0
- package/task-lib/omp-session-cleanup.js +1 -1
- package/task-lib/omp-storage-root.js +8 -12
- package/task-lib/omp-storage-root.ts +62 -0
- package/task-lib/process-termination.js +143 -166
- package/task-lib/process-termination.ts +268 -0
|
@@ -1,264 +1,155 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* - Config validation and normalization
|
|
6
|
-
* - Default values for optional fields
|
|
7
|
-
* - Model configuration setup
|
|
8
|
-
* - Safety checks for test mode
|
|
9
|
-
* - maxModel ceiling enforcement at config time
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
const { loadSettings, validateModelAgainstMax, VALID_MODELS } = require('../../lib/settings');
|
|
13
|
-
const { applyValidatorQualityGateDefaults } = require('./agent-quality-gate-schema');
|
|
14
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
/** Agent configuration validation and defaults. */
|
|
3
|
+
const qualityGateSchema = require("./agent-quality-gate-schema");
|
|
4
|
+
const settingsFacade = require("./agent-config-settings");
|
|
15
5
|
const VALID_LEVELS = ['level1', 'level2', 'level3'];
|
|
16
|
-
|
|
17
|
-
// Default max iterations (high limit - let the user decide when to give up)
|
|
18
6
|
const DEFAULT_MAX_ITERATIONS = 100;
|
|
19
|
-
|
|
20
|
-
// Default timeout: 0 = no timeout (task runs until completion or explicit kill)
|
|
21
|
-
// Use positive number for timeout in milliseconds
|
|
22
7
|
const DEFAULT_TIMEOUT = 0;
|
|
23
|
-
|
|
24
|
-
// Output-silence detection is opt-in because healthy provider operations may be quiet for
|
|
25
|
-
// longer than the stale threshold. Explicit task timeouts remain independently supported.
|
|
26
|
-
const DEFAULT_STALE_DURATION_MS = 30 * 60 * 1000; // 30 minutes before triggering analysis
|
|
8
|
+
const DEFAULT_STALE_DURATION_MS = 30 * 60 * 1000;
|
|
27
9
|
const DEFAULT_LIVENESS_CHECK_ENABLED = false;
|
|
28
|
-
|
|
10
|
+
function isRecord(value) {
|
|
11
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
12
|
+
}
|
|
13
|
+
function isModelLevel(value) {
|
|
14
|
+
return value === 'level1' || value === 'level2' || value === 'level3';
|
|
15
|
+
}
|
|
16
|
+
const { loadSettings, validateModelAgainstMax, VALID_MODELS } = settingsFacade;
|
|
17
|
+
const { applyValidatorQualityGateDefaults } = qualityGateSchema;
|
|
29
18
|
function applyOutputDefaults(config) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
config.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
config
|
|
45
|
-
type: 'object',
|
|
46
|
-
properties: {
|
|
47
|
-
summary: {
|
|
48
|
-
type: 'string',
|
|
49
|
-
description: 'Brief summary of what was done',
|
|
50
|
-
},
|
|
51
|
-
result: {
|
|
52
|
-
type: 'string',
|
|
53
|
-
description: 'Detailed result or output',
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
required: ['summary', 'result'],
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
applyValidatorQualityGateDefaults(config);
|
|
19
|
+
if (!config.outputFormat)
|
|
20
|
+
config.outputFormat = 'json';
|
|
21
|
+
if (config.structuredOutput && !config.jsonSchema)
|
|
22
|
+
config.jsonSchema = config.structuredOutput;
|
|
23
|
+
if (config.outputFormat === 'json' && !config.jsonSchema) {
|
|
24
|
+
config.jsonSchema = {
|
|
25
|
+
type: 'object',
|
|
26
|
+
properties: {
|
|
27
|
+
summary: { type: 'string', description: 'Brief summary of what was done' },
|
|
28
|
+
result: { type: 'string', description: 'Detailed result or output' },
|
|
29
|
+
},
|
|
30
|
+
required: ['summary', 'result'],
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
applyValidatorQualityGateDefaults(config);
|
|
61
34
|
}
|
|
62
|
-
|
|
63
35
|
function buildModelConfig(config) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return {
|
|
68
|
-
type: 'static',
|
|
69
|
-
model: config.model || null,
|
|
70
|
-
modelLevel: config.modelLevel || null,
|
|
71
|
-
};
|
|
36
|
+
if (config.modelRules)
|
|
37
|
+
return { type: 'rules', rules: config.modelRules };
|
|
38
|
+
return { type: 'static', model: config.model || null, modelLevel: config.modelLevel || null };
|
|
72
39
|
}
|
|
73
|
-
|
|
74
40
|
function applyStrictSchemaDefault(config, settings) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
41
|
+
if (config.strictSchema === undefined)
|
|
42
|
+
config.strictSchema = settings.strictSchema !== false;
|
|
43
|
+
}
|
|
44
|
+
function errorMessage(error) {
|
|
45
|
+
return isRecord(error) ? error.message : undefined;
|
|
78
46
|
}
|
|
79
|
-
|
|
80
47
|
function validateStaticModelConfig(configId, modelConfig, maxModel, minModel) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
48
|
+
if (modelConfig.model && VALID_MODELS.includes(modelConfig.model)) {
|
|
49
|
+
try {
|
|
50
|
+
validateModelAgainstMax(modelConfig.model, maxModel, minModel);
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
throw new Error(`Agent "${configId}": ${String(errorMessage(error))}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (modelConfig.modelLevel && !isModelLevel(modelConfig.modelLevel)) {
|
|
57
|
+
throw new Error(`Agent "${configId}": invalid modelLevel "${modelConfig.modelLevel}". Valid: ${VALID_LEVELS.join(', ')}`);
|
|
86
58
|
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (modelConfig.modelLevel && !VALID_LEVELS.includes(modelConfig.modelLevel)) {
|
|
90
|
-
throw new Error(
|
|
91
|
-
`Agent "${configId}": invalid modelLevel "${modelConfig.modelLevel}". ` +
|
|
92
|
-
`Valid: ${VALID_LEVELS.join(', ')}`
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
59
|
}
|
|
96
|
-
|
|
97
60
|
function validateModelRule(configId, rule, maxModel, minModel) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
61
|
+
if (rule.model && VALID_MODELS.includes(rule.model)) {
|
|
62
|
+
try {
|
|
63
|
+
validateModelAgainstMax(rule.model, maxModel, minModel);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
throw new Error(`Agent "${configId}": modelRule "${String(rule.iterations)}" requests "${rule.model}" ` +
|
|
67
|
+
`but maxModel is "${maxModel}"${minModel ? ` and minModel is "${minModel}"` : ''}. ` +
|
|
68
|
+
`Either adjust the rule's model or change maxModel/minModel settings.`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (rule.modelLevel && !isModelLevel(rule.modelLevel)) {
|
|
72
|
+
throw new Error(`Agent "${configId}": modelRule "${String(rule.iterations)}" has invalid modelLevel ` +
|
|
73
|
+
`"${rule.modelLevel}". Valid: ${VALID_LEVELS.join(', ')}`);
|
|
107
74
|
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (rule.modelLevel && !VALID_LEVELS.includes(rule.modelLevel)) {
|
|
111
|
-
throw new Error(
|
|
112
|
-
`Agent "${configId}": modelRule "${rule.iterations}" has invalid modelLevel ` +
|
|
113
|
-
`"${rule.modelLevel}". Valid: ${VALID_LEVELS.join(', ')}`
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
75
|
}
|
|
117
|
-
|
|
118
76
|
function validateModelConfig(config, modelConfig, maxModel, minModel) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
for (const rule of modelConfig.rules) {
|
|
126
|
-
validateModelRule(config.id, rule, maxModel, minModel);
|
|
77
|
+
if (modelConfig.type === 'static') {
|
|
78
|
+
validateStaticModelConfig(config.id, modelConfig, maxModel, minModel);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
for (const rule of modelConfig.rules)
|
|
82
|
+
validateModelRule(config.id, rule, maxModel, minModel);
|
|
127
83
|
}
|
|
128
|
-
}
|
|
129
84
|
}
|
|
130
|
-
|
|
131
85
|
function buildInitialPromptRules(prompt) {
|
|
132
|
-
|
|
86
|
+
if (!prompt.initial && !prompt.subsequent)
|
|
87
|
+
return null;
|
|
133
88
|
const rules = [];
|
|
134
|
-
if (prompt.initial)
|
|
135
|
-
|
|
89
|
+
if (prompt.initial)
|
|
90
|
+
rules.push({ match: '1', system: prompt.initial });
|
|
91
|
+
if (prompt.subsequent)
|
|
92
|
+
rules.push({ match: '2+', system: prompt.subsequent });
|
|
136
93
|
return rules;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return null;
|
|
140
94
|
}
|
|
141
|
-
|
|
142
95
|
function buildPromptConfig(config) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
return
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
if (prompt) {
|
|
162
|
-
throw new Error(`Agent "${config.id}": invalid prompt format`);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
return null;
|
|
96
|
+
const prompt = config.prompt;
|
|
97
|
+
if (prompt && typeof prompt !== 'string' && prompt.iterations) {
|
|
98
|
+
return { type: 'rules', rules: prompt.iterations };
|
|
99
|
+
}
|
|
100
|
+
if (prompt && typeof prompt !== 'string') {
|
|
101
|
+
const initialRules = buildInitialPromptRules(prompt);
|
|
102
|
+
if (initialRules)
|
|
103
|
+
return { type: 'rules', rules: initialRules };
|
|
104
|
+
}
|
|
105
|
+
if (typeof prompt === 'string')
|
|
106
|
+
return { type: 'static', system: prompt };
|
|
107
|
+
if (prompt?.system)
|
|
108
|
+
return { type: 'static', system: prompt.system };
|
|
109
|
+
if (prompt)
|
|
110
|
+
throw new Error(`Agent "${config.id}": invalid prompt format`);
|
|
111
|
+
return null;
|
|
166
112
|
}
|
|
167
|
-
|
|
168
113
|
function normalizeTimeout(config) {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
config.timeout =
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
`Agent "${config.id}": timeout must be a non-negative number (got ${config.timeout}).`
|
|
178
|
-
);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return config.timeout;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
function buildNormalizedConfig(config, modelConfig, promptConfig) {
|
|
185
|
-
return {
|
|
186
|
-
...config,
|
|
187
|
-
modelConfig,
|
|
188
|
-
promptConfig,
|
|
189
|
-
maxIterations: config.maxIterations || DEFAULT_MAX_ITERATIONS,
|
|
190
|
-
timeout: config.timeout,
|
|
191
|
-
staleDuration: config.staleDuration || DEFAULT_STALE_DURATION_MS,
|
|
192
|
-
enableLivenessCheck: config.enableLivenessCheck ?? DEFAULT_LIVENESS_CHECK_ENABLED,
|
|
193
|
-
};
|
|
114
|
+
const timeout = config.timeout === undefined || config.timeout === null || config.timeout === ''
|
|
115
|
+
? DEFAULT_TIMEOUT
|
|
116
|
+
: Number(config.timeout);
|
|
117
|
+
config.timeout = timeout;
|
|
118
|
+
if (!Number.isFinite(timeout) || timeout < 0) {
|
|
119
|
+
throw new Error(`Agent "${config.id}": timeout must be a non-negative number (got ${timeout}).`);
|
|
120
|
+
}
|
|
121
|
+
return timeout;
|
|
194
122
|
}
|
|
195
|
-
|
|
196
123
|
function assertTestModeSafety(config, options) {
|
|
197
|
-
|
|
198
|
-
(
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
if (options.testMode && !hasMock && executesTask) {
|
|
203
|
-
throw new Error(
|
|
204
|
-
`AgentWrapper: testMode=true but no mockSpawnFn/taskRunner provided for agent '${config.id}'. ` +
|
|
205
|
-
`This would cause real Claude API calls. ABORTING.`
|
|
206
|
-
);
|
|
207
|
-
}
|
|
124
|
+
const executesTask = config.triggers?.some((trigger) => !trigger.action || trigger.action === 'execute_task');
|
|
125
|
+
if (options.testMode && !options.mockSpawnFn && !options.taskRunner && executesTask) {
|
|
126
|
+
throw new Error(`AgentWrapper: testMode=true but no mockSpawnFn/taskRunner provided for agent '${config.id}'. ` +
|
|
127
|
+
`This would cause real Claude API calls. ABORTING.`);
|
|
128
|
+
}
|
|
208
129
|
}
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* Validate and normalize agent configuration
|
|
212
|
-
* @param {Object} config - Raw agent configuration
|
|
213
|
-
* @param {Object} options - Agent wrapper options
|
|
214
|
-
* @returns {Object} Normalized configuration
|
|
215
|
-
*/
|
|
216
130
|
function validateAgentConfig(config, options = {}) {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
// Prompt configuration: support static prompt OR iteration-based rules
|
|
237
|
-
// Formats:
|
|
238
|
-
// prompt: "string" -> static
|
|
239
|
-
// prompt: { system: "string" } -> static
|
|
240
|
-
// prompt: { initial: "...", subsequent: "..." } -> iteration 1 vs 2+
|
|
241
|
-
// prompt: { iterations: [...] } -> full control
|
|
242
|
-
const promptConfig = buildPromptConfig(config);
|
|
243
|
-
|
|
244
|
-
// Default timeout to 0 (no timeout) if not specified
|
|
245
|
-
// Use positive number for timeout in milliseconds
|
|
246
|
-
// ROBUST: Handle undefined, null, AND string values from template resolution
|
|
247
|
-
normalizeTimeout(config);
|
|
248
|
-
|
|
249
|
-
// Build normalized config
|
|
250
|
-
const normalizedConfig = buildNormalizedConfig(config, modelConfig, promptConfig);
|
|
251
|
-
|
|
252
|
-
// SAFETY: In test mode, verify mock is provided for agents that execute tasks
|
|
253
|
-
// Check if this agent executes tasks (vs orchestrator agents that only publish messages)
|
|
254
|
-
assertTestModeSafety(config, options);
|
|
255
|
-
|
|
256
|
-
return normalizedConfig;
|
|
131
|
+
applyOutputDefaults(config);
|
|
132
|
+
const modelConfig = buildModelConfig(config);
|
|
133
|
+
const settings = loadSettings();
|
|
134
|
+
const minModel = settings.minModel || null;
|
|
135
|
+
applyStrictSchemaDefault(config, settings);
|
|
136
|
+
validateModelConfig(config, modelConfig, settings.maxModel, minModel);
|
|
137
|
+
const promptConfig = buildPromptConfig(config);
|
|
138
|
+
const timeout = normalizeTimeout(config);
|
|
139
|
+
assertTestModeSafety(config, options);
|
|
140
|
+
return {
|
|
141
|
+
...config,
|
|
142
|
+
modelConfig,
|
|
143
|
+
promptConfig,
|
|
144
|
+
maxIterations: config.maxIterations || DEFAULT_MAX_ITERATIONS,
|
|
145
|
+
timeout,
|
|
146
|
+
staleDuration: config.staleDuration || DEFAULT_STALE_DURATION_MS,
|
|
147
|
+
enableLivenessCheck: config.enableLivenessCheck ?? DEFAULT_LIVENESS_CHECK_ENABLED,
|
|
148
|
+
};
|
|
257
149
|
}
|
|
258
|
-
|
|
259
150
|
module.exports = {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
151
|
+
validateAgentConfig,
|
|
152
|
+
DEFAULT_MAX_ITERATIONS,
|
|
153
|
+
DEFAULT_STALE_DURATION_MS,
|
|
154
|
+
DEFAULT_LIVENESS_CHECK_ENABLED,
|
|
264
155
|
};
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/** Agent configuration validation and defaults. */
|
|
2
|
+
|
|
3
|
+
import qualityGateSchema = require('./agent-quality-gate-schema');
|
|
4
|
+
import settingsFacade = require('./agent-config-settings');
|
|
5
|
+
|
|
6
|
+
type ModelLevel = 'level1' | 'level2' | 'level3';
|
|
7
|
+
type JsonSchemaType = 'array' | 'boolean' | 'integer' | 'number' | 'object' | 'string';
|
|
8
|
+
|
|
9
|
+
interface JsonSchema {
|
|
10
|
+
type?: JsonSchemaType;
|
|
11
|
+
description?: string;
|
|
12
|
+
enum?: string[];
|
|
13
|
+
items?: JsonSchema;
|
|
14
|
+
properties?: Record<string, JsonSchema>;
|
|
15
|
+
required?: string[];
|
|
16
|
+
anyOf?: JsonSchema[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface ModelRule extends Record<string, unknown> {
|
|
20
|
+
iterations?: unknown;
|
|
21
|
+
model?: string;
|
|
22
|
+
modelLevel?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface PromptRule extends Record<string, unknown> {}
|
|
26
|
+
|
|
27
|
+
interface PromptOptions extends Record<string, unknown> {
|
|
28
|
+
initial?: string;
|
|
29
|
+
subsequent?: string;
|
|
30
|
+
iterations?: PromptRule[];
|
|
31
|
+
system?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface AgentTrigger extends Record<string, unknown> {
|
|
35
|
+
action?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface AgentConfig extends Record<string, unknown> {
|
|
39
|
+
id: string;
|
|
40
|
+
outputFormat?: string;
|
|
41
|
+
structuredOutput?: JsonSchema;
|
|
42
|
+
jsonSchema?: JsonSchema;
|
|
43
|
+
modelRules?: ModelRule[];
|
|
44
|
+
model?: string;
|
|
45
|
+
modelLevel?: string;
|
|
46
|
+
strictSchema?: boolean;
|
|
47
|
+
prompt?: string | PromptOptions | null;
|
|
48
|
+
timeout?: number | string | null;
|
|
49
|
+
maxIterations?: number;
|
|
50
|
+
staleDuration?: number;
|
|
51
|
+
enableLivenessCheck?: boolean;
|
|
52
|
+
triggers?: AgentTrigger[];
|
|
53
|
+
role?: string;
|
|
54
|
+
requiredQualityGates?: unknown;
|
|
55
|
+
hooks?: {
|
|
56
|
+
onComplete?: {
|
|
57
|
+
config?: {
|
|
58
|
+
content?: {
|
|
59
|
+
data?: {
|
|
60
|
+
qualityGates?: unknown;
|
|
61
|
+
[key: string]: unknown;
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
interface AgentConfigOptions extends Record<string, unknown> {
|
|
70
|
+
mockSpawnFn?: unknown;
|
|
71
|
+
taskRunner?: unknown;
|
|
72
|
+
testMode?: boolean;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
type SettingsRecord = ReturnType<typeof settingsFacade.loadSettings>;
|
|
76
|
+
|
|
77
|
+
interface StaticModelConfig {
|
|
78
|
+
type: 'static';
|
|
79
|
+
model: string | null;
|
|
80
|
+
modelLevel: string | null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
interface RulesModelConfig {
|
|
84
|
+
type: 'rules';
|
|
85
|
+
rules: ModelRule[];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
type ModelConfig = StaticModelConfig | RulesModelConfig;
|
|
89
|
+
type PromptConfig =
|
|
90
|
+
| { type: 'static'; system: string }
|
|
91
|
+
| { type: 'rules'; rules: PromptRule[] }
|
|
92
|
+
| null;
|
|
93
|
+
|
|
94
|
+
type NormalizedAgentConfig = Omit<AgentConfig, 'timeout'> & {
|
|
95
|
+
modelConfig: ModelConfig;
|
|
96
|
+
promptConfig: PromptConfig;
|
|
97
|
+
maxIterations: number;
|
|
98
|
+
timeout: number;
|
|
99
|
+
staleDuration: number;
|
|
100
|
+
enableLivenessCheck: boolean;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const VALID_LEVELS: readonly ModelLevel[] = ['level1', 'level2', 'level3'];
|
|
104
|
+
const DEFAULT_MAX_ITERATIONS = 100;
|
|
105
|
+
const DEFAULT_TIMEOUT = 0;
|
|
106
|
+
const DEFAULT_STALE_DURATION_MS = 30 * 60 * 1000;
|
|
107
|
+
const DEFAULT_LIVENESS_CHECK_ENABLED = false;
|
|
108
|
+
|
|
109
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
110
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function isModelLevel(value: string): value is ModelLevel {
|
|
114
|
+
return value === 'level1' || value === 'level2' || value === 'level3';
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const { loadSettings, validateModelAgainstMax, VALID_MODELS } = settingsFacade;
|
|
118
|
+
const { applyValidatorQualityGateDefaults } = qualityGateSchema;
|
|
119
|
+
|
|
120
|
+
function applyOutputDefaults(config: AgentConfig): void {
|
|
121
|
+
if (!config.outputFormat) config.outputFormat = 'json';
|
|
122
|
+
if (config.structuredOutput && !config.jsonSchema) config.jsonSchema = config.structuredOutput;
|
|
123
|
+
if (config.outputFormat === 'json' && !config.jsonSchema) {
|
|
124
|
+
config.jsonSchema = {
|
|
125
|
+
type: 'object',
|
|
126
|
+
properties: {
|
|
127
|
+
summary: { type: 'string', description: 'Brief summary of what was done' },
|
|
128
|
+
result: { type: 'string', description: 'Detailed result or output' },
|
|
129
|
+
},
|
|
130
|
+
required: ['summary', 'result'],
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
applyValidatorQualityGateDefaults(config);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function buildModelConfig(config: AgentConfig): ModelConfig {
|
|
137
|
+
if (config.modelRules) return { type: 'rules', rules: config.modelRules };
|
|
138
|
+
return { type: 'static', model: config.model || null, modelLevel: config.modelLevel || null };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function applyStrictSchemaDefault(config: AgentConfig, settings: SettingsRecord): void {
|
|
142
|
+
if (config.strictSchema === undefined) config.strictSchema = settings.strictSchema !== false;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function errorMessage(error: unknown): unknown {
|
|
146
|
+
return isRecord(error) ? error.message : undefined;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function validateStaticModelConfig(
|
|
150
|
+
configId: string,
|
|
151
|
+
modelConfig: StaticModelConfig,
|
|
152
|
+
maxModel: string,
|
|
153
|
+
minModel: string | null
|
|
154
|
+
): void {
|
|
155
|
+
if (modelConfig.model && VALID_MODELS.includes(modelConfig.model)) {
|
|
156
|
+
try {
|
|
157
|
+
validateModelAgainstMax(modelConfig.model, maxModel, minModel);
|
|
158
|
+
} catch (error: unknown) {
|
|
159
|
+
throw new Error(`Agent "${configId}": ${String(errorMessage(error))}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (modelConfig.modelLevel && !isModelLevel(modelConfig.modelLevel)) {
|
|
163
|
+
throw new Error(
|
|
164
|
+
`Agent "${configId}": invalid modelLevel "${modelConfig.modelLevel}". Valid: ${VALID_LEVELS.join(', ')}`
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function validateModelRule(
|
|
170
|
+
configId: string,
|
|
171
|
+
rule: ModelRule,
|
|
172
|
+
maxModel: string,
|
|
173
|
+
minModel: string | null
|
|
174
|
+
): void {
|
|
175
|
+
if (rule.model && VALID_MODELS.includes(rule.model)) {
|
|
176
|
+
try {
|
|
177
|
+
validateModelAgainstMax(rule.model, maxModel, minModel);
|
|
178
|
+
} catch {
|
|
179
|
+
throw new Error(
|
|
180
|
+
`Agent "${configId}": modelRule "${String(rule.iterations)}" requests "${rule.model}" ` +
|
|
181
|
+
`but maxModel is "${maxModel}"${minModel ? ` and minModel is "${minModel}"` : ''}. ` +
|
|
182
|
+
`Either adjust the rule's model or change maxModel/minModel settings.`
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
if (rule.modelLevel && !isModelLevel(rule.modelLevel)) {
|
|
187
|
+
throw new Error(
|
|
188
|
+
`Agent "${configId}": modelRule "${String(rule.iterations)}" has invalid modelLevel ` +
|
|
189
|
+
`"${rule.modelLevel}". Valid: ${VALID_LEVELS.join(', ')}`
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function validateModelConfig(
|
|
195
|
+
config: AgentConfig,
|
|
196
|
+
modelConfig: ModelConfig,
|
|
197
|
+
maxModel: string,
|
|
198
|
+
minModel: string | null
|
|
199
|
+
): void {
|
|
200
|
+
if (modelConfig.type === 'static') {
|
|
201
|
+
validateStaticModelConfig(config.id, modelConfig, maxModel, minModel);
|
|
202
|
+
} else {
|
|
203
|
+
for (const rule of modelConfig.rules) validateModelRule(config.id, rule, maxModel, minModel);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function buildInitialPromptRules(prompt: PromptOptions): PromptRule[] | null {
|
|
208
|
+
if (!prompt.initial && !prompt.subsequent) return null;
|
|
209
|
+
const rules: PromptRule[] = [];
|
|
210
|
+
if (prompt.initial) rules.push({ match: '1', system: prompt.initial });
|
|
211
|
+
if (prompt.subsequent) rules.push({ match: '2+', system: prompt.subsequent });
|
|
212
|
+
return rules;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function buildPromptConfig(config: AgentConfig): PromptConfig {
|
|
216
|
+
const prompt = config.prompt;
|
|
217
|
+
if (prompt && typeof prompt !== 'string' && prompt.iterations) {
|
|
218
|
+
return { type: 'rules', rules: prompt.iterations };
|
|
219
|
+
}
|
|
220
|
+
if (prompt && typeof prompt !== 'string') {
|
|
221
|
+
const initialRules = buildInitialPromptRules(prompt);
|
|
222
|
+
if (initialRules) return { type: 'rules', rules: initialRules };
|
|
223
|
+
}
|
|
224
|
+
if (typeof prompt === 'string') return { type: 'static', system: prompt };
|
|
225
|
+
if (prompt?.system) return { type: 'static', system: prompt.system };
|
|
226
|
+
if (prompt) throw new Error(`Agent "${config.id}": invalid prompt format`);
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function normalizeTimeout(config: AgentConfig): number {
|
|
231
|
+
const timeout =
|
|
232
|
+
config.timeout === undefined || config.timeout === null || config.timeout === ''
|
|
233
|
+
? DEFAULT_TIMEOUT
|
|
234
|
+
: Number(config.timeout);
|
|
235
|
+
config.timeout = timeout;
|
|
236
|
+
if (!Number.isFinite(timeout) || timeout < 0) {
|
|
237
|
+
throw new Error(
|
|
238
|
+
`Agent "${config.id}": timeout must be a non-negative number (got ${timeout}).`
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
return timeout;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function assertTestModeSafety(config: AgentConfig, options: AgentConfigOptions): void {
|
|
245
|
+
const executesTask = config.triggers?.some(
|
|
246
|
+
(trigger) => !trigger.action || trigger.action === 'execute_task'
|
|
247
|
+
);
|
|
248
|
+
if (options.testMode && !options.mockSpawnFn && !options.taskRunner && executesTask) {
|
|
249
|
+
throw new Error(
|
|
250
|
+
`AgentWrapper: testMode=true but no mockSpawnFn/taskRunner provided for agent '${config.id}'. ` +
|
|
251
|
+
`This would cause real Claude API calls. ABORTING.`
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function validateAgentConfig(
|
|
257
|
+
config: AgentConfig,
|
|
258
|
+
options: AgentConfigOptions = {}
|
|
259
|
+
): NormalizedAgentConfig {
|
|
260
|
+
applyOutputDefaults(config);
|
|
261
|
+
const modelConfig = buildModelConfig(config);
|
|
262
|
+
const settings = loadSettings();
|
|
263
|
+
const minModel = settings.minModel || null;
|
|
264
|
+
applyStrictSchemaDefault(config, settings);
|
|
265
|
+
validateModelConfig(config, modelConfig, settings.maxModel, minModel);
|
|
266
|
+
const promptConfig = buildPromptConfig(config);
|
|
267
|
+
const timeout = normalizeTimeout(config);
|
|
268
|
+
assertTestModeSafety(config, options);
|
|
269
|
+
return {
|
|
270
|
+
...config,
|
|
271
|
+
modelConfig,
|
|
272
|
+
promptConfig,
|
|
273
|
+
maxIterations: config.maxIterations || DEFAULT_MAX_ITERATIONS,
|
|
274
|
+
timeout,
|
|
275
|
+
staleDuration: config.staleDuration || DEFAULT_STALE_DURATION_MS,
|
|
276
|
+
enableLivenessCheck: config.enableLivenessCheck ?? DEFAULT_LIVENESS_CHECK_ENABLED,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export = {
|
|
281
|
+
validateAgentConfig,
|
|
282
|
+
DEFAULT_MAX_ITERATIONS,
|
|
283
|
+
DEFAULT_STALE_DURATION_MS,
|
|
284
|
+
DEFAULT_LIVENESS_CHECK_ENABLED,
|
|
285
|
+
};
|