@sanity/ailf 0.1.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/README.md +89 -0
- package/bin/ailf.js +64 -0
- package/canonical/grader-references/README.md +88 -0
- package/canonical/grader-references/groq.yaml +234 -0
- package/canonical/grader-references/studio-setup.yaml +275 -0
- package/canonical/reference-solutions/.gitkeep +1 -0
- package/canonical/reference-solutions/frameworks/nuxt.ts +119 -0
- package/canonical/reference-solutions/frameworks/remix.tsx +100 -0
- package/canonical/reference-solutions/functions/publish-webhook.ts +60 -0
- package/canonical/reference-solutions/groq/advanced-filtering.ts +379 -0
- package/canonical/reference-solutions/groq/blog-queries.ts +137 -0
- package/canonical/reference-solutions/groq/joins-references.ts +300 -0
- package/canonical/reference-solutions/nextjs/app-router-integration.tsx +128 -0
- package/canonical/reference-solutions/studio-setup/blog-schema.ts +143 -0
- package/canonical/reference-solutions/studio-setup/custom-tool.tsx +78 -0
- package/canonical/reference-solutions/visual-editing/live-preview.tsx +137 -0
- package/canonical/reference-solutions/visual-editing/presentation-nextjs.tsx +130 -0
- package/config/airbyte/ai_literacy_framework.connector.yaml +639 -0
- package/config/bigquery/README.md +74 -0
- package/config/bigquery/views/area_scores.sql +87 -0
- package/config/bigquery/views/reports.sql +49 -0
- package/config/features.yaml +116 -0
- package/config/models.yaml +115 -0
- package/config/prompts.yaml +75 -0
- package/config/rubrics.yaml +62 -0
- package/config/schedules.yaml +43 -0
- package/config/sinks.yaml +54 -0
- package/config/sources.yaml +51 -0
- package/config/thresholds.yaml +49 -0
- package/dist/_vendor/ailf-core/examples/index.d.ts +190 -0
- package/dist/_vendor/ailf-core/examples/index.js +285 -0
- package/dist/_vendor/ailf-core/index.d.ts +17 -0
- package/dist/_vendor/ailf-core/index.js +17 -0
- package/dist/_vendor/ailf-core/ports/cache-store.d.ts +72 -0
- package/dist/_vendor/ailf-core/ports/cache-store.js +17 -0
- package/dist/_vendor/ailf-core/ports/config-source.d.ts +33 -0
- package/dist/_vendor/ailf-core/ports/config-source.js +15 -0
- package/dist/_vendor/ailf-core/ports/context.d.ts +172 -0
- package/dist/_vendor/ailf-core/ports/context.js +14 -0
- package/dist/_vendor/ailf-core/ports/doc-fetcher.d.ts +131 -0
- package/dist/_vendor/ailf-core/ports/doc-fetcher.js +12 -0
- package/dist/_vendor/ailf-core/ports/eval-runner.d.ts +24 -0
- package/dist/_vendor/ailf-core/ports/eval-runner.js +8 -0
- package/dist/_vendor/ailf-core/ports/index.d.ts +15 -0
- package/dist/_vendor/ailf-core/ports/index.js +7 -0
- package/dist/_vendor/ailf-core/ports/logger.d.ts +36 -0
- package/dist/_vendor/ailf-core/ports/logger.js +11 -0
- package/dist/_vendor/ailf-core/ports/pipeline-step.d.ts +46 -0
- package/dist/_vendor/ailf-core/ports/pipeline-step.js +8 -0
- package/dist/_vendor/ailf-core/ports/task-source.d.ts +159 -0
- package/dist/_vendor/ailf-core/ports/task-source.js +72 -0
- package/dist/_vendor/ailf-core/schemas/callback-payload.d.ts +24 -0
- package/dist/_vendor/ailf-core/schemas/callback-payload.js +29 -0
- package/dist/_vendor/ailf-core/schemas/eval-config.d.ts +55 -0
- package/dist/_vendor/ailf-core/schemas/eval-config.js +78 -0
- package/dist/_vendor/ailf-core/schemas/index.d.ts +16 -0
- package/dist/_vendor/ailf-core/schemas/index.js +16 -0
- package/dist/_vendor/ailf-core/schemas/pipeline-request.d.ts +125 -0
- package/dist/_vendor/ailf-core/schemas/pipeline-request.js +67 -0
- package/dist/_vendor/ailf-core/schemas/pipeline.d.ts +531 -0
- package/dist/_vendor/ailf-core/schemas/pipeline.js +318 -0
- package/dist/_vendor/ailf-core/schemas/schedules.d.ts +68 -0
- package/dist/_vendor/ailf-core/schemas/schedules.js +74 -0
- package/dist/_vendor/ailf-core/schemas/sinks.d.ts +207 -0
- package/dist/_vendor/ailf-core/schemas/sinks.js +108 -0
- package/dist/_vendor/ailf-core/services/comparison-formatters.d.ts +18 -0
- package/dist/_vendor/ailf-core/services/comparison-formatters.js +189 -0
- package/dist/_vendor/ailf-core/services/config-helpers.d.ts +41 -0
- package/dist/_vendor/ailf-core/services/config-helpers.js +86 -0
- package/dist/_vendor/ailf-core/services/index.d.ts +12 -0
- package/dist/_vendor/ailf-core/services/index.js +12 -0
- package/dist/_vendor/ailf-core/services/scoring.d.ts +49 -0
- package/dist/_vendor/ailf-core/services/scoring.js +222 -0
- package/dist/_vendor/ailf-core/types/index.d.ts +1082 -0
- package/dist/_vendor/ailf-core/types/index.js +21 -0
- package/dist/_vendor/ailf-core/types/scoring-input.d.ts +54 -0
- package/dist/_vendor/ailf-core/types/scoring-input.js +9 -0
- package/dist/_vendor/ailf-shared/dimension-names.d.ts +21 -0
- package/dist/_vendor/ailf-shared/dimension-names.js +27 -0
- package/dist/_vendor/ailf-shared/document-ref.d.ts +29 -0
- package/dist/_vendor/ailf-shared/document-ref.js +1 -0
- package/dist/_vendor/ailf-shared/eval-modes.d.ts +12 -0
- package/dist/_vendor/ailf-shared/eval-modes.js +8 -0
- package/dist/_vendor/ailf-shared/index.d.ts +16 -0
- package/dist/_vendor/ailf-shared/index.js +16 -0
- package/dist/_vendor/ailf-shared/noise-threshold.d.ts +9 -0
- package/dist/_vendor/ailf-shared/noise-threshold.js +9 -0
- package/dist/_vendor/ailf-shared/score-grades.d.ts +17 -0
- package/dist/_vendor/ailf-shared/score-grades.js +23 -0
- package/dist/adapters/cache/content-lake-cache.d.ts +24 -0
- package/dist/adapters/cache/content-lake-cache.js +59 -0
- package/dist/adapters/cache/filesystem-cache.d.ts +18 -0
- package/dist/adapters/cache/filesystem-cache.js +54 -0
- package/dist/adapters/cache/index.d.ts +2 -0
- package/dist/adapters/cache/index.js +2 -0
- package/dist/adapters/config-sources/cli-config-adapter.d.ts +17 -0
- package/dist/adapters/config-sources/cli-config-adapter.js +23 -0
- package/dist/adapters/config-sources/file-config-adapter.d.ts +26 -0
- package/dist/adapters/config-sources/file-config-adapter.js +96 -0
- package/dist/adapters/config-sources/index.d.ts +2 -0
- package/dist/adapters/config-sources/index.js +2 -0
- package/dist/adapters/doc-fetchers/index.d.ts +1 -0
- package/dist/adapters/doc-fetchers/index.js +1 -0
- package/dist/adapters/doc-fetchers/sanity-doc-fetcher.d.ts +76 -0
- package/dist/adapters/doc-fetchers/sanity-doc-fetcher.js +620 -0
- package/dist/adapters/eval-runners/index.d.ts +1 -0
- package/dist/adapters/eval-runners/index.js +1 -0
- package/dist/adapters/eval-runners/promptfoo-eval-adapter.d.ts +14 -0
- package/dist/adapters/eval-runners/promptfoo-eval-adapter.js +63 -0
- package/dist/adapters/index.d.ts +12 -0
- package/dist/adapters/index.js +12 -0
- package/dist/adapters/loggers/console-logger.d.ts +22 -0
- package/dist/adapters/loggers/console-logger.js +54 -0
- package/dist/adapters/loggers/index.d.ts +9 -0
- package/dist/adapters/loggers/index.js +9 -0
- package/dist/adapters/loggers/json-logger.d.ts +18 -0
- package/dist/adapters/loggers/json-logger.js +33 -0
- package/dist/adapters/loggers/quiet-logger.d.ts +16 -0
- package/dist/adapters/loggers/quiet-logger.js +30 -0
- package/dist/adapters/task-sources/composite-task-source.d.ts +20 -0
- package/dist/adapters/task-sources/composite-task-source.js +59 -0
- package/dist/adapters/task-sources/content-lake-task-source.d.ts +20 -0
- package/dist/adapters/task-sources/content-lake-task-source.js +219 -0
- package/dist/adapters/task-sources/index.d.ts +7 -0
- package/dist/adapters/task-sources/index.js +7 -0
- package/dist/adapters/task-sources/repo-schemas.d.ts +245 -0
- package/dist/adapters/task-sources/repo-schemas.js +234 -0
- package/dist/adapters/task-sources/repo-task-source.d.ts +22 -0
- package/dist/adapters/task-sources/repo-task-source.js +104 -0
- package/dist/adapters/task-sources/repo-trigger.d.ts +52 -0
- package/dist/adapters/task-sources/repo-trigger.js +153 -0
- package/dist/adapters/task-sources/repo-validation.d.ts +49 -0
- package/dist/adapters/task-sources/repo-validation.js +164 -0
- package/dist/adapters/task-sources/yaml-task-source.d.ts +18 -0
- package/dist/adapters/task-sources/yaml-task-source.js +136 -0
- package/dist/agent-observer/agentic-provider.d.ts +132 -0
- package/dist/agent-observer/agentic-provider.js +983 -0
- package/dist/agent-observer/classifier.d.ts +62 -0
- package/dist/agent-observer/classifier.js +269 -0
- package/dist/agent-observer/index.d.ts +7 -0
- package/dist/agent-observer/index.js +4 -0
- package/dist/agent-observer/pricing.d.ts +35 -0
- package/dist/agent-observer/pricing.js +82 -0
- package/dist/agent-observer/provider.d.ts +77 -0
- package/dist/agent-observer/provider.js +151 -0
- package/dist/agent-observer/proxy.d.ts +91 -0
- package/dist/agent-observer/proxy.js +321 -0
- package/dist/agent-observer/test-imports.d.ts +7 -0
- package/dist/agent-observer/test-imports.js +185 -0
- package/dist/agent-observer/types.d.ts +137 -0
- package/dist/agent-observer/types.js +16 -0
- package/dist/assertions/source-isolation.d.ts +72 -0
- package/dist/assertions/source-isolation.js +117 -0
- package/dist/cli.d.ts +24 -0
- package/dist/cli.js +199 -0
- package/dist/commands/agent-report.d.ts +5 -0
- package/dist/commands/agent-report.js +69 -0
- package/dist/commands/baseline.d.ts +9 -0
- package/dist/commands/baseline.js +141 -0
- package/dist/commands/cache.d.ts +13 -0
- package/dist/commands/cache.js +135 -0
- package/dist/commands/calculate-scores.d.ts +8 -0
- package/dist/commands/calculate-scores.js +48 -0
- package/dist/commands/compare.d.ts +8 -0
- package/dist/commands/compare.js +120 -0
- package/dist/commands/completion.d.ts +18 -0
- package/dist/commands/completion.js +260 -0
- package/dist/commands/coverage-audit.d.ts +7 -0
- package/dist/commands/coverage-audit.js +40 -0
- package/dist/commands/discovery-report.d.ts +10 -0
- package/dist/commands/discovery-report.js +44 -0
- package/dist/commands/eval.d.ts +9 -0
- package/dist/commands/eval.js +35 -0
- package/dist/commands/explain-handler.d.ts +34 -0
- package/dist/commands/explain-handler.js +719 -0
- package/dist/commands/fetch-docs.d.ts +8 -0
- package/dist/commands/fetch-docs.js +128 -0
- package/dist/commands/generate-configs.d.ts +8 -0
- package/dist/commands/generate-configs.js +46 -0
- package/dist/commands/grader/index.d.ts +11 -0
- package/dist/commands/grader/index.js +118 -0
- package/dist/commands/init.d.ts +19 -0
- package/dist/commands/init.js +150 -0
- package/dist/commands/interactive.d.ts +12 -0
- package/dist/commands/interactive.js +238 -0
- package/dist/commands/lookup-doc.d.ts +15 -0
- package/dist/commands/lookup-doc.js +84 -0
- package/dist/commands/measure-retrieval.d.ts +5 -0
- package/dist/commands/measure-retrieval.js +65 -0
- package/dist/commands/pipeline-action.d.ts +71 -0
- package/dist/commands/pipeline-action.js +305 -0
- package/dist/commands/pipeline.d.ts +62 -0
- package/dist/commands/pipeline.js +53 -0
- package/dist/commands/pr-comment.d.ts +8 -0
- package/dist/commands/pr-comment.js +47 -0
- package/dist/commands/publish.d.ts +26 -0
- package/dist/commands/publish.js +253 -0
- package/dist/commands/readiness-report.d.ts +10 -0
- package/dist/commands/readiness-report.js +104 -0
- package/dist/commands/shared/options.d.ts +29 -0
- package/dist/commands/shared/options.js +57 -0
- package/dist/commands/update-quality-scores.d.ts +5 -0
- package/dist/commands/update-quality-scores.js +20 -0
- package/dist/commands/validate-tasks.d.ts +16 -0
- package/dist/commands/validate-tasks.js +93 -0
- package/dist/commands/validate.d.ts +9 -0
- package/dist/commands/validate.js +73 -0
- package/dist/commands/webhook-server.d.ts +5 -0
- package/dist/commands/webhook-server.js +30 -0
- package/dist/commands/weekly-digest.d.ts +10 -0
- package/dist/commands/weekly-digest.js +104 -0
- package/dist/composition-root.d.ts +26 -0
- package/dist/composition-root.js +107 -0
- package/dist/interpolate.d.ts +26 -0
- package/dist/interpolate.js +70 -0
- package/dist/job-store.d.ts +104 -0
- package/dist/job-store.js +188 -0
- package/dist/lib/agent-behavior-report.d.ts +8 -0
- package/dist/lib/agent-behavior-report.js +185 -0
- package/dist/lib/baseline.d.ts +19 -0
- package/dist/lib/baseline.js +153 -0
- package/dist/lib/calculate-scores.d.ts +23 -0
- package/dist/lib/calculate-scores.js +42 -0
- package/dist/lib/compare.d.ts +18 -0
- package/dist/lib/compare.js +170 -0
- package/dist/lib/coverage-audit.d.ts +4 -0
- package/dist/lib/coverage-audit.js +42 -0
- package/dist/lib/discovery-report.d.ts +13 -0
- package/dist/lib/discovery-report.js +57 -0
- package/dist/lib/fetch-docs.d.ts +30 -0
- package/dist/lib/fetch-docs.js +171 -0
- package/dist/lib/generate-configs.d.ts +25 -0
- package/dist/lib/generate-configs.js +42 -0
- package/dist/lib/grader-api.d.ts +21 -0
- package/dist/lib/grader-api.js +34 -0
- package/dist/lib/grader-compare.d.ts +19 -0
- package/dist/lib/grader-compare.js +91 -0
- package/dist/lib/grader-consistency.d.ts +27 -0
- package/dist/lib/grader-consistency.js +79 -0
- package/dist/lib/grader-sensitivity.d.ts +19 -0
- package/dist/lib/grader-sensitivity.js +75 -0
- package/dist/lib/grader-validate.d.ts +19 -0
- package/dist/lib/grader-validate.js +78 -0
- package/dist/lib/measure-retrieval.d.ts +14 -0
- package/dist/lib/measure-retrieval.js +71 -0
- package/dist/lib/pr-comment.d.ts +16 -0
- package/dist/lib/pr-comment.js +28 -0
- package/dist/lib/readiness-report.d.ts +13 -0
- package/dist/lib/readiness-report.js +108 -0
- package/dist/lib/webhook-server.d.ts +11 -0
- package/dist/lib/webhook-server.js +24 -0
- package/dist/lib/weekly-digest.d.ts +24 -0
- package/dist/lib/weekly-digest.js +148 -0
- package/dist/orchestration/build-app-context.d.ts +27 -0
- package/dist/orchestration/build-app-context.js +81 -0
- package/dist/orchestration/build-step-sequence.d.ts +15 -0
- package/dist/orchestration/build-step-sequence.js +84 -0
- package/dist/orchestration/config-to-source-overrides.d.ts +9 -0
- package/dist/orchestration/config-to-source-overrides.js +28 -0
- package/dist/orchestration/env-bridge.d.ts +21 -0
- package/dist/orchestration/env-bridge.js +66 -0
- package/dist/orchestration/index.d.ts +11 -0
- package/dist/orchestration/index.js +11 -0
- package/dist/orchestration/pipeline-orchestrator.d.ts +24 -0
- package/dist/orchestration/pipeline-orchestrator.js +153 -0
- package/dist/orchestration/step-runner.d.ts +20 -0
- package/dist/orchestration/step-runner.js +88 -0
- package/dist/orchestration/steps/calculate-scores-step.d.ts +13 -0
- package/dist/orchestration/steps/calculate-scores-step.js +95 -0
- package/dist/orchestration/steps/callback-step.d.ts +24 -0
- package/dist/orchestration/steps/callback-step.js +76 -0
- package/dist/orchestration/steps/compare-step.d.ts +14 -0
- package/dist/orchestration/steps/compare-step.js +92 -0
- package/dist/orchestration/steps/discovery-report-step.d.ts +13 -0
- package/dist/orchestration/steps/discovery-report-step.js +55 -0
- package/dist/orchestration/steps/fetch-docs-shell.d.ts +17 -0
- package/dist/orchestration/steps/fetch-docs-shell.js +30 -0
- package/dist/orchestration/steps/fetch-docs-step.d.ts +14 -0
- package/dist/orchestration/steps/fetch-docs-step.js +135 -0
- package/dist/orchestration/steps/gap-analysis-step.d.ts +16 -0
- package/dist/orchestration/steps/gap-analysis-step.js +136 -0
- package/dist/orchestration/steps/generate-configs-step.d.ts +14 -0
- package/dist/orchestration/steps/generate-configs-step.js +85 -0
- package/dist/orchestration/steps/grader-consistency-step.d.ts +13 -0
- package/dist/orchestration/steps/grader-consistency-step.js +64 -0
- package/dist/orchestration/steps/index.d.ts +19 -0
- package/dist/orchestration/steps/index.js +19 -0
- package/dist/orchestration/steps/mirror-repo-tasks-step.d.ts +21 -0
- package/dist/orchestration/steps/mirror-repo-tasks-step.js +94 -0
- package/dist/orchestration/steps/publish-report-step.d.ts +26 -0
- package/dist/orchestration/steps/publish-report-step.js +216 -0
- package/dist/orchestration/steps/readiness-step.d.ts +13 -0
- package/dist/orchestration/steps/readiness-step.js +91 -0
- package/dist/orchestration/steps/report-step.d.ts +12 -0
- package/dist/orchestration/steps/report-step.js +49 -0
- package/dist/orchestration/steps/run-eval-step.d.ts +17 -0
- package/dist/orchestration/steps/run-eval-step.js +195 -0
- package/dist/orchestration/steps/validate-step.d.ts +12 -0
- package/dist/orchestration/steps/validate-step.js +41 -0
- package/dist/pipeline/agent-behavior-report.d.ts +53 -0
- package/dist/pipeline/agent-behavior-report.js +132 -0
- package/dist/pipeline/attribution.d.ts +47 -0
- package/dist/pipeline/attribution.js +226 -0
- package/dist/pipeline/baseline.d.ts +37 -0
- package/dist/pipeline/baseline.js +141 -0
- package/dist/pipeline/cache.d.ts +101 -0
- package/dist/pipeline/cache.js +283 -0
- package/dist/pipeline/calculate-scores.d.ts +102 -0
- package/dist/pipeline/calculate-scores.js +1128 -0
- package/dist/pipeline/callback-delivery.d.ts +50 -0
- package/dist/pipeline/callback-delivery.js +89 -0
- package/dist/pipeline/checks.d.ts +39 -0
- package/dist/pipeline/checks.js +280 -0
- package/dist/pipeline/classify-url.d.ts +61 -0
- package/dist/pipeline/classify-url.js +93 -0
- package/dist/pipeline/compare.d.ts +31 -0
- package/dist/pipeline/compare.js +208 -0
- package/dist/pipeline/coverage-audit.d.ts +39 -0
- package/dist/pipeline/coverage-audit.js +165 -0
- package/dist/pipeline/degradations.d.ts +85 -0
- package/dist/pipeline/degradations.js +242 -0
- package/dist/pipeline/discovery-report.d.ts +55 -0
- package/dist/pipeline/discovery-report.js +178 -0
- package/dist/pipeline/eval-constants.d.ts +68 -0
- package/dist/pipeline/eval-constants.js +111 -0
- package/dist/pipeline/eval-fingerprint.d.ts +66 -0
- package/dist/pipeline/eval-fingerprint.js +175 -0
- package/dist/pipeline/expand-tasks.d.ts +220 -0
- package/dist/pipeline/expand-tasks.js +421 -0
- package/dist/pipeline/failure-modes.d.ts +46 -0
- package/dist/pipeline/failure-modes.js +348 -0
- package/dist/pipeline/fetch-url-content.d.ts +44 -0
- package/dist/pipeline/fetch-url-content.js +93 -0
- package/dist/pipeline/gap-analysis.d.ts +48 -0
- package/dist/pipeline/gap-analysis.js +231 -0
- package/dist/pipeline/generate-configs.d.ts +72 -0
- package/dist/pipeline/generate-configs.js +395 -0
- package/dist/pipeline/grader-api.d.ts +49 -0
- package/dist/pipeline/grader-api.js +200 -0
- package/dist/pipeline/grader-compare-runner.d.ts +44 -0
- package/dist/pipeline/grader-compare-runner.js +301 -0
- package/dist/pipeline/grader-comparison.d.ts +111 -0
- package/dist/pipeline/grader-comparison.js +161 -0
- package/dist/pipeline/grader-consistency-runner.d.ts +60 -0
- package/dist/pipeline/grader-consistency-runner.js +270 -0
- package/dist/pipeline/grader-consistency.d.ts +103 -0
- package/dist/pipeline/grader-consistency.js +146 -0
- package/dist/pipeline/grader-sensitivity-runner.d.ts +40 -0
- package/dist/pipeline/grader-sensitivity-runner.js +282 -0
- package/dist/pipeline/grader-sensitivity.d.ts +94 -0
- package/dist/pipeline/grader-sensitivity.js +144 -0
- package/dist/pipeline/grader-validate-runner.d.ts +38 -0
- package/dist/pipeline/grader-validate-runner.js +229 -0
- package/dist/pipeline/grader-validation.d.ts +107 -0
- package/dist/pipeline/grader-validation.js +169 -0
- package/dist/pipeline/map-request-to-config.d.ts +19 -0
- package/dist/pipeline/map-request-to-config.js +80 -0
- package/dist/pipeline/measure-retrieval.d.ts +59 -0
- package/dist/pipeline/measure-retrieval.js +111 -0
- package/dist/pipeline/mirror-repo-tasks.d.ts +86 -0
- package/dist/pipeline/mirror-repo-tasks.js +350 -0
- package/dist/pipeline/plan-format.d.ts +33 -0
- package/dist/pipeline/plan-format.js +202 -0
- package/dist/pipeline/plan.d.ts +169 -0
- package/dist/pipeline/plan.js +708 -0
- package/dist/pipeline/pr-comment.d.ts +19 -0
- package/dist/pipeline/pr-comment.js +502 -0
- package/dist/pipeline/probe.d.ts +52 -0
- package/dist/pipeline/probe.js +390 -0
- package/dist/pipeline/provenance.d.ts +47 -0
- package/dist/pipeline/provenance.js +146 -0
- package/dist/pipeline/readiness-report.d.ts +87 -0
- package/dist/pipeline/readiness-report.js +205 -0
- package/dist/pipeline/release-classification.d.ts +54 -0
- package/dist/pipeline/release-classification.js +238 -0
- package/dist/pipeline/release-report.d.ts +37 -0
- package/dist/pipeline/release-report.js +222 -0
- package/dist/pipeline/repo-eval-comment.d.ts +37 -0
- package/dist/pipeline/repo-eval-comment.js +165 -0
- package/dist/pipeline/repo-threshold-evaluator.d.ts +89 -0
- package/dist/pipeline/repo-threshold-evaluator.js +162 -0
- package/dist/pipeline/resolve-mappings.d.ts +35 -0
- package/dist/pipeline/resolve-mappings.js +72 -0
- package/dist/pipeline/retrieval-metrics.d.ts +39 -0
- package/dist/pipeline/retrieval-metrics.js +136 -0
- package/dist/pipeline/reverse-mapping.d.ts +67 -0
- package/dist/pipeline/reverse-mapping.js +88 -0
- package/dist/pipeline/schemas.d.ts +9 -0
- package/dist/pipeline/schemas.js +9 -0
- package/dist/pipeline/steps/calculate-scores-step.d.ts +11 -0
- package/dist/pipeline/steps/calculate-scores-step.js +89 -0
- package/dist/pipeline/steps/compare-step.d.ts +18 -0
- package/dist/pipeline/steps/compare-step.js +90 -0
- package/dist/pipeline/steps/eval-step.d.ts +53 -0
- package/dist/pipeline/steps/eval-step.js +347 -0
- package/dist/pipeline/steps/fetch-docs-step.d.ts +11 -0
- package/dist/pipeline/steps/fetch-docs-step.js +84 -0
- package/dist/pipeline/steps/generate-configs-step.d.ts +11 -0
- package/dist/pipeline/steps/generate-configs-step.js +98 -0
- package/dist/pipeline/steps/grader-consistency-step.d.ts +21 -0
- package/dist/pipeline/steps/grader-consistency-step.js +74 -0
- package/dist/pipeline/steps/publish-report-step.d.ts +57 -0
- package/dist/pipeline/steps/publish-report-step.js +243 -0
- package/dist/pipeline/steps/report-step.d.ts +13 -0
- package/dist/pipeline/steps/report-step.js +56 -0
- package/dist/pipeline/steps/update-scores-step.d.ts +11 -0
- package/dist/pipeline/steps/update-scores-step.js +42 -0
- package/dist/pipeline/targeted-loo.d.ts +88 -0
- package/dist/pipeline/targeted-loo.js +203 -0
- package/dist/pipeline/thresholds.d.ts +27 -0
- package/dist/pipeline/thresholds.js +245 -0
- package/dist/pipeline/types.d.ts +10 -0
- package/dist/pipeline/types.js +10 -0
- package/dist/pipeline/validate.d.ts +67 -0
- package/dist/pipeline/validate.js +406 -0
- package/dist/pipeline/webhook-server.d.ts +37 -0
- package/dist/pipeline/webhook-server.js +133 -0
- package/dist/report-store.d.ts +84 -0
- package/dist/report-store.js +208 -0
- package/dist/sanity/client.d.ts +38 -0
- package/dist/sanity/client.js +86 -0
- package/dist/sanity/portable-text.d.ts +11 -0
- package/dist/sanity/portable-text.js +211 -0
- package/dist/sanity/queries.d.ts +133 -0
- package/dist/sanity/queries.js +300 -0
- package/dist/schedules/digest.d.ts +116 -0
- package/dist/schedules/digest.js +156 -0
- package/dist/schedules/index.d.ts +12 -0
- package/dist/schedules/index.js +10 -0
- package/dist/schedules/loader.d.ts +31 -0
- package/dist/schedules/loader.js +73 -0
- package/dist/schedules/schema.d.ts +9 -0
- package/dist/schedules/schema.js +9 -0
- package/dist/scripts/agent-behavior-report.d.ts +19 -0
- package/dist/scripts/agent-behavior-report.js +315 -0
- package/dist/scripts/baseline.d.ts +43 -0
- package/dist/scripts/baseline.js +267 -0
- package/dist/scripts/calculate-scores.d.ts +166 -0
- package/dist/scripts/calculate-scores.js +1296 -0
- package/dist/scripts/compare.d.ts +22 -0
- package/dist/scripts/compare.js +334 -0
- package/dist/scripts/coverage-audit.d.ts +44 -0
- package/dist/scripts/coverage-audit.js +209 -0
- package/dist/scripts/debug-eval.d.ts +19 -0
- package/dist/scripts/debug-eval.js +73 -0
- package/dist/scripts/discovery-report.d.ts +58 -0
- package/dist/scripts/discovery-report.js +250 -0
- package/dist/scripts/fetch-docs.d.ts +35 -0
- package/dist/scripts/fetch-docs.js +472 -0
- package/dist/scripts/generate-configs.d.ts +66 -0
- package/dist/scripts/generate-configs.js +459 -0
- package/dist/scripts/grader-api.d.ts +27 -0
- package/dist/scripts/grader-api.js +206 -0
- package/dist/scripts/grader-compare.d.ts +22 -0
- package/dist/scripts/grader-compare.js +368 -0
- package/dist/scripts/grader-consistency.d.ts +20 -0
- package/dist/scripts/grader-consistency.js +313 -0
- package/dist/scripts/grader-sensitivity.d.ts +22 -0
- package/dist/scripts/grader-sensitivity.js +354 -0
- package/dist/scripts/grader-validate.d.ts +19 -0
- package/dist/scripts/grader-validate.js +267 -0
- package/dist/scripts/measure-retrieval.d.ts +10 -0
- package/dist/scripts/measure-retrieval.js +145 -0
- package/dist/scripts/migrate-tasks-to-content-lake.d.ts +24 -0
- package/dist/scripts/migrate-tasks-to-content-lake.js +327 -0
- package/dist/scripts/pipeline.d.ts +76 -0
- package/dist/scripts/pipeline.js +1031 -0
- package/dist/scripts/pr-comment.d.ts +10 -0
- package/dist/scripts/pr-comment.js +510 -0
- package/dist/scripts/readiness-report.d.ts +88 -0
- package/dist/scripts/readiness-report.js +342 -0
- package/dist/scripts/update-quality-scores.d.ts +15 -0
- package/dist/scripts/update-quality-scores.js +184 -0
- package/dist/scripts/validate-task-sources.d.ts +21 -0
- package/dist/scripts/validate-task-sources.js +210 -0
- package/dist/scripts/validate.d.ts +13 -0
- package/dist/scripts/validate.js +79 -0
- package/dist/scripts/webhook-server.d.ts +26 -0
- package/dist/scripts/webhook-server.js +147 -0
- package/dist/scripts/weekly-digest.d.ts +24 -0
- package/dist/scripts/weekly-digest.js +144 -0
- package/dist/sinks/bigquery/index.d.ts +131 -0
- package/dist/sinks/bigquery/index.js +222 -0
- package/dist/sinks/format-slack.d.ts +64 -0
- package/dist/sinks/format-slack.js +306 -0
- package/dist/sinks/index.d.ts +23 -0
- package/dist/sinks/index.js +18 -0
- package/dist/sinks/loader.d.ts +18 -0
- package/dist/sinks/loader.js +82 -0
- package/dist/sinks/retry.d.ts +24 -0
- package/dist/sinks/retry.js +52 -0
- package/dist/sinks/schema.d.ts +9 -0
- package/dist/sinks/schema.js +9 -0
- package/dist/sinks/slack/format.d.ts +65 -0
- package/dist/sinks/slack/format.js +327 -0
- package/dist/sinks/slack/index.d.ts +27 -0
- package/dist/sinks/slack/index.js +78 -0
- package/dist/sinks/slack-sink.d.ts +27 -0
- package/dist/sinks/slack-sink.js +78 -0
- package/dist/sinks/types.d.ts +59 -0
- package/dist/sinks/types.js +44 -0
- package/dist/sinks/webhook/index.d.ts +19 -0
- package/dist/sinks/webhook/index.js +50 -0
- package/dist/sinks/webhook-sink.d.ts +19 -0
- package/dist/sinks/webhook-sink.js +50 -0
- package/dist/sources.d.ts +104 -0
- package/dist/sources.js +292 -0
- package/dist/webhook/budget.d.ts +42 -0
- package/dist/webhook/budget.js +60 -0
- package/dist/webhook/debounce.d.ts +67 -0
- package/dist/webhook/debounce.js +76 -0
- package/dist/webhook/dispatch.d.ts +45 -0
- package/dist/webhook/dispatch.js +84 -0
- package/dist/webhook/eval-request-handler.d.ts +87 -0
- package/dist/webhook/eval-request-handler.js +181 -0
- package/dist/webhook/handler.d.ts +88 -0
- package/dist/webhook/handler.js +203 -0
- package/dist/webhook/index.d.ts +17 -0
- package/dist/webhook/index.js +12 -0
- package/dist/webhook/types.d.ts +109 -0
- package/dist/webhook/types.js +10 -0
- package/package.json +72 -0
- package/tasks/.expanded.agentic.yaml +51 -0
- package/tasks/.expanded.yaml +66 -0
- package/tasks/frameworks.yaml +98 -0
- package/tasks/functions.yaml +51 -0
- package/tasks/groq.yaml +216 -0
- package/tasks/nextjs-live.yaml +62 -0
- package/tasks/studio-setup.yaml +111 -0
- package/tasks/visual-editing.yaml +120 -0
|
@@ -0,0 +1,620 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SanityDocFetcher — full adapter for the DocFetcher port.
|
|
3
|
+
*
|
|
4
|
+
* Fetches documentation from the Sanity Content Lake with support for:
|
|
5
|
+
* - Basic slug-based fetching (GROQ → Portable Text → Markdown)
|
|
6
|
+
* - Perspective-aware fetching (content release diffing)
|
|
7
|
+
* - Document overlays (replace/append canonical docs by document ID)
|
|
8
|
+
* - Direct URL fetching (markdown endpoints + content negotiation)
|
|
9
|
+
* - Custom HTTP headers
|
|
10
|
+
* - Document manifest (traceability: _id, _rev, slug, title)
|
|
11
|
+
* - Release impact metadata (added/modified/removed/unchanged)
|
|
12
|
+
*
|
|
13
|
+
* The pipeline step (FetchDocsStep) calls ctx.docFetcher.fetch() and
|
|
14
|
+
* writes the returned metadata to disk for downstream consumption.
|
|
15
|
+
*/
|
|
16
|
+
import { mkdirSync, writeFileSync } from "fs";
|
|
17
|
+
import { join } from "path";
|
|
18
|
+
import { canonicalDocRefLabel, isIdRef, isPathRef, isPerspectiveRef, isSlugRef, } from "../../_vendor/ailf-core/index.js";
|
|
19
|
+
import { fetchUrlContent, } from "../../pipeline/fetch-url-content.js";
|
|
20
|
+
import { createPerspectiveClient, createPublishedClient, getSanityClient, } from "../../sanity/client.js";
|
|
21
|
+
import { toMarkdown } from "../../sanity/portable-text.js";
|
|
22
|
+
import { ALL_ARTICLES_QUERY, ALL_FEATURE_AREAS, ARTICLE_BY_ID_QUERY, ARTICLE_BY_SLUG_QUERY, ARTICLE_BY_SLUG_WITH_PERSPECTIVE_QUERY, ARTICLE_SLUG_BY_PATH_QUERY, ARTICLE_SLUG_BY_SECTION_PATH_QUERY, ARTICLES_IN_RELEASE_QUERY, ARTICLES_METADATA_BY_SLUGS_QUERY, FEATURE_AREA_QUERIES, } from "../../sanity/queries.js";
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Helpers
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
/**
|
|
27
|
+
* Escape `{{` and `}}` so Promptfoo's Nunjucks template engine doesn't
|
|
28
|
+
* try to interpret them as template variables (e.g. Vue `{{ post.title }}`
|
|
29
|
+
* in Nuxt docs would break Nunjucks parsing).
|
|
30
|
+
*/
|
|
31
|
+
function escapeNunjucks(text) {
|
|
32
|
+
return text.replace(/\{\{|\}\}/g, (match) => match === "{{" ? '{{ "{{" }}' : '{{ "}}" }}');
|
|
33
|
+
}
|
|
34
|
+
function estimateTokens(text) {
|
|
35
|
+
return Math.ceil(text.length / 4);
|
|
36
|
+
}
|
|
37
|
+
function formatArticle(doc) {
|
|
38
|
+
const sectionLabel = doc.section ? `Section: ${doc.section.title}\n` : "";
|
|
39
|
+
const desc = doc.description ? `${doc.description}\n\n` : "";
|
|
40
|
+
const markdown = toMarkdown(doc.content ?? []);
|
|
41
|
+
return `## ${doc.title}\n\n${sectionLabel}${desc}${markdown}`;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Bridge DocSourceConfig (domain type) to getSanityClient overrides.
|
|
45
|
+
*
|
|
46
|
+
* DocSourceConfig is the port's domain type; the Sanity client expects
|
|
47
|
+
* its own config shape. This bridges the gap.
|
|
48
|
+
*/
|
|
49
|
+
function toSanityOverrides(source) {
|
|
50
|
+
if (!source)
|
|
51
|
+
return undefined;
|
|
52
|
+
const overrides = {};
|
|
53
|
+
if (source.dataset)
|
|
54
|
+
overrides.dataset = source.dataset;
|
|
55
|
+
if (source.projectId)
|
|
56
|
+
overrides.projectId = source.projectId;
|
|
57
|
+
return Object.keys(overrides).length > 0 ? overrides : undefined;
|
|
58
|
+
}
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// SanityDocFetcher
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
export class SanityDocFetcher {
|
|
63
|
+
rootDir;
|
|
64
|
+
constructor(rootDir) {
|
|
65
|
+
this.rootDir = rootDir;
|
|
66
|
+
}
|
|
67
|
+
async fetch(tasks, source) {
|
|
68
|
+
// 1. Collect all unique slugs and IDs across every task.
|
|
69
|
+
// ID refs are resolved to slugs via a batch query so the rest of the
|
|
70
|
+
// slug-based pipeline works unchanged.
|
|
71
|
+
const allSlugs = new Set();
|
|
72
|
+
const idRefs = [];
|
|
73
|
+
const pathRefs = [];
|
|
74
|
+
const perspectiveRefs = [];
|
|
75
|
+
for (const task of tasks) {
|
|
76
|
+
for (const ref of task.canonicalDocs) {
|
|
77
|
+
if (isSlugRef(ref)) {
|
|
78
|
+
allSlugs.add(ref.slug);
|
|
79
|
+
}
|
|
80
|
+
else if (isIdRef(ref)) {
|
|
81
|
+
idRefs.push({ id: ref.id, taskId: task.id });
|
|
82
|
+
}
|
|
83
|
+
else if (isPathRef(ref)) {
|
|
84
|
+
pathRefs.push({ path: ref.path, taskId: task.id });
|
|
85
|
+
}
|
|
86
|
+
else if (isPerspectiveRef(ref)) {
|
|
87
|
+
perspectiveRefs.push({
|
|
88
|
+
perspective: ref.perspective,
|
|
89
|
+
taskId: task.id,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
console.warn(` [warn] Skipping unsupported canonical doc ref: ${canonicalDocRefLabel(ref)}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Resolve ID refs → slugs via batch query
|
|
98
|
+
const idToSlug = await this.resolveIdRefsToSlugs(idRefs, source);
|
|
99
|
+
for (const slug of idToSlug.values()) {
|
|
100
|
+
allSlugs.add(slug);
|
|
101
|
+
}
|
|
102
|
+
// Resolve path refs → slugs
|
|
103
|
+
const pathToSlug = await this.resolvePathRefsToSlugs(pathRefs, source);
|
|
104
|
+
for (const slug of pathToSlug.values()) {
|
|
105
|
+
allSlugs.add(slug);
|
|
106
|
+
}
|
|
107
|
+
// Resolve perspective refs → slugs (one-to-many: each release expands
|
|
108
|
+
// to all articles versioned within it)
|
|
109
|
+
const perspectiveToSlugs = await this.resolvePerspectiveRefsToSlugs(perspectiveRefs, source);
|
|
110
|
+
for (const slugs of perspectiveToSlugs.values()) {
|
|
111
|
+
for (const slug of slugs) {
|
|
112
|
+
allSlugs.add(slug);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const metadata = {};
|
|
116
|
+
// 2. Fetch document manifest (traceability metadata)
|
|
117
|
+
const manifest = await this.fetchManifest(allSlugs, source);
|
|
118
|
+
if (manifest.length > 0) {
|
|
119
|
+
metadata.manifest = manifest;
|
|
120
|
+
}
|
|
121
|
+
// 3. Perspective diffing — identify which docs changed in the release
|
|
122
|
+
let releaseImpact;
|
|
123
|
+
if (source?.perspective) {
|
|
124
|
+
releaseImpact = await this.identifyAffectedDocs([...allSlugs], source);
|
|
125
|
+
metadata.releaseImpact = releaseImpact;
|
|
126
|
+
const affected = releaseImpact.added.length +
|
|
127
|
+
releaseImpact.modified.length +
|
|
128
|
+
releaseImpact.removed.length;
|
|
129
|
+
console.log(` Perspective diff: ${affected} of ${allSlugs.size} canonical docs affected`);
|
|
130
|
+
if (releaseImpact.added.length > 0)
|
|
131
|
+
console.log(` Added: ${releaseImpact.added.join(", ")}`);
|
|
132
|
+
if (releaseImpact.modified.length > 0)
|
|
133
|
+
console.log(` Modified: ${releaseImpact.modified.join(", ")}`);
|
|
134
|
+
if (releaseImpact.removed.length > 0)
|
|
135
|
+
console.log(` Removed: ${releaseImpact.removed.join(", ")}`);
|
|
136
|
+
}
|
|
137
|
+
// 4. Document overlay — resolve document IDs against canonical set
|
|
138
|
+
let documentOverlay;
|
|
139
|
+
if (source?.documentIds && source.documentIds.length > 0) {
|
|
140
|
+
console.log(` Resolving ${source.documentIds.length} document ID(s) against canonical set...`);
|
|
141
|
+
documentOverlay = await this.resolveDocumentOverlay(source.documentIds, allSlugs, source);
|
|
142
|
+
const summary = {
|
|
143
|
+
appendedCount: documentOverlay.appendedContent.length,
|
|
144
|
+
documentIds: source.documentIds,
|
|
145
|
+
replacedSlugs: [...documentOverlay.replacements.keys()],
|
|
146
|
+
};
|
|
147
|
+
metadata.documentOverlay = summary;
|
|
148
|
+
console.log(` Document overlay: ${documentOverlay.replacements.size} replacement(s), ${documentOverlay.appendedContent.length} appended`);
|
|
149
|
+
}
|
|
150
|
+
// 5. URL content fetch — fetch direct URLs
|
|
151
|
+
const urlContent = [];
|
|
152
|
+
if (source?.urls && source.urls.length > 0) {
|
|
153
|
+
const urlFetchMeta = [];
|
|
154
|
+
console.log(` Fetching ${source.urls.length} direct URL(s)...`);
|
|
155
|
+
for (const url of source.urls) {
|
|
156
|
+
const result = await fetchUrlContent(url, source.headers);
|
|
157
|
+
urlFetchMeta.push({
|
|
158
|
+
contentLength: result.content?.length,
|
|
159
|
+
error: result.error,
|
|
160
|
+
method: result.method,
|
|
161
|
+
status: result.status,
|
|
162
|
+
url: result.url,
|
|
163
|
+
});
|
|
164
|
+
if (result.content) {
|
|
165
|
+
urlContent.push(result.content);
|
|
166
|
+
const tokens = estimateTokens(result.content);
|
|
167
|
+
console.log(` ✅ ${url} (via ${result.method}, ~${tokens} tokens)`);
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
console.warn(` ⚠️ ${url}: ${result.error}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const fetched = urlFetchMeta.filter((m) => m.method !== "failed");
|
|
174
|
+
const failures = urlFetchMeta.filter((m) => m.method === "failed");
|
|
175
|
+
metadata.urlFetch = {
|
|
176
|
+
failures: failures.map((f) => ({ error: f.error, url: f.url })),
|
|
177
|
+
fetchedUrls: fetched,
|
|
178
|
+
totalFailed: failures.length,
|
|
179
|
+
totalFetched: fetched.length,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
// 6. Fetch canonical docs and assemble per-task contexts
|
|
183
|
+
//
|
|
184
|
+
// Build a per-slug perspective map so each slug is fetched with the
|
|
185
|
+
// right perspective client. Sources:
|
|
186
|
+
// a) release impact diff (added/modified slugs → source perspective)
|
|
187
|
+
// b) perspective ref expansion (expanded slugs → ref's perspective)
|
|
188
|
+
// When both set a perspective for the same slug, the ref-level
|
|
189
|
+
// perspective wins (it's more specific).
|
|
190
|
+
const slugPerspective = new Map();
|
|
191
|
+
// Source-level perspective affects release-impacted slugs
|
|
192
|
+
if (source?.perspective) {
|
|
193
|
+
for (const slug of [
|
|
194
|
+
...(releaseImpact?.added ?? []),
|
|
195
|
+
...(releaseImpact?.modified ?? []),
|
|
196
|
+
]) {
|
|
197
|
+
slugPerspective.set(slug, source.perspective);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
// Perspective ref expansion — each slug gets its ref's perspective
|
|
201
|
+
for (const [perspectiveId, slugs] of perspectiveToSlugs) {
|
|
202
|
+
for (const slug of slugs) {
|
|
203
|
+
slugPerspective.set(slug, perspectiveId);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
const affectedSlugs = new Set(slugPerspective.keys());
|
|
207
|
+
const removedSlugs = new Set(releaseImpact?.removed ?? []);
|
|
208
|
+
const contentBySlug = await this.fetchCanonicalDocs(allSlugs, affectedSlugs, removedSlugs, documentOverlay, source, slugPerspective);
|
|
209
|
+
// 7. Assemble per-task context, write files, build DocContext[]
|
|
210
|
+
const canonicalDir = join(this.rootDir, "contexts", "canonical");
|
|
211
|
+
mkdirSync(canonicalDir, { recursive: true });
|
|
212
|
+
const contexts = tasks.map((task) => {
|
|
213
|
+
const parts = [];
|
|
214
|
+
const slugs = [];
|
|
215
|
+
for (const ref of task.canonicalDocs) {
|
|
216
|
+
// Perspective refs expand to multiple slugs
|
|
217
|
+
if (isPerspectiveRef(ref)) {
|
|
218
|
+
const expanded = perspectiveToSlugs.get(ref.perspective) ?? [];
|
|
219
|
+
for (const slug of expanded) {
|
|
220
|
+
if (removedSlugs.has(slug))
|
|
221
|
+
continue;
|
|
222
|
+
const content = contentBySlug.get(slug) ?? "";
|
|
223
|
+
if (content) {
|
|
224
|
+
parts.push(content);
|
|
225
|
+
slugs.push(slug);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
let slug;
|
|
231
|
+
if (isSlugRef(ref)) {
|
|
232
|
+
slug = ref.slug;
|
|
233
|
+
}
|
|
234
|
+
else if (isIdRef(ref)) {
|
|
235
|
+
slug = idToSlug.get(ref.id);
|
|
236
|
+
}
|
|
237
|
+
else if (isPathRef(ref)) {
|
|
238
|
+
slug = pathToSlug.get(ref.path);
|
|
239
|
+
}
|
|
240
|
+
if (!slug)
|
|
241
|
+
continue;
|
|
242
|
+
if (removedSlugs.has(slug))
|
|
243
|
+
continue;
|
|
244
|
+
const content = contentBySlug.get(slug) ?? "";
|
|
245
|
+
if (content) {
|
|
246
|
+
parts.push(content);
|
|
247
|
+
slugs.push(slug);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
// Append extra documents from overlay that didn't match canonical slugs
|
|
251
|
+
if (documentOverlay && documentOverlay.appendedContent.length > 0) {
|
|
252
|
+
parts.push(...documentOverlay.appendedContent);
|
|
253
|
+
}
|
|
254
|
+
// Append URL-fetched content
|
|
255
|
+
if (urlContent.length > 0) {
|
|
256
|
+
parts.push(...urlContent);
|
|
257
|
+
}
|
|
258
|
+
const combined = escapeNunjucks(parts.join("\n\n---\n\n"));
|
|
259
|
+
const contextPath = join(canonicalDir, `${task.id}.md`);
|
|
260
|
+
writeFileSync(contextPath, combined, "utf-8");
|
|
261
|
+
return {
|
|
262
|
+
taskId: task.id,
|
|
263
|
+
content: combined,
|
|
264
|
+
slugs,
|
|
265
|
+
tokenCount: estimateTokens(combined),
|
|
266
|
+
};
|
|
267
|
+
});
|
|
268
|
+
const hasMetadata = Object.keys(metadata).length > 0;
|
|
269
|
+
return {
|
|
270
|
+
contexts,
|
|
271
|
+
...(hasMetadata ? { metadata } : {}),
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
// -----------------------------------------------------------------------
|
|
275
|
+
// Private: Fetch document manifest
|
|
276
|
+
// -----------------------------------------------------------------------
|
|
277
|
+
async fetchManifest(allSlugs, source) {
|
|
278
|
+
const client = source?.perspective
|
|
279
|
+
? createPerspectiveClient(source.perspective, source)
|
|
280
|
+
: getSanityClient(toSanityOverrides(source));
|
|
281
|
+
const allMetadata = await client.fetch(ARTICLES_METADATA_BY_SLUGS_QUERY, { slugs: [...allSlugs] });
|
|
282
|
+
return allMetadata
|
|
283
|
+
.map((m) => ({ _id: m._id, _rev: m._rev, slug: m.slug, title: m.title }))
|
|
284
|
+
.sort((a, b) => a.slug.localeCompare(b.slug));
|
|
285
|
+
}
|
|
286
|
+
// -----------------------------------------------------------------------
|
|
287
|
+
// Private: Resolve ID refs to slugs
|
|
288
|
+
// -----------------------------------------------------------------------
|
|
289
|
+
/**
|
|
290
|
+
* Batch-resolve document ID refs to their article slugs.
|
|
291
|
+
*
|
|
292
|
+
* This bridges IdDocRef entries into the slug-based fetch pipeline.
|
|
293
|
+
* Articles are queried by _id and their slugs are returned for use
|
|
294
|
+
* in the existing slug-based content map.
|
|
295
|
+
*/
|
|
296
|
+
async resolveIdRefsToSlugs(idRefs, source) {
|
|
297
|
+
const result = new Map();
|
|
298
|
+
if (idRefs.length === 0)
|
|
299
|
+
return result;
|
|
300
|
+
const uniqueIds = [...new Set(idRefs.map((r) => r.id))];
|
|
301
|
+
const client = source?.perspective
|
|
302
|
+
? createPerspectiveClient(source.perspective, source)
|
|
303
|
+
: getSanityClient(toSanityOverrides(source));
|
|
304
|
+
// Batch query: fetch slug for each document ID
|
|
305
|
+
const articles = await client.fetch(`*[_type == "article" && _id in $ids] { _id, "slug": slug.current }`, { ids: uniqueIds });
|
|
306
|
+
const idToSlugMap = new Map(articles.map((a) => [a._id, a.slug]));
|
|
307
|
+
for (const { id, taskId } of idRefs) {
|
|
308
|
+
const slug = idToSlugMap.get(id);
|
|
309
|
+
if (slug) {
|
|
310
|
+
result.set(id, slug);
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
console.warn(` [warn] No article found for document ID "${id}" (referenced by task "${taskId}")`);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
if (result.size > 0) {
|
|
317
|
+
console.log(` Resolved ${result.size} document ID ref(s) to slugs`);
|
|
318
|
+
}
|
|
319
|
+
return result;
|
|
320
|
+
}
|
|
321
|
+
// -----------------------------------------------------------------------
|
|
322
|
+
// Private: Resolve path refs to slugs
|
|
323
|
+
// -----------------------------------------------------------------------
|
|
324
|
+
/**
|
|
325
|
+
* Resolve path-based canonical doc references to their article slugs.
|
|
326
|
+
*
|
|
327
|
+
* Handles two path formats:
|
|
328
|
+
* - Simple path: "webhooks" → resolves as slug lookup
|
|
329
|
+
* - Section-qualified path: "content-lake/webhooks" → matches section + slug
|
|
330
|
+
*
|
|
331
|
+
* @see docs/design-docs/canonical-doc-resolution.md
|
|
332
|
+
*/
|
|
333
|
+
async resolvePathRefsToSlugs(pathRefs, source) {
|
|
334
|
+
const result = new Map();
|
|
335
|
+
if (pathRefs.length === 0)
|
|
336
|
+
return result;
|
|
337
|
+
const client = source?.perspective
|
|
338
|
+
? createPerspectiveClient(source.perspective, source)
|
|
339
|
+
: getSanityClient(toSanityOverrides(source));
|
|
340
|
+
for (const { path, taskId } of pathRefs) {
|
|
341
|
+
const segments = path.split("/").filter(Boolean);
|
|
342
|
+
const articleSlug = segments[segments.length - 1];
|
|
343
|
+
const sectionSlug = segments.length > 1 ? segments.slice(0, -1).join("/") : undefined;
|
|
344
|
+
let article;
|
|
345
|
+
if (sectionSlug) {
|
|
346
|
+
// Section-qualified path: disambiguate by section
|
|
347
|
+
article = await client.fetch(ARTICLE_SLUG_BY_SECTION_PATH_QUERY, {
|
|
348
|
+
articleSlug,
|
|
349
|
+
sectionSlug,
|
|
350
|
+
});
|
|
351
|
+
if (!article) {
|
|
352
|
+
// Fallback: try without section qualifier (section slug might differ)
|
|
353
|
+
article = await client.fetch(ARTICLE_SLUG_BY_PATH_QUERY, { slug: articleSlug });
|
|
354
|
+
if (article) {
|
|
355
|
+
console.warn(` [warn] Path "${path}" section "${sectionSlug}" didn't match (article found in section "${article.sectionSlug ?? "unknown"}")`);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
// Simple path: resolve by slug directly
|
|
361
|
+
article = await client.fetch(ARTICLE_SLUG_BY_PATH_QUERY, { slug: articleSlug });
|
|
362
|
+
}
|
|
363
|
+
if (article) {
|
|
364
|
+
result.set(path, article.slug);
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
console.warn(` [warn] No article found for path "${path}" (referenced by task "${taskId}")`);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
if (result.size > 0) {
|
|
371
|
+
console.log(` Resolved ${result.size} path ref(s) to slugs`);
|
|
372
|
+
}
|
|
373
|
+
return result;
|
|
374
|
+
}
|
|
375
|
+
// -----------------------------------------------------------------------
|
|
376
|
+
// Private: Resolve perspective refs to slugs (one-to-many)
|
|
377
|
+
// -----------------------------------------------------------------------
|
|
378
|
+
/**
|
|
379
|
+
* Expand perspective canonical doc refs to the article slugs within
|
|
380
|
+
* each content release.
|
|
381
|
+
*
|
|
382
|
+
* Each perspective ref resolves to ALL article documents versioned in
|
|
383
|
+
* that release. This is the one-to-many expansion described in the
|
|
384
|
+
* canonical-doc-resolution design doc.
|
|
385
|
+
*
|
|
386
|
+
* The perspective value from the ref is used as both the release ID
|
|
387
|
+
* for the versioned document query AND the client perspective for
|
|
388
|
+
* fetching content. If a source-level perspective is also set, the
|
|
389
|
+
* ref-level perspective takes precedence for its own resolution.
|
|
390
|
+
*
|
|
391
|
+
* @see docs/design-docs/canonical-doc-resolution.md
|
|
392
|
+
*/
|
|
393
|
+
async resolvePerspectiveRefsToSlugs(perspectiveRefs, source) {
|
|
394
|
+
const result = new Map();
|
|
395
|
+
if (perspectiveRefs.length === 0)
|
|
396
|
+
return result;
|
|
397
|
+
// Deduplicate by perspective ID (multiple tasks may reference the same release)
|
|
398
|
+
const uniquePerspectives = [
|
|
399
|
+
...new Set(perspectiveRefs.map((r) => r.perspective)),
|
|
400
|
+
];
|
|
401
|
+
for (const perspectiveId of uniquePerspectives) {
|
|
402
|
+
// Create a client with this specific perspective so versioned docs are visible
|
|
403
|
+
const client = createPerspectiveClient(perspectiveId, source);
|
|
404
|
+
const articles = await client.fetch(ARTICLES_IN_RELEASE_QUERY, { releaseId: perspectiveId });
|
|
405
|
+
if (articles.length === 0) {
|
|
406
|
+
const taskIds = perspectiveRefs
|
|
407
|
+
.filter((r) => r.perspective === perspectiveId)
|
|
408
|
+
.map((r) => r.taskId);
|
|
409
|
+
console.warn(` [warn] No articles found in release "${perspectiveId}" (referenced by task(s): ${taskIds.join(", ")})`);
|
|
410
|
+
result.set(perspectiveId, []);
|
|
411
|
+
continue;
|
|
412
|
+
}
|
|
413
|
+
const slugs = articles
|
|
414
|
+
.map((a) => a.slug)
|
|
415
|
+
.filter((s) => Boolean(s));
|
|
416
|
+
result.set(perspectiveId, slugs);
|
|
417
|
+
console.log(` Expanded perspective "${perspectiveId}" → ${slugs.length} article(s): ${slugs.join(", ")}`);
|
|
418
|
+
}
|
|
419
|
+
return result;
|
|
420
|
+
}
|
|
421
|
+
// -----------------------------------------------------------------------
|
|
422
|
+
// Private: Perspective diffing
|
|
423
|
+
// -----------------------------------------------------------------------
|
|
424
|
+
async identifyAffectedDocs(canonicalSlugs, source) {
|
|
425
|
+
if (!source.perspective) {
|
|
426
|
+
return {
|
|
427
|
+
added: [],
|
|
428
|
+
modified: [],
|
|
429
|
+
removed: [],
|
|
430
|
+
unchanged: [...canonicalSlugs],
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
const publishedClient = createPublishedClient(source);
|
|
434
|
+
const perspectiveClient = createPerspectiveClient(source.perspective, source);
|
|
435
|
+
const [publishedMeta, perspectiveMeta] = await Promise.all([
|
|
436
|
+
publishedClient.fetch(ARTICLES_METADATA_BY_SLUGS_QUERY, { slugs: canonicalSlugs }),
|
|
437
|
+
perspectiveClient.fetch(ARTICLES_METADATA_BY_SLUGS_QUERY, { slugs: canonicalSlugs }),
|
|
438
|
+
]);
|
|
439
|
+
const publishedMap = new Map(publishedMeta.map((d) => [d.slug, d]));
|
|
440
|
+
const perspectiveMap = new Map(perspectiveMeta.map((d) => [d.slug, d]));
|
|
441
|
+
const added = [];
|
|
442
|
+
const modified = [];
|
|
443
|
+
const removed = [];
|
|
444
|
+
const unchanged = [];
|
|
445
|
+
for (const slug of canonicalSlugs) {
|
|
446
|
+
const pub = publishedMap.get(slug);
|
|
447
|
+
const persp = perspectiveMap.get(slug);
|
|
448
|
+
if (!pub && persp) {
|
|
449
|
+
added.push(slug);
|
|
450
|
+
}
|
|
451
|
+
else if (pub && !persp) {
|
|
452
|
+
removed.push(slug);
|
|
453
|
+
}
|
|
454
|
+
else if (pub && persp && pub._rev !== persp._rev) {
|
|
455
|
+
modified.push(slug);
|
|
456
|
+
}
|
|
457
|
+
else {
|
|
458
|
+
unchanged.push(slug);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
return { added, modified, removed, unchanged };
|
|
462
|
+
}
|
|
463
|
+
// -----------------------------------------------------------------------
|
|
464
|
+
// Private: Document overlay
|
|
465
|
+
// -----------------------------------------------------------------------
|
|
466
|
+
async resolveDocumentOverlay(documentIds, canonicalSlugs, source) {
|
|
467
|
+
const overlay = {
|
|
468
|
+
appendedContent: [],
|
|
469
|
+
replacements: new Map(),
|
|
470
|
+
};
|
|
471
|
+
if (documentIds.length === 0)
|
|
472
|
+
return overlay;
|
|
473
|
+
const results = await Promise.all(documentIds.map(async (id) => {
|
|
474
|
+
const doc = await this.fetchArticleById(id, source);
|
|
475
|
+
return { doc, id };
|
|
476
|
+
}));
|
|
477
|
+
for (const { doc, id } of results) {
|
|
478
|
+
if (!doc) {
|
|
479
|
+
console.warn(` [warn] No article found for document ID "${id}"`);
|
|
480
|
+
continue;
|
|
481
|
+
}
|
|
482
|
+
const content = formatArticle(doc);
|
|
483
|
+
if (!content)
|
|
484
|
+
continue;
|
|
485
|
+
if (doc.slug && canonicalSlugs.has(doc.slug)) {
|
|
486
|
+
overlay.replacements.set(doc.slug, content);
|
|
487
|
+
console.log(` 📄 Document ${id} → replaces canonical doc "${doc.slug}"`);
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
overlay.appendedContent.push(content);
|
|
491
|
+
const slugInfo = doc.slug ? ` (slug: "${doc.slug}")` : "";
|
|
492
|
+
console.log(` 📄 Document ${id} → appended as additional context${slugInfo}`);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
return overlay;
|
|
496
|
+
}
|
|
497
|
+
// -----------------------------------------------------------------------
|
|
498
|
+
// Private: Fetch individual articles
|
|
499
|
+
// -----------------------------------------------------------------------
|
|
500
|
+
async fetchArticleById(id, source) {
|
|
501
|
+
const client = source.perspective
|
|
502
|
+
? createPerspectiveClient(source.perspective, source)
|
|
503
|
+
: getSanityClient(toSanityOverrides(source));
|
|
504
|
+
return client.fetch(ARTICLE_BY_ID_QUERY, { id });
|
|
505
|
+
}
|
|
506
|
+
async fetchArticleBySlug(slug) {
|
|
507
|
+
const client = getSanityClient();
|
|
508
|
+
const doc = await client.fetch(ARTICLE_BY_SLUG_QUERY, { slug });
|
|
509
|
+
if (!doc) {
|
|
510
|
+
console.warn(` [warn] No article found for slug "${slug}"`);
|
|
511
|
+
return "";
|
|
512
|
+
}
|
|
513
|
+
return formatArticle(doc);
|
|
514
|
+
}
|
|
515
|
+
async fetchArticleBySlugWithPerspective(slug, source) {
|
|
516
|
+
if (!source.perspective) {
|
|
517
|
+
return this.fetchArticleBySlug(slug);
|
|
518
|
+
}
|
|
519
|
+
const client = createPerspectiveClient(source.perspective, source);
|
|
520
|
+
const doc = await client.fetch(ARTICLE_BY_SLUG_WITH_PERSPECTIVE_QUERY, { slug });
|
|
521
|
+
if (!doc) {
|
|
522
|
+
console.warn(` [warn] No article found for slug "${slug}" in perspective "${source.perspective}"`);
|
|
523
|
+
return "";
|
|
524
|
+
}
|
|
525
|
+
return formatArticle(doc);
|
|
526
|
+
}
|
|
527
|
+
// -----------------------------------------------------------------------
|
|
528
|
+
// Private: Fetch all canonical docs with perspective/overlay awareness
|
|
529
|
+
// -----------------------------------------------------------------------
|
|
530
|
+
async fetchCanonicalDocs(allSlugs, affectedSlugs, removedSlugs, overlay, source, slugPerspective) {
|
|
531
|
+
const contentBySlug = new Map();
|
|
532
|
+
for (const slug of allSlugs) {
|
|
533
|
+
if (removedSlugs.has(slug))
|
|
534
|
+
continue;
|
|
535
|
+
// Check if this slug has a document overlay replacement
|
|
536
|
+
if (overlay?.replacements.has(slug)) {
|
|
537
|
+
console.log(` Fetching: ${slug} (from document overlay)`);
|
|
538
|
+
contentBySlug.set(slug, overlay.replacements.get(slug));
|
|
539
|
+
}
|
|
540
|
+
else if (affectedSlugs.has(slug)) {
|
|
541
|
+
// Use the per-slug perspective when available; fall back to
|
|
542
|
+
// source-level perspective. This ensures perspective-ref-expanded
|
|
543
|
+
// slugs are fetched from their specific release even when no
|
|
544
|
+
// source-level --sanity-perspective is set.
|
|
545
|
+
const perspective = slugPerspective?.get(slug) ?? source?.perspective;
|
|
546
|
+
if (perspective && source) {
|
|
547
|
+
const perspectiveSource = { ...source, perspective };
|
|
548
|
+
console.log(` Fetching: ${slug} (from perspective: ${perspective})`);
|
|
549
|
+
const content = await this.fetchArticleBySlugWithPerspective(slug, perspectiveSource);
|
|
550
|
+
contentBySlug.set(slug, content);
|
|
551
|
+
}
|
|
552
|
+
else {
|
|
553
|
+
// No perspective available — fetch from published
|
|
554
|
+
console.log(` Fetching: ${slug}`);
|
|
555
|
+
const content = await this.fetchArticleBySlug(slug);
|
|
556
|
+
contentBySlug.set(slug, content);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
else {
|
|
560
|
+
console.log(` Fetching: ${slug}`);
|
|
561
|
+
const content = await this.fetchArticleBySlug(slug);
|
|
562
|
+
contentBySlug.set(slug, content);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
return contentBySlug;
|
|
566
|
+
}
|
|
567
|
+
// -----------------------------------------------------------------------
|
|
568
|
+
// Public non-port methods — opt-in CLI features
|
|
569
|
+
// -----------------------------------------------------------------------
|
|
570
|
+
/**
|
|
571
|
+
* Generate feature-area context files (one per GROQ feature area query).
|
|
572
|
+
*
|
|
573
|
+
* This is NOT part of the DocFetcher port — it's an opt-in CLI feature
|
|
574
|
+
* used by `ailf fetch-docs --include-feature-areas`.
|
|
575
|
+
*/
|
|
576
|
+
async fetchFeatureAreaContexts(source) {
|
|
577
|
+
const client = getSanityClient(toSanityOverrides(source), source);
|
|
578
|
+
const contextsDir = join(this.rootDir, "contexts");
|
|
579
|
+
mkdirSync(contextsDir, { recursive: true });
|
|
580
|
+
console.log("Generating feature-area contexts...\n");
|
|
581
|
+
for (const feature of ALL_FEATURE_AREAS) {
|
|
582
|
+
const query = FEATURE_AREA_QUERIES[feature];
|
|
583
|
+
const docs = await client.fetch(query);
|
|
584
|
+
if (docs.length === 0) {
|
|
585
|
+
console.warn(` [warn] No articles found for "${feature}"`);
|
|
586
|
+
continue;
|
|
587
|
+
}
|
|
588
|
+
const combined = docs.map(formatArticle).join("\n\n---\n\n");
|
|
589
|
+
const outPath = join(contextsDir, `${feature}.md`);
|
|
590
|
+
writeFileSync(outPath, escapeNunjucks(combined), "utf-8");
|
|
591
|
+
console.log(` ${feature}: ${docs.length} articles, ~${estimateTokens(combined)} tokens`);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* Generate a full corpus context file (all articles in one markdown file).
|
|
596
|
+
*
|
|
597
|
+
* This is NOT part of the DocFetcher port — it's an opt-in CLI feature
|
|
598
|
+
* used by `ailf fetch-docs --include-corpus`.
|
|
599
|
+
*/
|
|
600
|
+
async fetchFullCorpus(source) {
|
|
601
|
+
const client = getSanityClient(toSanityOverrides(source), source);
|
|
602
|
+
const baseUrl = source?.baseUrl ?? "https://www.sanity.io/docs";
|
|
603
|
+
console.log("\nGenerating full corpus...");
|
|
604
|
+
const docs = await client.fetch(ALL_ARTICLES_QUERY);
|
|
605
|
+
const corpus = docs
|
|
606
|
+
.map((d) => {
|
|
607
|
+
const markdown = toMarkdown(d.content ?? []);
|
|
608
|
+
return (`## ${d.title}\n\n` +
|
|
609
|
+
// oxlint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty string title should fall back to "General"
|
|
610
|
+
`Section: ${d.section?.title || "General"}\n` +
|
|
611
|
+
`URL: ${baseUrl}/${d.slug}\n\n` +
|
|
612
|
+
markdown);
|
|
613
|
+
})
|
|
614
|
+
.join("\n\n---\n\n");
|
|
615
|
+
const outDir = join(this.rootDir, "contexts");
|
|
616
|
+
mkdirSync(outDir, { recursive: true });
|
|
617
|
+
writeFileSync(join(outDir, "full-corpus.md"), escapeNunjucks(corpus), "utf-8");
|
|
618
|
+
console.log(` full-corpus.md: ${docs.length} articles, ~${estimateTokens(corpus)} tokens`);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { PromptfooEvalAdapter } from "./promptfoo-eval-adapter.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { PromptfooEvalAdapter } from "./promptfoo-eval-adapter.js";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapter: Run evaluation via Promptfoo CLI subprocess.
|
|
3
|
+
*
|
|
4
|
+
* This wraps the current execSync-based eval execution behind the
|
|
5
|
+
* EvalRunner port interface, enabling mock-based testing of the
|
|
6
|
+
* pipeline orchestrator.
|
|
7
|
+
*/
|
|
8
|
+
import type { EvalRunConfig, EvalRunner, StepResult } from "../../_vendor/ailf-core/index.d.ts";
|
|
9
|
+
export declare class PromptfooEvalAdapter implements EvalRunner {
|
|
10
|
+
private readonly rootDir;
|
|
11
|
+
constructor(rootDir: string);
|
|
12
|
+
run(config: EvalRunConfig): Promise<StepResult>;
|
|
13
|
+
extractShareUrl(outputPath: string): string | undefined;
|
|
14
|
+
}
|