@plune-ai/cli 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { z } from 'zod';
2
+
1
3
  interface Summary {
2
4
  total: number;
3
5
  passed: number;
@@ -212,4 +214,538 @@ interface RunOptions {
212
214
  }
213
215
  declare function handleRun(options: RunOptions, depsFactory?: (config: Config, baseDir: string) => RunDeps): Promise<RunResult>;
214
216
 
215
- export { type AssertionResultRecord, type Config, type EvalResult, type RowResult, type RunError, type RunOptions, type RunResult, type Summary, type Usage, handleRun as run };
217
+ declare const assertionConfigSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
218
+ type: z.ZodLiteral<"exact-match">;
219
+ value: z.ZodString;
220
+ trim: z.ZodOptional<z.ZodBoolean>;
221
+ ignore_case: z.ZodOptional<z.ZodBoolean>;
222
+ }, "strip", z.ZodTypeAny, {
223
+ type: "exact-match";
224
+ value: string;
225
+ trim?: boolean | undefined;
226
+ ignore_case?: boolean | undefined;
227
+ }, {
228
+ type: "exact-match";
229
+ value: string;
230
+ trim?: boolean | undefined;
231
+ ignore_case?: boolean | undefined;
232
+ }>, z.ZodObject<{
233
+ type: z.ZodLiteral<"contains">;
234
+ value: z.ZodString;
235
+ ignore_case: z.ZodOptional<z.ZodBoolean>;
236
+ }, "strip", z.ZodTypeAny, {
237
+ type: "contains";
238
+ value: string;
239
+ ignore_case?: boolean | undefined;
240
+ }, {
241
+ type: "contains";
242
+ value: string;
243
+ ignore_case?: boolean | undefined;
244
+ }>, z.ZodObject<{
245
+ type: z.ZodLiteral<"contains-any">;
246
+ values: z.ZodArray<z.ZodString, "many">;
247
+ ignore_case: z.ZodOptional<z.ZodBoolean>;
248
+ }, "strip", z.ZodTypeAny, {
249
+ type: "contains-any";
250
+ values: string[];
251
+ ignore_case?: boolean | undefined;
252
+ }, {
253
+ type: "contains-any";
254
+ values: string[];
255
+ ignore_case?: boolean | undefined;
256
+ }>, z.ZodObject<{
257
+ type: z.ZodLiteral<"contains-all">;
258
+ values: z.ZodArray<z.ZodString, "many">;
259
+ ignore_case: z.ZodOptional<z.ZodBoolean>;
260
+ }, "strip", z.ZodTypeAny, {
261
+ type: "contains-all";
262
+ values: string[];
263
+ ignore_case?: boolean | undefined;
264
+ }, {
265
+ type: "contains-all";
266
+ values: string[];
267
+ ignore_case?: boolean | undefined;
268
+ }>, z.ZodObject<{
269
+ type: z.ZodLiteral<"json-schema">;
270
+ schema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
271
+ extract: z.ZodOptional<z.ZodEnum<["auto", "strict"]>>;
272
+ }, "strip", z.ZodTypeAny, {
273
+ type: "json-schema";
274
+ schema: Record<string, unknown>;
275
+ extract?: "auto" | "strict" | undefined;
276
+ }, {
277
+ type: "json-schema";
278
+ schema: Record<string, unknown>;
279
+ extract?: "auto" | "strict" | undefined;
280
+ }>, z.ZodObject<{
281
+ type: z.ZodLiteral<"llm-judge">;
282
+ criteria: z.ZodString;
283
+ provider: z.ZodOptional<z.ZodObject<{
284
+ type: z.ZodOptional<z.ZodEnum<["anthropic", "openai", "openrouter"]>>;
285
+ model: z.ZodOptional<z.ZodString>;
286
+ temperature: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
287
+ max_tokens: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
288
+ concurrency: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
289
+ timeout: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
290
+ max_retries: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
291
+ }, "strip", z.ZodTypeAny, {
292
+ type?: "anthropic" | "openai" | "openrouter" | undefined;
293
+ model?: string | undefined;
294
+ temperature?: number | undefined;
295
+ max_tokens?: number | undefined;
296
+ concurrency?: number | undefined;
297
+ timeout?: number | undefined;
298
+ max_retries?: number | undefined;
299
+ }, {
300
+ type?: "anthropic" | "openai" | "openrouter" | undefined;
301
+ model?: string | undefined;
302
+ temperature?: number | undefined;
303
+ max_tokens?: number | undefined;
304
+ concurrency?: number | undefined;
305
+ timeout?: number | undefined;
306
+ max_retries?: number | undefined;
307
+ }>>;
308
+ pass_threshold: z.ZodOptional<z.ZodNumber>;
309
+ }, "strip", z.ZodTypeAny, {
310
+ type: "llm-judge";
311
+ criteria: string;
312
+ provider?: {
313
+ type?: "anthropic" | "openai" | "openrouter" | undefined;
314
+ model?: string | undefined;
315
+ temperature?: number | undefined;
316
+ max_tokens?: number | undefined;
317
+ concurrency?: number | undefined;
318
+ timeout?: number | undefined;
319
+ max_retries?: number | undefined;
320
+ } | undefined;
321
+ pass_threshold?: number | undefined;
322
+ }, {
323
+ type: "llm-judge";
324
+ criteria: string;
325
+ provider?: {
326
+ type?: "anthropic" | "openai" | "openrouter" | undefined;
327
+ model?: string | undefined;
328
+ temperature?: number | undefined;
329
+ max_tokens?: number | undefined;
330
+ concurrency?: number | undefined;
331
+ timeout?: number | undefined;
332
+ max_retries?: number | undefined;
333
+ } | undefined;
334
+ pass_threshold?: number | undefined;
335
+ }>, z.ZodObject<{
336
+ type: z.ZodLiteral<"semantic-similarity">;
337
+ reference: z.ZodString;
338
+ threshold: z.ZodOptional<z.ZodNumber>;
339
+ }, "strip", z.ZodTypeAny, {
340
+ type: "semantic-similarity";
341
+ reference: string;
342
+ threshold?: number | undefined;
343
+ }, {
344
+ type: "semantic-similarity";
345
+ reference: string;
346
+ threshold?: number | undefined;
347
+ }>, z.ZodObject<{
348
+ type: z.ZodLiteral<"faithfulness">;
349
+ context: z.ZodString;
350
+ threshold: z.ZodOptional<z.ZodNumber>;
351
+ }, "strip", z.ZodTypeAny, {
352
+ type: "faithfulness";
353
+ context: string;
354
+ threshold?: number | undefined;
355
+ }, {
356
+ type: "faithfulness";
357
+ context: string;
358
+ threshold?: number | undefined;
359
+ }>, z.ZodObject<{
360
+ type: z.ZodLiteral<"answer-relevance">;
361
+ question: z.ZodString;
362
+ threshold: z.ZodOptional<z.ZodNumber>;
363
+ }, "strip", z.ZodTypeAny, {
364
+ type: "answer-relevance";
365
+ question: string;
366
+ threshold?: number | undefined;
367
+ }, {
368
+ type: "answer-relevance";
369
+ question: string;
370
+ threshold?: number | undefined;
371
+ }>, z.ZodObject<{
372
+ type: z.ZodLiteral<"context-precision">;
373
+ context: z.ZodString;
374
+ question: z.ZodString;
375
+ threshold: z.ZodOptional<z.ZodNumber>;
376
+ }, "strip", z.ZodTypeAny, {
377
+ type: "context-precision";
378
+ context: string;
379
+ question: string;
380
+ threshold?: number | undefined;
381
+ }, {
382
+ type: "context-precision";
383
+ context: string;
384
+ question: string;
385
+ threshold?: number | undefined;
386
+ }>]>;
387
+
388
+ /**
389
+ * Runtime validation for the RunResult contract — the JSON that `plune run --format json` emits.
390
+ *
391
+ * The canonical TypeScript shape is owned by `./results.ts` (golden-pinned, `schemaVersion: 1`,
392
+ * snake_case). This module is its zod mirror: the validator for anything that has to *ingest* that
393
+ * output rather than produce it. `plune sync` validates the local run file with it before uploading,
394
+ * and the Plune platform validates the same body on `POST /v1/runs` — one schema, both ends, so a
395
+ * divergent copy is impossible (the reason it lives here and not in the platform).
396
+ *
397
+ * Superset: an assertion record may carry an optional `binaryVerdicts[]` — the per-question breakdown
398
+ * of an llm-judge verdict `{ question, passed }`. The runner does not emit the field; plain output
399
+ * validates unchanged, and a consumer that enriches a result stays valid. Purely additive.
400
+ */
401
+ /**
402
+ * Version marker for the RunResult contract, type-pinned to the frozen `RunResult['schemaVersion']`
403
+ * literal: if the public contract ever bumps its version, this line fails typecheck until it is
404
+ * updated in lockstep with the golden test.
405
+ */
406
+ declare const RUN_RESULT_SCHEMA_VERSION: RunResult['schemaVersion'];
407
+ declare const binaryVerdictSchema: z.ZodObject<{
408
+ question: z.ZodString;
409
+ passed: z.ZodBoolean;
410
+ }, "strip", z.ZodTypeAny, {
411
+ question: string;
412
+ passed: boolean;
413
+ }, {
414
+ question: string;
415
+ passed: boolean;
416
+ }>;
417
+ declare const assertionResultRecordSchema: z.ZodObject<{
418
+ type: z.ZodString;
419
+ passed: z.ZodBoolean;
420
+ score: z.ZodOptional<z.ZodNumber>;
421
+ reason: z.ZodOptional<z.ZodString>;
422
+ binaryVerdicts: z.ZodOptional<z.ZodArray<z.ZodObject<{
423
+ question: z.ZodString;
424
+ passed: z.ZodBoolean;
425
+ }, "strip", z.ZodTypeAny, {
426
+ question: string;
427
+ passed: boolean;
428
+ }, {
429
+ question: string;
430
+ passed: boolean;
431
+ }>, "many">>;
432
+ }, "strip", z.ZodTypeAny, {
433
+ type: string;
434
+ passed: boolean;
435
+ score?: number | undefined;
436
+ reason?: string | undefined;
437
+ binaryVerdicts?: {
438
+ question: string;
439
+ passed: boolean;
440
+ }[] | undefined;
441
+ }, {
442
+ type: string;
443
+ passed: boolean;
444
+ score?: number | undefined;
445
+ reason?: string | undefined;
446
+ binaryVerdicts?: {
447
+ question: string;
448
+ passed: boolean;
449
+ }[] | undefined;
450
+ }>;
451
+ declare const runResultSchema: z.ZodObject<{
452
+ schemaVersion: z.ZodLiteral<1>;
453
+ plune_version: z.ZodString;
454
+ started_at: z.ZodString;
455
+ finished_at: z.ZodString;
456
+ config_hash: z.ZodString;
457
+ summary: z.ZodObject<{
458
+ total: z.ZodNumber;
459
+ passed: z.ZodNumber;
460
+ failed: z.ZodNumber;
461
+ errored: z.ZodNumber;
462
+ cost_usd: z.ZodNumber;
463
+ duration_ms: z.ZodNumber;
464
+ }, "strip", z.ZodTypeAny, {
465
+ cost_usd: number;
466
+ passed: number;
467
+ failed: number;
468
+ errored: number;
469
+ total: number;
470
+ duration_ms: number;
471
+ }, {
472
+ cost_usd: number;
473
+ passed: number;
474
+ failed: number;
475
+ errored: number;
476
+ total: number;
477
+ duration_ms: number;
478
+ }>;
479
+ evals: z.ZodArray<z.ZodObject<{
480
+ id: z.ZodString;
481
+ tags: z.ZodArray<z.ZodString, "many">;
482
+ rows: z.ZodArray<z.ZodObject<{
483
+ vars: z.ZodRecord<z.ZodString, z.ZodUnknown>;
484
+ output: z.ZodNullable<z.ZodString>;
485
+ cached: z.ZodBoolean;
486
+ usage: z.ZodOptional<z.ZodObject<{
487
+ input_tokens: z.ZodNumber;
488
+ output_tokens: z.ZodNumber;
489
+ cost_usd: z.ZodNumber;
490
+ }, "strip", z.ZodTypeAny, {
491
+ cost_usd: number;
492
+ input_tokens: number;
493
+ output_tokens: number;
494
+ }, {
495
+ cost_usd: number;
496
+ input_tokens: number;
497
+ output_tokens: number;
498
+ }>>;
499
+ latency_ms: z.ZodOptional<z.ZodNumber>;
500
+ error: z.ZodOptional<z.ZodObject<{
501
+ code: z.ZodString;
502
+ message: z.ZodString;
503
+ }, "strip", z.ZodTypeAny, {
504
+ code: string;
505
+ message: string;
506
+ }, {
507
+ code: string;
508
+ message: string;
509
+ }>>;
510
+ assertions: z.ZodArray<z.ZodObject<{
511
+ type: z.ZodString;
512
+ passed: z.ZodBoolean;
513
+ score: z.ZodOptional<z.ZodNumber>;
514
+ reason: z.ZodOptional<z.ZodString>;
515
+ binaryVerdicts: z.ZodOptional<z.ZodArray<z.ZodObject<{
516
+ question: z.ZodString;
517
+ passed: z.ZodBoolean;
518
+ }, "strip", z.ZodTypeAny, {
519
+ question: string;
520
+ passed: boolean;
521
+ }, {
522
+ question: string;
523
+ passed: boolean;
524
+ }>, "many">>;
525
+ }, "strip", z.ZodTypeAny, {
526
+ type: string;
527
+ passed: boolean;
528
+ score?: number | undefined;
529
+ reason?: string | undefined;
530
+ binaryVerdicts?: {
531
+ question: string;
532
+ passed: boolean;
533
+ }[] | undefined;
534
+ }, {
535
+ type: string;
536
+ passed: boolean;
537
+ score?: number | undefined;
538
+ reason?: string | undefined;
539
+ binaryVerdicts?: {
540
+ question: string;
541
+ passed: boolean;
542
+ }[] | undefined;
543
+ }>, "many">;
544
+ }, "strip", z.ZodTypeAny, {
545
+ vars: Record<string, unknown>;
546
+ assertions: {
547
+ type: string;
548
+ passed: boolean;
549
+ score?: number | undefined;
550
+ reason?: string | undefined;
551
+ binaryVerdicts?: {
552
+ question: string;
553
+ passed: boolean;
554
+ }[] | undefined;
555
+ }[];
556
+ output: string | null;
557
+ cached: boolean;
558
+ error?: {
559
+ code: string;
560
+ message: string;
561
+ } | undefined;
562
+ usage?: {
563
+ cost_usd: number;
564
+ input_tokens: number;
565
+ output_tokens: number;
566
+ } | undefined;
567
+ latency_ms?: number | undefined;
568
+ }, {
569
+ vars: Record<string, unknown>;
570
+ assertions: {
571
+ type: string;
572
+ passed: boolean;
573
+ score?: number | undefined;
574
+ reason?: string | undefined;
575
+ binaryVerdicts?: {
576
+ question: string;
577
+ passed: boolean;
578
+ }[] | undefined;
579
+ }[];
580
+ output: string | null;
581
+ cached: boolean;
582
+ error?: {
583
+ code: string;
584
+ message: string;
585
+ } | undefined;
586
+ usage?: {
587
+ cost_usd: number;
588
+ input_tokens: number;
589
+ output_tokens: number;
590
+ } | undefined;
591
+ latency_ms?: number | undefined;
592
+ }>, "many">;
593
+ passed: z.ZodBoolean;
594
+ }, "strip", z.ZodTypeAny, {
595
+ id: string;
596
+ tags: string[];
597
+ passed: boolean;
598
+ rows: {
599
+ vars: Record<string, unknown>;
600
+ assertions: {
601
+ type: string;
602
+ passed: boolean;
603
+ score?: number | undefined;
604
+ reason?: string | undefined;
605
+ binaryVerdicts?: {
606
+ question: string;
607
+ passed: boolean;
608
+ }[] | undefined;
609
+ }[];
610
+ output: string | null;
611
+ cached: boolean;
612
+ error?: {
613
+ code: string;
614
+ message: string;
615
+ } | undefined;
616
+ usage?: {
617
+ cost_usd: number;
618
+ input_tokens: number;
619
+ output_tokens: number;
620
+ } | undefined;
621
+ latency_ms?: number | undefined;
622
+ }[];
623
+ }, {
624
+ id: string;
625
+ tags: string[];
626
+ passed: boolean;
627
+ rows: {
628
+ vars: Record<string, unknown>;
629
+ assertions: {
630
+ type: string;
631
+ passed: boolean;
632
+ score?: number | undefined;
633
+ reason?: string | undefined;
634
+ binaryVerdicts?: {
635
+ question: string;
636
+ passed: boolean;
637
+ }[] | undefined;
638
+ }[];
639
+ output: string | null;
640
+ cached: boolean;
641
+ error?: {
642
+ code: string;
643
+ message: string;
644
+ } | undefined;
645
+ usage?: {
646
+ cost_usd: number;
647
+ input_tokens: number;
648
+ output_tokens: number;
649
+ } | undefined;
650
+ latency_ms?: number | undefined;
651
+ }[];
652
+ }>, "many">;
653
+ }, "strip", z.ZodTypeAny, {
654
+ evals: {
655
+ id: string;
656
+ tags: string[];
657
+ passed: boolean;
658
+ rows: {
659
+ vars: Record<string, unknown>;
660
+ assertions: {
661
+ type: string;
662
+ passed: boolean;
663
+ score?: number | undefined;
664
+ reason?: string | undefined;
665
+ binaryVerdicts?: {
666
+ question: string;
667
+ passed: boolean;
668
+ }[] | undefined;
669
+ }[];
670
+ output: string | null;
671
+ cached: boolean;
672
+ error?: {
673
+ code: string;
674
+ message: string;
675
+ } | undefined;
676
+ usage?: {
677
+ cost_usd: number;
678
+ input_tokens: number;
679
+ output_tokens: number;
680
+ } | undefined;
681
+ latency_ms?: number | undefined;
682
+ }[];
683
+ }[];
684
+ schemaVersion: 1;
685
+ plune_version: string;
686
+ summary: {
687
+ cost_usd: number;
688
+ passed: number;
689
+ failed: number;
690
+ errored: number;
691
+ total: number;
692
+ duration_ms: number;
693
+ };
694
+ started_at: string;
695
+ finished_at: string;
696
+ config_hash: string;
697
+ }, {
698
+ evals: {
699
+ id: string;
700
+ tags: string[];
701
+ passed: boolean;
702
+ rows: {
703
+ vars: Record<string, unknown>;
704
+ assertions: {
705
+ type: string;
706
+ passed: boolean;
707
+ score?: number | undefined;
708
+ reason?: string | undefined;
709
+ binaryVerdicts?: {
710
+ question: string;
711
+ passed: boolean;
712
+ }[] | undefined;
713
+ }[];
714
+ output: string | null;
715
+ cached: boolean;
716
+ error?: {
717
+ code: string;
718
+ message: string;
719
+ } | undefined;
720
+ usage?: {
721
+ cost_usd: number;
722
+ input_tokens: number;
723
+ output_tokens: number;
724
+ } | undefined;
725
+ latency_ms?: number | undefined;
726
+ }[];
727
+ }[];
728
+ schemaVersion: 1;
729
+ plune_version: string;
730
+ summary: {
731
+ cost_usd: number;
732
+ passed: number;
733
+ failed: number;
734
+ errored: number;
735
+ total: number;
736
+ duration_ms: number;
737
+ };
738
+ started_at: string;
739
+ finished_at: string;
740
+ config_hash: string;
741
+ }>;
742
+ /**
743
+ * Type inferred from the zod mirror — structurally a superset of the frozen `RunResult`
744
+ * (adds optional `binaryVerdicts`). The canonical `RunResult` remains the source of truth.
745
+ */
746
+ type ParsedRunResult = z.infer<typeof runResultSchema>;
747
+ type BinaryVerdict = z.infer<typeof binaryVerdictSchema>;
748
+ /** Parse + validate an unknown value as a RunResult. Throws ZodError on failure. */
749
+ declare function parseRunResult(value: unknown): ParsedRunResult;
750
+
751
+ export { type AssertionResultRecord, type BinaryVerdict, type Config, type EvalResult, type ParsedRunResult, RUN_RESULT_SCHEMA_VERSION, type RowResult, type RunError, type RunOptions, type RunResult, type Summary, type Usage, assertionConfigSchema, assertionResultRecordSchema, binaryVerdictSchema, parseRunResult, handleRun as run, runResultSchema };
package/dist/index.js CHANGED
@@ -1460,6 +1460,71 @@ async function handleRun(options, depsFactory) {
1460
1460
  deps.cache.close();
1461
1461
  }
