@sanity/ailf 2.7.1 → 2.9.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 (92) hide show
  1. package/dist/_vendor/ailf-core/artifact-capture/association.d.ts +35 -0
  2. package/dist/_vendor/ailf-core/artifact-capture/association.js +28 -0
  3. package/dist/_vendor/ailf-core/artifact-registry.d.ts +173 -0
  4. package/dist/_vendor/ailf-core/artifact-registry.js +811 -0
  5. package/dist/_vendor/ailf-core/index.d.ts +3 -1
  6. package/dist/_vendor/ailf-core/index.js +3 -1
  7. package/dist/_vendor/ailf-core/ports/artifact-collector.d.ts +3 -3
  8. package/dist/_vendor/ailf-core/ports/artifact-writer.d.ts +95 -0
  9. package/dist/_vendor/ailf-core/ports/artifact-writer.js +51 -0
  10. package/dist/_vendor/ailf-core/ports/context.d.ts +32 -3
  11. package/dist/_vendor/ailf-core/ports/index.d.ts +3 -3
  12. package/dist/_vendor/ailf-core/ports/index.js +1 -1
  13. package/dist/_vendor/ailf-core/schemas/pipeline.d.ts +6 -6
  14. package/dist/_vendor/ailf-core/services/index.d.ts +1 -0
  15. package/dist/_vendor/ailf-core/services/index.js +1 -0
  16. package/dist/_vendor/ailf-core/services/slim-report-summary.d.ts +31 -0
  17. package/dist/_vendor/ailf-core/services/slim-report-summary.js +217 -0
  18. package/dist/_vendor/ailf-core/types/branded-ids.d.ts +42 -0
  19. package/dist/_vendor/ailf-core/types/branded-ids.js +21 -0
  20. package/dist/_vendor/ailf-core/types/index.d.ts +298 -77
  21. package/dist/_vendor/ailf-core/types/index.js +1 -1
  22. package/dist/_vendor/ailf-shared/index.d.ts +2 -0
  23. package/dist/_vendor/ailf-shared/index.js +2 -0
  24. package/dist/_vendor/ailf-shared/run-context.d.ts +55 -0
  25. package/dist/_vendor/ailf-shared/run-context.js +17 -0
  26. package/dist/_vendor/ailf-shared/run-trigger.d.ts +30 -0
  27. package/dist/_vendor/ailf-shared/run-trigger.js +13 -0
  28. package/dist/artifact-capture/accumulating-artifact-writer.d.ts +50 -0
  29. package/dist/artifact-capture/accumulating-artifact-writer.js +111 -0
  30. package/dist/artifact-capture/api-gateway-artifact-writer.d.ts +52 -0
  31. package/dist/artifact-capture/api-gateway-artifact-writer.js +199 -0
  32. package/dist/artifact-capture/emit-file.d.ts +28 -0
  33. package/dist/artifact-capture/emit-file.js +56 -0
  34. package/dist/artifact-capture/fanout-artifact-writer.d.ts +39 -0
  35. package/dist/artifact-capture/fanout-artifact-writer.js +76 -0
  36. package/dist/artifact-capture/filesystem-collector.d.ts +22 -4
  37. package/dist/artifact-capture/filesystem-collector.js +48 -23
  38. package/dist/artifact-capture/gcs-artifact-writer.d.ts +67 -0
  39. package/dist/artifact-capture/gcs-artifact-writer.js +343 -0
  40. package/dist/artifact-capture/local-fs-artifact-writer.d.ts +71 -0
  41. package/dist/artifact-capture/local-fs-artifact-writer.js +273 -0
  42. package/dist/commands/explain-handler.js +4 -0
  43. package/dist/commands/pipeline-action.d.ts +5 -0
  44. package/dist/commands/pipeline-action.js +56 -5
  45. package/dist/commands/pipeline.d.ts +4 -0
  46. package/dist/commands/pipeline.js +6 -2
  47. package/dist/commands/publish.js +7 -3
  48. package/dist/composition-root.d.ts +14 -11
  49. package/dist/composition-root.js +90 -31
  50. package/dist/orchestration/build-step-sequence.js +6 -1
  51. package/dist/orchestration/pipeline-orchestrator.d.ts +1 -1
  52. package/dist/orchestration/pipeline-orchestrator.js +41 -30
  53. package/dist/orchestration/steps/calculate-scores-step.d.ts +1 -1
  54. package/dist/orchestration/steps/calculate-scores-step.js +50 -10
  55. package/dist/orchestration/steps/callback-step.d.ts +1 -1
  56. package/dist/orchestration/steps/callback-step.js +6 -4
  57. package/dist/orchestration/steps/compare-step.d.ts +1 -1
  58. package/dist/orchestration/steps/compare-step.js +4 -2
  59. package/dist/orchestration/steps/discovery-report-step.d.ts +1 -1
  60. package/dist/orchestration/steps/discovery-report-step.js +4 -1
  61. package/dist/orchestration/steps/fetch-docs-step.js +9 -15
  62. package/dist/orchestration/steps/finalize-run-step.d.ts +29 -0
  63. package/dist/orchestration/steps/finalize-run-step.js +117 -0
  64. package/dist/orchestration/steps/gap-analysis-step.js +34 -6
  65. package/dist/orchestration/steps/generate-configs-step.d.ts +1 -1
  66. package/dist/orchestration/steps/generate-configs-step.js +11 -11
  67. package/dist/orchestration/steps/publish-report-step.d.ts +1 -1
  68. package/dist/orchestration/steps/publish-report-step.js +40 -55
  69. package/dist/orchestration/steps/readiness-step.d.ts +1 -1
  70. package/dist/orchestration/steps/readiness-step.js +4 -1
  71. package/dist/orchestration/steps/report-step.d.ts +1 -1
  72. package/dist/orchestration/steps/report-step.js +6 -3
  73. package/dist/orchestration/steps/run-eval-step.js +14 -9
  74. package/dist/pipeline/calculate-scores.js +13 -2
  75. package/dist/pipeline/compare.d.ts +2 -2
  76. package/dist/pipeline/emit-eval-results.d.ts +38 -0
  77. package/dist/pipeline/emit-eval-results.js +100 -0
  78. package/dist/pipeline/provenance.d.ts +24 -44
  79. package/dist/pipeline/provenance.js +17 -165
  80. package/dist/pipeline/report-title.d.ts +2 -2
  81. package/dist/pipeline/run-context.d.ts +57 -0
  82. package/dist/pipeline/run-context.js +156 -0
  83. package/dist/pipeline/upload-test-outputs.d.ts +26 -0
  84. package/dist/pipeline/upload-test-outputs.js +34 -0
  85. package/dist/report-store.js +4 -2
  86. package/package.json +3 -3
  87. package/dist/_vendor/ailf-core/ports/artifact-uploader.d.ts +0 -35
  88. package/dist/_vendor/ailf-core/ports/artifact-uploader.js +0 -18
  89. package/dist/artifact-capture/api-gateway-artifact-uploader.d.ts +0 -41
  90. package/dist/artifact-capture/api-gateway-artifact-uploader.js +0 -123
  91. package/dist/artifact-capture/gcs-report-artifact-uploader.d.ts +0 -31
  92. package/dist/artifact-capture/gcs-report-artifact-uploader.js +0 -66
