@toloka-platform/sdk 0.1.0 → 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.
- package/README.md +2 -2
- package/dist/cli/toloka.js +138 -136
- package/dist/cli/toloka.js.jsc +0 -0
- package/dist/cli/toloka.js.jsc.sha256 +1 -1
- package/dist/cli/toloka.js.sha256 +1 -1
- package/docs/cli-v2.md +1 -1
- package/docs/cli.md +3 -1
- package/docs/getting-started.md +1 -1
- package/docs/limitations.md +2 -2
- package/docs/testing.md +1 -1
- package/examples/face-image-collection/README.md +1 -1
- package/openapi/gen/api.ts +1482 -777
- package/openapi/gen/models/createDatasetExportBody.ts +5 -3
- package/openapi/gen/models/createDatasetExportBodyFormat.ts +2 -0
- package/openapi/gen/models/createProjectTrainingBody.ts +6 -0
- package/openapi/gen/models/createTrainingRunBody.ts +6 -0
- package/openapi/gen/models/datasetExportReportTokens.ts +4 -1
- package/openapi/gen/models/datasetExportReportTokensEstimatorVersion.ts +2 -0
- package/openapi/gen/models/datasetExportReportTokensTotal.ts +2 -0
- package/openapi/gen/models/estimateTrainingCostBody.ts +5 -0
- package/openapi/gen/models/exportJob.ts +2 -0
- package/openapi/gen/models/exportJobError.ts +3 -0
- package/openapi/gen/models/exportJobErrorAnyOf.ts +7 -0
- package/openapi/gen/models/exportJobErrorAnyOfCode.ts +2 -0
- package/openapi/gen/models/exportJobStatus.ts +1 -1
- package/openapi/gen/models/getTrainingRunLogsParams.ts +5 -0
- package/openapi/gen/models/gistingTrainingConfiguration.ts +13 -0
- package/openapi/gen/models/gistingTrainingConfigurationInput.ts +13 -0
- package/openapi/gen/models/gistingTrainingConfigurationInputRegime.ts +2 -0
- package/openapi/gen/models/gistingTrainingConfigurationRegime.ts +2 -0
- package/openapi/gen/models/index.ts +230 -16
- package/openapi/gen/models/listProjectTrainings200.ts +7 -0
- package/openapi/gen/models/listProjectTrainingsParams.ts +5 -0
- package/openapi/gen/models/listTrainingRuns200.ts +7 -0
- package/openapi/gen/models/listTrainingRunsParams.ts +5 -0
- package/openapi/gen/models/modelVersion.ts +6 -1
- package/openapi/gen/models/modelVersionContent.ts +4 -0
- package/openapi/gen/models/modelVersionContentDownload.ts +11 -0
- package/openapi/gen/models/modelVersionContentDownloadContent.ts +4 -0
- package/openapi/gen/models/modelVersionContentDownloadContentOneOf.ts +10 -0
- package/openapi/gen/models/modelVersionContentDownloadContentOneOfManifestItem.ts +8 -0
- package/openapi/gen/models/modelVersionContentDownloadContentOneOfManifestItemMediaType.ts +2 -0
- package/openapi/gen/models/modelVersionContentDownloadContentOneOfNine.ts +8 -0
- package/openapi/gen/models/modelVersionContentDownloadContentOneOfNineManifestItem.ts +8 -0
- package/openapi/gen/models/modelVersionContentDownloadContentOneOfNineManifestItemMediaType.ts +2 -0
- package/openapi/gen/models/modelVersionContentDownloadContentOneOfNineRuntimeBase.ts +2 -0
- package/openapi/gen/models/modelVersionContentDownloadContentOneOfParent.ts +4 -0
- package/openapi/gen/models/modelVersionContentDownloadContentOneOfParentOneOf.ts +6 -0
- package/openapi/gen/models/modelVersionContentDownloadContentOneOfParentOneOfBaseModelId.ts +2 -0
- package/openapi/gen/models/modelVersionContentDownloadContentOneOfParentOneOfThree.ts +5 -0
- package/openapi/gen/models/modelVersionContentDownloadContentOneOfRuntimeBase.ts +2 -0
- package/openapi/gen/models/modelVersionContentDownloadFilesItem.ts +9 -0
- package/openapi/gen/models/modelVersionContentDownloadFilesItemMediaType.ts +2 -0
- package/openapi/gen/models/modelVersionContentOneOf.ts +10 -0
- package/openapi/gen/models/modelVersionContentOneOfManifestItem.ts +8 -0
- package/openapi/gen/models/modelVersionContentOneOfManifestItemMediaType.ts +2 -0
- package/openapi/gen/models/modelVersionContentOneOfNine.ts +8 -0
- package/openapi/gen/models/modelVersionContentOneOfNineManifestItem.ts +8 -0
- package/openapi/gen/models/modelVersionContentOneOfNineManifestItemMediaType.ts +2 -0
- package/openapi/gen/models/modelVersionContentOneOfNineRuntimeBase.ts +2 -0
- package/openapi/gen/models/modelVersionContentOneOfParent.ts +4 -0
- package/openapi/gen/models/modelVersionContentOneOfParentOneOf.ts +6 -0
- package/openapi/gen/models/modelVersionContentOneOfParentOneOfBaseModelId.ts +2 -0
- package/openapi/gen/models/modelVersionContentOneOfParentOneOfThree.ts +5 -0
- package/openapi/gen/models/modelVersionContentOneOfRuntimeBase.ts +2 -0
- package/openapi/gen/models/modelVersionProducer.ts +5 -0
- package/openapi/gen/models/prepareTrainingCostEstimateInputsBody.ts +2 -0
- package/openapi/gen/models/replaceTrainingConfigurationBody.ts +5 -0
- package/openapi/gen/models/sftTrainingConfiguration.ts +13 -0
- package/openapi/gen/models/sftTrainingConfigurationInput.ts +13 -0
- package/openapi/gen/models/sftTrainingConfigurationInputRegime.ts +2 -0
- package/openapi/gen/models/sftTrainingConfigurationRegime.ts +2 -0
- package/openapi/gen/models/training.ts +16 -0
- package/openapi/gen/models/trainingArchivedAt.ts +2 -0
- package/openapi/gen/models/trainingConfiguration.ts +4 -0
- package/openapi/gen/models/trainingConfigurationInput.ts +4 -0
- package/openapi/gen/models/trainingCostEstimate.ts +4 -0
- package/openapi/gen/models/trainingCostEstimateInputSet.ts +12 -0
- package/openapi/gen/models/trainingCostEstimateInputSetExports.ts +6 -0
- package/openapi/gen/models/trainingCostEstimateInputSetExportsValidation.ts +2 -0
- package/openapi/gen/models/trainingCostEstimateInputSetId.ts +2 -0
- package/openapi/gen/models/trainingCostEstimateOneOf.ts +16 -0
- package/openapi/gen/models/trainingCostEstimateOneOfInputs.ts +7 -0
- package/openapi/gen/models/trainingCostEstimateOneOfInputsTraining.ts +9 -0
- package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingFailure.ts +3 -0
- package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingFailureAnyOf.ts +7 -0
- package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingFailureAnyOfCode.ts +2 -0
- package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingReport.ts +3 -0
- package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingReportAnyOf.ts +9 -0
- package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingReportAnyOfErrorsItem.ts +5 -0
- package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingReportAnyOfTokens.ts +10 -0
- package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingReportAnyOfTokensEstimatorVersion.ts +2 -0
- package/openapi/gen/models/trainingCostEstimateOneOfInputsTrainingReportAnyOfTokensTotal.ts +2 -0
- package/openapi/gen/models/trainingCostEstimateOneOfInputsValidation.ts +3 -0
- package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOf.ts +9 -0
- package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfFailure.ts +3 -0
- package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfFailureAnyOf.ts +7 -0
- package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfFailureAnyOfCode.ts +2 -0
- package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfReport.ts +3 -0
- package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfReportAnyOf.ts +9 -0
- package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfReportAnyOfErrorsItem.ts +5 -0
- package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfReportAnyOfTokens.ts +10 -0
- package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfReportAnyOfTokensEstimatorVersion.ts +2 -0
- package/openapi/gen/models/trainingCostEstimateOneOfInputsValidationAnyOfReportAnyOfTokensTotal.ts +2 -0
- package/openapi/gen/models/trainingCostEstimateOneOfIssuesItem.ts +8 -0
- package/openapi/gen/models/trainingCostEstimateOneOfIssuesItemCode.ts +2 -0
- package/openapi/gen/models/trainingCostEstimateOneOfIssuesItemPurpose.ts +2 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwoseven.ts +23 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenBudget.ts +9 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputs.ts +7 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTraining.ts +9 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingFailure.ts +3 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingFailureAnyOf.ts +7 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingFailureAnyOfCode.ts +2 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingReport.ts +3 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingReportAnyOf.ts +9 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingReportAnyOfErrorsItem.ts +5 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingReportAnyOfTokens.ts +10 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingReportAnyOfTokensEstimatorVersion.ts +2 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsTrainingReportAnyOfTokensTotal.ts +2 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidation.ts +3 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOf.ts +9 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfFailure.ts +3 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfFailureAnyOf.ts +7 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfFailureAnyOfCode.ts +2 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfReport.ts +3 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfReportAnyOf.ts +9 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfReportAnyOfErrorsItem.ts +5 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfReportAnyOfTokens.ts +10 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfReportAnyOfTokensEstimatorVersion.ts +2 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenInputsValidationAnyOfReportAnyOfTokensTotal.ts +2 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenIssuesItem.ts +8 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenIssuesItemCode.ts +2 -0
- package/openapi/gen/models/trainingCostEstimateOneOfTwosevenIssuesItemPurpose.ts +2 -0
- package/openapi/gen/models/trainingDatasetItemFilter.ts +8 -0
- package/openapi/gen/models/trainingDatasetItemFilterFieldSourcesItem.ts +6 -0
- package/openapi/gen/models/trainingDatasetItemFilterFieldSourcesItemSourcesItem.ts +4 -0
- package/openapi/gen/models/trainingDatasetItemFilterFieldSourcesItemSourcesItemOneOf.ts +5 -0
- package/openapi/gen/models/trainingDatasetItemFilterFieldSourcesItemSourcesItemOneOfTwo.ts +5 -0
- package/openapi/gen/models/trainingDatasetItemFilterFieldValuesItem.ts +12 -0
- package/openapi/gen/models/trainingDatasetItemFilterFieldValuesItemOperator.ts +2 -0
- package/openapi/gen/models/trainingDatasetItemFilterFieldValuesItemSourcesItem.ts +4 -0
- package/openapi/gen/models/trainingDatasetItemFilterFieldValuesItemSourcesItemOneOf.ts +5 -0
- package/openapi/gen/models/trainingDatasetItemFilterFieldValuesItemSourcesItemOneOfTwo.ts +5 -0
- package/openapi/gen/models/trainingDatasetItemFilterFieldValuesItemValue.ts +2 -0
- package/openapi/gen/models/trainingDatasetItemFilterInput.ts +8 -0
- package/openapi/gen/models/trainingDatasetItemFilterInputFieldSourcesItem.ts +6 -0
- package/openapi/gen/models/trainingDatasetItemFilterInputFieldSourcesItemSourcesItem.ts +4 -0
- package/openapi/gen/models/trainingDatasetItemFilterInputFieldSourcesItemSourcesItemOneOf.ts +5 -0
- package/openapi/gen/models/trainingDatasetItemFilterInputFieldSourcesItemSourcesItemOneOfTwo.ts +5 -0
- package/openapi/gen/models/trainingDatasetItemFilterInputFieldValuesItem.ts +12 -0
- package/openapi/gen/models/trainingDatasetItemFilterInputFieldValuesItemOperator.ts +2 -0
- package/openapi/gen/models/trainingDatasetItemFilterInputFieldValuesItemSourcesItem.ts +4 -0
- package/openapi/gen/models/trainingDatasetItemFilterInputFieldValuesItemSourcesItemOneOf.ts +5 -0
- package/openapi/gen/models/trainingDatasetItemFilterInputFieldValuesItemSourcesItemOneOfTwo.ts +5 -0
- package/openapi/gen/models/trainingDatasetItemFilterInputFieldValuesItemValue.ts +2 -0
- package/openapi/gen/models/trainingDatasetSelection.ts +6 -0
- package/openapi/gen/models/trainingDatasetSelectionInput.ts +6 -0
- package/openapi/gen/models/trainingId.ts +2 -0
- package/openapi/gen/models/trainingModelId.ts +3 -0
- package/openapi/gen/models/trainingModelSource.ts +4 -0
- package/openapi/gen/models/trainingModelSourceOneOf.ts +6 -0
- package/openapi/gen/models/trainingModelSourceOneOfBaseModelId.ts +2 -0
- package/openapi/gen/models/trainingModelSourceOneOfThree.ts +5 -0
- package/openapi/gen/models/trainingRun.ts +39 -0
- package/openapi/gen/models/trainingRunBillingStatus.ts +2 -0
- package/openapi/gen/models/trainingRunBlockedReason.ts +2 -0
- package/openapi/gen/models/trainingRunChargedAmount.ts +2 -0
- package/openapi/gen/models/trainingRunError.ts +3 -0
- package/openapi/gen/models/trainingRunErrorAnyOf.ts +7 -0
- package/openapi/gen/models/trainingRunErrorAnyOfCode.ts +2 -0
- package/openapi/gen/models/trainingRunId.ts +2 -0
- package/openapi/gen/models/trainingRunInputs.ts +3 -0
- package/openapi/gen/models/trainingRunInputsAnyOf.ts +7 -0
- package/openapi/gen/models/trainingRunInputsAnyOfTraining.ts +15 -0
- package/openapi/gen/models/trainingRunInputsAnyOfTrainingContract.ts +2 -0
- package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilter.ts +9 -0
- package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldSourcesItem.ts +6 -0
- package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldSourcesItemSourcesItem.ts +4 -0
- package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldSourcesItemSourcesItemOneOf.ts +5 -0
- package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldSourcesItemSourcesItemOneOfTwo.ts +5 -0
- package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldValuesItem.ts +12 -0
- package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldValuesItemOperator.ts +2 -0
- package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldValuesItemSourcesItem.ts +4 -0
- package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldValuesItemSourcesItemOneOf.ts +5 -0
- package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldValuesItemSourcesItemOneOfTwo.ts +5 -0
- package/openapi/gen/models/trainingRunInputsAnyOfTrainingItemFilterFieldValuesItemValue.ts +2 -0
- package/openapi/gen/models/trainingRunInputsAnyOfTrainingReport.ts +9 -0
- package/openapi/gen/models/trainingRunInputsAnyOfTrainingReportErrorsItem.ts +5 -0
- package/openapi/gen/models/trainingRunInputsAnyOfTrainingReportTokens.ts +10 -0
- package/openapi/gen/models/trainingRunInputsAnyOfTrainingReportTokensEstimatorVersion.ts +2 -0
- package/openapi/gen/models/trainingRunInputsAnyOfTrainingReportTokensTotal.ts +2 -0
- package/openapi/gen/models/trainingRunInputsAnyOfValidation.ts +3 -0
- package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOf.ts +15 -0
- package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfContract.ts +2 -0
- package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilter.ts +9 -0
- package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldSourcesItem.ts +6 -0
- package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldSourcesItemSourcesItem.ts +4 -0
- package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldSourcesItemSourcesItemOneOf.ts +5 -0
- package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldSourcesItemSourcesItemOneOfTwo.ts +5 -0
- package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldValuesItem.ts +12 -0
- package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldValuesItemOperator.ts +2 -0
- package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldValuesItemSourcesItem.ts +4 -0
- package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldValuesItemSourcesItemOneOf.ts +5 -0
- package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldValuesItemSourcesItemOneOfTwo.ts +5 -0
- package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfItemFilterFieldValuesItemValue.ts +2 -0
- package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfReport.ts +9 -0
- package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfReportErrorsItem.ts +5 -0
- package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfReportTokens.ts +10 -0
- package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfReportTokensEstimatorVersion.ts +2 -0
- package/openapi/gen/models/trainingRunInputsAnyOfValidationAnyOfReportTokensTotal.ts +2 -0
- package/openapi/gen/models/trainingRunLogs.ts +9 -0
- package/openapi/gen/models/trainingRunLogsEntriesItem.ts +7 -0
- package/openapi/gen/models/trainingRunLogsEntriesItemLevel.ts +2 -0
- package/openapi/gen/models/trainingRunLogsNextCursor.ts +2 -0
- package/openapi/gen/models/trainingRunMessage.ts +2 -0
- package/openapi/gen/models/trainingRunOutputModelVersionRevision.ts +2 -0
- package/openapi/gen/models/trainingRunProgress.ts +3 -0
- package/openapi/gen/models/trainingRunProgressAnyOf.ts +10 -0
- package/openapi/gen/models/trainingRunProgressAnyOfMessage.ts +2 -0
- package/openapi/gen/models/trainingRunProgressAnyOfStep.ts +2 -0
- package/openapi/gen/models/trainingRunProgressAnyOfTotal.ts +2 -0
- package/openapi/gen/models/trainingRunQuote.ts +17 -0
- package/openapi/gen/models/trainingRunQuoteBudget.ts +9 -0
- package/openapi/gen/models/trainingRunQuoteInputs.ts +7 -0
- package/openapi/gen/models/trainingRunQuoteInputsTraining.ts +9 -0
- package/openapi/gen/models/trainingRunQuoteInputsTrainingFailure.ts +3 -0
- package/openapi/gen/models/trainingRunQuoteInputsTrainingFailureAnyOf.ts +7 -0
- package/openapi/gen/models/trainingRunQuoteInputsTrainingFailureAnyOfCode.ts +2 -0
- package/openapi/gen/models/trainingRunQuoteInputsTrainingReport.ts +3 -0
- package/openapi/gen/models/trainingRunQuoteInputsTrainingReportAnyOf.ts +9 -0
- package/openapi/gen/models/trainingRunQuoteInputsTrainingReportAnyOfErrorsItem.ts +5 -0
- package/openapi/gen/models/trainingRunQuoteInputsTrainingReportAnyOfTokens.ts +10 -0
- package/openapi/gen/models/trainingRunQuoteInputsTrainingReportAnyOfTokensEstimatorVersion.ts +2 -0
- package/openapi/gen/models/trainingRunQuoteInputsTrainingReportAnyOfTokensTotal.ts +2 -0
- package/openapi/gen/models/trainingRunQuoteInputsValidation.ts +3 -0
- package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOf.ts +9 -0
- package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfFailure.ts +3 -0
- package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfFailureAnyOf.ts +7 -0
- package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfFailureAnyOfCode.ts +2 -0
- package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfReport.ts +3 -0
- package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfReportAnyOf.ts +9 -0
- package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfReportAnyOfErrorsItem.ts +5 -0
- package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfReportAnyOfTokens.ts +10 -0
- package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfReportAnyOfTokensEstimatorVersion.ts +2 -0
- package/openapi/gen/models/trainingRunQuoteInputsValidationAnyOfReportAnyOfTokensTotal.ts +2 -0
- package/openapi/gen/models/trainingRunStatus.ts +2 -0
- package/openapi/gen/models/updateTrainingMetadataBody.ts +5 -0
- package/package.json +1 -1
- package/skills/catalog.json +19 -7
- package/skills/toloka-build/SKILL.md +3 -3
- package/skills/toloka-build/references/workflow-and-cli.md +19 -2
- package/skills/toloka-report-issue/references/report-template.md +1 -1
- package/src/cli/auth.ts +1 -1
- package/src/cli/bin.ts +1 -1
- package/src/cli/cost.ts +1 -1
- package/src/cli/models.ts +107 -2
- package/src/cli/program.ts +243 -0
- package/src/cli/project-context.ts +9 -10
- package/src/cli/project.ts +2 -1
- package/src/cli/secrets.ts +4 -4
- package/src/cli/trainings.ts +627 -0
- package/src/client.ts +164 -30
- package/src/index.ts +2 -0
- package/openapi/gen/models/createDatasetExportBodyOneOf.ts +0 -6
- package/openapi/gen/models/createDatasetExportBodyOneOfFormat.ts +0 -2
- package/openapi/gen/models/createDatasetExportBodyOneOfThree.ts +0 -10
- package/openapi/gen/models/createDatasetExportBodyOneOfThreeContract.ts +0 -2
- package/openapi/gen/models/createDatasetExportBodyOneOfThreeFormat.ts +0 -2
- package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilter.ts +0 -9
- package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldSourcesItem.ts +0 -6
- package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldSourcesItemSourcesItem.ts +0 -4
- package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldSourcesItemSourcesItemOneOf.ts +0 -5
- package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldSourcesItemSourcesItemOneOfTwo.ts +0 -5
- package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldValuesItem.ts +0 -12
- package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldValuesItemOperator.ts +0 -2
- package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldValuesItemSourcesItem.ts +0 -4
- package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldValuesItemSourcesItemOneOf.ts +0 -5
- package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldValuesItemSourcesItemOneOfTwo.ts +0 -5
- package/openapi/gen/models/createDatasetExportBodyOneOfThreeItemFilterFieldValuesItemValue.ts +0 -2
package/src/cli/program.ts
CHANGED
|
@@ -48,6 +48,7 @@ import {
|
|
|
48
48
|
import {
|
|
49
49
|
archiveModel,
|
|
50
50
|
createModel,
|
|
51
|
+
downloadModelVersion,
|
|
51
52
|
getBaseModel,
|
|
52
53
|
getModel,
|
|
53
54
|
listBaseModels,
|
|
@@ -79,6 +80,20 @@ import {
|
|
|
79
80
|
pipelineRunStatus,
|
|
80
81
|
startPipelineRun,
|
|
81
82
|
} from "./runs";
|
|
83
|
+
import {
|
|
84
|
+
cancelTrainingRun,
|
|
85
|
+
createTraining,
|
|
86
|
+
createTrainingRun,
|
|
87
|
+
estimateTrainingCost,
|
|
88
|
+
getTraining,
|
|
89
|
+
getTrainingRun,
|
|
90
|
+
readTrainingRunLogs,
|
|
91
|
+
listTrainingRuns,
|
|
92
|
+
resumeTrainingRun,
|
|
93
|
+
listTrainings,
|
|
94
|
+
updateTraining,
|
|
95
|
+
} from "./trainings";
|
|
96
|
+
import type { TrainingDraftOptions } from "./trainings";
|
|
82
97
|
|
|
83
98
|
import type { RunOutcome } from "./runs";
|
|
84
99
|
import { skillInstallCommand, skillListCommand, skillSearchCommand } from "./skill";
|
|
@@ -129,6 +144,55 @@ const positiveInteger = (raw: string): number => {
|
|
|
129
144
|
return value;
|
|
130
145
|
};
|
|
131
146
|
|
|
147
|
+
const nonNegativeInteger = (raw: string): number => {
|
|
148
|
+
const value = Number(raw);
|
|
149
|
+
if (!Number.isInteger(value) || value < 0)
|
|
150
|
+
throw new InvalidArgumentError("Expected a non-negative integer.");
|
|
151
|
+
return value;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const trainingMethod = (raw: string): "sft" | "gisting" => {
|
|
155
|
+
if (raw !== "sft" && raw !== "gisting") {
|
|
156
|
+
throw new InvalidArgumentError('Expected training method "sft" or "gisting".');
|
|
157
|
+
}
|
|
158
|
+
return raw;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const trainingRegime = (raw: string): "low" | "medium" | "high" => {
|
|
162
|
+
if (raw !== "low" && raw !== "medium" && raw !== "high") {
|
|
163
|
+
throw new InvalidArgumentError('Expected regime "low", "medium", or "high".');
|
|
164
|
+
}
|
|
165
|
+
return raw;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
type RawTrainingDraftOptions = {
|
|
169
|
+
method?: TrainingDraftOptions["method"];
|
|
170
|
+
baseModel?: TrainingDraftOptions["baseModelId"];
|
|
171
|
+
modelVersion?: string;
|
|
172
|
+
dataset?: string;
|
|
173
|
+
validationDataset?: string;
|
|
174
|
+
trainFilter?: string;
|
|
175
|
+
validationFilter?: string;
|
|
176
|
+
regime?: TrainingDraftOptions["regime"];
|
|
177
|
+
epochs?: number;
|
|
178
|
+
evalSteps?: number;
|
|
179
|
+
promptFile?: string;
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
const trainingDraftOptions = (options: RawTrainingDraftOptions): TrainingDraftOptions => ({
|
|
183
|
+
method: options.method,
|
|
184
|
+
baseModelId: options.baseModel,
|
|
185
|
+
modelVersionId: options.modelVersion,
|
|
186
|
+
datasetId: options.dataset,
|
|
187
|
+
validationDatasetId: options.validationDataset,
|
|
188
|
+
trainingFilter: options.trainFilter,
|
|
189
|
+
validationFilter: options.validationFilter,
|
|
190
|
+
regime: options.regime,
|
|
191
|
+
epochs: options.epochs,
|
|
192
|
+
evalSteps: options.evalSteps,
|
|
193
|
+
promptFilePath: options.promptFile,
|
|
194
|
+
});
|
|
195
|
+
|
|
132
196
|
const exitCodeForOutcome = (outcome: RunOutcome): number => {
|
|
133
197
|
if (outcome === "failed") return 1;
|
|
134
198
|
if (outcome === "timedOut") return 2;
|
|
@@ -798,6 +862,185 @@ export function createProgram(context: ProgramContext): CreatedProgram {
|
|
|
798
862
|
await archiveModel(client, { projectId, nameOrId, json: options.json }, context.io);
|
|
799
863
|
});
|
|
800
864
|
|
|
865
|
+
const modelVersion = model.command("version").description("manage one immutable Model Version");
|
|
866
|
+
modelVersion
|
|
867
|
+
.command("download")
|
|
868
|
+
.argument("<model-version>", "Model Version ID or Model@name")
|
|
869
|
+
.requiredOption("--out <directory>", "output directory")
|
|
870
|
+
.description("download and verify Model Version content")
|
|
871
|
+
.action(async (modelVersionId: string, options: { out: string }) => {
|
|
872
|
+
const { client, projectId } = await resolveContext(globals(), context);
|
|
873
|
+
await downloadModelVersion(
|
|
874
|
+
client,
|
|
875
|
+
{ projectId, modelVersionId, out: options.out },
|
|
876
|
+
context.io,
|
|
877
|
+
);
|
|
878
|
+
});
|
|
879
|
+
|
|
880
|
+
const training = program.command("training").description("manage project Training drafts");
|
|
881
|
+
training
|
|
882
|
+
.command("list")
|
|
883
|
+
.option("--json", "print JSON", false)
|
|
884
|
+
.description("list active Trainings owned by the selected project")
|
|
885
|
+
.action(async (options: { json: boolean }) => {
|
|
886
|
+
const { client, projectId } = await resolveContext(globals(), context);
|
|
887
|
+
assert(projectId, MISSING_PROJECT_ID_MESSAGE);
|
|
888
|
+
await listTrainings(client, { projectId, json: options.json }, context.io);
|
|
889
|
+
});
|
|
890
|
+
training
|
|
891
|
+
.command("get")
|
|
892
|
+
.argument("<name-or-id>", "Training name or ID")
|
|
893
|
+
.option("--json", "print JSON", false)
|
|
894
|
+
.description("show one Training draft")
|
|
895
|
+
.action(async (nameOrId: string, options: { json: boolean }) => {
|
|
896
|
+
const { client, projectId } = await resolveContext(globals(), context);
|
|
897
|
+
assert(projectId, MISSING_PROJECT_ID_MESSAGE);
|
|
898
|
+
await getTraining(client, { projectId, nameOrId, json: options.json }, context.io);
|
|
899
|
+
});
|
|
900
|
+
training
|
|
901
|
+
.command("create")
|
|
902
|
+
.argument("<name>", "new Training name")
|
|
903
|
+
.option("--method <method>", "Training method", trainingMethod, "sft")
|
|
904
|
+
.option("--base-model <id>", "catalog Base Model source", parseBaseModelId)
|
|
905
|
+
.option("--model-version <id>", "exact Model Version source")
|
|
906
|
+
.requiredOption("--dataset <id>", "required training Dataset ID")
|
|
907
|
+
.option("--validation-dataset <id>", "optional validation Dataset ID")
|
|
908
|
+
.option("--train-filter <field=value>", "training Dataset field equality filter")
|
|
909
|
+
.option("--validation-filter <field=value>", "validation Dataset field equality filter")
|
|
910
|
+
.option("--regime <regime>", "Python training regime", trainingRegime)
|
|
911
|
+
.option("--epochs <count>", "training epochs", nonNegativeInteger)
|
|
912
|
+
.option("--eval-steps <count>", "SFT eval steps", positiveInteger)
|
|
913
|
+
.option("--prompt-file <path>", "gisting prompt text file")
|
|
914
|
+
.option("--json", "print JSON", false)
|
|
915
|
+
.description("create a normalized Training draft")
|
|
916
|
+
.action(async (name: string, options: RawTrainingDraftOptions & { json: boolean }) => {
|
|
917
|
+
const { client, projectId } = await resolveContext(globals(), context);
|
|
918
|
+
assert(projectId, MISSING_PROJECT_ID_MESSAGE);
|
|
919
|
+
await createTraining(
|
|
920
|
+
client,
|
|
921
|
+
{
|
|
922
|
+
...trainingDraftOptions(options),
|
|
923
|
+
projectId,
|
|
924
|
+
name,
|
|
925
|
+
json: options.json,
|
|
926
|
+
},
|
|
927
|
+
context.io,
|
|
928
|
+
);
|
|
929
|
+
});
|
|
930
|
+
training
|
|
931
|
+
.command("update")
|
|
932
|
+
.argument("<name-or-id>", "Training name or ID")
|
|
933
|
+
.option("--base-model <id>", "catalog Base Model source", parseBaseModelId)
|
|
934
|
+
.option("--model-version <id>", "exact Model Version source")
|
|
935
|
+
.option("--dataset <id>", "required training Dataset ID")
|
|
936
|
+
.option("--validation-dataset <id>", "replacement validation Dataset ID")
|
|
937
|
+
.option("--train-filter <field=value>", "replacement training Dataset field equality filter")
|
|
938
|
+
.option("--validation-filter <field=value>", "replacement validation Dataset field equality filter")
|
|
939
|
+
.option("--regime <regime>", "Python training regime", trainingRegime)
|
|
940
|
+
.option("--epochs <count>", "training epochs", nonNegativeInteger)
|
|
941
|
+
.option("--eval-steps <count>", "SFT eval steps", positiveInteger)
|
|
942
|
+
.option("--prompt-file <path>", "replacement gisting prompt text file")
|
|
943
|
+
.option("--json", "print JSON", false)
|
|
944
|
+
.description("replace the complete Training draft")
|
|
945
|
+
.action(async (nameOrId: string, options: RawTrainingDraftOptions & { json: boolean }) => {
|
|
946
|
+
const { client, projectId } = await resolveContext(globals(), context);
|
|
947
|
+
assert(projectId, MISSING_PROJECT_ID_MESSAGE);
|
|
948
|
+
await updateTraining(
|
|
949
|
+
client,
|
|
950
|
+
{
|
|
951
|
+
...trainingDraftOptions(options),
|
|
952
|
+
projectId,
|
|
953
|
+
nameOrId,
|
|
954
|
+
json: options.json,
|
|
955
|
+
},
|
|
956
|
+
context.io,
|
|
957
|
+
);
|
|
958
|
+
});
|
|
959
|
+
training
|
|
960
|
+
.command("cost")
|
|
961
|
+
.argument("<name-or-id>", "Training name or ID")
|
|
962
|
+
.option("--idempotency-key <key>", "reuse one Cost Estimate input preparation")
|
|
963
|
+
.option("--json", "print JSON", false)
|
|
964
|
+
.description("validate Training inputs and calculate the maximum charge")
|
|
965
|
+
.action(async (nameOrId: string, options: { idempotencyKey?: string; json: boolean }) => {
|
|
966
|
+
const { client, projectId } = await resolveContext(globals(), context);
|
|
967
|
+
assert(projectId, MISSING_PROJECT_ID_MESSAGE);
|
|
968
|
+
await estimateTrainingCost(
|
|
969
|
+
client,
|
|
970
|
+
{ projectId, nameOrId, idempotencyKey: options.idempotencyKey, json: options.json },
|
|
971
|
+
context.io,
|
|
972
|
+
);
|
|
973
|
+
});
|
|
974
|
+
training
|
|
975
|
+
.command("run")
|
|
976
|
+
.argument("<name-or-id>", "Training name or ID")
|
|
977
|
+
.requiredOption("--estimate-file <path>", "ready Training Cost Estimate JSON")
|
|
978
|
+
.requiredOption("--version-name <name>", "unique Model Version name for this run")
|
|
979
|
+
.option("--idempotency-key <key>", "reuse one Training Run creation")
|
|
980
|
+
.option("--json", "print JSON", false)
|
|
981
|
+
.description("create one queued Training Run from a ready Cost Estimate")
|
|
982
|
+
.action(
|
|
983
|
+
async (
|
|
984
|
+
nameOrId: string,
|
|
985
|
+
options: {
|
|
986
|
+
estimateFile: string;
|
|
987
|
+
versionName: string;
|
|
988
|
+
idempotencyKey?: string;
|
|
989
|
+
json: boolean;
|
|
990
|
+
},
|
|
991
|
+
) => {
|
|
992
|
+
const { client, projectId } = await resolveContext(globals(), context);
|
|
993
|
+
assert(projectId, MISSING_PROJECT_ID_MESSAGE);
|
|
994
|
+
await createTrainingRun(client, { projectId, nameOrId, ...options }, context.io);
|
|
995
|
+
},
|
|
996
|
+
);
|
|
997
|
+
training
|
|
998
|
+
.command("runs")
|
|
999
|
+
.argument("<name-or-id>", "Training name or ID")
|
|
1000
|
+
.option("--json", "print JSON", false)
|
|
1001
|
+
.description("list Training Run history")
|
|
1002
|
+
.action(async (nameOrId: string, options: { json: boolean }) => {
|
|
1003
|
+
const { client, projectId } = await resolveContext(globals(), context);
|
|
1004
|
+
assert(projectId, MISSING_PROJECT_ID_MESSAGE);
|
|
1005
|
+
await listTrainingRuns(client, { projectId, nameOrId, json: options.json }, context.io);
|
|
1006
|
+
});
|
|
1007
|
+
training
|
|
1008
|
+
.command("status")
|
|
1009
|
+
.argument("<training-run-id>", "Training Run ID")
|
|
1010
|
+
.option("--json", "print JSON", false)
|
|
1011
|
+
.description("show one Training Run")
|
|
1012
|
+
.action(async (trainingRunId: string, options: { json: boolean }) => {
|
|
1013
|
+
const { client } = await resolveContext(globals(), context);
|
|
1014
|
+
await getTrainingRun(client, { trainingRunId, json: options.json }, context.io);
|
|
1015
|
+
});
|
|
1016
|
+
training
|
|
1017
|
+
.command("resume")
|
|
1018
|
+
.argument("<training-run-id>", "Training Run ID")
|
|
1019
|
+
.option("--json", "print JSON", false)
|
|
1020
|
+
.description("resume a Training Run blocked on funds or payment")
|
|
1021
|
+
.action(async (trainingRunId: string, options: { json: boolean }) => {
|
|
1022
|
+
const { client } = await resolveContext(globals(), context);
|
|
1023
|
+
await resumeTrainingRun(client, { trainingRunId, json: options.json }, context.io);
|
|
1024
|
+
});
|
|
1025
|
+
training
|
|
1026
|
+
.command("cancel")
|
|
1027
|
+
.argument("<training-run-id>", "Training Run ID")
|
|
1028
|
+
.option("--json", "print JSON", false)
|
|
1029
|
+
.description("cancel a Training Run before provider work completes")
|
|
1030
|
+
.action(async (trainingRunId: string, options: { json: boolean }) => {
|
|
1031
|
+
const { client } = await resolveContext(globals(), context);
|
|
1032
|
+
await cancelTrainingRun(client, { trainingRunId, json: options.json }, context.io);
|
|
1033
|
+
});
|
|
1034
|
+
training
|
|
1035
|
+
.command("logs")
|
|
1036
|
+
.argument("<training-run-id>", "Training Run ID")
|
|
1037
|
+
.option("--follow", "wait for new log entries until complete", false)
|
|
1038
|
+
.description("read sanitized Training Run logs")
|
|
1039
|
+
.action(async (trainingRunId: string, options: { follow: boolean }) => {
|
|
1040
|
+
const { client } = await resolveContext(globals(), context);
|
|
1041
|
+
await readTrainingRunLogs(client, { trainingRunId, follow: options.follow }, context.io);
|
|
1042
|
+
});
|
|
1043
|
+
|
|
801
1044
|
const dataset = program
|
|
802
1045
|
.command("dataset")
|
|
803
1046
|
.description("inspect and move dataset catalog and rows");
|
|
@@ -35,10 +35,10 @@ export type ProjectCreateApi = {
|
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
export const MISSING_PROJECT_ID_MESSAGE =
|
|
38
|
-
"Missing project ID. Pass --project-id, set TOLOKA_PROJECT_ID,
|
|
38
|
+
"Missing project ID. Pass --project-id, set TOLOKA_PROJECT_ID, use a bound toloka.json, run toloka project create for a new project, or run toloka project add for an existing project.";
|
|
39
39
|
|
|
40
40
|
export const NO_PROJECT_SELECTED_MESSAGE =
|
|
41
|
-
"No project selected. Run toloka project add, or cd into a checkout.";
|
|
41
|
+
"No project selected. Run toloka project create for a new project, toloka project add for an existing project, or cd into a checkout.";
|
|
42
42
|
|
|
43
43
|
const NETWORK_MISMATCH_MESSAGE =
|
|
44
44
|
"project add writes the machine registry; unset --api-key / --base-url / POTATO_API_KEY / POTATO_BASE_URL, or run login against that platform first.";
|
|
@@ -168,7 +168,8 @@ export const formatProjectContextLine = (
|
|
|
168
168
|
project: ProjectContext | undefined,
|
|
169
169
|
stored?: StoredCredentials,
|
|
170
170
|
): string => {
|
|
171
|
-
if (project === undefined)
|
|
171
|
+
if (project === undefined)
|
|
172
|
+
return "Project: (none). Run toloka project create or toloka project add.";
|
|
172
173
|
const alias = project.alias === undefined ? "" : `alias ${project.alias}, `;
|
|
173
174
|
const registryNote =
|
|
174
175
|
project.source !== "registry" && stored?.current !== undefined
|
|
@@ -232,14 +233,12 @@ export async function listRemoteProjects(options: {
|
|
|
232
233
|
}): Promise<{ readonly output: string }> {
|
|
233
234
|
const limit = options.limit ?? 20;
|
|
234
235
|
const page = await options.client.projects.listPage({ limit });
|
|
235
|
-
const
|
|
236
|
-
const
|
|
237
|
-
const alias =
|
|
238
|
-
|
|
239
|
-
? `\t${options.context.alias}`
|
|
240
|
-
: "";
|
|
241
|
-
return `${mark}\t${project.id}\t${project.name}\t${project.teamId}${alias}`;
|
|
236
|
+
const rows = page.projects.map((project) => {
|
|
237
|
+
const current = options.context?.id === project.id;
|
|
238
|
+
const alias = current ? (options.context.alias ?? "-") : "-";
|
|
239
|
+
return `${current ? "*" : "-"}\t${project.id}\t${project.name}\t${alias}`;
|
|
242
240
|
});
|
|
241
|
+
const lines = rows.length === 0 ? [] : ["CURRENT\tID\tNAME\tALIAS", ...rows];
|
|
243
242
|
if (page.pagination.hasMore) {
|
|
244
243
|
lines.push(
|
|
245
244
|
`Showing ${page.projects.length} of ${page.pagination.total} projects. Raise --limit to see more.`,
|
package/src/cli/project.ts
CHANGED
|
@@ -848,10 +848,11 @@ export async function applyProject(
|
|
|
848
848
|
if (valueKey(inspection.state) !== valueKey(nextState))
|
|
849
849
|
await writeTolokaState(options.sourceRoot, nextState);
|
|
850
850
|
const action = writes === 0 ? "unchanged" : "changed";
|
|
851
|
+
const plannedChanges = inspection.changes.length;
|
|
851
852
|
const output =
|
|
852
853
|
writes === 0
|
|
853
854
|
? "No changes."
|
|
854
|
-
: `Applied ${writes} ${writes === 1 ? "write" : "writes"} to project ${inspection.projectId}.`;
|
|
855
|
+
: `Applied ${plannedChanges} planned ${plannedChanges === 1 ? "change" : "changes"} with ${writes} platform ${writes === 1 ? "write" : "writes"} to project ${inspection.projectId}.`;
|
|
855
856
|
return {
|
|
856
857
|
action,
|
|
857
858
|
state: nextState,
|
package/src/cli/secrets.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import type { PipelineGraphV1 } from
|
|
1
|
+
import type { PipelineGraphV1 } from "../../openapi/gen/models";
|
|
2
2
|
|
|
3
3
|
export function collectGraphSecretNames(graph: {
|
|
4
|
-
readonly nodes: ReadonlyArray<PipelineGraphV1[
|
|
4
|
+
readonly nodes: ReadonlyArray<PipelineGraphV1["nodes"][number]>;
|
|
5
5
|
}): readonly string[] {
|
|
6
6
|
const names = new Set<string>();
|
|
7
7
|
for (const node of graph.nodes) {
|
|
8
|
-
if (node.type !==
|
|
8
|
+
if (node.type !== "code") continue;
|
|
9
9
|
for (const environmentVariable of node.settings.envVars ?? []) {
|
|
10
|
-
if (environmentVariable.type ===
|
|
10
|
+
if (environmentVariable.type === "secret") names.add(environmentVariable.secretName);
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
return [...names].toSorted((left, right) => left.localeCompare(right));
|