@sanity/ailf 0.5.0 → 1.0.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.
Files changed (288) hide show
  1. package/config/features.ts +23 -0
  2. package/config/models.ts +83 -0
  3. package/config/prompts.ts +16 -0
  4. package/config/rubrics.ts +225 -0
  5. package/config/schedules.ts +47 -0
  6. package/config/sinks.ts +37 -0
  7. package/config/sources.ts +21 -0
  8. package/config/thresholds.ts +61 -0
  9. package/dist/_vendor/ailf-core/config-helpers.d.ts +174 -0
  10. package/dist/_vendor/ailf-core/config-helpers.js +150 -0
  11. package/dist/_vendor/ailf-core/env-helper.d.ts +35 -0
  12. package/dist/_vendor/ailf-core/env-helper.js +45 -0
  13. package/dist/_vendor/ailf-core/index.d.ts +3 -0
  14. package/dist/_vendor/ailf-core/index.js +5 -0
  15. package/dist/_vendor/ailf-core/ports/context.d.ts +15 -2
  16. package/dist/_vendor/ailf-core/ports/doc-fetcher.d.ts +2 -2
  17. package/dist/_vendor/ailf-core/ports/index.d.ts +2 -1
  18. package/dist/_vendor/ailf-core/ports/mode-handler.d.ts +129 -0
  19. package/dist/_vendor/ailf-core/ports/mode-handler.js +19 -0
  20. package/dist/_vendor/ailf-core/ports/task-source.d.ts +16 -122
  21. package/dist/_vendor/ailf-core/ports/task-source.js +7 -7
  22. package/dist/_vendor/ailf-core/schemas/eval-config.d.ts +7 -2
  23. package/dist/_vendor/ailf-core/schemas/eval-config.js +7 -2
  24. package/dist/_vendor/ailf-core/schemas/pipeline-request.d.ts +8 -3
  25. package/dist/_vendor/ailf-core/schemas/pipeline-request.js +6 -1
  26. package/dist/_vendor/ailf-core/schemas/pipeline.d.ts +14 -29
  27. package/dist/_vendor/ailf-core/schemas/pipeline.js +17 -8
  28. package/dist/_vendor/ailf-core/schemas/schedules.d.ts +14 -4
  29. package/dist/_vendor/ailf-core/schemas/schedules.js +6 -2
  30. package/dist/_vendor/ailf-core/schemas/sinks.d.ts +1 -1
  31. package/dist/_vendor/ailf-core/services/comparison-formatters.js +57 -19
  32. package/dist/_vendor/ailf-core/services/index.d.ts +2 -1
  33. package/dist/_vendor/ailf-core/services/index.js +2 -1
  34. package/dist/_vendor/ailf-core/services/scoring-engine.d.ts +153 -0
  35. package/dist/_vendor/ailf-core/services/scoring-engine.js +237 -0
  36. package/dist/_vendor/ailf-core/services/scoring.d.ts +15 -2
  37. package/dist/_vendor/ailf-core/services/scoring.js +25 -15
  38. package/dist/_vendor/ailf-core/types/branded-ids.d.ts +137 -0
  39. package/dist/_vendor/ailf-core/types/branded-ids.js +136 -0
  40. package/dist/_vendor/ailf-core/types/eval-mode-config.d.ts +150 -0
  41. package/dist/_vendor/ailf-core/types/eval-mode-config.js +24 -0
  42. package/dist/_vendor/ailf-core/types/generalized-task.d.ts +319 -0
  43. package/dist/_vendor/ailf-core/types/generalized-task.js +13 -0
  44. package/dist/_vendor/ailf-core/types/index.d.ts +45 -81
  45. package/dist/_vendor/ailf-core/types/index.js +8 -1
  46. package/dist/_vendor/ailf-core/types/plugin-registry.d.ts +202 -0
  47. package/dist/_vendor/ailf-core/types/plugin-registry.js +132 -0
  48. package/dist/_vendor/ailf-core/types/storage-schema.d.ts +199 -0
  49. package/dist/_vendor/ailf-core/types/storage-schema.js +39 -0
  50. package/dist/_vendor/ailf-core/types/task-graph.d.ts +86 -0
  51. package/dist/_vendor/ailf-core/types/task-graph.js +20 -0
  52. package/dist/_vendor/ailf-core/types/trace.d.ts +118 -0
  53. package/dist/_vendor/ailf-core/types/trace.js +18 -0
  54. package/dist/_vendor/ailf-core/types/variable-envelope.d.ts +80 -0
  55. package/dist/_vendor/ailf-core/types/variable-envelope.js +16 -0
  56. package/dist/_vendor/ailf-shared/dimension-names.d.ts +5 -18
  57. package/dist/_vendor/ailf-shared/dimension-names.js +6 -24
  58. package/dist/_vendor/ailf-shared/eval-modes.d.ts +38 -6
  59. package/dist/_vendor/ailf-shared/eval-modes.js +26 -2
  60. package/dist/_vendor/ailf-shared/index.d.ts +0 -1
  61. package/dist/_vendor/ailf-shared/index.js +0 -1
  62. package/dist/adapters/api-client/build-request.js +14 -13
  63. package/dist/adapters/config-sources/file-config-adapter.d.ts +20 -11
  64. package/dist/adapters/config-sources/file-config-adapter.js +38 -12
  65. package/dist/adapters/config-sources/index.d.ts +2 -0
  66. package/dist/adapters/config-sources/index.js +1 -0
  67. package/dist/adapters/config-sources/ts-config-loader.d.ts +59 -0
  68. package/dist/adapters/config-sources/ts-config-loader.js +133 -0
  69. package/dist/adapters/doc-fetchers/sanity-doc-fetcher.d.ts +3 -2
  70. package/dist/adapters/doc-fetchers/sanity-doc-fetcher.js +7 -2
  71. package/dist/adapters/task-sources/composite-task-source.d.ts +3 -3
  72. package/dist/adapters/task-sources/composite-task-source.js +1 -1
  73. package/dist/adapters/task-sources/content-lake-task-source.d.ts +7 -6
  74. package/dist/adapters/task-sources/content-lake-task-source.js +22 -23
  75. package/dist/adapters/task-sources/index.d.ts +1 -0
  76. package/dist/adapters/task-sources/index.js +1 -0
  77. package/dist/adapters/task-sources/repo-task-source.d.ts +4 -4
  78. package/dist/adapters/task-sources/repo-task-source.js +69 -16
  79. package/dist/adapters/task-sources/task-file-loader.d.ts +64 -0
  80. package/dist/adapters/task-sources/task-file-loader.js +83 -0
  81. package/dist/adapters/task-sources/yaml-task-source.d.ts +6 -6
  82. package/dist/adapters/task-sources/yaml-task-source.js +19 -16
  83. package/dist/cli.js +0 -2
  84. package/dist/commands/baseline.js +4 -1
  85. package/dist/commands/calculate-scores.js +1 -1
  86. package/dist/commands/coverage-audit.js +7 -1
  87. package/dist/commands/explain-handler.js +25 -23
  88. package/dist/commands/fetch-docs.js +3 -2
  89. package/dist/commands/generate-configs.js +1 -1
  90. package/dist/commands/interactive.js +11 -7
  91. package/dist/commands/pipeline-action.d.ts +2 -0
  92. package/dist/commands/pipeline-action.js +16 -6
  93. package/dist/commands/pipeline.d.ts +1 -0
  94. package/dist/commands/pipeline.js +4 -2
  95. package/dist/commands/pr-comment.js +1 -1
  96. package/dist/commands/publish.js +2 -2
  97. package/dist/commands/readiness-report.js +13 -6
  98. package/dist/composition-root.d.ts +1 -1
  99. package/dist/composition-root.js +67 -4
  100. package/dist/orchestration/build-app-context.js +1 -0
  101. package/dist/orchestration/build-step-sequence.js +24 -6
  102. package/dist/orchestration/steps/calculate-scores-step.js +24 -11
  103. package/dist/orchestration/steps/fetch-docs-step.js +6 -4
  104. package/dist/orchestration/steps/gap-analysis-step.js +8 -7
  105. package/dist/orchestration/steps/generate-configs-step.d.ts +16 -3
  106. package/dist/orchestration/steps/generate-configs-step.js +245 -51
  107. package/dist/orchestration/steps/grader-consistency-step.js +7 -4
  108. package/dist/orchestration/steps/mirror-repo-tasks-step.js +1 -1
  109. package/dist/orchestration/steps/readiness-step.js +5 -6
  110. package/dist/orchestration/steps/run-eval-step.d.ts +1 -2
  111. package/dist/orchestration/steps/run-eval-step.js +8 -7
  112. package/dist/pipeline/cache.d.ts +1 -1
  113. package/dist/pipeline/cache.js +36 -8
  114. package/dist/pipeline/calculate-scores.d.ts +2 -4
  115. package/dist/pipeline/calculate-scores.js +43 -113
  116. package/dist/pipeline/checks.js +2 -2
  117. package/dist/pipeline/compare.js +8 -8
  118. package/dist/pipeline/compiler/__tests__/agent-harness-handler.test.d.ts +10 -0
  119. package/dist/pipeline/compiler/__tests__/agent-harness-handler.test.js +288 -0
  120. package/dist/pipeline/compiler/__tests__/assertion-mapper.test.d.ts +9 -0
  121. package/dist/pipeline/compiler/__tests__/assertion-mapper.test.js +145 -0
  122. package/dist/pipeline/compiler/__tests__/knowledge-probe-handler.test.d.ts +10 -0
  123. package/dist/pipeline/compiler/__tests__/knowledge-probe-handler.test.js +314 -0
  124. package/dist/pipeline/compiler/__tests__/literacy-handler.test.d.ts +10 -0
  125. package/dist/pipeline/compiler/__tests__/literacy-handler.test.js +486 -0
  126. package/dist/pipeline/compiler/__tests__/mcp-server-handler.test.d.ts +10 -0
  127. package/dist/pipeline/compiler/__tests__/mcp-server-handler.test.js +355 -0
  128. package/dist/pipeline/compiler/__tests__/promptfoo-compiler.test.d.ts +9 -0
  129. package/dist/pipeline/compiler/__tests__/promptfoo-compiler.test.js +333 -0
  130. package/dist/pipeline/compiler/__tests__/sandbox-and-fixtures.test.d.ts +12 -0
  131. package/dist/pipeline/compiler/__tests__/sandbox-and-fixtures.test.js +210 -0
  132. package/dist/pipeline/compiler/__tests__/scoring-and-presets.test.d.ts +7 -0
  133. package/dist/pipeline/compiler/__tests__/scoring-and-presets.test.js +471 -0
  134. package/dist/pipeline/compiler/__tests__/scoring-bridge.test.d.ts +10 -0
  135. package/dist/pipeline/compiler/__tests__/scoring-bridge.test.js +184 -0
  136. package/dist/pipeline/compiler/__tests__/task-graph-builder.test.d.ts +8 -0
  137. package/dist/pipeline/compiler/__tests__/task-graph-builder.test.js +301 -0
  138. package/dist/pipeline/compiler/__tests__/telemetry.test.d.ts +9 -0
  139. package/dist/pipeline/compiler/__tests__/telemetry.test.js +503 -0
  140. package/dist/pipeline/compiler/assertion-mapper.d.ts +58 -0
  141. package/dist/pipeline/compiler/assertion-mapper.js +175 -0
  142. package/dist/pipeline/compiler/compiler-to-yaml.d.ts +51 -0
  143. package/dist/pipeline/compiler/compiler-to-yaml.js +222 -0
  144. package/dist/pipeline/compiler/config-loader.d.ts +56 -0
  145. package/dist/pipeline/compiler/config-loader.js +111 -0
  146. package/dist/pipeline/compiler/fixture-resolver.d.ts +41 -0
  147. package/dist/pipeline/compiler/fixture-resolver.js +113 -0
  148. package/dist/pipeline/compiler/hash.d.ts +11 -0
  149. package/dist/pipeline/compiler/hash.js +18 -0
  150. package/dist/pipeline/compiler/ignore-fields.d.ts +53 -0
  151. package/dist/pipeline/compiler/ignore-fields.js +113 -0
  152. package/dist/pipeline/compiler/index.d.ts +29 -0
  153. package/dist/pipeline/compiler/index.js +45 -0
  154. package/dist/pipeline/compiler/literacy-bridge.d.ts +102 -0
  155. package/dist/pipeline/compiler/literacy-bridge.js +172 -0
  156. package/dist/pipeline/compiler/mode-handlers/__fixtures__/agent-harness-example-tasks.d.ts +14 -0
  157. package/dist/pipeline/compiler/mode-handlers/__fixtures__/agent-harness-example-tasks.js +152 -0
  158. package/dist/pipeline/compiler/mode-handlers/__fixtures__/knowledge-probe-example-tasks.d.ts +32 -0
  159. package/dist/pipeline/compiler/mode-handlers/__fixtures__/knowledge-probe-example-tasks.js +176 -0
  160. package/dist/pipeline/compiler/mode-handlers/__fixtures__/mcp-example-tasks.d.ts +49 -0
  161. package/dist/pipeline/compiler/mode-handlers/__fixtures__/mcp-example-tasks.js +259 -0
  162. package/dist/pipeline/compiler/mode-handlers/agent-harness-handler.d.ts +70 -0
  163. package/dist/pipeline/compiler/mode-handlers/agent-harness-handler.js +485 -0
  164. package/dist/pipeline/compiler/mode-handlers/index.d.ts +16 -0
  165. package/dist/pipeline/compiler/mode-handlers/index.js +21 -0
  166. package/dist/pipeline/compiler/mode-handlers/knowledge-probe-handler.d.ts +76 -0
  167. package/dist/pipeline/compiler/mode-handlers/knowledge-probe-handler.js +245 -0
  168. package/dist/pipeline/compiler/mode-handlers/literacy-handler.d.ts +89 -0
  169. package/dist/pipeline/compiler/mode-handlers/literacy-handler.js +379 -0
  170. package/dist/pipeline/compiler/mode-handlers/mcp-assertions.d.ts +50 -0
  171. package/dist/pipeline/compiler/mode-handlers/mcp-assertions.js +277 -0
  172. package/dist/pipeline/compiler/mode-handlers/mcp-server-handler.d.ts +67 -0
  173. package/dist/pipeline/compiler/mode-handlers/mcp-server-handler.js +309 -0
  174. package/dist/pipeline/compiler/presets/index.d.ts +9 -0
  175. package/dist/pipeline/compiler/presets/index.js +8 -0
  176. package/dist/pipeline/compiler/presets/sanity-literacy.d.ts +45 -0
  177. package/dist/pipeline/compiler/presets/sanity-literacy.js +354 -0
  178. package/dist/pipeline/compiler/promptfoo-compiler.d.ts +96 -0
  179. package/dist/pipeline/compiler/promptfoo-compiler.js +230 -0
  180. package/dist/pipeline/compiler/provider-assembler.d.ts +39 -0
  181. package/dist/pipeline/compiler/provider-assembler.js +137 -0
  182. package/dist/pipeline/compiler/sandbox/docker-sandbox.d.ts +21 -0
  183. package/dist/pipeline/compiler/sandbox/docker-sandbox.js +136 -0
  184. package/dist/pipeline/compiler/sandbox/fixture-provisioner.d.ts +69 -0
  185. package/dist/pipeline/compiler/sandbox/fixture-provisioner.js +189 -0
  186. package/dist/pipeline/compiler/sandbox/git-worktree-sandbox.d.ts +20 -0
  187. package/dist/pipeline/compiler/sandbox/git-worktree-sandbox.js +114 -0
  188. package/dist/pipeline/compiler/sandbox/index.d.ts +10 -0
  189. package/dist/pipeline/compiler/sandbox/index.js +11 -0
  190. package/dist/pipeline/compiler/sandbox/sandbox-selector.d.ts +35 -0
  191. package/dist/pipeline/compiler/sandbox/sandbox-selector.js +86 -0
  192. package/dist/pipeline/compiler/sandbox/sandbox-strategy.d.ts +81 -0
  193. package/dist/pipeline/compiler/sandbox/sandbox-strategy.js +15 -0
  194. package/dist/pipeline/compiler/sandbox/tempdir-sandbox.d.ts +20 -0
  195. package/dist/pipeline/compiler/sandbox/tempdir-sandbox.js +74 -0
  196. package/dist/pipeline/compiler/scoring-bridge.d.ts +49 -0
  197. package/dist/pipeline/compiler/scoring-bridge.js +114 -0
  198. package/dist/pipeline/compiler/task-graph-builder.d.ts +54 -0
  199. package/dist/pipeline/compiler/task-graph-builder.js +291 -0
  200. package/dist/pipeline/compiler/telemetry/cost-tracker.d.ts +90 -0
  201. package/dist/pipeline/compiler/telemetry/cost-tracker.js +146 -0
  202. package/dist/pipeline/compiler/telemetry/index.d.ts +14 -0
  203. package/dist/pipeline/compiler/telemetry/index.js +19 -0
  204. package/dist/pipeline/compiler/telemetry/redactor.d.ts +58 -0
  205. package/dist/pipeline/compiler/telemetry/redactor.js +222 -0
  206. package/dist/pipeline/compiler/telemetry/tool-classifier.d.ts +32 -0
  207. package/dist/pipeline/compiler/telemetry/tool-classifier.js +120 -0
  208. package/dist/pipeline/compiler/telemetry/trace-collector.d.ts +75 -0
  209. package/dist/pipeline/compiler/telemetry/trace-collector.js +297 -0
  210. package/dist/pipeline/compiler/telemetry/trace-store.d.ts +78 -0
  211. package/dist/pipeline/compiler/telemetry/trace-store.js +85 -0
  212. package/dist/pipeline/compiler/variable-resolver.d.ts +46 -0
  213. package/dist/pipeline/compiler/variable-resolver.js +115 -0
  214. package/dist/pipeline/coverage-audit.d.ts +15 -5
  215. package/dist/pipeline/coverage-audit.js +41 -22
  216. package/dist/pipeline/eval-constants.d.ts +16 -6
  217. package/dist/pipeline/eval-constants.js +25 -4
  218. package/dist/pipeline/eval-fingerprint.d.ts +2 -2
  219. package/dist/pipeline/eval-fingerprint.js +8 -9
  220. package/dist/pipeline/expand-tasks.d.ts +19 -10
  221. package/dist/pipeline/expand-tasks.js +34 -28
  222. package/dist/pipeline/gap-analysis.d.ts +1 -1
  223. package/dist/pipeline/gap-analysis.js +2 -2
  224. package/dist/pipeline/generate-configs.d.ts +22 -4
  225. package/dist/pipeline/generate-configs.js +53 -24
  226. package/dist/pipeline/grader-api.d.ts +3 -3
  227. package/dist/pipeline/grader-api.js +5 -12
  228. package/dist/pipeline/grader-compare-runner.js +20 -27
  229. package/dist/pipeline/grader-comparison.d.ts +4 -8
  230. package/dist/pipeline/grader-comparison.js +11 -17
  231. package/dist/pipeline/grader-consistency-runner.d.ts +2 -3
  232. package/dist/pipeline/grader-consistency-runner.js +16 -20
  233. package/dist/pipeline/grader-consistency.d.ts +6 -10
  234. package/dist/pipeline/grader-consistency.js +13 -32
  235. package/dist/pipeline/grader-sensitivity-runner.js +7 -5
  236. package/dist/pipeline/grader-sensitivity.d.ts +2 -6
  237. package/dist/pipeline/grader-sensitivity.js +10 -10
  238. package/dist/pipeline/grader-validate-runner.js +7 -5
  239. package/dist/pipeline/grader-validation.d.ts +2 -6
  240. package/dist/pipeline/grader-validation.js +14 -22
  241. package/dist/pipeline/map-request-to-config.js +6 -1
  242. package/dist/pipeline/mirror-repo-tasks.d.ts +6 -6
  243. package/dist/pipeline/mirror-repo-tasks.js +16 -15
  244. package/dist/pipeline/normalize-mode.d.ts +49 -0
  245. package/dist/pipeline/normalize-mode.js +64 -0
  246. package/dist/pipeline/plan.d.ts +5 -2
  247. package/dist/pipeline/plan.js +134 -78
  248. package/dist/pipeline/pr-comment.js +2 -0
  249. package/dist/pipeline/profile-resolution.d.ts +22 -14
  250. package/dist/pipeline/profile-resolution.js +41 -19
  251. package/dist/pipeline/provenance.d.ts +2 -2
  252. package/dist/pipeline/provenance.js +12 -17
  253. package/dist/pipeline/release-report.js +4 -4
  254. package/dist/pipeline/repo-threshold-evaluator.d.ts +1 -1
  255. package/dist/pipeline/repo-threshold-evaluator.js +1 -1
  256. package/dist/pipeline/rubric-loader.d.ts +20 -0
  257. package/dist/pipeline/rubric-loader.js +37 -0
  258. package/dist/pipeline/validate.d.ts +4 -4
  259. package/dist/pipeline/validate.js +64 -53
  260. package/dist/schedules/loader.js +18 -8
  261. package/dist/scripts/migrate-task-mode.d.ts +24 -0
  262. package/dist/scripts/migrate-task-mode.js +85 -0
  263. package/dist/scripts/migrate-tasks-to-content-lake.js +11 -10
  264. package/dist/scripts/validate-task-sources.d.ts +1 -1
  265. package/dist/scripts/validate-task-sources.js +15 -15
  266. package/dist/sinks/loader.js +5 -7
  267. package/dist/sources.d.ts +7 -7
  268. package/dist/sources.js +22 -24
  269. package/dist/webhook/dispatch.js +2 -1
  270. package/package.json +6 -3
  271. package/tasks/knowledge-probe/define-type-api.task.ts +55 -0
  272. package/tasks/knowledge-probe/groq-projections.task.ts +59 -0
  273. package/tasks/literacy/frameworks.task.ts +128 -0
  274. package/tasks/literacy/functions.task.ts +69 -0
  275. package/tasks/literacy/groq.task.ts +258 -0
  276. package/tasks/literacy/nextjs-live.task.ts +75 -0
  277. package/tasks/literacy/studio-setup.task.ts +131 -0
  278. package/tasks/literacy/visual-editing.task.ts +146 -0
  279. package/config/features.yaml +0 -116
  280. package/config/models.yaml +0 -116
  281. package/config/prompts.yaml +0 -75
  282. package/config/rubrics.yaml +0 -81
  283. package/config/schedules.yaml +0 -43
  284. package/config/sinks.yaml +0 -54
  285. package/config/sources.yaml +0 -51
  286. package/config/thresholds.yaml +0 -49
  287. package/dist/agent-observer/test-imports.d.ts +0 -7
  288. package/dist/agent-observer/test-imports.js +0 -185