@@ -0,0 +1,34 @@
1
+ /**
2
+ * upload-test-outputs.ts — shared helper for the testOutputs artifact upload.
3
+ *
4
+ * CalculateScoresStep calls this once its score-summary.json is complete.
5
+ * Each {taskId, modelId} pair becomes one GCS object under
6
+ * `runs/{runId}/test-outputs/{taskId}--{modelId}.json` carrying the full
7
+ * response output and truncation flag. The returned ArtifactRef's
8
+ * `entries[]` catalog lists every uploaded entry so Studio can render
9
+ * drill-down state without a second listing call.
10
+ *
11
+ * PublishReportStep later strips responseOutput from the inline
12
+ * testResults[] when this upload succeeds, so the Content Lake document
13
+ * stays slim — the full output lives in GCS and is fetched per-entry
14
+ * on click.
15
+ *
16
+ * @see docs/decisions/D0032-run-anchored-artifact-store.md
17
+ */
18
+ /**
19
+ * Upload testOutputs as per-entry GCS objects under
20
+ * `runs/{runId}/test-outputs/`, one per `{taskId}::{modelId}` pair.
21
+ *
22
+ * Returns the `ArtifactRef` on success, or `null` when upload is skipped or
23
+ * fails (P5: non-blocking).
24
+ */
25
+ export async function uploadTestOutputs(writer, runId, testResults) {
26
+ const entries = testResults.map((tr) => ({
27
+ key: `${tr.taskId}::${tr.modelId}`,
28
+ data: {
29
+ responseOutput: tr.responseOutput ?? "",
30
+ responseOutputTruncated: tr.responseOutputTruncated ?? false,
31
+ },
32
+ }));
33
+ return writer.writePerEntry("testOutputs", runId, entries);
34
+ }
@@ -211,8 +211,10 @@ export class ReportStore {
211
211
  summary: {
212
212
  ...report.summary,
213
213
  // Artifact references live inside summary in Sanity so they're
214
- // projected automatically by the reportDetailQuery (D0030)
215
- ...(report.artifacts ? { artifacts: report.artifacts } : {}),
214
+ // projected automatically by the reportDetailQuery (D0032)
215
+ ...(report.artifactManifest
216
+ ? { artifactManifest: report.artifactManifest }
217
+ : {}),
216
218
  },
217
219
  tag: report.tag ?? null,
218
220
  title: report.title ?? null,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/ailf",
3
- "version": "2.7.1",
3
+ "version": "2.9.0",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -52,8 +52,8 @@
52
52
  "@types/node": "^22.13.1",
53
53
  "tsx": "^4.19.2",
54
54
  "typescript": "^5.7.3",
55
- "@sanity/ailf-shared": "0.1.0",
56
- "@sanity/ailf-core": "0.1.0"
55
+ "@sanity/ailf-core": "0.1.0",
56
+ "@sanity/ailf-shared": "0.1.0"
57
57
  },
