@mcoda/mswarm 0.1.90 → 0.1.94

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 (113) hide show
  1. package/dist/codali-executor.d.ts +107 -6
  2. package/dist/codali-executor.d.ts.map +1 -1
  3. package/dist/codali-executor.js +500 -26
  4. package/dist/codali-executor.js.map +1 -1
  5. package/dist/runtime.d.ts +4 -2
  6. package/dist/runtime.d.ts.map +1 -1
  7. package/dist/runtime.js +18 -5
  8. package/dist/runtime.js.map +1 -1
  9. package/dist/vendor/codali/cli/DatasetCommand.d.ts +38 -0
  10. package/dist/vendor/codali/cli/DatasetCommand.d.ts.map +1 -0
  11. package/dist/vendor/codali/cli/DatasetCommand.js +959 -0
  12. package/dist/vendor/codali/cli/EvalCommand.d.ts +3 -0
  13. package/dist/vendor/codali/cli/EvalCommand.d.ts.map +1 -1
  14. package/dist/vendor/codali/cli/EvalCommand.js +55 -1
  15. package/dist/vendor/codali/cli/ImprovementCommand.d.ts +97 -0
  16. package/dist/vendor/codali/cli/ImprovementCommand.d.ts.map +1 -0
  17. package/dist/vendor/codali/cli/ImprovementCommand.js +1879 -0
  18. package/dist/vendor/codali/cli.d.ts.map +1 -1
  19. package/dist/vendor/codali/cli.js +15 -0
  20. package/dist/vendor/codali/dataset-cli.d.ts +3 -0
  21. package/dist/vendor/codali/dataset-cli.d.ts.map +1 -0
  22. package/dist/vendor/codali/dataset-cli.js +30 -0
  23. package/dist/vendor/codali/eval/CodaliGatewayLiveHarness.d.ts +90 -1
  24. package/dist/vendor/codali/eval/CodaliGatewayLiveHarness.d.ts.map +1 -1
  25. package/dist/vendor/codali/eval/CodaliGatewayLiveHarness.js +443 -9
  26. package/dist/vendor/codali/eval/GatewayDatasetEval.d.ts +70 -0
  27. package/dist/vendor/codali/eval/GatewayDatasetEval.d.ts.map +1 -0
  28. package/dist/vendor/codali/eval/GatewayDatasetEval.js +477 -0
  29. package/dist/vendor/codali/eval/GatewayEvalSuite.d.ts +52 -0
  30. package/dist/vendor/codali/eval/GatewayEvalSuite.d.ts.map +1 -1
  31. package/dist/vendor/codali/eval/GatewayEvalSuite.js +135 -1
  32. package/dist/vendor/codali/gateway/CodaliGateway.d.ts +4 -0
  33. package/dist/vendor/codali/gateway/CodaliGateway.d.ts.map +1 -1
  34. package/dist/vendor/codali/gateway/CodaliGateway.js +37 -1
  35. package/dist/vendor/codali/gateway/CodaliGatewaySchemas.d.ts.map +1 -1
  36. package/dist/vendor/codali/gateway/CodaliGatewaySchemas.js +0 -4
  37. package/dist/vendor/codali/gateway/CodaliGatewayStore.d.ts.map +1 -1
  38. package/dist/vendor/codali/gateway/CodaliGatewayStore.js +1 -0
  39. package/dist/vendor/codali/gateway/GatewayPlanner.d.ts.map +1 -1
  40. package/dist/vendor/codali/gateway/GatewayPlanner.js +355 -41
  41. package/dist/vendor/codali/gateway/GatewayStateMachine.d.ts +1 -0
  42. package/dist/vendor/codali/gateway/GatewayStateMachine.d.ts.map +1 -1
  43. package/dist/vendor/codali/gateway/GatewayStateMachine.js +221 -5
  44. package/dist/vendor/codali/improvement/CandidateReleaseBuilder.d.ts +201 -0
  45. package/dist/vendor/codali/improvement/CandidateReleaseBuilder.d.ts.map +1 -0
  46. package/dist/vendor/codali/improvement/CandidateReleaseBuilder.js +1175 -0
  47. package/dist/vendor/codali/improvement/DatasetEligibilityGate.d.ts +75 -0
  48. package/dist/vendor/codali/improvement/DatasetEligibilityGate.d.ts.map +1 -0
  49. package/dist/vendor/codali/improvement/DatasetEligibilityGate.js +497 -0
  50. package/dist/vendor/codali/improvement/DatasetExportManifestReader.d.ts +88 -0
  51. package/dist/vendor/codali/improvement/DatasetExportManifestReader.d.ts.map +1 -0
  52. package/dist/vendor/codali/improvement/DatasetExportManifestReader.js +333 -0
  53. package/dist/vendor/codali/improvement/DocdexRetrievalCandidateBuilder.d.ts +192 -0
  54. package/dist/vendor/codali/improvement/DocdexRetrievalCandidateBuilder.d.ts.map +1 -0
  55. package/dist/vendor/codali/improvement/DocdexRetrievalCandidateBuilder.js +625 -0
  56. package/dist/vendor/codali/improvement/EvalReplayCandidateBuilder.d.ts +173 -0
  57. package/dist/vendor/codali/improvement/EvalReplayCandidateBuilder.d.ts.map +1 -0
  58. package/dist/vendor/codali/improvement/EvalReplayCandidateBuilder.js +363 -0
  59. package/dist/vendor/codali/improvement/FineTuneJobPlanner.d.ts +281 -0
  60. package/dist/vendor/codali/improvement/FineTuneJobPlanner.d.ts.map +1 -0
  61. package/dist/vendor/codali/improvement/FineTuneJobPlanner.js +823 -0
  62. package/dist/vendor/codali/improvement/ImprovementEvalRunner.d.ts +50 -0
  63. package/dist/vendor/codali/improvement/ImprovementEvalRunner.d.ts.map +1 -0
  64. package/dist/vendor/codali/improvement/ImprovementEvalRunner.js +648 -0
  65. package/dist/vendor/codali/improvement/ImprovementPolicy.d.ts +272 -0
  66. package/dist/vendor/codali/improvement/ImprovementPolicy.d.ts.map +1 -0
  67. package/dist/vendor/codali/improvement/ImprovementPolicy.js +1450 -0
  68. package/dist/vendor/codali/improvement/ModelRouterCandidateBuilder.d.ts +186 -0
  69. package/dist/vendor/codali/improvement/ModelRouterCandidateBuilder.d.ts.map +1 -0
  70. package/dist/vendor/codali/improvement/ModelRouterCandidateBuilder.js +880 -0
  71. package/dist/vendor/codali/improvement/OperatorInspector.d.ts +182 -0
  72. package/dist/vendor/codali/improvement/OperatorInspector.d.ts.map +1 -0
  73. package/dist/vendor/codali/improvement/OperatorInspector.js +604 -0
  74. package/dist/vendor/codali/improvement/ProductionGovernance.d.ts +91 -0
  75. package/dist/vendor/codali/improvement/ProductionGovernance.d.ts.map +1 -0
  76. package/dist/vendor/codali/improvement/ProductionGovernance.js +329 -0
  77. package/dist/vendor/codali/improvement/PromptSchemaToolMetadataCandidateBuilder.d.ts +152 -0
  78. package/dist/vendor/codali/improvement/PromptSchemaToolMetadataCandidateBuilder.d.ts.map +1 -0
  79. package/dist/vendor/codali/improvement/PromptSchemaToolMetadataCandidateBuilder.js +480 -0
  80. package/dist/vendor/codali/improvement/PublishOrchestrator.d.ts +113 -0
  81. package/dist/vendor/codali/improvement/PublishOrchestrator.d.ts.map +1 -0
  82. package/dist/vendor/codali/improvement/PublishOrchestrator.js +590 -0
  83. package/dist/vendor/codali/improvement/ReleaseOutcomeReporter.d.ts +133 -0
  84. package/dist/vendor/codali/improvement/ReleaseOutcomeReporter.d.ts.map +1 -0
  85. package/dist/vendor/codali/improvement/ReleaseOutcomeReporter.js +501 -0
  86. package/dist/vendor/codali/improvement/StorageServiceImprovementClient.d.ts +71 -0
  87. package/dist/vendor/codali/improvement/StorageServiceImprovementClient.d.ts.map +1 -0
  88. package/dist/vendor/codali/improvement/StorageServiceImprovementClient.js +245 -0
  89. package/dist/vendor/codali/index.d.ts +43 -0
  90. package/dist/vendor/codali/index.d.ts.map +1 -1
  91. package/dist/vendor/codali/index.js +21 -0
  92. package/dist/vendor/codali/runtime/CodaliRuntime.d.ts +0 -2
  93. package/dist/vendor/codali/runtime/CodaliRuntime.d.ts.map +1 -1
  94. package/dist/vendor/codali/runtime/CodaliRuntime.js +0 -5
  95. package/dist/vendor/codali/storage/CodaliDatasetPrivacyEngine.d.ts +138 -0
  96. package/dist/vendor/codali/storage/CodaliDatasetPrivacyEngine.d.ts.map +1 -0
  97. package/dist/vendor/codali/storage/CodaliDatasetPrivacyEngine.js +417 -0
  98. package/dist/vendor/codali/storage/CodaliFeedbackReviewIngestion.d.ts +50 -0
  99. package/dist/vendor/codali/storage/CodaliFeedbackReviewIngestion.d.ts.map +1 -0
  100. package/dist/vendor/codali/storage/CodaliFeedbackReviewIngestion.js +141 -0
  101. package/dist/vendor/codali/storage/CodaliStorageContracts.d.ts +337 -0
  102. package/dist/vendor/codali/storage/CodaliStorageContracts.d.ts.map +1 -0
  103. package/dist/vendor/codali/storage/CodaliStorageContracts.js +1555 -0
  104. package/dist/vendor/codali/storage/DatasetExportJob.d.ts +51 -0
  105. package/dist/vendor/codali/storage/DatasetExportJob.d.ts.map +1 -0
  106. package/dist/vendor/codali/storage/DatasetExportJob.js +358 -0
  107. package/dist/vendor/codali/storage/DatasetReviewQueue.d.ts +98 -0
  108. package/dist/vendor/codali/storage/DatasetReviewQueue.d.ts.map +1 -0
  109. package/dist/vendor/codali/storage/DatasetReviewQueue.js +426 -0
  110. package/dist/vendor/codali/storage/GatewayDatasetStore.d.ts +233 -0
  111. package/dist/vendor/codali/storage/GatewayDatasetStore.d.ts.map +1 -0
  112. package/dist/vendor/codali/storage/GatewayDatasetStore.js +2070 -0
  113. package/package.json +3 -3