@@ -7,11 +7,10 @@
7
7
  *
8
8
  * @see docs/design-docs/report-store/sink-architecture.md
9
9
  */
10
- import { existsSync, readFileSync } from "fs";
11
10
  import { dirname, resolve } from "path";
12
11
  import { fileURLToPath } from "url";
13
- import { load } from "js-yaml";
14
12
  import { interpolate } from "../interpolate.js";
13
+ import { tryLoadConfigFile } from "../pipeline/compiler/config-loader.js";
15
14
  import { BigQuerySink } from "./bigquery/index.js";
16
15
  import { SinksFileSchema } from "./schema.js";
17
16
  import { SlackSink } from "./slack/index.js";
@@ -20,7 +19,7 @@ import { WebhookSink } from "./webhook/index.js";
20
19
  // Paths
21
20
  // ---------------------------------------------------------------------------
22
21
  const __dirname = dirname(fileURLToPath(import.meta.url));
23
- const SINKS_CONFIG_PATH = resolve(__dirname, "..", "..", "config", "sinks.yaml");
22
+ const PACKAGE_ROOT = resolve(__dirname, "..", "..");
24
23
  // ---------------------------------------------------------------------------
25
24
  // Public API
26
25
  // ---------------------------------------------------------------------------
@@ -32,13 +31,12 @@ const SINKS_CONFIG_PATH = resolve(__dirname, "..", "..", "config", "sinks.yaml")
32
31
  * - The config file fails to parse or validate