58
58
  "scripts": {
59
59
  "build": "tsc && tsx scripts/bundle-workspace-deps.ts",
@@ -1,35 +0,0 @@
1
- /**
2
- * Port: ArtifactUploader — uploads report artifacts to external object storage.
3
- *
4
- * Separate from ArtifactCollector (which captures forensic archives).
5
- * This port puts structured files at known paths so Studio can fetch
6
- * them on demand via signed URLs.
7
- *
8
- * @see docs/design-docs/external-artifact-store.md
9
- * @see docs/decisions/D0030-external-artifact-store.md
10
- */
11
- import type { ArtifactRef } from "../types/index.js";
12
- /**
13
- * Uploads report artifacts to external storage.
14
- *
15
- * Implementations:
16
- * - GcsReportArtifactUploader (packages/eval) — uploads to GCS
17
- * - NoOpArtifactUploader (below) — returns null (no-op when GCS is not configured)
18
- */
19
- export interface ArtifactUploader {
20
- /**
21
- * Upload a JSON artifact for a report.
22
- *
23
- * @param reportId - Report identifier (used as the GCS path prefix)
24
- * @param fileName - File name within the report prefix (e.g., "test-outputs.json")
25
- * @param data - Serializable data (will be JSON.stringify'd)
26
- * @returns ArtifactRef on success, null if upload is skipped or fails
27
- */
28
- upload(reportId: string, fileName: string, data: unknown): Promise<ArtifactRef | null>;
29
- }
30
- /**
31
- * No-op uploader — always returns null. Used when GCS is not configured.
32
- */
33
- export declare class NoOpArtifactUploader implements ArtifactUploader {
34
- upload(): Promise<null>;
35
- }
@@ -1,18 +0,0 @@
1
- /**
2
- * Port: ArtifactUploader — uploads report artifacts to external object storage.
3
- *
4
- * Separate from ArtifactCollector (which captures forensic archives).
5
- * This port puts structured files at known paths so Studio can fetch
6
- * them on demand via signed URLs.
7
- *
8
- * @see docs/design-docs/external-artifact-store.md
9
- * @see docs/decisions/D0030-external-artifact-store.md
10
- */
11
- /**
12
- * No-op uploader — always returns null. Used when GCS is not configured.
13
- */
14
- export class NoOpArtifactUploader {
15
- async upload() {
16
- return null;
17
- }
18
- }
@@ -1,41 +0,0 @@
1
- /**
2
- * ApiGatewayArtifactUploader — uploads report artifacts via the API Gateway.
3
- *
4
- * Counterpart to GcsReportArtifactUploader. Used when the CLI runs locally
5
- * without GCS credentials. Two-step flow:
6
- *
7
- * 1. GET {apiBaseUrl}/v1/artifacts/{reportId}/upload-url?type={artifactType}
8
- * with Authorization: Bearer {apiKey} — returns a signed PUT URL.
9
- * 2. PUT the JSON to that URL with Content-Type: application/json and
10
- * x-goog-if-generation-match: 0 (overwrite-protection contract from
11
- * the gateway's signed URL).
12
- *
13
- * The gateway stays out of the data path — Vercel only signs the URL,
14
- * the artifact bytes go directly to GCS.
15
- *
16
- * Design principles:
17
- * - P5: Non-blocking — any failure returns null and warns, never throws.
18
- * - Stateless — no client to keep around between calls.
19
- *
20
- * @see docs/design-docs/external-artifact-store.md
21
- * @see docs/decisions/D0030-external-artifact-store.md
22
- */
23
- import type { ArtifactRef, ArtifactUploader } from "../_vendor/ailf-core/index.d.ts";
24
- export interface ApiGatewayUploaderOptions {
25
- /** Base URL of the API gateway (e.g., "https://api.ailf.sanity.io"). */
26
- apiBaseUrl: string;
27
- /** AILF API key with the `artifact:write` scope. */
28
- apiKey: string;
29
- /** GCS bucket name — included in the returned ArtifactRef. */
30
- bucket: string;
31
- }
32
- export declare class ApiGatewayArtifactUploader implements ArtifactUploader {
33
- private readonly options;
34
- constructor(options: ApiGatewayUploaderOptions);
35
- upload(reportId: string, fileName: string, data: unknown): Promise<ArtifactRef | null>;
36
- /**
37
- * Fetch a signed upload URL from the gateway. Returns null on any non-2xx
38
- * response or malformed body so the caller can stay non-blocking.
39
- */
40
- private fetchSignedUrl;
41
- }
@@ -1,123 +0,0 @@
1
- /**
2
- * ApiGatewayArtifactUploader — uploads report artifacts via the API Gateway.
3
- *
4
- * Counterpart to GcsReportArtifactUploader. Used when the CLI runs locally
5
- * without GCS credentials. Two-step flow:
6
- *
7
- * 1. GET {apiBaseUrl}/v1/artifacts/{reportId}/upload-url?type={artifactType}
8
- * with Authorization: Bearer {apiKey} — returns a signed PUT URL.
9
- * 2. PUT the JSON to that URL with Content-Type: application/json and
10
- * x-goog-if-generation-match: 0 (overwrite-protection contract from
11
- * the gateway's signed URL).
12
- *
13
- * The gateway stays out of the data path — Vercel only signs the URL,
14
- * the artifact bytes go directly to GCS.
15
- *
16
- * Design principles:
17
- * - P5: Non-blocking — any failure returns null and warns, never throws.
18
- * - Stateless — no client to keep around between calls.
19
- *
20
- * @see docs/design-docs/external-artifact-store.md
21
- * @see docs/decisions/D0030-external-artifact-store.md
22
- */
23
- // ---------------------------------------------------------------------------
24
- // File-name → artifact-type mapping (mirrors packages/api ARTIFACT_FILES)
25
- // ---------------------------------------------------------------------------
26
- /**
27
- * Reverse map of the API gateway's ARTIFACT_FILES. The uploader port speaks
28
- * file names; the gateway endpoint speaks artifact types. Keep these in sync
29
- * with packages/api/src/routes/artifacts.ts.
30
- */
31
- const FILE_TO_TYPE = {
32
- "eval-results.json": "evalResults",
33
- "grader-prompts.json": "graderPrompts",
34
- "rendered-prompts.json": "renderedPrompts",
35
- "task-definitions.json": "taskDefinitions",
36
- "test-outputs.json": "testOutputs",
37
- };
38
- export class ApiGatewayArtifactUploader {
39
- options;
40
- constructor(options) {
41
- this.options = options;
42
- }
43
- async upload(reportId, fileName, data) {
44
- const artifactType = FILE_TO_TYPE[fileName];
45
- if (!artifactType) {
46
- console.warn(` ⚠️ Artifact upload skipped (unknown fileName): ${fileName}`);
47
- return null;
48
- }
49
- const objectPath = `reports/${reportId}/${fileName}`;
50
- const json = JSON.stringify(data);
51
- const bytes = Buffer.byteLength(json, "utf-8");
52
- try {
53
- const signed = await this.fetchSignedUrl(reportId, artifactType);
54
- if (!signed)
55
- return null;
56
- const putRes = await fetch(signed.url, {
57
- body: json,
58
- headers: signed.requiredHeaders,
59
- method: "PUT",
60
- });
61
- if (!putRes.ok) {
62
- console.warn(` ⚠️ Artifact upload failed (non-blocking): ${objectPath} — GCS PUT ${putRes.status} ${putRes.statusText}`);
63
- return null;
64
- }
65
- return {
66
- bucket: signed.bucket,
67
- bytes,
68
- entryCount: extractEntryCount(data),
69
- path: signed.path,
70
- store: "gcs",
71
- };
72
- }
73
- catch (err) {
74
- const message = err instanceof Error ? err.message : String(err);
75
- console.warn(` ⚠️ Artifact upload failed (non-blocking): ${objectPath} — ${message}`);
76
- return null;
77
- }
78
- }
79
- /**
80
- * Fetch a signed upload URL from the gateway. Returns null on any non-2xx
81
- * response or malformed body so the caller can stay non-blocking.
82
- */
83
- async fetchSignedUrl(reportId, artifactType) {
84
- const url = `${this.options.apiBaseUrl.replace(/\/$/, "")}/v1/artifacts/${encodeURIComponent(reportId)}/upload-url?type=${encodeURIComponent(artifactType)}`;
85
- const res = await fetch(url, {
86
- headers: {
87
- Authorization: `Bearer ${this.options.apiKey}`,
88
- },
89
- method: "GET",
90
- });
91
- if (!res.ok) {
92
- console.warn(` ⚠️ Signed-URL request failed: ${res.status} ${res.statusText}`);
93
- return null;
94
- }
95
- const body = (await res.json());
96
- if (body.object !== "signed_upload_url" ||
97
- typeof body.url !== "string" ||
98
- typeof body.path !== "string" ||
99
- typeof body.bucket !== "string" ||
100
- !body.requiredHeaders) {
101
- console.warn(` ⚠️ Signed-URL response was malformed`);
102
- return null;
103
- }
104
- return {
105
- bucket: body.bucket,
106
- method: "PUT",
107
- object: "signed_upload_url",
108
- path: body.path,
109
- requiredHeaders: body.requiredHeaders,
110
- url: body.url,
111
- };
112
- }
113
- }
114
- function extractEntryCount(data) {
115
- if (typeof data === "object" &&
116
- data !== null &&
117
- "entries" in data &&
118
- typeof data.entries === "object") {
119
- return Object.keys(data.entries)
120
- .length;
121
- }
122
- return undefined;
123
- }
@@ -1,31 +0,0 @@
1
- /**
2
- * GcsReportArtifactUploader — uploads report artifacts to known GCS paths.
3
- *
4
- * Separate from GcsArtifactCollector (which handles forensic capture archives).
5
- * This uploader puts structured JSON files at predictable paths so the
6
- * API Gateway can sign URLs and Studio can fetch them on demand.
7
- *
8
- * GCS path convention: reports/{reportId}/{fileName}
9
- * Example: reports/01926abc.../test-outputs.json
10
- *
11
- * Design principles:
12
- * - P5: Non-blocking — GCS upload failure returns null, never throws
13
- * - Lazy client — Storage created on first upload, not at construction
14
- * - Same credentials path as GcsArtifactCollector (ADC or key file)
15
- *
16
- * @see docs/design-docs/external-artifact-store.md
17
- * @see docs/decisions/D0030-external-artifact-store.md
18
- */
19
- import type { ArtifactRef, ArtifactUploader } from "../_vendor/ailf-core/index.d.ts";
20
- export interface GcsUploaderOptions {
21
- /** GCS bucket name (e.g., "ailf-artifacts") */
22
- bucket: string;
23
- }
24
- export declare class GcsReportArtifactUploader implements ArtifactUploader {
25
- private client;
26
- private readonly options;
27
- constructor(options: GcsUploaderOptions);
28
- upload(reportId: string, fileName: string, data: unknown): Promise<ArtifactRef | null>;
29
- /** Lazily create the GCS Storage client (ADC). */
30
- private getClient;
31
- }
@@ -1,66 +0,0 @@
1
- /**
2
- * GcsReportArtifactUploader — uploads report artifacts to known GCS paths.
3
- *
4
- * Separate from GcsArtifactCollector (which handles forensic capture archives).
5
- * This uploader puts structured JSON files at predictable paths so the
6
- * API Gateway can sign URLs and Studio can fetch them on demand.
7
- *
8
- * GCS path convention: reports/{reportId}/{fileName}
9
- * Example: reports/01926abc.../test-outputs.json
10
- *
11
- * Design principles:
12
- * - P5: Non-blocking — GCS upload failure returns null, never throws
13
- * - Lazy client — Storage created on first upload, not at construction
14
- * - Same credentials path as GcsArtifactCollector (ADC or key file)
15
- *
16
- * @see docs/design-docs/external-artifact-store.md
17
- * @see docs/decisions/D0030-external-artifact-store.md
18
- */
19
- import { Storage } from "@google-cloud/storage";
20
- export class GcsReportArtifactUploader {
21
- client = null;
22
- options;
23
- constructor(options) {
24
- this.options = options;
25
- }
26
- async upload(reportId, fileName, data) {
27
- const objectPath = `reports/${reportId}/${fileName}`;
28
- const json = JSON.stringify(data);
29
- const bytes = Buffer.byteLength(json, "utf-8");
30
- try {
31
- const storage = this.getClient();
32
- const file = storage.bucket(this.options.bucket).file(objectPath);
33
- await file.save(json, {
34
- contentType: "application/json",
35
- metadata: {
36
- reportId,
37
- },
38
- });
39
- return {
40
- store: "gcs",
41
- bucket: this.options.bucket,
42
- path: objectPath,
43
- bytes,
44
- entryCount: typeof data === "object" &&
45
- data !== null &&
46
- "entries" in data &&
47
- typeof data.entries === "object"
48
- ? Object.keys(data.entries)
49
- .length
50
- : undefined,
51
- };
52
- }
53
- catch (err) {
54
- const message = err instanceof Error ? err.message : String(err);
55
- console.warn(` ⚠️ Artifact upload failed (non-blocking): ${objectPath} — ${message}`);
56
- return null;
57
- }
58
- }
59
- /** Lazily create the GCS Storage client (ADC). */
60
- getClient() {
61
- if (this.client)
62
- return this.client;
63
- this.client = new Storage();
64
- return this.client;
65
- }
66
- }