runbios-sdk 0.4.0-rc.337 → 0.5.0-dev.338

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;
@@ -3094,6 +3094,14 @@ export interface LoopMetricPoint {
3094
3094
  benchmark_spent_cents: number;
3095
3095
  /** Scoring the samples nobody reviewed, in the passes the attempt took when it was booked. */
3096
3096
  sample_scoring_cents?: number;
3097
+ /**
3098
+ * The run priced as its attempt row prices it (`cost_cents` on
3099
+ * {@link PipelineAttempt}), so the points add up to the pipeline's
3100
+ * `totals.spent_cents`; `cost_up_to` true means it is the most it can have
3101
+ * cost: say "at most". Absent from a service from before they were sent.
3102
+ */
3103
+ cost_cents?: number;
3104
+ cost_up_to?: boolean;
3097
3105
  evaluation_id: string | null;
3098
3106
  rows_scored: number | null;
3099
3107
  rows_failed: number | null;
@@ -3223,8 +3231,9 @@ export type TrainingRulePausedReason = 'consent_invalid' | 'insufficient_funds'
3223
3231
  /**
3224
3232
  * Why a run fired, as the run stores it: `rows` (enough new samples),
3225
3233
  * `cadence` (the schedule), `both`, `manual` (train now), `challenger` (the
3226
- * pipeline's challenger model, trained from its own base on every sample the
3227
- * attempt before it could train on), `rebuild` (a member deleted a
3234
+ * pipeline's second model on the same samples as the attempt before it: built
3235
+ * on its own latest version, or from its original model on every sample while
3236
+ * it has none), `rebuild` (a member deleted a
3228
3237
  * conversation the live version learned from, so the model is trained again
3229
3238
  * from the base on every remaining sample), or `variant` (a recipe variant,
3230
3239
  * retired: the same base model on the same conversations with one training
@@ -3237,15 +3246,19 @@ export type TrainingTrigger = 'rows' | 'cadence' | 'both' | 'manual' | 'variant'
3237
3246
  * side of an attempt comparison.
3238
3247
  *
3239
3248
  * `trained_from` is `versions` when the attempt trained a new adapter on top
3240
- * of the live version: the pipeline's pinned base with the versions in
3241
- * `built_on` (oldest first) merged into it in that order. It is `base` when
3242
- * it started from the base model, and `from_base_reason` says why:
3243
- * `first_version`, `challenger` (the second model never builds on another
3244
- * model's versions), `rebuild` (a deleted conversation, with `rebuild` true;
3245
- * or, with `rebuild` false, a live version already built on 64 versions, the
3246
- * most one attempt can build on), `model_cannot_build_on` or
3247
- * `chain_link_unreadable` (an earlier version could not be read). Null when
3248
- * it built on versions.
3249
+ * of its model's own latest version -- the live one, or, while the other
3250
+ * model's version is live, its own -- the pipeline's pinned base with the
3251
+ * versions in `built_on` (oldest first) merged into it in that order. Each
3252
+ * model keeps its own line: neither builds on the other's versions. It is
3253
+ * `base` when it started from its original model, and `from_base_reason` says
3254
+ * why: `first_version`, `challenger` (the second model has no version of its
3255
+ * own yet), `rebuild` (a deleted conversation, with `rebuild` true; or, with
3256
+ * `rebuild` false, its own latest version already built on 64 versions, the
3257
+ * most one attempt can build on, so its line starts again),
3258
+ * `model_cannot_build_on`, `chain_link_unreadable` (an earlier version could
3259
+ * not be read) or `line_learned_deleted` (a version of its own line learned a
3260
+ * sample a member deleted, so its line starts again without it). Null when it
3261
+ * built on versions.
3249
3262
  *
3250
3263
  * What it trained on (`train_rows`) is `new_samples` (new since the attempt
3251
3264
  * before it) + `carried_samples` (trained by the attempts in
@@ -3278,7 +3291,7 @@ export interface Lineage {
3278
3291
  learned_before: number | null;
3279
3292
  rebuild: boolean;
3280
3293
  learned_deleted_conversation: boolean;
3281
- from_base_reason: 'first_version' | 'challenger' | 'rebuild' | 'model_cannot_build_on' | 'chain_link_unreadable' | null;
3294
+ from_base_reason: 'first_version' | 'challenger' | 'rebuild' | 'model_cannot_build_on' | 'chain_link_unreadable' | 'line_learned_deleted' | null;
3282
3295
  }
3283
3296
  /**
3284
3297
  * The four training settings a recipe variant may change, as the run was
@@ -3380,6 +3393,16 @@ export interface TrainingRunRejectRequest {
3380
3393
  export interface TrainingRunRollbackRequest {
3381
3394
  reason?: string;
3382
3395
  }
3396
+ /**
3397
+ * The machine codes `retestTrainingRun` can be refused with, beside the ones
3398
+ * Train now answers (`PIPELINE_NEEDS_SAVE`, `RULE_PAUSED`, `RUN_ACTIVE`,
3399
+ * `MONTHLY_LIMIT_REACHED`, `AGENT_OFF`, `SCORING_CAPPED`).
3400
+ *
3401
+ * - `CANNOT_TEST_AGAIN` (409): the training cannot be tested again; the
3402
+ * message says why (already tested, went live, never finished training,
3403
+ * still under way, the amount set aside for testing it spent, ...).
3404
+ */
3405
+ export type TrainingRunRetestRefusalCode = 'CANNOT_TEST_AGAIN' | 'PIPELINE_NEEDS_SAVE' | 'RULE_PAUSED' | 'RUN_ACTIVE' | 'MONTHLY_LIMIT_REACHED' | 'AGENT_OFF' | 'SCORING_CAPPED';
3383
3406
  /**
3384
3407
  * The machine codes `rollbackTrainingRun` can be refused with.
3385
3408
  *
@@ -3436,6 +3459,11 @@ export interface TrainingRun {
3436
3459
  seq: number;
3437
3460
  rule_revision: number;
3438
3461
  trigger: TrainingTrigger;
3462
+ /**
3463
+ * Which of the pipeline's models it trained: `main`, or `second` for the
3464
+ * second model (trigger `challenger`). Absent from an older service.
3465
+ */
3466
+ model_role?: PipelineModelRole;
3439
3467
  /**
3440
3468
  * For a recipe variant, what it changed, in plain words ("half the learning
3441
3469
  * rate"). Null for every run that trained on the ordinary recipe.
@@ -3465,6 +3493,12 @@ export interface TrainingRun {
3465
3493
  * training started; nothing was charged and the next attempt asks again).
3466
3494
  * `STEP_STALLED:TRAINING_SERVICE_BEHIND` is the same for one that waited
3467
3495
  * six hours for that update; the pipeline tries again on its own.
3496
+ * `STEP_STALLED:SERVING_NOT_CERTIFIED`: the platform had not yet checked
3497
+ * that it can test new versions of its model on the current serving engine,
3498
+ * so it waited six hours before its training and stood down; nothing was
3499
+ * charged, the pipeline is not paused, and its next training waits the same
3500
+ * way until that check is done. `CHECKPOINT_NOT_DEPLOYABLE:SERVING_NOT_CERTIFIED`
3501
+ * is the same found at its comparison, after it trained.
3468
3502
  * `ENV_GATED:SWITCHED_OFF`: the Conscious Loop was switched off on the
3469
3503
  * platform before its training started, so it stopped there; no GPU time
3470
3504
  * was charged, and the pipeline trains again on its own once the loop is
@@ -3498,11 +3532,11 @@ export interface TrainingRun {
3498
3532
  */
3499
3533
  billed_candidate_up_to: boolean;
3500
3534
  /**
3501
- * What was taken off for comparison machines that never started (never
3502
- * reached running): the platform charged nothing for them, so neither does
3503
- * the attempt -- say "Comparison machine: not charged (it never started)",
3504
- * or, while a comparison machine that ran is still charged beside it, that
3505
- * the one that never started was not charged. 0 when none; the cost figures
3535
+ * What was taken off for test machines that never started (never reached
3536
+ * running): the platform charged nothing for them, so neither does the
3537
+ * training -- say "Test machine: not charged (it never started)", or, while
3538
+ * a test machine that ran is still charged beside it, that the one that
3539
+ * never started was not charged. 0 when none; the cost figures
3506
3540
  * beside it are already net of it.
3507
3541
  */
3508
3542
  comparison_returned_cents: number;
@@ -3554,6 +3588,13 @@ export interface TrainingRun {
3554
3588
  * before it was sent.
3555
3589
  */
3556
3590
  trained_on?: TrainedOn | null;
3591
+ /**
3592
+ * Whether its comparison measured anything: at least one question of its
3593
+ * automatic test scored, or a benchmark that stood in for it published a
3594
+ * score. A training never tested can never go live (`NOT_TESTED`) and,
3595
+ * while its trained model is kept, can be tested again.
3596
+ */
3597
+ tested: boolean;
3557
3598
  candidate_deployment_id: string | null;
3558
3599
  candidate_name: string | null;
3559
3600
  candidate_seq: number;
@@ -3682,10 +3723,16 @@ export interface TrainingRunLinks {
3682
3723
  }
3683
3724
  /** What this reader may do right now. A button that cannot work is never shown. */
3684
3725
  export interface TrainingRunActions {
3726
+ /** Never for a training that was never tested: that answers NOT_TESTED. */
3685
3727
  promote: boolean;
3686
3728
  reject: boolean;
3687
3729
  rollback: boolean;
3688
3730
  cancel: boolean;
3731
+ /**
3732
+ * Test again ({@link LoopResource.retestTrainingRun}): a training that
3733
+ * trained and was never tested, whose trained model is kept.
3734
+ */
3735
+ retest: boolean;
3689
3736
  }
3690
3737
  export interface EvaluationRef {
3691
3738
  kind: ServingKind;
@@ -4290,6 +4337,85 @@ export interface BenchmarkHistoryParams {
4290
4337
  export interface BenchmarkRetireParams {
4291
4338
  reason?: string;
4292
4339
  }
4340
+ /** What `listBenchmarkQuestions` asks for. */
4341
+ export interface BenchmarkQuestionsParams {
4342
+ /** The pipeline whose trainings to show (its id, `rule_id`). Required: training numbers are per pipeline. */
4343
+ pipeline: string;
4344
+ /** How many of its newest trainings: 5 when absent, 1 to 20. */
4345
+ trainings?: number;
4346
+ /** Questions per page: 50 when absent; at most 200. */
4347
+ limit?: number;
4348
+ offset?: number;
4349
+ }
4350
+ /** One training whose results a benchmark's questions carry. */
4351
+ export interface BenchmarkQuestionsTraining {
4352
+ /** The training (`getTrainingRun(run_id)`). */
4353
+ run_id: string;
4354
+ /** Its number in its pipeline. */
4355
+ attempt: number | null;
4356
+ /** The version it became; null when it did not become one. */
4357
+ version: number | null;
4358
+ /** Its replay of this benchmark (`getBenchmarkRun`). */
4359
+ benchmark_run_id: string;
4360
+ /** That replay's status: anything but `done` scored only some questions. */
4361
+ status: BenchmarkRunStatus;
4362
+ }
4363
+ /** One training's result on one question; `passed` and `score` are null when it did not score it. */
4364
+ export interface BenchmarkQuestionResult {
4365
+ attempt: number | null;
4366
+ /** A score of 0.70 or more. */
4367
+ passed: boolean | null;
4368
+ score: number | null;
4369
+ }
4370
+ /** One pinned question, with every listed training's result on it, in the order of `trainings`. */
4371
+ export interface BenchmarkQuestion {
4372
+ item_id: number;
4373
+ ordinal: number;
4374
+ /** The last thing the user said in the pinned conversation (`listBenchmarkItems` has all of it). */
4375
+ question: string;
4376
+ /** The right answer's text, null when nobody gave one (or it is tool calls only: see `reference`). */
4377
+ right_answer: string | null;
4378
+ reference: EvaluationReference | null;
4379
+ results: BenchmarkQuestionResult[];
4380
+ }
4381
+ /** Every question of a benchmark with how one pipeline's newest trainings did on each, oldest training first. */
4382
+ export interface BenchmarkQuestionsResponse {
4383
+ benchmark_id: string;
4384
+ pipeline_id: string;
4385
+ trainings: BenchmarkQuestionsTraining[];
4386
+ items: BenchmarkQuestion[];
4387
+ /** How many questions the benchmark has. */
4388
+ total: number;
4389
+ limit: number;
4390
+ offset: number;
4391
+ }
4392
+ /** One step of a training's chart. */
4393
+ export interface TrainingCurvePoint {
4394
+ step: number;
4395
+ /** Its loss on the samples it trained on; null at a practice check the thinned series did not keep. */
4396
+ train_loss: number | null;
4397
+ /** Its loss on the practice questions it set aside and did not train on; null at a step it did not check. */
4398
+ check_loss: number | null;
4399
+ }
4400
+ /**
4401
+ * How a training went while it trained (`getTrainingCurve`): at most 200
4402
+ * points, every practice check among them, and the step whose model it kept.
4403
+ * No points and a plain `reason` when there is nothing to chart (no training
4404
+ * job yet, or it never checked itself on practice questions).
4405
+ */
4406
+ export interface TrainingCurve {
4407
+ run_id: string;
4408
+ points: TrainingCurvePoint[];
4409
+ /** The step whose model it kept; null until it kept one. */
4410
+ kept_step: number | null;
4411
+ /** The steps it trained (so far, while it trains). */
4412
+ trained_steps: number | null;
4413
+ /** The steps it planned. */
4414
+ planned_steps: number | null;
4415
+ /** It keeps its last step, not the one that did best on the practice questions (a Gemma 4 training). */
4416
+ keeps_last: boolean;
4417
+ reason: string | null;
4418
+ }
4293
4419
  /**
4294
4420
  * The machine codes `runPipeline` (train now) can be refused with: every one
4295
4421
  * the run route answers (the SDK's tests read them off the service). Each is
@@ -4390,8 +4516,11 @@ export type TrainingRuleRunRefusalCode = 'NOT_ENOUGH_SAMPLES' | 'PIPELINE_NEEDS_
4390
4516
  * that meets it at fire time is paused `training_not_enabled` instead (see
4391
4517
  * {@link TrainingRulePausedReason}); switching it back on later starts it
4392
4518
  * again.
4393
- * - `METHOD_NOT_ENABLED` (422): the platform has switched off the training
4394
- * method pipelines train with.
4519
+ * - `METHOD_NOT_ENABLED` (422): the body asks for preference or reward
4520
+ * training -- a `training_method`, `rlhf_type`, `method` or `algorithm`
4521
+ * naming rlhf, dpo, kto, grpo or the like, at the top or under `training` --
4522
+ * which is not available yet (the message says so in one sentence), or the
4523
+ * platform has switched off the training method pipelines train with.
4395
4524
  * - `CEILING_TOO_LOW` (422): the platform's own runaway limits cannot cover
4396
4525
  * the machines it chose for the model. Nothing in the request sets them.
4397
4526
  * - `MODELS_UNAVAILABLE`, `GPU_OPTIONS_UNAVAILABLE`, `AGENT_COULD_NOT_START`
@@ -4494,7 +4623,10 @@ export interface PipelineActiveRun {
4494
4623
  /**
4495
4624
  * One version: an attempt that was put live -- promoted by the pipeline's
4496
4625
  * rule or by a member. Only winners are versions, numbered v1, v2, ... in the
4497
- * order they went live; numbers only go up and a rollback renumbers nothing.
4626
+ * order they went live; version numbers count up and a rollback renumbers
4627
+ * nothing (a later version can still score lower: a member may approve one).
4628
+ * Nothing untested goes live any more; `tested` says whether an older version
4629
+ * was tested.
4498
4630
  */
4499
4631
  export interface PipelineVersion {
4500
4632
  version: number;
@@ -4518,6 +4650,12 @@ export interface PipelineVersion {
4518
4650
  holdout_rows: number | null;
4519
4651
  /** What it was trained on top of, and on which samples. See {@link Lineage}. */
4520
4652
  lineage: Lineage;
4653
+ /**
4654
+ * Whether its comparison measured anything. Every version put live since
4655
+ * nothing untested goes live was; a rebuild put live untested before that
4656
+ * says false.
4657
+ */
4658
+ tested: boolean;
4521
4659
  /** Head-to-head against the champion of its day, on conversations neither trained on. */
4522
4660
  rows_scored: number | null;
4523
4661
  win_rate: number | null;
@@ -4595,12 +4733,42 @@ export interface PipelineVersion {
4595
4733
  */
4596
4734
  /**
4597
4735
  * Why an attempt was made: new data (`data`, a recipe variant included), the
4598
- * schedule (`schedule`), a member's train-now (`manual`), the challenger
4599
- * model trained from its own base on all samples (`challenger`), or a rebuild
4600
- * from the base after a member deleted a conversation the live version
4601
- * learned from (`rebuild`).
4736
+ * schedule (`schedule`), a member's train-now (`manual`), the second model on
4737
+ * the same samples (`challenger`: it builds on its own latest version, or
4738
+ * trains from its original model on all samples while it has none), or a
4739
+ * rebuild from the base after a member deleted a conversation the live
4740
+ * version learned from (`rebuild`).
4602
4741
  */
4603
4742
  export type PipelineAttemptTrigger = 'data' | 'schedule' | 'manual' | 'challenger' | 'rebuild';
4743
+ /**
4744
+ * Which of a pipeline's models an attempt trained. Each model keeps its own
4745
+ * line of versions: each builds on its own latest version, never the other's,
4746
+ * and each training that wins becomes the next version, in turn.
4747
+ */
4748
+ export type PipelineModelRole = 'main' | 'second';
4749
+ /** Where a pipeline's second model stands (`second_model` on a pipeline). */
4750
+ export type PipelineSecondModelState = 'waiting' | 'training' | 'tested' | 'skipped' | 'held' | 'none';
4751
+ /**
4752
+ * Where a pipeline's second model stands: `training` (a training of it is
4753
+ * under way), `tested` (its training on the main model's newest samples was
4754
+ * tested), `skipped` (it did not train on them, and will not -- reason says
4755
+ * why), `held` (it is owed a training and a money limit, a scoring key, a
4756
+ * live version that cannot answer or a paused pipeline holds it), `waiting`
4757
+ * (it trains next, or after the main model's next training), `none` (the
4758
+ * pipeline trains neither model now). A skipped set is never a training.
4759
+ */
4760
+ export interface PipelineSecondModel {
4761
+ model_id: string;
4762
+ state: PipelineSecondModelState;
4763
+ /** The training the state is about; null when it waits for the main model's next training. */
4764
+ for_training: number | null;
4765
+ /** Its newest training that ended, in either role. */
4766
+ last_training: number | null;
4767
+ /** Its own latest version, which it builds on next; null when it trains from its original. */
4768
+ own_latest_version: number | null;
4769
+ /** The state in one plain sentence. */
4770
+ reason: string | null;
4771
+ }
4604
4772
  /**
4605
4773
  * What became of an attempt. `inconclusive` is a held-back test that ran and
4606
4774
  * could not decide; `not_tested` is an attempt that ended before it was tested
@@ -4613,6 +4781,13 @@ export interface PipelineAttempt {
4613
4781
  run_id: string;
4614
4782
  state: TrainingRunState;
4615
4783
  trigger: PipelineAttemptTrigger;
4784
+ /**
4785
+ * Which of the pipeline's models it trained: `main`, or `second` for its
4786
+ * second model (trigger `challenger`) -- the role it had when it trained,
4787
+ * and the words of `model=` on `listPipelineAttempts`. Absent from an older
4788
+ * service.
4789
+ */
4790
+ model_role?: PipelineModelRole;
4616
4791
  base_model_id: string | null;
4617
4792
  model_family: string | null;
4618
4793
  outcome: PipelineAttemptOutcome;
@@ -4673,9 +4848,46 @@ export interface PipelineAttempt {
4673
4848
  * {@link TrainedOn}. Null when its set is gone.
4674
4849
  */
4675
4850
  trained_on?: TrainedOn | null;
4851
+ /** The version it was built on; null when it trained from the original model. */
4852
+ builds_on_version?: number | null;
4853
+ /**
4854
+ * What its automatic test asked as the opponent, recorded when the test
4855
+ * opened: `compared_with` is `version` (then `compared_with_version` is
4856
+ * the version), `original` (the original model, while no version was live)
4857
+ * or null (not tested, or nothing recorded which). These four are absent
4858
+ * from a service from before they were sent.
4859
+ */
4860
+ compared_with_version?: number | null;
4861
+ compared_with?: PipelineComparedWith | null;
4862
+ /**
4863
+ * For `not_better` and `inconclusive`, the first bar its automatic test
4864
+ * missed; null otherwise, and when the bars do not explain the verdict.
4865
+ */
4866
+ missed_bar?: AttemptMissedBar | null;
4867
+ /**
4868
+ * Whether its comparison measured anything. A training never tested can
4869
+ * never go live (`NOT_TESTED`) and, while its trained model is kept, can be
4870
+ * tested again ({@link LoopResource.retestTrainingRun}).
4871
+ */
4872
+ tested: boolean;
4873
+ }
4874
+ /** What a training's automatic test asked as its opponent. */
4875
+ export type PipelineComparedWith = 'version' | 'original';
4876
+ /**
4877
+ * The first bar a training's automatic test missed: `key` is the bar
4878
+ * (`rows_scored`, `failures`, `rubric`, `mean_change`, `win_rate` or
4879
+ * `beyond_chance`, as {@link VerdictCheck.key}), `what` says it and what the
4880
+ * training got in plain words, and `needed` and `got` are on the bar's own
4881
+ * scale (null where it has none).
4882
+ */
4883
+ export interface AttemptMissedBar {
4884
+ key: string;
4885
+ what: string;
4886
+ needed: number | null;
4887
+ got: number | null;
4676
4888
  }
4677
4889
  /**
4678
- * An attempt's outcome in plain words: `headline` ("Could not be tested"),
4890
+ * An attempt's outcome in plain words: `headline` ("Couldn't be tested"),
4679
4891
  * `detail` (what happened and why) and `next` (what happens now; null when
4680
4892
  * there is nothing to say).
4681
4893
  */
@@ -4955,11 +5167,14 @@ export interface Pipeline {
4955
5167
  */
4956
5168
  capture: LoopCaptureHealth | null;
4957
5169
  /**
4958
- * A second base model, trained from its own base on all samples after each
4959
- * attempt (it never builds on this pipeline's versions, which are another
4960
- * model); it becomes the next version only if it beats the live one, and then it
5170
+ * A second model, a different one from the main model, trained on the same
5171
+ * samples after each training of the main model: each model keeps its own
5172
+ * line of versions, so it builds on its own latest version (never the main
5173
+ * model's), or from its original model on all samples while it has none.
5174
+ * Whichever does better becomes the next version; a winning second model
4961
5175
  * becomes the pipeline's model (`base_model_id`) while the model it replaced
4962
- * becomes this one. `revision` is the commit the server pinned.
5176
+ * becomes this one. `revision` is the commit the server pinned. Where it
5177
+ * stands is `second_model`.
4963
5178
  */
4964
5179
  challenger_model: PipelineModelRef | null;
4965
5180
  train_when: PipelineTrainWhen;
@@ -4989,6 +5204,13 @@ export interface Pipeline {
4989
5204
  live_deployment: PipelineLiveDeployment | null;
4990
5205
  /** The live version as the versions merged into it. See {@link PipelineChain}. */
4991
5206
  chain: PipelineChain | null;
5207
+ /**
5208
+ * Where the second model stands, and its own latest version. Null when the
5209
+ * pipeline names no second model -- and on the list only, also when where
5210
+ * it stands could not be read just then (`challenger_model` still names
5211
+ * it; the detail answers it or fails); absent from an older service.
5212
+ */
5213
+ second_model?: PipelineSecondModel | null;
4992
5214
  /** What the pipeline's history takes up in storage. */
4993
5215
  storage: LoopStorage;
4994
5216
  /** The name the app calls. It does not change when a version is promoted. */
@@ -5026,6 +5248,12 @@ export interface Pipeline {
5026
5248
  versions_total: number;
5027
5249
  /** How many attempts it has made; `attempts` holds only the latest of them. */
5028
5250
  attempts_total: number;
5251
+ /**
5252
+ * Every training it made, what became of them and what they cost in all,
5253
+ * on `listPipelines` and `getPipeline` alike. See {@link PipelineTotals}.
5254
+ * Absent from a service from before it was sent.
5255
+ */
5256
+ totals?: PipelineTotals;
5029
5257
  /** Winners only, v1 first: every one from `getPipeline`, the latest few and the live one on `listPipelines`. */
5030
5258
  versions: PipelineVersion[];
5031
5259
  /**
@@ -5035,6 +5263,83 @@ export interface Pipeline {
5035
5263
  */
5036
5264
  attempts: PipelineAttempt[];
5037
5265
  }
5266
+ /**
5267
+ * A pipeline's trainings, all of them. `spent_cents` is every attempt's
5268
+ * `cost_cents` added up (one price for both, so paging through every attempt
5269
+ * gives exactly `spent_cents - scoring_not_yet_in_a_training_cents`) plus the
5270
+ * scoring of unreviewed samples no training has taken yet, and `spent_parts`
5271
+ * adds up to it. Say it by both flags together: neither -> "$X";
5272
+ * `spent_up_to` only -> "at most $X" (at least one part is an upper bound);
5273
+ * `spent_so_far` only -> "$X so far" (the figure can still grow); both ->
5274
+ * "at most $X so far". Training and testing only: the live version's serving
5275
+ * is billed on its deployment.
5276
+ */
5277
+ export interface PipelineTotals {
5278
+ /** Every numbered attempt, running ones included (= `attempts_total`). */
5279
+ trainings: number;
5280
+ trainings_finished: number;
5281
+ /**
5282
+ * Trainings that trained a model and are no longer running, whose
5283
+ * automatic test graded nothing and that no benchmark scored.
5284
+ */
5285
+ trainings_untested: number;
5286
+ /** By outcome, each training once (`running` excludes `waiting_for_review`). */
5287
+ trainings_by_result: PipelineTrainingsByResult;
5288
+ trainings_by_model: PipelineTrainingsByModel;
5289
+ /** How many became versions (= `versions_total`). */
5290
+ versions: number;
5291
+ spent_cents: number;
5292
+ /**
5293
+ * True when at least one part of `spent_cents` is an upper bound (an
5294
+ * attempt's `cost_up_to`): say "at most", with "so far" too when
5295
+ * `spent_so_far` is also true ("at most $X so far").
5296
+ */
5297
+ spent_up_to: boolean;
5298
+ /**
5299
+ * True while `spent_cents` can still change: a training is running or
5300
+ * waiting for a member, billing has not yet settled a finished one's
5301
+ * training time, or a scoring pass is still running. Say "so far" -- "$X
5302
+ * so far", or "at most $X so far" when `spent_up_to` is also true. Never
5303
+ * "at most" for this flag alone: the figure is still growing.
5304
+ */
5305
+ spent_so_far: boolean;
5306
+ /**
5307
+ * What scoring the samples nobody reviewed cost that no training has taken
5308
+ * yet (the next training takes it when it starts). It is in `spent_cents`
5309
+ * and in `spent_parts.sample_scoring_cents`; no attempt row carries it.
5310
+ */
5311
+ scoring_not_yet_in_a_training_cents: number;
5312
+ spent_parts: PipelineSpentParts;
5313
+ /** Every training's GPU time added up; 0 when none was recorded. */
5314
+ gpu_seconds: number;
5315
+ /** When the first and the latest training were made; null before the first. */
5316
+ first_training_at: string | null;
5317
+ last_training_at: string | null;
5318
+ }
5319
+ /** {@link PipelineTotals.trainings} by outcome. */
5320
+ export interface PipelineTrainingsByResult {
5321
+ became_version: number;
5322
+ not_better: number;
5323
+ inconclusive: number;
5324
+ not_tested: number;
5325
+ stopped: number;
5326
+ failed: number;
5327
+ running: number;
5328
+ waiting_for_review: number;
5329
+ }
5330
+ /** {@link PipelineTotals.trainings} by the model they trained. */
5331
+ export interface PipelineTrainingsByModel {
5332
+ main: number;
5333
+ second: number;
5334
+ }
5335
+ /** {@link PipelineTotals.spent_cents} part by part; the parts add up to it. */
5336
+ export interface PipelineSpentParts {
5337
+ training_cents: number;
5338
+ test_machine_cents: number;
5339
+ grading_cents: number;
5340
+ benchmark_cents: number;
5341
+ sample_scoring_cents: number;
5342
+ }
5038
5343
  export interface TrainingRuleDeleteResponse {
5039
5344
  deleted: boolean;
5040
5345
  rule_id: string;
@@ -5100,6 +5405,19 @@ export interface TrainingRunResponse {
5100
5405
  * before it was sent.
5101
5406
  */
5102
5407
  explanation?: AttemptExplanation | null;
5408
+ /**
5409
+ * The attempt row's {@link PipelineAttempt.model_role},
5410
+ * `builds_on_version`, `compared_with_version`, `compared_with` and
5411
+ * `missed_bar`: which model it trained, what it built on, what its
5412
+ * automatic test asked and the first bar a training that was not better
5413
+ * missed. `model_role` is "" for a run that is not a numbered attempt.
5414
+ * Absent from a service from before they were sent.
5415
+ */
5416
+ model_role?: PipelineModelRole | '';
5417
+ builds_on_version?: number | null;
5418
+ compared_with_version?: number | null;
5419
+ compared_with?: PipelineComparedWith | null;
5420
+ missed_bar?: AttemptMissedBar | null;
5103
5421
  /**
5104
5422
  * True when this service lists an attempt's own samples
5105
5423
  * (`listTraces({ attempt, split })`). Absent from a service that cannot.
@@ -5167,8 +5485,8 @@ export interface TrainingRunCost {
5167
5485
  total_cents: number;
5168
5486
  up_to: boolean;
5169
5487
  /**
5170
- * What was taken off `comparison_cents` for comparison machines that never
5171
- * started: "Comparison machine: not charged (it never started)" (with
5488
+ * What was taken off `comparison_cents` for test machines that never
5489
+ * started: "Test machine: not charged (it never started)" (with
5172
5490
  * `comparison_cents` above 0, only the one that never started). 0 when
5173
5491
  * none.
5174
5492
  */
@@ -5387,7 +5705,8 @@ export interface PipelineFloors {
5387
5705
  * The held-back rule: a pipeline holds back max(`min_rows`, its percent of its
5388
5706
  * samples), and chooses the percent from `default_percent` to `max_percent`
5389
5707
  * (the body's `holdout.percent`). Each attempt is judged on at most
5390
- * `scored_rows` of them (the same ones every time); a share that holds back
5708
+ * `scored_rows` of them (the ones held back longest first, so later trainings
5709
+ * are mostly asked the same questions); a share that holds back
5391
5710
  * more than that only keeps samples out of training.
5392
5711
  */
5393
5712
  export interface HeldBackFloors {
@@ -5519,6 +5838,12 @@ export interface PromotionOutcome {
5519
5838
  decided_by: string;
5520
5839
  reason: string;
5521
5840
  auto_promote_allowed: boolean;
5841
+ /**
5842
+ * Why a better version waits for a member instead of going live by itself:
5843
+ * a benchmark with no score for it, or one it got significantly worse on,
5844
+ * named. Absent otherwise.
5845
+ */
5846
+ held_for_review?: string;
5522
5847
  weighted_delta: number | null;
5523
5848
  measurements: PromotionMeasurement[];
5524
5849
  }
@@ -5530,6 +5855,30 @@ export interface VersionHoldout {
5530
5855
  /** The share each side passed (score 0.70 or more). */
5531
5856
  incumbent_pass_rate: number | null;
5532
5857
  candidate_pass_rate: number | null;
5858
+ /**
5859
+ * The share of the response's `common_set` this version got right (score
5860
+ * 0.70 or more), over `common_rows`, the questions of that set its own test
5861
+ * graded against the same right answer: one fixed set for every version,
5862
+ * so these may be drawn as one line across versions. `common_rows` can
5863
+ * differ between versions: a question a test could not grade, or a sample
5864
+ * deleted or past its retention before a later version's test, is not in
5865
+ * that version's count -- "every version answered the same N questions"
5866
+ * holds only when every version's `common_rows` is N. Null when its test
5867
+ * graded none of them, and absent from a service from before they were sent.
5868
+ */
5869
+ common_pass_rate?: number | null;
5870
+ common_rows?: number | null;
5871
+ }
5872
+ /**
5873
+ * The fixed questions every version's `holdout.common_pass_rate` is measured
5874
+ * on: the samples held back before the first version that was tested (`from`,
5875
+ * "samples held back before v1"), each once, at most 1,500, read from the
5876
+ * answers already stored -- kept after the samples themselves are deleted or
5877
+ * expire. `rows` 0 and `from` null while no version was tested.
5878
+ */
5879
+ export interface VersionCommonSet {
5880
+ rows: number;
5881
+ from: string | null;
5533
5882
  }
5534
5883
  /** One version with every measurement it has. */
5535
5884
  export interface VersionScores {
@@ -5543,7 +5892,38 @@ export interface VersionScores {
5543
5892
  verdict: string | null;
5544
5893
  decision: string | null;
5545
5894
  compared_at: string | null;
5895
+ /**
5896
+ * Whether its comparison measured anything, as on {@link PipelineVersion.tested}:
5897
+ * nothing untested goes live any more; a rebuild put live untested before
5898
+ * that says false.
5899
+ */
5900
+ tested: boolean;
5546
5901
  holdout: VersionHoldout;
5902
+ /**
5903
+ * When it first went live; whether it answers the pipeline's name now;
5904
+ * whether it was rolled back. This field and the eleven after it are absent
5905
+ * from a service from before they were sent.
5906
+ */
5907
+ promoted_at?: string;
5908
+ is_live?: boolean;
5909
+ rolled_back?: boolean;
5910
+ /** The model it was trained from, and which of the pipeline's models that was. */
5911
+ model_id?: string | null;
5912
+ model_role?: PipelineModelRole;
5913
+ /** Its training's cost, "at most" flag and GPU time, as its attempt row says them. */
5914
+ cost_cents?: number;
5915
+ cost_up_to?: boolean;
5916
+ gpu_seconds?: number | null;
5917
+ /**
5918
+ * What its training trained on, and the samples it learned that no version
5919
+ * it builds on had (new plus carried from trainings that did not become a
5920
+ * version; null on a training from before those were counted).
5921
+ */
5922
+ train_rows?: number | null;
5923
+ learned_new?: number | null;
5924
+ /** What its automatic test asked as the opponent, as on {@link PipelineAttempt}. */
5925
+ compared_with_version?: number | null;
5926
+ compared_with?: PipelineComparedWith | null;
5547
5927
  /** One entry per entry of the response's `benchmarks`, in the same order. */
5548
5928
  benchmarks: VersionBenchmarkScore[];
5549
5929
  promotion: PromotionOutcome | null;
@@ -5566,6 +5946,8 @@ export interface VersionCompareResponse {
5566
5946
  a: number | null;
5567
5947
  b: number | null;
5568
5948
  differences: VersionScoreDifference[];
5949
+ /** The fixed questions `holdout.common_pass_rate` is measured on; absent from a service from before it was sent. */
5950
+ common_set?: VersionCommonSet;
5569
5951
  }
5570
5952
  /** Which two versions to set side by side, by VERSION number (v1 is 1). */
5571
5953
  export interface VersionCompareParams {
@@ -5796,9 +6178,85 @@ export interface LoopDataset {
5796
6178
  in_benchmarks: number;
5797
6179
  /** The pipelines that train on it. */
5798
6180
  used_by: LoopDatasetPipelineRef[];
6181
+ /** Who saved it; null for a dataset saved before that was recorded. */
6182
+ created_by: LoopDatasetCreator | null;
6183
+ /**
6184
+ * The trainings that learned from it, newest first, at most 50: every
6185
+ * numbered training whose own set took this dataset and that kept a model,
6186
+ * or is still training. One that ended without learning anything (stopped
6187
+ * before it trained) is not listed. Read from each training's set, not from
6188
+ * today's settings.
6189
+ */
6190
+ learned_by: LoopDatasetLearnedBy[];
6191
+ /** How many trainings learned from it in all (`learned_by` lists at most 50). */
6192
+ learned_by_total: number;
5799
6193
  created_at: string;
5800
6194
  updated_at: string;
5801
6195
  }
6196
+ /** The member who saved a dataset. */
6197
+ export interface LoopDatasetCreator {
6198
+ id: string;
6199
+ /** Their name (or email) as the platform has it; null when it could not be looked up just now. */
6200
+ name: string | null;
6201
+ }
6202
+ /** One training that learned from a dataset. */
6203
+ export interface LoopDatasetLearnedBy {
6204
+ pipeline_id: string;
6205
+ pipeline_name: string;
6206
+ /** The training (`getTrainingRun(run_id)`). */
6207
+ run_id: string;
6208
+ /** Its number in its pipeline. */
6209
+ attempt: number;
6210
+ /** The version it became; null when it did not become one. */
6211
+ version: number | null;
6212
+ }
6213
+ /** What `exportDataset` asks for. */
6214
+ export interface LoopDatasetExportParams {
6215
+ /** `jsonl`, the default and the only format. */
6216
+ format?: 'jsonl';
6217
+ /** At most this many samples, oldest first; every one when absent. */
6218
+ limit?: number;
6219
+ }
6220
+ /**
6221
+ * One line of an exported dataset: one sample in the import's chat format,
6222
+ * so the file imports again (`importRows`) with its feedback. A sample with
6223
+ * an answer is `messages`, the answer last; one nobody answered is its
6224
+ * question, `prompt`. The feedback a person gave is in the import's words:
6225
+ * Good is `label: true`, Wrong `label: false`, Wrong + right answer
6226
+ * `correction`; a right answer given as the gold answer, or written on a
6227
+ * question nobody answered, is `ground_truth`. No feedback writes none of
6228
+ * them.
6229
+ */
6230
+ export interface LoopDatasetExportLine {
6231
+ /** The sample's id; the import does not read it. */
6232
+ sample_id: string;
6233
+ /** The conversation, the model's answer last; absent for a question nobody answered. */
6234
+ messages?: LoopMessage[];
6235
+ /** A question nobody answered: the conversation so far, with `ground_truth` when a person gave its right answer. */
6236
+ prompt?: LoopMessage[];
6237
+ /** The tools the conversation offered, as recorded. */
6238
+ tools?: unknown;
6239
+ /** The model that answered. */
6240
+ model?: string;
6241
+ label?: boolean;
6242
+ correction?: string;
6243
+ ground_truth?: string;
6244
+ }
6245
+ /**
6246
+ * An exported dataset. `jsonl` is the file exactly as sent (one line a
6247
+ * sample, nothing else); `lines` is each line parsed. A sample whose text
6248
+ * could not be read (kept in the workspace's own storage and refused just
6249
+ * now, or gone) is left out: `stored_elsewhere` is how many of the dataset's
6250
+ * samples have no conversation kept with them on the platform -- kept in your
6251
+ * own storage, or none at all -- which is the most that can be left out (0:
6252
+ * none can be). The exact count left out is the response's `X-Loop-Skipped`
6253
+ * HTTP trailer, which `fetch` does not expose.
6254
+ */
6255
+ export interface LoopDatasetExport {
6256
+ jsonl: string;
6257
+ lines: LoopDatasetExportLine[];
6258
+ stored_elsewhere: number | null;
6259
+ }
5802
6260
  /**
5803
6261
  * The body of `updateDataset`: every field optional. Unknown keys are refused
5804
6262
  * 400 naming them. An absent key is left as it is, null clears `origin`,
@@ -5862,6 +6320,8 @@ export interface LoopDatasetPreview {
5862
6320
  models: LoopDatasetPreviewModel[];
5863
6321
  }
5864
6322
  export interface LoopDatasetListParams {
6323
+ /** Only the datasets whose name contains this, whatever its case (at most 80 characters). */
6324
+ q?: string;
5865
6325
  /** 50 when absent; at most 200. */
5866
6326
  limit?: number;
5867
6327
  offset?: number;