@toloka-platform/sdk 0.1.0 → 0.2.0-preview.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (294) hide show
  1. package/README.md +2 -2
  2. package/dist/cli/toloka.js +138 -136
  3. package/dist/cli/toloka.js.jsc +0 -0
  4. package/dist/cli/toloka.js.jsc.sha256 +1 -1
  5. package/dist/cli/toloka.js.sha256 +1 -1
  6. package/docs/cli-v2.md +1 -1
  7. package/docs/cli.md +3 -1
  8. package/docs/getting-started.md +1 -1
  9. package/docs/limitations.md +2 -2
  10. package/docs/testing.md +1 -1
  11. package/examples/face-image-collection/README.md +1 -1
  12. package/openapi/gen/api.ts +1482 -777
  13. package/openapi/gen/models/createDatasetExportBody.ts +5 -3
  14. package/openapi/gen/models/createDatasetExportBodyFormat.ts +2 -0
  15. package/openapi/gen/models/createProjectTrainingBody.ts +6 -0
  16. package/openapi/gen/models/createTrainingRunBody.ts +6 -0
  17. package/openapi/gen/models/datasetExportReportTokens.ts +4 -1
  18. package/openapi/gen/models/datasetExportReportTokensEstimatorVersion.ts +2 -0
  19. package/openapi/gen/models/datasetExportReportTokensTotal.ts +2 -0
  20. package/openapi/gen/models/estimateTrainingCostBody.ts +5 -0
  21. package/openapi/gen/models/exportJob.ts +2 -0
  22. package/openapi/gen/models/exportJobError.ts +3 -0
  23. package/openapi/gen/models/exportJobErrorAnyOf.ts +7 -0
  24. package/openapi/gen/models/exportJobErrorAnyOfCode.ts +2 -0
  25. package/openapi/gen/models/exportJobStatus.ts +1 -1
  26. package/openapi/gen/models/generationNodeSettingsAudienceAndPricingOneOfOneoneGenerationModelId.ts +1 -1
  27. package/openapi/gen/models/generationNodeSettingsQualityAssuranceOneOfFourLlmQaModelId.ts +1 -1
  28. package/openapi/gen/models/generationNodeSettingsQualityAssuranceOneOfLlmQaModelId.ts +1 -1
  29. package/openapi/gen/models/getTrainingRunLogsParams.ts +5 -0
  30. package/openapi/gen/models/gistingTrainingConfiguration.ts +13 -0
  31. package/openapi/gen/models/gistingTrainingConfigurationInput.ts +13 -0
  32. package/openapi/gen/models/gistingTrainingConfigurationInputRegime.ts +2 -0
  33. package/openapi/gen/models/gistingTrainingConfigurationRegime.ts +2 -0
  34. package/openapi/gen/models/index.ts +230 -16
  35. package/openapi/gen/models/listProjectTrainings200.ts +7 -0
  36. package/openapi/gen/models/listProjectTrainingsParams.ts +5 -0
  37. package/openapi/gen/models/listTrainingRuns200.ts +7 -0
  38. package/openapi/gen/models/listTrainingRunsParams.ts +5 -0
  39. package/openapi/gen/models/modelVersion.ts +6 -1
  40. package/openapi/gen/models/modelVersionContent.ts +4 -0
  41. package/openapi/gen/models/modelVersionContentDownload.ts +11 -0
  42. package/openapi/gen/models/modelVersionContentDownloadContent.ts +4 -0
  43. package/openapi/gen/models/modelVersionContentDownloadContentOneOf.ts +10 -0
  44. package/openapi/gen/models/modelVersionContentDownloadContentOneOfManifestItem.ts +8 -0
  45. package/openapi/gen/models/modelVersionContentDownloadContentOneOfManifestItemMediaType.ts +2 -0
  46. package/openapi/gen/models/modelVersionContentDownloadContentOneOfNine.ts +8 -0
  47. package/openapi/gen/models/modelVersionContentDownloadContentOneOfNineManifestItem.ts +8 -0
  48. package/openapi/gen/models/modelVersionContentDownloadContentOneOfNineManifestItemMediaType.ts +2 -0
  49. package/openapi/gen/models/modelVersionContentDownloadContentOneOfNineRuntimeBase.ts +2 -0
  50. package/openapi/gen/models/modelVersionContentDownloadContentOneOfParent.ts +4 -0
  51. package/openapi/gen/models/modelVersionContentDownloadContentOneOfParentOneOf.ts +6 -0
  52. package/openapi/gen/models/modelVersionContentDownloadContentOneOfParentOneOfBaseModelId.ts +2 -0
  53. package/openapi/gen/models/modelVersionContentDownloadContentOneOfParentOneOfThree.ts +5 -0
  54. package/openapi/gen/models/modelVersionContentDownloadContentOneOfRuntimeBase.ts +2 -0
  55. package/openapi/gen/models/modelVersionContentDownloadFilesItem.ts +9 -0
  56. package/openapi/gen/models/modelVersionContentDownloadFilesItemMediaType.ts +2 -0
  57. package/openapi/gen/models/modelVersionContentOneOf.ts +10 -0
  58. package/openapi/gen/models/modelVersionContentOneOfManifestItem.ts +8 -0
  59. package/openapi/gen/models/modelVersionContentOneOfManifestItemMediaType.ts +2 -0
  60. package/openapi/gen/models/modelVersionContentOneOfNine.ts +8 -0
  61. package/openapi/gen/models/modelVersionContentOneOfNineManifestItem.ts +8 -0
  62. package/openapi/gen/models/modelVersionContentOneOfNineManifestItemMediaType.ts +2 -0
  63. package/openapi/gen/models/modelVersionContentOneOfNineRuntimeBase.ts +2 -0
  64. package/openapi/gen/models/modelVersionContentOneOfParent.ts +4 -0
  65. package/openapi/gen/models/modelVersionContentOneOfParentOneOf.ts +6 -0
  66. package/openapi/gen/models/modelVersionContentOneOfParentOneOfBaseModelId.ts +2 -0
  67. package/openapi/gen/models/modelVersionContentOneOfParentOneOfThree.ts +5 -0
  68. package/openapi/gen/models/modelVersionContentOneOfRuntimeBase.ts +2 -0
  69. package/openapi/gen/models/modelVersionProducer.ts +5 -0
  70. package/openapi/gen/models/pipelineGraphSnapshotGraphNodesItemOneOfOnefoursevenSettingsQualityAssuranceOneOfLlmQaModelId.ts +1 -1
  71. package/openapi/gen/models/pipelineGraphSnapshotGraphNodesItemOneOfThreeoneSettingsAudienceAndPricingOneOfOneoneGenerationModelId.ts +1 -1
  72. package/openapi/gen/models/pipelineGraphSnapshotGraphNodesItemOneOfThreeoneSettingsQualityAssuranceOneOfFourLlmQaModelId.ts +1 -1
  73. package/openapi/gen/models/pipelineGraphSnapshotGraphNodesItemOneOfThreeoneSettingsQualityAssuranceOneOfLlmQaModelId.ts +1 -1
  74. package/openapi/gen/models/prepareTrainingCostEstimateInputsBody.ts +2 -0
  75. package/openapi/gen/models/quorumNodeSettingsQualityAssuranceOneOfLlmQaModelId.ts +1 -1
  76. package/openapi/gen/models/replaceTrainingConfigurationBody.ts +5 -0
  77. package/openapi/gen/models/sftTrainingConfiguration.ts +13 -0
  78. package/openapi/gen/models/sftTrainingConfigurationInput.ts +13 -0
  79. package/openapi/gen/models/sftTrainingConfigurationInputRegime.ts +2 -0
  80. package/openapi/gen/models/sftTrainingConfigurationRegime.ts +2 -0
  81. package/openapi/gen/models/training.ts +16 -0
  82. package/openapi/gen/models/trainingArchivedAt.ts +2 -0
  83. package/openapi/gen/models/trainingConfiguration.ts +4 -0
  84. package/openapi/gen/models/trainingConfigurationInput.ts +4 -0
  85. package/openapi/gen/models/trainingCostEstimate.ts +4 -0
  86. package/openapi/gen/models/trainingCostEstimateInputSet.ts +12 -0
  87. package/openapi/gen/models/trainingCostEstimateInputSetExports.ts +6 -0
  88. package/openapi/gen/models/trainingCostEstimateInputSetExportsValidation.ts +2 -0
  89. package/openapi/gen/models/trainingCostEstimateInputSetId.ts +2 -0
  90. package/openapi/gen/models/trainingCostEstimateOneOf.ts +16 -0
  91. package/openapi/gen/models/trainingCostEstimateOneOfInputs.ts +7 -0
  92. package/openapi/gen/models/trainingCostEstimateOneOfInputsTraining.ts +9 -0
  93. package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingFailure.ts +3 -0
  94. package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingFailureAnyOf.ts +7 -0
  95. package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingFailureAnyOfCode.ts +2 -0
  96. package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingReport.ts +3 -0
  97. package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingReportAnyOf.ts +9 -0
  98. package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingReportAnyOfErrorsItem.ts +5 -0
  99. package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingReportAnyOfTokens.ts +10 -0
  100. package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingReportAnyOfTokensEstimatorVersion.ts +2 -0
  101. package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingReportAnyOfTokensTotal.ts +2 -0
  102. package/openapi/gen/models/trainingCostEstimateOneOfInputsValidation.ts +3 -0
  103. package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOf.ts +9 -0
  104. package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfFailure.ts +3 -0
  105. package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfFailureAnyOf.ts +7 -0
  106. package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfFailureAnyOfCode.ts +2 -0
  107. package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfReport.ts +3 -0
  108. package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfReportAnyOf.ts +9 -0
  109. package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfReportAnyOfErrorsItem.ts +5 -0
  110. package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfReportAnyOfTokens.ts +10 -0
  111. package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfReportAnyOfTokensEstimatorVersion.ts +2 -0
  112. package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfReportAnyOfTokensTotal.ts +2 -0
  113. package/openapi/gen/models/trainingCostEstimateOneOfIssuesItem.ts +8 -0
  114. package/openapi/gen/models/trainingCostEstimateOneOfIssuesItemCode.ts +2 -0
  115. package/openapi/gen/models/trainingCostEstimateOneOfIssuesItemPurpose.ts +2 -0
  116. package/openapi/gen/models/trainingCostEstimateOneOfTwoseven.ts +23 -0
  117. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenBudget.ts +9 -0
  118. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputs.ts +7 -0
  119. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTraining.ts +9 -0
  120. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingFailure.ts +3 -0
  121. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingFailureAnyOf.ts +7 -0
  122. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingFailureAnyOfCode.ts +2 -0
  123. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingReport.ts +3 -0
  124. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingReportAnyOf.ts +9 -0
  125. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingReportAnyOfErrorsItem.ts +5 -0
  126. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingReportAnyOfTokens.ts +10 -0
  127. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingReportAnyOfTokensEstimatorVersion.ts +2 -0
  128. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingReportAnyOfTokensTotal.ts +2 -0
  129. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidation.ts +3 -0
  130. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOf.ts +9 -0
  131. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfFailure.ts +3 -0
  132. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfFailureAnyOf.ts +7 -0
  133. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfFailureAnyOfCode.ts +2 -0
  134. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfReport.ts +3 -0
  135. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfReportAnyOf.ts +9 -0
  136. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfReportAnyOfErrorsItem.ts +5 -0
  137. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfReportAnyOfTokens.ts +10 -0
  138. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfReportAnyOfTokensEstimatorVersion.ts +2 -0
  139. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfReportAnyOfTokensTotal.ts +2 -0
  140. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenIssuesItem.ts +8 -0
  141. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenIssuesItemCode.ts +2 -0
  142. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenIssuesItemPurpose.ts +2 -0
  143. package/openapi/gen/models/trainingDatasetItemFilter.ts +8 -0
  144. package/openapi/gen/models/trainingDatasetItemFilterFieldSourcesItem.ts +6 -0
  145. package/openapi/gen/models/trainingDatasetItemFilterFieldSourcesItemSourcesItem.ts +4 -0
  146. package/openapi/gen/models/trainingDatasetItemFilterFieldSourcesItemSourcesItemOneOf.ts +5 -0
  147. package/openapi/gen/models/trainingDatasetItemFilterFieldSourcesItemSourcesItemOneOfTwo.ts +5 -0
  148. package/openapi/gen/models/trainingDatasetItemFilterFieldValuesItem.ts +12 -0
  149. package/openapi/gen/models/trainingDatasetItemFilterFieldValuesItemOperator.ts +2 -0
  150. package/openapi/gen/models/trainingDatasetItemFilterFieldValuesItemSourcesItem.ts +4 -0
  151. package/openapi/gen/models/trainingDatasetItemFilterFieldValuesItemSourcesItemOneOf.ts +5 -0
  152. package/openapi/gen/models/trainingDatasetItemFilterFieldValuesItemSourcesItemOneOfTwo.ts +5 -0
  153. package/openapi/gen/models/trainingDatasetItemFilterFieldValuesItemValue.ts +2 -0
  154. package/openapi/gen/models/trainingDatasetItemFilterInput.ts +8 -0
  155. package/openapi/gen/models/trainingDatasetItemFilterInputFieldSourcesItem.ts +6 -0
  156. package/openapi/gen/models/trainingDatasetItemFilterInputFieldSourcesItemSourcesItem.ts +4 -0
  157. package/openapi/gen/models/trainingDatasetItemFilterInputFieldSourcesItemSourcesItemOneOf.ts +5 -0
  158. package/openapi/gen/models/trainingDatasetItemFilterInputFieldSourcesItemSourcesItemOneOfTwo.ts +5 -0
  159. package/openapi/gen/models/trainingDatasetItemFilterInputFieldValuesItem.ts +12 -0
  160. package/openapi/gen/models/trainingDatasetItemFilterInputFieldValuesItemOperator.ts +2 -0
  161. package/openapi/gen/models/trainingDatasetItemFilterInputFieldValuesItemSourcesItem.ts +4 -0
  162. package/openapi/gen/models/trainingDatasetItemFilterInputFieldValuesItemSourcesItemOneOf.ts +5 -0
  163. package/openapi/gen/models/trainingDatasetItemFilterInputFieldValuesItemSourcesItemOneOfTwo.ts +5 -0
  164. package/openapi/gen/models/trainingDatasetItemFilterInputFieldValuesItemValue.ts +2 -0
  165. package/openapi/gen/models/trainingDatasetSelection.ts +6 -0
  166. package/openapi/gen/models/trainingDatasetSelectionInput.ts +6 -0
  167. package/openapi/gen/models/trainingId.ts +2 -0
  168. package/openapi/gen/models/trainingModelId.ts +3 -0
  169. package/openapi/gen/models/trainingModelSource.ts +4 -0
  170. package/openapi/gen/models/trainingModelSourceOneOf.ts +6 -0
  171. package/openapi/gen/models/trainingModelSourceOneOfBaseModelId.ts +2 -0
  172. package/openapi/gen/models/trainingModelSourceOneOfThree.ts +5 -0
  173. package/openapi/gen/models/trainingRun.ts +39 -0
  174. package/openapi/gen/models/trainingRunBillingStatus.ts +2 -0
  175. package/openapi/gen/models/trainingRunBlockedReason.ts +2 -0
  176. package/openapi/gen/models/trainingRunChargedAmount.ts +2 -0
  177. package/openapi/gen/models/trainingRunError.ts +3 -0
  178. package/openapi/gen/models/trainingRunErrorAnyOf.ts +7 -0
  179. package/openapi/gen/models/trainingRunErrorAnyOfCode.ts +2 -0
  180. package/openapi/gen/models/trainingRunId.ts +2 -0
  181. package/openapi/gen/models/trainingRunInputs.ts +3 -0
  182. package/openapi/gen/models/trainingRunInputsAnyOf.ts +7 -0
  183. package/openapi/gen/models/trainingRunInputsAnyOfTraining.ts +15 -0
  184. package/openapi/gen/models/trainingRunInputsAnyOfTrainingContract.ts +2 -0
  185. package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilter.ts +9 -0
  186. package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldSourcesItem.ts +6 -0
  187. package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldSourcesItemSourcesItem.ts +4 -0
  188. package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldSourcesItemSourcesItemOneOf.ts +5 -0
  189. package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldSourcesItemSourcesItemOneOfTwo.ts +5 -0
  190. package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldValuesItem.ts +12 -0
  191. package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldValuesItemOperator.ts +2 -0
  192. package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldValuesItemSourcesItem.ts +4 -0
  193. package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldValuesItemSourcesItemOneOf.ts +5 -0
  194. package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldValuesItemSourcesItemOneOfTwo.ts +5 -0
  195. package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldValuesItemValue.ts +2 -0
  196. package/openapi/gen/models/trainingRunInputsAnyOfTrainingReport.ts +9 -0
  197. package/openapi/gen/models/trainingRunInputsAnyOfTrainingReportErrorsItem.ts +5 -0
  198. package/openapi/gen/models/trainingRunInputsAnyOfTrainingReportTokens.ts +10 -0
  199. package/openapi/gen/models/trainingRunInputsAnyOfTrainingReportTokensEstimatorVersion.ts +2 -0
  200. package/openapi/gen/models/trainingRunInputsAnyOfTrainingReportTokensTotal.ts +2 -0
  201. package/openapi/gen/models/trainingRunInputsAnyOfValidation.ts +3 -0
  202. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOf.ts +15 -0
  203. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfContract.ts +2 -0
  204. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilter.ts +9 -0
  205. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldSourcesItem.ts +6 -0
  206. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldSourcesItemSourcesItem.ts +4 -0
  207. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldSourcesItemSourcesItemOneOf.ts +5 -0
  208. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldSourcesItemSourcesItemOneOfTwo.ts +5 -0
  209. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldValuesItem.ts +12 -0
  210. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldValuesItemOperator.ts +2 -0
  211. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldValuesItemSourcesItem.ts +4 -0
  212. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldValuesItemSourcesItemOneOf.ts +5 -0
  213. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldValuesItemSourcesItemOneOfTwo.ts +5 -0
  214. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldValuesItemValue.ts +2 -0
  215. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfReport.ts +9 -0
  216. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfReportErrorsItem.ts +5 -0
  217. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfReportTokens.ts +10 -0
  218. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfReportTokensEstimatorVersion.ts +2 -0
  219. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfReportTokensTotal.ts +2 -0
  220. package/openapi/gen/models/trainingRunLogs.ts +9 -0
  221. package/openapi/gen/models/trainingRunLogsEntriesItem.ts +7 -0
  222. package/openapi/gen/models/trainingRunLogsEntriesItemLevel.ts +2 -0
  223. package/openapi/gen/models/trainingRunLogsNextCursor.ts +2 -0
  224. package/openapi/gen/models/trainingRunMessage.ts +2 -0
  225. package/openapi/gen/models/trainingRunOutputModelVersionRevision.ts +2 -0
  226. package/openapi/gen/models/trainingRunProgress.ts +3 -0
  227. package/openapi/gen/models/trainingRunProgressAnyOf.ts +10 -0
  228. package/openapi/gen/models/trainingRunProgressAnyOfMessage.ts +2 -0
  229. package/openapi/gen/models/trainingRunProgressAnyOfStep.ts +2 -0
  230. package/openapi/gen/models/trainingRunProgressAnyOfTotal.ts +2 -0
  231. package/openapi/gen/models/trainingRunQuote.ts +17 -0
  232. package/openapi/gen/models/trainingRunQuoteBudget.ts +9 -0
  233. package/openapi/gen/models/trainingRunQuoteInputs.ts +7 -0
  234. package/openapi/gen/models/trainingRunQuoteInputsTraining.ts +9 -0
  235. package/openapi/gen/models/trainingRunQuoteInputsTrainingFailure.ts +3 -0
  236. package/openapi/gen/models/trainingRunQuoteInputsTrainingFailureAnyOf.ts +7 -0
  237. package/openapi/gen/models/trainingRunQuoteInputsTrainingFailureAnyOfCode.ts +2 -0
  238. package/openapi/gen/models/trainingRunQuoteInputsTrainingReport.ts +3 -0
  239. package/openapi/gen/models/trainingRunQuoteInputsTrainingReportAnyOf.ts +9 -0
  240. package/openapi/gen/models/trainingRunQuoteInputsTrainingReportAnyOfErrorsItem.ts +5 -0
  241. package/openapi/gen/models/trainingRunQuoteInputsTrainingReportAnyOfTokens.ts +10 -0
  242. package/openapi/gen/models/trainingRunQuoteInputsTrainingReportAnyOfTokensEstimatorVersion.ts +2 -0
  243. package/openapi/gen/models/trainingRunQuoteInputsTrainingReportAnyOfTokensTotal.ts +2 -0
  244. package/openapi/gen/models/trainingRunQuoteInputsValidation.ts +3 -0
  245. package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOf.ts +9 -0
  246. package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfFailure.ts +3 -0
  247. package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfFailureAnyOf.ts +7 -0
  248. package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfFailureAnyOfCode.ts +2 -0
  249. package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfReport.ts +3 -0
  250. package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfReportAnyOf.ts +9 -0
  251. package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfReportAnyOfErrorsItem.ts +5 -0
  252. package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfReportAnyOfTokens.ts +10 -0
  253. package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfReportAnyOfTokensEstimatorVersion.ts +2 -0
  254. package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfReportAnyOfTokensTotal.ts +2 -0
  255. package/openapi/gen/models/trainingRunStatus.ts +2 -0
  256. package/openapi/gen/models/updateTrainingMetadataBody.ts +5 -0
  257. package/openapi/gen/models/validatePipelineGraphBodyGraphNodesItemOneOfOnefoursevenSettingsQualityAssuranceOneOfLlmQaModelId.ts +1 -1
  258. package/openapi/gen/models/validatePipelineGraphBodyGraphNodesItemOneOfThreeoneSettingsAudienceAndPricingOneOfOneoneGenerationModelId.ts +1 -1
  259. package/openapi/gen/models/validatePipelineGraphBodyGraphNodesItemOneOfThreeoneSettingsQualityAssuranceOneOfFourLlmQaModelId.ts +1 -1
  260. package/openapi/gen/models/validatePipelineGraphBodyGraphNodesItemOneOfThreeoneSettingsQualityAssuranceOneOfLlmQaModelId.ts +1 -1
  261. package/package.json +1 -1
  262. package/skills/catalog.json +19 -7
  263. package/skills/toloka-build/SKILL.md +3 -3
  264. package/skills/toloka-build/references/node-semantics.md +2 -1
  265. package/skills/toloka-build/references/workflow-and-cli.md +19 -2
  266. package/skills/toloka-report-issue/references/report-template.md +1 -1
  267. package/src/cli/auth.ts +1 -1
  268. package/src/cli/bin.ts +1 -1
  269. package/src/cli/cost.ts +1 -1
  270. package/src/cli/models.ts +107 -2
  271. package/src/cli/program.ts +243 -0
  272. package/src/cli/project-context.ts +9 -10
  273. package/src/cli/project.ts +2 -1
  274. package/src/cli/secrets.ts +4 -4
  275. package/src/cli/trainings.ts +627 -0
  276. package/src/client.ts +164 -30
  277. package/src/index.ts +2 -0
  278. package/src/pipeline-graph-v1.contract.json +16 -6
  279. package/openapi/gen/models/createDatasetExportBodyOneOf.ts +0 -6
  280. package/openapi/gen/models/createDatasetExportBodyOneOfFormat.ts +0 -2
  281. package/openapi/gen/models/createDatasetExportBodyOneOfThree.ts +0 -10
  282. package/openapi/gen/models/createDatasetExportBodyOneOfThreeContract.ts +0 -2
  283. package/openapi/gen/models/createDatasetExportBodyOneOfThreeFormat.ts +0 -2
  284. package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilter.ts +0 -9
  285. package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldSourcesItem.ts +0 -6
  286. package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldSourcesItemSourcesItem.ts +0 -4
  287. package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldSourcesItemSourcesItemOneOf.ts +0 -5
  288. package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldSourcesItemSourcesItemOneOfTwo.ts +0 -5
  289. package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldValuesItem.ts +0 -12
  290. package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldValuesItemOperator.ts +0 -2
  291. package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldValuesItemSourcesItem.ts +0 -4
  292. package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldValuesItemSourcesItemOneOf.ts +0 -5
  293. package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldValuesItemSourcesItemOneOfTwo.ts +0 -5
  294. package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldValuesItemValue.ts +0 -2
