bailian-cli-commands 1.18.1 → 1.18.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.
package/dist/index.d.mts CHANGED
@@ -3864,6 +3864,13 @@ declare const _default$114: _$bailian_cli_core0.Command<{
3864
3864
  "zh-CN": string;
3865
3865
  };
3866
3866
  };
3867
+ yes: {
3868
+ type: "switch";
3869
+ description: {
3870
+ "en-US": string;
3871
+ "zh-CN": string;
3872
+ };
3873
+ };
3867
3874
  }>;
3868
3875
  //#endregion
3869
3876
  //#region src/commands/quota/history.d.ts
@@ -4115,6 +4122,13 @@ declare const _default$14: _$bailian_cli_core0.Command<{
4115
4122
  };
4116
4123
  required: true;
4117
4124
  };
4125
+ yes: {
4126
+ type: "switch";
4127
+ description: {
4128
+ "en-US": string;
4129
+ "zh-CN": string;
4130
+ };
4131
+ };
4118
4132
  }>;
4119
4133
  //#endregion
4120
4134
  //#region src/commands/dataset/validate.d.ts
@@ -4481,6 +4495,13 @@ declare const _default$31: _$bailian_cli_core0.Command<{
4481
4495
  };
4482
4496
  required: true;
4483
4497
  };
4498
+ yes: {
4499
+ type: "switch";
4500
+ description: {
4501
+ "en-US": string;
4502
+ "zh-CN": string;
4503
+ };
4504
+ };
4484
4505
  }>;
4485
4506
  //#endregion
4486
4507
  //#region src/commands/finetune/logs.d.ts
@@ -5079,6 +5100,13 @@ declare const _default$19: _$bailian_cli_core0.Command<{
5079
5100
  "zh-CN": string;
5080
5101
  };
5081
5102
  };
5103
+ yes: {
5104
+ type: "switch";
5105
+ description: {
5106
+ "en-US": string;
5107
+ "zh-CN": string;
5108
+ };
5109
+ };
5082
5110
  }>;
5083
5111
  //#endregion
5084
5112
  //#region src/commands/deploy/pause.d.ts
package/dist/index.mjs CHANGED
@@ -2781,7 +2781,7 @@ Hint: Add --diarization flag to enable speaker separation.`,c.USAGE);let s=r.mod
2781
2781
  `)}var Gd=w({description:{"en-US":`List all workspaces`,"zh-CN":`列出全部 Workspace`},auth:`console`,usageArgs:`[flags]`,flags:{list:{type:`string`,valueHint:`<n>`,description:{"en-US":`Limit number of results`,"zh-CN":`限制结果数量`}}},exampleArgs:[``,`--list 5`,`--output json`],async run(e){let{settings:t,flags:n}=e,r=Number(n.list)||0,i=T(t.output);if(t.dryRun){A({api:Vd,data:{}},i);return}let a=Ud(await e.client.console(Vd,{})).data;if(!Array.isArray(a)||a.length===0){i===`json`?A([],i):process.stdout.write(`No workspace found.
2782
2782
  `);return}let o=a;if(r>0&&(o=o.slice(0,r)),i===`json`){A(o.map(e=>({workspaceId:e.workspaceId,name:e.agentName,default:e.defaultAgent})),i);return}Wd(o)}});function Kd(e){return[...new Set(e.split(`,`).map(e=>e.trim()).filter(Boolean))]}function qd(e){let t=new URLSearchParams;for(let[n,r]of Object.entries(e))r!==void 0&&r!==``&&t.set(n,String(r));let n=t.toString();return n?`?${n}`:``}function Jd(e,t){if(e==null)return`-`;let n=t??60;return n===1?`${q(e)}/s`:n===60?`${q(e)}/min`:`${q(e)}/${n}s`}function Yd(e){return e?Jd(e.request_limit,e.request_limit_period):`-`}function Xd(e){return e?Jd(e.usage_limit,e.usage_limit_period):`-`}function Zd(e){return!e||e.async_user_queue_limit==null&&e.async_user_concurrency_limit==null?`-`:`${e.async_user_queue_limit==null?`-`:q(e.async_user_queue_limit)}/${e.async_user_concurrency_limit==null?`-`:q(e.async_user_concurrency_limit)}`}function Qd(e,t){if(e.length===0){process.stdout.write(`No rate limits found.
2783
2783
  `);return}let n=Fn({headers:[`Model`,`Req Limit`,`Usage Limit`,`WS Req`,`WS Usage`,`Async Q/C`],rows:e.map(e=>[e.model,Yd(e.model_limit),Xd(e.model_limit),Yd(e.workspace_limit),Xd(e.workspace_limit),Zd(e.model_limit)]),align:[`left`,`right`,`right`,`right`,`right`,`right`]});for(let e of n)process.stdout.write(e+`
2784
- `);process.stdout.write(`\nTotal: ${t}\n`)}var $d=w({description:{"en-US":`View model rate limits (QPM/TPM, account and workspace level)`,"zh-CN":`查看模型限流配置(QPM/TPM,账号级和 Workspace 级)`},auth:`apiKey`,usageArgs:`[--model <model>] [--name <name>] [--page <n>] [--page-size <n>]`,flags:{model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Model name(s), comma-separated (exact match)`,"zh-CN":`模型名称,多个以逗号分隔(精确匹配)`}},name:{type:`string`,valueHint:`<name>`,description:{"en-US":`Fuzzy search by model name`,"zh-CN":`按模型名称模糊搜索`}},page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Results per page (default: 20)`,"zh-CN":`每页结果数(默认:20)`}}},exampleArgs:[``,`--model qwen3-max`,`--model qwen3-max,qwen-plus`,`--name qwen --page-size 50`,`--output json`],notes:[{"en-US":"Usage-vs-limit pressure checks live in `quota check` (console auth).","zh-CN":"用量与限流压力检查位于 `quota check`(Console 鉴权)。"}],async run(e){let{settings:t,flags:n}=e,r=n.model||void 0,i=n.name||void 0,a=T(t.output),o=e.client.url(St());if(t.dryRun){A(r?{requests:Kd(r).map(e=>({endpoint:o,method:`GET`,query:{model:e,page_size:100}}))}:{endpoint:o,method:`GET`,query:{name:i,page_no:n.page||1,page_size:n.pageSize||20}},a);return}let s,c;if(r)s=(await Promise.all(Kd(r).map(t=>e.client.requestJson({path:St()+qd({model:t,page_size:100})})))).flatMap(e=>e.output?.quotas??[]),c=s.length;else{let t=await e.client.requestJson({path:St()+qd({name:i,page_no:n.page||1,page_size:n.pageSize||20})});s=t.output?.quotas??[],c=t.output?.total??s.length}if(a===`json`){A({items:s,total:c},a);return}Qd(s,c)}}),ef=w({description:{"en-US":`Update model rate limits (QPM/TPM), or clear them with --delete`,"zh-CN":`更新模型限流配置(QPM/TPM),或使用 --delete 清除配置`},auth:`apiKey`,usageArgs:`--model <model> [--rpm <n>] [--tpm <n>] [--delete]`,flags:{model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Model name (required)`,"zh-CN":`模型名称(必填)`},required:!0},rpm:{type:`number`,valueHint:`<n>`,description:{"en-US":`Max requests per minute (QPM)`,"zh-CN":`每分钟最大请求数(QPM)`}},tpm:{type:`number`,valueHint:`<n>`,description:{"en-US":`Max tokens per minute (TPM)`,"zh-CN":`每分钟最大 Token 数(TPM)`}},delete:{type:`switch`,description:{"en-US":`Clear all custom rate limits for the model`,"zh-CN":`清除该模型的所有自定义限流配置`}}},exampleArgs:[`--model qwen-plus --rpm 60 --tpm 100000`,`--model qwen3-max --tpm 500000`,`--model qwen-plus --delete`,`--model qwen-plus --rpm 60 --output json`],notes:[{"en-US":`Fields you omit keep their current values (server-side OVERLAY merge); --delete clears all custom limits.`,"zh-CN":`未指定的字段将保留当前值(服务端 OVERLAY 合并);--delete 会清除所有自定义限流配置。`},{"en-US":`Setting TPM without an existing QPM limit is rejected server-side — pass --rpm first or together.`,"zh-CN":`若当前没有 QPM 限制,单独设置 TPM 会被服务端拒绝——请先设置 --rpm,或同时传入。`}],validate:e=>{if(e.delete&&(e.rpm!==void 0||e.tpm!==void 0))return`--delete cannot be combined with --rpm/--tpm.`;if(!e.delete&&e.rpm===void 0&&e.tpm===void 0)return`one of --rpm / --tpm / --delete is required.`;if(e.rpm!==void 0&&e.rpm<0)return`--rpm must be a non-negative number.`;if(e.tpm!==void 0&&e.tpm<0)return`--tpm must be a non-negative number.`},async run(e){let{settings:t,flags:n}=e,r=n.model,i=T(t.output),a={model:r};n.delete?a.operation_type=`DELETE`:(n.rpm!==void 0&&(a.request_limit=n.rpm,a.request_limit_period=60),n.tpm!==void 0&&(a.usage_limit=n.tpm,a.usage_limit_period=60));let o={models:[a]};if(t.dryRun){A({endpoint:e.client.url(St()),method:`POST`,request:o},i);return}let s=await e.client.requestJson({path:St(),method:`POST`,body:o});if(i===`json`){A({model:r,...s},i);return}if(n.delete){process.stdout.write(`Rate limits cleared for "${r}".\n`);return}let c=[];n.rpm!==void 0&&c.push(`QPM ${q(n.rpm)}`),n.tpm!==void 0&&c.push(`TPM ${q(n.tpm)}`),process.stdout.write(`Rate limits updated for "${r}": ${c.join(`, `)}\n`)}});const tf=`zeldaEasy.broadscope-platform.modelInstance.listModelLimitApplications`;function nf(e,t){let n=e[t];if(n&&typeof n==`object`&&!Array.isArray(n))return n}function rf(e){let t=nf(e,`data`);if(!t)return e;let n=nf(t,`DataV2`);if(n){let e=nf(n,`data`);return(e?nf(e,`data`):void 0)??e??n}return nf(t,`data`)??t}function af(e){if(!e)return`-`;try{let t=new Date(e);return isNaN(t.getTime())?e:`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)} ${String(t.getHours()).padStart(2,`0`)}:${String(t.getMinutes()).padStart(2,`0`)}`}catch{return e}}function of(e,t){let n=O(process.stdout),r=[`Model`,`Token Limit`,`Applied At`],i=e.map(e=>[e.deployedModel,q(e.usageLimit),af(e.gmtCreate)]),a=r.map((e,t)=>Math.max(xn(e),...i.map(e=>xn(e[t])))),o=r.map((e,t)=>n.bold(M(e,a[t]))).join(` `),s=a.map(e=>n.dim(`─`.repeat(e))).join(`──`);process.stdout.write(o+`
2784
+ `);process.stdout.write(`\nTotal: ${t}\n`)}var $d=w({description:{"en-US":`View model rate limits (QPM/TPM, account and workspace level)`,"zh-CN":`查看模型限流配置(QPM/TPM,账号级和 Workspace 级)`},auth:`apiKey`,usageArgs:`[--model <model>] [--name <name>] [--page <n>] [--page-size <n>]`,flags:{model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Model name(s), comma-separated (exact match)`,"zh-CN":`模型名称,多个以逗号分隔(精确匹配)`}},name:{type:`string`,valueHint:`<name>`,description:{"en-US":`Fuzzy search by model name`,"zh-CN":`按模型名称模糊搜索`}},page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Results per page (default: 20)`,"zh-CN":`每页结果数(默认:20)`}}},exampleArgs:[``,`--model qwen3-max`,`--model qwen3-max,qwen-plus`,`--name qwen --page-size 50`,`--output json`],notes:[{"en-US":"Usage-vs-limit pressure checks live in `quota check` (console auth).","zh-CN":"用量与限流压力检查位于 `quota check`(Console 鉴权)。"}],async run(e){let{settings:t,flags:n}=e,r=n.model||void 0,i=n.name||void 0,a=T(t.output),o=e.client.url(St());if(t.dryRun){A(r?{requests:Kd(r).map(e=>({endpoint:o,method:`GET`,query:{model:e,page_size:100}}))}:{endpoint:o,method:`GET`,query:{name:i,page_no:n.page||1,page_size:n.pageSize||20}},a);return}let s,c;if(r)s=(await Promise.all(Kd(r).map(t=>e.client.requestJson({path:St()+qd({model:t,page_size:100})})))).flatMap(e=>e.output?.quotas??[]),c=s.length;else{let t=await e.client.requestJson({path:St()+qd({name:i,page_no:n.page||1,page_size:n.pageSize||20})});s=t.output?.quotas??[],c=t.output?.total??s.length}if(a===`json`){A({items:s,total:c},a);return}Qd(s,c)}}),ef=w({description:{"en-US":`Update model rate limits (QPM/TPM), or clear them with --delete`,"zh-CN":`更新模型限流配置(QPM/TPM),或使用 --delete 清除配置`},auth:`apiKey`,usageArgs:`--model <model> [--rpm <n>] [--tpm <n>] [--delete] [--yes]`,flags:{model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Model name (required)`,"zh-CN":`模型名称(必填)`},required:!0},rpm:{type:`number`,valueHint:`<n>`,description:{"en-US":`Max requests per minute (QPM)`,"zh-CN":`每分钟最大请求数(QPM)`}},tpm:{type:`number`,valueHint:`<n>`,description:{"en-US":`Max tokens per minute (TPM)`,"zh-CN":`每分钟最大 Token 数(TPM)`}},delete:{type:`switch`,description:{"en-US":`Clear all custom rate limits for the model`,"zh-CN":`清除该模型的所有自定义限流配置`}},yes:{type:`switch`,description:{"en-US":`Skip the confirmation prompt for --delete`,"zh-CN":`使用 --delete 时跳过确认提示`}}},exampleArgs:[`--model qwen-plus --rpm 60 --tpm 100000`,`--model qwen3-max --tpm 500000`,`--model qwen-plus --delete`,`--model qwen-plus --delete --yes`,`--model qwen-plus --rpm 60 --output json`],notes:[{"en-US":`Fields you omit keep their current values (server-side OVERLAY merge); --delete clears all custom limits.`,"zh-CN":`未指定的字段将保留当前值(服务端 OVERLAY 合并);--delete 会清除所有自定义限流配置。`},{"en-US":`--delete requires confirmation; pass --yes to skip the prompt in scripts.`,"zh-CN":`--delete 需要确认;脚本中可加 --yes 跳过交互提示。`},{"en-US":`Setting TPM without an existing QPM limit is rejected server-side — pass --rpm first or together.`,"zh-CN":`若当前没有 QPM 限制,单独设置 TPM 会被服务端拒绝——请先设置 --rpm,或同时传入。`}],validate:e=>{if(e.delete&&(e.rpm!==void 0||e.tpm!==void 0))return`--delete cannot be combined with --rpm/--tpm.`;if(!e.delete&&e.rpm===void 0&&e.tpm===void 0)return`one of --rpm / --tpm / --delete is required.`;if(e.rpm!==void 0&&e.rpm<0)return`--rpm must be a non-negative number.`;if(e.tpm!==void 0&&e.tpm<0)return`--tpm must be a non-negative number.`},async run(e){let{settings:t,flags:n}=e,r=n.model,i=T(t.output),a={model:r};n.delete?a.operation_type=`DELETE`:(n.rpm!==void 0&&(a.request_limit=n.rpm,a.request_limit_period=60),n.tpm!==void 0&&(a.usage_limit=n.tpm,a.usage_limit_period=60));let o={models:[a]};if(t.dryRun){A({endpoint:e.client.url(St()),method:`POST`,request:o},i);return}n.delete&&await yn(`Clear all custom rate limits for model ${r}.\nYour custom QPM/TPM configuration will be removed.`,n.yes??!1);let s=await e.client.requestJson({path:St(),method:`POST`,body:o});if(i===`json`){A({model:r,...s},i);return}if(n.delete){process.stdout.write(`Rate limits cleared for "${r}".\n`);return}let c=[];n.rpm!==void 0&&c.push(`QPM ${q(n.rpm)}`),n.tpm!==void 0&&c.push(`TPM ${q(n.tpm)}`),process.stdout.write(`Rate limits updated for "${r}": ${c.join(`, `)}\n`)}});const tf=`zeldaEasy.broadscope-platform.modelInstance.listModelLimitApplications`;function nf(e,t){let n=e[t];if(n&&typeof n==`object`&&!Array.isArray(n))return n}function rf(e){let t=nf(e,`data`);if(!t)return e;let n=nf(t,`DataV2`);if(n){let e=nf(n,`data`);return(e?nf(e,`data`):void 0)??e??n}return nf(t,`data`)??t}function af(e){if(!e)return`-`;try{let t=new Date(e);return isNaN(t.getTime())?e:`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)} ${String(t.getHours()).padStart(2,`0`)}:${String(t.getMinutes()).padStart(2,`0`)}`}catch{return e}}function of(e,t){let n=O(process.stdout),r=[`Model`,`Token Limit`,`Applied At`],i=e.map(e=>[e.deployedModel,q(e.usageLimit),af(e.gmtCreate)]),a=r.map((e,t)=>Math.max(xn(e),...i.map(e=>xn(e[t])))),o=r.map((e,t)=>n.bold(M(e,a[t]))).join(` `),s=a.map(e=>n.dim(`─`.repeat(e))).join(`──`);process.stdout.write(o+`
2785
2785
  `),process.stdout.write(s+`
2786
2786
  `);for(let e of i)process.stdout.write(e.map((e,t)=>M(e,a[t])).join(` `)+`
2787
2787
  `);process.stdout.write(n.dim(`\nTotal: ${t} records`)+`
@@ -2792,12 +2792,12 @@ Hint: Add --diarization flag to enable speaker separation.`,c.USAGE);let s=r.mod
2792
2792
  `);process.stdout.write(`\nTotal: ${t}\n`)}var _f=w({description:{"en-US":`List model permissions (inference / fine-tune / deploy) in the workspace`,"zh-CN":`列出 Workspace 中的模型权限(推理 / 微调 / 部署)`},auth:`apiKey`,usageArgs:`[--scope <scope>] [--model <model>] [--name <name>] [--page <n>] [--page-size <n>]`,flags:{scope:{type:`string`,valueHint:`<scope>`,choices:[`authorized`,`authorizable`],description:{"en-US":`Authorization scope: authorizable (default, full catalog), authorized`,"zh-CN":`授权范围:authorizable(默认,完整目录)、authorized(已授权)`}},model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Model ID (exact match)`,"zh-CN":`模型 ID(精确匹配)`}},name:{type:`string`,valueHint:`<name>`,description:{"en-US":`Fuzzy search by model name or ID`,"zh-CN":`按模型名称或 ID 模糊搜索`}},page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Results per page (default: 20)`,"zh-CN":`每页结果数(默认:20)`}}},exampleArgs:[``,`--model qwen-plus`,`--scope authorized`,`--name qwen --page-size 50`,`--output text`],notes:[{"en-US":"Default scope is `authorizable` (the full grantable catalog); use `--scope authorized` to see only models already granted.","zh-CN":"默认范围为 `authorizable`(完整可授权目录);使用 `--scope authorized` 仅查看已授权模型。"},{"en-US":"Output defaults to JSON; pass `--output text` for a table. Permission values are tri-state: true / false / null (never set).","zh-CN":"默认输出 JSON;传入 `--output text` 可查看表格。权限值为三态:true / false / null(从未设置)。"},{"en-US":`Values mirror the server's grant records as-is for the workspace bound to your API key. A model reporting false/null can still be callable (access may come from other channels); see the Model Studio authorization docs for the exact semantics.`,"zh-CN":`这些值原样反映 API Key 所绑定 Workspace 的服务端授权记录。显示 false/null 的模型仍可能可以调用(访问权限可能来自其他渠道);准确语义请参阅百炼模型授权文档。`}],async run(e){let{settings:t,flags:n}=e,r=t.outputExplicit?T(t.output):`json`,i=n.scope??`authorizable`,a={authorization_scope:i.toUpperCase(),model:n.model||void 0,name:n.name||void 0,page_no:n.page||1,page_size:n.pageSize||20};if(t.dryRun){A({endpoint:e.client.url(Ct()),method:`GET`,query:a},r);return}let o=await e.client.requestJson({path:Ct()+qd(a)}),s=o.output?.permissions??[],c=o.output?.total??s.length;if(r===`json`){A({items:s,total:c},r);return}let l=e.identity.binName;gf(s,c,i===`authorized`?`Nothing granted yet in this workspace. Browse grantable models with \`${l} permission list --scope authorizable\`, then grant with \`${l} permission grant --model <model>\`.`:`Adjust --name/--model filters, or check pagination with --page/--page-size.`)}});const vf=[`inference`,`finetune`,`deploy`];function yf(e){if(!e)return[`inference`];let t=Kd(e);if(t.length===0)return{error:`--action must not be empty.`};for(let e of t)if(!vf.includes(e))return{error:`--action "${e}" is invalid; use ${vf.join(`, `)}.`};return t}function bf(e){if(e.all&&e.model)return`--all cannot be combined with --model.`;if(!e.all&&!e.model)return`one of --model / --all is required.`;let t=yf(e.action);if(`error`in t)return t.error;if(e.all&&(t.length!==1||t[0]!==`inference`))return`--all only supports the inference action.`;if(e.model){let t=Kd(e.model);if(t.length===0)return`--model must not be empty.`;if(t.length>20)return`--model accepts at most 20 models per call.`}}async function xf(e,t,n){let r=e.settings.outputExplicit?T(e.settings.output):`json`,i=yf(t.action),a=t.model?Kd(t.model):[],o=t.all?{access_all_entities:n?`OPEN`:`CLOSE`}:{models:a.map(e=>{let t={model:e};for(let e of i)t[e]=n;return t})};if(e.settings.dryRun){A({endpoint:e.client.url(Ct()),method:`POST`,request:o},r);return}let s=await e.client.requestJson({path:Ct(),method:`POST`,body:o}),c=n?`granted`:`revoked`;if(r===`json`){A({...t.all?{all:!0,action:`inference`}:{models:a,actions:i},[c]:!0,request_id:s.request_id},r);return}if(t.all){process.stdout.write(n?`Inference permission granted for all models in the workspace (including future ones).