1462
1462
  }
1463
+
1464
+ // src/types/run-result-schema.ts
1465
+ import { z as z2 } from "zod";
1466
+ var RUN_RESULT_SCHEMA_VERSION = 1;
1467
+ var binaryVerdictSchema = z2.object({
1468
+ question: z2.string().min(1),
1469
+ passed: z2.boolean()
1470
+ });
1471
+ var assertionResultRecordSchema = z2.object({
1472
+ type: z2.string(),
1473
+ passed: z2.boolean(),
1474
+ score: z2.number().optional(),
1475
+ reason: z2.string().optional(),
1476
+ binaryVerdicts: z2.array(binaryVerdictSchema).optional()
1477
+ });
1478
+ var usageSchema = z2.object({
1479
+ input_tokens: z2.number(),
1480
+ output_tokens: z2.number(),
1481
+ cost_usd: z2.number()
1482
+ });
1483
+ var runErrorSchema = z2.object({
1484
+ code: z2.string(),
1485
+ message: z2.string()
1486
+ });
1487
+ var rowResultSchema = z2.object({
1488
+ vars: z2.record(z2.unknown()),
1489
+ output: z2.string().nullable(),
1490
+ cached: z2.boolean(),
1491
+ usage: usageSchema.optional(),
1492
+ latency_ms: z2.number().optional(),
1493
+ error: runErrorSchema.optional(),
1494
+ assertions: z2.array(assertionResultRecordSchema)
1495
+ });
1496
+ var summarySchema = z2.object({
1497
+ total: z2.number(),
1498
+ passed: z2.number(),
1499
+ failed: z2.number(),
1500
+ errored: z2.number(),
1501
+ cost_usd: z2.number(),
1502
+ duration_ms: z2.number()
1503
+ });
1504
+ var evalResultSchema = z2.object({
1505
+ id: z2.string(),
1506
+ tags: z2.array(z2.string()),
1507
+ rows: z2.array(rowResultSchema),
1508
+ passed: z2.boolean()
1509
+ });
1510
+ var runResultSchema = z2.object({
1511
+ schemaVersion: z2.literal(RUN_RESULT_SCHEMA_VERSION),
1512
+ plune_version: z2.string(),
1513
+ started_at: z2.string(),
1514
+ finished_at: z2.string(),
1515
+ config_hash: z2.string(),
1516
+ summary: summarySchema,
1517
+ evals: z2.array(evalResultSchema)
1518
+ });
1519
+ function parseRunResult(value) {
1520
+ return runResultSchema.parse(value);
1521
+ }
1463
1522
  export {
1464
- handleRun as run
1523
+ RUN_RESULT_SCHEMA_VERSION,
1524
+ assertionConfigSchema,
1525
+ assertionResultRecordSchema,
1526
+ binaryVerdictSchema,
1527
+ parseRunResult,
1528
+ handleRun as run,
1529
+ runResultSchema
1465
1530
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plune-ai/cli",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "AI-powered assertion testing for LLM apps — write assertions, run them against any provider, get a pass/fail report (local, CI, or diff).",
5
5
  "keywords": [
6
6
  "ai",