@toloka-platform/sdk 0.1.0-preview.9 → 0.2.0-preview.1

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 (286) hide show
  1. package/README.md +6 -5
  2. package/dist/cli/toloka.js +143 -139
  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/authoring.md +9 -4
  7. package/docs/cli-v2.md +3 -3
  8. package/docs/cli.md +16 -3
  9. package/docs/getting-started.md +4 -4
  10. package/docs/limitations.md +3 -3
  11. package/docs/testing.md +1 -1
  12. package/examples/face-image-collection/README.md +1 -1
  13. package/openapi/gen/api.ts +1482 -777
  14. package/openapi/gen/models/createDatasetExportBody.ts +5 -3
  15. package/openapi/gen/models/createDatasetExportBodyFormat.ts +2 -0
  16. package/openapi/gen/models/createProjectTrainingBody.ts +6 -0
  17. package/openapi/gen/models/createTrainingRunBody.ts +6 -0
  18. package/openapi/gen/models/datasetExportReportTokens.ts +4 -1
  19. package/openapi/gen/models/datasetExportReportTokensEstimatorVersion.ts +2 -0
  20. package/openapi/gen/models/datasetExportReportTokensTotal.ts +2 -0
  21. package/openapi/gen/models/estimateTrainingCostBody.ts +5 -0
  22. package/openapi/gen/models/exportJob.ts +2 -0
  23. package/openapi/gen/models/exportJobError.ts +3 -0
  24. package/openapi/gen/models/exportJobErrorAnyOf.ts +7 -0
  25. package/openapi/gen/models/exportJobErrorAnyOfCode.ts +2 -0
  26. package/openapi/gen/models/exportJobStatus.ts +1 -1
  27. package/openapi/gen/models/getTrainingRunLogsParams.ts +5 -0
  28. package/openapi/gen/models/gistingTrainingConfiguration.ts +13 -0
  29. package/openapi/gen/models/gistingTrainingConfigurationInput.ts +13 -0
  30. package/openapi/gen/models/gistingTrainingConfigurationInputRegime.ts +2 -0
  31. package/openapi/gen/models/gistingTrainingConfigurationRegime.ts +2 -0
  32. package/openapi/gen/models/index.ts +230 -16
  33. package/openapi/gen/models/listProjectTrainings200.ts +7 -0
  34. package/openapi/gen/models/listProjectTrainingsParams.ts +5 -0
  35. package/openapi/gen/models/listTrainingRuns200.ts +7 -0
  36. package/openapi/gen/models/listTrainingRunsParams.ts +5 -0
  37. package/openapi/gen/models/modelVersion.ts +6 -1
  38. package/openapi/gen/models/modelVersionContent.ts +4 -0
  39. package/openapi/gen/models/modelVersionContentDownload.ts +11 -0
  40. package/openapi/gen/models/modelVersionContentDownloadContent.ts +4 -0
  41. package/openapi/gen/models/modelVersionContentDownloadContentOneOf.ts +10 -0
  42. package/openapi/gen/models/modelVersionContentDownloadContentOneOfManifestItem.ts +8 -0
  43. package/openapi/gen/models/modelVersionContentDownloadContentOneOfManifestItemMediaType.ts +2 -0
  44. package/openapi/gen/models/modelVersionContentDownloadContentOneOfNine.ts +8 -0
  45. package/openapi/gen/models/modelVersionContentDownloadContentOneOfNineManifestItem.ts +8 -0
  46. package/openapi/gen/models/modelVersionContentDownloadContentOneOfNineManifestItemMediaType.ts +2 -0
  47. package/openapi/gen/models/modelVersionContentDownloadContentOneOfNineRuntimeBase.ts +2 -0
  48. package/openapi/gen/models/modelVersionContentDownloadContentOneOfParent.ts +4 -0
  49. package/openapi/gen/models/modelVersionContentDownloadContentOneOfParentOneOf.ts +6 -0
  50. package/openapi/gen/models/modelVersionContentDownloadContentOneOfParentOneOfBaseModelId.ts +2 -0
  51. package/openapi/gen/models/modelVersionContentDownloadContentOneOfParentOneOfThree.ts +5 -0
  52. package/openapi/gen/models/modelVersionContentDownloadContentOneOfRuntimeBase.ts +2 -0
  53. package/openapi/gen/models/modelVersionContentDownloadFilesItem.ts +9 -0
  54. package/openapi/gen/models/modelVersionContentDownloadFilesItemMediaType.ts +2 -0
  55. package/openapi/gen/models/modelVersionContentOneOf.ts +10 -0
  56. package/openapi/gen/models/modelVersionContentOneOfManifestItem.ts +8 -0
  57. package/openapi/gen/models/modelVersionContentOneOfManifestItemMediaType.ts +2 -0
  58. package/openapi/gen/models/modelVersionContentOneOfNine.ts +8 -0
  59. package/openapi/gen/models/modelVersionContentOneOfNineManifestItem.ts +8 -0
  60. package/openapi/gen/models/modelVersionContentOneOfNineManifestItemMediaType.ts +2 -0
  61. package/openapi/gen/models/modelVersionContentOneOfNineRuntimeBase.ts +2 -0
  62. package/openapi/gen/models/modelVersionContentOneOfParent.ts +4 -0
  63. package/openapi/gen/models/modelVersionContentOneOfParentOneOf.ts +6 -0
  64. package/openapi/gen/models/modelVersionContentOneOfParentOneOfBaseModelId.ts +2 -0
  65. package/openapi/gen/models/modelVersionContentOneOfParentOneOfThree.ts +5 -0
  66. package/openapi/gen/models/modelVersionContentOneOfRuntimeBase.ts +2 -0
  67. package/openapi/gen/models/modelVersionProducer.ts +5 -0
  68. package/openapi/gen/models/prepareTrainingCostEstimateInputsBody.ts +2 -0
  69. package/openapi/gen/models/replaceTrainingConfigurationBody.ts +5 -0
  70. package/openapi/gen/models/sftTrainingConfiguration.ts +13 -0
  71. package/openapi/gen/models/sftTrainingConfigurationInput.ts +13 -0
  72. package/openapi/gen/models/sftTrainingConfigurationInputRegime.ts +2 -0
  73. package/openapi/gen/models/sftTrainingConfigurationRegime.ts +2 -0
  74. package/openapi/gen/models/training.ts +16 -0
  75. package/openapi/gen/models/trainingArchivedAt.ts +2 -0
  76. package/openapi/gen/models/trainingConfiguration.ts +4 -0
  77. package/openapi/gen/models/trainingConfigurationInput.ts +4 -0
  78. package/openapi/gen/models/trainingCostEstimate.ts +4 -0
  79. package/openapi/gen/models/trainingCostEstimateInputSet.ts +12 -0
  80. package/openapi/gen/models/trainingCostEstimateInputSetExports.ts +6 -0
  81. package/openapi/gen/models/trainingCostEstimateInputSetExportsValidation.ts +2 -0
  82. package/openapi/gen/models/trainingCostEstimateInputSetId.ts +2 -0
  83. package/openapi/gen/models/trainingCostEstimateOneOf.ts +16 -0
  84. package/openapi/gen/models/trainingCostEstimateOneOfInputs.ts +7 -0
  85. package/openapi/gen/models/trainingCostEstimateOneOfInputsTraining.ts +9 -0
  86. package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingFailure.ts +3 -0
  87. package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingFailureAnyOf.ts +7 -0
  88. package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingFailureAnyOfCode.ts +2 -0
  89. package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingReport.ts +3 -0
  90. package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingReportAnyOf.ts +9 -0
  91. package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingReportAnyOfErrorsItem.ts +5 -0
  92. package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingReportAnyOfTokens.ts +10 -0
  93. package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingReportAnyOfTokensEstimatorVersion.ts +2 -0
  94. package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingReportAnyOfTokensTotal.ts +2 -0
  95. package/openapi/gen/models/trainingCostEstimateOneOfInputsValidation.ts +3 -0
  96. package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOf.ts +9 -0
  97. package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfFailure.ts +3 -0
  98. package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfFailureAnyOf.ts +7 -0
  99. package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfFailureAnyOfCode.ts +2 -0
  100. package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfReport.ts +3 -0
  101. package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfReportAnyOf.ts +9 -0
  102. package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfReportAnyOfErrorsItem.ts +5 -0
  103. package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfReportAnyOfTokens.ts +10 -0
  104. package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfReportAnyOfTokensEstimatorVersion.ts +2 -0
  105. package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfReportAnyOfTokensTotal.ts +2 -0
  106. package/openapi/gen/models/trainingCostEstimateOneOfIssuesItem.ts +8 -0
  107. package/openapi/gen/models/trainingCostEstimateOneOfIssuesItemCode.ts +2 -0
  108. package/openapi/gen/models/trainingCostEstimateOneOfIssuesItemPurpose.ts +2 -0
  109. package/openapi/gen/models/trainingCostEstimateOneOfTwoseven.ts +23 -0
  110. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenBudget.ts +9 -0
  111. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputs.ts +7 -0
  112. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTraining.ts +9 -0
  113. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingFailure.ts +3 -0
  114. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingFailureAnyOf.ts +7 -0
  115. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingFailureAnyOfCode.ts +2 -0
  116. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingReport.ts +3 -0
  117. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingReportAnyOf.ts +9 -0
  118. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingReportAnyOfErrorsItem.ts +5 -0
  119. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingReportAnyOfTokens.ts +10 -0
  120. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingReportAnyOfTokensEstimatorVersion.ts +2 -0
  121. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingReportAnyOfTokensTotal.ts +2 -0
  122. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidation.ts +3 -0
  123. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOf.ts +9 -0
  124. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfFailure.ts +3 -0
  125. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfFailureAnyOf.ts +7 -0
  126. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfFailureAnyOfCode.ts +2 -0
  127. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfReport.ts +3 -0
  128. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfReportAnyOf.ts +9 -0
  129. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfReportAnyOfErrorsItem.ts +5 -0
  130. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfReportAnyOfTokens.ts +10 -0
  131. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfReportAnyOfTokensEstimatorVersion.ts +2 -0
  132. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfReportAnyOfTokensTotal.ts +2 -0
  133. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenIssuesItem.ts +8 -0
  134. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenIssuesItemCode.ts +2 -0
  135. package/openapi/gen/models/trainingCostEstimateOneOfTwosevenIssuesItemPurpose.ts +2 -0
  136. package/openapi/gen/models/trainingDatasetItemFilter.ts +8 -0
  137. package/openapi/gen/models/trainingDatasetItemFilterFieldSourcesItem.ts +6 -0
  138. package/openapi/gen/models/trainingDatasetItemFilterFieldSourcesItemSourcesItem.ts +4 -0
  139. package/openapi/gen/models/trainingDatasetItemFilterFieldSourcesItemSourcesItemOneOf.ts +5 -0
  140. package/openapi/gen/models/trainingDatasetItemFilterFieldSourcesItemSourcesItemOneOfTwo.ts +5 -0
  141. package/openapi/gen/models/trainingDatasetItemFilterFieldValuesItem.ts +12 -0
  142. package/openapi/gen/models/trainingDatasetItemFilterFieldValuesItemOperator.ts +2 -0
  143. package/openapi/gen/models/trainingDatasetItemFilterFieldValuesItemSourcesItem.ts +4 -0
  144. package/openapi/gen/models/trainingDatasetItemFilterFieldValuesItemSourcesItemOneOf.ts +5 -0
  145. package/openapi/gen/models/trainingDatasetItemFilterFieldValuesItemSourcesItemOneOfTwo.ts +5 -0
  146. package/openapi/gen/models/trainingDatasetItemFilterFieldValuesItemValue.ts +2 -0
  147. package/openapi/gen/models/trainingDatasetItemFilterInput.ts +8 -0
  148. package/openapi/gen/models/trainingDatasetItemFilterInputFieldSourcesItem.ts +6 -0
  149. package/openapi/gen/models/trainingDatasetItemFilterInputFieldSourcesItemSourcesItem.ts +4 -0
  150. package/openapi/gen/models/trainingDatasetItemFilterInputFieldSourcesItemSourcesItemOneOf.ts +5 -0
  151. package/openapi/gen/models/trainingDatasetItemFilterInputFieldSourcesItemSourcesItemOneOfTwo.ts +5 -0
  152. package/openapi/gen/models/trainingDatasetItemFilterInputFieldValuesItem.ts +12 -0
  153. package/openapi/gen/models/trainingDatasetItemFilterInputFieldValuesItemOperator.ts +2 -0
  154. package/openapi/gen/models/trainingDatasetItemFilterInputFieldValuesItemSourcesItem.ts +4 -0
  155. package/openapi/gen/models/trainingDatasetItemFilterInputFieldValuesItemSourcesItemOneOf.ts +5 -0
  156. package/openapi/gen/models/trainingDatasetItemFilterInputFieldValuesItemSourcesItemOneOfTwo.ts +5 -0
  157. package/openapi/gen/models/trainingDatasetItemFilterInputFieldValuesItemValue.ts +2 -0
  158. package/openapi/gen/models/trainingDatasetSelection.ts +6 -0
  159. package/openapi/gen/models/trainingDatasetSelectionInput.ts +6 -0
  160. package/openapi/gen/models/trainingId.ts +2 -0
  161. package/openapi/gen/models/trainingModelId.ts +3 -0
  162. package/openapi/gen/models/trainingModelSource.ts +4 -0
  163. package/openapi/gen/models/trainingModelSourceOneOf.ts +6 -0
  164. package/openapi/gen/models/trainingModelSourceOneOfBaseModelId.ts +2 -0
  165. package/openapi/gen/models/trainingModelSourceOneOfThree.ts +5 -0
  166. package/openapi/gen/models/trainingRun.ts +39 -0
  167. package/openapi/gen/models/trainingRunBillingStatus.ts +2 -0
  168. package/openapi/gen/models/trainingRunBlockedReason.ts +2 -0
  169. package/openapi/gen/models/trainingRunChargedAmount.ts +2 -0
  170. package/openapi/gen/models/trainingRunError.ts +3 -0
  171. package/openapi/gen/models/trainingRunErrorAnyOf.ts +7 -0
  172. package/openapi/gen/models/trainingRunErrorAnyOfCode.ts +2 -0
  173. package/openapi/gen/models/trainingRunId.ts +2 -0
  174. package/openapi/gen/models/trainingRunInputs.ts +3 -0
  175. package/openapi/gen/models/trainingRunInputsAnyOf.ts +7 -0
  176. package/openapi/gen/models/trainingRunInputsAnyOfTraining.ts +15 -0
  177. package/openapi/gen/models/trainingRunInputsAnyOfTrainingContract.ts +2 -0
  178. package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilter.ts +9 -0
  179. package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldSourcesItem.ts +6 -0
  180. package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldSourcesItemSourcesItem.ts +4 -0
  181. package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldSourcesItemSourcesItemOneOf.ts +5 -0
  182. package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldSourcesItemSourcesItemOneOfTwo.ts +5 -0
  183. package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldValuesItem.ts +12 -0
  184. package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldValuesItemOperator.ts +2 -0
  185. package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldValuesItemSourcesItem.ts +4 -0
  186. package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldValuesItemSourcesItemOneOf.ts +5 -0
  187. package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldValuesItemSourcesItemOneOfTwo.ts +5 -0
  188. package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldValuesItemValue.ts +2 -0
  189. package/openapi/gen/models/trainingRunInputsAnyOfTrainingReport.ts +9 -0
  190. package/openapi/gen/models/trainingRunInputsAnyOfTrainingReportErrorsItem.ts +5 -0
  191. package/openapi/gen/models/trainingRunInputsAnyOfTrainingReportTokens.ts +10 -0
  192. package/openapi/gen/models/trainingRunInputsAnyOfTrainingReportTokensEstimatorVersion.ts +2 -0
  193. package/openapi/gen/models/trainingRunInputsAnyOfTrainingReportTokensTotal.ts +2 -0
  194. package/openapi/gen/models/trainingRunInputsAnyOfValidation.ts +3 -0
  195. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOf.ts +15 -0
  196. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfContract.ts +2 -0
  197. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilter.ts +9 -0
  198. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldSourcesItem.ts +6 -0
  199. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldSourcesItemSourcesItem.ts +4 -0
  200. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldSourcesItemSourcesItemOneOf.ts +5 -0
  201. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldSourcesItemSourcesItemOneOfTwo.ts +5 -0
  202. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldValuesItem.ts +12 -0
  203. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldValuesItemOperator.ts +2 -0
  204. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldValuesItemSourcesItem.ts +4 -0
  205. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldValuesItemSourcesItemOneOf.ts +5 -0
  206. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldValuesItemSourcesItemOneOfTwo.ts +5 -0
  207. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldValuesItemValue.ts +2 -0
  208. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfReport.ts +9 -0
  209. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfReportErrorsItem.ts +5 -0
  210. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfReportTokens.ts +10 -0
  211. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfReportTokensEstimatorVersion.ts +2 -0
  212. package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfReportTokensTotal.ts +2 -0
  213. package/openapi/gen/models/trainingRunLogs.ts +9 -0
  214. package/openapi/gen/models/trainingRunLogsEntriesItem.ts +7 -0
  215. package/openapi/gen/models/trainingRunLogsEntriesItemLevel.ts +2 -0
  216. package/openapi/gen/models/trainingRunLogsNextCursor.ts +2 -0
  217. package/openapi/gen/models/trainingRunMessage.ts +2 -0
  218. package/openapi/gen/models/trainingRunOutputModelVersionRevision.ts +2 -0
  219. package/openapi/gen/models/trainingRunProgress.ts +3 -0
  220. package/openapi/gen/models/trainingRunProgressAnyOf.ts +10 -0
  221. package/openapi/gen/models/trainingRunProgressAnyOfMessage.ts +2 -0
  222. package/openapi/gen/models/trainingRunProgressAnyOfStep.ts +2 -0
  223. package/openapi/gen/models/trainingRunProgressAnyOfTotal.ts +2 -0
  224. package/openapi/gen/models/trainingRunQuote.ts +17 -0
  225. package/openapi/gen/models/trainingRunQuoteBudget.ts +9 -0
  226. package/openapi/gen/models/trainingRunQuoteInputs.ts +7 -0
  227. package/openapi/gen/models/trainingRunQuoteInputsTraining.ts +9 -0
  228. package/openapi/gen/models/trainingRunQuoteInputsTrainingFailure.ts +3 -0
  229. package/openapi/gen/models/trainingRunQuoteInputsTrainingFailureAnyOf.ts +7 -0
  230. package/openapi/gen/models/trainingRunQuoteInputsTrainingFailureAnyOfCode.ts +2 -0
  231. package/openapi/gen/models/trainingRunQuoteInputsTrainingReport.ts +3 -0
  232. package/openapi/gen/models/trainingRunQuoteInputsTrainingReportAnyOf.ts +9 -0
  233. package/openapi/gen/models/trainingRunQuoteInputsTrainingReportAnyOfErrorsItem.ts +5 -0
  234. package/openapi/gen/models/trainingRunQuoteInputsTrainingReportAnyOfTokens.ts +10 -0
  235. package/openapi/gen/models/trainingRunQuoteInputsTrainingReportAnyOfTokensEstimatorVersion.ts +2 -0
  236. package/openapi/gen/models/trainingRunQuoteInputsTrainingReportAnyOfTokensTotal.ts +2 -0
  237. package/openapi/gen/models/trainingRunQuoteInputsValidation.ts +3 -0
  238. package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOf.ts +9 -0
  239. package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfFailure.ts +3 -0
  240. package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfFailureAnyOf.ts +7 -0
  241. package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfFailureAnyOfCode.ts +2 -0
  242. package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfReport.ts +3 -0
  243. package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfReportAnyOf.ts +9 -0
  244. package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfReportAnyOfErrorsItem.ts +5 -0
  245. package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfReportAnyOfTokens.ts +10 -0
  246. package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfReportAnyOfTokensEstimatorVersion.ts +2 -0
  247. package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfReportAnyOfTokensTotal.ts +2 -0
  248. package/openapi/gen/models/trainingRunStatus.ts +2 -0
  249. package/openapi/gen/models/updateTrainingMetadataBody.ts +5 -0
  250. package/package.json +3 -3
  251. package/skills/catalog.json +19 -7
  252. package/skills/toloka-build/SKILL.md +4 -4
  253. package/skills/toloka-build/references/node-semantics.md +2 -2
  254. package/skills/toloka-build/references/workflow-and-cli.md +21 -3
  255. package/skills/toloka-report-issue/references/report-template.md +1 -1
  256. package/src/authoring/index.ts +10 -0
  257. package/src/cli/auth.ts +1 -1
  258. package/src/cli/auto-update.ts +1 -5
  259. package/src/cli/bin.ts +1 -1
  260. package/src/cli/check.ts +91 -30
  261. package/src/cli/cost.ts +8 -2
  262. package/src/cli/models.ts +107 -2
  263. package/src/cli/program.ts +271 -2
  264. package/src/cli/project-context.ts +55 -11
  265. package/src/cli/project.ts +55 -11
  266. package/src/cli/secrets.ts +4 -4
  267. package/src/cli/trainings.ts +627 -0
  268. package/src/cli/version.ts +68 -0
  269. package/src/client.ts +164 -30
  270. package/src/index.ts +4 -0
  271. package/openapi/gen/models/createDatasetExportBodyOneOf.ts +0 -6
  272. package/openapi/gen/models/createDatasetExportBodyOneOfFormat.ts +0 -2
  273. package/openapi/gen/models/createDatasetExportBodyOneOfThree.ts +0 -10
  274. package/openapi/gen/models/createDatasetExportBodyOneOfThreeContract.ts +0 -2
  275. package/openapi/gen/models/createDatasetExportBodyOneOfThreeFormat.ts +0 -2
  276. package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilter.ts +0 -9
  277. package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldSourcesItem.ts +0 -6
  278. package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldSourcesItemSourcesItem.ts +0 -4
  279. package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldSourcesItemSourcesItemOneOf.ts +0 -5
  280. package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldSourcesItemSourcesItemOneOfTwo.ts +0 -5
  281. package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldValuesItem.ts +0 -12
  282. package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldValuesItemOperator.ts +0 -2
  283. package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldValuesItemSourcesItem.ts +0 -4
  284. package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldValuesItemSourcesItemOneOf.ts +0 -5
  285. package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldValuesItemSourcesItemOneOfTwo.ts +0 -5
  286. 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