2793
2793
  `:`One-key authorization closed; historical inference grants cleared.
2794
2794
  `);return}process.stdout.write(`Permissions ${c} (${i.join(`, `)}): ${a.join(`, `)}\n`)}var Sf=w({description:{"en-US":`Grant model permissions (inference / finetune / deploy)`,"zh-CN":`授予模型权限(推理 / 微调 / 部署)`},auth:`apiKey`,usageArgs:`--model <models> [--action <actions>] | --all`,flags:{model:{type:`string`,valueHint:`<models>`,description:{"en-US":`Model ID(s), comma-separated (max 20)`,"zh-CN":`模型 ID,多个以逗号分隔(最多 20 个)`}},action:{type:`string`,valueHint:`<actions>`,description:{"en-US":`Permission action(s), comma-separated: inference, finetune, deploy (default: inference)`,"zh-CN":`权限操作,多个以逗号分隔:inference、finetune、deploy(默认:inference)`}},all:{type:`switch`,description:{"en-US":`One-key grant inference for all models in the workspace (including future ones)`,"zh-CN":`一键授予 Workspace 中所有模型的推理权限(包括未来新增模型)`}}},exampleArgs:[`--model qwen-plus`,`--model qwen-plus,qwen3-max --action inference,finetune`,`--all`,`--model qwen-plus --dry-run --output json`],notes:[{"en-US":`Grants apply to the business workspace your API key belongs to.`,"zh-CN":`授权将应用于 API Key 所属的业务 Workspace。`},{"en-US":`--all maps to the server one-key switch (access_all_entities: OPEN) and only covers inference.`,"zh-CN":`--all 对应服务端一键授权开关(access_all_entities: OPEN),仅涵盖推理权限。`},{"en-US":`Actions you omit keep their current grants (server-side tri-state patch).`,"zh-CN":`未指定的操作将保留当前授权状态(服务端三态增量更新)。`}],validate:e=>bf(e),async run(e){await xf(e,e.flags,!0)}}),Cf=w({description:{"en-US":`Revoke model permissions (inference / finetune / deploy)`,"zh-CN":`撤销模型权限(推理 / 微调 / 部署)`},auth:`apiKey`,usageArgs:`--model <models> [--action <actions>] | --all --yes`,flags:{model:{type:`string`,valueHint:`<models>`,description:{"en-US":`Model ID(s), comma-separated (max 20)`,"zh-CN":`模型 ID,多个以逗号分隔(最多 20 个)`}},action:{type:`string`,valueHint:`<actions>`,description:{"en-US":`Permission action(s), comma-separated: inference, finetune, deploy (default: inference)`,"zh-CN":`权限操作,多个以逗号分隔:inference、finetune、deploy(默认:inference)`}},all:{type:`switch`,description:{"en-US":`Close one-key authorization and clear ALL historical inference grants`,"zh-CN":`关闭一键授权并清除所有历史推理授权`}},yes:{type:`switch`,description:{"en-US":`Confirm --all without an interactive prompt (required)`,"zh-CN":`无需交互提示确认执行 --all(必填)`}}},exampleArgs:[`--model qwen-plus`,`--model qwen-plus,qwen3-max --action inference,finetune`,`--all --yes`,`--model qwen-plus --dry-run --output json`],notes:[{"en-US":`Grants apply to the business workspace your API key belongs to.`,"zh-CN":`授权将应用于 API Key 所属的业务 Workspace。`},{"en-US":`--all maps to the server one-key switch (access_all_entities: CLOSE): it clears every historical inference grant and cannot be undone, so it requires --yes.`,"zh-CN":`--all 对应服务端一键授权开关(access_all_entities: CLOSE):它会清除所有历史推理授权且无法撤销,因此必须同时传入 --yes。`},{"en-US":`Actions you omit keep their current grants (server-side tri-state patch).`,"zh-CN":`未指定的操作将保留当前授权状态(服务端三态增量更新)。`}],validate:e=>bf(e),async run(e){let{flags:n,settings:r}=e;if(n.all&&!n.yes&&!r.dryRun)throw new t(`Refusing to clear all historical inference grants without confirmation.`,c.USAGE,`Re-run with --yes to close one-key authorization (or preview with --dry-run).`);await xf(e,n,!1)}}),wf=w({description:{"en-US":`Upload a dataset file (.jsonl or .zip) to Bailian`,"zh-CN":`将数据集文件(.jsonl 或 .zip)上传到百炼`},auth:`apiKey`,usageArgs:`--file <path> [--purpose <name>] [--schema <chatml|dpo|cpt|tts|image|video>] [--no-validate] [--full-validate]`,flags:{file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Local dataset file (.jsonl or .zip; ≤200MB SFT/DPO, ≤300MB CPT, ≤2GB media zip)`,"zh-CN":`本地数据集文件(.jsonl 或 .zip;SFT/DPO 不超过 200MB,CPT 不超过 300MB,媒体 ZIP 不超过 2GB)`},required:!0},purpose:{type:`string`,valueHint:`<name>`,description:{"en-US":`Dataset purpose tag (default: "fine-tune"; e.g. "evaluation")`,"zh-CN":`数据集用途标签(默认:"fine-tune";例如 "evaluation")`}},schema:{type:`string`,valueHint:`<s>`,description:{"en-US":`Record schema: "chatml" (SFT), "dpo" (chosen/rejected), "cpt" (raw text), "tts" (audio), "image" (image generation), or "video" (video generation). Default auto-detects per record.`,"zh-CN":`记录 Schema:"chatml"(SFT)、"dpo"(chosen/rejected)、"cpt"(原始文本)、"tts"(音频)、"image"(图片生成)或 "video"(视频生成)。默认逐条自动识别。`}},noValidate:{type:`switch`,description:{"en-US":`Skip the local JSONL pre-flight check (not recommended)`,"zh-CN":`跳过本地 JSONL 预检查(不推荐)`}},fullValidate:{type:`switch`,description:{"en-US":`JSON.parse every line instead of sampling (slower)`,"zh-CN":`使用 JSON.parse 检查每一行,而不是抽样检查(速度较慢)`}}},exampleArgs:[`--file train.jsonl`,`--file dpo.jsonl --schema dpo`,`--file cpt.jsonl --schema cpt`,`--file audio.zip --schema tts`,`--file eval.jsonl --purpose evaluation`,`--file train.jsonl --full-validate`,`--file train.jsonl --no-validate`],notes:[{"en-US":`Supports .jsonl (text) and .zip (audio/image/video archives with a data.jsonl manifest). Six record schemas are recognized: chatml = {messages:[...]} (SFT); dpo = {messages:[...], chosen, rejected}; cpt = {text:"..."} (continual pre-training, raw text); tts = {wav_fn:"train/xxx.wav", text:"..."} (audio fine-tuning); image = {img_path:"..."} (image generation); video = {first_frame_path:...} (video generation).`,"zh-CN":`支持 .jsonl(文本)和 .zip(包含 data.jsonl 清单的音频、图片或视频归档)。可识别六种记录 Schema:chatml = {messages:[...]}(SFT);dpo = {messages:[...], chosen, rejected};cpt = {text:"..."}(持续预训练,原始文本);tts = {wav_fn:"train/xxx.wav", text:"..."}(音频微调);image = {img_path:"..."}(图片生成);video = {first_frame_path:...}(视频生成)。`},{"en-US":`With no --schema, a record carrying wav_fn is validated as TTS, img_path as image, chosen/rejected as DPO, text (no messages) as CPT, otherwise ChatML.`,"zh-CN":`未指定 --schema 时,包含 wav_fn 的记录按 TTS 验证,包含 img_path 的按 image 验证,包含 chosen/rejected 的按 DPO 验证,仅含 text(无 messages)的按 CPT 验证,其他记录按 ChatML 验证。`},{"en-US":`Upload cap: 200MB SFT/DPO text, 300MB CPT, 2GB media zip. Upload uses the OpenAI-compatible /compatible-mode/v1/files endpoint so the purpose tag is persisted (the DashScope-native /api/v1/files drops it).`,"zh-CN":`上传上限:SFT/DPO 文本 200MB、CPT 300MB、媒体 ZIP 2GB。上传使用 OpenAI 兼容的 /compatible-mode/v1/files Endpoint,以便保留 purpose 标签;DashScope 原生 /api/v1/files 会丢弃该标签。`}],async run(e){let{identity:n,settings:r,flags:i}=e,a=i.file,o=i.purpose||`fine-tune`,s=Et(i.schema),f=s===`image`||s===`video`?d:s===`cpt`?l:u;if(!i.noValidate){let e=await sn(a,{fullValidate:i.fullValidate,schema:s,maxBytes:f});if(!e.valid){let r=[`Dataset validation failed for ${a}`,...e.errors.slice(0,10).map(Fe)];throw e.errors.length>10&&r.push(` … and ${e.errors.length-10} more error(s).`),r.push(``,`Hint: re-run \`${n.binName} dataset validate --file <path>\` for the full report,`,` or pass --no-validate to skip this check at your own risk.`),new t(r.join(`
2795
- `),c.GENERAL)}if(e.warnings.length>0&&!r.quiet){process.stderr.write(`Dataset validation passed with ${e.warnings.length} warning(s):\n`);for(let t of e.warnings.slice(0,5))process.stderr.write(`${Fe(t)}\n`);e.warnings.length>5&&process.stderr.write(` … and ${e.warnings.length-5} more.\n`)}}if(r.dryRun){A({action:`dataset.upload`,file:a,purpose:o,max_bytes:f,validate:!i.noValidate,schema:s??`auto`},`json`);return}let{request_id:p,...m}=await an(e.client,{filePath:a,purpose:o});r.quiet?k(m.file_id):A({...m,request_id:p},`json`)}}),Tf=w({description:{"en-US":`List uploaded dataset files`,"zh-CN":`列出已上传的数据集文件`},auth:`apiKey`,usageArgs:`[--page <n>] [--page-size <n>] [--purpose <name>]`,flags:{page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Results per page (default: 10, max 100)`,"zh-CN":`每页结果数(默认:10,最多:100)`}},purpose:{type:`string`,valueHint:`<name>`,description:{"en-US":`Filter by purpose (e.g. "fine-tune", "evaluation"). Omit to list all.`,"zh-CN":`按用途筛选(例如 "fine-tune"、"evaluation")。省略时列出全部。`}}},exampleArgs:[``,`--purpose fine-tune`,`--purpose evaluation --page-size 20`,`--output json`],async run(e){let{settings:t,flags:n}=e;if(t.dryRun){A({action:`dataset.list`,page:n.page,page_size:n.pageSize,purpose:n.purpose},`json`);return}let r=await ot(e.client,{pageNo:n.page,pageSize:n.pageSize,purpose:n.purpose||void 0}),i=r.data?.files??[],a=r.data?.total,o=i.map(e=>({file_id:e.file_id??``,name:e.name??``,size:e.size===void 0?`?`:`${(e.size/1024).toFixed(1)} KB`,purpose:e.purpose??``}));if(t.quiet)for(let e of o)k(e.file_id);else A({items:o,total:a,request_id:r.request_id},`json`)}}),Ef=w({description:{"en-US":`Get details of a single dataset file`,"zh-CN":`获取单个数据集文件的详情`},auth:`apiKey`,usageArgs:`--file-id <id>`,flags:{fileId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Dataset file ID (required)`,"zh-CN":`数据集文件 ID(必填)`},required:!0}},exampleArgs:[`--file-id file-xxx`,`--file-id file-xxx --output json`],async run(e){let{settings:t,flags:n}=e,r=n.fileId;if(t.dryRun){A({action:`dataset.get`,file_id:r},`json`);return}let i=await ze(e.client,r),a=i.data;if(!a){k(`No data returned for ${r}`);return}let o=a.size===void 0?`?`:`${(a.size/1024).toFixed(1)} KB`,s={file_id:a.file_id??r,name:a.name??``,size:o,md5:a.md5??``,purpose:a.purpose??``,created_at:a.gmt_create??``,description:a.description??``};t.quiet?k(s.file_id):A({...s,request_id:i.request_id},`json`)}}),Df=w({description:{"en-US":`Delete a dataset file by ID`,"zh-CN":`通过 ID 删除数据集文件`},auth:`apiKey`,usageArgs:`--file-id <id>`,flags:{fileId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Dataset file ID (required)`,"zh-CN":`数据集文件 ID(必填)`},required:!0}},exampleArgs:[`--file-id file-id-xxx`,`--file-id file-id-xxx --dry-run`],async run(e){let{settings:t,flags:n}=e,r=n.fileId;if(t.dryRun){A({action:`dataset.delete`,file_id:r},`json`);return}let i=await he(e.client,r);t.quiet?k(r):A(i,`json`)}}),Of=w({description:{"en-US":`Locally validate a dataset file (.jsonl or .zip) without uploading`,"zh-CN":`在本地验证数据集文件(.jsonl 或 .zip),不执行上传`},auth:`none`,usageArgs:`--file <path> [--full-validate] [--schema <chatml|dpo|cpt|tts|image|video>]`,flags:{file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Local dataset file (.jsonl or .zip)`,"zh-CN":`本地数据集文件(.jsonl 或 .zip)`},required:!0},fullValidate:{type:`switch`,description:{"en-US":`JSON.parse every line instead of sampling (slower)`,"zh-CN":`使用 JSON.parse 检查每一行,而不是抽样检查(速度较慢)`}},schema:{type:`string`,valueHint:`<s>`,description:{"en-US":`Record schema: "chatml" (SFT), "dpo" (chosen/rejected), "cpt" (raw text), "tts" (audio), "image" (image generation), or "video" (video generation). Default auto-detects per record.`,"zh-CN":`记录 Schema:"chatml"(SFT)、"dpo"(chosen/rejected)、"cpt"(原始文本)、"tts"(音频)、"image"(图片生成)或 "video"(视频生成)。默认逐条自动识别。`}}},exampleArgs:[`--file train.jsonl`,`--file dpo.jsonl --schema dpo`,`--file cpt.jsonl --schema cpt`,`--file audio.zip --schema tts`,`--file wan-i2v-training-dataset.zip --schema video`,`--file eval.jsonl --full-validate`,`--file train.jsonl --output json`],notes:[{"en-US":`Default scan: every line gets a structural check, then ~160 lines (front 50, evenly spaced 100, last 10) are JSON.parsed against the active schema.`,"zh-CN":`默认扫描:先对每一行进行结构检查,再抽取约 160 行(前 50 行、均匀抽取 100 行、最后 10 行),使用 JSON.parse 按当前 Schema 验证。`},{"en-US":`Schemas: chatml = {messages:[...]} (SFT); dpo = {messages:[...], chosen, rejected}; cpt = {text:"..."} (continual pre-training, raw text); tts = {wav_fn:"train/xxx.wav", text:"..."} (audio fine-tuning); image = {img_path:"..."} (image generation); video = {first_frame_path:"...", video_path:"..."} (video generation, i2v first-frame or kf2v first+last-frame with last_frame_path).`,"zh-CN":`Schema:chatml = {messages:[...]}(SFT);dpo = {messages:[...], chosen, rejected};cpt = {text:"..."}(持续预训练,原始文本);tts = {wav_fn:"train/xxx.wav", text:"..."}(音频微调);image = {img_path:"..."}(图片生成);video = {first_frame_path:"...", video_path:"..."}(视频生成,支持 i2v 首帧或通过 last_frame_path 指定 kf2v 首尾帧)。`},{"en-US":`With no --schema, a record carrying wav_fn is validated as TTS, img_path as image, first_frame_path/video_path as video, chosen/rejected as DPO, text (no messages) as CPT, otherwise ChatML. Pass --schema to require a specific shape on every record.`,"zh-CN":`未指定 --schema 时,包含 wav_fn 的记录按 TTS 验证,包含 img_path 的按 image 验证,包含 first_frame_path/video_path 的按 video 验证,包含 chosen/rejected 的按 DPO 验证,仅含 text(无 messages)的按 CPT 验证,其他记录按 ChatML 验证。使用 --schema 要求每条记录符合指定结构。`},{"en-US":`ZIP archives (.zip) are validated structurally (data.jsonl present, media references resolve) in addition to per-record content checks. Use --full-validate to JSON.parse every line.`,"zh-CN":`ZIP 归档(.zip)除逐条检查记录内容外,还会执行结构验证(存在 data.jsonl、媒体引用可解析)。使用 --full-validate 对每一行执行 JSON.parse。`}],async run(e){let{settings:n,flags:r}=e,i=r.file,a=Et(r.schema);if(n.dryRun){A({action:`dataset.validate`,file:i,full:r.fullValidate,schema:a??`auto`},`json`);return}let o=await sn(i,{fullValidate:r.fullValidate,schema:a});if(n.quiet?k(o.valid?`ok`:`fail`):A(o,`json`),!o.valid)throw new t(`Dataset validation failed: ${o.errors.length} error(s).`,c.GENERAL)}});function kf(e){return Jn(e)&&Qn(e).isFile()}async function Af(e,n,r,i,a,o,s,l){let u=r.split(`,`).map(e=>e.trim()).filter(Boolean);if(u.length===0)throw new t(`--${i} must contain at least one entry.`,c.USAGE);let d=[],f=[],p,m,h=!0;for(let r of u){if(!kf(r)){d.push(r),h=!1;continue}if(d.push(r),f.push(r),e.dryRun)continue;let i=l&&l.path===r?l.modality:o,u=await a.validate(r,i,{model:s});if(!u.valid){let e=[`Dataset validation failed for ${r}`,...u.errors.slice(0,10).map(Fe)];throw u.errors.length>10&&e.push(` … and ${u.errors.length-10} more error(s).`),e.push(``,`Hint: re-run \`${n} dataset validate --file <path>\` for the full report,`,` or upload manually with \`${n} dataset upload --no-validate\` and`,` pass the resulting file-id here.`),new t(e.join(`
2795
+ `),c.GENERAL)}if(e.warnings.length>0&&!r.quiet){process.stderr.write(`Dataset validation passed with ${e.warnings.length} warning(s):\n`);for(let t of e.warnings.slice(0,5))process.stderr.write(`${Fe(t)}\n`);e.warnings.length>5&&process.stderr.write(` … and ${e.warnings.length-5} more.\n`)}}if(r.dryRun){A({action:`dataset.upload`,file:a,purpose:o,max_bytes:f,validate:!i.noValidate,schema:s??`auto`},`json`);return}let{request_id:p,...m}=await an(e.client,{filePath:a,purpose:o});r.quiet?k(m.file_id):A({...m,request_id:p},`json`)}}),Tf=w({description:{"en-US":`List uploaded dataset files`,"zh-CN":`列出已上传的数据集文件`},auth:`apiKey`,usageArgs:`[--page <n>] [--page-size <n>] [--purpose <name>]`,flags:{page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Results per page (default: 10, max 100)`,"zh-CN":`每页结果数(默认:10,最多:100)`}},purpose:{type:`string`,valueHint:`<name>`,description:{"en-US":`Filter by purpose (e.g. "fine-tune", "evaluation"). Omit to list all.`,"zh-CN":`按用途筛选(例如 "fine-tune"、"evaluation")。省略时列出全部。`}}},exampleArgs:[``,`--purpose fine-tune`,`--purpose evaluation --page-size 20`,`--output json`],async run(e){let{settings:t,flags:n}=e;if(t.dryRun){A({action:`dataset.list`,page:n.page,page_size:n.pageSize,purpose:n.purpose},`json`);return}let r=await ot(e.client,{pageNo:n.page,pageSize:n.pageSize,purpose:n.purpose||void 0}),i=r.data?.files??[],a=r.data?.total,o=i.map(e=>({file_id:e.file_id??``,name:e.name??``,size:e.size===void 0?`?`:`${(e.size/1024).toFixed(1)} KB`,purpose:e.purpose??``}));if(t.quiet)for(let e of o)k(e.file_id);else A({items:o,total:a,request_id:r.request_id},`json`)}}),Ef=w({description:{"en-US":`Get details of a single dataset file`,"zh-CN":`获取单个数据集文件的详情`},auth:`apiKey`,usageArgs:`--file-id <id>`,flags:{fileId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Dataset file ID (required)`,"zh-CN":`数据集文件 ID(必填)`},required:!0}},exampleArgs:[`--file-id file-xxx`,`--file-id file-xxx --output json`],async run(e){let{settings:t,flags:n}=e,r=n.fileId;if(t.dryRun){A({action:`dataset.get`,file_id:r},`json`);return}let i=await ze(e.client,r),a=i.data;if(!a){k(`No data returned for ${r}`);return}let o=a.size===void 0?`?`:`${(a.size/1024).toFixed(1)} KB`,s={file_id:a.file_id??r,name:a.name??``,size:o,md5:a.md5??``,purpose:a.purpose??``,created_at:a.gmt_create??``,description:a.description??``};t.quiet?k(s.file_id):A({...s,request_id:i.request_id},`json`)}}),Df=w({description:{"en-US":`Delete a dataset file by ID`,"zh-CN":`通过 ID 删除数据集文件`},auth:`apiKey`,usageArgs:`--file-id <id> [--yes]`,flags:{fileId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Dataset file ID (required)`,"zh-CN":`数据集文件 ID(必填)`},required:!0},yes:{type:`switch`,description:{"en-US":`Skip the confirmation prompt`,"zh-CN":`跳过确认提示`}}},exampleArgs:[`--file-id file-id-xxx`,`--file-id file-id-xxx --dry-run`,`--file-id file-id-xxx --yes`],notes:[{"en-US":`Irreversible — the dataset file is permanently removed.`,"zh-CN":`该操作不可撤销——数据集文件将被永久删除。`}],async run(e){let{settings:t,flags:n}=e,r=n.fileId;if(t.dryRun){A({action:`dataset.delete`,file_id:r},`json`);return}await yn(`Delete dataset file ${r}.\nThe file is permanently removed. This cannot be undone.`,n.yes??!1);let i=await he(e.client,r);t.quiet?k(r):A(i,`json`)}}),Of=w({description:{"en-US":`Locally validate a dataset file (.jsonl or .zip) without uploading`,"zh-CN":`在本地验证数据集文件(.jsonl 或 .zip),不执行上传`},auth:`none`,usageArgs:`--file <path> [--full-validate] [--schema <chatml|dpo|cpt|tts|image|video>]`,flags:{file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Local dataset file (.jsonl or .zip)`,"zh-CN":`本地数据集文件(.jsonl 或 .zip)`},required:!0},fullValidate:{type:`switch`,description:{"en-US":`JSON.parse every line instead of sampling (slower)`,"zh-CN":`使用 JSON.parse 检查每一行,而不是抽样检查(速度较慢)`}},schema:{type:`string`,valueHint:`<s>`,description:{"en-US":`Record schema: "chatml" (SFT), "dpo" (chosen/rejected), "cpt" (raw text), "tts" (audio), "image" (image generation), or "video" (video generation). Default auto-detects per record.`,"zh-CN":`记录 Schema:"chatml"(SFT)、"dpo"(chosen/rejected)、"cpt"(原始文本)、"tts"(音频)、"image"(图片生成)或 "video"(视频生成)。默认逐条自动识别。`}}},exampleArgs:[`--file train.jsonl`,`--file dpo.jsonl --schema dpo`,`--file cpt.jsonl --schema cpt`,`--file audio.zip --schema tts`,`--file wan-i2v-training-dataset.zip --schema video`,`--file eval.jsonl --full-validate`,`--file train.jsonl --output json`],notes:[{"en-US":`Default scan: every line gets a structural check, then ~160 lines (front 50, evenly spaced 100, last 10) are JSON.parsed against the active schema.`,"zh-CN":`默认扫描:先对每一行进行结构检查,再抽取约 160 行(前 50 行、均匀抽取 100 行、最后 10 行),使用 JSON.parse 按当前 Schema 验证。`},{"en-US":`Schemas: chatml = {messages:[...]} (SFT); dpo = {messages:[...], chosen, rejected}; cpt = {text:"..."} (continual pre-training, raw text); tts = {wav_fn:"train/xxx.wav", text:"..."} (audio fine-tuning); image = {img_path:"..."} (image generation); video = {first_frame_path:"...", video_path:"..."} (video generation, i2v first-frame or kf2v first+last-frame with last_frame_path).`,"zh-CN":`Schema:chatml = {messages:[...]}(SFT);dpo = {messages:[...], chosen, rejected};cpt = {text:"..."}(持续预训练,原始文本);tts = {wav_fn:"train/xxx.wav", text:"..."}(音频微调);image = {img_path:"..."}(图片生成);video = {first_frame_path:"...", video_path:"..."}(视频生成,支持 i2v 首帧或通过 last_frame_path 指定 kf2v 首尾帧)。`},{"en-US":`With no --schema, a record carrying wav_fn is validated as TTS, img_path as image, first_frame_path/video_path as video, chosen/rejected as DPO, text (no messages) as CPT, otherwise ChatML. Pass --schema to require a specific shape on every record.`,"zh-CN":`未指定 --schema 时,包含 wav_fn 的记录按 TTS 验证,包含 img_path 的按 image 验证,包含 first_frame_path/video_path 的按 video 验证,包含 chosen/rejected 的按 DPO 验证,仅含 text(无 messages)的按 CPT 验证,其他记录按 ChatML 验证。使用 --schema 要求每条记录符合指定结构。`},{"en-US":`ZIP archives (.zip) are validated structurally (data.jsonl present, media references resolve) in addition to per-record content checks. Use --full-validate to JSON.parse every line.`,"zh-CN":`ZIP 归档(.zip)除逐条检查记录内容外,还会执行结构验证(存在 data.jsonl、媒体引用可解析)。使用 --full-validate 对每一行执行 JSON.parse。`}],async run(e){let{settings:n,flags:r}=e,i=r.file,a=Et(r.schema);if(n.dryRun){A({action:`dataset.validate`,file:i,full:r.fullValidate,schema:a??`auto`},`json`);return}let o=await sn(i,{fullValidate:r.fullValidate,schema:a});if(n.quiet?k(o.valid?`ok`:`fail`):A(o,`json`),!o.valid)throw new t(`Dataset validation failed: ${o.errors.length} error(s).`,c.GENERAL)}});function kf(e){return Jn(e)&&Qn(e).isFile()}async function Af(e,n,r,i,a,o,s,l){let u=r.split(`,`).map(e=>e.trim()).filter(Boolean);if(u.length===0)throw new t(`--${i} must contain at least one entry.`,c.USAGE);let d=[],f=[],p,m,h=!0;for(let r of u){if(!kf(r)){d.push(r),h=!1;continue}if(d.push(r),f.push(r),e.dryRun)continue;let i=l&&l.path===r?l.modality:o,u=await a.validate(r,i,{model:s});if(!u.valid){let e=[`Dataset validation failed for ${r}`,...u.errors.slice(0,10).map(Fe)];throw u.errors.length>10&&e.push(` … and ${u.errors.length-10} more error(s).`),e.push(``,`Hint: re-run \`${n} dataset validate --file <path>\` for the full report,`,` or upload manually with \`${n} dataset upload --no-validate\` and`,` pass the resulting file-id here.`),new t(e.join(`
2796
2796
  `),c.GENERAL)}if(u.warnings.length>0&&!e.quiet){process.stderr.write(`Dataset validation passed with ${u.warnings.length} warning(s) for ${r}:\n`);for(let e of u.warnings.slice(0,5))process.stderr.write(`${Fe(e)}\n`);u.warnings.length>5&&process.stderr.write(` … and ${u.warnings.length-5} more.\n`)}let g=u.stats.totalRecords;typeof g==`number`&&(m=(m??0)+g),p===void 0&&(p=Qn(r).size)}return{fileIds:d,localPaths:f,firstSize:p,recordCount:h?m:void 0}}async function jf(e,n,r,i,a){let o=[];for(let[s,l]of r.fileIds.entries()){if(!kf(l))continue;let u=await an(e,{filePath:l,purpose:i});if(!u.file_id)throw new t(`Upload of ${l} succeeded but no file_id was returned.`,c.GENERAL);o.push(u),r.fileIds[s]=u.file_id,n.quiet||process.stderr.write(`Uploaded ${er(l)} → ${u.file_id} (auto from --${a})\n`)}return o}const Mf={baseModel:{type:`string`,valueHint:`<model>`,description:{"en-US":`Base model to fine-tune (e.g. qwen3-8b; not the output model name)`,"zh-CN":`要微调的基础模型(例如 qwen3-8b;不是输出模型名称)`},required:!0},datasets:{type:`string`,valueHint:`<ids|paths>`,description:{"en-US":`Comma-separated dataset file IDs or local paths (.jsonl for text, .zip for audio/image/video). Local paths are uploaded (validated) first, then their file-ids are used.`,"zh-CN":`数据集文件 ID 或本地路径,以逗号分隔(文本使用 .jsonl,音频、图片和视频使用 .zip)。本地路径会先验证并上传,再使用对应的 file-id。`},required:!0},validations:{type:`string`,valueHint:`<ids|paths>`,description:{"en-US":`Comma-separated validation dataset file IDs or local paths (auto-uploaded like --datasets).`,"zh-CN":`验证数据集文件 ID 或本地路径,以逗号分隔(与 --datasets 一样自动上传)。`}},modelName:{type:`string`,valueHint:`<name>`,description:{"en-US":`Output model name (after training)`,"zh-CN":`训练完成后的输出模型名称`}},suffix:{type:`string`,valueHint:`<text>`,description:{"en-US":`Output suffix appended by the platform (finetuned_output_suffix)`,"zh-CN":`平台追加的输出后缀(finetuned_output_suffix)`}}},Nf={...Mf,trainingType:{type:`string`,valueHint:`<t>`,description:{"en-US":`Training type: ${v.join(` | `)} (default: ${o}). Mapping to the server happens at the interface boundary (e.g. sft-lora -> efficient_sft, dpo -> dpo_full).`,"zh-CN":`训练类型:${v.join(` | `)}(默认:${o})。在接口边界转换为服务端值(例如 sft-lora -> efficient_sft、dpo -> dpo_full)。`}},nEpochs:{type:`number`,valueHint:`<n>`,description:{"en-US":`Number of epochs (default: 3)`,"zh-CN":`训练轮数(默认:3)`}},batchSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Per-device batch size (clamped to [8, 1024]). Auto-set to 8 for small datasets (<100KB)`,"zh-CN":`单设备 Batch Size(限制在 [8, 1024])。小数据集(<100KB)自动设为 8`}},learningRate:{type:`string`,valueHint:`<str>`,description:{"en-US":`Learning rate as a string to preserve precision (e.g. "1.6e-5")`,"zh-CN":`以字符串形式指定学习率以保留精度(例如 "1.6e-5")`}},maxLength:{type:`number`,valueHint:`<n>`,description:{"en-US":`Max sequence length`,"zh-CN":`最大序列长度`}}},Pf={...Mf},Ff={...Mf,generationType:{type:`string`,choices:[`t2i`,`i2i`],valueHint:`<t2i|i2i>`,description:{"en-US":`Generation type: t2i (default) | i2i. Sets generation_type/max_pixels. Required to train I2I from a file-id or with --dry-run (local data auto-detects input_img).`,"zh-CN":`生成类型:t2i(默认)| i2i。用于设置 generation_type/max_pixels。通过 file-id 训练 I2I 或使用 --dry-run 时必填(本地数据会自动识别 input_img)。`}},learningRate:{type:`string`,valueHint:`<str>`,description:{"en-US":`Learning rate as a string to preserve precision (e.g. "3e-5")`,"zh-CN":`以字符串形式指定学习率以保留精度(例如 "3e-5")`}}},If={...Mf,nEpochs:{type:`number`,valueHint:`<n>`,description:{"en-US":`Training epochs (default: 50)`,"zh-CN":`训练轮数(默认:50)`}},batchSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Batch size (default: model-specific, 1 for wan2.7, 4 for wan2.5/2.2)`,"zh-CN":`Batch Size(默认值因模型而异:wan2.7 为 1,wan2.5/2.2 为 4)`}},learningRate:{type:`string`,valueHint:`<str>`,description:{"en-US":`Learning rate as a string to preserve precision (default: "2e-5")`,"zh-CN":`以字符串形式指定学习率以保留精度(默认:"2e-5")`}}},Lf=[{"en-US":`Creating a job uploads any local datasets and consumes training quota.`,"zh-CN":`创建任务会上传所有本地数据集并消耗训练额度。`},{"en-US":`Use --dry-run to preview the request body without submitting.`,"zh-CN":`使用 --dry-run 预览请求体,不实际提交。`},{"en-US":"--datasets / --validations accept either file-ids (from `dataset upload`) or local paths. Local paths are validated and uploaded first, then their file-ids are submitted — a one-step upload-and-train.","zh-CN":"--datasets / --validations 可接受 file-id(来自 `dataset upload`)或本地路径。本地路径会先验证并上传,再提交对应的 file-id,实现一步上传并训练。"}],Rf=[...Lf,{"en-US":"Training-type values use the `<method>` / `<method>-lora` convention: sft (full) | sft-lora (LoRA) | dpo (full) | dpo-lora (LoRA) | cpt. These map to the server's training_type at the interface boundary, so the rest of the CLI never sees the raw server strings.","zh-CN":"训练类型遵循 `<method>` / `<method>-lora` 命名约定:sft(全量)| sft-lora(LoRA)| dpo(全量)| dpo-lora(LoRA)| cpt。这些值会在接口边界映射为服务端 training_type,因此 CLI 的其他部分不会接触服务端原始字符串。"},{"en-US":`Before submitting (non dry-run) the job, the model's training capability is checked via listFoundationModels (no console login required); an unsupported training type fails fast with the list the model actually supports.`,"zh-CN":`提交任务前(非 dry-run),会通过 listFoundationModels 检查模型训练能力(无需登录控制台);如果训练类型不受支持,会立即失败并列出该模型实际支持的训练类型。`},{"en-US":`n_epochs defaults to 3. Other hyper-parameters are platform defaults unless set.`,"zh-CN":`n_epochs 默认为 3。其他超参数未设置时使用平台默认值。`},{"en-US":`Learning rate is forwarded as a string to avoid JSON-number precision loss.`,"zh-CN":`学习率以字符串形式传递,避免 JSON 数字精度损失。`},{"en-US":`Pre-submit gate: if the training dataset's sample count is not greater than batch_size, the job is rejected before upload or quota consumption (the platform would otherwise fail ~10 min in, after data processing).`,"zh-CN":`提交前检查:如果训练数据集的样本数不大于 batch_size,会在上传或消耗额度前拒绝任务(否则平台会在数据处理约 10 分钟后才失败)。`}],zf=[...Lf,{"en-US":`Audio TTS training runs sft-lora (efficient_sft) with fixed CosyVoice hyper-parameter defaults; there are no training-type or hyper-parameter knobs to set.`,"zh-CN":`音频 TTS 训练使用 sft-lora(efficient_sft)和固定的 CosyVoice 超参数默认值;没有可设置的训练类型或超参数选项。`}],Bf=[...Lf,{"en-US":`Image generation training runs sft-lora (efficient_sft) with fixed defaults; only --learning-rate is overridable. T2I vs I2I is declared with --generation-type (default t2i), which sets generation_type/max_pixels. For local data the type is auto-detected (records with input_img train I2I); pass --generation-type explicitly to train I2I from a file-id or in --dry-run.`,"zh-CN":`图片生成训练使用 sft-lora(efficient_sft)和固定默认值;仅 --learning-rate 可覆盖。通过 --generation-type(默认 t2i)声明 T2I 或 I2I,并设置 generation_type/max_pixels。本地数据会自动识别类型(包含 input_img 的记录训练 I2I);通过 file-id 训练 I2I 或使用 --dry-run 时,请显式传入 --generation-type。`}];async function Vf(e,n){let{identity:r,settings:i}=n,a=n.flags,s=a.baseModel,l=a.datasets;if(e===`audio`){let e=l.split(`,`).map(e=>e.trim()).filter(Boolean);if(e.length>1)throw new t(`Audio (TTS) fine-tuning accepts exactly one training file, got ${e.length}.`,c.USAGE,`Merge your recordings into a single .zip (or pass one file-id).`)}let u=a.trainingType||o;if(!et(u))throw new t(`--training-type "${u}" is not supported.`,c.USAGE,`Supported values: ${v.join(`, `)} (default: ${o}).`);let d=Ge(u),f=l.split(`,`).map(e=>e.trim()).find(e=>kf(e)),p=e;if(e===`image`){let e=a.generationType;(e===`i2i`||!e&&f&&!i.dryRun&&await ye(f)===`image-i2i`)&&(p=`image-i2i`)}e===`video`&&f&&!i.dryRun&&await ye(f)===`video-kf2v`&&(p=`video-kf2v`);let m=await Af(i,r.binName,l,`datasets`,d,p,s,f?{path:f,modality:p}:void 0),h=m.fileIds,g=a.validations?await Af(i,r.binName,a.validations,`validations`,d,p,s):void 0,_=g?.fileIds,y=a.modelName,b=a.suffix,x=d.resolveHyperParameters(p,a);if(a.batchSize!==void 0&&x.batch_size!==void 0&&!i.quiet&&!d.shouldSkipGate(`batch_size`,p)){let e=a.batchSize;x.batch_size!==e&&process.stderr.write(`warning: --batch-size ${e} clamped to ${x.batch_size} (server range [8, 1024] for the common training types).\n`)}if(a.batchSize!==void 0&&!i.quiet&&d.shouldSkipGate(`batch_size`,p)){let e=a.batchSize;x.batch_size!==void 0&&x.batch_size!==e&&process.stderr.write(`warning: --batch-size ${e} ignored for ${p} training (model uses a fixed batch_size of ${x.batch_size}).\n`)}if(p===`text`&&x.batch_size===void 0&&!i.dryRun){let e=m.firstSize??0;if(e===0)try{e=(await ze(n.client,h[0])).data?.size??0}catch{}e>0&&e<100*1024&&(x.batch_size=8)}if(!i.dryRun&&m.recordCount!==void 0&&!d.shouldSkipGate(`batch_size`,p)){let e=x.batch_size??16,n=At({recordCount:m.recordCount,batchSize:e});if(!n.ok&&n.issue)throw new t(n.issue.message,c.GENERAL,n.hint)}if(!i.dryRun&&!d.shouldSkipCapabilityCheck(p)){let e;try{e=await Ee(i,s)}catch(e){i.quiet||process.stderr.write(`warning: model capability lookup failed (${e.message}); proceeding without local pre-flight.
2797
- `)}if(e&&!ft(e).includes(u)){let n=ft(e);throw new t(`Model "${s}" does not support training type "${u}".`,c.USAGE,n.length?`This model supports: ${n.join(`, `)}.`:`This model reports no supported training types.`)}}i.dryRun||(await jf(n.client,i,m,`fine-tune`,`datasets`),g&&await jf(n.client,i,g,`fine-tune`,`validations`));let S={model:s,training_file_ids:h,training_type:d.serverTrainingType,hyper_parameters:x};if(_&&_.length>0&&(S.validation_file_ids=_),y&&(S.model_name=y),b&&(S.finetuned_output_suffix=b),i.dryRun){let e=[...m.localPaths.map(e=>({field:`datasets`,path:e})),...(g?.localPaths??[]).map(e=>({field:`validations`,path:e}))];A(e.length>0?{action:`finetune.create`,body:S,pending_uploads:e}:{action:`finetune.create`,body:S},`json`);return}let C=await de(n.client,S),ee=C.output??C.data;i.quiet?ee?.job_id&&k(ee.job_id):A(C,`json`)}const Hf=w({description:{"en-US":`Create a text model fine-tune job (sft | sft-lora | dpo | dpo-lora | cpt)`,"zh-CN":`创建文本模型微调任务(sft | sft-lora | dpo | dpo-lora | cpt)`},auth:`apiKey`,usageArgs:`--base-model <model> --datasets <id|path,...> [--validations <id|path,...>] [--model-name <name>] [--suffix <text>] [--n-epochs <n>] [--batch-size <n>] [--learning-rate <str>] [--max-length <n>] [--training-type <sft|sft-lora|dpo|dpo-lora|cpt>]`,flags:Nf,exampleArgs:[`--base-model qwen3-8b --datasets file-xxx`,`--base-model qwen3-8b --datasets ./train.jsonl`,`--base-model qwen3-8b --datasets ./train.jsonl --validations ./eval.jsonl`,`--base-model qwen3-8b --datasets file-aaa,./extra.jsonl`,`--base-model qwen3-8b --datasets ./train.jsonl --training-type sft`,`--base-model qwen3-8b --datasets file-xxx --learning-rate "1.6e-5" --n-epochs 4`,`--base-model qwen3-8b --datasets file-xxx --output json`,`--base-model qwen3-8b --datasets file-xxx --dry-run`],notes:Rf,run:e=>Vf(`text`,e)}),Uf=w({description:{"en-US":`Create an audio TTS model fine-tune job (sft-lora)`,"zh-CN":`创建音频 TTS 模型微调任务(sft-lora)`},auth:`apiKey`,usageArgs:`--base-model <model> --datasets <id|path> [--validations <id|path>] [--model-name <name>] [--suffix <text>]`,flags:Pf,exampleArgs:[`--base-model cosyvoice-v3-flash --datasets ./audio.zip`,`--base-model cosyvoice-v3-flash --datasets file-xxx`,`--base-model cosyvoice-v3-flash --datasets ./audio.zip --model-name my-tts`,`--base-model cosyvoice-v3-flash --datasets file-xxx --output json`,`--base-model cosyvoice-v3-flash --datasets ./audio.zip --dry-run`],notes:zf,run:e=>Vf(`audio`,e)}),Wf=w({description:{"en-US":`Create an image generation model fine-tune job (sft-lora)`,"zh-CN":`创建图片生成模型微调任务(sft-lora)`},auth:`apiKey`,usageArgs:`--base-model <model> --datasets <id|path> [--validations <id|path>] [--model-name <name>] [--suffix <text>] [--generation-type <t2i|i2i>] [--learning-rate <str>]`,flags:Ff,exampleArgs:[`--base-model wan2.7-image-pro --datasets ./images.zip`,`--base-model wan2.7-image-pro --datasets file-xxx`,`--base-model wan2.7-image-pro --datasets file-xxx --generation-type i2i`,`--base-model wan2.7-image-pro --datasets ./images.zip --model-name my-wan`,`--base-model wan2.7-image-pro --datasets file-xxx --output json`,`--base-model wan2.7-image-pro --datasets ./images.zip --dry-run`],notes:Bf,run:e=>Vf(`image`,e)}),Gf=w({description:{"en-US":`Create a video generation model fine-tune job (Wan i2v/kf2v, efficient_sft)`,"zh-CN":`创建视频生成模型微调任务(Wan i2v/kf2v,efficient_sft)`},auth:`apiKey`,usageArgs:`--base-model <model> --datasets <id|path> [--validations <id|path>] [--model-name <name>] [--suffix <text>] [--n-epochs <n>] [--batch-size <n>] [--learning-rate <str>]`,flags:If,exampleArgs:[`--base-model wan2.7-i2v --datasets file-xxx`,`--base-model wan2.7-i2v --datasets ./i2v-data.zip`,`--base-model wan2.2-kf2v-flash --datasets file-xxx --n-epochs 100`,`--base-model wan2.7-i2v --datasets file-xxx --dry-run`],notes:[...Lf,{"en-US":`Video generation training (Wan i2v/kf2v) runs efficient_sft with model-specific defaults: wan2.7 (batch_size=1, max_pixels=102400), wan2.5/2.2 (batch_size=4, max_pixels per model). Override with --batch-size/--n-epochs.`,"zh-CN":`视频生成训练(Wan i2v/kf2v)使用 efficient_sft 和模型专属默认值:wan2.7(batch_size=1、max_pixels=102400),wan2.5/2.2(batch_size=4,max_pixels 因模型而异)。可通过 --batch-size/--n-epochs 覆盖。`},{"en-US":`Datasets are .zip archives with data.jsonl + frame images + videos.`,"zh-CN":`数据集为包含 data.jsonl、帧图片和视频的 .zip 归档。`},{"en-US":`Recommended: ≥10 training samples, 20-100 for stable results.`,"zh-CN":`建议至少准备 10 个训练样本;20–100 个样本可获得更稳定的效果。`}],run:e=>Vf(`video`,e)});var Kf=w({description:{"en-US":`List fine-tune jobs`,"zh-CN":`列出微调任务`},auth:`apiKey`,usageArgs:`[--page <n>] [--page-size <n>] [--status <s>] [--base-model <model>]`,flags:{page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Results per page (default: 10, max 100)`,"zh-CN":`每页结果数(默认:10,最多:100)`}},status:{type:`string`,valueHint:`<s>`,description:{"en-US":`Filter by status (PENDING / RUNNING / SUCCEEDED / FAILED / CANCELED)`,"zh-CN":`按状态筛选(PENDING / RUNNING / SUCCEEDED / FAILED / CANCELED)`}},baseModel:{type:`string`,valueHint:`<model>`,description:{"en-US":`Filter by base model ID (server-side)`,"zh-CN":`按基础模型 ID 筛选(服务端筛选)`}}},exampleArgs:[``,`--status RUNNING`,`--base-model qwen3-8b`,`--page-size 20`],async run(e){let{settings:t,flags:n}=e,r=n.page,i=n.pageSize,a=n.status||void 0,o=n.baseModel||void 0;if(t.dryRun){A({action:`finetune.list`,page:r,page_size:i,status:a,model:o},`json`);return}let s=await lt(e.client,{pageNo:r,pageSize:i,status:a,model:o}),c=s.output??s.data,l=c?.jobs??[],u=c?.total;A({items:l.map(e=>({job_id:e.job_id??``,base_model:e.model??``,status:e.status??``,training_type:e.training_type??``,output_model:e.finetuned_output??``,created_at:e.create_time??e.gmt_create??``})),total:u,request_id:s.request_id},`json`)}});async function qf(e,t){let n=be(e),r=nn(await ie({region:n.consoleRegion,site:n.consoleSite,switchAgent:n.consoleSwitchAgent},e.timeout,{api:f,data:{input:{pageNo:1,pageSize:10,group:!0,model:t,queryPrice:!0,querySampleCode:!1,queryGroupByModel:!0,queryQuota:!1,queryQpmInfo:!1,queryApplyStatus:!1,queryPermissions:!1,queryActivationStatus:!1}}})).list??[];for(let e of r){let n=e.items??[];for(let e of n)if(e.model===t)return(e.prices??[]).find(e=>e.type===`ft`)??null;if(e.model===t)return(e.prices??[]).find(e=>e.type===`ft`)??null}return null}async function Jf(e,t,n){try{let r=await qf(e,t),i=Number(r?.price);if(!Number.isFinite(i)||i<=0)return null;let a=r?.priceUnit??`每百万tokens`,o=n/1e6*i;return{cost:Number(o.toFixed(4)),unitPrice:i,priceUnit:a}}catch{return null}}var Yf=w({description:{"en-US":`Get details of a single fine-tune job`,"zh-CN":`获取单个微调任务的详情`},auth:`apiKey`,usageArgs:`--job-id <id>`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Fine-tune job ID (required)`,"zh-CN":`微调任务 ID(必填)`},required:!0}},exampleArgs:[`--job-id ft-xxx`,`--job-id ft-xxx --output json`],async run(e){let{settings:t,flags:n}=e,r=n.jobId;if(t.dryRun){A({action:`finetune.get`,job_id:r},`json`);return}let i=await Ve(e.client,r),a=i.output??i.data;if(!a){A({job_id:r,error:`No data returned`},`json`);return}let o=a.hyper_parameters,s=[];o?.n_epochs!==void 0&&s.push(`n_epochs=${o.n_epochs}`),o?.batch_size!==void 0&&s.push(`batch_size=${o.batch_size}`),o?.learning_rate!==void 0&&s.push(`learning_rate=${o.learning_rate}`),o?.max_length!==void 0&&s.push(`max_length=${o.max_length}`);let c=typeof a.usage==`number`?a.usage:void 0,l={job_id:a.job_id??r,base_model:a.model??``,status:a.status??``,training_type:a.training_type??``,training_files:a.training_file_ids??[],validation_files:a.validation_file_ids??[],hyper_params:s.length?s.join(` · `):``,output_model:a.finetuned_output??``,model_name:a.model_name??``,created_at:a.create_time??a.gmt_create??``,updated_at:a.end_time??a.gmt_modified??``,usage_tokens:c??``,charge_type:typeof a.charge_type==`string`?a.charge_type:``};if(c!==void 0&&c>0&&a.model){let e=await Jf(t,a.model,c);e&&(l.training_cost=e.cost,l.cost_basis=`${e.unitPrice} 元/${e.priceUnit}`)}A({...l,request_id:i.request_id},`json`)}}),Xf=w({description:{"en-US":`Cancel a running fine-tune job`,"zh-CN":`取消正在运行的微调任务`},auth:`apiKey`,usageArgs:`--job-id <id>`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Fine-tune job ID (required)`,"zh-CN":`微调任务 ID(必填)`},required:!0}},exampleArgs:[`--job-id ft-xxx`,`--job-id ft-xxx --dry-run`],notes:[{"en-US":`Only PENDING / RUNNING jobs can be cancelled. Completed / failed / already-cancelled jobs return a server-side error (passed through verbatim).`,"zh-CN":`只有 PENDING / RUNNING 状态的任务可以取消。已完成、失败或已取消的任务会返回服务端错误(原样透传)。`}],async run(e){let{settings:t,flags:n}=e,r=n.jobId;if(t.dryRun){A({action:`finetune.cancel`,job_id:r},`json`);return}let i=await ae(e.client,r);t.quiet?k(r):A(i,`json`)}}),Zf=w({description:{"en-US":`Delete a fine-tune job record`,"zh-CN":`删除微调任务记录`},auth:`apiKey`,usageArgs:`--job-id <id>`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Fine-tune job ID (required)`,"zh-CN":`微调任务 ID(必填)`},required:!0}},exampleArgs:[`--job-id ft-xxx`,`--job-id ft-xxx --dry-run`],notes:[{"en-US":"Cancel a RUNNING job first via `finetune cancel` — the platform refuses to delete jobs that are still in flight.","zh-CN":"请先通过 `finetune cancel` 取消 RUNNING 任务,平台拒绝删除仍在运行的任务。"}],async run(e){let{settings:t,flags:n}=e,r=n.jobId;if(t.dryRun){A({action:`finetune.delete`,job_id:r},`json`);return}let i=await _e(e.client,r);t.quiet?k(r):A(i,`json`)}});function Qf(e){if(typeof e==`string`)return e;let t=e,n=t.timestamp??t.time??t.create_time??``,r=t.level??``,i=t.message??t.msg??t.log??``;return i||n||r?[n,r,i].filter(Boolean).join(` `):JSON.stringify(e)}function $f(e,t){return Qf(e).toLowerCase().includes(t)}async function ep(e,t,n){let r=[],i=1,a=0;for(let o=0;o<200;o++){let o=await He(e,t,{pageNo:i,pageSize:n}),s=o.output??o.data,c=s?.logs??[];if(a=s?.total??a,c.length===0||(r.push(...c),a&&r.length>=a)||c.length<n)break;i++}return{entries:r,total:a}}var tp=w({description:{"en-US":`Fetch training logs for a fine-tune job`,"zh-CN":`获取微调任务的训练日志`},auth:`apiKey`,usageArgs:`--job-id <id> [--page <n>] [--page-size <n>] [--search <keyword>] [--tail <n>]`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Fine-tune job ID (required)`,"zh-CN":`微调任务 ID(必填)`},required:!0},page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Lines per page (default: server-defined)`,"zh-CN":`每页行数(默认:由服务端决定)`}},search:{type:`string`,valueHint:`<keyword>`,description:{"en-US":`Case-insensitive substring filter. When set, all log pages are fetched and filtered client-side (--page is ignored).`,"zh-CN":`不区分大小写的子字符串筛选。设置后会获取全部日志页并在客户端筛选(忽略 --page)。`}},tail:{type:`number`,valueHint:`<n>`,description:{"en-US":`Keep only the last N entries. When set, all log pages are fetched and the trailing N are kept (--page is ignored).`,"zh-CN":`仅保留最后 N 条记录。设置后会获取全部日志页并保留末尾 N 条(忽略 --page)。`}}},exampleArgs:[`--job-id ft-xxx`,`--job-id ft-xxx --page-size 100 --output json`,`--job-id ft-xxx --search checkpoint`,`--job-id ft-xxx --search error --output json`,`--job-id ft-xxx --tail 20`,`--job-id ft-xxx --search checkpoint --tail 5`],async run(e){let{settings:t,flags:n}=e,r=n.jobId,i=n.page,a=n.pageSize,o=n.search||void 0,s=n.tail;if(t.dryRun){A({action:`finetune.logs`,job_id:r,page:i,page_size:a,search:o,tail:s},`json`);return}if(o||s!==void 0){let{entries:t,total:n}=await ep(e.client,r,a??100),i=t,c;if(o){let e=o.toLowerCase();i=t.filter(t=>$f(t,e)),c=i.length}let l=s!==void 0&&s>=0?Math.min(s,i.length):void 0,u=l===void 0?i:i.slice(i.length-l);A({...c===void 0?{}:{matched:c},scanned:t.length,total:n||t.length,...o?{search:o}:{},...l===void 0?{}:{tail:l},logs:u},`json`);return}A(await He(e.client,r,{pageNo:i,pageSize:a}),`json`)}}),np=w({description:{"en-US":`List checkpoints produced by a fine-tune job`,"zh-CN":`列出微调任务生成的 Checkpoint`},auth:`apiKey`,usageArgs:`--job-id <id>`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Fine-tune job ID (required)`,"zh-CN":`微调任务 ID(必填)`},required:!0}},exampleArgs:[`--job-id ft-xxx`,`--job-id ft-xxx --output json`],notes:[{"en-US":"`model_name` (shown for SUCCEEDED checkpoints) is the direct input for `deploy create --model-name`.","zh-CN":"SUCCEEDED Checkpoint 中显示的 `model_name` 可直接作为 `deploy create --model-name` 的输入。"},{"en-US":"Checkpoints expire ~15 days after creation; `expire_time` shows the deadline. Export or deploy before expiry.","zh-CN":"Checkpoint 创建后约 15 天过期,`expire_time` 显示截止时间。请在过期前导出或部署。"}],async run(e){let{settings:t,flags:n}=e,r=n.jobId;if(t.dryRun){A({action:`finetune.checkpoints`,job_id:r},`json`);return}let i=await at(e.client,r),a=i.output??i.data,o=Array.isArray(a)?a:a?.checkpoints??[],s=Array.isArray(a)?a.length:a?.total??o.length,c=o.map(e=>({checkpoint:e.checkpoint??e.checkpoint_id??``,step:e.step===void 0?``:String(e.step),status:e.status??``,model_name:e.model_name??``,expire_time:e.expire_time??``}));A({items:c,total:s,request_id:i.request_id},`json`);let l=Date.now(),u=c.filter(e=>{if(!e.expire_time)return!1;let t=new Date(e.expire_time).getTime();if(Number.isNaN(t))return!1;let n=t-l;return n>0&&n<2592e5});u.length>0&&process.stderr.write(`\n[warning] ${u.length} checkpoint(s) will expire within 72 hours. Export or deploy before expiry to avoid losing the model artifact.
2797
+ `)}if(e&&!ft(e).includes(u)){let n=ft(e);throw new t(`Model "${s}" does not support training type "${u}".`,c.USAGE,n.length?`This model supports: ${n.join(`, `)}.`:`This model reports no supported training types.`)}}i.dryRun||(await jf(n.client,i,m,`fine-tune`,`datasets`),g&&await jf(n.client,i,g,`fine-tune`,`validations`));let S={model:s,training_file_ids:h,training_type:d.serverTrainingType,hyper_parameters:x};if(_&&_.length>0&&(S.validation_file_ids=_),y&&(S.model_name=y),b&&(S.finetuned_output_suffix=b),i.dryRun){let e=[...m.localPaths.map(e=>({field:`datasets`,path:e})),...(g?.localPaths??[]).map(e=>({field:`validations`,path:e}))];A(e.length>0?{action:`finetune.create`,body:S,pending_uploads:e}:{action:`finetune.create`,body:S},`json`);return}let C=await de(n.client,S),ee=C.output??C.data;i.quiet?ee?.job_id&&k(ee.job_id):A(C,`json`)}const Hf=w({description:{"en-US":`Create a text model fine-tune job (sft | sft-lora | dpo | dpo-lora | cpt)`,"zh-CN":`创建文本模型微调任务(sft | sft-lora | dpo | dpo-lora | cpt)`},auth:`apiKey`,usageArgs:`--base-model <model> --datasets <id|path,...> [--validations <id|path,...>] [--model-name <name>] [--suffix <text>] [--n-epochs <n>] [--batch-size <n>] [--learning-rate <str>] [--max-length <n>] [--training-type <sft|sft-lora|dpo|dpo-lora|cpt>]`,flags:Nf,exampleArgs:[`--base-model qwen3-8b --datasets file-xxx`,`--base-model qwen3-8b --datasets ./train.jsonl`,`--base-model qwen3-8b --datasets ./train.jsonl --validations ./eval.jsonl`,`--base-model qwen3-8b --datasets file-aaa,./extra.jsonl`,`--base-model qwen3-8b --datasets ./train.jsonl --training-type sft`,`--base-model qwen3-8b --datasets file-xxx --learning-rate "1.6e-5" --n-epochs 4`,`--base-model qwen3-8b --datasets file-xxx --output json`,`--base-model qwen3-8b --datasets file-xxx --dry-run`],notes:Rf,run:e=>Vf(`text`,e)}),Uf=w({description:{"en-US":`Create an audio TTS model fine-tune job (sft-lora)`,"zh-CN":`创建音频 TTS 模型微调任务(sft-lora)`},auth:`apiKey`,usageArgs:`--base-model <model> --datasets <id|path> [--validations <id|path>] [--model-name <name>] [--suffix <text>]`,flags:Pf,exampleArgs:[`--base-model cosyvoice-v3-flash --datasets ./audio.zip`,`--base-model cosyvoice-v3-flash --datasets file-xxx`,`--base-model cosyvoice-v3-flash --datasets ./audio.zip --model-name my-tts`,`--base-model cosyvoice-v3-flash --datasets file-xxx --output json`,`--base-model cosyvoice-v3-flash --datasets ./audio.zip --dry-run`],notes:zf,run:e=>Vf(`audio`,e)}),Wf=w({description:{"en-US":`Create an image generation model fine-tune job (sft-lora)`,"zh-CN":`创建图片生成模型微调任务(sft-lora)`},auth:`apiKey`,usageArgs:`--base-model <model> --datasets <id|path> [--validations <id|path>] [--model-name <name>] [--suffix <text>] [--generation-type <t2i|i2i>] [--learning-rate <str>]`,flags:Ff,exampleArgs:[`--base-model wan2.7-image-pro --datasets ./images.zip`,`--base-model wan2.7-image-pro --datasets file-xxx`,`--base-model wan2.7-image-pro --datasets file-xxx --generation-type i2i`,`--base-model wan2.7-image-pro --datasets ./images.zip --model-name my-wan`,`--base-model wan2.7-image-pro --datasets file-xxx --output json`,`--base-model wan2.7-image-pro --datasets ./images.zip --dry-run`],notes:Bf,run:e=>Vf(`image`,e)}),Gf=w({description:{"en-US":`Create a video generation model fine-tune job (Wan i2v/kf2v, efficient_sft)`,"zh-CN":`创建视频生成模型微调任务(Wan i2v/kf2v,efficient_sft)`},auth:`apiKey`,usageArgs:`--base-model <model> --datasets <id|path> [--validations <id|path>] [--model-name <name>] [--suffix <text>] [--n-epochs <n>] [--batch-size <n>] [--learning-rate <str>]`,flags:If,exampleArgs:[`--base-model wan2.7-i2v --datasets file-xxx`,`--base-model wan2.7-i2v --datasets ./i2v-data.zip`,`--base-model wan2.2-kf2v-flash --datasets file-xxx --n-epochs 100`,`--base-model wan2.7-i2v --datasets file-xxx --dry-run`],notes:[...Lf,{"en-US":`Video generation training (Wan i2v/kf2v) runs efficient_sft with model-specific defaults: wan2.7 (batch_size=1, max_pixels=102400), wan2.5/2.2 (batch_size=4, max_pixels per model). Override with --batch-size/--n-epochs.`,"zh-CN":`视频生成训练(Wan i2v/kf2v)使用 efficient_sft 和模型专属默认值:wan2.7(batch_size=1、max_pixels=102400),wan2.5/2.2(batch_size=4,max_pixels 因模型而异)。可通过 --batch-size/--n-epochs 覆盖。`},{"en-US":`Datasets are .zip archives with data.jsonl + frame images + videos.`,"zh-CN":`数据集为包含 data.jsonl、帧图片和视频的 .zip 归档。`},{"en-US":`Recommended: ≥10 training samples, 20-100 for stable results.`,"zh-CN":`建议至少准备 10 个训练样本;20–100 个样本可获得更稳定的效果。`}],run:e=>Vf(`video`,e)});var Kf=w({description:{"en-US":`List fine-tune jobs`,"zh-CN":`列出微调任务`},auth:`apiKey`,usageArgs:`[--page <n>] [--page-size <n>] [--status <s>] [--base-model <model>]`,flags:{page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Results per page (default: 10, max 100)`,"zh-CN":`每页结果数(默认:10,最多:100)`}},status:{type:`string`,valueHint:`<s>`,description:{"en-US":`Filter by status (PENDING / RUNNING / SUCCEEDED / FAILED / CANCELED)`,"zh-CN":`按状态筛选(PENDING / RUNNING / SUCCEEDED / FAILED / CANCELED)`}},baseModel:{type:`string`,valueHint:`<model>`,description:{"en-US":`Filter by base model ID (server-side)`,"zh-CN":`按基础模型 ID 筛选(服务端筛选)`}}},exampleArgs:[``,`--status RUNNING`,`--base-model qwen3-8b`,`--page-size 20`],async run(e){let{settings:t,flags:n}=e,r=n.page,i=n.pageSize,a=n.status||void 0,o=n.baseModel||void 0;if(t.dryRun){A({action:`finetune.list`,page:r,page_size:i,status:a,model:o},`json`);return}let s=await lt(e.client,{pageNo:r,pageSize:i,status:a,model:o}),c=s.output??s.data,l=c?.jobs??[],u=c?.total;A({items:l.map(e=>({job_id:e.job_id??``,base_model:e.model??``,status:e.status??``,training_type:e.training_type??``,output_model:e.finetuned_output??``,created_at:e.create_time??e.gmt_create??``})),total:u,request_id:s.request_id},`json`)}});async function qf(e,t){let n=be(e),r=nn(await ie({region:n.consoleRegion,site:n.consoleSite,switchAgent:n.consoleSwitchAgent},e.timeout,{api:f,data:{input:{pageNo:1,pageSize:10,group:!0,model:t,queryPrice:!0,querySampleCode:!1,queryGroupByModel:!0,queryQuota:!1,queryQpmInfo:!1,queryApplyStatus:!1,queryPermissions:!1,queryActivationStatus:!1}}})).list??[];for(let e of r){let n=e.items??[];for(let e of n)if(e.model===t)return(e.prices??[]).find(e=>e.type===`ft`)??null;if(e.model===t)return(e.prices??[]).find(e=>e.type===`ft`)??null}return null}async function Jf(e,t,n){try{let r=await qf(e,t),i=Number(r?.price);if(!Number.isFinite(i)||i<=0)return null;let a=r?.priceUnit??`每百万tokens`,o=n/1e6*i;return{cost:Number(o.toFixed(4)),unitPrice:i,priceUnit:a}}catch{return null}}var Yf=w({description:{"en-US":`Get details of a single fine-tune job`,"zh-CN":`获取单个微调任务的详情`},auth:`apiKey`,usageArgs:`--job-id <id>`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Fine-tune job ID (required)`,"zh-CN":`微调任务 ID(必填)`},required:!0}},exampleArgs:[`--job-id ft-xxx`,`--job-id ft-xxx --output json`],async run(e){let{settings:t,flags:n}=e,r=n.jobId;if(t.dryRun){A({action:`finetune.get`,job_id:r},`json`);return}let i=await Ve(e.client,r),a=i.output??i.data;if(!a){A({job_id:r,error:`No data returned`},`json`);return}let o=a.hyper_parameters,s=[];o?.n_epochs!==void 0&&s.push(`n_epochs=${o.n_epochs}`),o?.batch_size!==void 0&&s.push(`batch_size=${o.batch_size}`),o?.learning_rate!==void 0&&s.push(`learning_rate=${o.learning_rate}`),o?.max_length!==void 0&&s.push(`max_length=${o.max_length}`);let c=typeof a.usage==`number`?a.usage:void 0,l={job_id:a.job_id??r,base_model:a.model??``,status:a.status??``,training_type:a.training_type??``,training_files:a.training_file_ids??[],validation_files:a.validation_file_ids??[],hyper_params:s.length?s.join(` · `):``,output_model:a.finetuned_output??``,model_name:a.model_name??``,created_at:a.create_time??a.gmt_create??``,updated_at:a.end_time??a.gmt_modified??``,usage_tokens:c??``,charge_type:typeof a.charge_type==`string`?a.charge_type:``};if(c!==void 0&&c>0&&a.model){let e=await Jf(t,a.model,c);e&&(l.training_cost=e.cost,l.cost_basis=`${e.unitPrice} 元/${e.priceUnit}`)}A({...l,request_id:i.request_id},`json`)}}),Xf=w({description:{"en-US":`Cancel a running fine-tune job`,"zh-CN":`取消正在运行的微调任务`},auth:`apiKey`,usageArgs:`--job-id <id>`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Fine-tune job ID (required)`,"zh-CN":`微调任务 ID(必填)`},required:!0}},exampleArgs:[`--job-id ft-xxx`,`--job-id ft-xxx --dry-run`],notes:[{"en-US":`Only PENDING / RUNNING jobs can be cancelled. Completed / failed / already-cancelled jobs return a server-side error (passed through verbatim).`,"zh-CN":`只有 PENDING / RUNNING 状态的任务可以取消。已完成、失败或已取消的任务会返回服务端错误(原样透传)。`}],async run(e){let{settings:t,flags:n}=e,r=n.jobId;if(t.dryRun){A({action:`finetune.cancel`,job_id:r},`json`);return}let i=await ae(e.client,r);t.quiet?k(r):A(i,`json`)}}),Zf=w({description:{"en-US":`Delete a fine-tune job record`,"zh-CN":`删除微调任务记录`},auth:`apiKey`,usageArgs:`--job-id <id> [--yes]`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Fine-tune job ID (required)`,"zh-CN":`微调任务 ID(必填)`},required:!0},yes:{type:`switch`,description:{"en-US":`Skip the confirmation prompt`,"zh-CN":`跳过确认提示`}}},exampleArgs:[`--job-id ft-xxx`,`--job-id ft-xxx --dry-run`,`--job-id ft-xxx --yes`],notes:[{"en-US":`Irreversible — the job record is permanently removed.`,"zh-CN":`该操作不可撤销——任务记录将被永久删除。`},{"en-US":"Cancel a RUNNING job first via `finetune cancel` — the platform refuses to delete jobs that are still in flight.","zh-CN":"请先通过 `finetune cancel` 取消 RUNNING 任务,平台拒绝删除仍在运行的任务。"}],async run(e){let{settings:t,flags:n}=e,r=n.jobId;if(t.dryRun){A({action:`finetune.delete`,job_id:r},`json`);return}await yn(`Delete fine-tune job record ${r}.\nThe job record is permanently removed. This cannot be undone.`,n.yes??!1);let i=await _e(e.client,r);t.quiet?k(r):A(i,`json`)}});function Qf(e){if(typeof e==`string`)return e;let t=e,n=t.timestamp??t.time??t.create_time??``,r=t.level??``,i=t.message??t.msg??t.log??``;return i||n||r?[n,r,i].filter(Boolean).join(` `):JSON.stringify(e)}function $f(e,t){return Qf(e).toLowerCase().includes(t)}async function ep(e,t,n){let r=[],i=1,a=0;for(let o=0;o<200;o++){let o=await He(e,t,{pageNo:i,pageSize:n}),s=o.output??o.data,c=s?.logs??[];if(a=s?.total??a,c.length===0||(r.push(...c),a&&r.length>=a)||c.length<n)break;i++}return{entries:r,total:a}}var tp=w({description:{"en-US":`Fetch training logs for a fine-tune job`,"zh-CN":`获取微调任务的训练日志`},auth:`apiKey`,usageArgs:`--job-id <id> [--page <n>] [--page-size <n>] [--search <keyword>] [--tail <n>]`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Fine-tune job ID (required)`,"zh-CN":`微调任务 ID(必填)`},required:!0},page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Lines per page (default: server-defined)`,"zh-CN":`每页行数(默认:由服务端决定)`}},search:{type:`string`,valueHint:`<keyword>`,description:{"en-US":`Case-insensitive substring filter. When set, all log pages are fetched and filtered client-side (--page is ignored).`,"zh-CN":`不区分大小写的子字符串筛选。设置后会获取全部日志页并在客户端筛选(忽略 --page)。`}},tail:{type:`number`,valueHint:`<n>`,description:{"en-US":`Keep only the last N entries. When set, all log pages are fetched and the trailing N are kept (--page is ignored).`,"zh-CN":`仅保留最后 N 条记录。设置后会获取全部日志页并保留末尾 N 条(忽略 --page)。`}}},exampleArgs:[`--job-id ft-xxx`,`--job-id ft-xxx --page-size 100 --output json`,`--job-id ft-xxx --search checkpoint`,`--job-id ft-xxx --search error --output json`,`--job-id ft-xxx --tail 20`,`--job-id ft-xxx --search checkpoint --tail 5`],async run(e){let{settings:t,flags:n}=e,r=n.jobId,i=n.page,a=n.pageSize,o=n.search||void 0,s=n.tail;if(t.dryRun){A({action:`finetune.logs`,job_id:r,page:i,page_size:a,search:o,tail:s},`json`);return}if(o||s!==void 0){let{entries:t,total:n}=await ep(e.client,r,a??100),i=t,c;if(o){let e=o.toLowerCase();i=t.filter(t=>$f(t,e)),c=i.length}let l=s!==void 0&&s>=0?Math.min(s,i.length):void 0,u=l===void 0?i:i.slice(i.length-l);A({...c===void 0?{}:{matched:c},scanned:t.length,total:n||t.length,...o?{search:o}:{},...l===void 0?{}:{tail:l},logs:u},`json`);return}A(await He(e.client,r,{pageNo:i,pageSize:a}),`json`)}}),np=w({description:{"en-US":`List checkpoints produced by a fine-tune job`,"zh-CN":`列出微调任务生成的 Checkpoint`},auth:`apiKey`,usageArgs:`--job-id <id>`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Fine-tune job ID (required)`,"zh-CN":`微调任务 ID(必填)`},required:!0}},exampleArgs:[`--job-id ft-xxx`,`--job-id ft-xxx --output json`],notes:[{"en-US":"`model_name` (shown for SUCCEEDED checkpoints) is the direct input for `deploy create --model-name`.","zh-CN":"SUCCEEDED Checkpoint 中显示的 `model_name` 可直接作为 `deploy create --model-name` 的输入。"},{"en-US":"Checkpoints expire ~15 days after creation; `expire_time` shows the deadline. Export or deploy before expiry.","zh-CN":"Checkpoint 创建后约 15 天过期,`expire_time` 显示截止时间。请在过期前导出或部署。"}],async run(e){let{settings:t,flags:n}=e,r=n.jobId;if(t.dryRun){A({action:`finetune.checkpoints`,job_id:r},`json`);return}let i=await at(e.client,r),a=i.output??i.data,o=Array.isArray(a)?a:a?.checkpoints??[],s=Array.isArray(a)?a.length:a?.total??o.length,c=o.map(e=>({checkpoint:e.checkpoint??e.checkpoint_id??``,step:e.step===void 0?``:String(e.step),status:e.status??``,model_name:e.model_name??``,expire_time:e.expire_time??``}));A({items:c,total:s,request_id:i.request_id},`json`);let l=Date.now(),u=c.filter(e=>{if(!e.expire_time)return!1;let t=new Date(e.expire_time).getTime();if(Number.isNaN(t))return!1;let n=t-l;return n>0&&n<2592e5});u.length>0&&process.stderr.write(`\n[warning] ${u.length} checkpoint(s) will expire within 72 hours. Export or deploy before expiry to avoid losing the model artifact.
2798
2798
  `)}}),rp=w({description:{"en-US":`Publish a checkpoint as a deployable model`,"zh-CN":`将 Checkpoint 发布为可部署模型`},auth:`apiKey`,usageArgs:`--job-id <id> --checkpoint <name> --model-name <name>`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Fine-tune job ID (required)`,"zh-CN":`微调任务 ID(必填)`},required:!0},checkpoint:{type:`string`,valueHint:`<name>`,description:{"en-US":"Checkpoint identifier from `finetune checkpoints` (required)","zh-CN":"来自 `finetune checkpoints` 的 Checkpoint 标识(必填)"},required:!0},modelName:{type:`string`,valueHint:`<name>`,description:{"en-US":`Deployable model name (required)`,"zh-CN":`可部署模型名称(必填)`},required:!0}},exampleArgs:[`--job-id ft-xxx --checkpoint ckpt-3 --model-name my-qwen-sft`],notes:[{"en-US":"Required before `deploy <modality> create` can target a checkpoint. The platform may auto-export the best checkpoint when a job reaches SUCCEEDED — explicit export is the canonical path for non-best checkpoints.","zh-CN":"必须先执行此操作,`deploy <modality> create` 才能使用 Checkpoint。任务达到 SUCCEEDED 后,平台可能自动导出最佳 Checkpoint;对于非最佳 Checkpoint,显式导出是标准方式。"}],async run(e){let{settings:t,flags:n}=e,r=n.jobId,i=n.checkpoint,a=n.modelName;if(t.dryRun){A({action:`finetune.export`,job_id:r,checkpoint:i,model_name:a},`json`);return}let o=await Ce(e.client,r,i,a),s=(o.output??o.data)?.model_name??a;t.quiet?k(s):A(o,`json`)}});const ip=new Set([`SUCCEEDED`,`FAILED`,`CANCELED`]);function ap(){let e=new Date,t=e=>String(e).padStart(2,`0`);return`${t(e.getHours())}:${t(e.getMinutes())}:${t(e.getSeconds())}`}function op(e){let t=Math.floor(e/1e3),n=Math.floor(t/60),r=t%60;return n===0?`${r}s`:`${n}m ${r}s`}function sp(e,t){return new Promise((n,r)=>{if(t.aborted){r(Error(`aborted`));return}let i=()=>{clearTimeout(a),r(Error(`aborted`))},a=setTimeout(()=>{t.removeEventListener(`abort`,i),n()},e);t.addEventListener(`abort`,i,{once:!0})})}var cp=w({description:{"en-US":`Probe a fine-tune job's status (default: single non-blocking fetch). Pass --follow to poll until terminal.`,"zh-CN":`查询微调任务状态(默认:单次非阻塞获取)。使用 --follow 持续轮询至终态。`},auth:`apiKey`,usageArgs:`--job-id <id> [--follow] [--interval <sec>] [--poll-timeout <sec>]`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Fine-tune job ID (required)`,"zh-CN":`微调任务 ID(必填)`},required:!0},follow:{type:`switch`,description:{"en-US":`Block and poll until a terminal state (the legacy behavior). Without it, a single status probe is performed and the command returns immediately.`,"zh-CN":`阻塞并轮询至终态(旧版行为)。不使用时仅查询一次状态并立即返回。`}},interval:{type:`number`,valueHint:`<sec>`,description:{"en-US":`Seconds between polls with --follow (default: 10, min: 1). Ignored without --follow.`,"zh-CN":`使用 --follow 时的轮询间隔秒数(默认:10,最小:1)。未使用 --follow 时忽略。`}},pollTimeout:{type:`number`,valueHint:`<sec>`,description:{"en-US":`With --follow, stop polling after this many seconds (default: no limit). Ignored without --follow.`,"zh-CN":`使用 --follow 时,在指定秒数后停止轮询(默认:无限制)。未使用 --follow 时忽略。`}}},exampleArgs:[{"en-US":`--job-id ft-xxx # single probe, returns immediately`,"zh-CN":`--job-id ft-xxx # 单次查询,立即返回`},{"en-US":`--job-id ft-xxx --output json # status probe for agents`,"zh-CN":`--job-id ft-xxx --output json # 供智能体查询状态`},{"en-US":`--job-id ft-xxx --follow # block until terminal`,"zh-CN":`--job-id ft-xxx --follow # 阻塞等待至终态`},`--job-id ft-xxx --follow --interval 5`,`--job-id ft-xxx --follow --poll-timeout 3600`],notes:[{"en-US":`Default (no --follow) is a NON-BLOCKING single status probe: one fetch, then return immediately. This is the mode meant for agents / scripts — the caller owns the polling cadence, so the CLI never holds the terminal.`,"zh-CN":`默认不使用 --follow,执行非阻塞的单次状态查询:获取一次后立即返回。该模式适用于 Agent / 脚本,由调用方控制轮询节奏,CLI 不会持续占用终端。`},{"en-US":`A terminal FAILED/CANCELED status raises a normal CLI error (non-zero exit); a SUCCEEDED or still-running status returns 0. With --follow, exceeding --poll-timeout raises a timeout error.`,"zh-CN":`终态 FAILED/CANCELED 会触发普通 CLI 错误(非零退出码);SUCCEEDED 或仍在运行时返回 0。使用 --follow 时,超过 --poll-timeout 会触发超时错误。`},{"en-US":`Use --follow for the blocking, human-terminal-follow experience; use the default mode when driving the loop yourself (e.g. from an agent).`,"zh-CN":`需要在人工终端中阻塞跟踪时使用 --follow;自行驱动轮询(例如通过 Agent)时使用默认模式。`},{"en-US":"For per-step training output (not status), use `finetune logs`.","zh-CN":"要查看逐步骤训练输出(而非状态),请使用 `finetune logs`。"}],async run(e){let{settings:n,flags:r}=e,i=r.jobId,a=r.follow,o=Math.max(1,r.interval??10),s=r.pollTimeout;if(n.dryRun){A({action:`finetune.watch`,job_id:i,follow:a,interval:o,timeout:s},`json`);return}if(!a){let r=await Ve(e.client,i),a=r.output??r.data,o=String(a?.status??``).toUpperCase(),s=ip.has(o);if(n.quiet)k(o||`UNKNOWN`);else{let e={job_id:i,status:o||`UNKNOWN`,terminal:s,request_id:r.request_id},t=typeof a?.usage==`number`?a.usage:void 0;if(s&&t&&t>0&&a?.model){e.usage_tokens=t;let r=await Jf(n,a.model,t);r&&(e.training_cost=r.cost,e.cost_basis=`${r.unitPrice} 元/${r.priceUnit}`)}A(e,`json`)}if(s&&o!==`SUCCEEDED`)throw new t(`Fine-tune job ${i} ended in status ${o}.`,c.GENERAL);return}let l=new AbortController,u=()=>l.abort();process.on(`SIGINT`,u);try{let r=``,a=Date.now();for(;;){let u=await Ve(e.client,i,l.signal),d=u.output??u.data,f=String(d?.status??``).toUpperCase();if(!n.quiet&&f!==r&&(process.stderr.write(`${ap()} ${i} ${f||`UNKNOWN`}\n`),r=f),ip.has(f)){let e=Date.now()-a;if(n.quiet)k(f||`UNKNOWN`);else{let e=typeof d?.usage==`number`?d.usage:void 0,t={...u};if(e&&e>0&&d?.model){let r=await Jf(n,d.model,e);r&&(t.training_cost=r.cost,t.usage_tokens=e,t.cost_basis=`${r.unitPrice} 元/${r.priceUnit}`)}A(t,`json`)}if(f!==`SUCCEEDED`)throw new t(`Fine-tune job ${i} ended in status ${f} (elapsed ${op(e)}).`,c.GENERAL);return}if(s!==void 0&&(Date.now()-a)/1e3>=s)throw new t(`Watching fine-tune job ${i} timed out after ${op(Date.now()-a)} (last status: ${f||`UNKNOWN`}).`,c.TIMEOUT);await sp(o*1e3,l.signal)}}catch(e){if(l.signal.aborted){process.stderr.write(`
2799
2799
  Interrupted.
2800
- `);return}throw e}finally{process.off(`SIGINT`,u)}}});async function lp(e){return await ke(x(e))}var up=w({description:{"en-US":`Query fine-tune training capability — by model (which training types it supports) or by training type (which models support it)`,"zh-CN":`查询微调训练能力:按模型查询其支持的训练类型,或按训练类型查询支持它的模型`},auth:`none`,usageArgs:`--base-model <m> | --training-type <t>`,flags:{baseModel:{type:`string`,valueHint:`<m>`,description:{"en-US":`List training types supported by this base model.`,"zh-CN":`列出该基础模型支持的训练类型。`}},trainingType:{type:`string`,valueHint:`<t>`,description:{"en-US":`List models supporting this training type: ${v.join(` | `)}.`,"zh-CN":`列出支持该训练类型的模型:${v.join(` | `)}。`}}},exampleArgs:[`--base-model qwen3-8b`,`--training-type sft-lora`,`--training-type cpt --output json`,`--training-type sft --quiet`],notes:[{"en-US":`Exactly one of --base-model / --training-type is required.`,"zh-CN":`--base-model 和 --training-type 必须且只能指定一个。`},{"en-US":"Training-type values use the `<method>` / `<method>-lora` convention: sft | sft-lora | dpo | dpo-lora | cpt. (cpt has no -lora variant server-side.)","zh-CN":"训练类型遵循 `<method>` / `<method>-lora` 命名约定:sft | sft-lora | dpo | dpo-lora | cpt。(服务端没有 cpt-lora 变体。)"},{"en-US":`Queries listFoundationModels, a public API — no console login needed.`,"zh-CN":`查询公开 API listFoundationModels,无需登录控制台。`}],validate:e=>{if(e.baseModel&&e.trainingType)return`--base-model and --training-type are mutually exclusive; pass one.`;if(!e.baseModel&&!e.trainingType)return`one of --base-model / --training-type is required.`},async run(e){let{settings:t,flags:n}=e,r=n.baseModel||void 0,i=n.trainingType||void 0;if(t.dryRun){A({action:`finetune.capability`,model:r,training_type:i},`json`);return}if(r){let e=await Ee(t,r);if(!e){A({model:r,error:`No foundation model found matching "${r}".`},`json`);return}let n=ft(e);if(t.quiet){for(let e of n)k(e);return}A({model:e.model??r,supported:n,supports:e.supports,trainingTypes:e.trainingTypes},`json`);return}if(!i||!et(i))throw new y(`--training-type "${i}" is not supported. Valid: ${v.join(`, `)}.`);let{method:a,variant:o}=en(i),s=(await lp(t)).filter(e=>xt(e,i)).map(e=>({model:e.model,name:e.name??e.model})).filter(e=>!!e.model).sort((e,t)=>e.model.localeCompare(t.model));if(t.quiet){for(let e of s)k(e.model);return}A({training_type:i,method:a,variant:o,count:s.length,models:s},`json`)}});const dp={baseModel:{type:`string`,valueHint:`<model>`,description:{"en-US":`Base model to fine-tune (e.g. qwen3-8b; not the output model name)`,"zh-CN":`待微调的基座模型(例如 qwen3-8b;不是输出模型名称)`},required:!0},datasets:{type:`string`,valueHint:`<ids>`,description:{"en-US":`Training dataset file IDs, comma-separated (required)`,"zh-CN":`训练数据集文件 ID,多个以逗号分隔(必填)`},required:!0},trainingType:{type:`string`,valueHint:`<type>`,description:{"en-US":`Training type: sft | dpo | cpt (default: sft)`,"zh-CN":`训练类型:sft | dpo | cpt(默认:sft)`}},nEpochs:{type:`number`,valueHint:`<n>`,description:{"en-US":`Number of training epochs (default: 3)`,"zh-CN":`训练轮数(默认:3)`}}},fp=[`sft`,`dpo`,`cpt`];var pp=w({description:{"en-US":`Estimate the training cost for a fine-tune job (token billing)`,"zh-CN":`估算微调任务的训练费用(按 Token 计费)`},auth:`console`,usageArgs:`--base-model <model> --datasets <ids> [--training-type <type>] [--n-epochs <n>]`,flags:dp,exampleArgs:[`--base-model qwen3-8b --datasets file-ft-xxx`,`--base-model qwen3-8b --datasets file-ft-xxx,file-ft-yyy --n-epochs 2`,`--base-model qwen3-8b --datasets file-ft-xxx --training-type cpt`],notes:[{"en-US":`Estimate only — the server computes token usage from the datasets; final cost is subject to the bill.`,"zh-CN":`该结果仅为估算值——服务端根据数据集计算 Token 用量,最终费用以账单为准。`},{"en-US":`Covers token billing for sft / dpo / cpt. Training-unit (MTU) billing is not supported by this command.`,"zh-CN":`支持估算 sft / dpo / cpt 的 Token 计费;此命令不支持训练单元(MTU)计费估算。`},{"en-US":`Hyper-parameters other than --n-epochs are fixed at representative defaults for estimation.`,"zh-CN":`除 --n-epochs 外,其他超参数会使用具有代表性的固定默认值进行估算。`}],async run(e){let{settings:n,flags:r}=e,i=r.baseModel,a=r.datasets.split(`,`).map(e=>e.trim()).filter(Boolean),o=(r.trainingType??`sft`).toLowerCase(),s=r.nEpochs??3;if(!fp.includes(o))throw new t(`Unsupported training type "${o}". Supported: ${fp.join(`, `)}.`,c.USAGE);if(a.length===0)throw new t(`--datasets must contain at least one file ID.`,c.USAGE);if(n.dryRun){A({action:`finetune.price`,model:i,datasets:a,trainingType:o,nEpochs:s},`json`);return}let l=await Me(e.client,i),u=Number(l.price);if(!Number.isFinite(u))throw new t(`No training price found for model "${i}".`,c.GENERAL,void 0,{rawResponse:JSON.stringify(l)});let d=o===`cpt`?await xe(e.client,i,a.join(`,`),s):await Se(e.client,a,{nEpochs:s,batchSize:16,maxLength:8192}),f=d.estimatedDatasetConsumedTokensMinPerEpoch??0,p=d.estimatedDatasetConsumedTokensMaxPerEpoch??0,m=d.estimatedMixedConsumedTokensMinPerEpoch??0,h=d.estimatedMixedConsumedTokensMaxPerEpoch??0,g=(f+m)*s,_=(p+h)*s,v=g/1e3*u,y=_/1e3*u;A({model:i,training_type:o,n_epochs:s,unit_price:u,price_unit:l.priceUnit??`千Token`,estimated_tokens:{min:g,max:_},estimated_fee_yuan:{min:Number(v.toFixed(4)),max:Number(y.toFixed(4))},disclaimer:`Server-side estimate; final cost is subject to the bill.`},`json`)}});const mp={modelName:{type:`string`,valueHint:`<model_name>`,description:{"en-US":`Model to deploy — fine-tuned output name or catalog model (required)`,"zh-CN":`要部署的模型:微调输出模型名称或模型目录中的模型(必填)`},required:!0},displayName:{type:`string`,valueHint:`<display_name>`,description:{"en-US":`Console display name for the deployment (required)`,"zh-CN":`部署在控制台中的显示名称(必填)`},required:!0},plan:{type:`string`,valueHint:`<plan>`,description:{"en-US":`Billing plan: lora (default, Token-billed) | ptu (Token-billed) | mu`,"zh-CN":`计费方案:lora(默认,按 Token 计费)| ptu(按 Token 计费)| mu`}},deploySpec:{type:`string`,valueHint:`<id>`,description:{"en-US":`Deploy spec (only used by plan=mu; auto-picked if omitted)`,"zh-CN":`部署规格(仅 plan=mu 使用;省略时自动选择)`}},capacity:{type:`number`,valueHint:`<n>`,description:{"en-US":`Resource units (plan=mu only; required by API; defaults to the template's unit)`,"zh-CN":`资源单元数(仅 plan=mu;API 必填;默认为模板的单元数)`}},billingMethod:{type:`string`,valueHint:`<m>`,description:{"en-US":`Billing method (plan=mu only; default "POST_PAY", the only supported value)`,"zh-CN":`计费方式(仅 plan=mu;默认且仅支持 "POST_PAY")`}},inputTpm:{type:`number`,valueHint:`<n>`,description:{"en-US":`PTU max input tokens/min (required for plan=ptu)`,"zh-CN":`PTU 每分钟最大输入 Token 数(plan=ptu 时必填)`}},outputTpm:{type:`number`,valueHint:`<n>`,description:{"en-US":`PTU max output tokens/min (required for plan=ptu)`,"zh-CN":`PTU 每分钟最大输出 Token 数(plan=ptu 时必填)`}},thinkingOutputTpm:{type:`number`,valueHint:`<n>`,description:{"en-US":`PTU max thinking-output tokens/min (optional, some models)`,"zh-CN":`PTU 每分钟最大思考输出 Token 数(部分模型可选)`}}},hp=`--model-name <model_name> --display-name <display_name> [--plan <plan>] [--deploy-spec <id>] [--capacity <n>] [--billing-method <m>] [--input-tpm <n>] [--output-tpm <n>] [--thinking-output-tpm <n>]`,gp=[{"en-US":"Plan defaults to `lora` (Token-billed) for text/image and `mu` (model-unit-billed) for audio (CosyVoice TTS). Pass --plan to override.","zh-CN":"文本和图片部署默认使用 `lora`(按 Token 计费),音频(CosyVoice TTS)默认使用 `mu`(按模型单元计费)。可通过 --plan 覆盖。"},{"en-US":`For plan=ptu (Token-billed, provisioned throughput), --input-tpm and --output-tpm are required (the platform rejects creation without an explicit ptu_capacity despite the doc listing defaults).`,"zh-CN":`plan=ptu(按 Token 计费的预置吞吐)时,--input-tpm 和 --output-tpm 必填;即使文档列出了默认值,未显式传入 ptu_capacity 时平台也会拒绝创建。`},{"en-US":"For plan=mu, `capacity`, `billing_method` and `deploy_spec` are required. billing_method defaults to POST_PAY (only supported value); deploy_spec and capacity are auto-picked from GET /deployments/models when omitted.","zh-CN":"plan=mu 时,`capacity`、`billing_method` 和 `deploy_spec` 必填。billing_method 默认且仅支持 POST_PAY;省略 deploy_spec 和 capacity 时,会从 GET /deployments/models 自动选择。"},{"en-US":"Use `bl deploy models --source base` to inspect available templates.","zh-CN":"使用 `bl deploy models --source base` 查看可用模板。"},{"en-US":`After creation, status starts at PENDING and transitions to RUNNING. Invoke the deployed model with: bl text chat --model <deployed_model>`,"zh-CN":`创建后状态从 PENDING 开始,随后转为 RUNNING。调用已部署模型:bl text chat --model <deployed_model>`},{"en-US":"NOTE: --model-name is the model being deployed (e.g. `qwen3-8b-ft-...`). The create response also returns a `deployed_model` field — the deployment instance id (e.g. `qwen3-8b-5ecb5f068d79`). Use that id for inference (`bl text chat --model <deployed_model>`) and lifecycle commands (`deploy get/scale/pause/resume/delete --deployed-model <id>`).","zh-CN":"注意:--model-name 是要部署的模型(例如 `qwen3-8b-ft-...`)。创建响应中的 `deployed_model` 是部署实例 ID(例如 `qwen3-8b-5ecb5f068d79`),用于推理(`bl text chat --model <deployed_model>`)及生命周期命令(`deploy get/scale/pause/resume/delete --deployed-model <id>`)。"}];function _p(e,t){let n=t.plan||pe(e),r=g[n];return r?r.validateFlags(t):`Unsupported plan "${n}". Supported plans: ${Object.keys(g).join(`, `)}.`}async function vp(e,t){let{identity:n,settings:r,flags:i}=t,a=i.modelName,o=i.displayName,s=i.plan||pe(e),c={model_name:a,name:o,plan:s,...(await kt(s).resolve({client:t.client,dryRun:r.dryRun,binName:n.binName,flags:i,model:a,name:o})).body};if(r.dryRun){A({action:`deploy.create`,body:c},`json`);return}let l=await ue(t.client,c),u=l.output??l.data;r.quiet?k(u?.deployed_model??``):A(l,`json`)}const yp=w({description:{"en-US":`Create a text model deployment`,"zh-CN":`创建文本模型部署`},auth:`apiKey`,usageArgs:hp,flags:mp,exampleArgs:[`--model-name my-qwen-sft --display-name my-sft-test`,`--model-name qwen3.6-flash-2026-04-16 --display-name my-flash --plan ptu --input-tpm 10000 --output-tpm 1000`,`--model-name qwen3-8b --display-name my-qwen3-mu --plan mu`,`--model-name qwen3-8b --display-name my-qwen3 --plan mu --deploy-spec MU1 --capacity 2`],notes:gp,validate:e=>_p(`text`,e),run:e=>vp(`text`,e)}),bp=w({description:{"en-US":`Create an audio (TTS) model deployment`,"zh-CN":`创建音频(TTS)模型部署`},auth:`apiKey`,usageArgs:hp,flags:mp,exampleArgs:[`--model-name my-cosyvoice-ft --display-name my-tts`,`--model-name my-cosyvoice-ft --display-name my-tts --deploy-spec dps-xxxx --capacity 1`,`--model-name my-cosyvoice-ft --display-name my-tts --dry-run`],notes:gp,validate:e=>_p(`audio`,e),run:e=>vp(`audio`,e)}),xp=w({description:{"en-US":`Create an image generation model deployment`,"zh-CN":`创建图片生成模型部署`},auth:`apiKey`,usageArgs:hp,flags:mp,exampleArgs:[`--model-name my-wan-ft --display-name my-wan`,`--model-name my-wan-ft --display-name my-wan-mu --plan mu`,`--model-name my-wan-ft --display-name my-wan --dry-run`],notes:gp,validate:e=>_p(`image`,e),run:e=>vp(`image`,e)});var Sp=w({description:{"en-US":`List model deployments`,"zh-CN":`列出模型部署`},auth:`apiKey`,usageArgs:`[--page <n>] [--page-size <n>] [--status <s>]`,flags:{page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Results per page (default: 10, max 100)`,"zh-CN":`每页结果数(默认:10,最多:100)`}},status:{type:`string`,valueHint:`<s>`,description:{"en-US":`Filter by status (PENDING / RUNNING / STOPPED / FAILED)`,"zh-CN":`按状态筛选(PENDING / RUNNING / STOPPED / FAILED)`}}},exampleArgs:[``,`--status RUNNING`,`--page-size 20 --output json`],async run(e){let{settings:t,flags:n}=e,r=n.status||void 0;if(t.dryRun){A({action:`deploy.list`,page:n.page,page_size:n.pageSize,status:r},`json`);return}let i=await ct(e.client,{pageNo:n.page,pageSize:n.pageSize,status:r}),a=i.output??i.data,o=a?.deployments??[],s=a?.total;A({items:o.map(e=>({deployed_model:e.deployed_model??``,model_name:e.model_name??``,status:e.status??``,plan:e.plan??``,capacity:e.capacity===void 0?``:String(e.capacity),created_at:e.gmt_create??``})),total:s,request_id:i.request_id},`json`)}}),Cp=w({description:{"en-US":`Get details of a single model deployment`,"zh-CN":`获取单个模型部署的详情`},auth:`apiKey`,usageArgs:`--deployed-model <id>`,flags:{deployedModel:{type:`string`,valueHint:`<id>`,description:{"en-US":`Deployed model identifier (required)`,"zh-CN":`已部署模型标识(必填)`},required:!0}},exampleArgs:[`--deployed-model qwen-plus-2025-12-01-b6d61c71`,`--deployed-model qwen-plus-2025-12-01-b6d61c71 --output json`],async run(e){let{settings:t,flags:n}=e,r=n.deployedModel;if(t.dryRun){A({action:`deploy.get`,deployed_model:r},`json`);return}let i=await Be(e.client,r),a=i.output??i.data;if(!a){A({deployed_model:r,request_id:i.request_id},`json`);return}let o={deployed_model:a.deployed_model??r,deployed_name:a.name??``,model_name:a.model_name??``,base_model:a.base_model??``,status:a.status??``,plan:a.plan??``};a.model_unit_spec&&(o.model_unit_spec=a.model_unit_spec),a.charge_type&&(o.charge_type=a.charge_type),a.capacity!==void 0&&(o.capacity=a.capacity),a.base_capacity!==void 0&&(o.base_capacity=a.base_capacity),a.ready_capacity!==void 0&&(o.ready_capacity=a.ready_capacity),a.rpm_limit!==void 0&&(o.rpm_limit=a.rpm_limit),a.tpm_limit!==void 0&&(o.tpm_limit=a.tpm_limit),a.input_tpm!==void 0&&(o.input_tpm=a.input_tpm),a.output_tpm!==void 0&&(o.output_tpm=a.output_tpm),a.gmt_create&&(o.created_at=a.gmt_create),a.gmt_modified&&(o.updated_at=a.gmt_modified),A({...o,request_id:i.request_id},`json`)}}),wp=w({description:{"en-US":`List models available for deployment`,"zh-CN":`列出可部署的模型`},auth:`apiKey`,usageArgs:`[--page <n>] [--page-size <n>] [--catalog-version <v>] [--source <custom|public>]`,flags:{page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Results per page (default: 100)`,"zh-CN":`每页结果数(默认:100)`}},catalogVersion:{type:`string`,valueHint:`<v>`,description:{"en-US":`Catalog version filter (default: v1.0; required for new catalog models)`,"zh-CN":`模型目录版本筛选(默认:v1.0;新目录模型必填)`}},source:{type:`string`,valueHint:`<s>`,description:{"en-US":`Model source filter: custom (fine-tuned) | base (catalog) | public`,"zh-CN":`模型来源筛选:custom(微调模型)| base(模型目录)| public`}}},exampleArgs:[``,`--source base`,`--source custom --page-size 50`,`--catalog-version v1.0 --output json`],async run(e){let{settings:t,flags:n}=e,r=n.catalogVersion===``?void 0:n.catalogVersion??`v1.0`,i=n.source||void 0;if(t.dryRun){A({action:`deploy.models`,page:n.page,page_size:n.pageSize,version:r,model_source:i},`json`);return}let a=await st(e.client,{pageNo:n.page,pageSize:n.pageSize,version:r,modelSource:i}),o=a.output??a.data,s=o?.models??[],c=o?.total;A({items:s.map(e=>{let t={model_name:e.model_name??``};return e.base_model&&(t.base_model=e.base_model),e.model_source&&(t.model_source=e.model_source),e.supported_plans&&e.supported_plans.length>0&&(t.supported_plans=e.supported_plans),e.plans&&e.plans.length>0&&(t.plans=e.plans.map(e=>{let t={plan:e.plan??``};return e.cu_specs&&e.cu_specs.length>0&&(t.cu_specs=e.cu_specs),e.templates&&e.templates.length>0&&(t.templates=e.templates.map(e=>{let t={};e.template_id&&(t.template_id=e.template_id),e.template_name&&(t.template_name=e.template_name),e.charge_type&&(t.charge_type=e.charge_type);let n=e.roles?.unified;return n?.model_unit_spec&&(t.model_unit_spec=n.model_unit_spec),n?.capacity_unit_per_instance!==void 0&&(t.capacity_unit_per_instance=n.capacity_unit_per_instance),(e.roles?.prefill||e.roles?.decode)&&(t.roles={prefill:e.roles?.prefill,decode:e.roles?.decode}),e.template_desc&&(t.template_desc=e.template_desc),t})),t})),t}),total:c,request_id:a.request_id},`json`)}}),Tp=w({description:{"en-US":`Scale a deployment's capacity`,"zh-CN":`调整部署容量`},auth:`apiKey`,usageArgs:`--deployed-model <id> --capacity <n> [--input-tpm <n>] [--output-tpm <n>]`,flags:{deployedModel:{type:`string`,valueHint:`<id>`,description:{"en-US":`Deployed model identifier (required)`,"zh-CN":`已部署模型标识(必填)`},required:!0},capacity:{type:`number`,valueHint:`<n>`,description:{"en-US":`New capacity in plan units (must be a multiple of base_capacity)`,"zh-CN":`以方案单元表示的新容量(必须是 base_capacity 的整数倍)`}},inputTpm:{type:`number`,valueHint:`<n>`,description:{"en-US":`PTU only — input tokens per minute`,"zh-CN":`仅 PTU:每分钟输入 Token 数`}},outputTpm:{type:`number`,valueHint:`<n>`,description:{"en-US":`PTU only — output tokens per minute`,"zh-CN":`仅 PTU:每分钟输出 Token 数`}}},exampleArgs:[`--deployed-model qwen-plus-...-b6d61c71 --capacity 8`,`--deployed-model dep-... --capacity 2`],validate:e=>e.capacity===void 0&&e.inputTpm===void 0&&e.outputTpm===void 0?`Provide at least one of --capacity / --input-tpm / --output-tpm.`:void 0,async run(e){let{settings:t,flags:n}=e,r=n.deployedModel,i={};if(n.capacity!==void 0&&(i.capacity=n.capacity),n.inputTpm!==void 0&&(i.input_tpm=n.inputTpm),n.outputTpm!==void 0&&(i.output_tpm=n.outputTpm),t.dryRun){A({action:`deploy.scale`,deployed_model:r,body:i},`json`);return}let a=await qt(e.client,r,i);t.quiet?k(r):A(a,`json`)}}),Ep=w({description:{"en-US":`Update a deployment's rate limits (rpm_limit / tpm_limit)`,"zh-CN":`更新部署的限流配置(rpm_limit / tpm_limit)`},auth:`apiKey`,usageArgs:`--deployed-model <id> [--rpm-limit <n>] [--tpm-limit <n>]`,flags:{deployedModel:{type:`string`,valueHint:`<id>`,description:{"en-US":`Deployed model identifier (required)`,"zh-CN":`已部署模型标识(必填)`},required:!0},rpmLimit:{type:`number`,valueHint:`<n>`,description:{"en-US":`Requests per minute`,"zh-CN":`每分钟请求数`}},tpmLimit:{type:`number`,valueHint:`<n>`,description:{"en-US":`Tokens per minute`,"zh-CN":`每分钟 Token 数`}}},exampleArgs:[`--deployed-model dep-... --rpm-limit 1000`,`--deployed-model dep-... --rpm-limit 1000 --tpm-limit 200000`],notes:[{"en-US":`At least one of --rpm-limit / --tpm-limit must be provided.`,"zh-CN":`--rpm-limit / --tpm-limit 至少需要提供一个。`}],validate:e=>e.rpmLimit===void 0&&e.tpmLimit===void 0?`Provide at least one of --rpm-limit / --tpm-limit.`:void 0,async run(e){let{settings:t,flags:n}=e,r=n.deployedModel,i={};if(n.rpmLimit!==void 0&&(i.rpm_limit=n.rpmLimit),n.tpmLimit!==void 0&&(i.tpm_limit=n.tpmLimit),t.dryRun){A({action:`deploy.update`,deployed_model:r,body:i},`json`);return}let a=await rn(e.client,r,i);t.quiet?k(r):A(a,`json`)}}),Dp=w({description:{"en-US":`Delete a model deployment (must be STOPPED or FAILED)`,"zh-CN":`删除模型部署(状态必须为 STOPPED 或 FAILED)`},auth:`apiKey`,usageArgs:`--deployed-model <id> [--skip-precheck]`,flags:{deployedModel:{type:`string`,valueHint:`<id>`,description:{"en-US":`Deployed model identifier (required)`,"zh-CN":`已部署模型标识(必填)`},required:!0},skipPrecheck:{type:`switch`,description:{"en-US":`Skip the local STOPPED/FAILED status precheck`,"zh-CN":`跳过本地 STOPPED/FAILED 状态预检查`}}},exampleArgs:[`--deployed-model dep-...`,`--deployed-model dep-... --dry-run`],async run(e){let{settings:n,flags:r}=e,i=r.deployedModel;if(n.dryRun){A({action:`deploy.delete`,deployed_model:i},`json`);return}if(!r.skipPrecheck)try{let n=await Be(e.client,i),r=((n.output??n.data)?.status??``).toUpperCase();if(r&&r!==`STOPPED`&&r!==`FAILED`)throw new t(`Deployment ${i} is ${r}. Only STOPPED / FAILED deployments can be deleted. Run \`bl deploy pause --deployed-model ${i}\` to pause it first, or pass --skip-precheck to attempt deletion anyway.`,c.USAGE)}catch(e){if(e instanceof t)throw e}let a=await ge(e.client,i);n.quiet?k(i):A(a,`json`)}}),Op=w({description:{"en-US":`Pause a running model deployment (stops billing for mu/ptu)`,"zh-CN":`暂停运行中的模型部署(mu/ptu 方案将停止计费)`},auth:`console`,usageArgs:`--deployed-model <id> [--skip-precheck]`,flags:{deployedModel:{type:`string`,valueHint:`<id>`,description:{"en-US":`Deployed model identifier (required)`,"zh-CN":`已部署模型标识(必填)`},required:!0},skipPrecheck:{type:`switch`,description:{"en-US":`Skip the local RUNNING/PENDING status precheck`,"zh-CN":`跳过本地 RUNNING/PENDING 状态预检查`}}},exampleArgs:[`--deployed-model dep-...`,`--deployed-model dep-... --skip-precheck`,`--deployed-model dep-... --dry-run`],notes:[{"en-US":"While paused, billing ceases for mu/ptu plans. Use `deploy resume` to bring it back online or `deploy delete` to remove.","zh-CN":"暂停期间,mu/ptu 方案将停止计费。使用 `deploy resume` 恢复服务,或使用 `deploy delete` 删除部署。"},{"en-US":`Precheck verifies status is RUNNING/PENDING before issuing the pause; pass --skip-precheck to bypass.`,"zh-CN":`发起暂停前会预检查部署状态是否为 RUNNING/PENDING;可传入 --skip-precheck 跳过检查。`}],async run(e){let{settings:n,flags:r}=e,i=r.deployedModel;if(n.dryRun){A({action:`deploy.pause`,deployed_model:i},`json`);return}if(!r.skipPrecheck)try{let n=Ne(await ut(e.client),i);if(n){let e=(n.status??``).toUpperCase();if(e&&e!==`RUNNING`&&e!==`PENDING`)throw new t(`Deployment ${i} is ${e}. Only RUNNING / PENDING deployments can be paused. Pass --skip-precheck to attempt the pause anyway.`,c.USAGE)}}catch(e){if(e instanceof t)throw e}let a=await Zt(e.client,i);n.quiet?k(i):A({deployed_model:i,action:`pause`,...a},`json`)}}),kp=w({description:{"en-US":`Resume a paused model deployment (brings service back online)`,"zh-CN":`恢复已暂停的模型部署(使服务重新上线)`},auth:`console`,usageArgs:`--deployed-model <id> [--skip-precheck]`,flags:{deployedModel:{type:`string`,valueHint:`<id>`,description:{"en-US":`Deployed model identifier (required)`,"zh-CN":`已部署模型标识(必填)`},required:!0},skipPrecheck:{type:`switch`,description:{"en-US":`Skip the local STOPPED status precheck`,"zh-CN":`跳过本地 STOPPED 状态预检查`}}},exampleArgs:[`--deployed-model dep-...`,`--deployed-model dep-... --skip-precheck`,`--deployed-model dep-... --dry-run`],notes:[{"en-US":`Precheck verifies status is STOPPED before issuing the resume; pass --skip-precheck to bypass.`,"zh-CN":`发起恢复前会预检查部署状态是否为 STOPPED;可传入 --skip-precheck 跳过检查。`},{"en-US":`For mu/ptu plans, billing resumes once the service is back online.`,"zh-CN":`对于 mu/ptu 方案,服务重新上线后将恢复计费。`}],async run(e){let{settings:n,flags:r}=e,i=r.deployedModel;if(n.dryRun){A({action:`deploy.resume`,deployed_model:i},`json`);return}if(!r.skipPrecheck)try{let n=Ne(await ut(e.client),i);if(n){let e=(n.status??``).toUpperCase();if(e&&e!==`STOPPED`)throw new t(`Deployment ${i} is ${e}. Only STOPPED deployments can be resumed. Pass --skip-precheck to attempt the resume anyway.`,c.USAGE)}}catch(e){if(e instanceof t)throw e}let a=await Xt(e.client,i);n.quiet?k(i):A({deployed_model:i,action:`resume`,...a},`json`)}});const Ap={callerUacAccountId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Caller UAC account ID`,"zh-CN":`调用方 UAC 账号 ID`}},namespaceId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Product namespace ID (Token Plan default: namespace-1)`,"zh-CN":`产品 Namespace ID(Token Plan 默认:namespace-1)`}}},jp={workspaceId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Workspace ID (env: BAILIAN_WORKSPACE_ID, config: workspace_id)`,"zh-CN":`Workspace ID(环境变量:BAILIAN_WORKSPACE_ID,配置项:workspace_id)`}}},Mp={cn:`modelstudio.cn-beijing.aliyuncs.com`,intl:`modelstudio.ap-southeast-1.aliyuncs.com`};function Np(e){for(let[t,n]of Object.entries(m))if(e===n||e.startsWith(`${n}/`))return t;return`cn`}function Pp(e){return Mp[Np(e)]??Mp.cn}function Fp(e,n,r){let i=n.workspaceId||e.workspaceId;if(!i)throw new t(`Missing workspace ID.
2800
+ `);return}throw e}finally{process.off(`SIGINT`,u)}}});async function lp(e){return await ke(x(e))}var up=w({description:{"en-US":`Query fine-tune training capability — by model (which training types it supports) or by training type (which models support it)`,"zh-CN":`查询微调训练能力:按模型查询其支持的训练类型,或按训练类型查询支持它的模型`},auth:`none`,usageArgs:`--base-model <m> | --training-type <t>`,flags:{baseModel:{type:`string`,valueHint:`<m>`,description:{"en-US":`List training types supported by this base model.`,"zh-CN":`列出该基础模型支持的训练类型。`}},trainingType:{type:`string`,valueHint:`<t>`,description:{"en-US":`List models supporting this training type: ${v.join(` | `)}.`,"zh-CN":`列出支持该训练类型的模型:${v.join(` | `)}。`}}},exampleArgs:[`--base-model qwen3-8b`,`--training-type sft-lora`,`--training-type cpt --output json`,`--training-type sft --quiet`],notes:[{"en-US":`Exactly one of --base-model / --training-type is required.`,"zh-CN":`--base-model 和 --training-type 必须且只能指定一个。`},{"en-US":"Training-type values use the `<method>` / `<method>-lora` convention: sft | sft-lora | dpo | dpo-lora | cpt. (cpt has no -lora variant server-side.)","zh-CN":"训练类型遵循 `<method>` / `<method>-lora` 命名约定:sft | sft-lora | dpo | dpo-lora | cpt。(服务端没有 cpt-lora 变体。)"},{"en-US":`Queries listFoundationModels, a public API — no console login needed.`,"zh-CN":`查询公开 API listFoundationModels,无需登录控制台。`}],validate:e=>{if(e.baseModel&&e.trainingType)return`--base-model and --training-type are mutually exclusive; pass one.`;if(!e.baseModel&&!e.trainingType)return`one of --base-model / --training-type is required.`},async run(e){let{settings:t,flags:n}=e,r=n.baseModel||void 0,i=n.trainingType||void 0;if(t.dryRun){A({action:`finetune.capability`,model:r,training_type:i},`json`);return}if(r){let e=await Ee(t,r);if(!e){A({model:r,error:`No foundation model found matching "${r}".`},`json`);return}let n=ft(e);if(t.quiet){for(let e of n)k(e);return}A({model:e.model??r,supported:n,supports:e.supports,trainingTypes:e.trainingTypes},`json`);return}if(!i||!et(i))throw new y(`--training-type "${i}" is not supported. Valid: ${v.join(`, `)}.`);let{method:a,variant:o}=en(i),s=(await lp(t)).filter(e=>xt(e,i)).map(e=>({model:e.model,name:e.name??e.model})).filter(e=>!!e.model).sort((e,t)=>e.model.localeCompare(t.model));if(t.quiet){for(let e of s)k(e.model);return}A({training_type:i,method:a,variant:o,count:s.length,models:s},`json`)}});const dp={baseModel:{type:`string`,valueHint:`<model>`,description:{"en-US":`Base model to fine-tune (e.g. qwen3-8b; not the output model name)`,"zh-CN":`待微调的基座模型(例如 qwen3-8b;不是输出模型名称)`},required:!0},datasets:{type:`string`,valueHint:`<ids>`,description:{"en-US":`Training dataset file IDs, comma-separated (required)`,"zh-CN":`训练数据集文件 ID,多个以逗号分隔(必填)`},required:!0},trainingType:{type:`string`,valueHint:`<type>`,description:{"en-US":`Training type: sft | dpo | cpt (default: sft)`,"zh-CN":`训练类型:sft | dpo | cpt(默认:sft)`}},nEpochs:{type:`number`,valueHint:`<n>`,description:{"en-US":`Number of training epochs (default: 3)`,"zh-CN":`训练轮数(默认:3)`}}},fp=[`sft`,`dpo`,`cpt`];var pp=w({description:{"en-US":`Estimate the training cost for a fine-tune job (token billing)`,"zh-CN":`估算微调任务的训练费用(按 Token 计费)`},auth:`console`,usageArgs:`--base-model <model> --datasets <ids> [--training-type <type>] [--n-epochs <n>]`,flags:dp,exampleArgs:[`--base-model qwen3-8b --datasets file-ft-xxx`,`--base-model qwen3-8b --datasets file-ft-xxx,file-ft-yyy --n-epochs 2`,`--base-model qwen3-8b --datasets file-ft-xxx --training-type cpt`],notes:[{"en-US":`Estimate only — the server computes token usage from the datasets; final cost is subject to the bill.`,"zh-CN":`该结果仅为估算值——服务端根据数据集计算 Token 用量,最终费用以账单为准。`},{"en-US":`Covers token billing for sft / dpo / cpt. Training-unit (MTU) billing is not supported by this command.`,"zh-CN":`支持估算 sft / dpo / cpt 的 Token 计费;此命令不支持训练单元(MTU)计费估算。`},{"en-US":`Hyper-parameters other than --n-epochs are fixed at representative defaults for estimation.`,"zh-CN":`除 --n-epochs 外,其他超参数会使用具有代表性的固定默认值进行估算。`}],async run(e){let{settings:n,flags:r}=e,i=r.baseModel,a=r.datasets.split(`,`).map(e=>e.trim()).filter(Boolean),o=(r.trainingType??`sft`).toLowerCase(),s=r.nEpochs??3;if(!fp.includes(o))throw new t(`Unsupported training type "${o}". Supported: ${fp.join(`, `)}.`,c.USAGE);if(a.length===0)throw new t(`--datasets must contain at least one file ID.`,c.USAGE);if(n.dryRun){A({action:`finetune.price`,model:i,datasets:a,trainingType:o,nEpochs:s},`json`);return}let l=await Me(e.client,i),u=Number(l.price);if(!Number.isFinite(u))throw new t(`No training price found for model "${i}".`,c.GENERAL,void 0,{rawResponse:JSON.stringify(l)});let d=o===`cpt`?await xe(e.client,i,a.join(`,`),s):await Se(e.client,a,{nEpochs:s,batchSize:16,maxLength:8192}),f=d.estimatedDatasetConsumedTokensMinPerEpoch??0,p=d.estimatedDatasetConsumedTokensMaxPerEpoch??0,m=d.estimatedMixedConsumedTokensMinPerEpoch??0,h=d.estimatedMixedConsumedTokensMaxPerEpoch??0,g=(f+m)*s,_=(p+h)*s,v=g/1e3*u,y=_/1e3*u;A({model:i,training_type:o,n_epochs:s,unit_price:u,price_unit:l.priceUnit??`千Token`,estimated_tokens:{min:g,max:_},estimated_fee_yuan:{min:Number(v.toFixed(4)),max:Number(y.toFixed(4))},disclaimer:`Server-side estimate; final cost is subject to the bill.`},`json`)}});const mp={modelName:{type:`string`,valueHint:`<model_name>`,description:{"en-US":`Model to deploy — fine-tuned output name or catalog model (required)`,"zh-CN":`要部署的模型:微调输出模型名称或模型目录中的模型(必填)`},required:!0},displayName:{type:`string`,valueHint:`<display_name>`,description:{"en-US":`Console display name for the deployment (required)`,"zh-CN":`部署在控制台中的显示名称(必填)`},required:!0},plan:{type:`string`,valueHint:`<plan>`,description:{"en-US":`Billing plan: lora (default, Token-billed) | ptu (Token-billed) | mu`,"zh-CN":`计费方案:lora(默认,按 Token 计费)| ptu(按 Token 计费)| mu`}},deploySpec:{type:`string`,valueHint:`<id>`,description:{"en-US":`Deploy spec (only used by plan=mu; auto-picked if omitted)`,"zh-CN":`部署规格(仅 plan=mu 使用;省略时自动选择)`}},capacity:{type:`number`,valueHint:`<n>`,description:{"en-US":`Resource units (plan=mu only; required by API; defaults to the template's unit)`,"zh-CN":`资源单元数(仅 plan=mu;API 必填;默认为模板的单元数)`}},billingMethod:{type:`string`,valueHint:`<m>`,description:{"en-US":`Billing method (plan=mu only; default "POST_PAY", the only supported value)`,"zh-CN":`计费方式(仅 plan=mu;默认且仅支持 "POST_PAY")`}},inputTpm:{type:`number`,valueHint:`<n>`,description:{"en-US":`PTU max input tokens/min (required for plan=ptu)`,"zh-CN":`PTU 每分钟最大输入 Token 数(plan=ptu 时必填)`}},outputTpm:{type:`number`,valueHint:`<n>`,description:{"en-US":`PTU max output tokens/min (required for plan=ptu)`,"zh-CN":`PTU 每分钟最大输出 Token 数(plan=ptu 时必填)`}},thinkingOutputTpm:{type:`number`,valueHint:`<n>`,description:{"en-US":`PTU max thinking-output tokens/min (optional, some models)`,"zh-CN":`PTU 每分钟最大思考输出 Token 数(部分模型可选)`}}},hp=`--model-name <model_name> --display-name <display_name> [--plan <plan>] [--deploy-spec <id>] [--capacity <n>] [--billing-method <m>] [--input-tpm <n>] [--output-tpm <n>] [--thinking-output-tpm <n>]`,gp=[{"en-US":"Plan defaults to `lora` (Token-billed) for text/image and `mu` (model-unit-billed) for audio (CosyVoice TTS). Pass --plan to override.","zh-CN":"文本和图片部署默认使用 `lora`(按 Token 计费),音频(CosyVoice TTS)默认使用 `mu`(按模型单元计费)。可通过 --plan 覆盖。"},{"en-US":`For plan=ptu (Token-billed, provisioned throughput), --input-tpm and --output-tpm are required (the platform rejects creation without an explicit ptu_capacity despite the doc listing defaults).`,"zh-CN":`plan=ptu(按 Token 计费的预置吞吐)时,--input-tpm 和 --output-tpm 必填;即使文档列出了默认值,未显式传入 ptu_capacity 时平台也会拒绝创建。`},{"en-US":"For plan=mu, `capacity`, `billing_method` and `deploy_spec` are required. billing_method defaults to POST_PAY (only supported value); deploy_spec and capacity are auto-picked from GET /deployments/models when omitted.","zh-CN":"plan=mu 时,`capacity`、`billing_method` 和 `deploy_spec` 必填。billing_method 默认且仅支持 POST_PAY;省略 deploy_spec 和 capacity 时,会从 GET /deployments/models 自动选择。"},{"en-US":"Use `bl deploy models --source base` to inspect available templates.","zh-CN":"使用 `bl deploy models --source base` 查看可用模板。"},{"en-US":`After creation, status starts at PENDING and transitions to RUNNING. Invoke the deployed model with: bl text chat --model <deployed_model>`,"zh-CN":`创建后状态从 PENDING 开始,随后转为 RUNNING。调用已部署模型:bl text chat --model <deployed_model>`},{"en-US":"NOTE: --model-name is the model being deployed (e.g. `qwen3-8b-ft-...`). The create response also returns a `deployed_model` field — the deployment instance id (e.g. `qwen3-8b-5ecb5f068d79`). Use that id for inference (`bl text chat --model <deployed_model>`) and lifecycle commands (`deploy get/scale/pause/resume/delete --deployed-model <id>`).","zh-CN":"注意:--model-name 是要部署的模型(例如 `qwen3-8b-ft-...`)。创建响应中的 `deployed_model` 是部署实例 ID(例如 `qwen3-8b-5ecb5f068d79`),用于推理(`bl text chat --model <deployed_model>`)及生命周期命令(`deploy get/scale/pause/resume/delete --deployed-model <id>`)。"}];function _p(e,t){let n=t.plan||pe(e),r=g[n];return r?r.validateFlags(t):`Unsupported plan "${n}". Supported plans: ${Object.keys(g).join(`, `)}.`}async function vp(e,t){let{identity:n,settings:r,flags:i}=t,a=i.modelName,o=i.displayName,s=i.plan||pe(e),c={model_name:a,name:o,plan:s,...(await kt(s).resolve({client:t.client,dryRun:r.dryRun,binName:n.binName,flags:i,model:a,name:o})).body};if(r.dryRun){A({action:`deploy.create`,body:c},`json`);return}let l=await ue(t.client,c),u=l.output??l.data;r.quiet?k(u?.deployed_model??``):A(l,`json`)}const yp=w({description:{"en-US":`Create a text model deployment`,"zh-CN":`创建文本模型部署`},auth:`apiKey`,usageArgs:hp,flags:mp,exampleArgs:[`--model-name my-qwen-sft --display-name my-sft-test`,`--model-name qwen3.6-flash-2026-04-16 --display-name my-flash --plan ptu --input-tpm 10000 --output-tpm 1000`,`--model-name qwen3-8b --display-name my-qwen3-mu --plan mu`,`--model-name qwen3-8b --display-name my-qwen3 --plan mu --deploy-spec MU1 --capacity 2`],notes:gp,validate:e=>_p(`text`,e),run:e=>vp(`text`,e)}),bp=w({description:{"en-US":`Create an audio (TTS) model deployment`,"zh-CN":`创建音频(TTS)模型部署`},auth:`apiKey`,usageArgs:hp,flags:mp,exampleArgs:[`--model-name my-cosyvoice-ft --display-name my-tts`,`--model-name my-cosyvoice-ft --display-name my-tts --deploy-spec dps-xxxx --capacity 1`,`--model-name my-cosyvoice-ft --display-name my-tts --dry-run`],notes:gp,validate:e=>_p(`audio`,e),run:e=>vp(`audio`,e)}),xp=w({description:{"en-US":`Create an image generation model deployment`,"zh-CN":`创建图片生成模型部署`},auth:`apiKey`,usageArgs:hp,flags:mp,exampleArgs:[`--model-name my-wan-ft --display-name my-wan`,`--model-name my-wan-ft --display-name my-wan-mu --plan mu`,`--model-name my-wan-ft --display-name my-wan --dry-run`],notes:gp,validate:e=>_p(`image`,e),run:e=>vp(`image`,e)});var Sp=w({description:{"en-US":`List model deployments`,"zh-CN":`列出模型部署`},auth:`apiKey`,usageArgs:`[--page <n>] [--page-size <n>] [--status <s>]`,flags:{page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Results per page (default: 10, max 100)`,"zh-CN":`每页结果数(默认:10,最多:100)`}},status:{type:`string`,valueHint:`<s>`,description:{"en-US":`Filter by status (PENDING / RUNNING / STOPPED / FAILED)`,"zh-CN":`按状态筛选(PENDING / RUNNING / STOPPED / FAILED)`}}},exampleArgs:[``,`--status RUNNING`,`--page-size 20 --output json`],async run(e){let{settings:t,flags:n}=e,r=n.status||void 0;if(t.dryRun){A({action:`deploy.list`,page:n.page,page_size:n.pageSize,status:r},`json`);return}let i=await ct(e.client,{pageNo:n.page,pageSize:n.pageSize,status:r}),a=i.output??i.data,o=a?.deployments??[],s=a?.total;A({items:o.map(e=>({deployed_model:e.deployed_model??``,model_name:e.model_name??``,status:e.status??``,plan:e.plan??``,capacity:e.capacity===void 0?``:String(e.capacity),created_at:e.gmt_create??``})),total:s,request_id:i.request_id},`json`)}}),Cp=w({description:{"en-US":`Get details of a single model deployment`,"zh-CN":`获取单个模型部署的详情`},auth:`apiKey`,usageArgs:`--deployed-model <id>`,flags:{deployedModel:{type:`string`,valueHint:`<id>`,description:{"en-US":`Deployed model identifier (required)`,"zh-CN":`已部署模型标识(必填)`},required:!0}},exampleArgs:[`--deployed-model qwen-plus-2025-12-01-b6d61c71`,`--deployed-model qwen-plus-2025-12-01-b6d61c71 --output json`],async run(e){let{settings:t,flags:n}=e,r=n.deployedModel;if(t.dryRun){A({action:`deploy.get`,deployed_model:r},`json`);return}let i=await Be(e.client,r),a=i.output??i.data;if(!a){A({deployed_model:r,request_id:i.request_id},`json`);return}let o={deployed_model:a.deployed_model??r,deployed_name:a.name??``,model_name:a.model_name??``,base_model:a.base_model??``,status:a.status??``,plan:a.plan??``};a.model_unit_spec&&(o.model_unit_spec=a.model_unit_spec),a.charge_type&&(o.charge_type=a.charge_type),a.capacity!==void 0&&(o.capacity=a.capacity),a.base_capacity!==void 0&&(o.base_capacity=a.base_capacity),a.ready_capacity!==void 0&&(o.ready_capacity=a.ready_capacity),a.rpm_limit!==void 0&&(o.rpm_limit=a.rpm_limit),a.tpm_limit!==void 0&&(o.tpm_limit=a.tpm_limit),a.input_tpm!==void 0&&(o.input_tpm=a.input_tpm),a.output_tpm!==void 0&&(o.output_tpm=a.output_tpm),a.gmt_create&&(o.created_at=a.gmt_create),a.gmt_modified&&(o.updated_at=a.gmt_modified),A({...o,request_id:i.request_id},`json`)}}),wp=w({description:{"en-US":`List models available for deployment`,"zh-CN":`列出可部署的模型`},auth:`apiKey`,usageArgs:`[--page <n>] [--page-size <n>] [--catalog-version <v>] [--source <custom|public>]`,flags:{page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Results per page (default: 100)`,"zh-CN":`每页结果数(默认:100)`}},catalogVersion:{type:`string`,valueHint:`<v>`,description:{"en-US":`Catalog version filter (default: v1.0; required for new catalog models)`,"zh-CN":`模型目录版本筛选(默认:v1.0;新目录模型必填)`}},source:{type:`string`,valueHint:`<s>`,description:{"en-US":`Model source filter: custom (fine-tuned) | base (catalog) | public`,"zh-CN":`模型来源筛选:custom(微调模型)| base(模型目录)| public`}}},exampleArgs:[``,`--source base`,`--source custom --page-size 50`,`--catalog-version v1.0 --output json`],async run(e){let{settings:t,flags:n}=e,r=n.catalogVersion===``?void 0:n.catalogVersion??`v1.0`,i=n.source||void 0;if(t.dryRun){A({action:`deploy.models`,page:n.page,page_size:n.pageSize,version:r,model_source:i},`json`);return}let a=await st(e.client,{pageNo:n.page,pageSize:n.pageSize,version:r,modelSource:i}),o=a.output??a.data,s=o?.models??[],c=o?.total;A({items:s.map(e=>{let t={model_name:e.model_name??``};return e.base_model&&(t.base_model=e.base_model),e.model_source&&(t.model_source=e.model_source),e.supported_plans&&e.supported_plans.length>0&&(t.supported_plans=e.supported_plans),e.plans&&e.plans.length>0&&(t.plans=e.plans.map(e=>{let t={plan:e.plan??``};return e.cu_specs&&e.cu_specs.length>0&&(t.cu_specs=e.cu_specs),e.templates&&e.templates.length>0&&(t.templates=e.templates.map(e=>{let t={};e.template_id&&(t.template_id=e.template_id),e.template_name&&(t.template_name=e.template_name),e.charge_type&&(t.charge_type=e.charge_type);let n=e.roles?.unified;return n?.model_unit_spec&&(t.model_unit_spec=n.model_unit_spec),n?.capacity_unit_per_instance!==void 0&&(t.capacity_unit_per_instance=n.capacity_unit_per_instance),(e.roles?.prefill||e.roles?.decode)&&(t.roles={prefill:e.roles?.prefill,decode:e.roles?.decode}),e.template_desc&&(t.template_desc=e.template_desc),t})),t})),t}),total:c,request_id:a.request_id},`json`)}}),Tp=w({description:{"en-US":`Scale a deployment's capacity`,"zh-CN":`调整部署容量`},auth:`apiKey`,usageArgs:`--deployed-model <id> --capacity <n> [--input-tpm <n>] [--output-tpm <n>]`,flags:{deployedModel:{type:`string`,valueHint:`<id>`,description:{"en-US":`Deployed model identifier (required)`,"zh-CN":`已部署模型标识(必填)`},required:!0},capacity:{type:`number`,valueHint:`<n>`,description:{"en-US":`New capacity in plan units (must be a multiple of base_capacity)`,"zh-CN":`以方案单元表示的新容量(必须是 base_capacity 的整数倍)`}},inputTpm:{type:`number`,valueHint:`<n>`,description:{"en-US":`PTU only — input tokens per minute`,"zh-CN":`仅 PTU:每分钟输入 Token 数`}},outputTpm:{type:`number`,valueHint:`<n>`,description:{"en-US":`PTU only — output tokens per minute`,"zh-CN":`仅 PTU:每分钟输出 Token 数`}}},exampleArgs:[`--deployed-model qwen-plus-...-b6d61c71 --capacity 8`,`--deployed-model dep-... --capacity 2`],validate:e=>e.capacity===void 0&&e.inputTpm===void 0&&e.outputTpm===void 0?`Provide at least one of --capacity / --input-tpm / --output-tpm.`:void 0,async run(e){let{settings:t,flags:n}=e,r=n.deployedModel,i={};if(n.capacity!==void 0&&(i.capacity=n.capacity),n.inputTpm!==void 0&&(i.input_tpm=n.inputTpm),n.outputTpm!==void 0&&(i.output_tpm=n.outputTpm),t.dryRun){A({action:`deploy.scale`,deployed_model:r,body:i},`json`);return}let a=await qt(e.client,r,i);t.quiet?k(r):A(a,`json`)}}),Ep=w({description:{"en-US":`Update a deployment's rate limits (rpm_limit / tpm_limit)`,"zh-CN":`更新部署的限流配置(rpm_limit / tpm_limit)`},auth:`apiKey`,usageArgs:`--deployed-model <id> [--rpm-limit <n>] [--tpm-limit <n>]`,flags:{deployedModel:{type:`string`,valueHint:`<id>`,description:{"en-US":`Deployed model identifier (required)`,"zh-CN":`已部署模型标识(必填)`},required:!0},rpmLimit:{type:`number`,valueHint:`<n>`,description:{"en-US":`Requests per minute`,"zh-CN":`每分钟请求数`}},tpmLimit:{type:`number`,valueHint:`<n>`,description:{"en-US":`Tokens per minute`,"zh-CN":`每分钟 Token 数`}}},exampleArgs:[`--deployed-model dep-... --rpm-limit 1000`,`--deployed-model dep-... --rpm-limit 1000 --tpm-limit 200000`],notes:[{"en-US":`At least one of --rpm-limit / --tpm-limit must be provided.`,"zh-CN":`--rpm-limit / --tpm-limit 至少需要提供一个。`}],validate:e=>e.rpmLimit===void 0&&e.tpmLimit===void 0?`Provide at least one of --rpm-limit / --tpm-limit.`:void 0,async run(e){let{settings:t,flags:n}=e,r=n.deployedModel,i={};if(n.rpmLimit!==void 0&&(i.rpm_limit=n.rpmLimit),n.tpmLimit!==void 0&&(i.tpm_limit=n.tpmLimit),t.dryRun){A({action:`deploy.update`,deployed_model:r,body:i},`json`);return}let a=await rn(e.client,r,i);t.quiet?k(r):A(a,`json`)}}),Dp=w({description:{"en-US":`Delete a model deployment (must be STOPPED or FAILED)`,"zh-CN":`删除模型部署(状态必须为 STOPPED 或 FAILED)`},auth:`apiKey`,usageArgs:`--deployed-model <id> [--skip-precheck] [--yes]`,flags:{deployedModel:{type:`string`,valueHint:`<id>`,description:{"en-US":`Deployed model identifier (required)`,"zh-CN":`已部署模型标识(必填)`},required:!0},skipPrecheck:{type:`switch`,description:{"en-US":`Skip the local STOPPED/FAILED status precheck`,"zh-CN":`跳过本地 STOPPED/FAILED 状态预检查`}},yes:{type:`switch`,description:{"en-US":`Skip the confirmation prompt`,"zh-CN":`跳过确认提示`}}},notes:[{"en-US":`Irreversible — the deployment is permanently destroyed.`,"zh-CN":`该操作不可撤销——部署将被永久销毁。`}],exampleArgs:[`--deployed-model dep-...`,`--deployed-model dep-... --dry-run`,`--deployed-model dep-... --yes`],async run(e){let{settings:n,flags:r}=e,i=r.deployedModel;if(n.dryRun){A({action:`deploy.delete`,deployed_model:i},`json`);return}if(!r.skipPrecheck)try{let n=await Be(e.client,i),r=((n.output??n.data)?.status??``).toUpperCase();if(r&&r!==`STOPPED`&&r!==`FAILED`)throw new t(`Deployment ${i} is ${r}. Only STOPPED / FAILED deployments can be deleted. Run \`bl deploy pause --deployed-model ${i}\` to pause it first, or pass --skip-precheck to attempt deletion anyway.`,c.USAGE)}catch(e){if(e instanceof t)throw e}await yn(`Delete deployment ${i}.\nThe deployment is permanently destroyed. This cannot be undone.`,r.yes??!1);let a=await ge(e.client,i);n.quiet?k(i):A(a,`json`)}}),Op=w({description:{"en-US":`Pause a running model deployment (stops billing for mu/ptu)`,"zh-CN":`暂停运行中的模型部署(mu/ptu 方案将停止计费)`},auth:`console`,usageArgs:`--deployed-model <id> [--skip-precheck]`,flags:{deployedModel:{type:`string`,valueHint:`<id>`,description:{"en-US":`Deployed model identifier (required)`,"zh-CN":`已部署模型标识(必填)`},required:!0},skipPrecheck:{type:`switch`,description:{"en-US":`Skip the local RUNNING/PENDING status precheck`,"zh-CN":`跳过本地 RUNNING/PENDING 状态预检查`}}},exampleArgs:[`--deployed-model dep-...`,`--deployed-model dep-... --skip-precheck`,`--deployed-model dep-... --dry-run`],notes:[{"en-US":"While paused, billing ceases for mu/ptu plans. Use `deploy resume` to bring it back online or `deploy delete` to remove.","zh-CN":"暂停期间,mu/ptu 方案将停止计费。使用 `deploy resume` 恢复服务,或使用 `deploy delete` 删除部署。"},{"en-US":`Precheck verifies status is RUNNING/PENDING before issuing the pause; pass --skip-precheck to bypass.`,"zh-CN":`发起暂停前会预检查部署状态是否为 RUNNING/PENDING;可传入 --skip-precheck 跳过检查。`}],async run(e){let{settings:n,flags:r}=e,i=r.deployedModel;if(n.dryRun){A({action:`deploy.pause`,deployed_model:i},`json`);return}if(!r.skipPrecheck)try{let n=Ne(await ut(e.client),i);if(n){let e=(n.status??``).toUpperCase();if(e&&e!==`RUNNING`&&e!==`PENDING`)throw new t(`Deployment ${i} is ${e}. Only RUNNING / PENDING deployments can be paused. Pass --skip-precheck to attempt the pause anyway.`,c.USAGE)}}catch(e){if(e instanceof t)throw e}let a=await Zt(e.client,i);n.quiet?k(i):A({deployed_model:i,action:`pause`,...a},`json`)}}),kp=w({description:{"en-US":`Resume a paused model deployment (brings service back online)`,"zh-CN":`恢复已暂停的模型部署(使服务重新上线)`},auth:`console`,usageArgs:`--deployed-model <id> [--skip-precheck]`,flags:{deployedModel:{type:`string`,valueHint:`<id>`,description:{"en-US":`Deployed model identifier (required)`,"zh-CN":`已部署模型标识(必填)`},required:!0},skipPrecheck:{type:`switch`,description:{"en-US":`Skip the local STOPPED status precheck`,"zh-CN":`跳过本地 STOPPED 状态预检查`}}},exampleArgs:[`--deployed-model dep-...`,`--deployed-model dep-... --skip-precheck`,`--deployed-model dep-... --dry-run`],notes:[{"en-US":`Precheck verifies status is STOPPED before issuing the resume; pass --skip-precheck to bypass.`,"zh-CN":`发起恢复前会预检查部署状态是否为 STOPPED;可传入 --skip-precheck 跳过检查。`},{"en-US":`For mu/ptu plans, billing resumes once the service is back online.`,"zh-CN":`对于 mu/ptu 方案,服务重新上线后将恢复计费。`}],async run(e){let{settings:n,flags:r}=e,i=r.deployedModel;if(n.dryRun){A({action:`deploy.resume`,deployed_model:i},`json`);return}if(!r.skipPrecheck)try{let n=Ne(await ut(e.client),i);if(n){let e=(n.status??``).toUpperCase();if(e&&e!==`STOPPED`)throw new t(`Deployment ${i} is ${e}. Only STOPPED deployments can be resumed. Pass --skip-precheck to attempt the resume anyway.`,c.USAGE)}}catch(e){if(e instanceof t)throw e}let a=await Xt(e.client,i);n.quiet?k(i):A({deployed_model:i,action:`resume`,...a},`json`)}});const Ap={callerUacAccountId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Caller UAC account ID`,"zh-CN":`调用方 UAC 账号 ID`}},namespaceId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Product namespace ID (Token Plan default: namespace-1)`,"zh-CN":`产品 Namespace ID(Token Plan 默认:namespace-1)`}}},jp={workspaceId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Workspace ID (env: BAILIAN_WORKSPACE_ID, config: workspace_id)`,"zh-CN":`Workspace ID(环境变量:BAILIAN_WORKSPACE_ID,配置项:workspace_id)`}}},Mp={cn:`modelstudio.cn-beijing.aliyuncs.com`,intl:`modelstudio.ap-southeast-1.aliyuncs.com`};function Np(e){for(let[t,n]of Object.entries(m))if(e===n||e.startsWith(`${n}/`))return t;return`cn`}function Pp(e){return Mp[Np(e)]??Mp.cn}function Fp(e,n,r){let i=n.workspaceId||e.workspaceId;if(!i)throw new t(`Missing workspace ID.
2801
2801
  Set via: --workspace-id flag, env: BAILIAN_WORKSPACE_ID, or config: ${r} config set workspace_id <id>`,c.USAGE);return i}function Ip(e,t){t.callerUacAccountId&&(e.CallerUacAccountId=t.callerUacAccountId),t.namespaceId&&(e.NamespaceId=t.namespaceId)}function Lp(e,t,n){let r=ee(n),i=Pp(e);return{host:i,endpoint:`https://${i}${t}${r?`?${r}`:``}`,queryString:r,queryParams:n}}async function Rp(e){let{client:t,baseUrl:n,action:r,path:i,method:a,queryParams:o}=e,{host:s}=Lp(n,i,o);return t.openApiQueryJson({host:s,path:i,action:r,version:`2026-02-10`,method:a,queryParams:o})}const zp=`/tokenplan/subscription/seat-detail`;var Bp=w({description:{"en-US":`List Token Plan subscription seat details`,"zh-CN":`列出 Token Plan 订阅席位详情`},auth:`openapi`,usageArgs:`[flags]`,flags:{pageNo:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page size (default: 10)`,"zh-CN":`每页数量(默认:10)`}},...Ap,status:{type:`array`,valueHint:`<status>`,description:{"en-US":`Seat status filter (repeatable): CREATING, NORMAL, LIMIT, RELEASE, STOP, REFUNDED`,"zh-CN":`席位状态筛选(可重复):CREATING、NORMAL、LIMIT、RELEASE、STOP、REFUNDED`}},statusListStr:{type:`string`,valueHint:`<json>`,description:{"en-US":`StatusList as JSON string, e.g. '["NORMAL"]'`,"zh-CN":`JSON 字符串格式的 StatusList,例如 '["NORMAL"]'`}},seatId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Filter by seat ID`,"zh-CN":`按席位 ID 筛选`}},seatType:{type:`string`,valueHint:`<type>`,description:{"en-US":`Seat tier: standard, pro, or max`,"zh-CN":`席位档位:standard、pro 或 max`}},queryAssigned:{type:`string`,valueHint:`<bool>`,description:{"en-US":`Filter by assignment: true=assigned, false=unassigned`,"zh-CN":`按分配状态筛选:true=已分配,false=未分配`}}},exampleArgs:[``,`--page-size 20 --status NORMAL`,`--query-assigned true --seat-type standard`],async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=Vp(n);if(t.dryRun){let{endpoint:t,queryParams:n}=Lp(e.client.baseUrl,zp,i);A({endpoint:t,query:n},r);return}let a=await Rp({client:e.client,baseUrl:e.client.baseUrl,action:`GetSubscriptionSeatDetails`,path:zp,method:`GET`,queryParams:i}),o=a.Data?.Items??[];t.quiet||r===`text`?Hp(o,a.Data?.Total,a.Data?.PageNo,a.Data?.PageSize):A(a,r)}});function Vp(e){let n={};if(e.pageNo!==void 0&&(n.PageNo=String(e.pageNo)),e.pageSize!==void 0&&(n.PageSize=String(e.pageSize)),Ip(n,e),e.statusListStr&&(n.StatusListStr=e.statusListStr),e.status&&e.status.length>0&&(n.StatusList=e.status),e.seatId&&(n.SeatId=e.seatId),e.seatType&&(n.SeatType=e.seatType),typeof e.queryAssigned==`string`&&e.queryAssigned.length>0){let r=e.queryAssigned.toLowerCase();if(r!==`true`&&r!==`false`)throw new t(`--query-assigned must be 'true' or 'false'.`,c.USAGE);n.QueryAssigned=r}return n}function Hp(e,t,n,r){if(e.length===0){k(`No seats found.`);return}let i=[M(`SeatId`,18),M(`Type`,10),M(`Status`,10),M(`Assigned`,12),M(`Account`,20)].join(` `);k(i),k(`-`.repeat(i.length));for(let t of e)k([M(t.SeatId??`-`,18),M(t.SpecType??`-`,10),M(t.Status??`-`,10),M(t.AssignedStatus??`-`,12),M(t.AccountName??t.AccountId??`-`,20)].join(` `));t!==void 0&&(k(``),k(`Total: ${t}${n===void 0?``:` | Page: ${n}`}${r===void 0?``:` | PageSize: ${r}`}`))}const Up=`/tokenplan/api-keys`;var Wp=w({description:{"en-US":`Create a Token Plan API key for a seat`,"zh-CN":`为席位创建 Token Plan API Key`},auth:`openapi`,usageArgs:`--account-id <id> --workspace-id <id> [flags]`,flags:{accountId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Target member account ID`,"zh-CN":`目标成员账号 ID`},required:!0},...jp,description:{type:`string`,valueHint:`<text>`,description:{"en-US":`API key description`,"zh-CN":`API Key 描述`}},...Ap},exampleArgs:[`--account-id acc_123 --workspace-id ws_456`,{"en-US":`--account-id acc_123 --workspace-id ws_456 --description 'Dev key'`,"zh-CN":`--account-id acc_123 --workspace-id ws_456 --description '开发密钥'`}],async run(e){let{identity:t,settings:n,flags:r}=e,i=T(n.output),a=Fp(n,r,t.binName),o=Gp(r,{accountId:r.accountId,workspaceId:a});if(n.dryRun){let{endpoint:t,queryParams:n}=Lp(e.client.baseUrl,Up,o);A({endpoint:t,query:n},i);return}let s=await Rp({client:e.client,baseUrl:e.client.baseUrl,action:`CreateTokenPlanKey`,path:Up,method:`POST`,queryParams:o});n.quiet||i===`text`?Kp(s):A(s,i)}});function Gp(e,t){let n={};return n.AccountId=t.accountId,n.WorkspaceId=t.workspaceId,e.description&&(n.Description=e.description),Ip(n,e),n}function Kp(e){let t=e.Data;if(!t){k(`API key created.`);return}k(`${M(`ApiKeyId`,14)} ${t.ApiKeyId??`-`}`),k(`${M(`MaskedApiKey`,14)} ${t.MaskedApiKey??`-`}`),t.Description&&k(`${M(`Description`,14)} ${t.Description}`),t.PlainApiKey&&(k(``),k(`PlainApiKey (shown once): ${t.PlainApiKey}`))}const qp=`/tokenplan/subscription/seat-assignments`;var Jp=w({description:{"en-US":`Batch assign Token Plan seats to members`,"zh-CN":`批量向成员分配 Token Plan 席位`},auth:`openapi`,usageArgs:`--workspace-id <id> --seat-type <type> --account-id <id> [flags]`,flags:{...jp,seatType:{type:`string`,valueHint:`<type>`,description:{"en-US":`Seat tier: standard, pro, or max`,"zh-CN":`席位档位:standard、pro 或 max`},required:!0},accountId:{type:`array`,valueHint:`<id>`,description:{"en-US":`Target member account ID (repeatable)`,"zh-CN":`目标成员账号 ID(可重复)`}},...Ap,locale:{type:`string`,valueHint:`<locale>`,description:{"en-US":`Language: zh-CN or en-US`,"zh-CN":`语言:zh-CN 或 en-US`}}},exampleArgs:[`--workspace-id ws_456 --seat-type standard --account-id acc_123`,`--workspace-id ws_456 --seat-type pro --account-id acc_1 --account-id acc_2`],validate:e=>e.accountId&&e.accountId.length>0?void 0:`Missing required flag: --account-id`,async run(e){let{identity:t,settings:n,flags:r}=e,i=T(n.output),a=Yp(r,Fp(n,r,t.binName));if(n.dryRun){let{endpoint:t,queryParams:n}=Lp(e.client.baseUrl,qp,a);A({endpoint:t,query:n},i);return}let o=await Rp({client:e.client,baseUrl:e.client.baseUrl,action:`BatchAssignSeats`,path:qp,method:`POST`,queryParams:a});n.quiet||i===`text`?k(`Seats assigned successfully.`):A(o,i)}});function Yp(e,t){let n={};return n.WorkspaceId=t,e.seatType&&(n.SeatType=e.seatType),Ip(n,e),e.locale&&(n.Locale=e.locale),e.accountId&&e.accountId.length>0&&(n.AccountIds=e.accountId),n}const Xp=`/tokenplan/organization/member-additions`;var Zp=w({description:{"en-US":`Add a member to a Token Plan organization`,"zh-CN":`向 Token Plan 组织添加成员`},auth:`openapi`,usageArgs:`--account-name <name> --org-id <id> [flags]`,flags:{accountName:{type:`string`,valueHint:`<name>`,description:{"en-US":`Member display name`,"zh-CN":`成员显示名称`},required:!0},orgId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Organization ID`,"zh-CN":`组织 ID`},required:!0},orgRoleCode:{type:`string`,valueHint:`<code>`,description:{"en-US":`Organization role: ORG_ADMIN or ORG_MEMBER (default: ORG_MEMBER)`,"zh-CN":`组织角色:ORG_ADMIN 或 ORG_MEMBER(默认:ORG_MEMBER)`}},specType:{type:`string`,valueHint:`<type>`,description:{"en-US":`Seat tier to assign on creation: standard, pro, or max`,"zh-CN":`创建时分配的席位档位:standard、pro 或 max`}},...Ap},exampleArgs:[`--account-name dev_user --org-id org_123`,`--account-name admin_user --org-id org_123 --org-role-code ORG_ADMIN`,`--account-name member1 --org-id org_123 --spec-type standard`],async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=Qp(n);if(t.dryRun){let{endpoint:t,queryParams:n}=Lp(e.client.baseUrl,Xp,i);A({endpoint:t,query:n},r);return}let a=await Rp({client:e.client,baseUrl:e.client.baseUrl,action:`AddOrganizationMember`,path:Xp,method:`POST`,queryParams:i});t.quiet||r===`text`?$p(a):A(a,r)}});function Qp(e){let t={};return e.accountName&&(t.AccountName=e.accountName),e.orgId&&(t.OrgId=e.orgId),t.OrgRoleCode=e.orgRoleCode||`ORG_MEMBER`,e.specType&&(t.SpecType=e.specType),Ip(t,e),t}function $p(e){let t=e.Data;if(!t){k(`Member added.`);return}k(`${M(`AccountId`,14)} ${t.AccountId??`-`}`),k(`${M(`SeatAssigned`,14)} ${String(t.SeatAssigned??`-`)}`)}const em=[`bailian`,`claude`,`qoder`,`ark`,`all`],tm={bailian:` bailian:
2802
2802
  # bl auth login --api-key <key> sets DASHSCOPE_API_KEY; --base-url <url> sets BAILIAN_BASE_URL
2803
2803
  api_key: \${DASHSCOPE_API_KEY}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bailian-cli-commands",
3
- "version": "1.18.1",
3
+ "version": "1.18.2",
4
4
  "description": "Command library for bailian-cli products (knowledge, memory, media, …). See https://www.npmjs.com/package/bailian-cli for usage.",
5
5
  "homepage": "https://bailian.console.aliyun.com/cli",
6
6
  "bugs": {
@@ -32,8 +32,8 @@
32
32
  "chalk": "^5.6.2",
33
33
  "smol-toml": "^1.4.2",
34
34
  "yaml": "^2.8.3",
35
- "bailian-cli-core": "1.18.1",
36
- "bailian-cli-runtime": "1.18.1"
35
+ "bailian-cli-runtime": "1.18.2",
36
+ "bailian-cli-core": "1.18.2"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/node": "^24",