@@ -0,0 +1,627 @@
1
+ import { basename } from "node:path";
2
+ import { readFile, stat } from "node:fs/promises";
3
+
4
+ import { randomUUID } from "node:crypto";
5
+
6
+ import { assert } from "es-toolkit";
7
+
8
+ import type { PotatoClient, Training, TrainingCostEstimate, TrainingRun } from "../client";
9
+ import type { BaseModelId, TrainingConfigurationInput } from "../../openapi/gen/models";
10
+
11
+ type TrainingMethod = TrainingConfigurationInput["method"];
12
+ type TrainingSource = TrainingConfigurationInput["source"];
13
+ type TrainingSelection = Extract<TrainingConfigurationInput, { method: "sft" }>["training"];
14
+ type SftConfigurationInput = Extract<TrainingConfigurationInput, { method: "sft" }>;
15
+ type GistingConfigurationInput = Extract<TrainingConfigurationInput, { method: "gisting" }>;
16
+ type ResolvedSelections = Pick<SftConfigurationInput, "training" | "validation">;
17
+
18
+ export type TrainingDraftOptions = {
19
+ method?: TrainingMethod;
20
+ baseModelId?: BaseModelId;
21
+ modelVersionId?: string;
22
+ datasetId?: string;
23
+ validationDatasetId?: string;
24
+ trainingFilter?: string;
25
+ validationFilter?: string;
26
+ regime?: "low" | "medium" | "high";
27
+ epochs?: number;
28
+ evalSteps?: number;
29
+ promptFilePath?: string;
30
+ fetch?: typeof globalThis.fetch;
31
+ };
32
+
33
+ type TrainingApi = Pick<PotatoClient, "trainings">;
34
+ type TrainingDraftApi = Pick<PotatoClient, "trainings" | "files" | "datasets">;
35
+ type TrainingCostApi = Pick<PotatoClient, "trainings" | "waitFor">;
36
+ const GISTING_PROMPT_MAX_BYTES = 256 * 1024;
37
+ type TrainingIo = { readonly stdout: (text: string) => void };
38
+ type TableRow = readonly string[];
39
+
40
+ const formatTable = (rows: readonly TableRow[]): string => {
41
+ const widths = rows.reduce<number[]>(
42
+ (current, row) => row.map((cell, index) => Math.max(current[index] ?? 0, cell.length)),
43
+ [],
44
+ );
45
+ return rows
46
+ .map((row) =>
47
+ row
48
+ .map((cell, index) => cell.padEnd(widths[index] ?? cell.length))
49
+ .join(" ")
50
+ .trimEnd(),
51
+ )
52
+ .join("\n");
53
+ };
54
+
55
+ const writeOutput = (io: TrainingIo, json: boolean, value: unknown, formatted: string): void => {
56
+ io.stdout(json ? JSON.stringify(value, null, 2) : formatted);
57
+ };
58
+
59
+ const formatTraining = (training: Training): string =>
60
+ formatTable([
61
+ ["ID", training.id],
62
+ ["Project", training.projectId],
63
+ [
64
+ "Method",
65
+ training.configuration.method === "sft" ? "Supervised fine-tuning (SFT)" : "Prompt gisting",
66
+ ],
67
+ ["Output Model", training.modelId ?? "-"],
68
+ ["Archived at", training.archivedAt ?? "-"],
69
+ ["Created at", training.createdAt],
70
+ ["Updated at", training.updatedAt],
71
+ ]);
72
+
73
+ const formatTrainingRun = (run: TrainingRun): string =>
74
+ formatTable([
75
+ ["ID", run.id],
76
+ ["Training", run.trainingId],
77
+ ["Status", run.status],
78
+ ["Blocked reason", run.blockedReason ?? "-"],
79
+ ["Message", run.message ?? "-"],
80
+ ["Error code", run.error?.code ?? "-"],
81
+ ["Billing status", run.billingStatus],
82
+ [
83
+ "Charged amount",
84
+ run.chargedAmount === null ? "-" : `$${run.chargedAmount} ${run.quote.currency}`,
85
+ ],
86
+ [
87
+ "Progress",
88
+ run.progress
89
+ ? `${run.progress.phase}${run.progress.step === null ? "" : ` ${run.progress.step}${run.progress.total === null ? "" : `/${run.progress.total}`}`}`
90
+ : "-",
91
+ ],
92
+ ["Model Version name", run.outputModelVersionName],
93
+ [
94
+ "Model Version revision",
95
+ run.outputModelVersionRevision === null ? "-" : String(run.outputModelVersionRevision),
96
+ ],
97
+ ["Future Model Version", run.outputModelVersionId],
98
+ ["Maximum charge", `$${run.quote.maximumCharge} ${run.quote.currency}`],
99
+ ["Created at", run.createdAt],
100
+ ]);
101
+
102
+ type ReadyEstimateFile = {
103
+ status: "ready";
104
+ trainingId: string;
105
+ inputSetId: string;
106
+ fingerprint: string;
107
+ };
108
+
109
+ const parseReadyEstimateFile = (value: unknown): ReadyEstimateFile => {
110
+ assert(
111
+ typeof value === "object" && value !== null && !Array.isArray(value),
112
+ "The estimate file must contain a JSON object.",
113
+ );
114
+ assert(
115
+ "status" in value && value.status === "ready",
116
+ "The estimate file is not a ready Training Cost Estimate.",
117
+ );
118
+ assert(
119
+ "trainingId" in value && typeof value.trainingId === "string",
120
+ "The estimate file has no Training ID.",
121
+ );
122
+ assert(
123
+ "inputSetId" in value && typeof value.inputSetId === "string",
124
+ "The estimate file has no Input Set ID.",
125
+ );
126
+ assert(
127
+ "fingerprint" in value &&
128
+ typeof value.fingerprint === "string" &&
129
+ /^[0-9a-f]{64}$/.test(value.fingerprint),
130
+ "The estimate file has no valid fingerprint.",
131
+ );
132
+
133
+ return {
134
+ status: "ready",
135
+ trainingId: value.trainingId,
136
+ inputSetId: value.inputSetId,
137
+ fingerprint: value.fingerprint,
138
+ };
139
+ };
140
+
141
+ const formatCostEstimate = (estimate: TrainingCostEstimate): string => {
142
+ if (estimate.status === "blocked") {
143
+ return [
144
+ "Training cannot run with these inputs:",
145
+ ...estimate.issues.map((item) => `- ${item.message}`),
146
+ ].join("\n");
147
+ }
148
+
149
+ return formatTable([
150
+ ["Training", estimate.trainingId],
151
+ ["Training rows", String(estimate.inputs.training.report?.validCount ?? 0)],
152
+ ["Training tokens", String(estimate.inputs.training.report?.tokens.total ?? 0)],
153
+ ["Maximum GPU seconds", String(estimate.budget.maximumGpuSeconds)],
154
+ ["Maximum charge", `$${estimate.maximumCharge} ${estimate.currency}`],
155
+ ["Fingerprint", estimate.fingerprint],
156
+ ]);
157
+ };
158
+
159
+ const resolveTraining = async (
160
+ client: TrainingApi,
161
+ projectId: string,
162
+ nameOrId: string,
163
+ ): Promise<Training> => {
164
+ if (nameOrId.startsWith("trg.")) {
165
+ const training = await client.trainings.get({ trainingId: nameOrId });
166
+ assert(
167
+ training.projectId === projectId,
168
+ `Training ${nameOrId} was not found in project ${projectId}.`,
169
+ );
170
+ return training;
171
+ }
172
+
173
+ const matches: Training[] = [];
174
+ for await (const training of client.trainings.listAll({ projectId, limit: 100 })) {
175
+ if (training.name === nameOrId) matches.push(training);
176
+ }
177
+ assert(matches.length === 1, `Training ${nameOrId} was not found or is ambiguous.`);
178
+ return matches[0]!;
179
+ };
180
+
181
+ const parseFilterValue = (raw: string): string | number | boolean | null => {
182
+ if (raw === "true") return true;
183
+ if (raw === "false") return false;
184
+ if (raw === "null") return null;
185
+ const numeric = Number(raw);
186
+ return raw.trim() !== "" && Number.isFinite(numeric) ? numeric : raw;
187
+ };
188
+
189
+ const resolveSelection = async (
190
+ client: Pick<PotatoClient, "datasets">,
191
+ datasetId: string,
192
+ filter: string | undefined,
193
+ ): Promise<TrainingSelection> => {
194
+ assert(datasetId, "A Dataset is required when specifying a filter.");
195
+ if (filter === undefined) return { datasetId };
196
+ const separator = filter.indexOf("=");
197
+ assert(
198
+ separator > 0 && separator < filter.length - 1,
199
+ "Dataset filters must use FIELD=VALUE syntax.",
200
+ );
201
+ const fieldName = filter.slice(0, separator);
202
+ const rawValue = filter.slice(separator + 1);
203
+ const matches = [];
204
+ for await (const field of client.datasets.listAllFields({ datasetId })) {
205
+ if (field.name === fieldName) matches.push(field);
206
+ }
207
+ const [field] = matches;
208
+ assert(
209
+ field && matches.length === 1,
210
+ `Dataset field ${fieldName} was not found or is ambiguous.`,
211
+ );
212
+ return {
213
+ datasetId,
214
+ itemFilter: {
215
+ fieldValues: [
216
+ {
217
+ fieldId: field.id,
218
+ jsonPath: "$",
219
+ operator: "text_eq",
220
+ value: parseFilterValue(rawValue),
221
+ latestOnly: true,
222
+ sources: [],
223
+ },
224
+ ],
225
+ fieldSources: [],
226
+ missingRevisionFields: [],
227
+ },
228
+ };
229
+ };
230
+
231
+ const sourceFromOptions = (
232
+ options: Pick<TrainingDraftOptions, "baseModelId" | "modelVersionId">,
233
+ fallback?: TrainingSource,
234
+ ): TrainingSource => {
235
+ assert(
236
+ !(options.baseModelId && options.modelVersionId),
237
+ "Choose exactly one of --base-model and --model-version.",
238
+ );
239
+ if (options.baseModelId) return { type: "base_model", baseModelId: options.baseModelId };
240
+ if (options.modelVersionId)
241
+ return { type: "model_version", modelVersionId: options.modelVersionId };
242
+ assert(fallback, "Choose exactly one of --base-model and --model-version.");
243
+ return fallback;
244
+ };
245
+
246
+ const uploadPromptFile = async (
247
+ client: Pick<PotatoClient, "files">,
248
+ projectId: string,
249
+ filePath: string,
250
+ fetchImplementation: typeof globalThis.fetch,
251
+ ): Promise<string> => {
252
+ const metadata = await stat(filePath);
253
+ assert(metadata.isFile(), "--prompt-file must point to a file.");
254
+ assert(metadata.size > 0, "The gisting prompt file is empty.");
255
+ assert(
256
+ metadata.size <= GISTING_PROMPT_MAX_BYTES,
257
+ "The gisting prompt file exceeds the 256 KiB limit.",
258
+ );
259
+ const payload = await readFile(filePath);
260
+ let prompt: string;
261
+ try {
262
+ prompt = new TextDecoder("utf-8", { fatal: true }).decode(payload);
263
+ } catch {
264
+ throw new Error("The gisting prompt file must contain valid UTF-8 text.");
265
+ }
266
+ assert(prompt.trim().length > 0, "The gisting prompt file is empty.");
267
+ const started = await client.files.startUpload({
268
+ projectId,
269
+ filename: basename(filePath),
270
+ declaredSizeBytes: payload.byteLength,
271
+ });
272
+ try {
273
+ const response = await fetchImplementation(started.uploadUrl, {
274
+ method: "PUT",
275
+ headers: { "x-ms-blob-type": "BlockBlob", "Content-Type": "text/plain; charset=utf-8" },
276
+ body: payload,
277
+ });
278
+ assert(response.ok, `Failed to upload gisting prompt: HTTP ${response.status}.`);
279
+ return (await client.files.finalizeUpload({ projectId, fileId: started.file.id })).id;
280
+ } catch (error) {
281
+ await client.files.delete({ projectId, fileId: started.file.id }).catch(() => undefined);
282
+ throw error;
283
+ }
284
+ };
285
+
286
+ const resolveSelections = async ({
287
+ client,
288
+ current,
289
+ options,
290
+ }: {
291
+ client: TrainingDraftApi;
292
+ current: Training["configuration"] | undefined;
293
+ options: TrainingDraftOptions;
294
+ }): Promise<ResolvedSelections> => {
295
+ const trainingDatasetId = options.datasetId ?? current?.training.datasetId;
296
+ assert(trainingDatasetId, "--dataset is required.");
297
+ const training =
298
+ options.datasetId === undefined && options.trainingFilter === undefined && current
299
+ ? current.training
300
+ : await resolveSelection(client, trainingDatasetId, options.trainingFilter);
301
+ const validation =
302
+ options.validationDatasetId === undefined && options.validationFilter === undefined
303
+ ? current?.validation
304
+ : await resolveSelection(
305
+ client,
306
+ options.validationDatasetId ?? current?.validation?.datasetId ?? "",
307
+ options.validationFilter,
308
+ );
309
+ return { training, validation };
310
+ };
311
+
312
+ const buildSftConfiguration = ({
313
+ source,
314
+ selections,
315
+ current,
316
+ options,
317
+ }: {
318
+ source: TrainingSource;
319
+ selections: ResolvedSelections;
320
+ current: SftConfigurationInput | undefined;
321
+ options: TrainingDraftOptions;
322
+ }): SftConfigurationInput => {
323
+ assert(options.promptFilePath === undefined, "Gisting options cannot be used with SFT.");
324
+ return {
325
+ ...current,
326
+ method: "sft",
327
+ source,
328
+ ...selections,
329
+ ...(options.regime === undefined ? {} : { regime: options.regime }),
330
+ ...(options.epochs === undefined ? {} : { epochs: options.epochs }),
331
+ ...(options.evalSteps === undefined ? {} : { evalSteps: options.evalSteps }),
332
+ };
333
+ };
334
+
335
+ const buildGistingConfiguration = async ({
336
+ client,
337
+ projectId,
338
+ source,
339
+ selections,
340
+ current,
341
+ options,
342
+ }: {
343
+ client: TrainingDraftApi;
344
+ projectId: string;
345
+ source: TrainingSource;
346
+ selections: ResolvedSelections;
347
+ current: GistingConfigurationInput | undefined;
348
+ options: TrainingDraftOptions;
349
+ }): Promise<GistingConfigurationInput> => {
350
+ assert(options.evalSteps === undefined, "SFT options cannot be used with gisting.");
351
+ const promptFileId = options.promptFilePath
352
+ ? await uploadPromptFile(
353
+ client,
354
+ projectId,
355
+ options.promptFilePath,
356
+ options.fetch ?? globalThis.fetch,
357
+ )
358
+ : current?.promptFileId;
359
+ assert(promptFileId, "--prompt-file is required for gisting.");
360
+ return {
361
+ ...current,
362
+ method: "gisting",
363
+ source,
364
+ ...selections,
365
+ promptFileId,
366
+ ...(options.regime === undefined ? {} : { regime: options.regime }),
367
+ ...(options.epochs === undefined ? {} : { epochs: options.epochs }),
368
+ };
369
+ };
370
+
371
+ const buildTrainingConfiguration = async ({
372
+ client,
373
+ projectId,
374
+ current,
375
+ options,
376
+ }: {
377
+ client: TrainingDraftApi;
378
+ projectId: string;
379
+ current?: Training["configuration"];
380
+ options: TrainingDraftOptions;
381
+ }): Promise<TrainingConfigurationInput> => {
382
+ const source = sourceFromOptions(options, current?.source);
383
+ const selections = await resolveSelections({ client, current, options });
384
+ const method = options.method ?? current?.method ?? "sft";
385
+ return method === "sft"
386
+ ? buildSftConfiguration({
387
+ source,
388
+ selections,
389
+ current: current?.method === "sft" ? current : undefined,
390
+ options,
391
+ })
392
+ : buildGistingConfiguration({
393
+ client,
394
+ projectId,
395
+ source,
396
+ selections,
397
+ current: current?.method === "gisting" ? current : undefined,
398
+ options,
399
+ });
400
+ };
401
+
402
+ export const listTrainings = async (
403
+ client: TrainingApi,
404
+ input: { projectId: string; json: boolean },
405
+ io: TrainingIo,
406
+ ): Promise<void> => {
407
+ const page = await client.trainings.listPage({
408
+ projectId: input.projectId,
409
+ limit: 100,
410
+ offset: 0,
411
+ });
412
+ writeOutput(
413
+ io,
414
+ input.json,
415
+ page.trainings,
416
+ page.trainings.length === 0
417
+ ? "No Trainings found."
418
+ : formatTable([
419
+ ["ID", "NAME", "METHOD", "OUTPUT MODEL"],
420
+ ...page.trainings.map((training) => [
421
+ training.id,
422
+ training.name,
423
+ training.configuration.method === "sft" ? "SFT" : "GISTING",
424
+ training.modelId ?? "-",
425
+ ]),
426
+ ]),
427
+ );
428
+ };
429
+
430
+ export const getTraining = async (
431
+ client: TrainingApi,
432
+ input: { projectId: string; nameOrId: string; json: boolean },
433
+ io: TrainingIo,
434
+ ): Promise<void> => {
435
+ const training = await resolveTraining(client, input.projectId, input.nameOrId);
436
+ writeOutput(io, input.json, training, formatTraining(training));
437
+ };
438
+
439
+ export const createTraining = async (
440
+ client: TrainingDraftApi,
441
+ input: TrainingDraftOptions & {
442
+ projectId: string;
443
+ name: string;
444
+ json: boolean;
445
+ },
446
+ io: TrainingIo,
447
+ ): Promise<void> => {
448
+ assert(input.datasetId, "--dataset is required.");
449
+ assert(!input.validationFilter || input.validationDatasetId, "--validation-filter requires --validation-dataset.");
450
+
451
+ const configuration = await buildTrainingConfiguration({
452
+ client,
453
+ projectId: input.projectId,
454
+ options: input,
455
+ });
456
+ const training = await client.trainings.create({
457
+ projectId: input.projectId,
458
+ name: input.name,
459
+ configuration,
460
+ });
461
+ writeOutput(
462
+ io,
463
+ input.json,
464
+ training,
465
+ `Created training ${training.id}`,
466
+ );
467
+ };
468
+
469
+ export const updateTraining = async (
470
+ client: TrainingDraftApi,
471
+ input: TrainingDraftOptions & {
472
+ projectId: string;
473
+ nameOrId: string;
474
+ json: boolean;
475
+ },
476
+ io: TrainingIo,
477
+ ): Promise<void> => {
478
+ const current = await resolveTraining(client, input.projectId, input.nameOrId);
479
+ const updated = await client.trainings.replaceConfiguration({
480
+ trainingId: current.id,
481
+ configuration: await buildTrainingConfiguration({
482
+ client,
483
+ projectId: input.projectId,
484
+ current: current.configuration,
485
+ options: input,
486
+ }),
487
+ });
488
+ writeOutput(
489
+ io,
490
+ input.json,
491
+ updated,
492
+ `Updated training ${updated.id}`,
493
+ );
494
+ };
495
+
496
+ export const estimateTrainingCost = async (
497
+ client: TrainingCostApi,
498
+ input: { projectId: string; nameOrId: string; idempotencyKey?: string; json: boolean },
499
+ io: TrainingIo,
500
+ ): Promise<void> => {
501
+ const training = await resolveTraining(client, input.projectId, input.nameOrId);
502
+ const inputSet = await client.trainings.prepareCostEstimateInputs({
503
+ trainingId: training.id,
504
+ idempotencyKey: input.idempotencyKey ?? randomUUID(),
505
+ });
506
+ const exportIds = [inputSet.exports.training, inputSet.exports.validation].filter(
507
+ (exportId): exportId is string => exportId !== null,
508
+ );
509
+
510
+ await Promise.all(
511
+ exportIds.map((exportId) => client.waitFor({ type: "datasetExport", exportId })),
512
+ );
513
+
514
+ const estimate = await client.trainings.estimateCost({
515
+ trainingId: training.id,
516
+ inputSetId: inputSet.id,
517
+ });
518
+ writeOutput(io, input.json, estimate, formatCostEstimate(estimate));
519
+ };
520
+
521
+ export const createTrainingRun = async (
522
+ client: TrainingApi,
523
+ input: {
524
+ projectId: string;
525
+ nameOrId: string;
526
+ estimateFile: string;
527
+ versionName: string;
528
+ idempotencyKey?: string;
529
+ json: boolean;
530
+ },
531
+ io: TrainingIo,
532
+ ): Promise<void> => {
533
+ const training = await resolveTraining(client, input.projectId, input.nameOrId);
534
+ const estimate = parseReadyEstimateFile(JSON.parse(await readFile(input.estimateFile, "utf8")));
535
+ assert(estimate.trainingId === training.id, "The estimate file belongs to another Training.");
536
+ const run = await client.trainings.createRun({
537
+ trainingId: training.id,
538
+ inputSetId: estimate.inputSetId,
539
+ estimateFingerprint: estimate.fingerprint,
540
+ versionName: input.versionName,
541
+ idempotencyKey: input.idempotencyKey ?? randomUUID(),
542
+ });
543
+ writeOutput(io, input.json, run, formatTrainingRun(run));
544
+ };
545
+
546
+ export const listTrainingRuns = async (
547
+ client: TrainingApi,
548
+ input: { projectId: string; nameOrId: string; json: boolean },
549
+ io: TrainingIo,
550
+ ): Promise<void> => {
551
+ const training = await resolveTraining(client, input.projectId, input.nameOrId);
552
+ const page = await client.trainings.listRunsPage({
553
+ trainingId: training.id,
554
+ limit: 100,
555
+ offset: 0,
556
+ });
557
+ writeOutput(
558
+ io,
559
+ input.json,
560
+ page.trainingRuns,
561
+ page.trainingRuns.length === 0
562
+ ? "No Training Runs found."
563
+ : formatTable([
564
+ ["ID", "STATUS", "VERSION", "MAXIMUM CHARGE", "OUTPUT MODEL VERSION"],
565
+ ...page.trainingRuns.map((run) => [
566
+ run.id,
567
+ run.status,
568
+ run.outputModelVersionName,
569
+ `$${run.quote.maximumCharge}`,
570
+ run.outputModelVersionId,
571
+ ]),
572
+ ]),
573
+ );
574
+ };
575
+
576
+ export const getTrainingRun = async (
577
+ client: TrainingApi,
578
+ input: { trainingRunId: string; json: boolean },
579
+ io: TrainingIo,
580
+ ): Promise<void> => {
581
+ const run = await client.trainings.getRun({ trainingRunId: input.trainingRunId });
582
+ writeOutput(io, input.json, run, formatTrainingRun(run));
583
+ };
584
+
585
+ export const resumeTrainingRun = async (
586
+ client: TrainingApi,
587
+ input: { trainingRunId: string; json: boolean },
588
+ io: TrainingIo,
589
+ ): Promise<void> => {
590
+ const run = await client.trainings.resumeRun({ trainingRunId: input.trainingRunId });
591
+ writeOutput(io, input.json, run, formatTrainingRun(run));
592
+ };
593
+
594
+ export const cancelTrainingRun = async (
595
+ client: TrainingApi,
596
+ input: { trainingRunId: string; json: boolean },
597
+ io: TrainingIo,
598
+ ): Promise<void> => {
599
+ const run = await client.trainings.cancelRun({ trainingRunId: input.trainingRunId });
600
+ writeOutput(io, input.json, run, formatTrainingRun(run));
601
+ };
602
+
603
+ export const readTrainingRunLogs = async (
604
+ client: TrainingApi,
605
+ input: { trainingRunId: string; follow: boolean; pollIntervalMs?: number },
606
+ io: TrainingIo,
607
+ ): Promise<void> => {
608
+ let cursor: string | null = null;
609
+ for (;;) {
610
+ const page = await client.trainings.getRunLogs({
611
+ trainingRunId: input.trainingRunId,
612
+ cursor: cursor ?? undefined,
613
+ limit: 100,
614
+ });
615
+ for (const entry of page.entries) {
616
+ io.stdout(`${entry.timestamp} ${entry.level.toUpperCase()} ${entry.message}`);
617
+ }
618
+ if (!input.follow || page.complete) {
619
+ if (page.truncated) io.stdout("Training logs were truncated by the server.");
620
+ return;
621
+ }
622
+ cursor = page.nextCursor;
623
+ await new Promise<void>((resolve) => {
624
+ setTimeout(resolve, input.pollIntervalMs ?? 1_000);
625
+ });
626
+ }
627
+ };