33
32
  */
34
33
  export function loadSinks() {
35
- if (!existsSync(SINKS_CONFIG_PATH)) {
34
+ const loaded = tryLoadConfigFile("sinks", PACKAGE_ROOT);
35
+ if (!loaded) {
36
36
  return [];
37
37
  }
38
38
  try {
39
- const raw = readFileSync(SINKS_CONFIG_PATH, "utf-8");
40
- const parsed = load(raw);
41
- const interpolated = interpolate(parsed);
39
+ const interpolated = interpolate(loaded.data);
42
40
  // When all sinks are commented out, js-yaml returns { sinks: null }.
43
41
  // Normalize null → undefined so Zod's .default([]) can apply.
44
42
  const normalized = interpolated && typeof interpolated === "object"
package/dist/sources.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Sources.ts
3
3
  *
4
- * Loads and validates documentation source configurations from config/sources.yaml.
4
+ * Loads and validates documentation source configurations from config/sources.
5
5
  * Each source defines where to find documentation for evaluation — a Sanity
6
6
  * dataset, a branch deploy URL, a local dev server, etc.
7
7
  *
@@ -9,7 +9,7 @@
9
9
  * - Baseline/Observed: uses projectId + dataset (GROQ queries to Sanity CMS)
10
10
  * - Agentic: uses baseUrl (agent browses the live site, llms.txt derived automatically)
11
11
  *
12
- * Environment variables in config/sources.yaml are resolved via ${{ VAR | default }}
12
+ * Environment variables in config/sources are resolved via ${{ VAR | default }}
13
13
  * interpolation at load time.
14
14
  */
15
15
  import type { Logger } from "./_vendor/ailf-core/index.d.ts";
@@ -22,7 +22,7 @@ export type DocSource = ResolvedSourceConfig;
22
22
  * Fully resolved documentation source configuration.
23
23
  *
24
24
  * After all CLI flags, environment variables, URL classifications, and
25
- * config/sources.yaml defaults are merged, the system produces a single
25
+ * config/sources defaults are merged, the system produces a single
26
26
  * ResolvedSourceConfig that drives the entire pipeline.
27
27
  *
28
28
  * All ${{ }} expressions have been expanded by the time this is constructed.
@@ -40,7 +40,7 @@ export interface ResolvedSourceConfig {
40
40
  headers?: Record<string, string>;
41
41
  /** URL to the llms.txt file — always derived as baseUrl + "/llms.txt" */
42
42
  llmsTxt: string;
43
- /** Source name (the key from config/sources.yaml, or "env-override") */
43
+ /** Source name (the key from config/sources, or "env-override") */
44
44
  name: string;
45
45
  /** Sanity release perspective ID (optional — for evaluating content releases) */
46
46
  perspective?: string;
@@ -84,11 +84,11 @@ export interface SourceOverrides {
84
84
  *
85
85
  * Resolution order:
86
86
  * 1. If DOC_BASE_URL env var is set, build an ad-hoc source from env vars
87
- * 2. If config/sources.yaml exists, load and interpolate the named source
87
+ * 2. If config/sources exists, load and interpolate the named source
88
88
  * 3. Fall back to the built-in default (sanity.io production)
89
89
  *
90
- * @param name - Source name from config/sources.yaml. If omitted, uses DOC_SOURCE
91
- * env var or the first source defined in config/sources.yaml.
90
+ * @param name - Source name from config/sources. If omitted, uses DOC_SOURCE
91
+ * env var or the first source defined in config/sources.
92
92
  */
93
93
  export declare function loadSource(name?: string, overrides?: SourceOverrides, logger?: Logger): ResolvedSourceConfig;
94
94
  /**
package/dist/sources.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Sources.ts
3
3
  *
4
- * Loads and validates documentation source configurations from config/sources.yaml.
4
+ * Loads and validates documentation source configurations from config/sources.
5
5
  * Each source defines where to find documentation for evaluation — a Sanity
6
6
  * dataset, a branch deploy URL, a local dev server, etc.
7
7
  *
@@ -9,22 +9,21 @@
9
9
  * - Baseline/Observed: uses projectId + dataset (GROQ queries to Sanity CMS)
10
10
  * - Agentic: uses baseUrl (agent browses the live site, llms.txt derived automatically)
11
11
  *
12
- * Environment variables in config/sources.yaml are resolved via ${{ VAR | default }}
12
+ * Environment variables in config/sources are resolved via ${{ VAR | default }}
13
13
  * interpolation at load time.
14
14
  */
15
- import { readFileSync } from "fs";
16
15
  import { dirname, resolve } from "path";
17
16
  import { fileURLToPath } from "url";
18
- import { load } from "js-yaml";
19
17
  import { ConsoleLogger } from "./adapters/loggers/index.js";
20
18
  import { interpolate } from "./interpolate.js";
19
+ import { tryLoadConfigFile } from "./pipeline/compiler/config-loader.js";
21
20
  // ---------------------------------------------------------------------------
22
21
  // Paths
23
22
  // ---------------------------------------------------------------------------
24
23
  const __dirname = dirname(fileURLToPath(import.meta.url));
25
- const SOURCES_PATH = resolve(__dirname, "..", "config", "sources.yaml");
24
+ const PACKAGE_ROOT = resolve(__dirname, "..");
26
25
  // ---------------------------------------------------------------------------
27
- // Default source — used when no config/sources.yaml exists or no --source flag
26
+ // Default source — used when no config/sources exists or no --source flag
28
27
  // ---------------------------------------------------------------------------
29
28
  const DEFAULT_SOURCE = {
30
29
  baseUrl: "https://www.sanity.io/docs",
@@ -67,11 +66,11 @@ export function isAllowedOrigin(url, origins) {
67
66
  *
68
67
  * Resolution order:
69
68
  * 1. If DOC_BASE_URL env var is set, build an ad-hoc source from env vars
70
- * 2. If config/sources.yaml exists, load and interpolate the named source
69
+ * 2. If config/sources exists, load and interpolate the named source
71
70
  * 3. Fall back to the built-in default (sanity.io production)
72
71
  *
73
- * @param name - Source name from config/sources.yaml. If omitted, uses DOC_SOURCE
74
- * env var or the first source defined in config/sources.yaml.
72
+ * @param name - Source name from config/sources. If omitted, uses DOC_SOURCE
73
+ * env var or the first source defined in config/sources.
75
74
  */
76
75
  export function loadSource(name, overrides, logger) {
77
76
  const log = logger ?? new ConsoleLogger();
@@ -105,32 +104,31 @@ export function loadSource(name, overrides, logger) {
105
104
  urls: overrides?.directUrls ?? parseDirectUrlsEnv(),
106
105
  };
107
106
  }
108
- // Priority 2: Load from config/sources.yaml
107
+ // Priority 2: Load from config/sources (TS, JS, YAML, or JSON)
109
108
  let rawFile;
110
- try {
111
- const content = readFileSync(SOURCES_PATH, "utf-8");
112
- rawFile = load(content);
109
+ const loaded = tryLoadConfigFile("sources", PACKAGE_ROOT);
110
+ if (loaded) {
111
+ rawFile = loaded.data;
113
112
  }
114
- catch {
115
- // No config/sources.yaml — use built-in default
116
- log.debug("No config/sources.yaml found, falling back to built-in default", {
117
- path: SOURCES_PATH,
113
+ else {
114
+ // No config file found — use built-in default
115
+ log.debug("No config/sources found, falling back to built-in default", {
118
116
  defaultName: DEFAULT_SOURCE.name,
119
117
  defaultBaseUrl: DEFAULT_SOURCE.baseUrl,
120
118
  });
121
- console.log(" No config/sources.yaml found, using built-in default (sanity.io production)");
119
+ console.log(" No config/sources found, using built-in default (sanity.io production)");
122
120
  return DEFAULT_SOURCE;
123
121
  }
124
122
  if (!rawFile?.sources || Object.keys(rawFile.sources).length === 0) {
125
- log.debug("config/sources.yaml is empty, falling back to built-in default");
126
- console.log(" config/sources.yaml is empty, using built-in default");
123
+ log.debug("config/sources is empty, falling back to built-in default");
124
+ console.log(" config/sources is empty, using built-in default");
127
125
  return DEFAULT_SOURCE;
128
126
  }
129
127
  // Resolve which source to use
130
128
  const sourceName =
131
129
  // oxlint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty strings should fall through to next candidate
132
130
  name || process.env.DOC_SOURCE || Object.keys(rawFile.sources)[0];
133
- log.debug("Resolving source from config/sources.yaml", {
131
+ log.debug("Resolving source from config/sources", {
134
132
  requestedName: name,
135
133
  resolvedName: sourceName,
136
134
  availableSources: Object.keys(rawFile.sources),
@@ -140,7 +138,7 @@ export function loadSource(name, overrides, logger) {
140
138
  const available = Object.keys(rawFile.sources).join(", ");
141
139
  throw new Error('Source "' +
142
140
  sourceName +
143
- '" not found in config/sources.yaml. Available: ' +
141
+ '" not found in config/sources. Available: ' +
144
142
  available);
145
143
  }
146
144
  // Interpolate ${{ VAR }} expressions
@@ -151,7 +149,7 @@ export function loadSource(name, overrides, logger) {
151
149
  // An interpolation like ${{ DOC_ALLOWED_ORIGIN | }} resolves to "",
152
150
  // Which would produce [""] — matching nothing and silently blocking all origins.
153
151
  const filteredOrigins = resolved.allowedOrigins?.filter(Boolean);
154
- log.debug("Source resolved from config/sources.yaml", {
152
+ log.debug("Source resolved from config/sources", {
155
153
  name: sourceName,
156
154
  baseUrl: resolved.baseUrl,
157
155
  dataset: resolved.dataset,
@@ -208,7 +206,7 @@ function extractHostname(url) {
208
206
  }
209
207
  }
210
208
  /**
211
- * Merge headers from config/sources.yaml with DOC_HEADERS env var.
209
+ * Merge headers from config/sources with DOC_HEADERS env var.
212
210
  * Env var headers take precedence over source-defined headers.
213
211
  * Returns undefined if both are empty.
214
212
  */
@@ -15,6 +15,7 @@
15
15
  * @see .github/workflows/external-eval.yml
16
16
  * @see docs/design-docs/cross-repo-eval.md
17
17
  */
18
+ import { LiteracyVariant } from "../pipeline/normalize-mode.js";
18
19
  // ---------------------------------------------------------------------------
19
20
  // Constants
20
21
  // ---------------------------------------------------------------------------
@@ -43,7 +44,7 @@ export async function dispatchEvaluation(request, options) {
43
44
  ? request.documentSlug.split(",").filter(Boolean)
44
45
  : undefined,
45
46
  compare: true,
46
- mode: request.mode ?? "baseline",
47
+ mode: request.mode ?? LiteracyVariant.STANDARD,
47
48
  publish: true,
48
49
  source: "production",
49
50
  tasks: request.taskIds.length > 0 ? request.taskIds : undefined,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/ailf",
3
- "version": "0.5.0",
3
+ "version": "1.0.0",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "restricted"
@@ -31,6 +31,7 @@
31
31
  "commander": "^14.0.3",
32
32
  "dotenv": "^16.4.7",
33
33
  "dotenv-cli": "^11.0.0",
34
+ "jiti": "^2.6.1",
34
35
  "js-yaml": "^4.1.0",
35
36
  "promptfoo": "^0.120.24",
36
37
  "zod": "^4.3.6"
@@ -41,8 +42,8 @@
41
42
  "tsx": "^4.19.2",
42
43
  "typescript": "^5.7.3",
43
44
  "@sanity/ailf-core": "0.1.0",
44
- "@sanity/ailf-tasks": "0.1.4",
45
- "@sanity/ailf-shared": "0.1.0"
45
+ "@sanity/ailf-shared": "0.1.0",
46
+ "@sanity/ailf-tasks": "0.1.4"
46
47
  },
47
48
  "scripts": {
48
49
  "build": "tsc && tsx scripts/bundle-workspace-deps.ts",
@@ -63,6 +64,8 @@
63
64
  "pipeline": "tsx src/cli.ts pipeline",
64
65
  "validate": "tsx src/cli.ts validate",
65
66
  "test": "tsx --test src/__tests__/*.test.ts",
67
+ "test:e2e": "AILF_E2E=1 tsx --test src/__tests__/e2e/*.e2e.test.ts",
68
+ "test:all": "AILF_E2E=1 tsx --test src/__tests__/*.test.ts src/pipeline/compiler/__tests__/*.test.ts src/__tests__/e2e/*.e2e.test.ts",
66
69
  "pr-comment": "tsx src/cli.ts pr-comment",
67
70
  "coverage-audit": "tsx src/cli.ts coverage-audit",
68
71
  "readiness-report": "tsx src/cli.ts readiness-report",
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Knowledge probe: Sanity defineType API.
3
+ *
4
+ * Tests whether models know the current typed schema API
5
+ * vs the legacy untyped format.
6
+ */
7
+ import { defineTask } from "@sanity/ailf-core"
8
+
9
+ export default defineTask({
10
+ mode: "knowledge-probe",
11
+ id: "kp-define-type-api",
12
+ title: "What is Sanity's defineType API?",
13
+ description:
14
+ "Explain how to define document schemas in Sanity using the defineType, " +
15
+ "defineField, and defineArrayMember helper functions.",
16
+ area: "studio",
17
+ difficulty: "basic",
18
+ tags: ["knowledge-probe", "studio", "schema"],
19
+ probeStrategy: "breadth-first",
20
+ prompt: {
21
+ text:
22
+ "Explain Sanity's schema definition API:\n\n" +
23
+ "1. What is `defineType` and how do you use it?\n" +
24
+ "2. What are `defineField` and `defineArrayMember`?\n" +
25
+ "3. Why were these typed helpers introduced? What did they replace?\n" +
26
+ "4. Show a complete example of a document schema with various field types\n" +
27
+ "5. How do you add validation rules using the typed API?",
28
+ vars: {
29
+ task:
30
+ "Explain Sanity's defineType/defineField schema API with examples, " +
31
+ "motivation, and validation rules.",
32
+ },
33
+ },
34
+ assertions: [
35
+ { type: "contains", value: "defineType" },
36
+ { type: "contains", value: "defineField" },
37
+ {
38
+ type: "llm-rubric",
39
+ value:
40
+ "The response should accurately explain the typed schema helpers. " +
41
+ "Check that the code examples use the current API, not the legacy " +
42
+ "untyped format. Penalize if the response uses the old pattern " +
43
+ "without mentioning defineType.",
44
+ weight: 0.5,
45
+ },
46
+ {
47
+ type: "llm-rubric",
48
+ value:
49
+ "Evaluate currency: does the response know about defineType " +
50
+ "(introduced in Sanity v3)? Does it mention TypeScript type " +
51
+ "inference benefits?",
52
+ weight: 0.5,
53
+ },
54
+ ],
55
+ })
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Knowledge probe: GROQ projection syntax.
3
+ *
4
+ * Tests deep knowledge of Sanity's query language without
5
+ * providing any documentation context.
6
+ */
7
+ import { defineTask } from "@sanity/ailf-core"
8
+
9
+ export default defineTask({
10
+ mode: "knowledge-probe",
11
+ id: "kp-groq-projections",
12
+ title: "Explain GROQ Projection Syntax",
13
+ description:
14
+ "Explain GROQ's projection syntax in detail, including: " +
15
+ "object projections ({}), array projections, spread operator (...), " +
16
+ "computed field names, the dereference operator (->), and " +
17
+ "conditional projections using select().",
18
+ area: "groq",
19
+ difficulty: "intermediate",
20
+ tags: ["knowledge-probe", "groq", "syntax"],
21
+ probeStrategy: "depth-first",
22
+ prompt: {
23
+ text:
24
+ "Explain GROQ's projection syntax in Sanity. Cover these topics:\n\n" +
25
+ "1. Basic object projections with `{}`\n" +
26
+ "2. Nested projections and the spread operator `...`\n" +
27
+ "3. Computed field names\n" +
28
+ "4. The dereference operator `->` for following references\n" +
29
+ "5. Array slicing with `[0..5]` and `[0...5]`\n" +
30
+ "6. Conditional projections using `select()`\n\n" +
31
+ "Provide working code examples for each.",
32
+ vars: {
33
+ task:
34
+ "Explain GROQ projection syntax with working code examples " +
35
+ "covering projections, spread, dereference, slicing, and select().",
36
+ },
37
+ },
38
+ assertions: [
39
+ { type: "contains", value: "->" },
40
+ { type: "contains", value: "select(" },
41
+ {
42
+ type: "llm-rubric",
43
+ value:
44
+ "The response should demonstrate accurate knowledge of GROQ " +
45
+ "projection syntax with working code examples. Check that the " +
46
+ "dereference operator, spread syntax, and select() are correctly " +
47
+ "explained with valid GROQ code.",
48
+ weight: 0.6,
49
+ },
50
+ {
51
+ type: "llm-rubric",
52
+ value:
53
+ "Evaluate whether the response reflects current GROQ syntax " +
54
+ "(post-2023). Check for deprecated patterns or outdated " +
55
+ "recommendations.",
56
+ weight: 0.4,
57
+ },
58
+ ],
59
+ })
@@ -0,0 +1,128 @@
1
+ import { defineTask } from "@sanity/ailf-core"
2
+
3
+ export default [
4
+ defineTask({
5
+ id: "remix-integration",
6
+ mode: "literacy",
7
+ title: "Frameworks - Remix integration with data fetching",
8
+ description: "Frameworks - Remix integration with data fetching",
9
+ area: "frameworks",
10
+ docCoverage: true,
11
+ context: {
12
+ docs: [
13
+ {
14
+ slug: "displaying-content-in-a-react-router-front-end",
15
+ reason: "React Router front-end content display guide",
16
+ },
17
+ {
18
+ slug: "visual-editing-with-react-router",
19
+ reason: "React Router / Remix integration with visual editing",
20
+ },
21
+ {
22
+ slug: "functions-js-client",
23
+ reason: "Configuring @sanity/client for data fetching",
24
+ },
25
+ ],
26
+ },
27
+ referenceSolution: "reference-solutions/frameworks/remix.tsx",
28
+ prompt: {
29
+ vars: {
30
+ task: `Integrate Sanity into a Remix application:
31
+
32
+ 1. Set up the Sanity client
33
+ 2. Create a loader that fetches blog posts using GROQ
34
+ 3. Build a route component that renders the fetched posts
35
+ 4. Handle loading and error states properly
36
+
37
+ Provide all necessary files for a working Remix + Sanity integration.`,
38
+ docs: "file://contexts/canonical/remix-integration.md",
39
+ },
40
+ },
41
+ assertions: [
42
+ {
43
+ type: "llm-rubric",
44
+ template: "task-completion",
45
+ criteria: [
46
+ "Sanity client configuration",
47
+ "Remix loader function with GROQ query",
48
+ "Route component using useLoaderData",
49
+ "Proper typing",
50
+ ],
51
+ },
52
+ {
53
+ type: "llm-rubric",
54
+ template: "code-correctness",
55
+ criteria: [
56
+ "Modern Remix patterns (v2 conventions)",
57
+ "Proper loader/component separation",
58
+ "Valid GROQ queries",
59
+ "No deprecated APIs",
60
+ ],
61
+ },
62
+ {
63
+ type: "contains-any",
64
+ value: ["useLoaderData", "loader"],
65
+ weight: 1,
66
+ },
67
+ ],
68
+ }),
69
+
70
+ defineTask({
71
+ id: "nuxt-integration",
72
+ mode: "literacy",
73
+ title: "Frameworks - Nuxt 4 integration",
74
+ description: "Frameworks - Nuxt 4 integration",
75
+ area: "frameworks",
76
+ docCoverage: true,
77
+ context: {
78
+ docs: [
79
+ {
80
+ slug: "displaying-content-in-nuxt-js",
81
+ reason: "Nuxt.js front-end content display guide",
82
+ },
83
+ {
84
+ slug: "visual-editing-with-nuxt",
85
+ reason: "Nuxt visual editing integration",
86
+ },
87
+ ],
88
+ },
89
+ referenceSolution: "reference-solutions/frameworks/nuxt.ts",
90
+ prompt: {
91
+ vars: {
92
+ task: `Integrate Sanity into a Nuxt 4 application:
93
+
94
+ 1. Install and configure the @nuxtjs/sanity module
95
+ 2. Create a page that fetches and displays blog posts
96
+ 3. Use Nuxt composables for data fetching
97
+
98
+ Provide all necessary configuration and component code.`,
99
+ docs: "file://contexts/canonical/nuxt-integration.md",
100
+ },
101
+ },
102
+ assertions: [
103
+ {
104
+ type: "llm-rubric",
105
+ template: "task-completion",
106
+ criteria: [
107
+ "@nuxtjs/sanity module setup in nuxt.config.ts",
108
+ "Page component using Nuxt data fetching composables",
109
+ "Sanity GROQ query",
110
+ ],
111
+ },
112
+ {
113
+ type: "llm-rubric",
114
+ template: "code-correctness",
115
+ criteria: [
116
+ "Nuxt 3 module configuration syntax",
117
+ "Uses useSanityQuery or equivalent composable",
118
+ "Proper Nuxt 3 patterns (not Nuxt 2)",
119
+ ],
120
+ },
121
+ {
122
+ type: "contains-any",
123
+ value: ["@nuxtjs/sanity", "useSanityQuery", "sanity:"],
124
+ weight: 1,
125
+ },
126
+ ],
127
+ }),
128
+ ]
@@ -0,0 +1,69 @@
1
+ import { defineTask } from "@sanity/ailf-core"
2
+
3
+ export default [
4
+ defineTask({
5
+ id: "functions-webhook",
6
+ mode: "literacy",
7
+ title: "Functions - Webhook on document publish",
8
+ description: "Functions - Webhook on document publish",
9
+ area: "functions",
10
+ docCoverage: true,
11
+ context: {
12
+ docs: [
13
+ {
14
+ slug: "functions-introduction",
15
+ reason: "Functions overview — deployment, triggers, lifecycle",
16
+ },
17
+ {
18
+ slug: "webhooks",
19
+ reason: "GROQ-powered webhooks — configuration and filtering",
20
+ },
21
+ {
22
+ slug: "function-wrapper",
23
+ reason: "Function handler reference — event shape, exports",
24
+ },
25
+ {
26
+ slug: "functions-cheatsheet",
27
+ reason: "Quick reference for common function patterns",
28
+ },
29
+ ],
30
+ },
31
+ referenceSolution: "reference-solutions/functions/publish-webhook.ts",
32
+ prompt: {
33
+ vars: {
34
+ task: `Deploy a Sanity function that triggers when a document is published
35
+ and sends a webhook notification to an external endpoint.
36
+
37
+ Requirements:
38
+ 1. The function should trigger on document publish events
39
+ 2. Filter to only fire for "post" document types
40
+ 3. Send a POST request to an external URL with the document data
41
+ 4. Handle errors gracefully
42
+
43
+ Provide a complete implementation including any configuration.`,
44
+ docs: "file://contexts/canonical/functions-webhook.md",
45
+ },
46
+ },
47
+ assertions: [
48
+ {
49
+ type: "llm-rubric",
50
+ template: "task-completion",
51
+ criteria: [
52
+ "Event-driven function definition",
53
+ "Document type filtering (post type only)",
54
+ "HTTP webhook call with document payload",
55
+ "Basic error handling",
56
+ ],
57
+ },
58
+ {
59
+ type: "llm-rubric",
60
+ template: "code-correctness",
61
+ criteria: [
62
+ "No deprecated API patterns",
63
+ "Proper error handling",
64
+ "Idiomatic function handler structure",
65
+ ],
66
+ },
67
+ ],
68
+ }),
69
+ ]