@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,82 +1,39 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
* - Rate limits: 30s base, exponential backoff up to 5 minutes
|
|
9
|
-
* - Retry-After header: Honored if present (capped at 5 min)
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Check if error is a rate limit error
|
|
14
|
-
* @param {Error|string} error - Error object or message
|
|
15
|
-
* @returns {boolean} True if this is a rate limit error
|
|
16
|
-
*/
|
|
1
|
+
"use strict";
|
|
2
|
+
const crypto = require("node:crypto");
|
|
3
|
+
function sampleJitter() {
|
|
4
|
+
const range = 0x1_0000_0000;
|
|
5
|
+
return crypto.randomInt(range) / range;
|
|
6
|
+
}
|
|
7
|
+
/** Check if an error represents a rate limit. */
|
|
17
8
|
function isRateLimitError(error) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
msg
|
|
21
|
-
);
|
|
9
|
+
const msg = error instanceof Error ? error.message || String(error) : String(error);
|
|
10
|
+
return /\b429\b|rate.?limit|too many requests|no capacity|quota.?exceeded|resource.?exhausted/i.test(msg);
|
|
22
11
|
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Parse Retry-After from error message
|
|
26
|
-
* Looks for patterns like "Retry-After: 120" or "retry after 120 seconds"
|
|
27
|
-
* @param {Error} error - Error object
|
|
28
|
-
* @returns {number|null} Seconds to wait, or null if not found
|
|
29
|
-
*/
|
|
12
|
+
/** Parse a Retry-After delay in seconds from an error message. */
|
|
30
13
|
function parseRetryAfter(error) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
14
|
+
const msg = error?.message || '';
|
|
15
|
+
const match = /retry.?after[:\s]+(\d+)/i.exec(msg);
|
|
16
|
+
const retryAfterSeconds = match?.[1];
|
|
17
|
+
return retryAfterSeconds ? parseInt(retryAfterSeconds, 10) : null;
|
|
35
18
|
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Calculate delay for retry with rate-limit awareness
|
|
39
|
-
*
|
|
40
|
-
* Rate limit errors get 30s base delay instead of 2s.
|
|
41
|
-
* Regular errors use exponential backoff from 2s base.
|
|
42
|
-
*
|
|
43
|
-
* @param {Error} error - The error that occurred
|
|
44
|
-
* @param {number} attempt - Current attempt number (1-based)
|
|
45
|
-
* @param {Object} settings - Settings with backoff config
|
|
46
|
-
* @param {number} [settings.backoffBaseMs=2000] - Base delay for regular errors
|
|
47
|
-
* @param {number} [settings.backoffMaxMs=30000] - Max delay for regular errors
|
|
48
|
-
* @param {number} [settings.jitterFactor=0.2] - Jitter factor (±20%)
|
|
49
|
-
* @returns {number} Delay in milliseconds
|
|
50
|
-
*/
|
|
19
|
+
/** Calculate a retry delay with rate-limit awareness. */
|
|
51
20
|
function calculateRateLimitDelay(error, attempt, settings = {}) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const effectiveBase = isRateLimit ? 30000 : baseDelay;
|
|
66
|
-
|
|
67
|
-
// Exponential: base * 2^(attempt-1)
|
|
68
|
-
let delay = effectiveBase * Math.pow(2, attempt - 1);
|
|
69
|
-
|
|
70
|
-
// Cap at appropriate max (5 min for rate limits, settings max for others)
|
|
71
|
-
delay = Math.min(delay, isRateLimit ? 300000 : maxDelay);
|
|
72
|
-
|
|
73
|
-
// Add jitter (±jitterFactor)
|
|
74
|
-
const jitterAmount = delay * jitter * (Math.random() * 2 - 1);
|
|
75
|
-
return Math.round(delay + jitterAmount);
|
|
21
|
+
const baseDelay = settings.backoffBaseMs ?? 2000;
|
|
22
|
+
const maxDelay = settings.backoffMaxMs ?? 30000;
|
|
23
|
+
const jitter = settings.jitterFactor ?? 0.2;
|
|
24
|
+
const retryAfter = parseRetryAfter(error);
|
|
25
|
+
if (retryAfter) {
|
|
26
|
+
return Math.min(retryAfter * 1000, 300000);
|
|
27
|
+
}
|
|
28
|
+
const isRateLimit = isRateLimitError(error);
|
|
29
|
+
const effectiveBase = isRateLimit ? 30000 : baseDelay;
|
|
30
|
+
let delay = effectiveBase * Math.pow(2, attempt - 1);
|
|
31
|
+
delay = Math.min(delay, isRateLimit ? 300000 : maxDelay);
|
|
32
|
+
const jitterAmount = delay * jitter * (sampleJitter() * 2 - 1);
|
|
33
|
+
return Math.round(delay + jitterAmount);
|
|
76
34
|
}
|
|
77
|
-
|
|
78
35
|
module.exports = {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
36
|
+
calculateRateLimitDelay,
|
|
37
|
+
isRateLimitError,
|
|
38
|
+
parseRetryAfter,
|
|
82
39
|
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import crypto = require('node:crypto');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Rate-limit-aware backoff for API retries
|
|
5
|
+
*
|
|
6
|
+
* Rate limit errors (429, capacity exhausted, quota exceeded) need LONGER delays
|
|
7
|
+
* than transient errors (timeouts, network issues).
|
|
8
|
+
*
|
|
9
|
+
* - Regular errors: 2s base, exponential backoff up to 30s
|
|
10
|
+
* - Rate limits: 30s base, exponential backoff up to 5 minutes
|
|
11
|
+
* - Retry-After header: Honored if present (capped at 5 min)
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
type RateLimitError = Error | string | null | undefined;
|
|
15
|
+
|
|
16
|
+
interface BackoffSettings {
|
|
17
|
+
backoffBaseMs?: number;
|
|
18
|
+
backoffMaxMs?: number;
|
|
19
|
+
jitterFactor?: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function sampleJitter(): number {
|
|
23
|
+
const range = 0x1_0000_0000;
|
|
24
|
+
return crypto.randomInt(range) / range;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Check if an error represents a rate limit. */
|
|
28
|
+
function isRateLimitError(error: RateLimitError): boolean {
|
|
29
|
+
const msg = error instanceof Error ? error.message || String(error) : String(error);
|
|
30
|
+
return /\b429\b|rate.?limit|too many requests|no capacity|quota.?exceeded|resource.?exhausted/i.test(
|
|
31
|
+
msg
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Parse a Retry-After delay in seconds from an error message. */
|
|
36
|
+
function parseRetryAfter(error: Error | null | undefined): number | null {
|
|
37
|
+
const msg = error?.message || '';
|
|
38
|
+
const match = /retry.?after[:\s]+(\d+)/i.exec(msg);
|
|
39
|
+
const retryAfterSeconds = match?.[1];
|
|
40
|
+
return retryAfterSeconds ? parseInt(retryAfterSeconds, 10) : null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Calculate a retry delay with rate-limit awareness. */
|
|
44
|
+
function calculateRateLimitDelay(
|
|
45
|
+
error: Error,
|
|
46
|
+
attempt: number,
|
|
47
|
+
settings: BackoffSettings = {}
|
|
48
|
+
): number {
|
|
49
|
+
const baseDelay = settings.backoffBaseMs ?? 2000;
|
|
50
|
+
const maxDelay = settings.backoffMaxMs ?? 30000;
|
|
51
|
+
const jitter = settings.jitterFactor ?? 0.2;
|
|
52
|
+
|
|
53
|
+
const retryAfter = parseRetryAfter(error);
|
|
54
|
+
if (retryAfter) {
|
|
55
|
+
return Math.min(retryAfter * 1000, 300000);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const isRateLimit = isRateLimitError(error);
|
|
59
|
+
const effectiveBase = isRateLimit ? 30000 : baseDelay;
|
|
60
|
+
let delay = effectiveBase * Math.pow(2, attempt - 1);
|
|
61
|
+
delay = Math.min(delay, isRateLimit ? 300000 : maxDelay);
|
|
62
|
+
|
|
63
|
+
const jitterAmount = delay * jitter * (sampleJitter() * 2 - 1);
|
|
64
|
+
return Math.round(delay + jitterAmount);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export = {
|
|
68
|
+
calculateRateLimitDelay,
|
|
69
|
+
isRateLimitError,
|
|
70
|
+
parseRetryAfter,
|
|
71
|
+
};
|
|
@@ -1,146 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Schema utilities for normalizing LLM output before validation.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* SOLUTION: Normalize enum values BEFORE validation. Provider-agnostic.
|
|
5
|
+
* LLMs may return enum values that do not exactly match the schema. Normalize
|
|
6
|
+
* those values before validation without depending on a specific provider.
|
|
8
7
|
*/
|
|
9
|
-
|
|
10
8
|
const ENUM_VARIATIONS = {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
HIGH_RISK: 'CRITICAL',
|
|
39
|
-
DANGEROUS: 'CRITICAL',
|
|
9
|
+
BUG: 'DEBUG',
|
|
10
|
+
FIX: 'DEBUG',
|
|
11
|
+
BUGFIX: 'DEBUG',
|
|
12
|
+
BUG_FIX: 'DEBUG',
|
|
13
|
+
INVESTIGATE: 'DEBUG',
|
|
14
|
+
TROUBLESHOOT: 'DEBUG',
|
|
15
|
+
IMPLEMENT: 'TASK',
|
|
16
|
+
BUILD: 'TASK',
|
|
17
|
+
CREATE: 'TASK',
|
|
18
|
+
ADD: 'TASK',
|
|
19
|
+
FEATURE: 'TASK',
|
|
20
|
+
QUESTION: 'INQUIRY',
|
|
21
|
+
ASK: 'INQUIRY',
|
|
22
|
+
EXPLORE: 'INQUIRY',
|
|
23
|
+
RESEARCH: 'INQUIRY',
|
|
24
|
+
UNDERSTAND: 'INQUIRY',
|
|
25
|
+
EASY: 'TRIVIAL',
|
|
26
|
+
BASIC: 'SIMPLE',
|
|
27
|
+
MINOR: 'SIMPLE',
|
|
28
|
+
MODERATE: 'STANDARD',
|
|
29
|
+
MEDIUM: 'STANDARD',
|
|
30
|
+
NORMAL: 'STANDARD',
|
|
31
|
+
HARD: 'STANDARD',
|
|
32
|
+
COMPLEX: 'CRITICAL',
|
|
33
|
+
RISKY: 'CRITICAL',
|
|
34
|
+
HIGH_RISK: 'CRITICAL',
|
|
35
|
+
DANGEROUS: 'CRITICAL',
|
|
40
36
|
};
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
* Handles:
|
|
46
|
-
* - Case mismatches: "simple" → "SIMPLE"
|
|
47
|
-
* - Whitespace: " SIMPLE " → "SIMPLE"
|
|
48
|
-
* - Common variations: "bug" → "DEBUG", "fix" → "DEBUG"
|
|
49
|
-
*
|
|
50
|
-
* @param {Object} result - Parsed JSON result from LLM
|
|
51
|
-
* @param {Object} schema - JSON schema with enum definitions
|
|
52
|
-
* @returns {Object} Normalized result (mutates and returns same object)
|
|
53
|
-
*/
|
|
37
|
+
function isObjectRecord(value) {
|
|
38
|
+
return typeof value === 'object' && value !== null;
|
|
39
|
+
}
|
|
40
|
+
/** Normalize enum values in parsed JSON, mutating and returning the same value. */
|
|
54
41
|
function normalizeEnumValues(result, schema) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
});
|
|
65
|
-
if (matched) {
|
|
66
|
-
continue;
|
|
42
|
+
if (!isObjectRecord(result) || !schema?.properties) {
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
46
|
+
const matched = normalizeEnumValue({ result, key, propSchema });
|
|
47
|
+
if (matched) {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
normalizeNestedValues(result, propSchema, key);
|
|
67
51
|
}
|
|
68
|
-
|
|
69
|
-
// Recursively handle nested objects
|
|
70
|
-
normalizeNestedValues(result, propSchema, key);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return result;
|
|
52
|
+
return result;
|
|
74
53
|
}
|
|
75
|
-
|
|
76
54
|
function normalizeEnumValue({ result, key, propSchema }) {
|
|
77
|
-
|
|
55
|
+
const rawValue = result[key];
|
|
56
|
+
const enumValues = propSchema.enum;
|
|
57
|
+
if (!enumValues || typeof rawValue !== 'string') {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
let value = rawValue.trim().toUpperCase();
|
|
61
|
+
value = normalizeEnumCopyValue(value, enumValues, key, rawValue);
|
|
62
|
+
const match = findEnumMatch(enumValues, value);
|
|
63
|
+
if (match) {
|
|
64
|
+
result[key] = match;
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
const variation = ENUM_VARIATIONS[value];
|
|
68
|
+
if (variation && enumValues.includes(variation)) {
|
|
69
|
+
result[key] = variation;
|
|
70
|
+
}
|
|
78
71
|
return false;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const rawValue = result[key];
|
|
82
|
-
let value = rawValue.trim().toUpperCase();
|
|
83
|
-
value = normalizeEnumCopyValue(value, propSchema.enum, key, rawValue);
|
|
84
|
-
|
|
85
|
-
// Find exact match (case-insensitive)
|
|
86
|
-
const match = findEnumMatch(propSchema.enum, value);
|
|
87
|
-
if (match) {
|
|
88
|
-
result[key] = match;
|
|
89
|
-
return true;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Common variations mapping
|
|
93
|
-
const variation = ENUM_VARIATIONS[value];
|
|
94
|
-
if (variation && propSchema.enum.includes(variation)) {
|
|
95
|
-
result[key] = variation;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return false;
|
|
99
72
|
}
|
|
100
|
-
|
|
101
73
|
function normalizeEnumCopyValue(value, enumValues, key, rawValue) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if (!firstValid) {
|
|
117
|
-
return value;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
console.warn(
|
|
121
|
-
`⚠️ Model copied enum format instead of choosing. Field "${key}" had "${rawValue}", using "${firstValid}"`
|
|
122
|
-
);
|
|
123
|
-
return firstValid;
|
|
74
|
+
if (!value.includes('|')) {
|
|
75
|
+
return value;
|
|
76
|
+
}
|
|
77
|
+
const parts = value.split('|').map((part) => part.trim());
|
|
78
|
+
const matchCount = parts.filter((part) => enumValues.includes(part)).length;
|
|
79
|
+
if (matchCount < 2) {
|
|
80
|
+
return value;
|
|
81
|
+
}
|
|
82
|
+
const firstValid = parts.find((part) => enumValues.includes(part));
|
|
83
|
+
if (!firstValid) {
|
|
84
|
+
return value;
|
|
85
|
+
}
|
|
86
|
+
console.warn(`⚠️ Model copied enum format instead of choosing. Field "${key}" had "${rawValue}", using "${firstValid}"`);
|
|
87
|
+
return firstValid;
|
|
124
88
|
}
|
|
125
|
-
|
|
126
89
|
function findEnumMatch(enumValues, value) {
|
|
127
|
-
|
|
90
|
+
return enumValues.find((entry) => entry.toUpperCase() === value);
|
|
128
91
|
}
|
|
129
|
-
|
|
130
92
|
function normalizeNestedValues(result, propSchema, key) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
93
|
+
const value = result[key];
|
|
94
|
+
if (propSchema.type === 'object' && propSchema.properties && value) {
|
|
95
|
+
normalizeEnumValues(value, propSchema);
|
|
96
|
+
}
|
|
97
|
+
const itemSchema = propSchema.items;
|
|
98
|
+
if (propSchema.type === 'array' && itemSchema?.properties && Array.isArray(value)) {
|
|
99
|
+
for (const item of value) {
|
|
100
|
+
normalizeEnumValues(item, itemSchema);
|
|
101
|
+
}
|
|
140
102
|
}
|
|
141
|
-
}
|
|
142
103
|
}
|
|
143
|
-
|
|
144
104
|
module.exports = {
|
|
145
|
-
|
|
105
|
+
normalizeEnumValues,
|
|
146
106
|
};
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema utilities for normalizing LLM output before validation.
|
|
3
|
+
*
|
|
4
|
+
* LLMs may return enum values that do not exactly match the schema. Normalize
|
|
5
|
+
* those values before validation without depending on a specific provider.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
interface EnumSchema {
|
|
9
|
+
type?: string;
|
|
10
|
+
enum?: string[];
|
|
11
|
+
properties?: Record<string, EnumSchema>;
|
|
12
|
+
items?: EnumSchema;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface NormalizeEnumOptions {
|
|
16
|
+
result: Record<string, unknown>;
|
|
17
|
+
key: string;
|
|
18
|
+
propSchema: EnumSchema;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const ENUM_VARIATIONS: Readonly<Record<string, string>> = {
|
|
22
|
+
BUG: 'DEBUG',
|
|
23
|
+
FIX: 'DEBUG',
|
|
24
|
+
BUGFIX: 'DEBUG',
|
|
25
|
+
BUG_FIX: 'DEBUG',
|
|
26
|
+
INVESTIGATE: 'DEBUG',
|
|
27
|
+
TROUBLESHOOT: 'DEBUG',
|
|
28
|
+
IMPLEMENT: 'TASK',
|
|
29
|
+
BUILD: 'TASK',
|
|
30
|
+
CREATE: 'TASK',
|
|
31
|
+
ADD: 'TASK',
|
|
32
|
+
FEATURE: 'TASK',
|
|
33
|
+
QUESTION: 'INQUIRY',
|
|
34
|
+
ASK: 'INQUIRY',
|
|
35
|
+
EXPLORE: 'INQUIRY',
|
|
36
|
+
RESEARCH: 'INQUIRY',
|
|
37
|
+
UNDERSTAND: 'INQUIRY',
|
|
38
|
+
EASY: 'TRIVIAL',
|
|
39
|
+
BASIC: 'SIMPLE',
|
|
40
|
+
MINOR: 'SIMPLE',
|
|
41
|
+
MODERATE: 'STANDARD',
|
|
42
|
+
MEDIUM: 'STANDARD',
|
|
43
|
+
NORMAL: 'STANDARD',
|
|
44
|
+
HARD: 'STANDARD',
|
|
45
|
+
COMPLEX: 'CRITICAL',
|
|
46
|
+
RISKY: 'CRITICAL',
|
|
47
|
+
HIGH_RISK: 'CRITICAL',
|
|
48
|
+
DANGEROUS: 'CRITICAL',
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
function isObjectRecord(value: unknown): value is Record<string, unknown> {
|
|
52
|
+
return typeof value === 'object' && value !== null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Normalize enum values in parsed JSON, mutating and returning the same value. */
|
|
56
|
+
function normalizeEnumValues(result: unknown, schema: EnumSchema | null | undefined): unknown {
|
|
57
|
+
if (!isObjectRecord(result) || !schema?.properties) {
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
62
|
+
const matched = normalizeEnumValue({ result, key, propSchema });
|
|
63
|
+
if (matched) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
normalizeNestedValues(result, propSchema, key);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function normalizeEnumValue({ result, key, propSchema }: NormalizeEnumOptions): boolean {
|
|
74
|
+
const rawValue = result[key];
|
|
75
|
+
const enumValues = propSchema.enum;
|
|
76
|
+
if (!enumValues || typeof rawValue !== 'string') {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
let value = rawValue.trim().toUpperCase();
|
|
81
|
+
value = normalizeEnumCopyValue(value, enumValues, key, rawValue);
|
|
82
|
+
|
|
83
|
+
const match = findEnumMatch(enumValues, value);
|
|
84
|
+
if (match) {
|
|
85
|
+
result[key] = match;
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const variation = ENUM_VARIATIONS[value];
|
|
90
|
+
if (variation && enumValues.includes(variation)) {
|
|
91
|
+
result[key] = variation;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function normalizeEnumCopyValue(
|
|
98
|
+
value: string,
|
|
99
|
+
enumValues: string[],
|
|
100
|
+
key: string,
|
|
101
|
+
rawValue: string
|
|
102
|
+
): string {
|
|
103
|
+
if (!value.includes('|')) {
|
|
104
|
+
return value;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const parts = value.split('|').map((part) => part.trim());
|
|
108
|
+
const matchCount = parts.filter((part) => enumValues.includes(part)).length;
|
|
109
|
+
if (matchCount < 2) {
|
|
110
|
+
return value;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const firstValid = parts.find((part) => enumValues.includes(part));
|
|
114
|
+
if (!firstValid) {
|
|
115
|
+
return value;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
console.warn(
|
|
119
|
+
`⚠️ Model copied enum format instead of choosing. Field "${key}" had "${rawValue}", using "${firstValid}"`
|
|
120
|
+
);
|
|
121
|
+
return firstValid;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function findEnumMatch(enumValues: string[], value: string): string | undefined {
|
|
125
|
+
return enumValues.find((entry) => entry.toUpperCase() === value);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function normalizeNestedValues(
|
|
129
|
+
result: Record<string, unknown>,
|
|
130
|
+
propSchema: EnumSchema,
|
|
131
|
+
key: string
|
|
132
|
+
): void {
|
|
133
|
+
const value = result[key];
|
|
134
|
+
if (propSchema.type === 'object' && propSchema.properties && value) {
|
|
135
|
+
normalizeEnumValues(value, propSchema);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const itemSchema = propSchema.items;
|
|
139
|
+
if (propSchema.type === 'array' && itemSchema?.properties && Array.isArray(value)) {
|
|
140
|
+
for (const item of value) {
|
|
141
|
+
normalizeEnumValues(item, itemSchema);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export = {
|
|
147
|
+
normalizeEnumValues,
|
|
148
|
+
};
|
|
@@ -1,42 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
const STRUCTURED_OUTPUT_INVALID_CODE = 'STRUCTURED_OUTPUT_INVALID';
|
|
2
|
-
|
|
3
3
|
function createStructuredOutputInvalidError(message, kind, validation = null, recovery = null) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
4
|
+
const properties = {
|
|
5
|
+
code: STRUCTURED_OUTPUT_INVALID_CODE,
|
|
6
|
+
details: {
|
|
7
|
+
kind,
|
|
8
|
+
validationError: validation?.error ?? null,
|
|
9
|
+
recoveryAttempts: recovery?.status === 'exhausted' ? recovery.attempts : 0,
|
|
10
|
+
recoveryError: recovery?.status === 'exhausted' ? recovery.lastError : null,
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
return Object.assign(new Error(message), properties);
|
|
13
14
|
}
|
|
14
|
-
|
|
15
15
|
function isStructuredOutputInvalidError(error) {
|
|
16
|
-
|
|
16
|
+
if ((typeof error !== 'object' || error === null) && typeof error !== 'function') {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
return 'code' in error && error.code === STRUCTURED_OUTPUT_INVALID_CODE;
|
|
17
20
|
}
|
|
18
|
-
|
|
19
21
|
function buildStructuredOutputClusterFailure(agent, error) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
22
|
+
return {
|
|
23
|
+
topic: 'CLUSTER_FAILED',
|
|
24
|
+
receiver: 'broadcast',
|
|
25
|
+
content: {
|
|
26
|
+
text: `Cluster failed: structured output is invalid for ${agent.id} - ${error.message}`,
|
|
27
|
+
data: {
|
|
28
|
+
reason: 'structured_output_invalid',
|
|
29
|
+
agentId: agent.id,
|
|
30
|
+
role: agent.role,
|
|
31
|
+
code: error.code,
|
|
32
|
+
details: error.details ?? null,
|
|
33
|
+
error: error.message,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
};
|
|
35
37
|
}
|
|
36
|
-
|
|
37
38
|
module.exports = {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
STRUCTURED_OUTPUT_INVALID_CODE,
|
|
40
|
+
createStructuredOutputInvalidError,
|
|
41
|
+
isStructuredOutputInvalidError,
|
|
42
|
+
buildStructuredOutputClusterFailure,
|
|
42
43
|
};
|