@@ -0,0 +1,959 @@
1
+ import { mkdtemp } from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { CODALI_STORAGE_EXPORT_KINDS, } from "../storage/CodaliStorageContracts.js";
5
+ import { createGatewayDatasetLocalOnlyObjectPrivacyFlags, createGatewayDatasetLocalOnlyPrivacy, createLocalJsonlGatewayDatasetObjectStore, } from "../storage/GatewayDatasetStore.js";
6
+ import { CODALI_DATASET_SFT_EXPORT_KINDS, runCodaliDatasetExportJob, } from "../storage/DatasetExportJob.js";
7
+ import { applyDatasetLabel, applyDatasetPromotionTarget, datasetRecordBusinessValue, datasetRecordConfidence, datasetRecordFailureCluster, datasetRecordIntegration, readLocalDatasetCollection, sampleDatasetRecordEntries, summarizeDatasetCollection, writeLocalDatasetCollection, } from "../storage/DatasetReviewQueue.js";
8
+ import { formatCodaliDatasetRunOperatorInspectionText, inspectCodaliDatasetRunForOperators, } from "../improvement/OperatorInspector.js";
9
+ import { evaluateCodaliProductionGovernanceAction, resolveCodaliProductionGovernance, } from "../improvement/ProductionGovernance.js";
10
+ const DATASET_EXIT_CODES = {
11
+ usage_error: 2,
12
+ export_blocked: 3,
13
+ };
14
+ const DATASET_COMMANDS = new Set([
15
+ "inspect",
16
+ "review-queue",
17
+ "label",
18
+ "promote-target",
19
+ "export",
20
+ ]);
21
+ const REVIEW_PROMOTION_TARGETS = new Set([
22
+ "gold",
23
+ "silver",
24
+ "reject",
25
+ ]);
26
+ const REVIEW_DECISIONS = new Set([
27
+ "approved",
28
+ "rejected",
29
+ "needs_changes",
30
+ "escalated",
31
+ ]);
32
+ export class DatasetCommandError extends Error {
33
+ constructor(message, exitCode) {
34
+ super(message);
35
+ this.name = "DatasetCommandError";
36
+ this.exitCode = exitCode;
37
+ }
38
+ }
39
+ const HELP_TEXT = "Usage: codali dataset <inspect|review-queue|label|promote-target|export> [options]\n"
40
+ + "\n"
41
+ + "Commands:\n"
42
+ + " inspect Inspect a local dataset collection or run for operator dashboards.\n"
43
+ + " review-queue Print a deterministic tenant-scoped review queue.\n"
44
+ + " label Add review labels to a local dataset record.\n"
45
+ + " promote-target Mark a local dataset record as gold, silver, or reject.\n"
46
+ + " export Run an explicit local-only dataset export job.\n"
47
+ + "\n"
48
+ + "Options:\n"
49
+ + " JSONL Select JSONL output format for smoke exports.\n"
50
+ + " smoke Generate a deterministic local smoke dataset for export.\n"
51
+ + " --dry-run Count eligible rows and exclusion reasons without artifacts.\n"
52
+ + " --kind <kind> Export kind (default: prompt-regression).\n"
53
+ + " --directory <path> Local dataset directory (default: .codali/dataset).\n"
54
+ + " --seed <value> Deterministic sampler seed.\n"
55
+ + " --limit <count> Maximum sampled rows.\n"
56
+ + " --tenant <id> Filter by tenant scope.\n"
57
+ + " --all-tenants Allow review-queue to sample across tenants explicitly.\n"
58
+ + " --product <id> Filter by product scope.\n"
59
+ + " --run, --run-id <id> Filter by run scope; inspect emits run dashboard JSON.\n"
60
+ + " --failure-cluster <v> Filter by failure cluster/status/error.\n"
61
+ + " --integration <v> Filter by integration/tool/source/provider.\n"
62
+ + " --confidence <v> Filter by confidence bucket or minimum score.\n"
63
+ + " --business-value <v> Filter by business value bucket or minimum score.\n"
64
+ + " --record-id <id> Record id for label/promote-target.\n"
65
+ + " --label <label> Label to add; repeat or comma-separate.\n"
66
+ + " --target <target> Promotion target: gold|silver|reject.\n"
67
+ + " --output <text|json> Output mode (default: text).\n"
68
+ + " --help Show help.\n";
69
+ const expectValue = (argv, index, flag) => {
70
+ const value = argv[index + 1];
71
+ if (!value || value.startsWith("--")) {
72
+ throw new DatasetCommandError(`Missing value for ${flag}.`, DATASET_EXIT_CODES.usage_error);
73
+ }
74
+ return value;
75
+ };
76
+ const parseExportKind = (value) => {
77
+ if (CODALI_STORAGE_EXPORT_KINDS.includes(value)) {
78
+ return value;
79
+ }
80
+ throw new DatasetCommandError(`Invalid --kind value. Expected one of: ${CODALI_STORAGE_EXPORT_KINDS.join(", ")}.`, DATASET_EXIT_CODES.usage_error);
81
+ };
82
+ const parsePromotionTarget = (value) => {
83
+ if (REVIEW_PROMOTION_TARGETS.has(value)) {
84
+ return value;
85
+ }
86
+ throw new DatasetCommandError("Invalid promotion target. Expected gold|silver|reject.", DATASET_EXIT_CODES.usage_error);
87
+ };
88
+ const parseReviewDecision = (value) => {
89
+ if (REVIEW_DECISIONS.has(value)) {
90
+ return value;
91
+ }
92
+ throw new DatasetCommandError("Invalid review decision. Expected approved|rejected|needs_changes|escalated.", DATASET_EXIT_CODES.usage_error);
93
+ };
94
+ const parseLimit = (value, flag) => {
95
+ const parsed = Number(value);
96
+ if (!Number.isInteger(parsed) || parsed < 1) {
97
+ throw new DatasetCommandError(`Invalid ${flag} value. Expected a positive integer.`, DATASET_EXIT_CODES.usage_error);
98
+ }
99
+ return parsed;
100
+ };
101
+ const splitList = (value) => value.split(",").map((item) => item.trim()).filter(Boolean);
102
+ export const parseDatasetArgs = (argv) => {
103
+ const parsed = {
104
+ dryRun: false,
105
+ allTenants: false,
106
+ output: "text",
107
+ exportKind: "prompt-regression",
108
+ format: "jsonl",
109
+ smoke: false,
110
+ labels: [],
111
+ reasons: [],
112
+ productionGovernance: resolveCodaliProductionGovernance(),
113
+ positionals: [],
114
+ };
115
+ for (let index = 0; index < argv.length; index += 1) {
116
+ const arg = argv[index];
117
+ if (arg === "--help" || arg === "-h") {
118
+ parsed.help = true;
119
+ continue;
120
+ }
121
+ if (index === 0 && DATASET_COMMANDS.has(arg)) {
122
+ parsed.command = arg;
123
+ continue;
124
+ }
125
+ if (arg === "--dry-run") {
126
+ parsed.dryRun = true;
127
+ continue;
128
+ }
129
+ if (arg === "--all-tenants") {
130
+ parsed.allTenants = true;
131
+ continue;
132
+ }
133
+ if (arg === "--kind") {
134
+ parsed.exportKind = parseExportKind(expectValue(argv, index, "--kind"));
135
+ index += 1;
136
+ continue;
137
+ }
138
+ if (arg === "--directory") {
139
+ parsed.directory = expectValue(argv, index, "--directory");
140
+ index += 1;
141
+ continue;
142
+ }
143
+ if (arg === "--output") {
144
+ const value = expectValue(argv, index, "--output").toLowerCase();
145
+ if (value !== "text" && value !== "json") {
146
+ throw new DatasetCommandError("Invalid --output value. Expected text|json.", DATASET_EXIT_CODES.usage_error);
147
+ }
148
+ parsed.output = value;
149
+ index += 1;
150
+ continue;
151
+ }
152
+ if (arg === "--seed") {
153
+ parsed.seed = expectValue(argv, index, "--seed");
154
+ index += 1;
155
+ continue;
156
+ }
157
+ if (arg === "--limit") {
158
+ parsed.limit = parseLimit(expectValue(argv, index, "--limit"), "--limit");
159
+ index += 1;
160
+ continue;
161
+ }
162
+ if (arg === "--tenant" || arg === "--tenant-id") {
163
+ parsed.tenantId = expectValue(argv, index, arg);
164
+ index += 1;
165
+ continue;
166
+ }
167
+ if (arg === "--product" || arg === "--product-id") {
168
+ parsed.productId = expectValue(argv, index, arg);
169
+ index += 1;
170
+ continue;
171
+ }
172
+ if (arg === "--deployment" || arg === "--deployment-id") {
173
+ parsed.deploymentId = expectValue(argv, index, arg);
174
+ index += 1;
175
+ continue;
176
+ }
177
+ if (arg === "--run" || arg === "--run-id") {
178
+ parsed.runId = expectValue(argv, index, arg);
179
+ index += 1;
180
+ continue;
181
+ }
182
+ if (arg === "--failure-cluster") {
183
+ parsed.failureCluster = expectValue(argv, index, "--failure-cluster");
184
+ index += 1;
185
+ continue;
186
+ }
187
+ if (arg === "--integration") {
188
+ parsed.integration = expectValue(argv, index, "--integration");
189
+ index += 1;
190
+ continue;
191
+ }
192
+ if (arg === "--confidence") {
193
+ parsed.confidence = expectValue(argv, index, "--confidence");
194
+ index += 1;
195
+ continue;
196
+ }
197
+ if (arg === "--business-value") {
198
+ parsed.businessValue = expectValue(argv, index, "--business-value");
199
+ index += 1;
200
+ continue;
201
+ }
202
+ if (arg === "--record-id") {
203
+ parsed.recordId = expectValue(argv, index, "--record-id");
204
+ index += 1;
205
+ continue;
206
+ }
207
+ if (arg === "--label" || arg === "--labels") {
208
+ parsed.labels.push(...splitList(expectValue(argv, index, arg)));
209
+ index += 1;
210
+ continue;
211
+ }
212
+ if (arg === "--reason") {
213
+ parsed.reasons.push(expectValue(argv, index, "--reason"));
214
+ index += 1;
215
+ continue;
216
+ }
217
+ if (arg === "--reviewer-id") {
218
+ parsed.reviewerId = expectValue(argv, index, "--reviewer-id");
219
+ index += 1;
220
+ continue;
221
+ }
222
+ if (arg === "--target" || arg === "--promotion-target") {
223
+ parsed.promotionTarget = parsePromotionTarget(expectValue(argv, index, arg));
224
+ index += 1;
225
+ continue;
226
+ }
227
+ if (arg === "--decision") {
228
+ parsed.decision = parseReviewDecision(expectValue(argv, index, "--decision"));
229
+ index += 1;
230
+ continue;
231
+ }
232
+ if (arg?.toLowerCase() === "jsonl") {
233
+ parsed.format = "jsonl";
234
+ continue;
235
+ }
236
+ if (arg === "smoke") {
237
+ parsed.smoke = true;
238
+ continue;
239
+ }
240
+ if (arg?.startsWith("--")) {
241
+ throw new DatasetCommandError(`Unknown dataset option: ${arg}`, DATASET_EXIT_CODES.usage_error);
242
+ }
243
+ parsed.positionals.push(arg);
244
+ }
245
+ if ((parsed.command === "label" || parsed.command === "promote-target") && !parsed.recordId) {
246
+ parsed.recordId = parsed.positionals[0];
247
+ }
248
+ if (parsed.command === "label" && parsed.positionals.length > 1) {
249
+ parsed.labels.push(...parsed.positionals.slice(1).flatMap(splitList));
250
+ }
251
+ if (parsed.command === "promote-target" && !parsed.promotionTarget && parsed.positionals[1]) {
252
+ parsed.promotionTarget = parsePromotionTarget(parsed.positionals[1]);
253
+ }
254
+ if (parsed.allTenants && parsed.tenantId) {
255
+ throw new DatasetCommandError("Use either --tenant <id> or --all-tenants, not both.", DATASET_EXIT_CODES.usage_error);
256
+ }
257
+ parsed.productionGovernance = resolveCodaliProductionGovernance();
258
+ return parsed;
259
+ };
260
+ const fixedSmokeNow = () => new Date("2026-07-07T12:00:00.000Z");
261
+ const defaultDatasetDirectory = () => path.join(process.cwd(), ".codali", "dataset");
262
+ const smokeScope = () => ({
263
+ tenantId: "local",
264
+ productId: "product-neutral",
265
+ deploymentId: "smoke",
266
+ runId: "dataset-export-smoke",
267
+ });
268
+ const isDocdexRetrievalSmokeExportKind = (exportKind) => exportKind === "query-expander-sft" || exportKind === "rag-reranker";
269
+ const isModelRouterSmokeExportKind = (exportKind) => exportKind === "model-router";
270
+ const putSmokeRef = (objectStore, input) => objectStore.putObject({
271
+ scope: smokeScope(),
272
+ ownerType: "dataset_record",
273
+ ownerId: input.ownerId,
274
+ kind: input.part === "retrieval_evidence" ? "evidence" : "dataset",
275
+ payload: input.payload,
276
+ retentionClass: "dataset",
277
+ privacyFlags: input.privacyFlags,
278
+ metadata: {
279
+ part: input.part,
280
+ smoke: true,
281
+ },
282
+ });
283
+ const docdexRetrievalSmokeMetadata = (exportKind) => ({
284
+ artifactType: exportKind === "rag-reranker" ? "rag_reranker" : "query_expander",
285
+ exampleType: "docdex_retrieval",
286
+ smoke: true,
287
+ reviewDecision: "accepted",
288
+ confidenceBucket: "high",
289
+ taskHash: "docdex-retrieval-smoke-task",
290
+ promptHash: "docdex-retrieval-smoke-prompt",
291
+ expectedTargetHash: "docdex-retrieval-smoke-target",
292
+ retrieval: {
293
+ query: "tenant-scoped retrieval freshness query",
294
+ expandedQueries: [
295
+ "fresh retrieval source policy",
296
+ "duplicate retrieval evidence handling",
297
+ ],
298
+ selectedSources: [{
299
+ sourceId: "tenant-scoped-repo/docs/retrieval-policy.md",
300
+ sourceType: "repo_doc",
301
+ freshness: "fresh",
302
+ }],
303
+ sourceTypes: ["repo_doc", "fresh"],
304
+ },
305
+ scorecard: {
306
+ recallBefore: 0.45,
307
+ recallAfter: 0.78,
308
+ precisionBefore: 0.57,
309
+ precisionAfter: 0.84,
310
+ freshnessBefore: 0.39,
311
+ freshnessAfter: 0.9,
312
+ },
313
+ });
314
+ const modelRouterSmokeComparisonRecords = () => [
315
+ {
316
+ id: "model-router-smoke-extractor-primary",
317
+ scenarioId: "generic_question",
318
+ role: "small_json",
319
+ resolverRole: "extractor",
320
+ comparisonRole: "primary",
321
+ primary: true,
322
+ agentSlug: "current-extractor-worker",
323
+ tier: "small",
324
+ model: "current-extractor-model",
325
+ adapter: "openai-compatible",
326
+ source: "cloud",
327
+ healthStatus: "healthy",
328
+ capabilities: ["json_schema", "tool_calling"],
329
+ resultStatus: "passed",
330
+ selectedByPolicy: true,
331
+ metrics: {
332
+ quality: {
333
+ status: "passed",
334
+ score: 0.74,
335
+ jsonValid: true,
336
+ toolCallCount: 1,
337
+ },
338
+ latencyMs: 2400,
339
+ costUsd: 0.00018,
340
+ tokenUse: {
341
+ inputTokens: 950,
342
+ outputTokens: 220,
343
+ totalTokens: 1170,
344
+ },
345
+ queue: {
346
+ waitMs: 120,
347
+ depth: 2,
348
+ status: "ready",
349
+ },
350
+ throughput: {
351
+ tokensPerSecond: 18,
352
+ requestsPerMinute: 12,
353
+ },
354
+ failure: {
355
+ status: "none",
356
+ reasons: [],
357
+ },
358
+ },
359
+ warnings: [],
360
+ errors: [],
361
+ metadata: {
362
+ scorecard: {
363
+ toolAccuracy: 0.72,
364
+ schemaSuccess: 0.9,
365
+ confidence: 0.74,
366
+ fallbackRate: 0.14,
367
+ },
368
+ },
369
+ },
370
+ {
371
+ id: "model-router-smoke-extractor-shadow",
372
+ scenarioId: "generic_question",
373
+ role: "small_json",
374
+ resolverRole: "extractor",
375
+ comparisonRole: "shadow",
376
+ primary: false,
377
+ candidateRank: 1,
378
+ agentSlug: "local-extractor-worker",
379
+ tier: "small",
380
+ model: "local-extractor-model",
381
+ adapter: "ollama-remote",
382
+ source: "local",
383
+ healthStatus: "healthy",
384
+ capabilities: ["json_schema", "structured_output", "tool_calling"],
385
+ resultStatus: "passed",
386
+ selectedByPolicy: false,
387
+ metrics: {
388
+ quality: {
389
+ status: "passed",
390
+ score: 0.93,
391
+ jsonValid: true,
392
+ toolCallCount: 1,
393
+ },
394
+ latencyMs: 900,
395
+ costUsd: 0.00002,
396
+ tokenUse: {
397
+ inputTokens: 720,
398
+ outputTokens: 160,
399
+ totalTokens: 880,
400
+ },
401
+ queue: {
402
+ waitMs: 20,
403
+ depth: 0,
404
+ status: "ready",
405
+ },
406
+ throughput: {
407
+ tokensPerSecond: 44,
408
+ requestsPerMinute: 22,
409
+ },
410
+ failure: {
411
+ status: "none",
412
+ reasons: [],
413
+ },
414
+ localInference: {
415
+ backend: "local",
416
+ quantized: true,
417
+ },
418
+ },
419
+ warnings: [],
420
+ errors: [],
421
+ metadata: {
422
+ scorecard: {
423
+ toolAccuracy: 0.97,
424
+ schemaSuccess: 0.98,
425
+ confidence: 0.92,
426
+ fallbackRate: 0,
427
+ },
428
+ },
429
+ },
430
+ {
431
+ id: "model-router-smoke-final-primary",
432
+ scenarioId: "final_answer_large_model",
433
+ role: "large_final",
434
+ resolverRole: "final_synthesizer",
435
+ comparisonRole: "primary",
436
+ primary: true,
437
+ agentSlug: "current-final-synthesizer",
438
+ tier: "large",
439
+ model: "current-final-model",
440
+ adapter: "openai-compatible",
441
+ source: "cloud",
442
+ healthStatus: "healthy",
443
+ capabilities: ["long_context"],
444
+ resultStatus: "passed",
445
+ selectedByPolicy: true,
446
+ metrics: {
447
+ quality: {
448
+ status: "passed",
449
+ score: 0.94,
450
+ finalAnswerSucceeded: true,
451
+ },
452
+ latencyMs: 3200,
453
+ costUsd: 0.0009,
454
+ tokenUse: {
455
+ inputTokens: 3000,
456
+ outputTokens: 700,
457
+ totalTokens: 3700,
458
+ },
459
+ failure: {
460
+ status: "none",
461
+ reasons: [],
462
+ },
463
+ },
464
+ warnings: [],
465
+ errors: [],
466
+ metadata: {
467
+ scorecard: {
468
+ confidence: 0.94,
469
+ fallbackRate: 0,
470
+ },
471
+ },
472
+ },
473
+ {
474
+ id: "model-router-smoke-final-shadow",
475
+ scenarioId: "final_answer_large_model",
476
+ role: "large_final",
477
+ resolverRole: "final_synthesizer",
478
+ comparisonRole: "shadow",
479
+ primary: false,
480
+ candidateRank: 1,
481
+ agentSlug: "shadow-final-synthesizer",
482
+ tier: "large",
483
+ model: "shadow-final-model",
484
+ adapter: "openai-compatible",
485
+ source: "cloud",
486
+ healthStatus: "healthy",
487
+ capabilities: ["long_context"],
488
+ resultStatus: "passed",
489
+ selectedByPolicy: false,
490
+ metrics: {
491
+ quality: {
492
+ status: "passed",
493
+ score: 0.96,
494
+ finalAnswerSucceeded: true,
495
+ },
496
+ latencyMs: 2800,
497
+ costUsd: 0.0008,
498
+ tokenUse: {
499
+ inputTokens: 3000,
500
+ outputTokens: 650,
501
+ totalTokens: 3650,
502
+ },
503
+ failure: {
504
+ status: "none",
505
+ reasons: [],
506
+ },
507
+ },
508
+ warnings: [],
509
+ errors: [],
510
+ metadata: {
511
+ scorecard: {
512
+ confidence: 0.95,
513
+ fallbackRate: 0,
514
+ },
515
+ },
516
+ },
517
+ ];
518
+ const modelRouterSmokeMetadata = () => ({
519
+ artifactType: "model_router",
520
+ exampleType: "model_router_shadow_evidence",
521
+ smoke: true,
522
+ reviewDecision: "accepted",
523
+ confidenceBucket: "high",
524
+ taskHash: "model-router-smoke-task",
525
+ promptHash: "model-router-smoke-prompt",
526
+ expectedTargetHash: "model-router-smoke-target",
527
+ modelComparisonRecords: modelRouterSmokeComparisonRecords(),
528
+ });
529
+ const fineTuneSmokeRoleForExportKind = (exportKind) => exportKind.endsWith("-sft")
530
+ ? exportKind.slice(0, -"-sft".length).replace(/-/g, "_")
531
+ : exportKind.replace(/-/g, "_");
532
+ const fineTuneSmokeMetadata = (exportKind) => {
533
+ const role = fineTuneSmokeRoleForExportKind(exportKind);
534
+ return {
535
+ artifactType: `${role}_sft`,
536
+ exampleType: "model_stage",
537
+ smoke: true,
538
+ role,
539
+ reviewDecision: "accepted",
540
+ confidenceBucket: "high",
541
+ taskHash: `${role}-smoke-task`,
542
+ promptHash: `${role}-smoke-prompt`,
543
+ expectedTargetHash: `${role}-smoke-target`,
544
+ scorecard: {
545
+ accuracyBefore: 0.62,
546
+ accuracyAfter: 0.81,
547
+ passRateBefore: 0.58,
548
+ passRateAfter: 0.86,
549
+ latencyBefore: 1.2,
550
+ latencyAfter: 1.1,
551
+ },
552
+ };
553
+ };
554
+ const buildSmokeRecord = async (input) => {
555
+ const trainingAllowed = CODALI_DATASET_SFT_EXPORT_KINDS.includes(input.exportKind);
556
+ const docdexRetrievalSmoke = isDocdexRetrievalSmokeExportKind(input.exportKind);
557
+ const modelRouterSmoke = isModelRouterSmokeExportKind(input.exportKind);
558
+ const privacy = createGatewayDatasetLocalOnlyPrivacy({
559
+ exportAllowed: true,
560
+ trainingAllowed,
561
+ containsPersonalData: false,
562
+ policyTags: docdexRetrievalSmoke || modelRouterSmoke
563
+ ? ["local_only", "smoke", "tenant_scoped"]
564
+ : ["local_only", "smoke"],
565
+ metadata: {
566
+ source: "dataset_export_smoke",
567
+ },
568
+ });
569
+ const privacyFlags = createGatewayDatasetLocalOnlyObjectPrivacyFlags({
570
+ containsTenantPrivateData: docdexRetrievalSmoke || modelRouterSmoke,
571
+ containsCustomerData: false,
572
+ exportAllowed: true,
573
+ trainingAllowed,
574
+ });
575
+ const evidencePrivacyFlags = createGatewayDatasetLocalOnlyObjectPrivacyFlags({
576
+ containsTenantPrivateData: docdexRetrievalSmoke || modelRouterSmoke,
577
+ containsCustomerData: false,
578
+ containsSourceCode: docdexRetrievalSmoke,
579
+ exportAllowed: true,
580
+ trainingAllowed,
581
+ });
582
+ const recordId = input.recordId ?? "dataset-export-smoke-record";
583
+ const inputRef = await putSmokeRef(input.objectStore, {
584
+ ownerId: recordId,
585
+ part: "smoke_input",
586
+ privacyFlags,
587
+ payload: docdexRetrievalSmoke
588
+ ? {
589
+ query: "tenant-scoped retrieval freshness query",
590
+ }
591
+ : modelRouterSmoke
592
+ ? {
593
+ task: "Choose a product-neutral constrained worker route.",
594
+ }
595
+ : {
596
+ prompt: "Summarize the local-only dataset export policy.",
597
+ context: ["local storage", "explicit export"],
598
+ },
599
+ });
600
+ const outputRef = await putSmokeRef(input.objectStore, {
601
+ ownerId: recordId,
602
+ part: "smoke_output",
603
+ privacyFlags,
604
+ payload: docdexRetrievalSmoke
605
+ ? {
606
+ expandedQueries: [
607
+ "fresh retrieval source policy",
608
+ "duplicate retrieval evidence handling",
609
+ ],
610
+ }
611
+ : modelRouterSmoke
612
+ ? {
613
+ decision: "Shadow route is eligible for dry-run proposal only.",
614
+ }
615
+ : {
616
+ answer: "Exports are explicit, local-only, and manifest-backed.",
617
+ },
618
+ });
619
+ const evidenceRefs = docdexRetrievalSmoke
620
+ ? [await putSmokeRef(input.objectStore, {
621
+ ownerId: recordId,
622
+ part: "retrieval_evidence",
623
+ privacyFlags: evidencePrivacyFlags,
624
+ payload: {
625
+ selectedSource: "tenant-scoped-repo/docs/retrieval-policy.md",
626
+ freshness: "fresh",
627
+ },
628
+ })]
629
+ : undefined;
630
+ return {
631
+ schemaVersion: "codali.storage.v1",
632
+ recordType: "dataset_record",
633
+ recordId,
634
+ datasetKind: trainingAllowed ? "model_call" : "gateway_answer",
635
+ createdAt: fixedSmokeNow().toISOString(),
636
+ sourceGatewayRecordId: "gateway-export-smoke",
637
+ inputRef,
638
+ outputRef,
639
+ ...(evidenceRefs ? { evidenceRefs } : {}),
640
+ quality: {
641
+ score: input.qualityScore ?? (docdexRetrievalSmoke ? 0.97 : 0.91),
642
+ labels: docdexRetrievalSmoke
643
+ ? ["smoke", input.exportKind, "human_reviewed", "accepted_correction", "high_confidence"]
644
+ : ["smoke", input.exportKind],
645
+ reviewed: true,
646
+ },
647
+ privacy,
648
+ metadata: {
649
+ ...(docdexRetrievalSmoke
650
+ ? docdexRetrievalSmokeMetadata(input.exportKind)
651
+ : modelRouterSmoke
652
+ ? modelRouterSmokeMetadata()
653
+ : trainingAllowed
654
+ ? fineTuneSmokeMetadata(input.exportKind)
655
+ : {
656
+ artifactType: input.exportKind === "eval-replay" ? "eval" : input.exportKind,
657
+ exampleType: trainingAllowed ? "model_stage" : "final_answer",
658
+ smoke: true,
659
+ }),
660
+ },
661
+ };
662
+ };
663
+ const buildSmokeRecords = async (input) => {
664
+ if (!isDocdexRetrievalSmokeExportKind(input.exportKind)) {
665
+ return [await buildSmokeRecord(input)];
666
+ }
667
+ return [
668
+ await buildSmokeRecord({
669
+ ...input,
670
+ recordId: "dataset-export-docdex-retrieval-smoke-record",
671
+ qualityScore: 0.97,
672
+ }),
673
+ await buildSmokeRecord({
674
+ ...input,
675
+ recordId: "dataset-export-docdex-retrieval-smoke-duplicate",
676
+ qualityScore: 0.91,
677
+ }),
678
+ ];
679
+ };
680
+ const formatCounts = (counts) => {
681
+ const entries = Object.entries(counts).sort(([left], [right]) => left.localeCompare(right));
682
+ return entries.length ? entries.map(([key, count]) => `${key}=${count}`).join(",") : "none";
683
+ };
684
+ const formatExportText = (input) => {
685
+ const lines = [
686
+ `dataset export${input.smoke ? " smoke" : ""}: ${input.result.status}`,
687
+ `kind: ${input.result.exportKind}`,
688
+ `format: ${input.result.exportFormat}`,
689
+ ];
690
+ if (input.collectionTotal !== undefined || input.selectedCount !== undefined) {
691
+ lines.push(`collection_records: total=${input.collectionTotal ?? input.result.dryRun.totalCount} selected=${input.selectedCount ?? input.result.dryRun.totalCount}`);
692
+ }
693
+ lines.push(`records: total=${input.result.dryRun.totalCount} eligible=${input.result.dryRun.eligibleCount} excluded=${input.result.dryRun.excludedCount}`, `directory: ${input.directory}`, `exclusion_reasons: ${formatCounts(input.result.dryRun.exclusionReasonCounts)}`);
694
+ if (input.result.jsonlRef?.uri)
695
+ lines.push(`jsonl: ${input.result.jsonlRef.uri}`);
696
+ if (input.result.replayFixtureRef?.uri)
697
+ lines.push(`replay_fixture: ${input.result.replayFixtureRef.uri}`);
698
+ if (input.result.manifestRef?.uri)
699
+ lines.push(`manifest: ${input.result.manifestRef.uri}`);
700
+ return lines.join("\n");
701
+ };
702
+ const formatInspectText = (summary) => [
703
+ "dataset inspect",
704
+ `directory: ${summary.directory}`,
705
+ `records_file: ${summary.recordsPath}`,
706
+ `batches: ${summary.batchCount}`,
707
+ `records: rows=${summary.totalRecordRows} unique=${summary.uniqueRecordCount} invalid_lines=${summary.invalidLineCount} invalid_records=${summary.invalidRecordCount}`,
708
+ `review: reviewed=${summary.reviewedCount} unreviewed=${summary.unreviewedCount}`,
709
+ `privacy: export_allowed=${summary.exportAllowedCount} training_allowed=${summary.trainingAllowedCount}`,
710
+ `tenants: ${formatCounts(summary.byTenant)}`,
711
+ `products: ${formatCounts(summary.byProduct)}`,
712
+ `dataset_kinds: ${formatCounts(summary.byDatasetKind)}`,
713
+ `example_types: ${formatCounts(summary.byExampleType)}`,
714
+ `failure_clusters: ${formatCounts(summary.byFailureCluster)}`,
715
+ `integrations: ${formatCounts(summary.byIntegration)}`,
716
+ `confidence: ${formatCounts(summary.byConfidence)}`,
717
+ `business_value: ${formatCounts(summary.byBusinessValue)}`,
718
+ ].join("\n");
719
+ const formatRecordLine = (entry) => [
720
+ entry.record.recordId,
721
+ `tenant=${entry.scope.tenantId}`,
722
+ `product=${entry.scope.productId}`,
723
+ `kind=${entry.record.datasetKind}`,
724
+ `score=${entry.record.quality?.score ?? "unknown"}`,
725
+ `reviewed=${entry.record.quality?.reviewed === true ? "true" : "false"}`,
726
+ `failure_cluster=${datasetRecordFailureCluster(entry.record)}`,
727
+ `integration=${datasetRecordIntegration(entry.record)}`,
728
+ `confidence=${datasetRecordConfidence(entry.record)}`,
729
+ `business_value=${datasetRecordBusinessValue(entry.record)}`,
730
+ `labels=${entry.record.quality?.labels?.join(",") ?? "none"}`,
731
+ ].join("\t");
732
+ const formatReviewQueueText = (input) => [
733
+ "dataset review-queue",
734
+ `directory: ${input.directory}`,
735
+ `seed: ${input.parsed.seed ?? "review-queue"}`,
736
+ `selected: ${input.entries.length}`,
737
+ ...input.entries.map(formatRecordLine),
738
+ ].join("\n");
739
+ const sampleOptionsFromParsed = (parsed, overrides = {}) => ({
740
+ seed: parsed.seed,
741
+ limit: parsed.limit,
742
+ tenantId: parsed.tenantId,
743
+ productId: parsed.productId,
744
+ deploymentId: parsed.deploymentId,
745
+ runId: parsed.runId,
746
+ failureCluster: parsed.failureCluster,
747
+ integration: parsed.integration,
748
+ confidence: parsed.confidence,
749
+ businessValue: parsed.businessValue,
750
+ ...overrides,
751
+ });
752
+ const exportScope = (entries, parsed) => {
753
+ const first = entries[0]?.scope;
754
+ return {
755
+ tenantId: parsed.tenantId ?? first?.tenantId ?? "local",
756
+ productId: parsed.productId ?? first?.productId ?? "product-neutral",
757
+ deploymentId: parsed.deploymentId ?? first?.deploymentId ?? "local",
758
+ runId: parsed.runId ?? first?.runId ?? "dataset-export",
759
+ };
760
+ };
761
+ const assertSingleScopeForWriteExport = (entries) => {
762
+ const scopes = new Set(entries.map((entry) => `${entry.scope.tenantId}:${entry.scope.productId}:${entry.scope.deploymentId}`));
763
+ if (scopes.size > 1) {
764
+ throw new DatasetCommandError("Non-dry-run dataset export requires a single tenant/product/deployment scope.", DATASET_EXIT_CODES.export_blocked);
765
+ }
766
+ };
767
+ const assertProductionGovernanceAllowsDatasetExport = (parsed) => {
768
+ const decision = evaluateCodaliProductionGovernanceAction(parsed.productionGovernance, "dataset_export");
769
+ if (!decision.allowed) {
770
+ throw new DatasetCommandError(`Dataset export disabled by production governance: ${decision.reasons.join(", ")}.`, DATASET_EXIT_CODES.export_blocked);
771
+ }
772
+ };
773
+ const runSmokeExport = async (parsed) => {
774
+ assertProductionGovernanceAllowsDatasetExport(parsed);
775
+ const directory = parsed.directory ??
776
+ await mkdtemp(path.join(os.tmpdir(), "codali-dataset-export-"));
777
+ const objectStore = createLocalJsonlGatewayDatasetObjectStore({
778
+ directory: path.join(directory, "objects"),
779
+ now: fixedSmokeNow,
780
+ });
781
+ const records = await buildSmokeRecords({
782
+ objectStore,
783
+ exportKind: parsed.exportKind,
784
+ });
785
+ const result = await runCodaliDatasetExportJob({
786
+ exportKind: parsed.exportKind,
787
+ records,
788
+ objectStore,
789
+ scope: smokeScope(),
790
+ dryRun: parsed.dryRun,
791
+ generatedBy: "dataset export smoke",
792
+ now: fixedSmokeNow,
793
+ metadata: {
794
+ smoke: true,
795
+ },
796
+ });
797
+ if (!result.accepted && !parsed.dryRun) {
798
+ throw new DatasetCommandError(`Dataset export blocked: ${result.exclusionReasons.map((reason) => reason.code).join(", ")}`, DATASET_EXIT_CODES.export_blocked);
799
+ }
800
+ // eslint-disable-next-line no-console
801
+ console.log(parsed.output === "json"
802
+ ? JSON.stringify({
803
+ directory,
804
+ result,
805
+ productionGovernance: parsed.productionGovernance,
806
+ }, null, 2)
807
+ : formatExportText({ directory, result, smoke: true }));
808
+ };
809
+ const runDatasetExport = async (parsed) => {
810
+ assertProductionGovernanceAllowsDatasetExport(parsed);
811
+ if (parsed.smoke) {
812
+ await runSmokeExport(parsed);
813
+ return;
814
+ }
815
+ const directory = parsed.directory ?? defaultDatasetDirectory();
816
+ const collection = await readLocalDatasetCollection({ directory });
817
+ const summary = summarizeDatasetCollection(collection);
818
+ const entries = sampleDatasetRecordEntries(collection, sampleOptionsFromParsed(parsed));
819
+ if (!parsed.dryRun)
820
+ assertSingleScopeForWriteExport(entries);
821
+ const objectStore = createLocalJsonlGatewayDatasetObjectStore({
822
+ directory: path.join(directory, "exports", "objects"),
823
+ });
824
+ const result = await runCodaliDatasetExportJob({
825
+ exportKind: parsed.exportKind,
826
+ records: entries.map((entry) => entry.record),
827
+ objectStore,
828
+ scope: exportScope(entries, parsed),
829
+ dryRun: parsed.dryRun,
830
+ generatedBy: "dataset export",
831
+ metadata: {
832
+ explicitExport: true,
833
+ sampler: sampleOptionsFromParsed(parsed),
834
+ sourceDirectory: directory,
835
+ },
836
+ });
837
+ if (!result.accepted && !parsed.dryRun) {
838
+ throw new DatasetCommandError(`Dataset export blocked: ${result.exclusionReasons.map((reason) => reason.code).join(", ")}`, DATASET_EXIT_CODES.export_blocked);
839
+ }
840
+ // eslint-disable-next-line no-console
841
+ console.log(parsed.output === "json"
842
+ ? JSON.stringify({
843
+ directory,
844
+ summary,
845
+ selectedRecordIds: entries.map((entry) => entry.record.recordId),
846
+ result,
847
+ productionGovernance: parsed.productionGovernance,
848
+ }, null, 2)
849
+ : formatExportText({
850
+ directory,
851
+ result,
852
+ collectionTotal: summary.uniqueRecordCount,
853
+ selectedCount: entries.length,
854
+ }));
855
+ };
856
+ const runInspect = async (parsed) => {
857
+ const directory = parsed.directory ?? defaultDatasetDirectory();
858
+ if (parsed.runId || parsed.output === "json") {
859
+ const inspection = await inspectCodaliDatasetRunForOperators({
860
+ directory,
861
+ ...(parsed.runId ? { runId: parsed.runId } : {}),
862
+ });
863
+ // eslint-disable-next-line no-console
864
+ console.log(parsed.output === "json"
865
+ ? JSON.stringify(inspection, null, 2)
866
+ : formatCodaliDatasetRunOperatorInspectionText(inspection));
867
+ return;
868
+ }
869
+ const collection = await readLocalDatasetCollection({ directory });
870
+ const summary = summarizeDatasetCollection(collection);
871
+ // eslint-disable-next-line no-console
872
+ console.log(formatInspectText(summary));
873
+ };
874
+ const runReviewQueue = async (parsed) => {
875
+ if (!parsed.tenantId && !parsed.allTenants) {
876
+ throw new DatasetCommandError("dataset review-queue requires --tenant <id> or explicit --all-tenants.", DATASET_EXIT_CODES.usage_error);
877
+ }
878
+ const directory = parsed.directory ?? defaultDatasetDirectory();
879
+ const collection = await readLocalDatasetCollection({ directory });
880
+ const entries = sampleDatasetRecordEntries(collection, sampleOptionsFromParsed(parsed, {
881
+ seed: parsed.seed ?? "review-queue",
882
+ unreviewedOnly: true,
883
+ }));
884
+ // eslint-disable-next-line no-console
885
+ console.log(parsed.output === "json"
886
+ ? JSON.stringify({ directory, seed: parsed.seed ?? "review-queue", records: entries }, null, 2)
887
+ : formatReviewQueueText({ directory, entries, parsed: { ...parsed, seed: parsed.seed ?? "review-queue" } }));
888
+ };
889
+ const runLabel = async (parsed) => {
890
+ if (!parsed.recordId) {
891
+ throw new DatasetCommandError("dataset label requires --record-id or a record id argument.", DATASET_EXIT_CODES.usage_error);
892
+ }
893
+ if (parsed.labels.length === 0) {
894
+ throw new DatasetCommandError("dataset label requires at least one --label.", DATASET_EXIT_CODES.usage_error);
895
+ }
896
+ const directory = parsed.directory ?? defaultDatasetDirectory();
897
+ const collection = await readLocalDatasetCollection({ directory });
898
+ const result = applyDatasetLabel(collection, {
899
+ ...sampleOptionsFromParsed(parsed),
900
+ recordId: parsed.recordId,
901
+ labels: parsed.labels,
902
+ reviewerId: parsed.reviewerId,
903
+ reason: parsed.reasons[0],
904
+ });
905
+ await writeLocalDatasetCollection(collection);
906
+ // eslint-disable-next-line no-console
907
+ console.log(parsed.output === "json" ? JSON.stringify(result, null, 2) : `dataset label: updated=${result.updatedCount} records=${result.recordIds.join(",")}`);
908
+ };
909
+ const runPromoteTarget = async (parsed) => {
910
+ if (!parsed.recordId) {
911
+ throw new DatasetCommandError("dataset promote-target requires --record-id or a record id argument.", DATASET_EXIT_CODES.usage_error);
912
+ }
913
+ if (!parsed.promotionTarget) {
914
+ throw new DatasetCommandError("dataset promote-target requires --target gold|silver|reject.", DATASET_EXIT_CODES.usage_error);
915
+ }
916
+ const directory = parsed.directory ?? defaultDatasetDirectory();
917
+ const collection = await readLocalDatasetCollection({ directory });
918
+ const result = applyDatasetPromotionTarget(collection, {
919
+ ...sampleOptionsFromParsed(parsed),
920
+ recordId: parsed.recordId,
921
+ promotionTarget: parsed.promotionTarget,
922
+ decision: parsed.decision,
923
+ labels: parsed.labels.length ? parsed.labels : undefined,
924
+ reasons: parsed.reasons.length ? parsed.reasons : undefined,
925
+ reviewerId: parsed.reviewerId,
926
+ });
927
+ await writeLocalDatasetCollection(collection);
928
+ // eslint-disable-next-line no-console
929
+ console.log(parsed.output === "json" ? JSON.stringify(result, null, 2) : `dataset promote-target: updated=${result.updatedCount} records=${result.recordIds.join(",")}`);
930
+ };
931
+ export class DatasetCommand {
932
+ static async run(argv) {
933
+ const parsed = parseDatasetArgs(argv);
934
+ if (parsed.help) {
935
+ // eslint-disable-next-line no-console
936
+ console.log(HELP_TEXT);
937
+ return;
938
+ }
939
+ switch (parsed.command) {
940
+ case "inspect":
941
+ await runInspect(parsed);
942
+ return;
943
+ case "review-queue":
944
+ await runReviewQueue(parsed);
945
+ return;
946
+ case "label":
947
+ await runLabel(parsed);
948
+ return;
949
+ case "promote-target":
950
+ await runPromoteTarget(parsed);
951
+ return;
952
+ case "export":
953
+ await runDatasetExport(parsed);
954
+ return;
955
+ default:
956
+ throw new DatasetCommandError(HELP_TEXT, DATASET_EXIT_CODES.usage_error);
957
+ }
958
+ }
959
+ }