+ };
@@ -0,0 +1,68 @@
1
+ import { realpathSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { dirname, join, resolve, sep } from "node:path";
4
+
5
+ import { assert } from "es-toolkit";
6
+ import { SDK_VERSION } from "./init";
7
+
8
+ export type CliInstallChannel = "global-registry" | "linked" | "project-local";
9
+
10
+ type VersionInfoOptions = {
11
+ readonly globalBinDirectory?: string;
12
+ readonly globalPackageDirectory?: string;
13
+ };
14
+
15
+ const GLOBAL_PACKAGE_MARKER = `${sep}install${sep}global${sep}`;
16
+
17
+ const realpathOrSelf = (path: string): string => {
18
+ try {
19
+ return realpathSync(path);
20
+ } catch {
21
+ return path;
22
+ }
23
+ };
24
+
25
+ const classifyInstallChannel = (
26
+ entryPath: string,
27
+ packageRoot: string,
28
+ globalBinDirectory: string,
29
+ globalPackageDirectory: string,
30
+ ): CliInstallChannel => {
31
+ const resolvedEntryPath = realpathOrSelf(entryPath);
32
+ if (resolvedEntryPath.includes(GLOBAL_PACKAGE_MARKER)) return "global-registry";
33
+ if (realpathOrSelf(globalPackageDirectory) === packageRoot) return "linked";
34
+ if (dirname(resolve(entryPath)) === resolve(globalBinDirectory)) return "linked";
35
+ return "project-local";
36
+ };
37
+
38
+ export const cliVersionInfo = (entryPath = process.argv[1], options: VersionInfoOptions = {}) => {
39
+ assert(entryPath, "CLI entry path is unavailable");
40
+ const globalBinDirectory =
41
+ options.globalBinDirectory ??
42
+ resolve(process.env.BUN_INSTALL ?? join(homedir(), ".bun"), "bin");
43
+ const globalPackageDirectory =
44
+ options.globalPackageDirectory ??
45
+ resolve(
46
+ globalBinDirectory,
47
+ "..",
48
+ "install",
49
+ "global",
50
+ "node_modules",
51
+ "@toloka-platform",
52
+ "sdk",
53
+ );
54
+ const packageRoot = resolve(dirname(realpathOrSelf(entryPath)), "..");
55
+ const channel = classifyInstallChannel(
56
+ entryPath,
57
+ packageRoot,
58
+ globalBinDirectory,
59
+ globalPackageDirectory,
60
+ );
61
+
62
+ return {
63
+ version: SDK_VERSION,
64
+ commit: process.env.TOLOKA_BUILD_COMMIT ?? null,
65
+ channel,
66
+ ...(channel === "linked" ? { path: packageRoot } : {}),
67
+ };
68
+ };