runbios-sdk 0.3.0-rc.330 → 0.4.0-dev.333

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/types.d.ts CHANGED
@@ -8,13 +8,13 @@ export interface BiOSConfig {
8
8
  orgId?: string;
9
9
  /** Workspace ID. Optional when using API keys (resolved from the key). Can override for multi-workspace keys. */
10
10
  workspaceId?: string;
11
- /** Base URL for the API. Falls back to the RUNBIOS_BASE_URL environment variable (legacy: BIOS_BASE_URL), then the canonical https://api-staging.runbios.ai hostname. */
11
+ /** Base URL for the API. Falls back to the RUNBIOS_BASE_URL environment variable (legacy: BIOS_BASE_URL), then the canonical https://api-dev.runbios.ai hostname. */
12
12
  baseUrl?: string;
13
13
  /** Request timeout in milliseconds. Defaults to 30000. */
14
14
  timeout?: number;
15
15
  /** Default per-deployment inference key. Can be overridden per inference call. */
16
16
  inferenceKey?: string;
17
- /** Inference base URL. Defaults to baseUrl, then https://api-staging.runbios.ai. */
17
+ /** Inference base URL. Defaults to baseUrl, then https://api-dev.runbios.ai. */
18
18
  inferenceBaseUrl?: string;
19
19
  /** End-to-end inference timeout in milliseconds. Defaults to 15 minutes. */
20
20
  inferenceTimeout?: number;
@@ -2439,7 +2439,10 @@ export type LoopSource = 'human' | 'verifier' | 'judge' | 'behavioural';
2439
2439
  * trained on in place of the model's.
2440
2440
  * `gold` records the reference answer for the question, making no claim about
2441
2441
  * whether the model was right; it is trained on the same way.
2442
- * `scored` is a score the platform's own scoring wrote; it is read, never sent.
2442
+ * `scored` is the judge's score of a sample nobody reviewed (source `judge`),
2443
+ * written by the platform's automatic scoring; it is read, never sent. It is
2444
+ * not feedback: the sample stays unreviewed, and it is trained on only when
2445
+ * the judge picked it (`picked`, a score of 0.8 or more).
2443
2446
  */
2444
2447
  export type LoopVerdict = 'accepted' | 'rejected' | 'edited' | 'scored' | 'gold';
2445
2448
  /** The verdicts feedback can send: a person's good, bad, correction or reference answer. */
@@ -2665,7 +2668,14 @@ export interface LoopImportResult {
2665
2668
  * was written.
2666
2669
  */
2667
2670
  by_shape: Record<string, number>;
2671
+ /** The refused rows counted by code. Kept for older readers: show `refused_reasons`, which carries the words. */
2668
2672
  refused_why: Record<string, number>;
2673
+ /**
2674
+ * Why rows were refused, one entry per reason: its `code`, how many rows
2675
+ * (`count`) and one plain `sentence` to show. Absent from a service from
2676
+ * before it was sent; `refused_why` then has the codes alone.
2677
+ */
2678
+ refused_reasons?: LoopImportRefusal[];
2669
2679
  /**
2670
2680
  * The conversations from this file that are now in the loop, in file order:
2671
2681
  * the ones this call created and the ones it found already there. Without
@@ -2675,6 +2685,12 @@ export interface LoopImportResult {
2675
2685
  trace_ids?: string[];
2676
2686
  notes: string[];
2677
2687
  }
2688
+ /** One reason an import refused rows: the code, how many rows, and the sentence to show for it. */
2689
+ export interface LoopImportRefusal {
2690
+ code: string;
2691
+ count: number;
2692
+ sentence: string;
2693
+ }
2678
2694
  export interface LoopSignal {
2679
2695
  id: string;
2680
2696
  trace_id: string;
@@ -2688,6 +2704,18 @@ export interface LoopSignal {
2688
2704
  /** What the caller attached when recording it, or null. */
2689
2705
  metadata: Record<string, unknown> | null;
2690
2706
  created_at: string;
2707
+ /**
2708
+ * Present only on the judge's score of an unreviewed sample (source
2709
+ * `judge`, verdict `scored`): true when the score reached the bar (0.8) and
2710
+ * the answer is trained on, false when it did not. No feedback route writes
2711
+ * it, and a person's feedback on the sample decides over it.
2712
+ */
2713
+ picked?: boolean;
2714
+ /**
2715
+ * True on the judge's score when its reason is kept in storage and could
2716
+ * not be read just now: `reason` is then null. Read the sample again later.
2717
+ */
2718
+ reason_unavailable?: boolean;
2691
2719
  }
2692
2720
  /** One feedback item for `loop.signalMany`: the sample's id and its feedback. */
2693
2721
  export interface LoopSignalManyItem extends LoopSignalParams {
@@ -2776,10 +2804,24 @@ export interface LoopTrace {
2776
2804
  /** Who gave that verdict. */
2777
2805
  verdict_source?: LoopSource;
2778
2806
  /**
2779
- * The score a `scored` verdict carries: above zero it trains the answer as
2780
- * it stands (good feedback), zero or below it trains nothing (bad).
2807
+ * The score a `scored` verdict carries: the judge's score of a sample nobody
2808
+ * reviewed. Whether it is trained on is `judge.picked`, never this number.
2781
2809
  */
2782
2810
  verdict_score?: number;
2811
+ /**
2812
+ * The judge's score of this sample, when the platform's automatic scoring
2813
+ * scored it (it scores only samples nobody reviewed): `picked` is true when
2814
+ * the score reached the bar (0.8) and the answer is trained on. Present
2815
+ * whatever a person said later; a person's feedback decides over it.
2816
+ * Absent when the judge never scored it.
2817
+ */
2818
+ judge?: LoopTraceJudge;
2819
+ /**
2820
+ * What happens to this sample in the pipeline the list was narrowed to
2821
+ * (`pipeline`). Only on the rows of a list read with `pipeline`; absent from
2822
+ * a service from before it was sent.
2823
+ */
2824
+ state?: LoopSampleState;
2783
2825
  /** Its tags. On the single read only. */
2784
2826
  labels?: LoopLabel[];
2785
2827
  /**
@@ -2795,12 +2837,49 @@ export interface LoopTrace {
2795
2837
  */
2796
2838
  payload_unavailable?: boolean;
2797
2839
  }
2840
+ /** The judge's score of an unreviewed sample: its mean over the rubric's aspects, and whether it reached the bar. */
2841
+ export interface LoopTraceJudge {
2842
+ score: number;
2843
+ /** True at 0.8 or more: the answer is trained on, as long as no person says otherwise. */
2844
+ picked: boolean;
2845
+ }
2846
+ /**
2847
+ * What happens to a sample in one pipeline, in that pipeline's terms:
2848
+ * - `held_back`: held back to test its attempts, never trained on;
2849
+ * - `learned`: a version that went live learned it (`version_no`);
2850
+ * - `trained`: an attempt trained on it that did not go live (`attempt_no`);
2851
+ * - `waiting`: it waits for the next attempt;
2852
+ * - `left_out`: the pipeline does not train on it as it is, and `reason`
2853
+ * says why.
2854
+ *
2855
+ * `reason` is always the plain sentence to show.
2856
+ */
2857
+ export type LoopSampleStateName = 'held_back' | 'learned' | 'trained' | 'waiting' | 'left_out';
2858
+ /** A sample's state in one pipeline: see {@link LoopSampleStateName}. */
2859
+ export interface LoopSampleState {
2860
+ state: LoopSampleStateName;
2861
+ /** The attempt it is about (the one that learned it, held it back or trained on it); null when there is none. */
2862
+ attempt_no: number | null;
2863
+ /** The version that learned it; null unless `state` is `learned`. */
2864
+ version_no: number | null;
2865
+ /** The plain sentence that says it (for `left_out`, why): show it as it is sent. */
2866
+ reason: string;
2867
+ }
2868
+ /**
2869
+ * The judge's split of the samples nobody reviewed: `picked` (scored 0.8 or
2870
+ * more, trained on), `below_bar` (scored lower, not trained on) and
2871
+ * `unscored` (not scored yet).
2872
+ */
2873
+ export type LoopJudgeFilter = 'picked' | 'below_bar' | 'unscored';
2798
2874
  export interface LoopTraceListParams {
2799
2875
  deployment_id?: string;
2800
2876
  conversation_id?: string;
2801
2877
  from?: string;
2802
2878
  to?: string;
2803
- /** Only conversations that already carry a verdict. */
2879
+ /**
2880
+ * Only conversations a person gave feedback on. The judge's score of an
2881
+ * unreviewed sample is not feedback: see `judge`.
2882
+ */
2804
2883
  signalled?: boolean;
2805
2884
  /** One bare tag. A tag with children matches them too. */
2806
2885
  label?: string;
@@ -2818,17 +2897,42 @@ export interface LoopTraceListParams {
2818
2897
  /** `captured` (our model's own behaviour) or `imported` (a file somebody brought). */
2819
2898
  origin?: 'captured' | 'imported';
2820
2899
  /**
2821
- * Only the conversations one pipeline's selection covers -- any of its tags
2822
- * -- reviewed or not. The other filters narrow it further.
2900
+ * Only the conversations one pipeline trains on -- any of its tags or its
2901
+ * datasets, narrowed by its conditions -- reviewed or not. Each row then
2902
+ * carries `state`, what happens to it in that pipeline. The other filters
2903
+ * narrow it further. Not with `dataset`.
2823
2904
  */
2824
2905
  pipeline?: string;
2825
2906
  /**
2826
- * Only the conversations whose deciding verdict is this feedback: `good`
2827
- * (accepted), `bad` (rejected) or `corrected` (edited, or gold).
2907
+ * Only the conversations one saved dataset selects (its id): the same
2908
+ * samples, and the same `total`, as its `samples` count. Not with
2909
+ * `pipeline`.
2910
+ */
2911
+ dataset?: string;
2912
+ /**
2913
+ * Only the samples of one attempt's set (a run id): with `split`, the ones
2914
+ * it trained on (`train`) or held back to test it (`held_back`).
2915
+ */
2916
+ attempt?: string;
2917
+ /** With `attempt`: `train` or `held_back`. */
2918
+ split?: 'train' | 'held_back';
2919
+ /**
2920
+ * Only the conversations whose deciding feedback from a person is this:
2921
+ * `good` (accepted), `bad` (rejected) or `corrected` (edited, or gold).
2922
+ * The judge's score is never one of these words.
2828
2923
  */
2829
2924
  signal?: 'good' | 'bad' | 'corrected';
2830
- /** Only the conversations nobody has given feedback on yet. */
2925
+ /**
2926
+ * Only the conversations no person has given feedback on yet, whether or
2927
+ * not the judge scored them.
2928
+ */
2831
2929
  unsignalled?: boolean;
2930
+ /**
2931
+ * The unreviewed samples, split by the judge: `picked`, `below_bar` or
2932
+ * `unscored` (see {@link LoopJudgeFilter}). Each implies no feedback from a
2933
+ * person; the three add up to `unsignalled`.
2934
+ */
2935
+ judge?: LoopJudgeFilter;
2832
2936
  /**
2833
2937
  * Text search: 2 to 200 characters, case-insensitive, matched as written
2834
2938
  * (`%` and `_` are plain characters) in every message, the answer and the
@@ -2891,6 +2995,29 @@ export interface LoopStats {
2891
2995
  * were not recorded under a tag, most first. Empty when every one was.
2892
2996
  */
2893
2997
  capture: LoopCaptureHealth;
2998
+ /** How many samples were recorded in the last 48 hours. Absent from a service from before it was sent. */
2999
+ samples_recent?: number;
3000
+ /**
3001
+ * Every sample by the feedback a person gave it, in the Samples list's
3002
+ * words (`unreviewed`: no feedback from a person yet). They add up to
3003
+ * `traces`. Absent from a service from before it was sent.
3004
+ */
3005
+ feedback?: LoopFeedbackCounts;
3006
+ /**
3007
+ * How many pipelines the workspace has, and how many of them are training,
3008
+ * waiting on you (`needs_you`), serving or paused: the counts of
3009
+ * `listPipelines({ status })`. Absent from a service from before it was
3010
+ * sent.
3011
+ */
3012
+ pipelines?: LoopPipelineCounts;
3013
+ }
3014
+ /** `LoopStats.pipelines`: the workspace's pipelines, counted by what they are doing. */
3015
+ export interface LoopPipelineCounts {
3016
+ total: number;
3017
+ training: number;
3018
+ needs_you: number;
3019
+ serving: number;
3020
+ paused: number;
2894
3021
  }
2895
3022
  /** `LoopStats.capture` and `Pipeline.capture`: what the one-header capture did not record. */
2896
3023
  export interface LoopCaptureHealth {
@@ -2921,9 +3048,21 @@ export interface LoopTracePipeline {
2921
3048
  name: string;
2922
3049
  /** Whether the pipeline is switched on. A paused one still selects the conversation. */
2923
3050
  enabled: boolean;
3051
+ /**
3052
+ * What happens to the conversation in this pipeline (see
3053
+ * {@link LoopSampleStateName}). Absent from a service from before it was
3054
+ * sent.
3055
+ */
3056
+ state?: LoopSampleStateName;
3057
+ /** See {@link LoopSampleState.attempt_no}. */
3058
+ attempt_no?: number | null;
3059
+ /** See {@link LoopSampleState.version_no}. */
3060
+ version_no?: number | null;
3061
+ /** See {@link LoopSampleState.reason}. */
3062
+ reason?: string;
2924
3063
  }
2925
3064
  export interface LoopTracePipelinesResponse {
2926
- /** Live pipelines whose tags select this conversation. Empty is a real answer. */
3065
+ /** Live pipelines whose tags, datasets and conditions select this conversation. Empty is a real answer. */
2927
3066
  pipelines: LoopTracePipeline[];
2928
3067
  /** Being selected is not being trained on; this sentence says so. */
2929
3068
  note: string;
@@ -2953,6 +3092,8 @@ export interface LoopMetricPoint {
2953
3092
  billed_candidate_cents: number;
2954
3093
  spent_eval_cents: number;
2955
3094
  benchmark_spent_cents: number;
3095
+ /** Scoring the samples nobody reviewed, in the passes the attempt took when it was booked. */
3096
+ sample_scoring_cents?: number;
2956
3097
  evaluation_id: string | null;
2957
3098
  rows_scored: number | null;
2958
3099
  rows_failed: number | null;
@@ -3002,10 +3143,28 @@ export interface LoopSignalDay {
3002
3143
  total: number;
3003
3144
  by_verdict: Record<string, number>;
3004
3145
  }
3146
+ /**
3147
+ * One day of a pipeline's samples, counted by their feedback today: `good`,
3148
+ * `bad`, `corrected`, and `unreviewed` (no feedback from a person).
3149
+ */
3150
+ export interface LoopSampleDay {
3151
+ day: string;
3152
+ good: number;
3153
+ bad: number;
3154
+ corrected: number;
3155
+ unreviewed: number;
3156
+ }
3005
3157
  export interface LoopMetricsHistory {
3006
3158
  /** Oldest first, so a chart reads left to right. */
3007
3159
  runs: LoopMetricPoint[];
3008
3160
  signals: LoopSignalDay[];
3161
+ /**
3162
+ * The samples recorded each day over `days`, oldest first, by their
3163
+ * feedback today: the pipeline's (the samples its Samples list holds) with
3164
+ * `rule_id`, the workspace's without. Absent from a service from before it
3165
+ * was sent.
3166
+ */
3167
+ samples?: LoopSampleDay[];
3009
3168
  /** True when older attempts exist beyond `limit`. */
3010
3169
  truncated: boolean;
3011
3170
  }
@@ -3260,6 +3419,11 @@ export interface TrainingRunCancelRequest {
3260
3419
  export interface TrainingRunListParams {
3261
3420
  rule_id?: string;
3262
3421
  state?: TrainingRunState;
3422
+ /**
3423
+ * Only the attempts that ended this way, in the words and values of
3424
+ * `listPipelineAttempts`' `result`. Only numbered attempts have one.
3425
+ */
3426
+ result?: PipelineAttemptResultFilter;
3263
3427
  limit?: number;
3264
3428
  offset?: number;
3265
3429
  }
@@ -3326,7 +3490,11 @@ export interface TrainingRun {
3326
3490
  * True when a comparison machine was charged: the figure is then the most
3327
3491
  * it can have cost ("up to"), since it counts each machine from its first
3328
3492
  * boot where the platform bills from its first answer (and at the hourly
3329
- * cap when no placement price was reported).
3493
+ * cap when no placement price was reported). False again once billing has
3494
+ * settled every such machine and its charge for the time each one served
3495
+ * replaced the "up to" figure (the run's timeline says what each was
3496
+ * charged). The new model's machine of a run that went live (a version) or
3497
+ * that a person took over is never settled, so it stays true for that run.
3330
3498
  */
3331
3499
  billed_candidate_up_to: boolean;
3332
3500
  /**
@@ -3380,6 +3548,12 @@ export interface TrainingRun {
3380
3548
  * has ended.
3381
3549
  */
3382
3550
  training_summary: string | null;
3551
+ /**
3552
+ * What it trained on, as it was when its set was built: see
3553
+ * {@link TrainedOn}. Null when its set is gone; absent from a service from
3554
+ * before it was sent.
3555
+ */
3556
+ trained_on?: TrainedOn | null;
3383
3557
  candidate_deployment_id: string | null;
3384
3558
  candidate_name: string | null;
3385
3559
  candidate_seq: number;
@@ -3410,6 +3584,12 @@ export interface TrainingRun {
3410
3584
  * anything totalling what a run cost has to add this one too.
3411
3585
  */
3412
3586
  benchmark_spent_cents: number;
3587
+ /**
3588
+ * What scoring the samples nobody reviewed cost, in the passes the attempt
3589
+ * took when it was booked. The fifth money column: the parts add up to the
3590
+ * attempt's `cost_cents` on the pipeline only with it.
3591
+ */
3592
+ sample_scoring_cents?: number;
3413
3593
  alias_name: string | null;
3414
3594
  alias_written_at: string | null;
3415
3595
  serving_before: TrainingRuleServing | null;
@@ -3464,6 +3644,8 @@ export interface TrainingRunSummary {
3464
3644
  spent_eval_cents: number;
3465
3645
  /** The fourth money column. A row that leaves it out adds up short. */
3466
3646
  benchmark_spent_cents: number;
3647
+ /** The fifth: scoring the samples nobody reviewed, taken when the attempt was booked. */
3648
+ sample_scoring_cents?: number;
3467
3649
  training_job_id: string | null;
3468
3650
  candidate_deployment_id: string | null;
3469
3651
  evaluation_id: string | null;
@@ -3471,6 +3653,13 @@ export interface TrainingRunSummary {
3471
3653
  auto_promote_at: string | null;
3472
3654
  created_at: string;
3473
3655
  finished_at: string | null;
3656
+ /**
3657
+ * This run as its pipeline's attempts list carries it (outcome, cost, pass
3658
+ * rates and the plain `explanation`), so the list of every pipeline's
3659
+ * attempts says what each pipeline's own list says. Null for a run that is
3660
+ * not a numbered attempt; absent from a service from before it was sent.
3661
+ */
3662
+ attempt?: PipelineAttempt | null;
3474
3663
  }
3475
3664
  /** One line of the timeline. detail holds codes, ids and cents, never prompt text. */
3476
3665
  export interface TrainingRunEvent {
@@ -3769,7 +3958,7 @@ export type BenchmarkRunStatus = 'open' | 'done' | 'failed' | 'budget_stopped' |
3769
3958
  * is a missing number, never a lower one.
3770
3959
  */
3771
3960
  export interface BenchmarkScoring {
3772
- /** `judge_overall` (a scoring model) or `exact_match` (the exact check). */
3961
+ /** `judge_overall` (the judge) or `exact_match` (the exact check). */
3773
3962
  metric: string;
3774
3963
  scale: string;
3775
3964
  aggregate: string;
@@ -3778,7 +3967,7 @@ export interface BenchmarkScoring {
3778
3967
  /**
3779
3968
  * How a benchmark's answers are scored, chosen when it is made and frozen:
3780
3969
  *
3781
- * - `judge` (the default): a scoring model reads both answers against the
3970
+ * - `judge` (the default): the judge reads both answers against the
3782
3971
  * right answer, as for the held-back set.
3783
3972
  * - `exact`: the answer or the tool call must match the right answer, and no
3784
3973
  * model is asked. When the right answer calls tools, the answer must make
@@ -3809,15 +3998,30 @@ export interface BenchmarkDimensionScore {
3809
3998
  /**
3810
3999
  * What a pipeline's history, or a benchmark's pinned set, takes up in storage
3811
4000
  * right now. Conversations, answers and scoring, and the training rows of a
3812
- * pipeline's curated sets, are kept in storage only, never in the database. Not billed; it counts toward the workspace's storage
3813
- * quota and is deleted with the pipeline (a benchmark's with the workspace).
3814
- * `where` is null while nothing is stored.
4001
+ * pipeline's curated sets, are kept in storage only, never in the database.
4002
+ * Only the part of a pipeline's figure kept in the platform's storage is ever
4003
+ * billed, as Conscious Loop storage at the storage rate with no daily minimum
4004
+ * (each day's cost is added up and charged once it reaches a whole cent), and
4005
+ * only where `billed` says so; deleting the pipeline stops it. The part in the
4006
+ * workspace's own storage and the index in the database never are, and
4007
+ * neither is a benchmark's pinned set, which is kept until the workspace is
4008
+ * deleted (`billed` is always false on a benchmark). It counts toward the
4009
+ * workspace's storage quota and is deleted with the pipeline (a benchmark's
4010
+ * with the workspace). `where` is null while nothing is stored.
3815
4011
  */
3816
4012
  export type LoopStorageWhere = 'platform' | 'your_storage' | 'both';
3817
4013
  export interface LoopStorage {
3818
4014
  bytes: number;
3819
4015
  objects: number;
3820
4016
  where: LoopStorageWhere | null;
4017
+ /**
4018
+ * True when part of a pipeline's figure is in the platform's storage and
4019
+ * this environment charges for that; false while nothing of it is charged
4020
+ * (all of it in the workspace's own storage, nothing stored, an environment
4021
+ * that only measures it for now, or a benchmark's pinned set, which is never
4022
+ * billed).
4023
+ */
4024
+ billed: boolean;
3821
4025
  }
3822
4026
  /**
3823
4027
  * The frozen definition: the oracle, the scoring rule and the fingerprint of
@@ -4255,8 +4459,9 @@ export interface PipelineActiveRun {
4255
4459
  /** What it has been billed so far, in cents. */
4256
4460
  cost_cents: number;
4257
4461
  /**
4258
- * True when a comparison machine was charged in `cost_cents`: the figure is
4259
- * the most it can have cost, so show it as "up to".
4462
+ * True when a comparison machine was charged in `cost_cents` and billing
4463
+ * has not settled it yet: the figure is the most it can have cost, so show
4464
+ * it as "up to".
4260
4465
  */
4261
4466
  cost_up_to: boolean;
4262
4467
  /** See {@link TrainingRun.comparison_returned_cents}. */
@@ -4277,6 +4482,14 @@ export interface PipelineActiveRun {
4277
4482
  * not a version, and becomes one only if a member promotes it.
4278
4483
  */
4279
4484
  competed: boolean;
4485
+ /** See {@link PipelineAttempt.sample_scoring_cents}. */
4486
+ sample_scoring_cents?: number;
4487
+ /** See {@link PipelineAttempt.sample_scored}. */
4488
+ sample_scored?: number;
4489
+ /** See {@link PipelineAttempt.sample_picked}. */
4490
+ sample_picked?: number;
4491
+ /** See {@link PipelineAttempt.train_rows_by_judge}. */
4492
+ train_rows_by_judge?: number | null;
4280
4493
  }
4281
4494
  /**
4282
4495
  * One version: an attempt that was put live -- promoted by the pipeline's
@@ -4342,12 +4555,22 @@ export interface PipelineVersion {
4342
4555
  * True when `cost_cents` is the most the version can have cost rather than
4343
4556
  * what it did: its comparison machines at their ceilings
4344
4557
  * (`cost_includes_candidate_ceiling`), or one charged (counted from its
4345
- * first boot, where the platform bills from its first answer). Show it as
4346
- * "up to".
4558
+ * first boot, where the platform bills from its first answer). A version's
4559
+ * own new-model machine is the one that went live, and billing's settled
4560
+ * figure never replaces its charge, so a version whose machine was charged
4561
+ * stays "up to". Show it as "up to".
4347
4562
  */
4348
4563
  cost_up_to: boolean;
4349
4564
  /** Machine time the attempt held (training and comparison); null when unknown. */
4350
4565
  gpu_seconds: number | null;
4566
+ /** See {@link PipelineAttempt.sample_scoring_cents}. */
4567
+ sample_scoring_cents?: number;
4568
+ /** See {@link PipelineAttempt.sample_scored}. */
4569
+ sample_scored?: number;
4570
+ /** See {@link PipelineAttempt.sample_picked}. */
4571
+ sample_picked?: number;
4572
+ /** See {@link PipelineAttempt.train_rows_by_judge}. */
4573
+ train_rows_by_judge?: number | null;
4351
4574
  created_at: string;
4352
4575
  /**
4353
4576
  * When this version's head-to-head started. The champion it faced is the
@@ -4430,6 +4653,26 @@ export interface PipelineAttempt {
4430
4653
  * verdict and error. See {@link AttemptExplanation}.
4431
4654
  */
4432
4655
  explanation: AttemptExplanation | null;
4656
+ /**
4657
+ * What the judge's scoring of unreviewed samples cost before this attempt
4658
+ * was made, in cents: already inside `cost_cents`, never on top of it. 0
4659
+ * when nothing was scored for it.
4660
+ */
4661
+ sample_scoring_cents?: number;
4662
+ /** How many unreviewed samples the judge scored for it. */
4663
+ sample_scored?: number;
4664
+ /** How many of those it picked (scored 0.8 or more). */
4665
+ sample_picked?: number;
4666
+ /**
4667
+ * How many of `train_rows` were samples the judge picked rather than ones a
4668
+ * person reviewed. Null on an attempt from before the judge picked samples.
4669
+ */
4670
+ train_rows_by_judge?: number | null;
4671
+ /**
4672
+ * What it trained on, as it was when its set was built: see
4673
+ * {@link TrainedOn}. Null when its set is gone.
4674
+ */
4675
+ trained_on?: TrainedOn | null;
4433
4676
  }
4434
4677
  /**
4435
4678
  * An attempt's outcome in plain words: `headline` ("Could not be tested"),
@@ -4552,9 +4795,13 @@ export interface PipelineHoldout {
4552
4795
  * rows it trains on plus the ones held back to judge it. `new_rows`: `needed`
4553
4796
  * usable samples the last trained attempt did not have, which is
4554
4797
  * `floors.new_samples` (1,000), however many rows that attempt trained on.
4555
- * `have`, `short` and `message` are
4556
- * measured on the detail only. There, after an attempt has trained, `short`
4557
- * is how many more new samples have to arrive: new samples fill the held-back
4798
+ * On the detail, `have`, `short` and `message` are measured: the samples
4799
+ * left once duplicates and conversations too long to train on are set aside.
4800
+ * On each pipeline of the list they are counted, not measured: `have` is the
4801
+ * count, and once it reaches `needed`, `short` is null (only the detail can
4802
+ * say how many of them can be trained on) and `message` says so. Get the
4803
+ * pipeline for the measured numbers. On the detail, after an attempt has
4804
+ * trained, `short` is how many more new samples have to arrive: new samples fill the held-back
4558
4805
  * set first, so after the held-back share is raised it can be more than
4559
4806
  * `needed` - `have`; and `have` is the new samples the next attempt would
4560
4807
  * train on, or the samples since that attempt when that count is what it
@@ -4567,6 +4814,44 @@ export interface PipelineMinimums {
4567
4814
  have: number | null;
4568
4815
  short: number | null;
4569
4816
  message: string | null;
4817
+ /**
4818
+ * How many of `have` are samples the judge picked rather than ones a person
4819
+ * reviewed (0 when none); `message` then says so in brackets.
4820
+ */
4821
+ picked_by_judge?: number;
4822
+ }
4823
+ /**
4824
+ * Where the pipeline's automatic scoring of unreviewed samples is:
4825
+ * - `scoring`: the judge is scoring samples nobody reviewed, newest first;
4826
+ * - `waiting`: the next attempt has what it needs, or the pipeline is paused
4827
+ * or can make no more versions;
4828
+ * - `idle`: nothing is left to score;
4829
+ * - `held`: the platform held it for now (`held_until` says until when, when
4830
+ * it knows);
4831
+ * - `off`: switched off on this pipeline.
4832
+ */
4833
+ export type PipelineAutoScoringStatus = 'scoring' | 'waiting' | 'idle' | 'held' | 'off';
4834
+ /**
4835
+ * The judge's scoring of the samples nobody reviewed. When the pipeline does
4836
+ * not yet have the samples its next attempt needs, the judge scores
4837
+ * unreviewed samples, newest first, with the rubric it tests attempts with;
4838
+ * one scoring 0.8 or more (`threshold`) is trained on like a sample marked
4839
+ * good, one below is not. A person's feedback always decides over it. What it
4840
+ * cost shows on the attempt it was for (`sample_scoring_cents`).
4841
+ *
4842
+ * `picked`, `below_bar` and `unscored` count the unreviewed samples of the
4843
+ * pipeline and add up to them. `message` is the service's own sentence: show
4844
+ * it as written.
4845
+ */
4846
+ export interface PipelineAutoScoring {
4847
+ enabled: boolean;
4848
+ status: PipelineAutoScoringStatus;
4849
+ threshold: number;
4850
+ picked: number;
4851
+ below_bar: number;
4852
+ unscored: number;
4853
+ held_until: string | null;
4854
+ message: string;
4570
4855
  }
4571
4856
  /**
4572
4857
  * The state of the live version's deployment:
@@ -4583,6 +4868,12 @@ export type PipelineLiveDeploymentStatus = 'serving' | 'starting' | 'stopped' |
4583
4868
  export interface PipelineLiveDeployment {
4584
4869
  status: PipelineLiveDeploymentStatus;
4585
4870
  checked_at: string;
4871
+ /**
4872
+ * The deployment the live version answers from, the one this check is
4873
+ * about: its id, to open it on Deployments. Absent from a service from
4874
+ * before it was sent.
4875
+ */
4876
+ deployment_id?: string;
4586
4877
  }
4587
4878
  /**
4588
4879
  * A rebuild on its way: a member deleted `conversations` conversations the
@@ -4629,6 +4920,31 @@ export interface Pipeline {
4629
4920
  own_tag: string | null;
4630
4921
  /** A conversation carrying ANY of these tags is this pipeline's data. */
4631
4922
  tags: string[];
4923
+ /**
4924
+ * The saved datasets it also trains on: a sample in any of them is its data
4925
+ * too, as a sample carrying one of its tags is. Absent from a service from
4926
+ * before datasets.
4927
+ */
4928
+ datasets?: PipelineDatasetRef[];
4929
+ /**
4930
+ * What narrows everything it trains on (its tags and its datasets alike).
4931
+ * Every field empty or null: nothing narrows it. See
4932
+ * {@link PipelineConditions}.
4933
+ */
4934
+ conditions?: PipelineConditions;
4935
+ /**
4936
+ * How many samples it has recorded, reviewed or not: its Samples list's
4937
+ * total (`listTraces({ pipeline })`). Not what it trains on: a bad sample,
4938
+ * one nobody reviewed yet and a held-back one are counted here too.
4939
+ */
4940
+ samples_total?: number;
4941
+ /** How many of `samples_total` were recorded in the last 48 hours. */
4942
+ samples_recent?: number;
4943
+ /**
4944
+ * The judge's scoring of its unreviewed samples. Null where the platform
4945
+ * does not score samples. See {@link PipelineAutoScoring}.
4946
+ */
4947
+ auto_scoring?: PipelineAutoScoring | null;
4632
4948
  /**
4633
4949
  * The calls sent with `X-Loop-Pipeline` in the last `days` days that were
4634
4950
  * not recorded: under this pipeline's tags (an answer too large to keep, or
@@ -4776,6 +5092,19 @@ export interface TrainingRunResponse {
4776
5092
  verdict_checks_withheld: VerdictChecksWithheld | null;
4777
5093
  /** What the attempt has cost, part by part, from the charges recorded on it. */
4778
5094
  cost: TrainingRunCost;
5095
+ /**
5096
+ * What became of the attempt in plain words: the same object its row on
5097
+ * the pipeline's attempts carries ({@link PipelineAttempt.explanation}), so
5098
+ * an attempt older than the latest a pipeline carries still says it. Null
5099
+ * for a run that is not a numbered attempt; absent from a service from
5100
+ * before it was sent.
5101
+ */
5102
+ explanation?: AttemptExplanation | null;
5103
+ /**
5104
+ * True when this service lists an attempt's own samples
5105
+ * (`listTraces({ attempt, split })`). Absent from a service that cannot.
5106
+ */
5107
+ traces_filter_attempt?: boolean;
4779
5108
  }
4780
5109
  /** Why a run detail's `verdict_checks` is withheld. */
4781
5110
  export type VerdictChecksWithheld = 'decided_under_earlier_rule';
@@ -4828,6 +5157,13 @@ export interface TrainingRunCost {
4828
5157
  comparison_cents: number;
4829
5158
  scoring_cents: number;
4830
5159
  benchmark_cents: number;
5160
+ /**
5161
+ * What the judge's scoring of unreviewed samples cost before the attempt
5162
+ * was made ({@link PipelineAttempt.sample_scoring_cents}): a part of
5163
+ * `total_cents` like the others. Absent from a service from before it was
5164
+ * sent.
5165
+ */
5166
+ sample_scoring_cents?: number;
4831
5167
  total_cents: number;
4832
5168
  up_to: boolean;
4833
5169
  /**
@@ -4944,6 +5280,30 @@ export interface PipelineWriteRequest {
4944
5280
  } | null;
4945
5281
  /** More tags whose conversations the pipeline trains on. On an edit the list replaces the old one. */
4946
5282
  tags?: string[];
5283
+ /**
5284
+ * The saved datasets (`listDatasets`) it also trains on, by id, at most 32.
5285
+ * Absent leaves them; `[]` takes every one off; a list replaces them. A
5286
+ * change applies from the next attempt: nothing is trained again, and
5287
+ * versions already made keep what they learned.
5288
+ */
5289
+ datasets?: string[];
5290
+ /**
5291
+ * What narrows everything it trains on. Absent leaves them; null clears
5292
+ * them; an object replaces them. `feedback`, when set, must include `good`
5293
+ * or `corrected` (refused 400 otherwise). A sample the judge picked has no
5294
+ * feedback from a person, so it counts as `unreviewed` here: a list without
5295
+ * `unreviewed` trains only on samples a person reviewed. A change applies
5296
+ * from the next attempt, as for `datasets`.
5297
+ */
5298
+ conditions?: PipelineConditionsWrite | null;
5299
+ /**
5300
+ * The judge's scoring of unreviewed samples: on by default.
5301
+ * `{ enabled: false }` trains only on samples a person reviewed. No other
5302
+ * key is taken. It is not a training change: nothing is asked again.
5303
+ */
5304
+ auto_scoring?: {
5305
+ enabled: boolean;
5306
+ };
4947
5307
  /**
4948
5308
  * The schedule to wait for, beside the platform's fixed sample minimum.
4949
5309
  * There is no `min_samples`: the minimums are fixed, and a body that sends
@@ -5072,7 +5432,7 @@ export interface RuleBenchmark {
5072
5432
  benchmark_status: string;
5073
5433
  item_count: number;
5074
5434
  items_digest: string;
5075
- /** How it scores an answer: a scoring model reading its rubric (`judge`) or an exact check against its right answer (`exact`). */
5435
+ /** How it scores an answer: the judge reading its rubric (`judge`) or an exact check against its right answer (`exact`). */
5076
5436
  check: BenchmarkCheck;
5077
5437
  /** What its pinned set takes up in storage now: the figure the benchmark itself carries, this workspace's alone. */
5078
5438
  storage: LoopStorage;
@@ -5227,7 +5587,7 @@ export type AttemptDirection = 'higher' | 'lower' | 'same';
5227
5587
  export interface AttemptHoldout {
5228
5588
  evaluation_id: string | null;
5229
5589
  status: EvaluationStatus | null;
5230
- /** The scoring model its comparison froze when it opened; null for an attempt never compared. */
5590
+ /** The judge its comparison froze when it opened; null for an attempt never compared. */
5231
5591
  judge_model: string | null;
5232
5592
  rows_scored: number | null;
5233
5593
  wins: number | null;
@@ -5263,7 +5623,7 @@ export interface AttemptCompareSide {
5263
5623
  * The held-back conversations both attempts were scored on (`rows`), matched
5264
5624
  * by the conversation they came from.
5265
5625
  *
5266
- * `comparable` says both were scored the same way: the same scoring model and
5626
+ * `comparable` says both were scored the same way: the same judge and
5267
5627
  * the same rubric, both recorded. When not, `why` says so, naming both scoring
5268
5628
  * models, and `higher`, `lower`, `same`, `a` and `b` are null: the two scores
5269
5629
  * are not on one scale. `answer_changed` counts the conversations whose right
@@ -5382,3 +5742,191 @@ export type PipelineImportParams = Omit<LoopImportParams, 'source'> & {
5382
5742
  source?: string;
5383
5743
  default_feedback?: 'good';
5384
5744
  };
5745
+ /**
5746
+ * The feedback words a dataset or a pipeline's conditions select by, read as
5747
+ * the Samples list reads them: the deciding feedback from a person. A sample
5748
+ * no person gave feedback on is `unreviewed`, whether or not the judge scored
5749
+ * it.
5750
+ */
5751
+ export type LoopDatasetFeedback = 'good' | 'corrected' | 'bad' | 'unreviewed';
5752
+ /** Where a sample came from: your app (`captured`) or an imported file (`imported`). */
5753
+ export type LoopSampleOrigin = 'captured' | 'imported';
5754
+ /**
5755
+ * Samples counted by the feedback a person gave them, in the Samples list's
5756
+ * words: a dataset's or a preview's (they add up to its `samples`) and the
5757
+ * workspace's on `stats` (they add up to `traces`).
5758
+ */
5759
+ export interface LoopFeedbackCounts {
5760
+ good: number;
5761
+ corrected: number;
5762
+ bad: number;
5763
+ unreviewed: number;
5764
+ }
5765
+ /** A pipeline, named: one that trains on a dataset, or that a dataset was taken off. */
5766
+ export interface LoopDatasetPipelineRef {
5767
+ rule_id: string;
5768
+ name: string;
5769
+ }
5770
+ /**
5771
+ * A saved dataset (`GET /api/loop/datasets/{id}`). Every condition is
5772
+ * optional and they all hold together; a dataset with none is every sample in
5773
+ * the workspace.
5774
+ */
5775
+ export interface LoopDataset {
5776
+ id: string;
5777
+ name: string;
5778
+ /** The tags it selects by; a tag selects its child tags too. May be empty. */
5779
+ tags: string[];
5780
+ /** `any`: a sample carrying at least one of `tags`; `all`: every one. `any` when `tags` is empty. */
5781
+ match: 'any' | 'all';
5782
+ /** The feedback words it keeps; empty keeps every sample. */
5783
+ feedback: LoopDatasetFeedback[];
5784
+ origin: LoopSampleOrigin | null;
5785
+ /** The model that answered, exactly. */
5786
+ model: string | null;
5787
+ /** When a sample was recorded, RFC 3339, both ends included. */
5788
+ from: string | null;
5789
+ to: string | null;
5790
+ /** Moves on every edit; send it back as `expected_revision`. */
5791
+ revision: number;
5792
+ /** How many samples it selects now: the same number `listTraces({ dataset })` totals. */
5793
+ samples: number;
5794
+ feedback_counts: LoopFeedbackCounts;
5795
+ /** How many of `samples` are in a benchmark, and so are never trained on. */
5796
+ in_benchmarks: number;
5797
+ /** The pipelines that train on it. */
5798
+ used_by: LoopDatasetPipelineRef[];
5799
+ created_at: string;
5800
+ updated_at: string;
5801
+ }
5802
+ /**
5803
+ * The body of `updateDataset`: every field optional. Unknown keys are refused
5804
+ * 400 naming them. An absent key is left as it is, null clears `origin`,
5805
+ * `model`, `from` and `to`, and `[]` clears `tags` and `feedback`.
5806
+ * `createDataset` takes {@link LoopDatasetCreate}.
5807
+ */
5808
+ export interface LoopDatasetWrite {
5809
+ /** 1 to 80 characters, unique in the workspace whatever its case (409 `DATASET_NAME_TAKEN`). */
5810
+ name?: string;
5811
+ /** At most 32. */
5812
+ tags?: string[];
5813
+ match?: 'any' | 'all';
5814
+ feedback?: LoopDatasetFeedback[];
5815
+ origin?: LoopSampleOrigin | null;
5816
+ /** 1 to 200 characters. */
5817
+ model?: string | null;
5818
+ /** RFC 3339; `from` may not be after `to`. */
5819
+ from?: string | null;
5820
+ to?: string | null;
5821
+ /** An edit's compare-and-set: refused 409 `REVISION_MISMATCH` when the dataset moved on. */
5822
+ expected_revision?: number;
5823
+ }
5824
+ /**
5825
+ * The body of `createDataset`: a `name`, which the service always needs, and
5826
+ * any of the conditions. There is no revision to compare against yet.
5827
+ */
5828
+ export type LoopDatasetCreate = Omit<LoopDatasetWrite, 'name' | 'expected_revision'> & {
5829
+ name: string;
5830
+ };
5831
+ /**
5832
+ * What `previewDataset` counts: a dataset's conditions without its name, and
5833
+ * `datasets`, saved datasets whose samples are added (as a pipeline adds
5834
+ * them), so a pipeline's tags, datasets and conditions can be counted in one
5835
+ * call before they are saved.
5836
+ */
5837
+ export interface LoopDatasetPreviewParams {
5838
+ tags?: string[];
5839
+ match?: 'any' | 'all';
5840
+ feedback?: LoopDatasetFeedback[];
5841
+ origin?: LoopSampleOrigin | null;
5842
+ model?: string | null;
5843
+ from?: string | null;
5844
+ to?: string | null;
5845
+ datasets?: string[];
5846
+ }
5847
+ /** One model that answered samples of a preview, and how many. */
5848
+ export interface LoopDatasetPreviewModel {
5849
+ model: string;
5850
+ samples: number;
5851
+ }
5852
+ /**
5853
+ * The counts a preview answers. They are before duplicates and conversations
5854
+ * too long to train on are set aside, which only an attempt does: a
5855
+ * pipeline's own `minimums` are the exact training numbers.
5856
+ */
5857
+ export interface LoopDatasetPreview {
5858
+ samples: number;
5859
+ feedback_counts: LoopFeedbackCounts;
5860
+ in_benchmarks: number;
5861
+ /** The 20 models that answered most of `samples`, most first. */
5862
+ models: LoopDatasetPreviewModel[];
5863
+ }
5864
+ export interface LoopDatasetListParams {
5865
+ /** 50 when absent; at most 200. */
5866
+ limit?: number;
5867
+ offset?: number;
5868
+ }
5869
+ /** A page of the workspace's datasets, the most recently changed first. */
5870
+ export interface LoopDatasetListResponse {
5871
+ datasets: LoopDataset[];
5872
+ total: number;
5873
+ limit: number;
5874
+ offset: number;
5875
+ }
5876
+ /**
5877
+ * `deleteDataset`: the samples stay; `removed_from` names every pipeline
5878
+ * that stops training on its samples from its next attempt.
5879
+ */
5880
+ export interface LoopDatasetDeleteResponse {
5881
+ deleted: boolean;
5882
+ removed_from: LoopDatasetPipelineRef[];
5883
+ }
5884
+ /** A dataset a pipeline trains on, by id and name. */
5885
+ export interface PipelineDatasetRef {
5886
+ id: string;
5887
+ name: string;
5888
+ }
5889
+ /**
5890
+ * What narrows everything a pipeline trains on: the feedback words it keeps
5891
+ * (empty keeps every one), where samples came from, the model that answered,
5892
+ * and when they were recorded. A pipeline's tags are its `tags` field, never a
5893
+ * condition.
5894
+ */
5895
+ export interface PipelineConditions {
5896
+ feedback: LoopDatasetFeedback[];
5897
+ origin: LoopSampleOrigin | null;
5898
+ model: string | null;
5899
+ from: string | null;
5900
+ to: string | null;
5901
+ }
5902
+ /** The conditions a pipeline create or edit sends: an object replaces them whole. */
5903
+ export interface PipelineConditionsWrite {
5904
+ feedback?: LoopDatasetFeedback[];
5905
+ origin?: LoopSampleOrigin | null;
5906
+ model?: string | null;
5907
+ from?: string | null;
5908
+ to?: string | null;
5909
+ }
5910
+ /** A dataset as an attempt trained on it: its conditions at the revision it had then. */
5911
+ export interface TrainedOnDataset {
5912
+ id: string;
5913
+ name: string;
5914
+ revision: number;
5915
+ tags: string[];
5916
+ match: 'any' | 'all';
5917
+ feedback: LoopDatasetFeedback[];
5918
+ origin: LoopSampleOrigin | null;
5919
+ model: string | null;
5920
+ from: string | null;
5921
+ to: string | null;
5922
+ }
5923
+ /**
5924
+ * What an attempt trained on, read from its own set as it was built, never
5925
+ * from today's settings: the pipeline's tags, its conditions, and each
5926
+ * dataset as it was then. A later edit of a dataset never changes it.
5927
+ */
5928
+ export interface TrainedOn {
5929
+ tags: string[];
5930
+ conditions: PipelineConditions;
5931
+ datasets: TrainedOnDataset[];
5932
+ }