@velum-labs/routekit-eval-setup 1.4.0 → 1.5.1
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/dist/adapters/authoring-responses-request.d.ts +5 -0
- package/dist/adapters/authoring-responses-request.js +38 -0
- package/dist/adapters/evaluation-evidence-freshness.d.ts +7 -0
- package/dist/adapters/evaluation-evidence-freshness.js +76 -0
- package/dist/adapters/git-task-history.d.ts +67 -0
- package/dist/adapters/git-task-history.js +171 -0
- package/dist/adapters/integrated-repository-history.d.ts +21 -0
- package/dist/adapters/integrated-repository-history.js +175 -0
- package/dist/adapters/repository-command-diagnostic.d.ts +8 -0
- package/dist/adapters/repository-command-diagnostic.js +46 -0
- package/dist/adapters/repository-command-evidence.d.ts +13 -0
- package/dist/adapters/repository-command-evidence.js +102 -0
- package/dist/adapters/repository-command-runner.d.ts +238 -0
- package/dist/adapters/repository-command-runner.js +1483 -0
- package/dist/adapters/repository-import-context.d.ts +47 -0
- package/dist/adapters/repository-import-context.js +469 -0
- package/dist/adapters/repository-node-test-reporter.d.ts +3 -0
- package/dist/adapters/repository-node-test-reporter.js +27 -0
- package/dist/adapters/repository-review-evidence.d.ts +39 -0
- package/dist/adapters/repository-review-evidence.js +632 -0
- package/dist/adapters/repository-seed-selection.d.ts +7 -0
- package/dist/adapters/repository-seed-selection.js +79 -0
- package/dist/adapters/repository-solution-edits.d.ts +49 -0
- package/dist/adapters/repository-solution-edits.js +136 -0
- package/dist/adapters/repository-vitest-phase-adapter.d.ts +8 -0
- package/dist/adapters/repository-vitest-phase-adapter.js +310 -0
- package/dist/adapters/repository-vitest-reporter.d.ts +24 -0
- package/dist/adapters/repository-vitest-reporter.js +314 -0
- package/dist/adapters/strict-authoring-schema.d.ts +5 -0
- package/dist/adapters/strict-authoring-schema.js +158 -0
- package/dist/adapters/test-discovery.d.ts +30 -0
- package/dist/adapters/test-discovery.js +124 -0
- package/dist/adapters/typescript-repository-index.d.ts +51 -0
- package/dist/adapters/typescript-repository-index.js +226 -0
- package/dist/agentic-capabilities-protocol.d.ts +1373 -0
- package/dist/agentic-capabilities-protocol.js +786 -0
- package/dist/case-checkpoint-store.d.ts +29 -0
- package/dist/case-checkpoint-store.js +133 -0
- package/dist/case-pipeline-protocol-v2.d.ts +184 -0
- package/dist/case-pipeline-protocol-v2.js +193 -0
- package/dist/case-pipeline-protocol.d.ts +2626 -0
- package/dist/case-pipeline-protocol.js +371 -0
- package/dist/effect-api.d.ts +74 -12
- package/dist/effect-api.js +56 -7
- package/dist/errors.d.ts +31 -0
- package/dist/errors.js +10 -0
- package/dist/eval-capability-execution-envelope.d.ts +64 -0
- package/dist/eval-capability-execution-envelope.js +98 -0
- package/dist/eval-capability-policy.d.ts +90 -0
- package/dist/eval-capability-policy.js +107 -0
- package/dist/eval-event-log.d.ts +51 -0
- package/dist/eval-event-log.js +69 -10
- package/dist/evaluation-authoring-policy.d.ts +18 -0
- package/dist/evaluation-authoring-policy.js +19 -0
- package/dist/evaluation-authoring-validation.d.ts +22 -0
- package/dist/evaluation-authoring-validation.js +72 -0
- package/dist/evaluation-evidence.d.ts +20 -0
- package/dist/evaluation-evidence.js +319 -0
- package/dist/evaluation-grader-calibration-protocol.d.ts +108 -0
- package/dist/evaluation-grader-calibration-protocol.js +80 -0
- package/dist/evaluation-grader-calibration.d.ts +18 -0
- package/dist/evaluation-grader-calibration.js +334 -0
- package/dist/evaluation-grading-policy.d.ts +24 -0
- package/dist/evaluation-grading-policy.js +54 -0
- package/dist/evaluation-proposal-policy.d.ts +4 -0
- package/dist/evaluation-proposal-policy.js +91 -0
- package/dist/evaluation-source-retrieval.d.ts +68 -0
- package/dist/evaluation-source-retrieval.js +513 -0
- package/dist/evaluation-structure-policy.d.ts +29 -0
- package/dist/evaluation-structure-policy.js +138 -0
- package/dist/index.d.ts +124 -19
- package/dist/index.js +69 -12
- package/dist/inspection.js +2 -3
- package/dist/project-artifacts.d.ts +2 -2
- package/dist/project-artifacts.js +26 -121
- package/dist/project-authoring.d.ts +66 -5
- package/dist/project-authoring.js +783 -109
- package/dist/project-contracts.d.ts +292 -82
- package/dist/project-contracts.js +65 -7
- package/dist/project-store.js +2 -1
- package/dist/project-workflow.d.ts +3 -3
- package/dist/project-workflow.js +116 -18
- package/dist/repository-adversary-protocol.d.ts +64 -0
- package/dist/repository-adversary-protocol.js +105 -0
- package/dist/repository-behavior-protocol.d.ts +188 -0
- package/dist/repository-behavior-protocol.js +202 -0
- package/dist/repository-benchmark-protocol.d.ts +487 -0
- package/dist/repository-benchmark-protocol.js +96 -0
- package/dist/repository-execution-protocol.d.ts +150 -0
- package/dist/repository-execution-protocol.js +38 -0
- package/dist/repository-fixture-instructions.d.ts +3 -0
- package/dist/repository-fixture-instructions.js +91 -0
- package/dist/repository-fixture-protocol.d.ts +79 -0
- package/dist/repository-fixture-protocol.js +79 -0
- package/dist/repository-foundry-plan-protocol.d.ts +118 -0
- package/dist/repository-foundry-plan-protocol.js +296 -0
- package/dist/repository-foundry-progress-protocol.d.ts +52 -0
- package/dist/repository-foundry-progress-protocol.js +52 -0
- package/dist/repository-improvement-protocol.d.ts +100 -0
- package/dist/repository-improvement-protocol.js +106 -0
- package/dist/repository-language-model-protocol.d.ts +43 -0
- package/dist/repository-language-model-protocol.js +146 -0
- package/dist/repository-oracle-coverage-protocol.d.ts +18 -0
- package/dist/repository-oracle-coverage-protocol.js +39 -0
- package/dist/repository-oracle-execution-binding.d.ts +27 -0
- package/dist/repository-oracle-execution-binding.js +59 -0
- package/dist/repository-oracle-protocol.d.ts +230 -0
- package/dist/repository-oracle-protocol.js +156 -0
- package/dist/repository-oracle-scope-policy.d.ts +22 -0
- package/dist/repository-oracle-scope-policy.js +92 -0
- package/dist/repository-quality-policy.d.ts +15 -0
- package/dist/repository-quality-policy.js +357 -0
- package/dist/repository-routing-benchmark-protocol.d.ts +176 -0
- package/dist/repository-routing-benchmark-protocol.js +103 -0
- package/dist/repository-routing-model-protocol.d.ts +36 -0
- package/dist/repository-routing-model-protocol.js +89 -0
- package/dist/repository-routing-plan-protocol.d.ts +112 -0
- package/dist/repository-routing-plan-protocol.js +58 -0
- package/dist/repository-routing-quality-policy.d.ts +9 -0
- package/dist/repository-routing-quality-policy.js +191 -0
- package/dist/repository-seed-qualification-progress-protocol.d.ts +205 -0
- package/dist/repository-seed-qualification-progress-protocol.js +28 -0
- package/dist/repository-semantic-calibration-protocol.d.ts +768 -0
- package/dist/repository-semantic-calibration-protocol.js +276 -0
- package/dist/repository-semantic-calibration.d.ts +163 -0
- package/dist/repository-semantic-calibration.js +581 -0
- package/dist/repository-specification-contract-facts-protocol.d.ts +224 -0
- package/dist/repository-specification-contract-facts-protocol.js +276 -0
- package/dist/repository-specification-critique-protocol.d.ts +189 -0
- package/dist/repository-specification-critique-protocol.js +103 -0
- package/dist/repository-task-family-protocol.d.ts +24 -0
- package/dist/repository-task-family-protocol.js +37 -0
- package/dist/repository-task-seed-protocol.d.ts +384 -0
- package/dist/repository-task-seed-protocol.js +236 -0
- package/dist/repository-trajectory-protocol.d.ts +20 -0
- package/dist/repository-trajectory-protocol.js +42 -0
- package/dist/service.js +1 -1
- package/dist/services/adversary/service.d.ts +64 -0
- package/dist/services/adversary/service.js +330 -0
- package/dist/services/benchmark-compiler/service.d.ts +450 -0
- package/dist/services/benchmark-compiler/service.js +9 -0
- package/dist/services/budgeted-model/service.d.ts +118 -0
- package/dist/services/budgeted-model/service.js +460 -0
- package/dist/services/case-authoring/service.d.ts +163 -0
- package/dist/services/case-authoring/service.js +1456 -0
- package/dist/services/case-finalization/service.d.ts +283 -0
- package/dist/services/case-finalization/service.js +370 -0
- package/dist/services/case-generation/service.d.ts +619 -0
- package/dist/services/case-generation/service.js +2628 -0
- package/dist/services/case-pipeline/service.d.ts +31 -0
- package/dist/services/case-pipeline/service.js +485 -0
- package/dist/services/case-pipeline-v2/service.d.ts +70 -0
- package/dist/services/case-pipeline-v2/service.js +477 -0
- package/dist/services/command-observability/service.d.ts +13 -0
- package/dist/services/command-observability/service.js +3 -0
- package/dist/services/dimension-labeling/service.d.ts +77 -0
- package/dist/services/dimension-labeling/service.js +188 -0
- package/dist/services/eval-candidate/service.d.ts +208 -0
- package/dist/services/eval-candidate/service.js +64 -0
- package/dist/services/eval-capabilities/service.d.ts +183 -0
- package/dist/services/eval-capabilities/service.js +1433 -0
- package/dist/services/eval-environment/service.d.ts +173 -0
- package/dist/services/eval-environment/service.js +127 -0
- package/dist/services/evidence-reconstruction/service.d.ts +36 -0
- package/dist/services/evidence-reconstruction/service.js +145 -0
- package/dist/services/fixture-builder/service.d.ts +62 -0
- package/dist/services/fixture-builder/service.js +36 -0
- package/dist/services/fixture-validation/service.d.ts +75 -0
- package/dist/services/fixture-validation/service.js +295 -0
- package/dist/services/foundry/service.d.ts +831 -0
- package/dist/services/foundry/service.js +442 -0
- package/dist/services/foundry-progress/service.d.ts +62 -0
- package/dist/services/foundry-progress/service.js +149 -0
- package/dist/services/foundry-v2/service.d.ts +54 -0
- package/dist/services/foundry-v2/service.js +28 -0
- package/dist/services/grounded-authoring/service.d.ts +126 -0
- package/dist/services/grounded-authoring/service.js +822 -0
- package/dist/services/historical-case/service.d.ts +722 -0
- package/dist/services/historical-case/service.js +177 -0
- package/dist/services/improvement-loop/service.d.ts +59 -0
- package/dist/services/improvement-loop/service.js +176 -0
- package/dist/services/language-model/service.d.ts +52 -0
- package/dist/services/language-model/service.js +194 -0
- package/dist/services/oracle-builder/service.d.ts +146 -0
- package/dist/services/oracle-builder/service.js +513 -0
- package/dist/services/oracle-coverage/service.d.ts +28 -0
- package/dist/services/oracle-coverage/service.js +50 -0
- package/dist/services/oracle-coverage-witness/service.d.ts +130 -0
- package/dist/services/oracle-coverage-witness/service.js +538 -0
- package/dist/services/pipeline-challenge/service.d.ts +551 -0
- package/dist/services/pipeline-challenge/service.js +427 -0
- package/dist/services/pipeline-controls/service.d.ts +130 -0
- package/dist/services/pipeline-controls/service.js +483 -0
- package/dist/services/pipeline-oracle/service.d.ts +8 -0
- package/dist/services/pipeline-oracle/service.js +256 -0
- package/dist/services/pipeline-seed/service.d.ts +298 -0
- package/dist/services/pipeline-seed/service.js +428 -0
- package/dist/services/pipeline-spec/service.d.ts +103 -0
- package/dist/services/pipeline-spec/service.js +619 -0
- package/dist/services/pipeline-tournament/service.d.ts +258 -0
- package/dist/services/pipeline-tournament/service.js +476 -0
- package/dist/services/quality-gate/service.d.ts +233 -0
- package/dist/services/quality-gate/service.js +136 -0
- package/dist/services/repository-bundle/service.d.ts +33 -0
- package/dist/services/repository-bundle/service.js +114 -0
- package/dist/services/repository-model/service.d.ts +105 -0
- package/dist/services/repository-model/service.js +250 -0
- package/dist/services/repository-public-artifact/service.d.ts +133 -0
- package/dist/services/repository-public-artifact/service.js +330 -0
- package/dist/services/routing-benchmark/service.d.ts +362 -0
- package/dist/services/routing-benchmark/service.js +96 -0
- package/dist/services/specification-critic/service.d.ts +92 -0
- package/dist/services/specification-critic/service.js +172 -0
- package/dist/services/task-family/service.d.ts +40 -0
- package/dist/services/task-family/service.js +55 -0
- package/dist/services/task-seed/service.d.ts +906 -0
- package/dist/services/task-seed/service.js +1406 -0
- package/dist/services/task-specification/service.d.ts +27 -0
- package/dist/services/task-specification/service.js +40 -0
- package/dist/services/trajectory-policy/service.d.ts +110 -0
- package/dist/services/trajectory-policy/service.js +216 -0
- package/dist/test/agentic-capabilities-protocol.test.d.ts +1 -0
- package/dist/test/agentic-capabilities-protocol.test.js +570 -0
- package/dist/test/agentic-capabilities.test.d.ts +1 -0
- package/dist/test/agentic-capabilities.test.js +1461 -0
- package/dist/test/agentic-environment.test.d.ts +1 -0
- package/dist/test/agentic-environment.test.js +213 -0
- package/dist/test/case-pipeline-foundation.test.d.ts +1 -0
- package/dist/test/case-pipeline-foundation.test.js +535 -0
- package/dist/test/case-pipeline-protocol-v2.test.d.ts +1 -0
- package/dist/test/case-pipeline-protocol-v2.test.js +124 -0
- package/dist/test/case-pipeline-v2.test.d.ts +1 -0
- package/dist/test/case-pipeline-v2.test.js +286 -0
- package/dist/test/case-pipeline.test.d.ts +1 -0
- package/dist/test/case-pipeline.test.js +851 -0
- package/dist/test/eval-capability-policy.test.d.ts +1 -0
- package/dist/test/eval-capability-policy.test.js +50 -0
- package/dist/test/eval-event-log.test.js +34 -1
- package/dist/test/evaluation-evidence-freshness.test.d.ts +1 -0
- package/dist/test/evaluation-evidence-freshness.test.js +44 -0
- package/dist/test/evaluation-evidence.test.d.ts +1 -0
- package/dist/test/evaluation-evidence.test.js +230 -0
- package/dist/test/evaluation-grader-calibration.test.d.ts +1 -0
- package/dist/test/evaluation-grader-calibration.test.js +373 -0
- package/dist/test/evaluation-proposal-digest.test.d.ts +1 -0
- package/dist/test/evaluation-proposal-digest.test.js +187 -0
- package/dist/test/evaluation-source-retrieval.test.d.ts +1 -0
- package/dist/test/evaluation-source-retrieval.test.js +237 -0
- package/dist/test/evaluation-structure-policy.test.d.ts +1 -0
- package/dist/test/evaluation-structure-policy.test.js +196 -0
- package/dist/test/fixtures/repository-resource-panel.d.ts +39 -0
- package/dist/test/fixtures/repository-resource-panel.js +111 -0
- package/dist/test/fixtures/vitest-boundary-panel.d.ts +84 -0
- package/dist/test/fixtures/vitest-boundary-panel.js +120 -0
- package/dist/test/fixtures/vitest-phase-panel.d.ts +135 -0
- package/dist/test/fixtures/vitest-phase-panel.js +213 -0
- package/dist/test/fixtures/vitest-reporter-results.d.ts +76 -0
- package/dist/test/fixtures/vitest-reporter-results.js +94 -0
- package/dist/test/grounded-authoring.test.d.ts +1 -0
- package/dist/test/grounded-authoring.test.js +565 -0
- package/dist/test/integrated-repository-history.test.d.ts +1 -0
- package/dist/test/integrated-repository-history.test.js +227 -0
- package/dist/test/project-authoring.test.js +593 -43
- package/dist/test/project-workflow.test.js +395 -32
- package/dist/test/repository-authoring-artifacts.test.d.ts +1 -0
- package/dist/test/repository-authoring-artifacts.test.js +185 -0
- package/dist/test/repository-bundle.test.d.ts +1 -0
- package/dist/test/repository-bundle.test.js +52 -0
- package/dist/test/repository-case-generation.test.d.ts +1 -0
- package/dist/test/repository-case-generation.test.js +3465 -0
- package/dist/test/repository-command-diagnostic.test.d.ts +1 -0
- package/dist/test/repository-command-diagnostic.test.js +55 -0
- package/dist/test/repository-command-signals.test.d.ts +1 -0
- package/dist/test/repository-command-signals.test.js +124 -0
- package/dist/test/repository-fixture-scope-coverage.test.d.ts +1 -0
- package/dist/test/repository-fixture-scope-coverage.test.js +127 -0
- package/dist/test/repository-fixture-validation.test.d.ts +1 -0
- package/dist/test/repository-fixture-validation.test.js +362 -0
- package/dist/test/repository-foundry-progress.test.d.ts +1 -0
- package/dist/test/repository-foundry-progress.test.js +110 -0
- package/dist/test/repository-foundry-quality.test.d.ts +1 -0
- package/dist/test/repository-foundry-quality.test.js +1138 -0
- package/dist/test/repository-import-context.test.d.ts +1 -0
- package/dist/test/repository-import-context.test.js +354 -0
- package/dist/test/repository-model-authoring.test.d.ts +1 -0
- package/dist/test/repository-model-authoring.test.js +544 -0
- package/dist/test/repository-model.test.d.ts +1 -0
- package/dist/test/repository-model.test.js +2195 -0
- package/dist/test/repository-node-test-reporter.test.d.ts +1 -0
- package/dist/test/repository-node-test-reporter.test.js +104 -0
- package/dist/test/repository-oracle-concurrency.test.d.ts +1 -0
- package/dist/test/repository-oracle-concurrency.test.js +542 -0
- package/dist/test/repository-oracle-coverage-witness.test.d.ts +1 -0
- package/dist/test/repository-oracle-coverage-witness.test.js +511 -0
- package/dist/test/repository-oracle-coverage.test.d.ts +1 -0
- package/dist/test/repository-oracle-coverage.test.js +168 -0
- package/dist/test/repository-oracle-evidence.test.d.ts +1 -0
- package/dist/test/repository-oracle-evidence.test.js +185 -0
- package/dist/test/repository-oracle-plan.test.d.ts +1 -0
- package/dist/test/repository-oracle-plan.test.js +176 -0
- package/dist/test/repository-overlay-isolation.test.d.ts +1 -0
- package/dist/test/repository-overlay-isolation.test.js +85 -0
- package/dist/test/repository-preparation-cache.test.d.ts +1 -0
- package/dist/test/repository-preparation-cache.test.js +414 -0
- package/dist/test/repository-public-artifact.test.d.ts +1 -0
- package/dist/test/repository-public-artifact.test.js +273 -0
- package/dist/test/repository-qualification-diagnostics.test.d.ts +1 -0
- package/dist/test/repository-qualification-diagnostics.test.js +524 -0
- package/dist/test/repository-reference-authoring.test.d.ts +1 -0
- package/dist/test/repository-reference-authoring.test.js +1633 -0
- package/dist/test/repository-review-evidence-v2.test.d.ts +1 -0
- package/dist/test/repository-review-evidence-v2.test.js +183 -0
- package/dist/test/repository-review-evidence.test.d.ts +1 -0
- package/dist/test/repository-review-evidence.test.js +124 -0
- package/dist/test/repository-seed-exclusions.test.d.ts +1 -0
- package/dist/test/repository-seed-exclusions.test.js +96 -0
- package/dist/test/repository-seed-selection.test.d.ts +1 -0
- package/dist/test/repository-seed-selection.test.js +504 -0
- package/dist/test/repository-semantic-calibration.test.d.ts +1 -0
- package/dist/test/repository-semantic-calibration.test.js +688 -0
- package/dist/test/repository-solution-edits.test.d.ts +1 -0
- package/dist/test/repository-solution-edits.test.js +377 -0
- package/dist/test/repository-specification-budget.test.d.ts +1 -0
- package/dist/test/repository-specification-budget.test.js +171 -0
- package/dist/test/repository-specification-contract-checkpoint.test.d.ts +1 -0
- package/dist/test/repository-specification-contract-checkpoint.test.js +228 -0
- package/dist/test/repository-specification-contract-facts.test.d.ts +1 -0
- package/dist/test/repository-specification-contract-facts.test.js +177 -0
- package/dist/test/repository-trajectory-authoring.test.d.ts +1 -0
- package/dist/test/repository-trajectory-authoring.test.js +176 -0
- package/dist/test/repository-valid-control-plan.test.d.ts +1 -0
- package/dist/test/repository-valid-control-plan.test.js +45 -0
- package/dist/test/repository-vitest-phase.test.d.ts +1 -0
- package/dist/test/repository-vitest-phase.test.js +848 -0
- package/dist/test/repository-vitest-reporter.test.d.ts +1 -0
- package/dist/test/repository-vitest-reporter.test.js +158 -0
- package/dist/test/repository-workspace-build.test.d.ts +1 -0
- package/dist/test/repository-workspace-build.test.js +160 -0
- package/dist/test/strict-authoring-schema.test.d.ts +1 -0
- package/dist/test/strict-authoring-schema.test.js +169 -0
- package/package.json +48 -7
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
import { Clock, Context, Effect, Layer, Option, Ref, Schema } from "effect";
|
|
2
|
+
import { HostFeedbackV1, checkpointDigestV1, PipelineBudgetExhaustedError } from "../../case-pipeline-protocol.js";
|
|
3
|
+
import { RepositoryFoundryError } from "../../errors.js";
|
|
4
|
+
import { RepositoryFoundryReasoningEffortV1, repositoryFoundryModelAssignmentV1 } from "../../repository-language-model-protocol.js";
|
|
5
|
+
import { makeRepositoryFoundryProgress, reportFoundryHeartbeatV1, RepositoryFoundryProgress } from "../foundry-progress/service.js";
|
|
6
|
+
import { RepositoryFoundryLanguageModel } from "../language-model/service.js";
|
|
7
|
+
/** Ref-backed accessor shared by the orchestrator and the budget wrapper. */
|
|
8
|
+
export const makePipelineStateAccessorV1 = (initial) => Effect.map(Ref.make(initial), (ref) => ({
|
|
9
|
+
get: Ref.get(ref),
|
|
10
|
+
set: (state) => Ref.set(ref, state)
|
|
11
|
+
}));
|
|
12
|
+
export class PipelineBudgetTracker extends Context.Service()("@velum-labs/routekit-eval-setup/PipelineBudgetTracker") {
|
|
13
|
+
}
|
|
14
|
+
export const budgetSnapshotV1 = Effect.flatMap(PipelineBudgetTracker, (tracker) => tracker.snapshot);
|
|
15
|
+
export const TRANSPORT_RETRY_BACKOFF_MS = [5_000, 15_000, 45_000, 90_000, 180_000];
|
|
16
|
+
export const TRANSPORT_ERROR_MARKERS = [
|
|
17
|
+
"transport error",
|
|
18
|
+
"before response headers",
|
|
19
|
+
"econnrefused",
|
|
20
|
+
"econnreset",
|
|
21
|
+
"fetch failed",
|
|
22
|
+
"timed out",
|
|
23
|
+
"socket",
|
|
24
|
+
"5xx",
|
|
25
|
+
"502",
|
|
26
|
+
"503",
|
|
27
|
+
"504",
|
|
28
|
+
"429",
|
|
29
|
+
"stream"
|
|
30
|
+
];
|
|
31
|
+
export const STRUCTURED_OUTPUT_INVALID_PREFIX = "structured-output-invalid:";
|
|
32
|
+
const RECEIVED_BUT_INVALID_MARKERS = [
|
|
33
|
+
"returned invalid json",
|
|
34
|
+
"violated ",
|
|
35
|
+
"could not restore optional fields"
|
|
36
|
+
];
|
|
37
|
+
const errorText = (error, depth = 0) => {
|
|
38
|
+
if (depth > 6 || error === null || error === undefined)
|
|
39
|
+
return "";
|
|
40
|
+
if (typeof error === "string")
|
|
41
|
+
return error;
|
|
42
|
+
if (typeof error !== "object")
|
|
43
|
+
return String(error);
|
|
44
|
+
const record = error;
|
|
45
|
+
return [
|
|
46
|
+
typeof record.message === "string" ? record.message : "",
|
|
47
|
+
typeof record.detail === "string" ? record.detail : "",
|
|
48
|
+
typeof record.code === "string" ? record.code : "",
|
|
49
|
+
errorText(record.cause, depth + 1)
|
|
50
|
+
].join("\n");
|
|
51
|
+
};
|
|
52
|
+
/** Transport failures are retried and are never a terminal outcome of a case. */
|
|
53
|
+
export const isTransportFailureV1 = (error) => {
|
|
54
|
+
const text = errorText(error).toLowerCase();
|
|
55
|
+
return TRANSPORT_ERROR_MARKERS.some((marker) => text.includes(marker));
|
|
56
|
+
};
|
|
57
|
+
export const isStructuredOutputInvalidV1 = (error) => error instanceof RepositoryFoundryError &&
|
|
58
|
+
error.operation === "invoke-language-model" &&
|
|
59
|
+
error.detail.startsWith(STRUCTURED_OUTPUT_INVALID_PREFIX);
|
|
60
|
+
export const BUDGET_EXHAUSTED_PREFIX = "budget-exhausted:";
|
|
61
|
+
/**
|
|
62
|
+
* The language-model shape only carries RepositoryFoundryError, so the wrapper
|
|
63
|
+
* fails with a tagged RepositoryFoundryError whose cause is the typed budget
|
|
64
|
+
* error. Substrate services propagate it unchanged; stage and orchestrator
|
|
65
|
+
* code unwraps it with `normalizePipelineFailureV1`.
|
|
66
|
+
*/
|
|
67
|
+
export const budgetExhaustedErrorOfV1 = (error) => {
|
|
68
|
+
if (error instanceof PipelineBudgetExhaustedError)
|
|
69
|
+
return error;
|
|
70
|
+
if (error instanceof RepositoryFoundryError &&
|
|
71
|
+
error.detail.startsWith(BUDGET_EXHAUSTED_PREFIX) &&
|
|
72
|
+
error.cause instanceof PipelineBudgetExhaustedError) {
|
|
73
|
+
return error.cause;
|
|
74
|
+
}
|
|
75
|
+
return undefined;
|
|
76
|
+
};
|
|
77
|
+
export const normalizePipelineFailureV1 = (error) => budgetExhaustedErrorOfV1(error) ?? error;
|
|
78
|
+
const wrapExhausted = (error) => new RepositoryFoundryError({
|
|
79
|
+
operation: "invoke-language-model",
|
|
80
|
+
detail: `${BUDGET_EXHAUSTED_PREFIX} ${error.message}`,
|
|
81
|
+
cause: error
|
|
82
|
+
});
|
|
83
|
+
/** The raw response text the wrapper captured for a received-but-invalid response. */
|
|
84
|
+
export const structuredOutputInvalidResponseTextV1 = (error) => {
|
|
85
|
+
const cause = error.cause;
|
|
86
|
+
if (typeof cause !== "object" || cause === null || !("responseText" in cause))
|
|
87
|
+
return undefined;
|
|
88
|
+
const text = cause.responseText;
|
|
89
|
+
return typeof text === "string" ? text : undefined;
|
|
90
|
+
};
|
|
91
|
+
const isReceivedButInvalid = (error) => {
|
|
92
|
+
if (isStructuredOutputInvalidV1(error))
|
|
93
|
+
return true;
|
|
94
|
+
const detail = error.detail.toLowerCase();
|
|
95
|
+
return RECEIVED_BUT_INVALID_MARKERS.some((marker) => detail.includes(marker));
|
|
96
|
+
};
|
|
97
|
+
const TRANSPORT_RETRY_BACKOFF_CAP_MS = 180_000;
|
|
98
|
+
const backoffMs = (attempt) => TRANSPORT_RETRY_BACKOFF_MS[Math.min(Math.max(attempt - 1, 0), TRANSPORT_RETRY_BACKOFF_MS.length - 1)] ?? TRANSPORT_RETRY_BACKOFF_CAP_MS;
|
|
99
|
+
const byteLength = (value) => {
|
|
100
|
+
const text = JSON.stringify(value);
|
|
101
|
+
return text === undefined ? 0 : Buffer.byteLength(text);
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* The inner language model reports receipt and raw response text through the
|
|
105
|
+
* progress service. Intercepting it makes accounting exact even when JSON
|
|
106
|
+
* decoding or schema validation fails afterwards; outer progress still sees
|
|
107
|
+
* every event.
|
|
108
|
+
*/
|
|
109
|
+
const interceptingProgress = (outer, observed) => Effect.gen(function* () {
|
|
110
|
+
const base = Option.isSome(outer) ? outer.value : yield* makeRepositoryFoundryProgress();
|
|
111
|
+
const forwardArtifact = base.recordAuthoringArtifact;
|
|
112
|
+
return {
|
|
113
|
+
...base,
|
|
114
|
+
reportModelCall: (input) => Effect.gen(function* () {
|
|
115
|
+
if (input.phase === "complete") {
|
|
116
|
+
observed.received = true;
|
|
117
|
+
if (input.callId !== undefined)
|
|
118
|
+
observed.callId = input.callId;
|
|
119
|
+
}
|
|
120
|
+
return yield* base.reportModelCall(input);
|
|
121
|
+
}),
|
|
122
|
+
recordAuthoringArtifact: (artifact) => Effect.gen(function* () {
|
|
123
|
+
observed.received = true;
|
|
124
|
+
observed.responseText = artifact.response.text;
|
|
125
|
+
if (artifact.response.callId !== undefined)
|
|
126
|
+
observed.callId = artifact.response.callId;
|
|
127
|
+
if (forwardArtifact !== undefined)
|
|
128
|
+
yield* forwardArtifact(artifact);
|
|
129
|
+
})
|
|
130
|
+
};
|
|
131
|
+
});
|
|
132
|
+
export const makeBudgetedLanguageModelV1 = Effect.fn("BudgetedModel.make")(function* (input) {
|
|
133
|
+
const now = input.now ?? Clock.currentTimeMillis;
|
|
134
|
+
const sleep = input.sleep ?? ((ms) => Effect.sleep(ms));
|
|
135
|
+
const initial = yield* input.state.get;
|
|
136
|
+
const baselineElapsedMs = initial.elapsedMs;
|
|
137
|
+
const elapsedNow = Effect.map(now, (at) => baselineElapsedMs + Math.max(0, at - input.startedAtMs));
|
|
138
|
+
const isoNow = Effect.map(now, (at) => new Date(at).toISOString());
|
|
139
|
+
const snapshot = Effect.gen(function* () {
|
|
140
|
+
const state = yield* input.state.get;
|
|
141
|
+
const elapsedMs = yield* elapsedNow;
|
|
142
|
+
return {
|
|
143
|
+
modelCalls: state.modelCalls,
|
|
144
|
+
elapsedMs,
|
|
145
|
+
remainingCalls: Math.max(0, input.budget.maxModelCalls - state.modelCalls),
|
|
146
|
+
remainingMs: Math.max(0, input.budget.maxWallMs - elapsedMs)
|
|
147
|
+
};
|
|
148
|
+
});
|
|
149
|
+
const exhausted = (modelCalls, elapsedMs, stage) => new PipelineBudgetExhaustedError({ budget: input.budget, modelCalls, elapsedMs, stage });
|
|
150
|
+
const assertAvailable = Effect.gen(function* () {
|
|
151
|
+
const state = yield* input.state.get;
|
|
152
|
+
const elapsedMs = yield* elapsedNow;
|
|
153
|
+
if (state.modelCalls >= input.budget.maxModelCalls || elapsedMs >= input.budget.maxWallMs) {
|
|
154
|
+
return yield* exhausted(state.modelCalls, elapsedMs, state.stage);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
const recordReceived = Effect.gen(function* () {
|
|
158
|
+
const state = yield* input.state.get;
|
|
159
|
+
const elapsedMs = yield* elapsedNow;
|
|
160
|
+
const next = {
|
|
161
|
+
...state,
|
|
162
|
+
modelCalls: state.modelCalls + 1,
|
|
163
|
+
elapsedMs,
|
|
164
|
+
updatedAt: yield* isoNow
|
|
165
|
+
};
|
|
166
|
+
yield* input.state.set(next);
|
|
167
|
+
yield* input.store.writeState(next);
|
|
168
|
+
});
|
|
169
|
+
const ledger = (entry) => Effect.gen(function* () {
|
|
170
|
+
const at = yield* isoNow;
|
|
171
|
+
yield* input.store.appendLedger({ at, ...entry });
|
|
172
|
+
});
|
|
173
|
+
const run = (request, invoke) => Effect.gen(function* () {
|
|
174
|
+
const outer = yield* Effect.serviceOption(RepositoryFoundryProgress);
|
|
175
|
+
const inputBytes = byteLength(request.input);
|
|
176
|
+
const identity = {
|
|
177
|
+
operationId: request.operationId,
|
|
178
|
+
role: request.role,
|
|
179
|
+
model: request.model
|
|
180
|
+
};
|
|
181
|
+
const callRecord = {
|
|
182
|
+
role: request.role,
|
|
183
|
+
model: request.model,
|
|
184
|
+
reasoningEffort: request.reasoningEffort,
|
|
185
|
+
operationId: request.operationId,
|
|
186
|
+
schemaName: request.schemaName,
|
|
187
|
+
instructions: request.instructions,
|
|
188
|
+
input: request.input,
|
|
189
|
+
maximumOutputTokens: request.maximumOutputTokens
|
|
190
|
+
};
|
|
191
|
+
for (let attempt = 1;; attempt += 1) {
|
|
192
|
+
yield* assertAvailable.pipe(Effect.mapError(wrapExhausted));
|
|
193
|
+
yield* ledger({ ...identity, phase: "start", attempt, inputBytes });
|
|
194
|
+
const observed = { received: false, responseText: undefined, callId: undefined };
|
|
195
|
+
const progress = yield* interceptingProgress(outer, observed);
|
|
196
|
+
const result = yield* invoke.pipe(Effect.provideService(RepositoryFoundryProgress, progress), Effect.result);
|
|
197
|
+
if (result._tag === "Success") {
|
|
198
|
+
const callId = result.success.call.callId ?? observed.callId;
|
|
199
|
+
const outputBytes = observed.responseText === undefined
|
|
200
|
+
? byteLength(result.success.value)
|
|
201
|
+
: Buffer.byteLength(observed.responseText);
|
|
202
|
+
yield* recordReceived;
|
|
203
|
+
yield* ledger({
|
|
204
|
+
...identity,
|
|
205
|
+
phase: "received",
|
|
206
|
+
attempt,
|
|
207
|
+
inputBytes,
|
|
208
|
+
outputBytes,
|
|
209
|
+
...(callId === undefined ? {} : { callId })
|
|
210
|
+
});
|
|
211
|
+
yield* input.store.writeCall(request.operationId, attempt, {
|
|
212
|
+
request: callRecord,
|
|
213
|
+
response: {
|
|
214
|
+
value: result.success.value,
|
|
215
|
+
...(observed.responseText === undefined ? {} : { text: observed.responseText }),
|
|
216
|
+
...(callId === undefined ? {} : { callId })
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
yield* ledger({
|
|
220
|
+
...identity,
|
|
221
|
+
phase: "validated",
|
|
222
|
+
attempt,
|
|
223
|
+
...(callId === undefined ? {} : { callId })
|
|
224
|
+
});
|
|
225
|
+
return result.success;
|
|
226
|
+
}
|
|
227
|
+
const error = result.failure;
|
|
228
|
+
if (observed.received || isReceivedButInvalid(error)) {
|
|
229
|
+
// The provider answered; the answer did not decode. Count it, keep the
|
|
230
|
+
// raw text for feedback, and let the role try again with findings.
|
|
231
|
+
const callId = observed.callId;
|
|
232
|
+
yield* recordReceived;
|
|
233
|
+
yield* ledger({
|
|
234
|
+
...identity,
|
|
235
|
+
phase: "received",
|
|
236
|
+
attempt,
|
|
237
|
+
inputBytes,
|
|
238
|
+
...(observed.responseText === undefined
|
|
239
|
+
? {}
|
|
240
|
+
: { outputBytes: Buffer.byteLength(observed.responseText) }),
|
|
241
|
+
...(callId === undefined ? {} : { callId }),
|
|
242
|
+
detail: error.detail
|
|
243
|
+
});
|
|
244
|
+
yield* input.store.writeCall(request.operationId, attempt, {
|
|
245
|
+
request: callRecord,
|
|
246
|
+
response: {
|
|
247
|
+
...(observed.responseText === undefined ? {} : { text: observed.responseText }),
|
|
248
|
+
...(callId === undefined ? {} : { callId }),
|
|
249
|
+
error: error.detail
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
yield* ledger({ ...identity, phase: "failed", attempt, detail: error.detail });
|
|
253
|
+
const detail = isStructuredOutputInvalidV1(error)
|
|
254
|
+
? error.detail
|
|
255
|
+
: `${STRUCTURED_OUTPUT_INVALID_PREFIX} ${error.detail}`;
|
|
256
|
+
return yield* new RepositoryFoundryError({
|
|
257
|
+
operation: "invoke-language-model",
|
|
258
|
+
detail,
|
|
259
|
+
cause: {
|
|
260
|
+
...(observed.responseText === undefined
|
|
261
|
+
? {}
|
|
262
|
+
: { responseText: observed.responseText }),
|
|
263
|
+
cause: error
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
if (isTransportFailureV1(error)) {
|
|
268
|
+
const delayMs = backoffMs(attempt);
|
|
269
|
+
const current = yield* snapshot;
|
|
270
|
+
if (current.elapsedMs + delayMs >= input.budget.maxWallMs) {
|
|
271
|
+
yield* ledger({
|
|
272
|
+
...identity,
|
|
273
|
+
phase: "failed",
|
|
274
|
+
attempt,
|
|
275
|
+
detail: `wall budget cannot absorb a ${String(delayMs)}ms retry: ${error.detail}`
|
|
276
|
+
});
|
|
277
|
+
const state = yield* input.state.get;
|
|
278
|
+
return yield* wrapExhausted(exhausted(current.modelCalls, current.elapsedMs, state.stage));
|
|
279
|
+
}
|
|
280
|
+
yield* ledger({
|
|
281
|
+
...identity,
|
|
282
|
+
phase: "retry",
|
|
283
|
+
attempt,
|
|
284
|
+
detail: `transport failure, retrying in ${String(delayMs)}ms: ${error.detail}`
|
|
285
|
+
});
|
|
286
|
+
yield* sleep(delayMs);
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
yield* ledger({ ...identity, phase: "failed", attempt, detail: error.detail });
|
|
290
|
+
return yield* error;
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
const generateAssignedStructured = (request) => run({
|
|
294
|
+
role: request.assignment.role,
|
|
295
|
+
model: request.assignment.model,
|
|
296
|
+
reasoningEffort: request.assignment.reasoningEffort,
|
|
297
|
+
operationId: request.operationId,
|
|
298
|
+
instructions: request.instructions,
|
|
299
|
+
input: request.input,
|
|
300
|
+
schemaName: request.schemaName,
|
|
301
|
+
maximumOutputTokens: request.maximumOutputTokens
|
|
302
|
+
}, input.inner.generateAssignedStructured(request));
|
|
303
|
+
const generateStructured = (request) => Effect.gen(function* () {
|
|
304
|
+
const assignment = yield* Effect.try({
|
|
305
|
+
try: () => repositoryFoundryModelAssignmentV1(request.plan, request.role),
|
|
306
|
+
catch: (cause) => new RepositoryFoundryError({
|
|
307
|
+
operation: "invoke-language-model",
|
|
308
|
+
detail: "repository foundry model request failed validation",
|
|
309
|
+
cause
|
|
310
|
+
})
|
|
311
|
+
});
|
|
312
|
+
return yield* run({
|
|
313
|
+
role: assignment.role,
|
|
314
|
+
model: assignment.model,
|
|
315
|
+
reasoningEffort: assignment.reasoningEffort,
|
|
316
|
+
operationId: request.operationId,
|
|
317
|
+
instructions: request.instructions,
|
|
318
|
+
input: request.input,
|
|
319
|
+
schemaName: request.schemaName,
|
|
320
|
+
maximumOutputTokens: request.maximumOutputTokens
|
|
321
|
+
}, input.inner.generateStructured(request));
|
|
322
|
+
});
|
|
323
|
+
const languageModel = {
|
|
324
|
+
generateAssignedStructured,
|
|
325
|
+
generateStructured
|
|
326
|
+
};
|
|
327
|
+
const tracker = { budget: input.budget, snapshot, assertAvailable };
|
|
328
|
+
return { languageModel, tracker };
|
|
329
|
+
});
|
|
330
|
+
/** Provides both the wrapped language model and the budget tracker. */
|
|
331
|
+
export const BudgetedLanguageModelLive = (input) => Layer.unwrap(Effect.map(makeBudgetedLanguageModelV1(input), ({ languageModel, tracker }) => Layer.mergeAll(Layer.succeed(RepositoryFoundryLanguageModel, languageModel), Layer.succeed(PipelineBudgetTracker, tracker))));
|
|
332
|
+
export const FEEDBACK_LOOP_UNRESOLVED_PREFIX = "feedback-loop-unresolved:";
|
|
333
|
+
export const DEFAULT_FEEDBACK_MAX_ATTEMPTS = 12;
|
|
334
|
+
const augmentInput = (input, hostFeedback) => input !== null && typeof input === "object" && !Array.isArray(input)
|
|
335
|
+
? { ...input, hostFeedback }
|
|
336
|
+
: { input, hostFeedback };
|
|
337
|
+
/**
|
|
338
|
+
* Model proposes, host verifies, same role repairs. Shortfalls become
|
|
339
|
+
* hostFeedback instead of terminal failures; only the global budget bounds
|
|
340
|
+
* the loop. A received response and completed feedback survive interruption;
|
|
341
|
+
* resuming revalidates the response, never treats authoring as executed proof.
|
|
342
|
+
*/
|
|
343
|
+
export const generateWithFeedbackV1 = (input) => Effect.gen(function* () {
|
|
344
|
+
const languageModel = input.languageModel ?? (yield* RepositoryFoundryLanguageModel);
|
|
345
|
+
const maxAttempts = input.maxAttempts ?? DEFAULT_FEEDBACK_MAX_ATTEMPTS;
|
|
346
|
+
const assignment = input.assignment ??
|
|
347
|
+
repositoryFoundryModelAssignmentV1(input.plan, input.role);
|
|
348
|
+
const workName = `model-feedback-${checkpointDigestV1(input.operationId)}`;
|
|
349
|
+
const bindingDigest = checkpointDigestV1({
|
|
350
|
+
version: 1,
|
|
351
|
+
operationId: input.operationId,
|
|
352
|
+
assignment,
|
|
353
|
+
instructions: input.instructions,
|
|
354
|
+
input: input.input,
|
|
355
|
+
schema: Schema.toJsonSchemaDocument(input.outputSchema),
|
|
356
|
+
maximumOutputTokens: input.maximumOutputTokens,
|
|
357
|
+
validation: input.checkpoint?.binding ?? null
|
|
358
|
+
});
|
|
359
|
+
const workSchema = Schema.Struct({
|
|
360
|
+
version: Schema.Literal(1),
|
|
361
|
+
bindingDigest: Schema.String,
|
|
362
|
+
feedback: Schema.Array(HostFeedbackV1),
|
|
363
|
+
received: Schema.optionalKey(Schema.Struct({
|
|
364
|
+
attempt: Schema.Int,
|
|
365
|
+
value: input.outputSchema,
|
|
366
|
+
call: Schema.Struct({
|
|
367
|
+
operationId: Schema.String,
|
|
368
|
+
role: Schema.String,
|
|
369
|
+
model: Schema.String,
|
|
370
|
+
reasoningEffort: RepositoryFoundryReasoningEffortV1,
|
|
371
|
+
callId: Schema.optionalKey(Schema.String)
|
|
372
|
+
})
|
|
373
|
+
}))
|
|
374
|
+
});
|
|
375
|
+
const retained = input.checkpoint === undefined
|
|
376
|
+
? Option.none()
|
|
377
|
+
: yield* input.checkpoint.store.readWorkCheckpoint(workName, workSchema);
|
|
378
|
+
const previous = Option.isSome(retained) && retained.value.bindingDigest === bindingDigest
|
|
379
|
+
? retained.value
|
|
380
|
+
: undefined;
|
|
381
|
+
const operationOf = (attempt) => attempt === 1 ? input.operationId : `${input.operationId}:attempt-${String(attempt)}`;
|
|
382
|
+
if (previous !== undefined && (previous.feedback.some((packet, index) => packet.attempt !== index + 1) ||
|
|
383
|
+
(previous.received !== undefined && (previous.received.attempt !== previous.feedback.length + 1 ||
|
|
384
|
+
previous.received.call.operationId !== operationOf(previous.received.attempt))))) {
|
|
385
|
+
return yield* new RepositoryFoundryError({
|
|
386
|
+
operation: "checkpoint-store",
|
|
387
|
+
detail: "feedback authoring work has an invalid attempt sequence"
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
const feedback = [...(previous?.feedback ?? [])];
|
|
391
|
+
let received = previous?.received;
|
|
392
|
+
const save = () => input.checkpoint === undefined
|
|
393
|
+
? Effect.void
|
|
394
|
+
: input.checkpoint.store.writeWorkCheckpoint(workName, {
|
|
395
|
+
version: 1, bindingDigest, feedback,
|
|
396
|
+
...(received === undefined ? {} : { received })
|
|
397
|
+
}).pipe(Effect.uninterruptible);
|
|
398
|
+
if (previous !== undefined) {
|
|
399
|
+
yield* reportFoundryHeartbeatV1({
|
|
400
|
+
role: assignment.role,
|
|
401
|
+
detail: `feedback authoring restored; completedAttempts=${String(feedback.length)}; pendingAttempt=${String(received?.attempt ?? 0)}`
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
for (let attempt = feedback.length + 1; attempt <= maxAttempts; attempt += 1) {
|
|
405
|
+
const pending = feedback.at(-1);
|
|
406
|
+
const operationId = operationOf(attempt);
|
|
407
|
+
const payload = pending === undefined ? input.input : augmentInput(input.input, pending);
|
|
408
|
+
const common = {
|
|
409
|
+
operationId,
|
|
410
|
+
instructions: input.instructions,
|
|
411
|
+
input: payload,
|
|
412
|
+
schemaName: input.schemaName,
|
|
413
|
+
outputSchema: input.outputSchema,
|
|
414
|
+
maximumOutputTokens: input.maximumOutputTokens
|
|
415
|
+
};
|
|
416
|
+
const generate = input.assignment !== undefined
|
|
417
|
+
? languageModel.generateAssignedStructured({ ...common, assignment: input.assignment })
|
|
418
|
+
: languageModel.generateStructured({ ...common, plan: input.plan, role: input.role });
|
|
419
|
+
if (received === undefined) {
|
|
420
|
+
yield* Effect.uninterruptibleMask((restore) => Effect.gen(function* () {
|
|
421
|
+
const generated = yield* Effect.result(restore(generate));
|
|
422
|
+
if (generated._tag === "Failure") {
|
|
423
|
+
const error = generated.failure;
|
|
424
|
+
if (!isStructuredOutputInvalidV1(error))
|
|
425
|
+
return yield* normalizePipelineFailureV1(error);
|
|
426
|
+
feedback.push({
|
|
427
|
+
attempt,
|
|
428
|
+
findings: [{ kind: "schema", message: error.detail }],
|
|
429
|
+
priorOutput: structuredOutputInvalidResponseTextV1(error) ?? null
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
else {
|
|
433
|
+
received = { attempt, ...generated.success };
|
|
434
|
+
}
|
|
435
|
+
yield* save();
|
|
436
|
+
}));
|
|
437
|
+
}
|
|
438
|
+
if (received === undefined)
|
|
439
|
+
continue;
|
|
440
|
+
const findings = yield* input.validate(received.value);
|
|
441
|
+
if (findings.length === 0) {
|
|
442
|
+
return {
|
|
443
|
+
value: received.value,
|
|
444
|
+
attempts: attempt,
|
|
445
|
+
call: received.call,
|
|
446
|
+
feedback
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
feedback.push({ attempt, findings, priorOutput: received.value });
|
|
450
|
+
received = undefined;
|
|
451
|
+
yield* save();
|
|
452
|
+
}
|
|
453
|
+
const last = feedback.at(-1)?.findings ?? [];
|
|
454
|
+
return yield* new RepositoryFoundryError({
|
|
455
|
+
operation: "invoke-language-model",
|
|
456
|
+
detail: `${FEEDBACK_LOOP_UNRESOLVED_PREFIX} ${last.length === 0
|
|
457
|
+
? "no attempts were made"
|
|
458
|
+
: last.map((finding) => `${finding.kind}: ${finding.message}`).join("; ")}`
|
|
459
|
+
});
|
|
460
|
+
});
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { Context, Effect, Layer, Schema } from "effect";
|
|
2
|
+
import { RepositoryFoundryError } from "../../errors.js";
|
|
3
|
+
import type { RepositoryBehaviorMapV1 } from "../../repository-behavior-protocol.js";
|
|
4
|
+
import type { RepositoryCandidateVisibleTaskV1 } from "../../repository-benchmark-protocol.js";
|
|
5
|
+
import type { RepositoryFoundryModelCallV1, RepositoryFoundryModelPlanV1 } from "../../repository-language-model-protocol.js";
|
|
6
|
+
import { RepositorySpecificationContractFactReviewV1, type RepositorySpecificationAcceptedContractFactsV1 } from "../../repository-specification-contract-facts-protocol.js";
|
|
7
|
+
import { RepositorySpecificationReferenceScopeV1, type RepositorySpecificationReviewV1 } from "../../repository-specification-critique-protocol.js";
|
|
8
|
+
import type { RepositoryTaskFamilyV1 } from "../../repository-task-family-protocol.js";
|
|
9
|
+
import type { RepositoryTaskSeedV1 } from "../../repository-task-seed-protocol.js";
|
|
10
|
+
import { RepositoryFoundryLanguageModel } from "../language-model/service.js";
|
|
11
|
+
declare const RepositoryAnalysisOutput: Schema.Struct<{
|
|
12
|
+
readonly summary: Schema.String;
|
|
13
|
+
readonly userObservableBehaviors: Schema.$Array<Schema.String>;
|
|
14
|
+
readonly constraints: Schema.$Array<Schema.String>;
|
|
15
|
+
readonly risks: Schema.$Array<Schema.String>;
|
|
16
|
+
readonly relevantPaths: Schema.$Array<Schema.String>;
|
|
17
|
+
readonly referenceScope: Schema.optionalKey<Schema.Struct<{
|
|
18
|
+
readonly clauses: Schema.$Array<Schema.Struct<{
|
|
19
|
+
readonly id: Schema.String;
|
|
20
|
+
readonly kind: Schema.Literals<readonly ["changed", "preserved"]>;
|
|
21
|
+
readonly behaviorIds: Schema.$Array<Schema.String>;
|
|
22
|
+
readonly description: Schema.String;
|
|
23
|
+
readonly evidence: Schema.$Array<Schema.Struct<{
|
|
24
|
+
readonly sourceId: Schema.String;
|
|
25
|
+
readonly startLine: Schema.Finite;
|
|
26
|
+
readonly endLine: Schema.Finite;
|
|
27
|
+
}>>;
|
|
28
|
+
}>>;
|
|
29
|
+
readonly unresolvedQuestions: Schema.$Array<Schema.String>;
|
|
30
|
+
}>>;
|
|
31
|
+
}>;
|
|
32
|
+
export type RepositoryAnalysisOutput = typeof RepositoryAnalysisOutput.Type;
|
|
33
|
+
declare const RepositorySpecificationOutput: Schema.Struct<{
|
|
34
|
+
readonly requestText: Schema.String;
|
|
35
|
+
readonly constraints: Schema.$Array<Schema.String>;
|
|
36
|
+
}>;
|
|
37
|
+
export type RepositorySpecificationOutput = typeof RepositorySpecificationOutput.Type;
|
|
38
|
+
declare const RepositorySpecificationReviewOutput: Schema.Struct<{
|
|
39
|
+
readonly verdict: Schema.Literals<readonly ["sufficient", "insufficient"]>;
|
|
40
|
+
readonly detail: Schema.String;
|
|
41
|
+
readonly criticalBehaviorCoverage: Schema.$Array<Schema.Struct<{
|
|
42
|
+
readonly behaviorId: Schema.String;
|
|
43
|
+
readonly outcome: Schema.Literals<readonly ["covered", "omitted", "uncertain"]>;
|
|
44
|
+
readonly detail: Schema.String;
|
|
45
|
+
}>>;
|
|
46
|
+
readonly dimensionFit: Schema.optionalKey<Schema.Struct<{
|
|
47
|
+
readonly requestedDimension: Schema.String;
|
|
48
|
+
readonly outcome: Schema.Literals<readonly ["fit", "mismatch", "uncertain"]>;
|
|
49
|
+
readonly detail: Schema.String;
|
|
50
|
+
readonly evidencePaths: Schema.$Array<Schema.String>;
|
|
51
|
+
}>>;
|
|
52
|
+
readonly referenceCompatibility: Schema.optionalKey<Schema.Struct<{
|
|
53
|
+
readonly outcome: Schema.Literals<readonly ["compatible", "contradictory", "uncertain"]>;
|
|
54
|
+
readonly detail: Schema.String;
|
|
55
|
+
readonly scopeCoverage: Schema.$Array<Schema.Struct<{
|
|
56
|
+
readonly scopeId: Schema.String;
|
|
57
|
+
readonly outcome: Schema.Literals<readonly ["supported", "contradictory", "uncertain"]>;
|
|
58
|
+
readonly detail: Schema.String;
|
|
59
|
+
readonly evidence: Schema.$Array<Schema.Struct<{
|
|
60
|
+
readonly sourceId: Schema.String;
|
|
61
|
+
readonly startLine: Schema.Finite;
|
|
62
|
+
readonly endLine: Schema.Finite;
|
|
63
|
+
}>>;
|
|
64
|
+
}>>;
|
|
65
|
+
readonly questionResolutions: Schema.optionalKey<Schema.$Array<Schema.Struct<{
|
|
66
|
+
readonly questionId: Schema.String;
|
|
67
|
+
readonly outcome: Schema.Literals<readonly ["answered", "not-required", "unresolved"]>;
|
|
68
|
+
readonly detail: Schema.String;
|
|
69
|
+
readonly affectedScopeIds: Schema.$Array<Schema.String>;
|
|
70
|
+
readonly evidence: Schema.$Array<Schema.Struct<{
|
|
71
|
+
readonly sourceId: Schema.String;
|
|
72
|
+
readonly startLine: Schema.Finite;
|
|
73
|
+
readonly endLine: Schema.Finite;
|
|
74
|
+
}>>;
|
|
75
|
+
readonly visibleScopeExclusion: Schema.optionalKey<Schema.Struct<{
|
|
76
|
+
readonly quotation: Schema.String;
|
|
77
|
+
readonly rationale: Schema.String;
|
|
78
|
+
}>>;
|
|
79
|
+
}>>>;
|
|
80
|
+
}>>;
|
|
81
|
+
readonly findings: Schema.$Array<Schema.Struct<{
|
|
82
|
+
readonly axis: Schema.Literals<readonly ["missing-precondition", "unavailable-context", "multiple-interpretations", "hidden-answer-leakage", "unrealistic-phrasing", "unsupported-assumption"]>;
|
|
83
|
+
readonly severity: Schema.Literals<readonly ["blocker", "warning"]>;
|
|
84
|
+
readonly detail: Schema.String;
|
|
85
|
+
}>>;
|
|
86
|
+
}>;
|
|
87
|
+
export type RepositorySpecificationReviewOutput = typeof RepositorySpecificationReviewOutput.Type;
|
|
88
|
+
type RepositoryAuthoredSpecificationReviewV1 = RepositorySpecificationReviewV1 & {
|
|
89
|
+
readonly contractFactReview?: RepositorySpecificationContractFactReviewV1;
|
|
90
|
+
};
|
|
91
|
+
export type RepositoryModelAuthoredCaseSpecificationV1 = {
|
|
92
|
+
readonly version: 1;
|
|
93
|
+
readonly caseId: string;
|
|
94
|
+
readonly analysis: RepositoryAnalysisOutput;
|
|
95
|
+
readonly contextSources: readonly {
|
|
96
|
+
readonly path: string;
|
|
97
|
+
readonly content: string;
|
|
98
|
+
}[];
|
|
99
|
+
readonly visible: RepositoryCandidateVisibleTaskV1;
|
|
100
|
+
readonly reviews: readonly RepositoryAuthoredSpecificationReviewV1[];
|
|
101
|
+
readonly modelCalls: readonly RepositoryFoundryModelCallV1[];
|
|
102
|
+
readonly contractFacts?: RepositorySpecificationAcceptedContractFactsV1;
|
|
103
|
+
readonly groundedTargetBehavior?: RepositoryTaskSeedV1["targetBehavior"];
|
|
104
|
+
readonly referenceGrounding?: {
|
|
105
|
+
readonly beforeCommit: string;
|
|
106
|
+
readonly referenceCommit: string;
|
|
107
|
+
readonly sources: readonly PrivateReferenceSource[];
|
|
108
|
+
readonly scope: RepositorySpecificationReferenceScopeV1;
|
|
109
|
+
};
|
|
110
|
+
readonly specificationRevisions?: readonly {
|
|
111
|
+
readonly sequence: number;
|
|
112
|
+
readonly visible: RepositoryCandidateVisibleTaskV1;
|
|
113
|
+
readonly reviews: readonly RepositoryAuthoredSpecificationReviewV1[];
|
|
114
|
+
readonly rejectionReasons: readonly string[];
|
|
115
|
+
readonly contractFactsDigest?: string;
|
|
116
|
+
}[];
|
|
117
|
+
};
|
|
118
|
+
type RepositoryContextPathCandidate = {
|
|
119
|
+
readonly path: string;
|
|
120
|
+
readonly relationships: readonly string[];
|
|
121
|
+
};
|
|
122
|
+
export declare const repositoryGenerationContextCandidatesV1: (input: {
|
|
123
|
+
readonly map: RepositoryBehaviorMapV1;
|
|
124
|
+
readonly seed: RepositoryTaskSeedV1;
|
|
125
|
+
}) => RepositoryContextPathCandidate[];
|
|
126
|
+
export type CaseAuthoringShape = {
|
|
127
|
+
readonly authorSpecification: (input: {
|
|
128
|
+
readonly repositoryRoot: string;
|
|
129
|
+
readonly operationId: string;
|
|
130
|
+
readonly caseId: string;
|
|
131
|
+
readonly requestedDimension?: string;
|
|
132
|
+
readonly maximumSpecificationRevisions?: number;
|
|
133
|
+
readonly specificationContractFactsVersion?: 1;
|
|
134
|
+
readonly map: RepositoryBehaviorMapV1;
|
|
135
|
+
readonly seed: RepositoryTaskSeedV1;
|
|
136
|
+
readonly family: RepositoryTaskFamilyV1;
|
|
137
|
+
readonly modelPlan: RepositoryFoundryModelPlanV1;
|
|
138
|
+
}) => Effect.Effect<RepositoryModelAuthoredCaseSpecificationV1, import("../../errors.js").RepositoryFoundryError>;
|
|
139
|
+
};
|
|
140
|
+
declare const CaseAuthoring_base: Context.ServiceClass<CaseAuthoring, "@velum-labs/routekit-eval-setup/CaseAuthoring", CaseAuthoringShape>;
|
|
141
|
+
export declare class CaseAuthoring extends CaseAuthoring_base {
|
|
142
|
+
}
|
|
143
|
+
export declare const authorRepositoryCaseSpecificationV1: (input: {
|
|
144
|
+
readonly repositoryRoot: string;
|
|
145
|
+
readonly operationId: string;
|
|
146
|
+
readonly caseId: string;
|
|
147
|
+
readonly requestedDimension?: string;
|
|
148
|
+
readonly maximumSpecificationRevisions?: number;
|
|
149
|
+
readonly specificationContractFactsVersion?: 1;
|
|
150
|
+
readonly map: RepositoryBehaviorMapV1;
|
|
151
|
+
readonly seed: RepositoryTaskSeedV1;
|
|
152
|
+
readonly family: RepositoryTaskFamilyV1;
|
|
153
|
+
readonly modelPlan: RepositoryFoundryModelPlanV1;
|
|
154
|
+
}) => Effect.Effect<RepositoryModelAuthoredCaseSpecificationV1, RepositoryFoundryError, RepositoryFoundryLanguageModel>;
|
|
155
|
+
type PrivateReferenceSource = {
|
|
156
|
+
readonly sourceId: string;
|
|
157
|
+
readonly phase: "before" | "after";
|
|
158
|
+
readonly path: string;
|
|
159
|
+
readonly content: string | null;
|
|
160
|
+
};
|
|
161
|
+
export declare const makeCaseAuthoring: Effect.Effect<CaseAuthoringShape, never, RepositoryFoundryLanguageModel>;
|
|
162
|
+
export declare const CaseAuthoringLive: Layer.Layer<CaseAuthoring, never, RepositoryFoundryLanguageModel>;
|
|
163
|
+
export {};
|