bailian-cli-commands 1.6.1 → 1.7.0
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 +1898 -78
- package/dist/index.mjs +81 -126
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -1,136 +1,91 @@
|
|
|
1
|
-
import{
|
|
2
|
-
`),new
|
|
3
|
-
`)
|
|
4
|
-
`);return}let{accessToken:r,apiKey:
|
|
1
|
+
import{ASYNC_FLAG as e,BailianError as t,CONCURRENT_FLAG as n,DEFAULT_TRAINING_TYPE as r,DOCS_HOSTS as i,ExitCode as a,MAX_DATASET_BYTES as o,REGIONS as s,SEMANTIC_TOP_K as c,TRAINING_TYPES_CLI as l,UsageError as u,analyzeIntent as d,appCompletionPath as f,bailianMcpPath as p,buildAcsCanonicalQuery as m,buildDocLink as h,callConsoleGateway as g,cancelFineTune as _,chatPath as v,createDeployment as y,createFineTune as b,defineCommand as x,deleteDataset as S,deleteDeployment as C,deleteFineTune as ee,detectOutputFormat as w,effectiveConsoleGatewayConfig as te,exportCheckpoint as ne,fetchModelCapability as re,fetchModelList as T,formatIssue as E,generateFilename as ie,getConfigDir as ae,getConfigPath as oe,getDataset as se,getDeployment as ce,getFineTune as le,getFineTuneLogs as ue,getModels as de,imagePath as fe,imageSyncPath as pe,isLocalFile as me,isTrainingTypeCli as he,knowledgeChatEndpoint as ge,knowledgeRetrievePath as _e,knowledgeSearchEndpoint as ve,listCheckpoints as ye,listDatasets as be,listDeployableModels as xe,listDeployments as Se,listFineTunes as Ce,listSupportedTrainingTypes as we,maskToken as D,mcpWebSearchPath as Te,memoryAddPath as Ee,memoryListPath as De,memoryNodePath as Oe,memorySearchPath as ke,modelSupportsTrainingType as Ae,parseDatasetSchemaFlag as je,parseSSE as O,preflightBatchSizeGate as Me,profileSchemaPath as Ne,rankModels as Pe,recallSemantic as Fe,requestJson as Ie,resolveBooleanFlag as k,resolveOutputDir as A,resolveWatermark as j,scaleDeployment as Le,speechRecognizePath as Re,speechSynthesizePath as ze,stripUndefined as Be,taskPath as M,toServerTrainingType as Ve,trackingHeaders as He,trainingTypeMethodVariant as Ue,updateDeployment as We,uploadDataset as Ge,userProfilePath as Ke,validateDataset as qe,videoGeneratePath as Je}from"bailian-cli-core";import{API_KEY_PAGE as Ye,BOOL_FLAG_PROMPT_EXTEND_API_DEFAULT as Xe,BOOL_FLAG_PROMPT_EXTEND_CLI_TRUE as Ze,BOOL_FLAG_PROMPT_EXTEND_IMAGE_GENERATE as Qe,BOOL_FLAG_WATERMARK as N,VOICE_TTS_PAGE as $e,ansi as P,collectPipelineHints as et,collectPipelineIssues as tt,createSpinner as nt,displayWidth as F,downloadFile as I,downloadParallel as rt,emitBare as L,emitResult as R,executePipeline as it,fetchLatestVersion as at,formatBytes as ot,formatTable as z,getConcurrency as B,initPipelineSteps as st,padEnd as V,poll as H,resolveImageSize as ct,runConcurrent as U,streamPipelineEvents as lt,supportsColor as ut}from"bailian-cli-runtime";import{execFile as dt}from"node:child_process";import{randomBytes as ft}from"node:crypto";import pt from"node:http";import{createWriteStream as mt,existsSync as ht,readFileSync as gt,statSync as _t,writeFileSync as vt}from"fs";import{basename as yt,extname as bt,join as W}from"path";import{execSync as xt}from"child_process";import{readFile as St}from"node:fs/promises";import{dirname as Ct,extname as wt,resolve as Tt}from"node:path";import Et from"boxen";import Dt,{Chalk as Ot}from"chalk";const kt={domestic:`https://bailian.console.aliyun.com`,international:`https://modelstudio.console.alibabacloud.com`};function At(e){return e&&kt[e]||kt.domestic}function jt(e){return new Promise((t,n)=>{let r=0,i=[];e.on(`data`,e=>{if(r+=e.length,r>65536){n(Error(`payload too large`));return}i.push(e)}),e.on(`end`,()=>t(Buffer.concat(i).toString(`utf8`))),e.on(`error`,n)})}function Mt(e){let t=e.headers[`content-type`];return Array.isArray(t)?t[0]??``:typeof t==`string`?t:``}function Nt(e){let t=e.split(`;`);for(let e of t){let t=e.trim();if(!t.toLowerCase().startsWith(`boundary=`))continue;let n=t.slice(9).trim();return(n.startsWith(`"`)&&n.endsWith(`"`)||n.startsWith(`'`)&&n.endsWith(`'`))&&(n=n.slice(1,-1)),n.length>0?n:null}return null}function Pt(e,t){let n=`--${t}`,r=e.split(n);for(let e=1;e<r.length;e++){let t=r[e];if(!/name\s*=\s*["'](?:access_token|accessToken)["']/i.test(t))continue;let n=t.match(/\r\n\r\n|\n\n/);if(!n||n.index===void 0)continue;let i=t.slice(n.index+n[0].length);if(i=i.replace(/(?:\r\n)+$/g,``).replace(/\n+$/g,``).trim(),i)return i}return null}function Ft(e){for(let t of[`access_token`,`accessToken`]){let n=e[t];if(typeof n==`string`&&n.trim())return n.trim()}return null}function It(e){for(let t of[`api_key`,`apiKey`]){let n=e[t];if(typeof n==`string`&&n.trim())return n.trim()}return null}function Lt(e){let t=e.trim();if(t.charCodeAt(0)===65279&&(t=t.slice(1)),!t)return null;let n;try{n=JSON.parse(t)}catch{return null}if(!n||typeof n!=`object`||Array.isArray(n))return null;let r=n,i=Ft(r);if(i)return i;let a=r.data;if(a&&typeof a==`object`&&!Array.isArray(a)){let e=Ft(a);if(e)return e}return null}function Rt(e,t){let n=t.toLowerCase();if(!e.trim())return null;if(n.includes(`multipart/form-data`)){let n=Nt(t);if(n){let t=Pt(e,n);if(t)return t}}if(n.includes(`application/json`)||n.includes(`text/json`)){let t=Lt(e);if(t)return t}if(n.includes(`application/x-www-form-urlencoded`))try{let t=new URLSearchParams(e.trim()),n=t.get(`access_token`)??t.get(`accessToken`);if(n?.trim())return n.trim()}catch{}let r=Lt(e);if(r)return r;try{let t=new URLSearchParams(e.trim()),n=t.get(`access_token`)??t.get(`accessToken`);if(n?.trim())return n.trim()}catch{}let i=Nt(t);if(i){let t=Pt(e,i);if(t)return t}return null}function zt(e){let t=e.trim();if(t.charCodeAt(0)===65279&&(t=t.slice(1)),!t)return null;let n;try{n=JSON.parse(t)}catch{return null}if(!n||typeof n!=`object`||Array.isArray(n))return null;let r=n,i=It(r);if(i)return i;let a=r.data;if(a&&typeof a==`object`&&!Array.isArray(a)){let e=It(a);if(e)return e}return null}function Bt(e,t){let n=t.toLowerCase();if(!e.trim())return null;if(n.includes(`application/json`)||n.includes(`text/json`)){let t=zt(e);if(t)return t}if(n.includes(`application/x-www-form-urlencoded`))try{let t=new URLSearchParams(e.trim()),n=t.get(`api_key`)??t.get(`apiKey`);if(n?.trim())return n.trim()}catch{}let r=zt(e);if(r)return r;try{let t=new URLSearchParams(e.trim()),n=t.get(`api_key`)??t.get(`apiKey`);if(n?.trim())return n.trim()}catch{}return null}function G(e,...t){for(let n of t){let t=e[n];if(typeof t==`string`&&t.trim())return t.trim()}return null}function Vt(e,t){let n={baseUrl:null,consoleSite:null,consoleRegion:null,consoleSwitchAgent:null,workspaceId:null};if(!e.trim())return n;let r=null,i=t.toLowerCase();if(i.includes(`application/json`)||i.includes(`text/json`))try{let t=JSON.parse(e.trim());t&&typeof t==`object`&&!Array.isArray(t)&&(r=t)}catch{}if(!r&&i.includes(`application/x-www-form-urlencoded`))try{let t=new URLSearchParams(e.trim());r=Object.fromEntries(t)}catch{}if(!r)try{let t=JSON.parse(e.trim());t&&typeof t==`object`&&!Array.isArray(t)&&(r=t)}catch{}return r?{baseUrl:G(r,`base_url`,`baseUrl`),consoleSite:G(r,`console_site`,`consoleSite`),consoleRegion:G(r,`console_region`,`consoleRegion`),consoleSwitchAgent:G(r,`console_switch_agent`,`consoleSwitchAgent`),workspaceId:G(r,`workspace_id`,`workspaceId`)}:n}async function Ht(e){let t=new URL(e.url??`/`,`http://127.0.0.1`),n=t.searchParams.get(`access_token`)??t.searchParams.get(`accessToken`),r=t.searchParams.get(`api_key`)??t.searchParams.get(`apiKey`),i=t.searchParams.get(`base_url`)??t.searchParams.get(`baseUrl`),a=t.searchParams.get(`console_site`)??t.searchParams.get(`consoleSite`),o=t.searchParams.get(`console_region`)??t.searchParams.get(`consoleRegion`),s=t.searchParams.get(`console_switch_agent`)??t.searchParams.get(`consoleSwitchAgent`),c=t.searchParams.get(`workspace_id`)??t.searchParams.get(`workspaceId`),l={baseUrl:i?.trim()||null,consoleSite:a?.trim()||null,consoleRegion:o?.trim()||null,consoleSwitchAgent:s?.trim()||null,workspaceId:c?.trim()||null},u=e.method??`GET`;if(u!==`POST`&&u!==`PUT`&&u!==`PATCH`)return{accessToken:n?.trim()||null,apiKey:r?.trim()||null,...l};let d=Mt(e),f;try{f=await jt(e)}catch{return{accessToken:n?.trim()||null,apiKey:r?.trim()||null,...l}}let p=n?.trim()||Rt(f,d),m=r?.trim()||Bt(f,d),h=Vt(f,d);return{accessToken:p,apiKey:m,baseUrl:l.baseUrl||h.baseUrl,consoleSite:l.consoleSite||h.consoleSite,consoleRegion:l.consoleRegion||h.consoleRegion,consoleSwitchAgent:l.consoleSwitchAgent||h.consoleSwitchAgent,workspaceId:l.workspaceId||h.workspaceId}}function Ut(e){return new Promise((t,n)=>{let r=e=>n(e);e.once(`error`,r),e.listen({port:0,host:`127.0.0.1`,exclusive:!0},()=>{e.off(`error`,r);let i=e.address();if(!i||typeof i==`string`){n(Error(`Expected TCP socket address`));return}t(i.port)})})}function Wt(e){let t=process.platform,n=t===`darwin`?`open`:t===`win32`?`cmd`:`xdg-open`,r=t===`win32`?[`/c`,`start`,``,e]:[e];return new Promise((e,t)=>{dt(n,r,{windowsHide:!0},n=>{n?t(n):e()})})}function Gt(e){if(e instanceof t){if(e.exitCode===a.NETWORK||e.exitCode===a.TIMEOUT)return!0;let t=e.api?.httpStatus;return t===401||t!==void 0&&t>=500}return e instanceof Error?e.name===`AbortError`||e.name===`TimeoutError`||e.message.includes(`timed out`)||e.message===`fetch failed`:!1}async function Kt(e,n,r){process.stderr.write(`Testing key... `);let i={identity:e.identity,settings:e.settings},o={url:r+v(),method:`POST`,headers:{Authorization:`Bearer ${n}`},timeout:Math.min(e.settings.timeout,30),body:{model:`qwen3.7-max`,messages:[{role:`user`,content:`hi`}],max_tokens:1}};for(let e=1;e<=3;e++)try{await Ie(i,o);break}catch(n){if(e>=3||!Gt(n))throw process.stderr.write(`Failed
|
|
2
|
+
`),new t(`API key validation failed`,a.AUTH,`Invalid API key.`,{cause:n});let r=500*2**(e-1);await new Promise(e=>setTimeout(e,r))}process.stderr.write(`Valid
|
|
3
|
+
`),await e.authStore.login({api_key:n})}async function qt(e,n,r){let i=ft(16).toString(`hex`),o,s=pt.createServer(async(e,t)=>{try{if(e.method===`OPTIONS`){t.writeHead(204,{"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, PATCH, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type`}),t.end();return}if(new URL(e.url??`/`,`http://127.0.0.1`).searchParams.get(`state`)!==i){t.writeHead(400,{"Content-Type":`text/plain; charset=utf-8`}),t.end(`bad state
|
|
4
|
+
`);return}let{accessToken:r,apiKey:a,baseUrl:c,consoleSite:l,consoleRegion:u,consoleSwitchAgent:d,workspaceId:f}=await Ht(e),p=r||c||l||u||d||f;if(p||a)try{p&&(await n.authStore.login({access_token:r||void 0,base_url:c||void 0,console_site:l||void 0,console_region:u||void 0,console_switch_agent:d?Number(d):void 0,workspace_id:f||void 0}),process.stderr.write(`Config saved to ${oe()}\n`)),a&&await Kt(n,a,c||n.authStore.resolveBaseUrl())}catch(e){o=e,t.writeHead(500,{"Content-Type":`text/plain; charset=utf-8`}),t.end(`Failed to save credentials
|
|
5
5
|
`),s.close();return}t.writeHead(200,{"Content-Type":`text/plain; charset=utf-8`,"Access-Control-Allow-Origin":`*`}),t.end(`OK
|
|
6
|
-
`),(p||
|
|
6
|
+
`),(p||a)&&s.close()}catch{t.statusCode=500,t.end()}}),c;try{c=await Ut(s)}catch(e){throw new t(`Could not bind to 127.0.0.1 (no free port or permission denied): ${e instanceof Error?e.message:String(e)}`,a.USAGE)}let l=`${e}/console-login?notice=127.0.0.1:${c}?state=${encodeURIComponent(i)}`;r?.needApiKey&&(l+=`&needapikey=true`);try{await Wt(l),process.stderr.write(`Opened the login page in your default browser. This process keeps the local port open for the console; press Ctrl+C when finished (or wait for idle timeout).
|
|
7
7
|
`)}catch(e){let t=e instanceof Error?e.message:String(e);process.stderr.write(`Could not open the default browser (${t}). Open this URL manually:\n\n`),process.stdout.write(`${l}\n`),process.stderr.write(`
|
|
8
8
|
This process keeps the local port open for the console; press Ctrl+C when finished (or wait for idle timeout).
|
|
9
|
-
`)}if(await new Promise((e,t)=>{let n=!1,r=()=>{n||(n=!0,clearTimeout(i),e())},i=setTimeout(()=>{s.close()},9e5);s.once(`close`,r),s.once(`error`,e=>{clearTimeout(i),n||(n=!0,t(e))})}),o)throw o}var
|
|
10
|
-
`),
|
|
11
|
-
`)}let r=t.apiKey||e.apiKey;r||(ut(process.stderr),process.exit(0));let i=t.baseUrl||void 0,a=i?{...e,baseUrl:i}:e;if(e.dryRun)W(`Would validate and save API key.`);else{if(i){let e=A();e.base_url=i,await Je(e)}await nn(a,r,a.baseUrl),dt()}}});function on(e){if(e.apiKey)return{configured:!0,source:`flag`,masked:O(e.apiKey)};if(e.fileApiKey)return{configured:!0,source:`config.json`,masked:O(e.fileApiKey)};let t=process.env.DASHSCOPE_API_KEY?.trim();return t?{configured:!0,source:`DASHSCOPE_API_KEY`,masked:O(t)}:{configured:!1}}function sn(e){return e.accessTokenEnv?{configured:!0,source:`DASHSCOPE_ACCESS_TOKEN`,masked:O(e.accessTokenEnv)}:e.fileAccessToken?{configured:!0,source:`config.json`,masked:O(e.fileAccessToken)}:{configured:!1}}async function cn(e){try{return await F(e)}catch{return}}async function ln(e){try{return await P(e)}catch{return}}async function un(e){let t={api_key:on(e),access_token:sn(e)},n=await cn(e);n&&(t.dashscope_commands={method:n.method,source:n.source,masked:O(n.token)});let r=await ln(e);return r&&(t.console_gateway_commands={method:r.method,source:r.source,masked:O(r.token)}),t}function dn(e){return e.api_key.configured||e.access_token.configured||!!e.dashscope_commands||!!e.console_gateway_commands}function fn(e,t){W(`Authentication Status:`),W(` Stored credentials (can coexist):`),e.api_key.configured?W(` API key: ${e.api_key.source} ${e.api_key.masked}`):W(` API key: not configured`),e.access_token.configured?W(` Console token: ${e.access_token.source} ${e.access_token.masked}`):W(` Console token: not configured`),W(` Effective credential per command family:`),e.dashscope_commands?W(` DashScope API: ${e.dashscope_commands.method} (${e.dashscope_commands.source}) ${e.dashscope_commands.masked}`):W(` DashScope API: unavailable`),e.console_gateway_commands?W(` Console gateway: ${e.console_gateway_commands.method} (${e.console_gateway_commands.source}) ${e.console_gateway_commands.masked}`):W(` Console gateway: unavailable (run ${t.binName} auth login --console)`)}var pn=y({description:`Show current authentication state`,options:[{flag:`--console-region <region>`,description:`Console region`},{flag:`--console-site <site>`,description:`Console site: domestic, international`},{flag:`--console-switch-agent <uid>`,description:`Switch agent UID`,type:`number`}],exampleArgs:[``,`--output json`],async run(e,t){let n=C(e.output),r=await un(e);if(!dn(r)){G({authenticated:!1,message:`Not authenticated.`,hint:[`DashScope API: ${e.binName} auth login --api-key <key> or DASHSCOPE_API_KEY`,`Console gateway: ${e.binName} auth login --console or DASHSCOPE_ACCESS_TOKEN`,`Get API Key: ${Ye}`].join(`
|
|
12
|
-
`),...r},n);return}if(n!==`text`){G({authenticated:!0,...r},n);return}fn(r,e)}});async function mn(){let e=A();return e.access_token?(delete e.access_token,await Je(e),!0):!1}var hn=y({description:`Clear stored credentials`,skipDefaultApiKeySetup:!0,usageArgs:`[--console] [--yes] [--dry-run]`,options:[{flag:`--console`,description:`Only clear the console access_token, keep api_key intact`,type:`boolean`},{flag:`--yes`,description:`Skip confirmation prompt`}],exampleArgs:[``,`--console`,`--dry-run`,`--yes`],async run(e,t){let n=A();if(t.console){let t=!!n.access_token;if(e.dryRun){W(t?`Would clear access_token from ~/.bailian/config.json`:`No console access_token to clear.`),W(`No changes made.`);return}t?(await mn(),process.stderr.write(`Cleared access_token from ${ie()}\n`),n.api_key&&process.stderr.write(`api_key is still configured and will be used for authentication.
|
|
9
|
+
`)}if(await new Promise((e,t)=>{let n=!1,r=()=>{n||(n=!0,clearTimeout(i),e())},i=setTimeout(()=>{s.close()},9e5);s.once(`close`,r),s.once(`error`,e=>{clearTimeout(i),n||(n=!0,t(e))})}),o)throw o}function K(e){return typeof e==`string`&&e.trim().length>0}var Jt=x({description:`Authenticate with API key, console browser login, or OpenAPI AK/SK (credentials can coexist)`,auth:`none`,usageArgs:`--api-key <key> | --console | --open-api --access-key-id <id> --access-key-secret <secret>`,flags:{apiKey:{type:`string`,valueHint:`<key>`,description:`DashScope API key to store`},baseUrl:{type:`string`,valueHint:`<url>`,description:`DashScope API base URL (used with --api-key for validation)`},console:{type:`switch`,description:`Sign in via browser; use --console-site to choose domestic (default) or international`},consoleSite:{type:`string`,valueHint:`<site>`,description:`Console site: domestic, international`},openApi:{type:`switch`,description:`Store Alibaba Cloud OpenAPI AK/SK credentials`},accessKeyId:{type:`string`,valueHint:`<id>`,description:`Alibaba Cloud Access Key ID to store`},accessKeySecret:{type:`string`,valueHint:`<secret>`,description:`Alibaba Cloud Access Key Secret to store`}},exampleArgs:[`--api-key sk-xxxxx`,`--console`,`--open-api --access-key-id LTAIxxxxx --access-key-secret xxxxx`],validate:e=>{let t=K(e.apiKey),n=e.console===!0,r=e.openApi===!0;if(!t&&K(e.baseUrl))return`Use --base-url only with --api-key`;if(!n&&K(e.consoleSite))return`Use --console-site only with --console`;if(!r&&(K(e.accessKeyId)||K(e.accessKeySecret)))return`Use --open-api with --access-key-id and --access-key-secret`;if([t,n,r].filter(Boolean).length!==1)return`Choose exactly one login mode: --api-key, --console, or --open-api`;if(r&&(!K(e.accessKeyId)||!K(e.accessKeySecret)))return`Provide --access-key-id and --access-key-secret with --open-api`},async run(e){let{identity:t,settings:n,flags:r}=e,i=e.authStore(),a={identity:t,settings:n,authStore:i},o=r.apiKey,s=r.baseUrl||void 0;if(r.console){if(n.dryRun){L(`Would bind a free port on 127.0.0.1 and open the console login URL in your browser.`);return}let e=!!(o||i.stored().apiKey);await qt(At(r.consoleSite||n.consoleSite||`domestic`),a,{needApiKey:!e});return}if(r.openApi){if(n.dryRun){L(`Would save OpenAPI AK/SK credentials.`);return}await i.login({access_key_id:r.accessKeyId,access_key_secret:r.accessKeySecret}),process.stderr.write(`OpenAPI credentials saved to ${oe()}\n`);return}if(o){if(n.dryRun){L(`Would validate and save API key.`);return}s&&await i.login({base_url:s}),await Kt(a,o,s||i.resolveBaseUrl())}}}),Yt=x({description:`Show current authentication state`,auth:`none`,exampleArgs:[``,`--output json`],async run(e){let{identity:t,settings:n}=e,r=w(n.output),i=e.authStore().describe(),a=i.apiKey?{source:i.apiKey.source,masked:D(i.apiKey.token),base_url:i.apiKey.baseUrl}:void 0,o=i.console?{source:i.console.source,masked:D(i.console.token),region:i.console.region,site:i.console.site}:void 0,s=i.openapi?{source:i.openapi.source,access_key_id:D(i.openapi.accessKeyId),access_key_secret:D(i.openapi.accessKeySecret)}:void 0;if(!(a||o||s)){R({authenticated:!1,message:`Not authenticated.`,hint:[`API key (model): ${t.binName} auth login --api-key <key> or DASHSCOPE_API_KEY`,`Console gateway: ${t.binName} auth login --console`,`OpenAPI (AK/SK): ${t.binName} auth login --open-api --access-key-id <id> --access-key-secret <secret>`,`Get API Key: ${Ye}`].join(`
|
|
10
|
+
`)},r);return}if(r!==`text`){R({authenticated:!0,api_key:a,console:o,openapi:s},r);return}L(`Authentication Status:`),L(a?` API key (model): ${a.source} ${a.masked}`:` API key (model): not configured`),L(o?` Console gateway: ${o.source} ${o.masked} (${o.region}, ${o.site})`:` Console gateway: not configured (run ${t.binName} auth login --console)`),L(s?` OpenAPI (AK/SK): ${s.source} ${s.access_key_id}`:` OpenAPI (AK/SK): not configured (run ${t.binName} auth login --open-api)`)}}),Xt=x({description:`Clear stored credentials`,auth:`none`,usageArgs:`[--console | --open-api] [--dry-run]`,flags:{console:{type:`switch`,description:`Only clear the console access_token, keep api_key intact`},openApi:{type:`switch`,description:`Only clear OpenAPI AK/SK credentials, keep other credentials intact`}},exampleArgs:[``,`--console`,`--open-api`,`--dry-run`],validate:e=>e.console&&e.openApi?`Use only one scope: --console or --open-api`:void 0,async run(e){let{settings:t,flags:n}=e,r=e.authStore(),i=r.stored();if(n.console){if(t.dryRun){i.console?L(`Would clear access_token from ~/.bailian/config.json`):L(`No console access_token to clear.`),L(`No changes made.`);return}await r.logout(`console`)?(process.stderr.write(`Cleared access_token from ${oe()}\n`),i.apiKey&&process.stderr.write(`api_key is still configured and will be used for authentication.
|
|
13
11
|
`)):process.stderr.write(`No console access_token to clear.
|
|
14
|
-
`);return}
|
|
15
|
-
`)):process.stderr.write(`No credentials to clear.
|
|
16
|
-
`)}
|
|
17
|
-
`)
|
|
18
|
-
`)}
|
|
12
|
+
`);return}if(n.openApi){if(t.dryRun){i.openapi?L(`Would clear access_key_id / access_key_secret from ~/.bailian/config.json`):L(`No OpenAPI AK/SK credentials to clear.`),L(`No changes made.`);return}await r.logout(`openapi`)?(process.stderr.write(`Cleared access_key_id / access_key_secret from ${oe()}\n`),(i.apiKey||i.console)&&process.stderr.write(`Other credentials are still configured and will be used for authentication.
|
|
13
|
+
`)):process.stderr.write(`No OpenAPI AK/SK credentials to clear.
|
|
14
|
+
`);return}let a=i.apiKey||i.console||i.openapi;if(t.dryRun){L(a?`Would clear api_key / access_token / access_key_id / access_key_secret from ~/.bailian/config.json`:`No credentials to clear.`),L(`No changes made.`);return}await r.logout(`all`)?process.stderr.write(`Cleared api_key / access_token / access_key_id / access_key_secret from ~/.bailian/config.json
|
|
15
|
+
`):process.stderr.write(`No credentials to clear.
|
|
16
|
+
`)}});const Zt={model:{type:`string`,valueHint:`<model>`,description:`Model ID (default: qwen3.7-max)`},message:{type:`array`,valueHint:`<text>`,description:`Message text (repeatable, prefix role: to set role); or use --messages-file`},messagesFile:{type:`string`,valueHint:`<path>`,description:`JSON file with messages array (use - for stdin)`},system:{type:`string`,valueHint:`<text>`,description:`System prompt`},maxTokens:{type:`number`,valueHint:`<n>`,description:`Maximum tokens to generate (default: 4096)`},temperature:{type:`number`,valueHint:`<n>`,description:`Sampling temperature (0.0, 2.0]`},topP:{type:`number`,valueHint:`<n>`,description:`Nucleus sampling threshold`},stream:{type:`switch`,description:`Stream response tokens (default: on in TTY)`},tool:{type:`array`,valueHint:`<json-or-path>`,description:`Tool definition as JSON or file path (repeatable)`},enableThinking:{type:`switch`,description:`Enable thinking/reasoning mode (for qwen3/qwq models)`},thinkingBudget:{type:`number`,valueHint:`<n>`,description:`Max tokens for thinking (default: 4096)`}};function Qt(e){let t=[],n;if(e.system&&(n=e.system),e.messagesFile){let r=e.messagesFile,i=gt(r===`-`?`/dev/stdin`:r,`utf-8`),a=JSON.parse(i);for(let e of a)e.role===`system`?n=typeof e.content==`string`?e.content:``:t.push(e)}if(e.message){let r=new Set([`system`,`user`,`assistant`]),i=e.message;for(let e of i){let i=e.indexOf(`:`),a=i===-1?``:e.slice(0,i);if(r.has(a)){let r=e.slice(i+1);a===`system`?n=r:t.push({role:a,content:r})}else t.push({role:`user`,content:e})}}return{system:n,messages:t}}var $t=x({description:`Send a chat completion (OpenAI compatible, DashScope)`,auth:`apiKey`,usageArgs:`--message <text> [flags]`,flags:Zt,exampleArgs:[`--message "What is Qwen?"`,`--model qwen-max --system "You are a coding assistant." --message "Write fizzbuzz in Python"`,`--message "Hello" --message "assistant:Hi!" --message "How are you?"`,`--messages-file - --stream`,`--message "Hello" --output json`,`--model qwq-plus --message "Solve 1+1" --enable-thinking`],validate:e=>!e.message&&!e.messagesFile?`Provide --message or --messages-file.`:void 0,async run(e){let{settings:t,flags:n}=e,{system:r,messages:i}=Qt(n),a=n.model||t.defaultTextModel||`qwen3.7-max`,o=n.stream||process.stdout.isTTY,s=w(t.output),c=[];r&&c.push({role:`system`,content:r}),c.push(...i);let l={model:a,messages:c,max_tokens:n.maxTokens??4096,stream:o};if(n.temperature!==void 0&&(l.temperature=n.temperature),n.topP!==void 0&&(l.top_p=n.topP),n.enableThinking?(l.enable_thinking=!0,n.thinkingBudget!==void 0&&(l.thinking_budget=n.thinkingBudget)):o||(l.enable_thinking=!1),n.tool&&(l.tools=n.tool.map(e=>{try{return JSON.parse(e)}catch{let t=gt(e,`utf-8`);return JSON.parse(t)}})),t.dryRun){R({request:l},s);return}if(o){let t=await e.client.request({path:v(),method:`POST`,body:l,stream:!0}),n=``,r=!1,i=s===`text`,a=process.stdout.isTTY,o=s===`json`?process.stderr:a?process.stdout:process.stderr,c=process.stdout,u=P(o);for await(let e of O(t)){if(e.data===`[DONE]`)break;try{let t=JSON.parse(e.data);for(let e of t.choices){let t=e.delta;t.reasoning_content&&(i&&!r&&(r=!0,o.write(u.dim(`Thinking:
|
|
17
|
+
`))),i&&o.write(t.reasoning_content)),t.content&&(i&&r&&(o.write(`${u.reset}\n\nResponse:\n`),r=!1),n+=t.content,i&&c.write(t.content))}}catch{}}r&&o.write(u.reset),s===`json`?R({content:n},s):c.write(`
|
|
18
|
+
`)}else{let n=await e.client.requestJson({path:v(),method:`POST`,body:l}),r=n.choices?.[0]?.message?.content??``;t.quiet||s===`text`?L(r):R(n,s)}}});const en=[{voice:`Tina`,name:`甜妹`,desc:`甜美亲切`,lang:`中文/英文`},{voice:`Dylan`,name:`北京-晓东`,desc:`胡同少年`,lang:`中文/北京`},{voice:`Kiki`,name:`粤语-阿清`,desc:`甜美港妹`,lang:`中文/英文`},{voice:`Li`,name:`南京-老李`,desc:`南京大叔`,lang:`中文/英文`},{voice:`Sunny`,name:`四川-晴儿`,desc:`甜飒川妹`,lang:`中文`},{voice:`Marcus`,name:`陕西-秦川`,desc:`陕北汉子`,lang:`中文/英文`},{voice:`Eric`,name:`四川-程川`,desc:`成都大哥`,lang:`中文/英文`},{voice:`Rocky`,name:`粤语-阿强`,desc:`幽默港仔`,lang:`中文/英文`},{voice:`Jennifer`,name:`詹妮弗`,desc:`美剧大女主`,lang:`中文/英文`},{voice:`Ryan`,name:`甜茶`,desc:`美剧张力男`,lang:`中文/英文`},{voice:`Katerina`,name:`卡捷琳娜`,desc:`御姐深情女`,lang:`中文/英文`},{voice:`Peter`,name:`天津-李彼得`,desc:`天津捧哏`,lang:`中文/英文`},{voice:`Ethan`,name:`晨煦`,desc:`北方口音男`,lang:`中文/英文`}];function tn(){let e=(e,t)=>e.padEnd(t);process.stdout.write(`
|
|
19
19
|
Omni output voices:
|
|
20
|
-
`),process.stdout.write(`${e(`VOICE ID`,12)} ${e(`NAME`,14)} ${e(`DESCRIPTION`,14)} LANGUAGE\n`),process.stdout.write(`${`-`.repeat(12)} ${`-`.repeat(14)} ${`-`.repeat(14)} ${`-`.repeat(12)}\n`);for(let t of
|
|
21
|
-
`)
|
|
22
|
-
`);
|
|
23
|
-
`)
|
|
24
|
-
`));
|
|
25
|
-
`),
|
|
26
|
-
`)):G({urls:g,saved:y,total:g.length},m)}}),Mn=y({description:`Generate a video from text or image (happyhorse-1.1-t2v / happyhorse-1.1-i2v / wan2.6-t2v)`,usageArgs:`--prompt <text> [--image <url>] [flags]`,options:[{flag:`--model <model>`,description:`Model ID (default: happyhorse-1.1-t2v, or happyhorse-1.1-i2v with --image)`},{flag:`--prompt <text>`,description:`Video description`,required:!0},{flag:`--image <url>`,description:`Input image URL for image-to-video generation`},{flag:`--negative-prompt <text>`,description:`Negative prompt to exclude unwanted content`},{flag:`--resolution <res>`,description:`Resolution: 720P or 1080P (default: 1080P)`},{flag:`--ratio <ratio>`,description:`Aspect ratio (e.g. 16:9, 9:16, 1:1)`},{flag:`--duration <seconds>`,description:`Video duration in seconds (default: 5)`,type:`number`},{flag:`--prompt-extend <bool>`,description:Xe},{flag:`--watermark <bool>`,description:B},{flag:`--seed <n>`,description:`Random seed for reproducible generation`,type:`number`},{flag:`--download <path>`,description:`Save video to file on completion`},{flag:`--no-wait`,description:`Return task ID immediately without waiting`},{flag:`--async`,description:`Return task ID immediately (agent/CI mode, same as --no-wait)`},{flag:`--poll-interval <seconds>`,description:`Polling interval when waiting (default: 5)`,type:`number`}],exampleArgs:[`--prompt "A person reading a book, static shot"`,`--prompt "Ocean waves at sunset." --download sunset.mp4`,`--image https://example.com/cat.png --prompt "Make the cat in the scene move"`,`--prompt "Mountain landscape" --resolution 720P --duration 5`,`--prompt "A cat playing with a ball" --watermark false`],async run(t,n){let r=n.prompt;if(!r)if(D({nonInteractive:t.nonInteractive})){let e=await Z({message:`Enter your video prompt:`});e||(process.stderr.write(`Video generation cancelled.
|
|
27
|
-
`),process.exit(1)),r=e}else K(`prompt`,V(t,`--prompt <text>`));let a=n.model||t.defaultVideoModel||(n.image?`happyhorse-1.1-i2v`:`happyhorse-1.1-t2v`),o=C(t.output),s=n.image,c;s&&(c=await I(s,(await F(t)).token,a));let l=R(n.watermark),u=N(n.promptExtend,void 0,`prompt-extend`),d={model:a,input:{prompt:r,negative_prompt:n.negativePrompt||void 0,...c?{media:[{type:`first_frame`,url:c}]}:{}},parameters:{resolution:n.resolution||void 0,ratio:n.ratio||void 0,duration:n.duration||void 0,prompt_extend:u,watermark:l,seed:n.seed}};if(t.dryRun){G({request:d},o);return}let f=ct(n),p=qe(t.baseUrl),m=(await mt(f,t,()=>M(t,{url:p,method:`POST`,body:d,async:!0}),`tasks`)).map(e=>e.output.task_id);if(t.quiet||process.stderr.write(`[Model: ${a}]\n`),n.noWait||t.async){G(m.length===1?{task_id:m[0]}:{task_ids:m},o);return}let h=n.pollInterval??5,g=m.map(e=>Y(t,{url:z(t.baseUrl,e),intervalSec:h,timeoutSec:t.timeout,isComplete:e=>e.output.task_status===`SUCCEEDED`,isFailed:e=>e.output.task_status===`FAILED`,getStatus:e=>e.output.task_status,getErrorMessage:e=>{let t=e.output;return t.message||t.code||void 0}})),_=await Promise.all(g),v=[];for(let e=0;e<_.length;e++){let t=_[e],n=t.output.video_url||t.output.results&&t.output.results[0]?.url;n&&v.push({taskId:m[e],videoUrl:n})}if(v.length===0)throw new e(`All tasks completed but no video URLs returned.`,i.GENERAL);if(n.download){let e=n.download,{size:r}=await U(v[0].videoUrl,e,{quiet:t.quiet});t.quiet?W(e):G({task_id:v[0].taskId,video_url:v[0].videoUrl,status:`SUCCEEDED`,saved:e,size:st(r)},o);return}let y=L(t,{subDir:`videos`}),{join:b}=await import(`path`),x=[];await Promise.all(v.map(async({taskId:e,videoUrl:n})=>{let r=b(y,`${e}.mp4`);await U(n,r,{quiet:t.quiet}),x.push({task_id:e,video_url:n,saved:r})})),x.length===1?G(x[0],o):G({videos:x,total:x.length},o)}}),Nn=y({description:`Edit a video with happyhorse-1.0-video-edit (style transfer, object replacement, etc.)`,usageArgs:`--video <url> --prompt <text> [flags]`,options:[{flag:`--model <model>`,description:`Model ID (default: happyhorse-1.0-video-edit)`},{flag:`--video <url>`,description:`Input video URL or local file (mp4/mov, 2-10s)`,required:!0},{flag:`--prompt <text>`,description:`Edit instruction (e.g. "Convert the scene to a claymation style")`},{flag:`--ref-image <url>`,description:`Reference image URL (up to 4, comma-separated)`},{flag:`--negative-prompt <text>`,description:`Negative prompt to exclude unwanted content`},{flag:`--resolution <res>`,description:`Resolution: 720P or 1080P (default: 1080P)`},{flag:`--ratio <ratio>`,description:`Aspect ratio (16:9, 9:16, 1:1, 4:3, 3:4)`},{flag:`--duration <seconds>`,description:`Output video duration in seconds (2-10)`,type:`number`},{flag:`--audio-setting <mode>`,description:`Audio: auto (default) or origin (keep original)`},{flag:`--prompt-extend <bool>`,description:Xe},{flag:`--watermark <bool>`,description:B},{flag:`--seed <n>`,description:`Random seed for reproducible generation`,type:`number`},{flag:`--download <path>`,description:`Save video to file on completion`},{flag:`--no-wait`,description:`Return task ID immediately without waiting`},{flag:`--async`,description:`Return task ID immediately (agent/CI mode, same as --no-wait)`},{flag:`--poll-interval <seconds>`,description:`Polling interval when waiting (default: 15)`,type:`number`}],exampleArgs:[`--video https://example.com/input.mp4 --prompt "Convert the entire scene to claymation style"`,`--video https://example.com/input.mp4 --prompt "Replace the outfit with the style shown in the image" --ref-image https://example.com/clothes.png`,`--video https://example.com/input.mp4 --prompt "Convert to anime style" --resolution 720P --download output.mp4`,`--video https://example.com/input.mp4 --prompt "Put clothes on the kitten in the video" --watermark false`],async run(t,n){let r=n.video;if(!r)if(D({nonInteractive:t.nonInteractive})){let e=await Z({message:`Enter the video URL to edit:`});e||(process.stderr.write(`Video editing cancelled.
|
|
28
|
-
`),process.exit(1)),r=e}else K(`video`,V(t,`--video <url> --prompt <text>`));let a=n.prompt;if(!a&&D({nonInteractive:t.nonInteractive})){let e=await Z({message:`Enter your edit instruction:`});e||(process.stderr.write(`Video editing cancelled.
|
|
29
|
-
`),process.exit(1)),a=e}let o=n.model||`happyhorse-1.0-video-edit`,s=C(t.output),c=await F(t),l=[{type:`video`,url:await I(r,c.token,o)}],u=n.refImage;if(u){let e=u.split(`,`).map(e=>e.trim()).filter(Boolean);for(let t of e){let e=await I(t,c.token,o);l.push({type:`reference_image`,url:e})}}let d=N(n.promptExtend,void 0,`prompt-extend`),f=R(n.watermark),p={model:o,input:{prompt:a||void 0,negative_prompt:n.negativePrompt||void 0,media:l},parameters:{resolution:n.resolution||void 0,ratio:n.ratio||void 0,duration:n.duration||void 0,audio_setting:n.audioSetting||void 0,prompt_extend:d,watermark:f,seed:n.seed}};if(t.dryRun){G({request:p},s);return}let m=(await M(t,{url:qe(t.baseUrl),method:`POST`,body:p,async:!0})).output.task_id;if(t.quiet||(process.stderr.write(`[Model: ${o}]\n`),process.stderr.write(`Note: Video editing typically takes 5-8 minutes. Please be patient.
|
|
30
|
-
`)),n.noWait||t.async){G({task_id:m},s);return}let h=n.pollInterval??15,g=await Y(t,{url:z(t.baseUrl,m),intervalSec:h,timeoutSec:Math.max(t.timeout,600),isComplete:e=>e.output.task_status===`SUCCEEDED`,isFailed:e=>e.output.task_status===`FAILED`,getStatus:e=>e.output.task_status,getErrorMessage:e=>{let t=e.output;return t.message||t.code||void 0}}),_=g.output.video_url||g.output.results&&g.output.results[0]?.url;if(!_)throw new e(`Task completed but no video URL returned.`,i.GENERAL);if(n.download){let e=n.download,{size:r}=await U(_,e,{quiet:t.quiet});t.quiet?W(e):G({task_id:m,video_url:_,status:`SUCCEEDED`,saved:e,size:st(r)},s);return}let v=await import(`path`),y=L(t,{subDir:`videos`}),b=v.join(y,`${m}.mp4`);await U(_,b,{quiet:t.quiet}),G({task_id:m,video_url:_,saved:b},s)}}),Pn=y({description:`Reference-to-video generation (happyhorse-1.1-r2v / wan2.6-r2v): multi-subject, multi-shot with voice`,usageArgs:`--prompt <text> --image <url>... [--ref-video <url>...] [flags]`,options:[{flag:`--model <model>`,description:`Model ID (default: happyhorse-1.1-r2v)`},{flag:`--prompt <text>`,description:`Video description with reference markers (image1, video1, etc.)`,required:!0},{flag:`--image <url>`,description:`Reference image URL or local file (repeatable for multiple subjects)`,type:`array`},{flag:`--ref-video <url>`,description:`Reference video URL or local file (repeatable)`,type:`array`},{flag:`--image-voice <url>`,description:`Voice URL for corresponding image (pairs by position)`,type:`array`},{flag:`--video-voice <url>`,description:`Voice URL for corresponding ref-video (pairs by position)`,type:`array`},{flag:`--resolution <res>`,description:`Resolution: 720P or 1080P (default: 1080P)`},{flag:`--ratio <ratio>`,description:`Aspect ratio (16:9, 9:16, 1:1)`},{flag:`--duration <seconds>`,description:`Video duration in seconds (default: 5)`,type:`number`},{flag:`--prompt-extend <bool>`,description:Xe},{flag:`--watermark <bool>`,description:B},{flag:`--seed <n>`,description:`Random seed for reproducible generation`,type:`number`},{flag:`--download <path>`,description:`Save video to file on completion`},{flag:`--no-wait`,description:`Return task ID immediately without waiting`},{flag:`--async`,description:`Return task ID immediately (agent/CI mode, same as --no-wait)`},{flag:`--poll-interval <seconds>`,description:`Polling interval when waiting (default: 15)`,type:`number`}],exampleArgs:[`--prompt "Image1 running on the grass" --image person.jpg`,`--prompt "Video 1 plays guitar, Image 1 walks over" --ref-video scene.mp4 --image person.jpg`,`--prompt "Image 1 speaks" --image person.jpg --image-voice voice.mp3 --resolution 1080P`,`--prompt "Image 1 and Image 2 have a conversation" --image a.jpg --image b.jpg --image-voice va.mp3 --image-voice vb.mp3`,`--prompt "Image 1 drinks water" --image person.jpg --watermark false`],async run(t,n){let r=n.prompt;if(!r)if(D({nonInteractive:t.nonInteractive})){let e=await Z({message:`Enter your video prompt (use Image1, Video1 to reference inputs):`});e||(process.stderr.write(`Video generation cancelled.
|
|
31
|
-
`),process.exit(1)),r=e}else K(`prompt`,V(t,`--prompt <text> --image <url>`));let a=n.image||[],o=n.refVideo||[];if(a.length===0&&o.length===0)throw new e(`At least one --image or --ref-video is required.`,i.USAGE,V(t,`--prompt "description" --image person.jpg`));let s=n.imageVoice||[],c=n.videoVoice||[],l=n.model||`happyhorse-1.1-r2v`,u=C(t.output),d=await F(t),f=[];for(let e=0;e<a.length;e++){let t={type:`reference_image`,url:await I(a[e],d.token,l)};s[e]&&(t.reference_voice=await I(s[e],d.token,l)),f.push(t)}for(let e=0;e<o.length;e++){let t={type:`reference_video`,url:await I(o[e],d.token,l)};c[e]&&(t.reference_voice=await I(c[e],d.token,l)),f.push(t)}let p=N(n.promptExtend,void 0,`prompt-extend`),m=R(n.watermark),h={model:l,input:{prompt:r,media:f},parameters:{resolution:n.resolution||void 0,ratio:n.ratio||void 0,duration:n.duration||void 0,prompt_extend:p,watermark:m,seed:n.seed}};if(t.dryRun){G({request:h},u);return}let g=(await M(t,{url:qe(t.baseUrl),method:`POST`,body:h,async:!0})).output.task_id;if(t.quiet||(process.stderr.write(`[Model: ${l}]\n`),process.stderr.write(`Note: Reference-to-video typically takes 5-10 minutes. Please be patient.
|
|
32
|
-
`)),n.noWait||t.async){G({task_id:g},u);return}let _=n.pollInterval??15,v=await Y(t,{url:z(t.baseUrl,g),intervalSec:_,timeoutSec:Math.max(t.timeout,600),isComplete:e=>e.output.task_status===`SUCCEEDED`,isFailed:e=>e.output.task_status===`FAILED`,getStatus:e=>e.output.task_status,getErrorMessage:e=>{let t=e.output;return t.message||t.code||void 0}}),y=v.output.video_url||v.output.results&&v.output.results[0]?.url;if(!y)throw new e(`Task completed but no video URL returned.`,i.GENERAL);if(n.download){let e=n.download,{size:r}=await U(y,e,{quiet:t.quiet});t.quiet?W(e):G({task_id:g,video_url:y,status:`SUCCEEDED`,saved:e,size:st(r)},u);return}let{join:b}=await import(`path`),x=b(L(t,{subDir:`videos`}),`${g}.mp4`);await U(y,x,{quiet:t.quiet}),G({task_id:g,video_url:y,saved:x},u)}}),Fn=y({description:`Query async task status`,usageArgs:`--task-id <id>`,options:[{flag:`--task-id <id>`,description:`Async task ID`}],exampleArgs:[`--task-id 3b256896-3e70-xxxx-xxxx-xxxxxxxxxxxx`,`--task-id 3b256896-3e70-xxxx --output json`],async run(e,t){let n=t.taskId;n||K(`task-id`,V(e,`--task-id <id>`));let r=C(e.output);if(e.dryRun){G({task_id:n},r);return}let i=await M(e,{url:z(e.baseUrl,n)});if(e.quiet){W(i.output.task_status);return}G({task_id:i.output.task_id,task_status:i.output.task_status,video_url:i.output.video_url,results:i.output.results,submit_time:i.output.submit_time,end_time:i.output.end_time},r)}}),In=y({description:`Download a completed video by task ID`,usageArgs:`--task-id <id> --out <path>`,options:[{flag:`--task-id <id>`,description:`Task ID to download from`},{flag:`--out <path>`,description:`Output file path`}],exampleArgs:[`--task-id 3b256896-xxxx --out video.mp4`,`--task-id 3b256896-xxxx --out video.mp4 --quiet`],async run(t,n){let r=n.taskId;r||K(`task-id`,V(t,`--task-id <id> --out <path>`));let a=n.out;a||K(`out`,V(t,`--task-id <id> --out video.mp4`));let o=C(t.output);if(t.dryRun){G({task_id:r,action:`download`,out:a},o);return}let s=await M(t,{url:z(t.baseUrl,r)});if(s.output.task_status!==`SUCCEEDED`)throw new e(`Task is not complete (status: ${s.output.task_status}).`,i.GENERAL,`Wait for the task to complete before downloading.`);let c=s.output.video_url||s.output.results&&s.output.results[0]?.url;if(!c)throw new e(`No download URL available for this task.`,i.GENERAL);let{size:l}=await U(c,a,{quiet:t.quiet});if(t.quiet){W(a);return}G({saved:a,size:st(l)},o)}});const Ln={".jpg":`image/jpeg`,".jpeg":`image/jpeg`,".png":`image/png`,".webp":`image/webp`},Rn=new Set([`.mp4`,`.mov`,`.avi`,`.mkv`,`.webm`,`.flv`,`.wmv`]);function zn(e){let t=Tt(e).toLowerCase().split(`?`)[0];return!!(Rn.has(t)||/\.(mp4|mov|avi|mkv|webm|flv|wmv)(\?|$)/i.test(e))}async function Bn(t){if(t.startsWith(`data:`)||t.startsWith(`http://`)||t.startsWith(`https://`)||t.startsWith(`oss://`))return t;if(!bt(t))throw new e(`File not found: ${t}`,i.USAGE);let n=Tt(t).toLowerCase(),r=Ln[n];if(!r)throw new e(`Unsupported image format "${n}". Supported: jpg, jpeg, png, webp`,i.USAGE);return`data:${r};base64,${xt(t).toString(`base64`)}`}var Vn=y({description:`Describe an image or video using Qwen-VL`,usageArgs:`--image <path-or-url> [--video <url>] [--prompt <text>]`,options:[{flag:`--image <path-or-url>`,description:`Local image path or URL`},{flag:`--video <url>`,description:`Video file URL or local path (mp4/mov/avi/mkv/webm)`,type:`array`},{flag:`--prompt <text>`,description:`Question about the content (default: auto-detected)`},{flag:`--model <model>`,description:`Vision model (default: qwen3-vl-plus)`}],exampleArgs:[`--image photo.jpg`,`--image https://example.com/photo.jpg --prompt "What breed is this dog?"`,`--video https://example.com/video.mp4 --prompt "Summarize the video content"`,`--video ./local-video.mp4`,`--image photo.png --prompt "Extract the text" --model qwen3-vl-plus`],async run(t,n){let r=n.image??n._positional?.[0],a=n.video??[],o=n.model||`qwen3-vl-plus`;r&&zn(r)&&(a.push(r),r=void 0);let s=a.length>0,c=s?`Describe the video.`:`Describe the image.`,l=n.prompt||c;if(!r&&!s)if(D({nonInteractive:t.nonInteractive})){let e=await Z({message:`Enter image/video path or URL:`});e||(process.stderr.write(`Vision describe cancelled.
|
|
33
|
-
`),process.exit(1)),zn(e)?a.push(e):r=e}else throw new e(`Missing required argument --image or --video.`,i.USAGE,`${V(t,`--image <path-or-url>`)}\n${V(t,`--video <url-or-path>`)}`);let u=C(t.output);if(t.dryRun){G({request:{prompt:l,image:r,video:a.length?a:void 0,model:o}},u);return}let d=[];if(a.length>0)for(let n of a){let r=n;if(fe(n)){if(!bt(n))throw new e(`Video file not found: ${n}`,i.USAGE);r=await I(n,(await F(t)).token,o)}d.push({type:`video_url`,video_url:{url:r}})}if(r){let e=await Bn(r),n=e;if(fe(r)&&e.startsWith(`data:`)){let{statSync:e}=await import(`fs`);if(e(r).size>5*1024*1024){let e=await F(t);n=await I(r,e.token,o)}}d.push({type:`image_url`,image_url:{url:n}})}d.push({type:`text`,text:l});let f={model:o,messages:[{role:`user`,content:d}]},p=await M(t,{url:h(t.baseUrl),method:`POST`,body:f}),m=p.choices?.[0]?.message?.content;if(u!==`text`){G(p,u);return}W(m||``)}}),Hn=y({description:`Display current configuration`,skipDefaultApiKeySetup:!0,exampleArgs:[``,`--output json`],async run(e,t){let n=A(),r=C(e.output),i={...n,base_url:e.baseUrl,output:e.output,timeout:e.timeout,config_file:ie()};typeof i.api_key==`string`&&(i.api_key=O(i.api_key)),typeof i.access_token==`string`&&(i.access_token=O(i.access_token)),typeof i.access_key_id==`string`&&(i.access_key_id=O(i.access_key_id)),typeof i.access_key_secret==`string`&&(i.access_key_secret=O(i.access_key_secret)),G(i,r)}});const Un=[`base_url`,`output`,`output_dir`,`timeout`,`api_key`,`access_token`,`default_text_model`,`default_video_model`,`default_image_model`,`default_speech_model`,`default_omni_model`,`access_key_id`,`access_key_secret`,`workspace_id`],Wn=new Set([`api_key`,`access_token`,`access_key_id`,`access_key_secret`]),Gn={"base-url":`base_url`,"output-dir":`output_dir`,"api-key":`api_key`,"access-token":`access_token`,"default-text-model":`default_text_model`,"default-video-model":`default_video_model`,"default-image-model":`default_image_model`,"default-speech-model":`default_speech_model`,"default-omni-model":`default_omni_model`,"access-key-id":`access_key_id`,"access-key-secret":`access_key_secret`,"workspace-id":`workspace_id`};var Kn=y({description:`Set a config value`,skipDefaultApiKeySetup:!0,usageArgs:`--key <key> --value <value>`,options:[{flag:`--key <key>`,description:`Config key (base_url, output, output_dir, timeout, api_key, access_token, default_*_model, access_key_id, access_key_secret, workspace_id)`},{flag:`--value <value>`,description:`Value to set`}],exampleArgs:[`--key output --value json`,`--key timeout --value 600`,`--key base_url --value https://dashscope.aliyuncs.com`],async run(t,n){let r=n.key,a=n.value;if(!r||a===void 0)throw new e(`--key and --value are required.`,i.USAGE,V(t,`--key <key> --value <value>`));let o=Gn[r]||r;if(!Un.includes(o))throw new e(`Invalid config key "${r}". Valid keys: ${Un.join(`, `)}`,i.USAGE);if(o===`output`&&![`text`,`json`].includes(a))throw new e(`Invalid output format "${a}". Valid values: text, json`,i.USAGE);if(o===`timeout`){let t=Number(a);if(isNaN(t)||t<=0)throw new e(`Invalid timeout "${a}". Must be a positive number.`,i.USAGE)}let s=C(t.output);if(t.dryRun){G({would_set:{[o]:a}},s);return}let c=A();if(c[o]=o===`timeout`?Number(a):a,await Je(c),!t.quiet){let e=Wn.has(o)?O(String(c[o])):c[o];G({[o]:e},s)}}});const qn=`npx skills add modelstudioai/cli --all -g -y`;function Jn(e){return{cmd:`npm install -g ${e}@latest`,label:`npm`}}function Yn(e){let{green:t,yellow:n,reset:r}=e;process.stderr.write(`
|
|
20
|
+
`),process.stdout.write(`${e(`VOICE ID`,12)} ${e(`NAME`,14)} ${e(`DESCRIPTION`,14)} LANGUAGE\n`),process.stdout.write(`${`-`.repeat(12)} ${`-`.repeat(14)} ${`-`.repeat(14)} ${`-`.repeat(12)}\n`);for(let t of en)process.stdout.write(`${e(t.voice,12)} ${e(t.name,14)} ${e(t.desc,14)} ${t.lang}\n`);process.stdout.write(`\nTotal: ${en.length} voices\n`)}const nn={wav:`wav`,mp3:`mp3`,amr:`amr`,aac:`aac`,m4a:`aac`,ogg:`ogg`,"3gp":`3gp`,"3gpp":`3gpp`},rn=Object.keys(nn);function an(e){let n=e.split(`?`)[0].split(`#`)[0],r=bt(n).slice(1).toLowerCase();if(!r)throw new t(`Cannot infer audio format from "${e}". Use a file/URL whose path ends with: ${rn.join(`, `)}.`,a.USAGE);let i=nn[r];if(!i)throw new t(`Unsupported audio extension ".${r}" for "${e}". Supported extensions: ${rn.join(`, `)}.`,a.USAGE);return i}function on(e){let t=Buffer.alloc(44);return t.write(`RIFF`,0),t.writeUInt32LE(36+e,4),t.write(`WAVE`,8),t.write(`fmt `,12),t.writeUInt32LE(16,16),t.writeUInt16LE(1,20),t.writeUInt16LE(1,22),t.writeUInt32LE(24e3,24),t.writeUInt32LE(48e3,28),t.writeUInt16LE(2,32),t.writeUInt16LE(16,34),t.write(`data`,36),t.writeUInt32LE(e,40),t}var sn=x({description:`Multimodal chat with text + audio output (Qwen-Omni)`,auth:`apiKey`,usageArgs:`--message <text> [flags]`,flags:{message:{type:`array`,valueHint:`<text>`,description:`Message text (repeatable, prefix role: to set role)`},model:{type:`string`,valueHint:`<model>`,description:`Model ID (default: qwen3.5-omni-plus)`},system:{type:`string`,valueHint:`<text>`,description:`System prompt`},image:{type:`array`,valueHint:`<url>`,description:`Image URL or local file (repeatable)`},audio:{type:`array`,valueHint:`<url>`,description:`Audio URL or local file (.wav/.mp3/.amr/.aac/.m4a/.ogg/.3gp/.3gpp)`},video:{type:`array`,valueHint:`<url>`,description:`Video file URL / local path, or comma-separated frame URLs`},voice:{type:`string`,valueHint:`<voice>`,description:`Output voice ID (default: Tina). Use --list-voices to see all options`},listVoices:{type:`switch`,description:`List available output voices and exit`},audioFormat:{type:`string`,valueHint:`<fmt>`,description:`Audio output format (default: wav)`},audioOut:{type:`string`,valueHint:`<path>`,description:`Save audio to file (default: auto-generate)`},textOnly:{type:`switch`,description:`Output text only, no audio generation`},maxTokens:{type:`number`,valueHint:`<n>`,description:`Maximum tokens to generate`},temperature:{type:`number`,valueHint:`<n>`,description:`Sampling temperature (0.0, 2.0]`}},exampleArgs:[`--list-voices`,`--message "Hello, who are you?"`,`--message "Describe this image" --image ./photo.jpg`,`--message "What is this audio saying?" --audio https://example.com/audio.wav`,`--message "Summarize this video" --video https://example.com/video.mp4`,`--message "What is this video about?" --video ./local-video.mp4 --text-only`,`--message "Answer in Sichuan dialect: How's the weather today?" --voice Sunny`,`--message "Hello" --text-only --output json`,`--message "Read this passage aloud" --audio-out greeting.wav`],validate:e=>e.listVoices||e.message?void 0:`Missing required flag: --message`,async run(e){let{settings:t,flags:n}=e;if(n.listVoices){tn();return}let r=n.message??[],i=n.model||t.defaultOmniModel||`qwen3.5-omni-plus`,a=n.voice||`Tina`,o=n.audioFormat||`wav`,s=n.textOnly===!0,c=w(t.output),l=[];n.system&&l.push({role:`system`,content:n.system});let u=new Set([`system`,`user`,`assistant`]);for(let e of r){let t=e.indexOf(`:`),n=t===-1?``:e.slice(0,t);if(u.has(n)){let r=e.slice(t+1);n===`system`?l.push({role:`system`,content:r}):l.push({role:n,content:r})}else l.push({role:`user`,content:e})}let d=n.image||[],f=n.audio||[],p=n.video||[],m=[],h=[],g=[];if(d.length>0||f.length>0||p.length>0){for(let t of d){let n=await e.client.uploadFile(t,i);m.push(n)}for(let t of f){let n=await e.client.uploadFile(t,i);h.push({source:t,data:n})}for(let t of p)if(t.includes(`,`)){let n=t.split(`,`).map(e=>e.trim()).filter(Boolean);for(let t of n){let n=await e.client.uploadFile(t,i);g.push(`frame:${n}`)}}else{let n=await e.client.uploadFile(t,i);g.push(n)}}if(m.length>0||h.length>0||g.length>0){for(let e=l.length-1;e>=0;e--)if(l[e].role===`user`){let t=l[e].content,n=[];typeof t==`string`?n.push({type:`text`,text:t}):Array.isArray(t)&&n.push(...t);for(let e of m)n.push({type:`image_url`,image_url:{url:e}});for(let{source:e,data:t}of h)n.push({type:`input_audio`,input_audio:{data:t,format:an(e)}});let r=g.filter(e=>e.startsWith(`frame:`)).map(e=>e.slice(6)),i=g.filter(e=>!e.startsWith(`frame:`));r.length>0&&n.push({type:`video`,video:r});for(let e of i)n.push({type:`video_url`,video_url:{url:e}});l[e]={role:`user`,content:n};break}}let _={model:i,messages:l,stream:!0,stream_options:{include_usage:!0}};if(s||(_.modalities=[`text`,`audio`],_.audio={voice:a,format:o}),n.maxTokens!==void 0&&(_.max_tokens=n.maxTokens),n.temperature!==void 0&&(_.temperature=n.temperature),t.dryRun){R({request:_},c);return}if(!t.quiet){let e=s?`text-only`:`text+audio, voice: ${a}`;process.stderr.write(`[Model: ${i}] [${e}]\n`)}let y=await e.client.request({path:v(),method:`POST`,body:_,stream:!0}),b=``,x=``,S=process.stdout.isTTY,C=process.stdout;for await(let e of O(y)){if(e.data===`[DONE]`)break;try{let t=JSON.parse(e.data);for(let e of t.choices){let t=e.delta;t.content&&(b+=t.content,S&&C.write(t.content)),t.audio?.data&&(x+=t.audio.data)}}catch{}}S&&b&&C.write(`
|
|
21
|
+
`);let ee;if(x&&!s){let e=Buffer.from(x,`base64`),r=on(e.length),i=Buffer.concat([r,e]),a=n.audioOut;if(!a){let{join:e}=await import(`path`);a=e(A(t,{subDir:`omni`}),`omni_${Date.now()}.wav`)}vt(a,i),ee=a,t.quiet||process.stderr.write(`Audio saved: ${a}\n`)}if(!S||c===`json`){let e={content:b};ee&&(e.audio_saved=ee,e.voice=a),R(e,c)}}});const cn=[`qwen-image-2.0`,`qwen-image-max`];function ln(e){return cn.some(t=>e.startsWith(t))}var un=x({description:`Generate images (Qwen-Image / wan2.x)`,auth:`apiKey`,usageArgs:`--prompt <text> [flags]`,flags:{prompt:{type:`string`,valueHint:`<text>`,description:`Image description`,required:!0},model:{type:`string`,valueHint:`<model>`,description:`Model ID (default: qwen-image-2.0)`},size:{type:`string`,valueHint:`<W*H>`,description:`Image size: ratio (3:4, 16:9, 1:1) or pixels (2048*2048)`},n:{type:`number`,valueHint:`<count>`,description:`Number of images per request (default: 1, max: 6)`},seed:{type:`number`,valueHint:`<n>`,description:`Random seed for reproducible generation`},negativePrompt:{type:`string`,valueHint:`<text>`,description:`Negative prompt to exclude unwanted content`},promptExtend:{type:`boolean`,valueHint:`<bool>`,description:Qe},watermark:{type:`boolean`,valueHint:`<bool>`,description:N},...e,...n,outDir:{type:`string`,valueHint:`<dir>`,description:`Download images to directory`},outPrefix:{type:`string`,valueHint:`<prefix>`,description:`Filename prefix (default: image)`},pollInterval:{type:`number`,valueHint:`<seconds>`,description:`Polling interval when waiting (default: 3)`}},exampleArgs:[`--prompt "A cat in a spacesuit on Mars"`,`--prompt "Logo design" --n 3 --out-dir ./generated/`,`--prompt "Mountain landscape" --size 2688*1536`,`--prompt "A castle" --seed 42 --prompt-extend false`,`--prompt "Logo" --watermark false`,`--prompt "An alien in the space" --watermark false`,`--prompt "sunset" --model wan2.6-t2i --async --quiet`,`--prompt "Pro quality" --model qwen-image-2.0-pro`,`--prompt "Product shots" --n 2 --concurrent 3 # 6 images in parallel`],async run(e){let{settings:t,flags:n}=e,r=n.prompt,i=n.model||t.defaultImageModel||`qwen-image-2.0`,a=ln(i),o=ct(n.size||`1:1`,a),s=n.n??1,c=B(n),l=k(n.promptExtend,a?!0:void 0,`prompt-extend`),u=j(n.watermark),d={model:i,input:{messages:[{role:`user`,content:[{text:r}]}]},parameters:{size:o,n:s,seed:n.seed,prompt_extend:l,watermark:u,negative_prompt:n.negativePrompt||void 0}},f=w(t.output);if(t.dryRun){R({request:d,mode:a?`sync`:`async`},f);return}t.quiet||process.stderr.write(`[Model: ${i}] [Mode: ${a?`sync`:`async`}]\n`),a?await dn(e.client,t,i,d,n,f,c):await fn(e.client,t,i,d,n,f,c)}});async function dn(e,n,r,i,o,s,c){let l=(await U(c,n,()=>e.requestJson({path:pe(),method:`POST`,body:i}))).flatMap(e=>e.output.choices||[]).flatMap(e=>e.message?.content||[]).map(e=>e.image).filter(Boolean);if(l.length===0)throw new t(`Generation completed but no images returned.`,a.GENERAL);await pn(l,o,n,s)}async function fn(e,n,r,i,o,s,c){let l=(await U(c,n,()=>e.requestJson({path:fe(),method:`POST`,body:i,async:!0}),`tasks`)).map(e=>e.output.task_id);if(o.async){R({task_ids:l},s);return}let u=o.pollInterval??3,d=l.map(t=>H(e,n,{url:e.url(M(t)),intervalSec:u,timeoutSec:n.timeout,isComplete:e=>e.output.task_status===`SUCCEEDED`,isFailed:e=>e.output.task_status===`FAILED`,getStatus:e=>e.output.task_status,getErrorMessage:e=>{let t=e.output;return t.message||t.code||void 0}})),f=await Promise.all(d),p=[];for(let e of f){if(e.output.choices){let t=e.output.choices.flatMap(e=>e.message?.content||[]).map(e=>e.image).filter(Boolean);p.push(...t)}if(e.output.results){let t=e.output.results.map(e=>e.url).filter(Boolean);t.length>0&&p.length===0&&p.push(...t)}}if(p.length===0)throw new t(`All tasks completed but no images returned.`,a.GENERAL);await pn(p,o,n,s,l.length===1?l[0]:void 0,l)}async function pn(e,t,n,r,i,a){let o=A(n,{flagDir:t.outDir,subDir:t.outDir?void 0:`images`}),s=t.prompt||``,c=t.outPrefix||ie(`image`,s),l=await rt(e.length>1?e.map((e,t)=>({url:e,destPath:W(o,`${c}_${String(t+1).padStart(3,`0`)}.png`)})):[{url:e[0],destPath:W(o,`${c}.png`)}],I,{quiet:n.quiet});if(n.quiet)L(l.join(`
|
|
22
|
+
`));else{let t={urls:e,saved:l,total:e.length};i&&(t.task_id=i),a&&a.length>1&&(t.task_ids=a),R(t,r)}}const mn=[`qwen-image-2.0`,`qwen-image-max`];function hn(e){return mn.some(t=>e.startsWith(t))}var gn=x({description:`Edit an existing image with text instructions (Qwen-Image)`,auth:`apiKey`,usageArgs:`--image <url> --prompt <text> [flags]`,flags:{image:{type:`array`,valueHint:`<url>`,description:`Source image URL or local file path (repeatable for multi-image merge)`,required:!0},prompt:{type:`string`,valueHint:`<text>`,description:`Edit instruction text`,required:!0},model:{type:`string`,valueHint:`<model>`,description:`Model ID (default: qwen-image-2.0)`},size:{type:`string`,valueHint:`<W*H>`,description:`Output image size: ratio (3:4, 16:9) or pixels (2048*2048)`},n:{type:`number`,valueHint:`<count>`,description:`Number of images (default: 1, max: 6)`},seed:{type:`number`,valueHint:`<n>`,description:`Random seed for reproducible results`},negativePrompt:{type:`string`,valueHint:`<text>`,description:`Negative prompt to exclude unwanted content`},promptExtend:{type:`boolean`,valueHint:`<bool>`,description:Ze},watermark:{type:`boolean`,valueHint:`<bool>`,description:N},outDir:{type:`string`,valueHint:`<dir>`,description:`Download images to directory`},outPrefix:{type:`string`,valueHint:`<prefix>`,description:`Filename prefix (default: edited)`},...e,...n,pollInterval:{type:`number`,valueHint:`<seconds>`,description:`Polling interval when waiting (default: 3)`}},exampleArgs:[`--image ./photo.png --prompt "Replace the background with a beach"`,`--image https://example.com/logo.png --prompt "Change color to blue" --n 3`,`--image ./a.png --image ./b.png --prompt "Merge two images into one collage"`,`--image https://example.com/photo.png --prompt "Remove the person" --model qwen-image-2.0-pro`,`--image ./photo.png --prompt "Replace the background with a beach" --watermark false`],async run(e){let{settings:t,flags:n}=e,r=[];Array.isArray(n.image)?r=n.image:typeof n.image==`string`&&(r=[n.image]);let i=n.prompt,a=n.model||t.defaultImageModel||`qwen-image-2.0`,o=hn(a),s=await Promise.all(r.map(t=>e.client.uploadFile(t,a))),c=n.n??1,l=k(n.promptExtend,o?!0:void 0,`prompt-extend`),u=s.map(e=>({image:e}));u.push({text:i});let d=j(n.watermark),f={model:a,input:{messages:[{role:`user`,content:u}]},parameters:{size:ct(n.size,o),n:c,seed:n.seed,prompt_extend:l,watermark:d,negative_prompt:n.negativePrompt||void 0}};Be(f.parameters);let p=w(t.output);if(t.dryRun){R({request:f,mode:o?`sync`:`async`},p);return}t.quiet||process.stderr.write(`[Model: ${a}] [Mode: ${o?`sync`:`async`}] [Images: ${s.length}]\n`);let m=B(n);o?await _n(e.client,t,f,n,p,m):await vn(e.client,t,f,n,p,m)}});async function _n(e,n,r,i,o,s){let c=(await U(s,n,()=>e.requestJson({path:pe(),method:`POST`,body:r}))).flatMap(e=>e.output.choices||[]).flatMap(e=>e.message?.content||[]).map(e=>e.image).filter(Boolean);if(c.length===0)throw new t(`Edit completed but no images returned.`,a.GENERAL);await yn(c,i,n,o)}async function vn(e,n,r,i,o,s){let c=(await U(s,n,()=>e.requestJson({path:fe(),method:`POST`,body:r,async:!0}),`tasks`)).map(e=>e.output.task_id);if(i.async){R({task_ids:c},o);return}let l=i.pollInterval??3,u=c.map(t=>H(e,n,{url:e.url(M(t)),intervalSec:l,timeoutSec:n.timeout,isComplete:e=>e.output.task_status===`SUCCEEDED`,isFailed:e=>e.output.task_status===`FAILED`,getStatus:e=>e.output.task_status,getErrorMessage:e=>{let t=e.output;return t.message||t.code||void 0}})),d=await Promise.all(u),f=[];for(let e of d){if(e.output.choices){let t=e.output.choices.flatMap(e=>e.message?.content||[]).map(e=>e.image).filter(Boolean);f.push(...t)}if(e.output.results){let t=e.output.results.map(e=>e.url).filter(Boolean);t.length>0&&f.length===0&&f.push(...t)}}if(f.length===0)throw new t(`All tasks completed but no images returned.`,a.GENERAL);await yn(f,i,n,o)}async function yn(e,t,n,r){let i=A(n,{flagDir:t.outDir,subDir:t.outDir?void 0:`images`}),a=t.outPrefix||ie(`edited`,t.prompt),o=await rt(e.length>1?e.map((e,t)=>({url:e,destPath:W(i,`${a}_${String(t+1).padStart(3,`0`)}.png`)})):[{url:e[0],destPath:W(i,`${a}.png`)}],I,{quiet:n.quiet});n.quiet?L(o.join(`
|
|
23
|
+
`)):R({urls:e,saved:o,total:e.length},r)}var bn=x({description:`Generate a video from text or image (happyhorse-1.1-t2v / happyhorse-1.1-i2v / wan2.6-t2v)`,auth:`apiKey`,usageArgs:`--prompt <text> [--image <url>] [flags]`,flags:{model:{type:`string`,valueHint:`<model>`,description:`Model ID (default: happyhorse-1.1-t2v, or happyhorse-1.1-i2v with --image)`},prompt:{type:`string`,valueHint:`<text>`,description:`Video description`,required:!0},image:{type:`string`,valueHint:`<url>`,description:`Input image URL for image-to-video generation`},negativePrompt:{type:`string`,valueHint:`<text>`,description:`Negative prompt to exclude unwanted content`},resolution:{type:`string`,valueHint:`<res>`,description:`Resolution: 720P or 1080P (default: 1080P)`},ratio:{type:`string`,valueHint:`<ratio>`,description:`Aspect ratio (e.g. 16:9, 9:16, 1:1)`},duration:{type:`number`,valueHint:`<seconds>`,description:`Video duration in seconds (default: 5)`},promptExtend:{type:`boolean`,valueHint:`<bool>`,description:Xe},watermark:{type:`boolean`,valueHint:`<bool>`,description:N},seed:{type:`number`,valueHint:`<n>`,description:`Random seed for reproducible generation`},download:{type:`string`,valueHint:`<path>`,description:`Save video to file on completion`},...e,...n,pollInterval:{type:`number`,valueHint:`<seconds>`,description:`Polling interval when waiting (default: 5)`}},exampleArgs:[`--prompt "A person reading a book, static shot"`,`--prompt "Ocean waves at sunset." --download sunset.mp4`,`--image https://example.com/cat.png --prompt "Make the cat in the scene move"`,`--prompt "Mountain landscape" --resolution 720P --duration 5`,`--prompt "A cat playing with a ball" --watermark false`],async run(e){let{settings:n,flags:r}=e,i=r.prompt,o=r.model||n.defaultVideoModel||(r.image?`happyhorse-1.1-i2v`:`happyhorse-1.1-t2v`),s=w(n.output),c=r.image,l;c&&(l=await e.client.uploadFile(c,o));let u=j(r.watermark),d=k(r.promptExtend,void 0,`prompt-extend`),f={model:o,input:{prompt:i,negative_prompt:r.negativePrompt||void 0,...l?{media:[{type:`first_frame`,url:l}]}:{}},parameters:{resolution:r.resolution||void 0,ratio:r.ratio||void 0,duration:r.duration||void 0,prompt_extend:d,watermark:u,seed:r.seed}};if(n.dryRun){R({request:f},s);return}let p=(await U(B(r),n,()=>e.client.requestJson({path:Je(),method:`POST`,body:f,async:!0}),`tasks`)).map(e=>e.output.task_id);if(n.quiet||process.stderr.write(`[Model: ${o}]\n`),r.async){R(p.length===1?{task_id:p[0]}:{task_ids:p},s);return}let m=r.pollInterval??5,h=p.map(t=>{let r=e.client.url(M(t));return H(e.client,n,{url:r,intervalSec:m,timeoutSec:n.timeout,isComplete:e=>e.output.task_status===`SUCCEEDED`,isFailed:e=>e.output.task_status===`FAILED`,getStatus:e=>e.output.task_status,getErrorMessage:e=>{let t=e.output;return t.message||t.code||void 0}})}),g=await Promise.all(h),_=[];for(let e=0;e<g.length;e++){let t=g[e],n=t.output.video_url||t.output.results&&t.output.results[0]?.url;n&&_.push({taskId:p[e],videoUrl:n})}if(_.length===0)throw new t(`All tasks completed but no video URLs returned.`,a.GENERAL);if(r.download){let e=r.download,{size:t}=await I(_[0].videoUrl,e,{quiet:n.quiet});n.quiet?L(e):R({task_id:_[0].taskId,video_url:_[0].videoUrl,status:`SUCCEEDED`,saved:e,size:ot(t)},s);return}let v=A(n,{subDir:`videos`}),{join:y}=await import(`path`),b=[];await Promise.all(_.map(async({taskId:e,videoUrl:t})=>{let r=y(v,`${e}.mp4`);await I(t,r,{quiet:n.quiet}),b.push({task_id:e,video_url:t,saved:r})})),b.length===1?R(b[0],s):R({videos:b,total:b.length},s)}}),xn=x({description:`Edit a video with happyhorse-1.0-video-edit (style transfer, object replacement, etc.)`,auth:`apiKey`,usageArgs:`--video <url> --prompt <text> [flags]`,flags:{model:{type:`string`,valueHint:`<model>`,description:`Model ID (default: happyhorse-1.0-video-edit)`},video:{type:`string`,valueHint:`<url>`,description:`Input video URL or local file (mp4/mov, 2-10s)`,required:!0},prompt:{type:`string`,valueHint:`<text>`,description:`Edit instruction (e.g. "Convert the scene to a claymation style")`},refImage:{type:`string`,valueHint:`<url>`,description:`Reference image URL (up to 4, comma-separated)`},negativePrompt:{type:`string`,valueHint:`<text>`,description:`Negative prompt to exclude unwanted content`},resolution:{type:`string`,valueHint:`<res>`,description:`Resolution: 720P or 1080P (default: 1080P)`},ratio:{type:`string`,valueHint:`<ratio>`,description:`Aspect ratio (16:9, 9:16, 1:1, 4:3, 3:4)`},duration:{type:`number`,valueHint:`<seconds>`,description:`Output video duration in seconds (2-10)`},audioSetting:{type:`string`,valueHint:`<mode>`,description:`Audio: auto (default) or origin (keep original)`,choices:[`auto`,`origin`]},promptExtend:{type:`boolean`,valueHint:`<bool>`,description:Xe},watermark:{type:`boolean`,valueHint:`<bool>`,description:N},seed:{type:`number`,valueHint:`<n>`,description:`Random seed for reproducible generation`},download:{type:`string`,valueHint:`<path>`,description:`Save video to file on completion`},...e,...n,pollInterval:{type:`number`,valueHint:`<seconds>`,description:`Polling interval when waiting (default: 15)`}},exampleArgs:[`--video https://example.com/input.mp4 --prompt "Convert the entire scene to claymation style"`,`--video https://example.com/input.mp4 --prompt "Replace the outfit with the style shown in the image" --ref-image https://example.com/clothes.png`,`--video https://example.com/input.mp4 --prompt "Convert to anime style" --resolution 720P --download output.mp4`,`--video https://example.com/input.mp4 --prompt "Put clothes on the kitten in the video" --watermark false`],async run(e){let{settings:n,flags:r}=e,i=r.video,o=r.prompt,s=r.model||`happyhorse-1.0-video-edit`,c=w(n.output),l=[{type:`video`,url:await e.client.uploadFile(i,s)}],u=r.refImage;if(u){let t=u.split(`,`).map(e=>e.trim()).filter(Boolean);for(let n of t){let t=await e.client.uploadFile(n,s);l.push({type:`reference_image`,url:t})}}let d=k(r.promptExtend,void 0,`prompt-extend`),f=j(r.watermark),p={model:s,input:{prompt:o||void 0,negative_prompt:r.negativePrompt||void 0,media:l},parameters:{resolution:r.resolution||void 0,ratio:r.ratio||void 0,duration:r.duration||void 0,audio_setting:r.audioSetting||void 0,prompt_extend:d,watermark:f,seed:r.seed}};if(n.dryRun){R({request:p},c);return}let m=(await U(B(r),n,()=>e.client.requestJson({path:Je(),method:`POST`,body:p,async:!0}),`tasks`)).map(e=>e.output.task_id);if(n.quiet||(process.stderr.write(`[Model: ${s}]\n`),process.stderr.write(`Note: Video editing typically takes 5-8 minutes. Please be patient.
|
|
24
|
+
`)),r.async){R(m.length===1?{task_id:m[0]}:{task_ids:m},c);return}let h=r.pollInterval??15,g=Math.max(n.timeout,600),_=await Promise.all(m.map(t=>H(e.client,n,{url:e.client.url(M(t)),intervalSec:h,timeoutSec:g,isComplete:e=>e.output.task_status===`SUCCEEDED`,isFailed:e=>e.output.task_status===`FAILED`,getStatus:e=>e.output.task_status,getErrorMessage:e=>{let t=e.output;return t.message||t.code||void 0}}))),v=[];for(let e=0;e<_.length;e++){let t=_[e],n=t.output.video_url||t.output.results&&t.output.results[0]?.url;n&&v.push({taskId:m[e],videoUrl:n})}if(v.length===0)throw new t(`All tasks completed but no video URLs returned.`,a.GENERAL);if(r.download){let e=r.download,{size:t}=await I(v[0].videoUrl,e,{quiet:n.quiet});n.quiet?L(e):R({task_id:v[0].taskId,video_url:v[0].videoUrl,status:`SUCCEEDED`,saved:e,size:ot(t)},c);return}let y=await import(`path`),b=A(n,{subDir:`videos`}),x=[];await Promise.all(v.map(async({taskId:e,videoUrl:t})=>{let r=y.join(b,`${e}.mp4`);await I(t,r,{quiet:n.quiet}),x.push({task_id:e,video_url:t,saved:r})})),x.length===1?R(x[0],c):R({videos:x,total:x.length},c)}}),Sn=x({description:`Reference-to-video generation (happyhorse-1.1-r2v / wan2.6-r2v): multi-subject, multi-shot with voice`,auth:`apiKey`,usageArgs:`--prompt <text> --image <url>... [--ref-video <url>...] [flags]`,flags:{model:{type:`string`,valueHint:`<model>`,description:`Model ID (default: happyhorse-1.1-r2v)`},prompt:{type:`string`,valueHint:`<text>`,description:`Video description with reference markers (image1, video1, etc.)`,required:!0},image:{type:`array`,valueHint:`<url>`,description:`Reference image URL or local file (repeatable for multiple subjects)`},refVideo:{type:`array`,valueHint:`<url>`,description:`Reference video URL or local file (repeatable)`},imageVoice:{type:`array`,valueHint:`<url>`,description:`Voice URL for corresponding image (pairs by position)`},videoVoice:{type:`array`,valueHint:`<url>`,description:`Voice URL for corresponding ref-video (pairs by position)`},resolution:{type:`string`,valueHint:`<res>`,description:`Resolution: 720P or 1080P (default: 1080P)`},ratio:{type:`string`,valueHint:`<ratio>`,description:`Aspect ratio (16:9, 9:16, 1:1)`},duration:{type:`number`,valueHint:`<seconds>`,description:`Video duration in seconds (default: 5)`},promptExtend:{type:`boolean`,valueHint:`<bool>`,description:Xe},watermark:{type:`boolean`,valueHint:`<bool>`,description:N},seed:{type:`number`,valueHint:`<n>`,description:`Random seed for reproducible generation`},download:{type:`string`,valueHint:`<path>`,description:`Save video to file on completion`},...e,...n,pollInterval:{type:`number`,valueHint:`<seconds>`,description:`Polling interval when waiting (default: 15)`}},exampleArgs:[`--prompt "Image1 running on the grass" --image person.jpg`,`--prompt "Video 1 plays guitar, Image 1 walks over" --ref-video scene.mp4 --image person.jpg`,`--prompt "Image 1 speaks" --image person.jpg --image-voice voice.mp3 --resolution 1080P`,`--prompt "Image 1 and Image 2 have a conversation" --image a.jpg --image b.jpg --image-voice va.mp3 --image-voice vb.mp3`,`--prompt "Image 1 drinks water" --image person.jpg --watermark false`],validate:e=>!e.image?.length&&!e.refVideo?.length?`Provide at least one --image or --ref-video.`:void 0,async run(e){let{settings:n,flags:r}=e,i=r.prompt,o=r.image||[],s=r.refVideo||[],c=r.imageVoice||[],l=r.videoVoice||[],u=r.model||`happyhorse-1.1-r2v`,d=w(n.output),f=[];for(let t=0;t<o.length;t++){let n={type:`reference_image`,url:await e.client.uploadFile(o[t],u)};c[t]&&(n.reference_voice=await e.client.uploadFile(c[t],u)),f.push(n)}for(let t=0;t<s.length;t++){let n={type:`reference_video`,url:await e.client.uploadFile(s[t],u)};l[t]&&(n.reference_voice=await e.client.uploadFile(l[t],u)),f.push(n)}let p=k(r.promptExtend,void 0,`prompt-extend`),m=j(r.watermark),h={model:u,input:{prompt:i,media:f},parameters:{resolution:r.resolution||void 0,ratio:r.ratio||void 0,duration:r.duration||void 0,prompt_extend:p,watermark:m,seed:r.seed}};if(n.dryRun){R({request:h},d);return}let g=(await U(B(r),n,()=>e.client.requestJson({path:Je(),method:`POST`,body:h,async:!0}),`tasks`)).map(e=>e.output.task_id);if(n.quiet||(process.stderr.write(`[Model: ${u}]\n`),process.stderr.write(`Note: Reference-to-video typically takes 5-10 minutes. Please be patient.
|
|
25
|
+
`)),r.async){R(g.length===1?{task_id:g[0]}:{task_ids:g},d);return}let _=r.pollInterval??15,v=Math.max(n.timeout,600),y=await Promise.all(g.map(t=>H(e.client,n,{url:e.client.url(M(t)),intervalSec:_,timeoutSec:v,isComplete:e=>e.output.task_status===`SUCCEEDED`,isFailed:e=>e.output.task_status===`FAILED`,getStatus:e=>e.output.task_status,getErrorMessage:e=>{let t=e.output;return t.message||t.code||void 0}}))),b=[];for(let e=0;e<y.length;e++){let t=y[e],n=t.output.video_url||t.output.results&&t.output.results[0]?.url;n&&b.push({taskId:g[e],videoUrl:n})}if(b.length===0)throw new t(`All tasks completed but no video URLs returned.`,a.GENERAL);if(r.download){let e=r.download,{size:t}=await I(b[0].videoUrl,e,{quiet:n.quiet});n.quiet?L(e):R({task_id:b[0].taskId,video_url:b[0].videoUrl,status:`SUCCEEDED`,saved:e,size:ot(t)},d);return}let{join:x}=await import(`path`),S=A(n,{subDir:`videos`}),C=[];await Promise.all(b.map(async({taskId:e,videoUrl:t})=>{let r=x(S,`${e}.mp4`);await I(t,r,{quiet:n.quiet}),C.push({task_id:e,video_url:t,saved:r})})),C.length===1?R(C[0],d):R({videos:C,total:C.length},d)}}),Cn=x({description:`Query async task status`,auth:`apiKey`,usageArgs:`--task-id <id>`,flags:{taskId:{type:`string`,valueHint:`<id>`,description:`Async task ID`,required:!0}},exampleArgs:[`--task-id 3b256896-3e70-xxxx-xxxx-xxxxxxxxxxxx`,`--task-id 3b256896-3e70-xxxx --output json`],async run(e){let{settings:t,flags:n}=e,r=n.taskId,i=w(t.output);if(t.dryRun){R({task_id:r},i);return}let a=await e.client.requestJson({path:M(r)});if(t.quiet){L(a.output.task_status);return}R({task_id:a.output.task_id,task_status:a.output.task_status,video_url:a.output.video_url,results:a.output.results,submit_time:a.output.submit_time,end_time:a.output.end_time},i)}}),wn=x({description:`Download a completed video by task ID`,auth:`apiKey`,usageArgs:`--task-id <id> --out <path>`,flags:{taskId:{type:`string`,valueHint:`<id>`,description:`Task ID to download from`,required:!0},out:{type:`string`,valueHint:`<path>`,description:`Output file path`,required:!0}},exampleArgs:[`--task-id 3b256896-xxxx --out video.mp4`,`--task-id 3b256896-xxxx --out video.mp4 --quiet`],async run(e){let{settings:n,flags:r}=e,i=r.taskId,o=r.out,s=w(n.output);if(n.dryRun){R({task_id:i,action:`download`,out:o},s);return}let c=await e.client.requestJson({path:M(i)});if(c.output.task_status!==`SUCCEEDED`)throw new t(`Task is not complete (status: ${c.output.task_status}).`,a.GENERAL,`Wait for the task to complete before downloading.`);let l=c.output.video_url||c.output.results&&c.output.results[0]?.url;if(!l)throw new t(`No download URL available for this task.`,a.GENERAL);let{size:u}=await I(l,o,{quiet:n.quiet});if(n.quiet){L(o);return}R({saved:o,size:ot(u)},s)}});const Tn={".jpg":`image/jpeg`,".jpeg":`image/jpeg`,".png":`image/png`,".webp":`image/webp`},En=new Set([`.mp4`,`.mov`,`.avi`,`.mkv`,`.webm`,`.flv`,`.wmv`]);function Dn(e){let t=bt(e).toLowerCase().split(`?`)[0];return!!(En.has(t)||/\.(mp4|mov|avi|mkv|webm|flv|wmv)(\?|$)/i.test(e))}async function On(e){if(e.startsWith(`data:`)||e.startsWith(`http://`)||e.startsWith(`https://`)||e.startsWith(`oss://`))return e;if(!ht(e))throw new t(`File not found: ${e}`,a.USAGE);let n=bt(e).toLowerCase(),r=Tn[n];if(!r)throw new t(`Unsupported image format "${n}". Supported: jpg, jpeg, png, webp`,a.USAGE);return`data:${r};base64,${gt(e).toString(`base64`)}`}var kn=x({description:`Describe an image or video using Qwen-VL`,auth:`apiKey`,usageArgs:`--image <path-or-url> [--video <url>] [--prompt <text>]`,flags:{image:{type:`string`,valueHint:`<path-or-url>`,description:`Local image path or URL`},video:{type:`array`,valueHint:`<url>`,description:`Video file URL or local path (mp4/mov/avi/mkv/webm)`},prompt:{type:`string`,valueHint:`<text>`,description:`Question about the content (default: auto-detected)`},model:{type:`string`,valueHint:`<model>`,description:`Vision model (default: qwen3-vl-plus)`}},exampleArgs:[`--image photo.jpg`,`--image https://example.com/photo.jpg --prompt "What breed is this dog?"`,`--video https://example.com/video.mp4 --prompt "Summarize the video content"`,`--video ./local-video.mp4`,`--image photo.png --prompt "Extract the text" --model qwen3-vl-plus`],validate:e=>!e.image&&!e.video?.length?`Provide --image or --video.`:void 0,async run(e){let{settings:n,flags:r}=e,i=r.image,o=r.video??[],s=r.model||`qwen3-vl-plus`;i&&Dn(i)&&(o.push(i),i=void 0);let c=o.length>0?`Describe the video.`:`Describe the image.`,l=r.prompt||c,u=w(n.output);if(n.dryRun){R({request:{prompt:l,image:i,video:o.length?o:void 0,model:s}},u);return}let d=[];if(o.length>0)for(let n of o){let r=n;if(me(n)){if(!ht(n))throw new t(`Video file not found: ${n}`,a.USAGE);r=await e.client.uploadFile(n,s)}d.push({type:`video_url`,video_url:{url:r}})}if(i){let t=await On(i),n=t;if(me(i)&&t.startsWith(`data:`)){let{statSync:t}=await import(`fs`);t(i).size>5*1024*1024&&(n=await e.client.uploadFile(i,s))}d.push({type:`image_url`,image_url:{url:n}})}d.push({type:`text`,text:l});let f={model:s,messages:[{role:`user`,content:d}]},p=await e.client.requestJson({path:v(),method:`POST`,body:f}),m=p.choices?.[0]?.message?.content;if(u!==`text`){R(p,u);return}L(m||``)}}),An=x({description:`Display current configuration`,auth:`none`,exampleArgs:[``,`--output json`],async run(e){let{settings:t,client:n}=e,r=e.configStore(),i=r.read(),a=w(t.output),o={...i,base_url:n.baseUrl,output:t.output,timeout:t.timeout,config_file:r.path};typeof o.api_key==`string`&&(o.api_key=D(o.api_key)),typeof o.access_token==`string`&&(o.access_token=D(o.access_token)),typeof o.access_key_id==`string`&&(o.access_key_id=D(o.access_key_id)),typeof o.access_key_secret==`string`&&(o.access_key_secret=D(o.access_key_secret)),R(o,a)}});const jn=[`base_url`,`output`,`output_dir`,`timeout`,`api_key`,`access_token`,`access_key_id`,`access_key_secret`,`default_text_model`,`default_video_model`,`default_image_model`,`default_speech_model`,`default_omni_model`,`workspace_id`],Mn=new Set([`api_key`,`access_token`,`access_key_id`,`access_key_secret`]),Nn={"base-url":`base_url`,"output-dir":`output_dir`,"api-key":`api_key`,"access-token":`access_token`,"access-key-id":`access_key_id`,"access-key-secret":`access_key_secret`,"default-text-model":`default_text_model`,"default-video-model":`default_video_model`,"default-image-model":`default_image_model`,"default-speech-model":`default_speech_model`,"default-omni-model":`default_omni_model`,"workspace-id":`workspace_id`};var Pn=x({description:`Set a config value`,auth:`none`,usageArgs:`--key <key> --value <value>`,flags:{key:{type:`string`,valueHint:`<key>`,description:`Config key (base_url, output, output_dir, timeout, api_key, access_token, access_key_id, access_key_secret, default_*_model, workspace_id)`,required:!0},value:{type:`string`,valueHint:`<value>`,description:`Value to set`,required:!0}},exampleArgs:[`--key output --value json`,`--key timeout --value 600`,`--key base_url --value https://dashscope.aliyuncs.com`],async run(e){let{settings:n,flags:r}=e,i=r.key,o=r.value,s=Nn[i]||i;if(!jn.includes(s))throw new t(`Invalid config key "${i}". Valid keys: ${jn.join(`, `)}`,a.USAGE);if(s===`output`&&![`text`,`json`].includes(o))throw new t(`Invalid output format "${o}". Valid values: text, json`,a.USAGE);if(s===`timeout`){let e=Number(o);if(isNaN(e)||e<=0)throw new t(`Invalid timeout "${o}". Must be a positive number.`,a.USAGE)}let c=w(n.output);if(n.dryRun){R({would_set:{[s]:o}},c);return}let l=s===`timeout`?Number(o):o;if(await e.configStore().write({[s]:l}),!n.quiet){let e=Mn.has(s)?D(String(l)):l;R({[s]:e},c)}}});const Fn=`npx skills add modelstudioai/cli --all -g -y`;function In(e){return{cmd:`npm install -g ${e}@latest`,label:`npm`}}function Ln(e){process.stderr.write(`
|
|
34
26
|
Updating agent skill...
|
|
35
|
-
`);try{
|
|
36
|
-
`);let
|
|
27
|
+
`);try{xt(Fn,{stdio:`inherit`}),process.stderr.write(`${e.green(`✓ Agent skill updated.`)}\n`)}catch{process.stderr.write(`${e.yellow(`Agent skill update skipped. Run manually: ${Fn}`)}\n`)}}var Rn=x({description:`Update the CLI to the latest version`,auth:`none`,exampleArgs:[``],async run(e){let{identity:t}=e,n=t.npmPackage,r=t.binName,i=t.version,a=P(process.stderr);process.stderr.write(`Current version: ${a.yellow(i)}\n`),process.stderr.write(`Checking for updates...
|
|
28
|
+
`);let o=await at(5e3,n);if(o&&o===i){process.stderr.write(`${a.green(`\u2713 Already up to date (${i}).`)}\n`),Ln(a);return}o&&process.stderr.write(`Latest version: ${a.green(o)}\n\n`);let{cmd:s,label:c}=In(n);process.stderr.write(`Updating ${n} via ${c}...\n\n`);try{xt(s,{stdio:`inherit`});try{let e=xt(`${r} --version 2>/dev/null`,{encoding:`utf-8`}).trim().replace(RegExp(`^${r}\\s+`),``);process.stderr.write(`\n${a.green(`\u2713 Update complete: ${i} \u2192 ${e}`)}\n`);try{vt(W(ae(),`update-state.json`),JSON.stringify({lastChecked:Date.now(),latestVersion:e}))}catch{}}catch{process.stderr.write(`\n${a.green(`✓ Update complete.`)}\n`)}Ln(a)}catch{process.stderr.write(`
|
|
37
29
|
Automatic update failed. Please run manually:
|
|
38
|
-
`),process.stderr.write(` ${
|
|
39
|
-
`),process.exit(1)}if(e.dryRun){G({endpoint:u(e.baseUrl,n),request:o},a);return}let l=u(e.baseUrl,n);if(i){let n=await j(e,{url:l,method:`POST`,body:o,headers:{"X-DashScope-SSE":`enable`},stream:!0}),r=``,i=``,s=a===`text`,c=e.noColor?``:`\x1B[2m`,u=e.noColor?``:`\x1B[0m`;for await(let e of k(n)){if(e.data===`[DONE]`)break;try{let n=JSON.parse(e.data),a=n.output?.text;if(a&&(s&&process.stdout.write(a),r+=a),n.output?.session_id&&(i=n.output.session_id),n.output?.thoughts&&t.hasThoughts)for(let e of n.output.thoughts)e.thought&&process.stderr.write(`${c}[Thinking] ${e.thought}${u}\n`),e.action_name&&process.stderr.write(`${c}[Action] ${e.action_name}: ${e.action_input||``}${u}\n`),e.observation&&process.stderr.write(`${c}[Observation] ${e.observation}${u}\n`)}catch{}}i&&!e.quiet&&process.stderr.write(`${c}Session ID: ${i}${u}\n`),a===`json`?G({text:r,session_id:i},a):process.stdout.write(`
|
|
40
|
-
`)}
|
|
41
|
-
`),
|
|
42
|
-
`)
|
|
43
|
-
`),
|
|
44
|
-
`)
|
|
45
|
-
`),process.
|
|
46
|
-
`)
|
|
47
|
-
|
|
48
|
-
Legacy (deprecated): set ALIBABA_CLOUD_ACCESS_KEY_ID / ALIBABA_CLOUD_ACCESS_KEY_SECRET.`,i.AUTH);if(!l)throw new e(`Knowledge retrieve requires a workspace ID.
|
|
49
|
-
Set via: --workspace-id flag, or env: BAILIAN_WORKSPACE_ID, or config: ${t.binName} config set workspace_id <id>`,i.USAGE);process.stderr.write(`Warning: AK/SK auth for knowledge retrieve is deprecated. Prefer --api-key or DASHSCOPE_API_KEY.
|
|
50
|
-
`);let u={IndexId:r,Query:a};if(n.topK!==void 0&&n.rerankTopN===void 0&&(process.stderr.write(`Warning: --top-k is deprecated. Use --rerank-top-n instead.
|
|
51
|
-
`),n.rerankTopN=n.topK),n.rerank&&(u.EnableReranking=!0),n.rerankTopN!==void 0&&(u.RerankTopN=n.rerankTopN),n.denseSimilarityTopK!==void 0&&(u.DenseSimilarityTopK=n.denseSimilarityTopK),n.sparseSimilarityTopK!==void 0&&(u.SparseSimilarityTopK=n.sparseSimilarityTopK),n.rerankModel){let e={ModelName:n.rerankModel};n.rerankMode&&(e.RerankMode=n.rerankMode),n.rerankInstruct&&(e.RerankInstruct=n.rerankInstruct),u.Rerank=[e]}let d=`/${l}/index/retrieve`;if(t.dryRun){G({endpoint:`https://${sr}${d}`,workspaceId:l,request:u},o);return}let f=JSON.stringify(u),p=Fe({accessKeyId:s,accessKeySecret:c,action:`Retrieve`,version:`2023-12-29`,body:f,host:sr,pathname:d}),m=`https://${sr}${d}`;t.verbose&&(process.stderr.write(`> POST ${m}\n`),process.stderr.write(`> AK: ${O(s)}\n`));let h=t.timeout*1e3,g=await fetch(m,{method:`POST`,headers:{...p,...Be()},body:f,signal:AbortSignal.timeout(h)});t.verbose&&process.stderr.write(`< ${g.status} ${g.statusText}\n`);let _=await g.json();if(!g.ok||_.Code&&_.Code!==`Success`)throw new e(`Knowledge retrieve failed: ${_.Code||g.status} - ${_.Message||g.statusText}`,i.GENERAL);let v=_.Data?.Nodes||[];t.quiet||o===`text`?dr(v.map(e=>({text:e.Text,score:e.Score}))):G(_,o)}function dr(e){if(e.length===0)W(`No results found.`);else for(let t=0;t<e.length;t++){let n=e[t];W(`[${t+1}] (score: ${n.score.toFixed(4)})`),W(n.text),W(``)}}var fr=y({description:`Search a Bailian knowledge base (RAG semantic retrieval)`,skipDefaultApiKeySetup:!0,usageArgs:`--query <text> --agent-id <id> [flags]`,options:[{flag:`--query <text>`,description:`Search query text (required, cannot be empty)`,required:!0},{flag:`--agent-id <id>`,description:`Retrieval service ID (find in console knowledge retrieval page)`,required:!0},{flag:`--workspace-id <id>`,description:`Workspace ID for API endpoint URL (or set BAILIAN_WORKSPACE_ID)`},{flag:`--image <url>`,description:`Image URL for multimodal retrieval (repeatable)`,type:`array`},{flag:`--query-history <json>`,description:`User conversation history JSON for context understanding and query rewriting. Format: '[{"role":"user","content":"What is RAG"},{"role":"assistant","content":"RAG is..."}]'`}],notes:[`Retrieval scope and strategy (multi-index weighting, routing, reranking, etc.) are driven by the agent_id service config. Only query and agent_id are required.`,`Auth: uses DashScope API Key (Bearer token). Get yours from the console API Key page.`,"`--workspace-id` can be set via BAILIAN_WORKSPACE_ID env or `kscli config set workspace_id <id>`.","`--query-history` passes prior conversation turns; the server rewrites the query based on context to improve retrieval relevance."],exampleArgs:[`--query "What is RAG?" --agent-id aid-xxx --workspace-id ws-xxx`,`--api-key $DASHSCOPE_API_KEY --query "test search" --agent-id aid-xxx --workspace-id ws-xxx --image https://example.com/img.jpg`,`--query "How does it work" --agent-id aid-xxx --workspace-id ws-xxx --query-history '[{"role":"user","content":"What is RAG"},{"role":"assistant","content":"RAG is retrieval-augmented generation"}]'`],async run(t,n){let r=n.query;if(!r)if(D({nonInteractive:t.nonInteractive})){let e=await Z({message:`Enter your search query:`});e||(process.stderr.write(`Search cancelled.
|
|
52
|
-
`),process.exit(1)),r=e}else K(`query`,V(t,`--query <text> --agent-id <id>`));let a=n.agentId;a||K(`agent-id`,V(t,`--query <text> --agent-id <id>`));let o=n.workspaceId||t.workspaceId;if(!o)throw new e(`Workspace ID is required.`,i.USAGE,`Pass --workspace-id, set BAILIAN_WORKSPACE_ID env, or configure: kscli config set workspace_id <id>`);let s=C(t.output),c={query:r,agent_id:a},l=n.image;if(l&&l.length>0&&(c.images=l),n.queryHistory)try{c.query_history=JSON.parse(n.queryHistory)}catch{throw new e(`--query-history must be valid JSON. Example: --query-history '[{"role":"user","content":"What is RAG"}]'`,i.USAGE)}let u=ge(o);if(t.dryRun){G({endpoint:u,request:c},s);return}let d=await M(t,{url:u,method:`POST`,body:c}),f=d.data?.nodes||[];if(t.quiet||s===`text`)if(f.length===0)W(`No results found.`);else for(let e=0;e<f.length;e++){let t=f[e];W(`[${e+1}] (score: ${t.score.toFixed(4)})`),W(t.text),W(``)}else G(d,s)}});function pr(e){let t=[];if(e.message){let n=new Set([`user`,`assistant`]),r=e.message;for(let e of r){if(e.startsWith(`{`))try{let r=JSON.parse(e);if(r.role&&n.has(r.role)&&r.content!==void 0){t.push(r);continue}}catch{}let r=e.indexOf(`:`),i=r===-1?``:e.slice(0,r);n.has(i)?t.push({role:i,content:e.slice(r+1)}):t.push({role:`user`,content:e})}}return t}function mr(e){for(let t of e)if(Array.isArray(t.content)&&t.content.some(e=>e.type===`image_url`))return!0;return!1}function hr(e,t){let n=-1;for(let t=e.length-1;t>=0;t--)if(e[t].role===`user`){n=t;break}n===-1&&(e.push({role:`user`,content:``}),n=e.length-1);let r=e[n],i=[];typeof r.content==`string`?i.push({type:`text`,text:r.content}):i.push(...r.content);for(let e of t)i.push({type:`image_url`,image_url:{url:e}});r.content=i}const gr={tool_calling:`🔍 Retrieving...`,plan_start:`🤔 Planning...`,generation_start:`✍️ Generating...`};var _r=y({description:`Chat with a Bailian knowledge base (RAG Q&A with streaming)`,skipDefaultApiKeySetup:!0,usageArgs:`--message <text> --agent-id <id> [flags]`,options:[{flag:`--message <text>`,description:`Message text (repeatable). Supports role:content prefix to set role (e.g. user:hello), defaults to user. Follows OpenAI message format`,required:!0,type:`array`},{flag:`--agent-id <id>`,description:`Q&A service ID (find in console knowledge Q&A page)`,required:!0},{flag:`--workspace-id <id>`,description:`Workspace ID for API endpoint URL (or set BAILIAN_WORKSPACE_ID)`},{flag:`--image <url>`,description:`Image URL (repeatable). Attached to the last user message as multimodal content`,type:`array`}],notes:[`Response is returned as SSE stream events. Event lifecycle: tool_calling → tool_return → plan_start → planning → plan_end → generation_start → generating → generation_end. tool_calling → tool_return may loop multiple times.`,`Auth: uses DashScope API Key (Bearer token). Get yours from the console API Key page.`,"`--workspace-id` can be set via BAILIAN_WORKSPACE_ID env or `kscli config set workspace_id <id>`.",`Multi-turn: use --message "user:..." and --message "assistant:..." to pass conversation history.`],exampleArgs:[`--message "What is RAG?" --agent-id aid-xxx --workspace-id ws-xxx`,`--message "user:What is RAG?" --message "assistant:RAG is..." --message "How does it work?" --agent-id aid-xxx --workspace-id ws-xxx`,`--message "Describe these images" --image https://example.com/a.png --image https://example.com/b.png --agent-id aid-xxx --workspace-id ws-xxx`],async run(t,n){let r=pr(n),a=n.image,o=a&&a.length>0;if(r.length===0)if(o)r=[{role:`user`,content:``}];else if(D({nonInteractive:t.nonInteractive})){let e=await Z({message:`Enter your message:`});e||(process.stderr.write(`Chat cancelled.
|
|
53
|
-
`),process.exit(1)),r=[{role:`user`,content:e}]}else K(`message`,V(t,`--message <text> --agent-id <id>`));let s=n.agentId;s||K(`agent-id`,V(t,`--message <text> --agent-id <id>`));let c=n.workspaceId||t.workspaceId;if(!c)throw new e(`Workspace ID is required.`,i.USAGE,`Pass --workspace-id, set BAILIAN_WORKSPACE_ID env, or configure: kscli config set workspace_id <id>`);let l=C(t.output),u=l===`text`&&!!process.stdout.isTTY;if(o){if(mr(r))throw new e(`Cannot use --image when messages already contain embedded image_url content parts. Use one approach or the other.`,i.USAGE);hr(r,a)}let d={input:{messages:r},parameters:{agent_options:{agent_id:s}},stream:!0},f=me(c);if(t.dryRun){G({endpoint:f,request:d},l);return}let p=await j(t,{url:f,method:`POST`,body:d,stream:!0});if(u){let n=``,r=t.noColor?``:`\x1B[2m`,a=t.noColor?``:`\x1B[0m`,o=t.verbose;for await(let t of k(p)){if(t.data===`[DONE]`)break;if(t.event===`error`){let n=`Chat API error`,r;try{let e=JSON.parse(t.data);n=e.message||n,r=e.code}catch{}throw new e(n,i.GENERAL,r?`API error: ${r}`:void 0)}try{let e=JSON.parse(t.data);for(let t of e.output?.choices??[]){let e=t.message;if(e.extra?.step_change){let t=gr[e.extra.step_change];t&&process.stdout.write(`${r}${t}${a}\n`)}if(o&&e.extra?.step_change&&process.stderr.write(`${r}[event] step_change=${e.extra.step_change} step=${e.extra?.step??``} group=${e.extra?.group??``}${a}\n`),e.content&&(n+=e.content,process.stdout.write(e.content)),t.finish_reason===`stop`)break}}catch{}}process.stdout.write(`
|
|
54
|
-
`)}else{let n=``,r=``;for await(let t of k(p)){if(t.data===`[DONE]`)break;if(t.event===`error`){let n=`Chat API error`,r;try{let e=JSON.parse(t.data);n=e.message||n,r=e.code}catch{}throw new e(n,i.GENERAL,r?`API error: ${r}`:void 0)}try{let e=JSON.parse(t.data);e.request_id&&(r=e.request_id);for(let t of e.output?.choices??[])if(t.message?.content&&(n+=t.message.content),t.finish_reason===`stop`)break}catch{}}t.quiet||l===`text`?W(n):G({answer:n,request_id:r},l)}}});function vr(e){let t={};for(let n of e){let e=n.indexOf(`=`);e<=0&&(process.stderr.write(`Error: --arg must be in K=V form, got: ${n}\n`),process.exit(1));let r=n.slice(0,e).trim(),i=n.slice(e+1);try{t[r]=JSON.parse(i)}catch{t[r]=i}}return t}var yr=y({description:`Call a tool on an MCP server (tools/call)`,skipDefaultApiKeySetup:!0,usageArgs:`<server-code>.<tool> [--arg k=v ...] [--json '{...}'] [--url <url>]`,options:[{flag:`<server-code>.<tool>`,description:`Server code and tool name joined by a dot, e.g. market-cmapi00073529.SmartStockSelection`,required:!0},{flag:`--arg <kv>`,description:`Tool argument (repeatable). Values parsed as JSON if possible, else string.`,type:`array`},{flag:`--json <obj>`,description:`Full arguments object as JSON; merged with --arg (arg wins).`},{flag:`--query <text>`,description:`Shortcut for --arg query=<text> (mirrors many DashScope MCP tools).`},{flag:`--url <url>`,description:`Override the MCP endpoint URL (for non-Bailian servers)`}],exampleArgs:[`market-cmapi00073529.SmartStockSelection --query "Screen consumer stocks with ROE > 15%"`,`market-cmapi00073529.FinQuery --json '{"q":"Guizhou Maotai","limit":5}'`,`market-cmapi00073529.SmartFundSelection --arg riskLevel=R3 --arg minScale=10`],async run(e,t){let n=(t._positional??[])[0];n||K(`<server-code>.<tool>`,V(e,`<server-code>.<tool>`));let r=n.indexOf(`.`);(r<=0||r===n.length-1)&&(process.stderr.write(`Error: target must be <server-code>.<tool>, got "${n}".\n`),process.exit(1));let i=n.slice(0,r),a=n.slice(r+1),s={};if(t.json)try{let e=JSON.parse(t.json);(!e||typeof e!=`object`||Array.isArray(e))&&(process.stderr.write(`Error: --json must decode to an object.
|
|
55
|
-
`),process.exit(1)),s=e}catch(e){process.stderr.write(`Error: --json is not valid JSON — ${e.message}\n`),process.exit(1)}Object.assign(s,vr(t.arg??[])),t.query!==void 0&&(s.query=t.query);let c=t.url||d(e.baseUrl,i),l=C(e.output);if(e.dryRun){G({server:i,url:c,tool:a,arguments:s},l);return}await it(e);let u=new o(e,c);await u.initialize();let f=await u.callTool(a,s);if(f.isError){let e=f.content.map(e=>e.text||``).join(`
|
|
56
|
-
`);process.stderr.write(`Tool error: ${e}\n`),process.exit(1)}G(f,l)}});const br=`zeldaEasy.broadscope-bailian.mcp-server.PageList`;var xr=y({description:`List MCP servers activated under your Bailian account`,skipDefaultApiKeySetup:!0,usageArgs:`[flags]`,options:[{flag:`--name <text>`,description:`Filter by server name (substring match)`},{flag:`--type <type>`,description:`Server type: OFFICIAL | PRIVATE (default: OFFICIAL)`},{flag:`--page <n>`,description:`Page number (default: 1)`,type:`number`},{flag:`--page-size <n>`,description:`Results per page (default: 30)`,type:`number`},{flag:`--console-region <region>`,description:`Console region`},{flag:`--console-site <site>`,description:`Console site: domestic, international`},{flag:`--console-switch-agent <uid>`,description:`Switch agent UID`,type:`number`}],exampleArgs:[``,`--name finance`,`--output json`],async run(t,n){let r=n.name||``,a=n.type||`OFFICIAL`,o=n.page||1,s=n.pageSize||30,c=C(t.output),l={reqDTO:{type:a,displayTools:!1,activated:1,pageNo:o,pageSize:s,serverName:r}};if(t.dryRun){G({api:br,data:l,...w(t)},c);return}let u=(await p(t,(await P(t)).token,{api:br,data:l}))?.data??{};if(u.success===!1){let n=u.errorCode??`UnknownError`,r=u.errorMsg??n,a=n===`BailianGateway.Login.NotLogined`?`Run \`${t.binName} auth login --console\` to refresh your console session.`:void 0;throw new e(`Console gateway: ${r}`,i.AUTH,a)}let d=(u.DataV2??{}).data?.data??{},f=d.mcpServerDetailList??[];G({total:d.total??0,servers:f.map(e=>({code:e.serverCode??``,name:e.serverName??``,description:e.description,type:e.type??``,source:e.source,bizType:e.bizType,installType:e.installType,streamable:e.streamable===!0}))},c)}}),Sr=y({description:`List tools exposed by an MCP server (tools/list)`,skipDefaultApiKeySetup:!0,usageArgs:`<server-code> [--url <url>]`,options:[{flag:`<server-code>`,description:"Server code from `mcp list` (e.g. market-cmapi00073529)",required:!0},{flag:`--url <url>`,description:`Override the MCP endpoint URL (for non-Bailian servers)`}],exampleArgs:[`market-cmapi00073529`,`market-cmapi00073529 --output json`,`my-server --url https://example.com/mcp`],async run(e,t){let n=(t._positional??[])[0];n||K(`server-code`,V(e,`<server-code>`));let r=t.url||d(e.baseUrl,n),i=C(e.output);if(e.dryRun){G({server:n,url:r,action:`tools/list`},i);return}await it(e);let a=new o(e,r);await a.initialize(),G({server:n,url:r,tools:await a.listTools()},i)}}),Cr=y({description:`Search the web using DashScope MCP WebSearch service`,usageArgs:`--query <text> [flags]`,options:[{flag:`--query <text>`,description:`Search query text`,required:!0},{flag:`--count <n>`,description:`Number of search results (default: 10)`,type:`number`},{flag:`--list-tools`,description:`List available MCP tools and exit`}],exampleArgs:[`--query "Alibaba Cloud Bailian latest features"`,`--query "TypeScript 5.9 new features" --count 5`,`--query "Today's news"`,`--list-tools`],async run(e,t){let n=Ce(e.baseUrl),r=C(e.output);if(t.listTools){if(e.dryRun){G({endpoint:n,action:`tools/list`},r);return}let t=new o(e,n);await t.initialize(),G({tools:await t.listTools()},r);return}let i=t.query;if(!i)if(D({nonInteractive:e.nonInteractive})){let e=await Z({message:`Enter your search query:`});e||(process.stderr.write(`Search cancelled.
|
|
57
|
-
`),process.exit(1)),i=e}else K(`query`,V(e,`--query <text>`));if(e.dryRun){G({endpoint:n,action:`tools/call`,tool:`bailian_web_search`,arguments:{query:i,count:t.count||void 0}},r);return}let a=new o(e,n),s=nt(`Initializing search...`);e.quiet||s.start();try{await a.initialize(),e.quiet||s.update(`Searching...`);let n={query:i};t.count&&(n.count=t.count);let o=await a.callTool(`bailian_web_search`,n);if(e.quiet||s.stop(`Done.`),o.isError){let e=o.content.map(e=>e.text||``).join(`
|
|
58
|
-
`);process.stderr.write(`Search error: ${e}\n`),process.exit(1)}if(r===`json`)G(o,r);else for(let e of o.content)if(e.type===`text`&&e.text)try{let t=JSON.parse(e.text);t.pages&&Array.isArray(t.pages)?G({pages:t.pages,total:t.pages.length},r):G(t,r)}catch{G({text:e.text},r)}}catch(e){throw s.stop(`Failed.`),e}}});const wr=`${r.cn}/cosyvoice-clone-design-api`,Tr=[{voice:`longanyang`,name:`龙安洋`,desc:`阳光大男孩`,lang:`中文/英文`},{voice:`longanhuan_v3`,name:`龙安欢`,desc:`欢脱元气女`,lang:`中文/英文`},{voice:`longantai_v3`,name:`龙安台`,desc:`嗲甜台湾女`,lang:`中文/英文`},{voice:`longhua_v3`,name:`龙华`,desc:`元气甜美女`,lang:`中文/英文`},{voice:`longcheng_v3`,name:`龙橙`,desc:`智慧青年男`,lang:`中文/英文`},{voice:`longze_v3`,name:`龙泽`,desc:`温暖元气男`,lang:`中文/英文`},{voice:`longzhe_v3`,name:`龙哲`,desc:`呆板大暖男`,lang:`中文/英文`},{voice:`longyan_v3`,name:`龙颜`,desc:`温暖春风女`,lang:`中文/英文`},{voice:`longxing_v3`,name:`龙星`,desc:`温婉邻家女`,lang:`中文/英文`},{voice:`longtian_v3`,name:`龙天`,desc:`磁性理智男`,lang:`中文/英文`},{voice:`longwan_v3`,name:`龙婉`,desc:`细腻柔声女`,lang:`中文/英文`},{voice:`longqiang_v3`,name:`龙嫱`,desc:`浪漫风情女`,lang:`中文/英文`},{voice:`longfeifei_v3`,name:`龙菲菲`,desc:`甜美娇气女`,lang:`中文/英文`},{voice:`longhao_v3`,name:`龙浩`,desc:`多情忧郁男`,lang:`中文/英文`},{voice:`longanrou_v3`,name:`龙安柔`,desc:`温柔娴静女`,lang:`中文/英文`},{voice:`longxiaochun_v3`,name:`龙小淳`,desc:`知性积极女`,lang:`中文/英文`},{voice:`longxiaoxia_v3`,name:`龙小夏`,desc:`沉稳权威女`,lang:`中文/英文`},{voice:`longyumi_v3`,name:`YUMI`,desc:`正经青年女`,lang:`中文/英文`},{voice:`longanyun_v3`,name:`龙安昀`,desc:`居家暖男`,lang:`中文/英文`},{voice:`longanwen_v3`,name:`龙安温`,desc:`优雅知性女`,lang:`中文/英文`},{voice:`longanli_v3`,name:`龙安莉`,desc:`利落从容女`,lang:`中文/英文`},{voice:`longanlang_v3`,name:`龙安朗`,desc:`清爽利落男`,lang:`中文/英文`},{voice:`longyingmu_v3`,name:`龙应沐`,desc:`优雅知性女`,lang:`中文/英文`},{voice:`longyingxun_v3`,name:`龙应询`,desc:`年轻青涩男`,lang:`中文/英文`},{voice:`longyingjing_v3`,name:`龙应静`,desc:`低调冷静女`,lang:`中文/英文`},{voice:`longyingling_v3`,name:`龙应聆`,desc:`温和共情女`,lang:`中文/英文`},{voice:`longyingtao_v3`,name:`龙应桃`,desc:`温柔淡定女`,lang:`中文/英文`},{voice:`longyingxiao_v3`,name:`龙应笑`,desc:`清甜推销女`,lang:`中文/英文`},{voice:`longfei_v3`,name:`龙飞`,desc:`热血磁性男`,lang:`中文/英文`},{voice:`longhuhu_v3`,name:`龙呼呼`,desc:`天真烂漫女童`,lang:`中文/英文`},{voice:`longpaopao_v3`,name:`龙泡泡`,desc:`飞天泡泡音`,lang:`中文/英文`},{voice:`longjielidou_v3`,name:`龙杰力豆`,desc:`阳光顽皮男`,lang:`中文/英文`},{voice:`longxian_v3`,name:`龙仙`,desc:`豪放可爱女`,lang:`中文/英文`},{voice:`longling_v3`,name:`龙铃`,desc:`稚气呆板女`,lang:`中文/英文`},{voice:`longshanshan_v3`,name:`龙闪闪`,desc:`戏剧化童声`,lang:`中文/英文`},{voice:`longniuniu_v3`,name:`龙牛牛`,desc:`阳光男童声`,lang:`中文/英文`},{voice:`longjiaxin_v3`,name:`龙嘉欣`,desc:`优雅粤语女`,lang:`粤语/英文`},{voice:`longjiayi_v3`,name:`龙嘉怡`,desc:`知性粤语女`,lang:`粤语/英文`},{voice:`longanyue_v3`,name:`龙安粤`,desc:`欢脱粤语男`,lang:`粤语/英文`},{voice:`longlaotie_v3`,name:`龙老铁`,desc:`东北直率男`,lang:`东北话/英文`},{voice:`longshange_v3`,name:`龙陕哥`,desc:`原味陕北男`,lang:`陕西话/英文`},{voice:`longanmin_v3`,name:`龙安闽`,desc:`清纯萝莉女`,lang:`闽南话/英文`},{voice:`loongabby_v3`,name:`loongabby`,desc:`美式英文女`,lang:`美式英语`},{voice:`loongandy_v3`,name:`loongandy`,desc:`美式英文男`,lang:`美式英语`},{voice:`loongannie_v3`,name:`loongannie`,desc:`美式英文女`,lang:`美式英语`},{voice:`loongava_v3`,name:`loongava`,desc:`美式英文女`,lang:`美式英语`},{voice:`loongbeth_v3`,name:`loongbeth`,desc:`美式英文女`,lang:`美式英语`},{voice:`loongbetty_v3`,name:`loongbetty`,desc:`美式英文女`,lang:`美式英语`},{voice:`loongcally_v3`,name:`loongcally`,desc:`美式英文女`,lang:`美式英语`},{voice:`loongcindy_v3`,name:`loongcindy`,desc:`美式英文女`,lang:`美式英语`},{voice:`loongdavid_v3`,name:`loongdavid`,desc:`美式英文男`,lang:`美式英语`},{voice:`loongdonna_v3`,name:`loongdonna`,desc:`美式英文女`,lang:`美式英语`},{voice:`loongemily_v3`,name:`loongemily`,desc:`英式英文女`,lang:`英式英语`},{voice:`loongeric_v3`,name:`loongeric`,desc:`英式英文男`,lang:`英式英语`},{voice:`loongluna_v3`,name:`loongluna`,desc:`英式英文女`,lang:`英式英语`},{voice:`loongluca_v3`,name:`loongluca`,desc:`英式英文男`,lang:`英式英语`},{voice:`loongriko_v3`,name:`Riko`,desc:`二次元霓虹女`,lang:`日语`},{voice:`loongtomoka_v3`,name:`loongtomoka`,desc:`日语女`,lang:`日语`},{voice:`loongtomoya_v3`,name:`loongtomoya`,desc:`日语男`,lang:`日语`},{voice:`loongyuuna_v3`,name:`Yuuna`,desc:`日语女`,lang:`日语`},{voice:`loongyuuma_v3`,name:`Yuuma`,desc:`日语男`,lang:`日语`},{voice:`loongkyong_v3`,name:`loongkyong`,desc:`韩语女`,lang:`韩语`},{voice:`loongjihun_v3`,name:`Jihun`,desc:`韩语男`,lang:`韩语`},{voice:`loongindah_v3`,name:`loongindah`,desc:`印尼女`,lang:`印尼语`}],Er={"cosyvoice-v3-flash":Tr,"cosyvoice-v3-plus":Tr,"cosyvoice-v3.5-flash":[],"cosyvoice-v3.5-plus":[],"cosyvoice-v2":[]};function Dr(e){let t=Er[e];if(!t){process.stdout.write(`No built-in voice list available for model: ${e}\n`),process.stdout.write(`Browse voices in the console: ${$e}\n`);return}if(t.length===0){process.stdout.write(`Model ${e} has no system voices.\n`),process.stdout.write(`Use clone or design voices created via the CosyVoice API.
|
|
59
|
-
`),process.stdout.write(`See: ${wr}\n`),process.stdout.write(`Browse voices in the console: ${$e}\n`);return}let n=(e,t)=>e.padEnd(t);process.stdout.write(`\nSystem voices for ${e}:\n`),process.stdout.write(`${n(`VOICE ID`,26)} ${n(`NAME`,10)} ${n(`DESCRIPTION`,16)} LANGUAGE\n`),process.stdout.write(`${`-`.repeat(26)} ${`-`.repeat(10)} ${`-`.repeat(16)} ${`-`.repeat(12)}\n`);for(let e of t)process.stdout.write(`${n(e.voice,26)} ${n(e.name,10)} ${n(e.desc,16)} ${e.lang}\n`);process.stdout.write(`\nTotal: ${t.length} voices\n`),process.stdout.write(`Preview and browse more voices in the console: \n${$e}\n`)}var Or=y({description:`Synthesize speech from text (CosyVoice TTS)`,usageArgs:`--text <text> [flags]`,options:[{flag:`--text <text>`,description:`Text to synthesize into speech`,required:!0},{flag:`--text-file <path>`,description:`Read text from a file instead of --text`},{flag:`--model <model>`,description:`Model ID (default: cosyvoice-v3-flash). System voices available for cosyvoice-v3-flash`},{flag:`--voice <voice>`,description:`Voice ID. Use --list-voices to see built-in voices for cosyvoice-v3-flash; for v3.5-flash provide a clone/design voice ID`},{flag:`--list-voices`,description:`List built-in system voices for the selected model and exit (console link shown in output)`},{flag:`--format <format>`,description:`Audio format: mp3, pcm, wav, opus (default: mp3)`},{flag:`--sample-rate <rate>`,description:`Audio sample rate in Hz (e.g. 24000)`},{flag:`--volume <volume>`,description:`Volume 0-100 (default: 50)`},{flag:`--rate <rate>`,description:`Speech rate 0.5-2.0 (default: 1.0)`},{flag:`--pitch <pitch>`,description:`Pitch multiplier 0.5-2.0 (default: 1.0)`},{flag:`--seed <seed>`,description:`Random seed 0-65535 for reproducible synthesis`},{flag:`--language <lang>`,description:`Language hint (e.g. zh, en, ja, ko, fr, de)`},{flag:`--instruction <text>`,description:`Natural language instruction to control speech style (e.g. "Use a gentle tone")`},{flag:`--enable-ssml`,description:`Enable SSML markup parsing in input text`},{flag:`--out <path>`,description:`Save audio to file (default: auto-generate in temp dir)`},{flag:`--stream`,description:`Stream raw PCM audio to stdout (pipe to player)`}],exampleArgs:[`--list-voices --model cosyvoice-v3-flash`,`--text "Hello, I am Qwen" --voice <voice_id>`,`--text "Hello world" --voice <voice_id> --language en`,`--text-file script.txt --out speech.wav --voice <voice_id>`,`--text "Today is a good day" --voice <voice_id> --instruction "Use a gentle tone"`,`--text "Hello" --voice <voice_id> --format wav --sample-rate 24000`,`# Stream to audio player (macOS)`,`--text "Hello" --voice <voice_id> --stream | afplay -`,`# Pipe to ffplay`,`--text "Hello" --voice <voice_id> --stream | ffplay -nodisp -autoexit -f s16le -ar 24000 -ac 1 -`],async run(t,n){let r=n.model||t.defaultSpeechModel||`cosyvoice-v3-flash`;if(n.listVoices){Dr(r);return}let a=n.text;if(!a&&n.textFile){let t=n.textFile;try{a=xt(t,`utf-8`).trim()}catch{throw new e(`Cannot read text file: ${t}`,i.USAGE)}}if(!a)if(D({nonInteractive:t.nonInteractive})){let e=await Z({message:`Enter text to synthesize:`});e||(process.stderr.write(`Speech synthesis cancelled.
|
|
60
|
-
`),process.exit(1)),a=e}else K(`text`,V(t,`--text <text>`));let o=n.voice||void 0;if(!o)if(D({nonInteractive:t.nonInteractive})){let e=Er[r];if(e&&e.length>0){let t=e[0].voice,n=e.map(e=>({value:e.voice,label:`${e.name} (${e.voice})`,hint:`${e.desc} · ${e.lang}`})),r=await ft({message:`Select a voice (default: ${t}):`,choices:n,defaultValue:t});r||(process.stderr.write(`Speech synthesis cancelled.
|
|
61
|
-
`),process.exit(1)),o=r}else{let e=await Z({message:`Enter voice ID (clone/design voice):`});e||(process.stderr.write(`Speech synthesis cancelled.
|
|
62
|
-
`),process.exit(1)),o=e}}else{let n=Er[r];throw n&&n.length>0?new e(`--voice is required.\nRun the following to see available voices:\n ${V(t,`--list-voices --model ${r}`)}\nBrowse more voices: ${$e}`,i.USAGE):new e(`--voice is required. Model ${r} has no built-in system voices.\nCreate a clone or design voice first, then pass its ID via --voice <voice_id>.\nSee: ${wr}`,i.USAGE)}let s=n.language||void 0,c=n.instruction||void 0,l=n.format||void 0,u=n.sampleRate===void 0?void 0:Number(n.sampleRate),d=n.volume===void 0?void 0:Number(n.volume),f=n.rate===void 0?void 0:Number(n.rate),p=n.pitch===void 0?void 0:Number(n.pitch),m=n.seed===void 0?void 0:Number(n.seed),h=n.enableSsml===!0?!0:void 0,g=n.stream===!0,_=C(t.output),v={model:r,input:{text:a,voice:o,format:l,sample_rate:u,volume:d,rate:f,pitch:p,seed:m,language_hints:s?[s]:void 0,instruction:c,enable_ssml:h}};if(Re(v.input),t.dryRun){G({request:v},_);return}t.quiet||process.stderr.write(`[Model: ${r}] [Voice: ${o}]\n`);let y=Le(t.baseUrl);g?await Ar(t,y,v,n,_):await kr(t,y,v,n,_)}});async function kr(t,n,r,a,o){let s=await mt(ct(a),t,()=>M(t,{url:n,method:`POST`,body:r})),c=s.map(e=>e.output?.audio?.url).filter(Boolean);if(c.length===0)throw new e(`API returned no audio URL.`,i.GENERAL);let l=await import(`path`),u=L(t,{subDir:`speech`}),d=await rt(c.map((e,t)=>{let n=a.out;if(!(n&&c.length===1)){let e=Date.now(),i=c.length>1?`_${String(t+1).padStart(3,`0`)}`:``,a=r.input.format??`mp3`;n=l.join(u,`tts_${e}${i}.${a}`)}return{url:e,destPath:n}}),U,{quiet:t.quiet});if(t.quiet)W(d.join(`
|
|
63
|
-
`));else if(d.length===1){let e=s[0].output?.audio?.expires_at;G({saved:d[0],audio_url:c[0],model:r.model,voice:r.input.voice,...e?{url_expires_at:e}:{}},o)}else G({saved:d,audio_urls:c,total:d.length,model:r.model,voice:r.input.voice},o)}async function Ar(e,t,n,r,i){let a=await j(e,{url:t,method:`POST`,body:n,stream:!0,headers:{Accept:`text/event-stream`,"X-DashScope-SSE":`enable`}}),o=r.out,s=o?yt(o):null,c;try{for await(let t of k(a)){if(!t.data||t.data===`[DONE]`)continue;let n;try{n=JSON.parse(t.data)}catch{continue}let r=n.output?.audio?.data;if(r){let e=Buffer.from(r,`base64`);s?s.write(e)||await new Promise(e=>s.once(`drain`,()=>e())):process.stdout.write(e)}if(n.output?.finish_reason===`stop`){c=n.output?.audio?.url,c&&!e.quiet&&process.stderr.write(`\nFull audio URL: ${c}\n`);break}}}finally{s&&(await new Promise((e,t)=>{s.on(`finish`,e),s.on(`error`,t),s.end()}),!e.quiet&&o&&process.stderr.write(`Saved: ${o}\n`))}o&&G({saved:o,...c?{audio_url:c}:{},model:n.model,voice:n.input.voice},i)}var jr=y({description:`Recognize speech from audio files (FunAudio-ASR)`,usageArgs:`--url <audio-url> [flags]`,options:[{flag:`--url <url>`,description:`Audio file URL or local file path (repeatable, max 100)`,required:!0,type:`array`},{flag:`--model <model>`,description:`Model ID (default: fun-asr)`},{flag:`--language <lang>`,description:`Language hint (e.g. zh, en, ja)`},{flag:`--diarization`,description:`Enable automatic speaker diarization`},{flag:`--speaker-count <n>`,description:`Expected number of speakers (requires --diarization)`,type:`number`},{flag:`--vocabulary-id <id>`,description:`Hot-word vocabulary ID for improved accuracy`},{flag:`--channel-id <n>`,description:`Audio channel ID (default: 0)`,type:`number`},{flag:`--out <path>`,description:`Save full transcription result to JSON file`},{flag:`--no-wait`,description:`Return task ID immediately without polling`},{flag:`--poll-interval <seconds>`,description:`Polling interval in seconds (default: 2)`,type:`number`}],exampleArgs:[`--url https://example.com/audio.mp3`,`--url https://example.com/a.mp3 --url https://example.com/b.mp3`,`--url https://example.com/meeting.wav --diarization --speaker-count 3`,`--url https://example.com/audio.mp3 --language zh`,`--url https://example.com/audio.mp3 --vocabulary-id vocab-abc123`,`--url https://example.com/audio.mp3 --out result.json`,`--url https://example.com/audio.mp3 --no-wait --quiet`],async run(t,n){let r=[];Array.isArray(n.url)?r=n.url:typeof n.url==`string`&&(r=[n.url]),r.length===0&&K(`url`,V(t,`--url <audio-url>`));let a=n.speakerCount,o=n.diarization===!0;if(a!==void 0&&!o)throw new e(`--speaker-count requires --diarization to be enabled.
|
|
64
|
-
Hint: Add --diarization flag to enable speaker separation.`,i.USAGE);let s=n.model||`fun-asr`,c=C(t.output),l=await F(t),u=await Promise.all(r.map(e=>I(e,l.token,s))),d=n.channelId,f=n.language,p=n.vocabularyId,m={model:s,input:{file_urls:u},parameters:{channel_id:d===void 0?[0]:[d],language_hints:f?[f]:void 0,diarization_enabled:o?!0:void 0,speaker_count:a,vocabulary_id:p}};if(Re(m.parameters),t.dryRun){G({request:m,mode:`async`},c);return}t.quiet||process.stderr.write(`[Model: ${s}] [Mode: async] [Files: ${u.length}]\n`),await Mr(t,Ie(t.baseUrl),m,n,c,u.length)}});async function Mr(t,n,r,a,o,s){let c=(await M(t,{url:n,method:`POST`,body:r,async:!0})).output.task_id;if(a.noWait||t.async){G({task_id:c},o);return}let l=a.pollInterval??2,u=await Y(t,{url:z(t.baseUrl,c),intervalSec:l,timeoutSec:t.timeout,isComplete:e=>e.output.task_status===`SUCCEEDED`,isFailed:e=>e.output.task_status===`FAILED`,getStatus:e=>e.output.task_status,getErrorMessage:e=>e.output.message}),d=u.output.results??[];if(d.length===0){G({task_id:c,status:u.output.task_status},o);return}let f=[];for(let t=0;t<d.length;t++){let n=d[t],r=s>1;if(r&&process.stdout.write(`=== [${t+1}/${d.length}] ${n.file_url??``} ===\n`),n.subtask_status===`FAILED`){let e=n.message??n.code??`unknown error`;process.stdout.write(`[FAILED] ${n.file_url??``} — ${e}\n`),r&&process.stdout.write(`
|
|
30
|
+
`),process.stderr.write(` ${s}\n\n`)}}}),zn=x({description:`Call a Bailian application (agent or workflow)`,auth:`apiKey`,usageArgs:`--app-id <id> --prompt <text> [flags]`,flags:{appId:{type:`string`,valueHint:`<id>`,description:`Application ID (required)`,required:!0},prompt:{type:`string`,valueHint:`<text>`,description:`Input prompt text`,required:!0},image:{type:`array`,valueHint:`<url>`,description:`Image URL(s) to pass to the app (repeatable)`},fileId:{type:`array`,valueHint:`<id>`,description:`Pre-uploaded file ID(s) (repeatable)`},sessionId:{type:`string`,valueHint:`<id>`,description:`Session ID for multi-turn conversation`},stream:{type:`switch`,description:`Stream response (default: on in TTY)`},pipelineIds:{type:`string`,valueHint:`<ids>`,description:`Knowledge base pipeline IDs (comma-separated)`},memoryId:{type:`string`,valueHint:`<id>`,description:`Memory ID for long-term memory`},bizParams:{type:`string`,valueHint:`<json>`,description:`Business parameters JSON (workflow variables)`},hasThoughts:{type:`switch`,description:`Show agent thinking process`}},exampleArgs:[`--app-id abc123 --prompt "Hello"`,`--app-id abc123 --prompt "Describe this image" --image https://example.com/photo.jpg`,`--app-id abc123 --prompt "Analyze the image" --image img1.jpg --image img2.jpg`,`--app-id abc123 --prompt "Continue" --session-id sess_xxx --stream`,`--app-id abc123 --prompt "Search for materials" --pipeline-ids pipe1,pipe2`,`--app-id abc123 --prompt "Start" --biz-params '{"key":"value"}'`],async run(e){let{settings:t,flags:n}=e,r=n.appId,i=n.prompt,a=n.stream||process.stdout.isTTY,o=w(t.output),s={input:{prompt:i},parameters:{incremental_output:a}};n.sessionId&&(s.input.session_id=n.sessionId);let c=n.image;c&&c.length>0&&(s.input.image_list=c);let l=n.fileId;if(l&&l.length>0&&(s.input.file_ids=l),n.hasThoughts&&(s.parameters.has_thoughts=!0),n.pipelineIds){let e=n.pipelineIds.split(`,`).map(e=>e.trim()).filter(Boolean);s.parameters.rag_options={pipeline_ids:e}}if(n.memoryId&&(s.parameters.memory_id=n.memoryId),n.bizParams)try{s.input.biz_params=JSON.parse(n.bizParams)}catch{throw new u(`--biz-params must be valid JSON`)}if(t.dryRun){R({endpoint:e.client.url(f(r)),request:s},o);return}if(a){let i=await e.client.request({path:f(r),method:`POST`,body:s,headers:{"X-DashScope-SSE":`enable`},stream:!0}),a=``,c=``,l=o===`text`,u=P(process.stderr);for await(let e of O(i)){if(e.data===`[DONE]`)break;try{let t=JSON.parse(e.data),r=t.output?.text;if(r&&(l&&process.stdout.write(r),a+=r),t.output?.session_id&&(c=t.output.session_id),t.output?.thoughts&&n.hasThoughts)for(let e of t.output.thoughts)e.thought&&process.stderr.write(`${u.dim(`[Thinking] ${e.thought}`)}\n`),e.action_name&&process.stderr.write(`${u.dim(`[Action] ${e.action_name}: ${e.action_input||``}`)}\n`),e.observation&&process.stderr.write(`${u.dim(`[Observation] ${e.observation}`)}\n`)}catch{}}c&&!t.quiet&&process.stderr.write(`${u.dim(`Session ID: ${c}`)}\n`),o===`json`?R({text:a,session_id:c},o):process.stdout.write(`
|
|
31
|
+
`)}else{let n=await e.client.requestJson({path:f(r),method:`POST`,body:s}),i=n.output?.text??``;t.quiet||o===`text`?L(i):R(n,o)}}});const Bn=`zeldaEasy.broadscope-bailian.app-control.list`;var Vn=x({description:`List Bailian applications`,auth:`console`,usageArgs:`[flags]`,flags:{name:{type:`string`,valueHint:`<name>`,description:`Filter by app name (keyword search)`},page:{type:`number`,valueHint:`<n>`,description:`Page number (default: 1)`},pageSize:{type:`number`,valueHint:`<n>`,description:`Results per page (default: 30)`}},exampleArgs:[``,`--name customer service`,`--page 2 --page-size 10`,`--output json`],async run(e){let{settings:t,flags:n}=e,r=n.name||``,i=n.page||1,a=n.pageSize||30,o=w(t.output),s={reqDTO:{name:r,notInTypes:[10],type:5,statuses:[1,4],page_no:i,page_size:a}};if(t.dryRun){R({api:Bn,data:s},o);return}let c=await e.client.console(Bn,s),l=c?.data?.DataV2?.data?.data?.list??[];R({total:c?.data?.DataV2?.data?.data?.total??0,apps:l.map(e=>({code:e.code,name:e.name,user_prompt_params:e.config?.user_prompt_params??[]}))},o)}}),Hn=x({description:`Add memory from messages or custom content`,auth:`apiKey`,usageArgs:`--user-id <id> [--messages <json>] [--content <text>] [flags]`,flags:{userId:{type:`string`,valueHint:`<id>`,description:`User ID (required)`,required:!0},messages:{type:`string`,valueHint:`<json>`,description:`Messages JSON array: [{"role":"user","content":"..."},...]`},content:{type:`string`,valueHint:`<text>`,description:`Custom content text to memorize`},profileSchema:{type:`string`,valueHint:`<id>`,description:`Profile schema ID for user profiling`},memoryLibraryId:{type:`string`,valueHint:`<id>`,description:`Memory library ID (isolate memory space)`}},exampleArgs:[`--user-id user1 --content "The user likes Python programming"`,`--user-id user1 --messages '[{"role":"user","content":"I like traveling"}]'`,`--user-id user1 --content "Lives in Beijing" --profile-schema schema_xxx`],validate:e=>!e.messages&&!e.content?`Provide --messages or --content.`:void 0,async run(e){let{settings:t,flags:n}=e,r={user_id:n.userId};if(n.messages)try{r.messages=JSON.parse(n.messages)}catch{throw new u(`--messages must be valid JSON array`)}n.content&&(r.custom_content=n.content),n.profileSchema&&(r.profile_schema=n.profileSchema),n.memoryLibraryId&&(r.memory_library_id=n.memoryLibraryId);let i=w(t.output);if(t.dryRun){R({endpoint:e.client.url(Ee()),request:r},i);return}let a=await e.client.requestJson({path:Ee(),method:`POST`,body:r});t.quiet||i===`text`?L(`Memory added. IDs: ${a.memory_ids?.join(`, `)||`none`}`):R(a,i)}}),Un=x({description:`Search memory nodes by query or messages`,auth:`apiKey`,usageArgs:`--user-id <id> [--query <text>] [flags]`,flags:{userId:{type:`string`,valueHint:`<id>`,description:`User ID (required)`,required:!0},query:{type:`string`,valueHint:`<text>`,description:`Search query text`},messages:{type:`string`,valueHint:`<json>`,description:`Messages JSON array for context-based search`},topK:{type:`number`,valueHint:`<n>`,description:`Number of results to return (default: 10)`},memoryLibraryId:{type:`string`,valueHint:`<id>`,description:`Memory library ID`}},exampleArgs:[`--user-id user1 --query "programming preferences"`,`--user-id user1 --messages '[{"role":"user","content":"recommend a book"}]' --top-k 5`],validate:e=>!e.query&&!e.messages?`Provide --query or --messages.`:void 0,async run(e){let{settings:t,flags:n}=e,r={user_id:n.userId};if(n.query&&(r.query=n.query),n.messages)try{r.messages=JSON.parse(n.messages)}catch{throw new u(`--messages must be valid JSON array`)}!r.messages&&r.query&&(r.messages=[{role:`user`,content:r.query}]),n.topK!==void 0&&(r.top_k=n.topK),n.memoryLibraryId&&(r.memory_library_id=n.memoryLibraryId);let i=w(t.output);if(t.dryRun){R({endpoint:e.client.url(ke()),request:r},i);return}let a=await e.client.requestJson({path:ke(),method:`POST`,body:r});if(t.quiet||i===`text`)if(!a.memory_nodes||a.memory_nodes.length===0)L(`No memory nodes found.`);else for(let e of a.memory_nodes)L(`[${e.memory_node_id}] ${e.content}`);else R(a,i)}}),Wn=x({description:`List memory nodes for a user`,auth:`apiKey`,usageArgs:`--user-id <id> [flags]`,flags:{userId:{type:`string`,valueHint:`<id>`,description:`User ID (required)`,required:!0},pageSize:{type:`number`,valueHint:`<n>`,description:`Results per page (default: 10)`},page:{type:`number`,valueHint:`<n>`,description:`Page number (default: 1)`},memoryLibraryId:{type:`string`,valueHint:`<id>`,description:`Memory library ID`}},exampleArgs:[`--user-id user1`,`--user-id user1 --page-size 20 --page 2`],async run(e){let{settings:t,flags:n}=e,r=n.userId,i=w(t.output),a=new URLSearchParams;a.set(`user_id`,r),n.pageSize!==void 0&&a.set(`page_size`,String(n.pageSize)),n.page!==void 0&&a.set(`page_num`,String(n.page)),n.memoryLibraryId&&a.set(`memory_library_id`,n.memoryLibraryId);let o=`${De()}?${a.toString()}`;if(t.dryRun){R({endpoint:e.client.url(o),method:`GET`},i);return}let s=await e.client.requestJson({path:o,method:`GET`});if(t.quiet||i===`text`)if(!s.memory_nodes||s.memory_nodes.length===0)L(`No memory nodes found.`);else{for(let e of s.memory_nodes)L(`[${e.memory_node_id}] ${e.content}`);s.total!==void 0&&L(`\nTotal: ${s.total}`)}else R(s,i)}}),Gn=x({description:`Update a memory node content`,auth:`apiKey`,usageArgs:`--node-id <id> --user-id <id> --content <text>`,flags:{nodeId:{type:`string`,valueHint:`<id>`,description:`Memory node ID (required)`,required:!0},userId:{type:`string`,valueHint:`<id>`,description:`User ID (required)`,required:!0},content:{type:`string`,valueHint:`<text>`,description:`New content for the memory node (required)`,required:!0},memoryLibraryId:{type:`string`,valueHint:`<id>`,description:`Memory library ID (non-default library)`}},exampleArgs:[`--node-id node_xxx --user-id user1 --content "updated memory content"`],async run(e){let{settings:t,flags:n}=e,r=n.nodeId,i={user_id:n.userId,custom_content:n.content};n.memoryLibraryId&&(i.memory_library_id=n.memoryLibraryId);let a=w(t.output);if(t.dryRun){R({endpoint:e.client.url(Oe(r)),method:`PATCH`,request:i},a);return}let o=await e.client.requestJson({path:Oe(r),method:`PATCH`,body:i});t.quiet||a===`text`?L(`Memory node ${r} updated.`):R(o,a)}}),Kn=x({description:`Delete a memory node`,auth:`apiKey`,usageArgs:`--node-id <id> --user-id <id>`,flags:{nodeId:{type:`string`,valueHint:`<id>`,description:`Memory node ID (required)`,required:!0},userId:{type:`string`,valueHint:`<id>`,description:`User ID (required)`,required:!0},memoryLibraryId:{type:`string`,valueHint:`<id>`,description:`Memory library ID (non-default library)`}},exampleArgs:[`--node-id node_xxx --user-id user1`],async run(e){let{settings:t,flags:n}=e,r=n.nodeId,i=n.userId,a=w(t.output),o=new URLSearchParams({user_id:i});n.memoryLibraryId&&o.set(`memory_library_id`,n.memoryLibraryId);let s=`${Oe(r)}?${o.toString()}`;if(t.dryRun){R({endpoint:e.client.url(s),method:`DELETE`},a);return}let c=await e.client.requestJson({path:s,method:`DELETE`});t.quiet||a===`text`?L(`Memory node ${r} deleted.`):R(c,a)}}),qn=x({description:`Create a user profile schema for memory profiling`,auth:`apiKey`,usageArgs:`--name <name> --attributes <json> [flags]`,flags:{name:{type:`string`,valueHint:`<name>`,description:`Schema name (required)`,required:!0},description:{type:`string`,valueHint:`<text>`,description:`Schema description`},attributes:{type:`string`,valueHint:`<json>`,description:`Attributes JSON array: [{"name":"age","description":"age"}]`,required:!0}},exampleArgs:[`--name "user_basic" --attributes '[{"name":"age","description":"age"},{"name":"hobby","description":"hobby"}]'`],async run(e){let{settings:t,flags:n}=e,r=n.name,i=n.attributes,a;try{a=JSON.parse(i)}catch{throw new u(`--attributes must be valid JSON array`)}let o={name:r,attributes:a};n.description&&(o.description=n.description);let s=w(t.output);if(t.dryRun){R({endpoint:e.client.url(Ne()),request:o},s);return}let c=await e.client.requestJson({path:Ne(),method:`POST`,body:o});t.quiet||s===`text`?L(`Profile schema created: ${c.profile_schema_id}`):R(c,s)}}),Jn=x({description:`Get user profile by schema ID and user ID`,auth:`apiKey`,usageArgs:`--schema-id <id> --user-id <id>`,flags:{schemaId:{type:`string`,valueHint:`<id>`,description:`Profile schema ID (required)`,required:!0},userId:{type:`string`,valueHint:`<id>`,description:`User ID (required)`,required:!0}},exampleArgs:[`--schema-id schema_xxx --user-id user1`],async run(e){let{settings:t,flags:n}=e,r=n.schemaId,i=n.userId,a=w(t.output),o=new URLSearchParams({user_id:i}),s=`${Ke(r)}?${o.toString()}`;if(t.dryRun){R({endpoint:e.client.url(s),method:`GET`},a);return}let c=await e.client.requestJson({path:s,method:`GET`});if(t.quiet||a===`text`)if(c.profile?.attributes)for(let e of c.profile.attributes)L(`${e.name}: ${e.value??`(empty)`}`);else L(`No profile data found.`);else R(c,a)}}),Yn=x({description:"Retrieve from a Bailian knowledge base (deprecated, use `search` instead)",auth:`apiKey`,usageArgs:`--index-id <id> --query <text> [flags]`,flags:{indexId:{type:`string`,valueHint:`<id>`,description:`Knowledge base index ID (required)`,required:!0},query:{type:`string`,valueHint:`<text>`,description:`Search query (required)`,required:!0},denseSimilarityTopK:{type:`number`,valueHint:`<n>`,description:`Dense retrieval top K`},sparseSimilarityTopK:{type:`number`,valueHint:`<n>`,description:`Sparse retrieval top K`},rerank:{type:`switch`,description:`Enable reranking`},rerankTopN:{type:`number`,valueHint:`<n>`,description:`Rerank top N results`},rerankModel:{type:`string`,valueHint:`<name>`,description:`Rerank model, e.g. qwen3-rerank-hybrid`},rerankMode:{type:`string`,valueHint:`<mode>`,description:`Rerank mode: qa, similar, or custom`},rerankInstruct:{type:`string`,valueHint:`<text>`,description:`Custom rerank instruction, when mode=custom`},topK:{type:`number`,valueHint:`<n>`,description:`Number of results (deprecated, use --rerank-top-n)`}},exampleArgs:[`--index-id idx_xxx --query "How to use Alibaba Cloud Bailian"`,`--index-id idx_xxx --query "RAG retrieval" --rerank --rerank-model qwen3-rerank-hybrid`],async run(e){let{settings:t,flags:n}=e,r=w(t.output);n.topK!==void 0&&n.rerankTopN===void 0&&(process.stderr.write(`Warning: --top-k is deprecated. Use --rerank-top-n instead.
|
|
32
|
+
`),n.rerankTopN=n.topK);let i={index_id:n.indexId,query:n.query,search_filters:[]};if(n.denseSimilarityTopK!==void 0&&(i.dense_similarity_top_k=n.denseSimilarityTopK),n.sparseSimilarityTopK!==void 0&&(i.sparse_similarity_top_k=n.sparseSimilarityTopK),n.rerank&&(i.enable_reranking=!0),n.rerankTopN!==void 0&&(i.rerank_top_n=n.rerankTopN),n.rerankModel){let e={model_name:n.rerankModel};n.rerankMode&&(e.rerank_mode=n.rerankMode),n.rerankInstruct&&(e.rerank_instruct=n.rerankInstruct),i.rerank=[e]}if(t.dryRun){R({endpoint:e.client.url(_e()),request:i},r);return}let a=await e.client.requestJson({path:_e(),method:`POST`,body:i}),o=a.data?.nodes||[];t.quiet||r===`text`?Xn(o.map(e=>({text:e.text,score:e.score}))):R(a,r)}});function Xn(e){if(e.length===0)L(`No results found.`);else for(let t=0;t<e.length;t++){let n=e[t];L(`[${t+1}] (score: ${n.score.toFixed(4)})`),L(n.text),L(``)}}var Zn=x({description:`Search a Bailian knowledge base (RAG semantic retrieval)`,auth:`apiKey`,usageArgs:`--query <text> --agent-id <id> [flags]`,flags:{query:{type:`string`,valueHint:`<text>`,description:`Search query text (required, cannot be empty)`,required:!0},agentId:{type:`string`,valueHint:`<id>`,description:`Retrieval service ID (find in console knowledge retrieval page)`,required:!0},workspaceId:{type:`string`,valueHint:`<id>`,description:`Workspace ID for API endpoint URL (or set BAILIAN_WORKSPACE_ID)`},image:{type:`array`,valueHint:`<url>`,description:`Image URL for multimodal retrieval (repeatable)`},queryHistory:{type:`string`,valueHint:`<json>`,description:`User conversation history JSON for context understanding and query rewriting. Format: '[{"role":"user","content":"What is RAG"},{"role":"assistant","content":"RAG is..."}]'`}},notes:[`Retrieval scope and strategy (multi-index weighting, routing, reranking, etc.) are driven by the agent_id service config. Only query and agent_id are required.`,`Auth: uses DashScope API Key (Bearer token). Get yours from the console API Key page.`,"`--workspace-id` can be set via BAILIAN_WORKSPACE_ID env or `kscli config set workspace_id <id>`.","`--query-history` passes prior conversation turns; the server rewrites the query based on context to improve retrieval relevance."],exampleArgs:[`--query "What is RAG?" --agent-id aid-xxx --workspace-id ws-xxx`,`--api-key $DASHSCOPE_API_KEY --query "test search" --agent-id aid-xxx --workspace-id ws-xxx --image https://example.com/img.jpg`,`--query "How does it work" --agent-id aid-xxx --workspace-id ws-xxx --query-history '[{"role":"user","content":"What is RAG"},{"role":"assistant","content":"RAG is retrieval-augmented generation"}]'`],async run(e){let{settings:n,flags:r}=e,i=r.workspaceId||n.workspaceId;if(!i)throw new t(`Workspace ID is required.`,a.USAGE,`Pass --workspace-id, set BAILIAN_WORKSPACE_ID env, or configure: ${e.identity.binName} config set workspace_id <id>`);let o=w(n.output),s={query:r.query,agent_id:r.agentId};if(r.image&&r.image.length>0&&(s.images=r.image),r.queryHistory)try{s.query_history=JSON.parse(r.queryHistory)}catch{throw new t(`--query-history must be valid JSON. Example: --query-history '[{"role":"user","content":"What is RAG"}]'`,a.USAGE)}let c=ve(i);if(n.dryRun){R({endpoint:c,request:s},o);return}let l=await e.client.requestJson({path:c,method:`POST`,body:s}),u=l.data?.nodes||[];if(n.quiet||o===`text`)if(u.length===0)L(`No results found.`);else for(let e=0;e<u.length;e++){let t=u[e];L(`[${e+1}] (score: ${t.score.toFixed(4)})`),L(t.text),L(``)}else R(l,o)}});const Qn={message:{type:`array`,valueHint:`<text>`,description:`Message text (repeatable). Supports role:content prefix to set role (e.g. user:hello), defaults to user. Follows OpenAI message format`},agentId:{type:`string`,valueHint:`<id>`,description:`Q&A service ID (find in console knowledge Q&A page)`,required:!0},workspaceId:{type:`string`,valueHint:`<id>`,description:`Workspace ID for API endpoint URL (or set BAILIAN_WORKSPACE_ID)`},image:{type:`array`,valueHint:`<url>`,description:`Image URL (repeatable). Attached to the last user message as multimodal content`}};function $n(e){let t=[];if(e.message){let n=new Set([`user`,`assistant`]);for(let r of e.message){if(r.startsWith(`{`))try{let e=JSON.parse(r);if(e.role&&n.has(e.role)&&e.content!==void 0){t.push(e);continue}}catch{}let e=r.indexOf(`:`),i=e===-1?``:r.slice(0,e);n.has(i)?t.push({role:i,content:r.slice(e+1)}):t.push({role:`user`,content:r})}}return t}function er(e){for(let t of e)if(Array.isArray(t.content)&&t.content.some(e=>e.type===`image_url`))return!0;return!1}function tr(e,t){let n=-1;for(let t=e.length-1;t>=0;t--)if(e[t].role===`user`){n=t;break}n===-1&&(e.push({role:`user`,content:``}),n=e.length-1);let r=e[n],i=[];typeof r.content==`string`?i.push({type:`text`,text:r.content}):i.push(...r.content);for(let e of t)i.push({type:`image_url`,image_url:{url:e}});r.content=i}const nr={tool_calling:`🔍 Retrieving...`,plan_start:`🤔 Planning...`,generation_start:`✍️ Generating...`};var rr=x({description:`Chat with a Bailian knowledge base (RAG Q&A with streaming)`,auth:`apiKey`,usageArgs:`--message <text> --agent-id <id> [flags]`,flags:Qn,notes:[`Response is returned as SSE stream events. Event lifecycle: tool_calling → tool_return → plan_start → planning → plan_end → generation_start → generating → generation_end. tool_calling → tool_return may loop multiple times.`,`Auth: uses DashScope API Key (Bearer token). Get yours from the console API Key page.`,"`--workspace-id` can be set via BAILIAN_WORKSPACE_ID env or `kscli config set workspace_id <id>`.",`Multi-turn: use --message "user:..." and --message "assistant:..." to pass conversation history.`],exampleArgs:[`--message "What is RAG?" --agent-id aid-xxx --workspace-id ws-xxx`,`--message "user:What is RAG?" --message "assistant:RAG is..." --message "How does it work?" --agent-id aid-xxx --workspace-id ws-xxx`,`--message "Describe these images" --image https://example.com/a.png --image https://example.com/b.png --agent-id aid-xxx --workspace-id ws-xxx`],validate:e=>e.message&&e.message.length>0||e.image&&e.image.length>0?void 0:`Provide --message (or --image for a pure image query).`,async run(e){let{settings:n,flags:r}=e,i=$n(r),o=r.image,s=!!o&&o.length>0;i.length===0&&s&&(i=[{role:`user`,content:``}]);let c=r.workspaceId||n.workspaceId;if(!c)throw new t(`Workspace ID is required.`,a.USAGE,`Pass --workspace-id, set BAILIAN_WORKSPACE_ID env, or configure: ${e.identity.binName} config set workspace_id <id>`);let l=w(n.output),u=l===`text`&&!!process.stdout.isTTY;if(s){if(er(i))throw new t(`Cannot use --image when messages already contain embedded image_url content parts. Use one approach or the other.`,a.USAGE);tr(i,o)}let d={input:{messages:i},parameters:{agent_options:{agent_id:r.agentId}},stream:!0},f=ge(c);if(n.dryRun){R({endpoint:f,request:d},l);return}let p=await e.client.request({path:f,method:`POST`,body:d,stream:!0});if(u){let e=P(process.stdout),r=n.verbose;for await(let n of O(p)){if(n.data===`[DONE]`)break;if(n.event===`error`){let e=`Chat API error`,r;try{let t=JSON.parse(n.data);e=t.message||e,r=t.code}catch{}throw new t(e,a.GENERAL,r?`API error: ${r}`:void 0)}try{let t=JSON.parse(n.data);for(let n of t.output?.choices??[]){let t=n.message;if(t.extra?.step_change){let n=nr[t.extra.step_change];n&&process.stdout.write(`${e.dim(n)}\n`)}if(r&&t.extra?.step_change&&process.stderr.write(P(process.stderr).dim(`[event] step_change=${t.extra.step_change} step=${t.extra?.step??``} group=${t.extra?.group??``}`)+`
|
|
33
|
+
`),t.content&&process.stdout.write(t.content),n.finish_reason===`stop`)break}}catch{}}process.stdout.write(`
|
|
34
|
+
`)}else{let e=``,r=``;for await(let n of O(p)){if(n.data===`[DONE]`)break;if(n.event===`error`){let e=`Chat API error`,r;try{let t=JSON.parse(n.data);e=t.message||e,r=t.code}catch{}throw new t(e,a.GENERAL,r?`API error: ${r}`:void 0)}try{let t=JSON.parse(n.data);t.request_id&&(r=t.request_id);for(let n of t.output?.choices??[])if(n.message?.content&&(e+=n.message.content),n.finish_reason===`stop`)break}catch{}}n.quiet||l===`text`?L(e):R({answer:e,request_id:r},l)}}});const ir={target:{type:`string`,valueHint:`<server.tool>`,description:`Server code and tool name joined by a dot, e.g. market-cmapi00073529.SmartStockSelection`,required:!0},arg:{type:`array`,valueHint:`<kv>`,description:`Tool argument (repeatable). Values parsed as JSON if possible, else string.`},json:{type:`string`,valueHint:`<obj>`,description:`Full arguments object as JSON; merged with --arg (arg wins).`},query:{type:`string`,valueHint:`<text>`,description:`Shortcut for --arg query=<text> (mirrors many DashScope MCP tools).`},url:{type:`string`,valueHint:`<url>`,description:`Override the MCP endpoint URL (for non-Bailian servers)`}};function ar(e){let t=e.indexOf(`.`);if(t<=0||t===e.length-1)throw new u(`target must be <server-code>.<tool>, got "${e}".`);return{serverCode:e.slice(0,t),toolName:e.slice(t+1)}}function or(e){let t={};for(let n of e){let e=n.indexOf(`=`);if(e<=0)throw new u(`--arg must be in K=V form, got: ${n}`);let r=n.slice(0,e).trim(),i=n.slice(e+1);try{t[r]=JSON.parse(i)}catch{t[r]=i}}return t}function sr(e){let t;try{t=JSON.parse(e)}catch(e){throw new u(`--json is not valid JSON — ${e.message}`)}if(!t||typeof t!=`object`||Array.isArray(t))throw new u(`--json must decode to an object.`);return t}function cr(e){let t=e.json?sr(e.json):{};return Object.assign(t,or(e.arg??[])),e.query!==void 0&&(t.query=e.query),t}function lr(e){try{ar(e.target),cr(e)}catch(e){if(e instanceof u)return e.message;throw e}}var ur=x({description:`Call a tool on an MCP server (tools/call)`,auth:`apiKey`,usageArgs:`--target <server.tool> [--arg k=v ...] [--json '{...}'] [--url <url>]`,flags:ir,exampleArgs:[`--target market-cmapi00073529.SmartStockSelection --query "Screen consumer stocks with ROE > 15%"`,`--target market-cmapi00073529.FinQuery --json '{"q":"Guizhou Maotai","limit":5}'`,`--target market-cmapi00073529.SmartFundSelection --arg riskLevel=R3 --arg minScale=10`],validate:lr,async run(e){let{settings:n,flags:r}=e,{serverCode:i,toolName:a}=ar(r.target),o=cr(r),s=r.url||e.client.url(p(i)),c=w(n.output);if(n.dryRun){R({server:i,url:s,tool:a,arguments:o},c);return}let l=e.client.mcp(s);await l.initialize();let u=await l.callTool(a,o);if(u.isError)throw new t(`Tool error: ${u.content.map(e=>e.text||``).join(`
|
|
35
|
+
`)}`);R(u,c)}});const dr=`zeldaEasy.broadscope-bailian.mcp-server.PageList`;var fr=x({description:`List MCP servers activated under your Bailian account`,auth:`console`,usageArgs:`[flags]`,flags:{name:{type:`string`,valueHint:`<text>`,description:`Filter by server name (substring match)`},type:{type:`string`,valueHint:`<type>`,description:`Server type: OFFICIAL | PRIVATE (default: OFFICIAL)`},page:{type:`number`,valueHint:`<n>`,description:`Page number (default: 1)`},pageSize:{type:`number`,valueHint:`<n>`,description:`Results per page (default: 30)`}},exampleArgs:[``,`--name finance`,`--output json`],async run(e){let{settings:n,identity:r,flags:i}=e,o=i.name||``,s=i.type||`OFFICIAL`,c=i.page||1,l=i.pageSize||30,u=w(n.output),d={reqDTO:{type:s,displayTools:!1,activated:1,pageNo:c,pageSize:l,serverName:o}};if(n.dryRun){R({api:dr,data:d,...te(n)},u);return}let f=(await e.client.console(dr,d))?.data??{};if(f.success===!1){let e=f.errorCode??`UnknownError`,n=f.errorMsg??e,i=e===`BailianGateway.Login.NotLogined`?`Run \`${r.binName} auth login --console\` to refresh your console session.`:void 0;throw new t(`Console gateway: ${n}`,a.AUTH,i)}let p=(f.DataV2??{}).data?.data??{},m=p.mcpServerDetailList??[];R({total:p.total??0,servers:m.map(e=>({code:e.serverCode??``,name:e.serverName??``,description:e.description,type:e.type??``,source:e.source,bizType:e.bizType,installType:e.installType,streamable:e.streamable===!0}))},u)}}),pr=x({description:`List tools exposed by an MCP server (tools/list)`,auth:`apiKey`,usageArgs:`--server <code> [--url <url>]`,flags:{server:{type:`string`,valueHint:`<code>`,description:"Server code from `mcp list` (e.g. market-cmapi00073529)",required:!0},url:{type:`string`,valueHint:`<url>`,description:`Override the MCP endpoint URL (for non-Bailian servers)`}},exampleArgs:[`--server market-cmapi00073529`,`--server market-cmapi00073529 --output json`,`--server my-server --url https://example.com/mcp`],async run(e){let{settings:t,flags:n}=e,r=n.server,i=n.url||e.client.url(p(r)),a=w(t.output);if(t.dryRun){R({server:r,url:i,action:`tools/list`},a);return}let o=e.client.mcp(i);await o.initialize(),R({server:r,url:i,tools:await o.listTools()},a)}}),mr=x({description:`Search the web using DashScope MCP WebSearch service`,auth:`apiKey`,usageArgs:`--query <text> [flags]`,flags:{query:{type:`string`,valueHint:`<text>`,description:`Search query text`},count:{type:`number`,valueHint:`<n>`,description:`Number of search results (default: 10)`},listTools:{type:`switch`,description:`List available MCP tools and exit`}},exampleArgs:[`--query "Alibaba Cloud Bailian latest features"`,`--query "TypeScript 5.9 new features" --count 5`,`--query "Today's news"`,`--list-tools`],validate:e=>!e.listTools&&!e.query?`Missing required flag: --query`:void 0,async run(e){let{settings:n,flags:r}=e,i=w(n.output);if(r.listTools){if(n.dryRun){R({endpoint:e.client.url(Te()),action:`tools/list`},i);return}let t=e.client.mcp(Te());await t.initialize(),R({tools:await t.listTools()},i);return}let a=r.query;if(n.dryRun){R({endpoint:e.client.url(Te()),action:`tools/call`,tool:`bailian_web_search`,arguments:{query:a,count:r.count||void 0}},i);return}let o=e.client.mcp(Te()),s=nt(`Initializing search...`);n.quiet||s.start();try{await o.initialize(),n.quiet||s.update(`Searching...`);let e={query:a};r.count&&(e.count=r.count);let c=await o.callTool(`bailian_web_search`,e);if(c.isError)throw new t(`Search error: ${c.content.map(e=>e.text||``).join(`
|
|
36
|
+
`)}`);if(n.quiet||s.stop(`Done.`),i===`json`)R(c,i);else for(let e of c.content)if(e.type===`text`&&e.text)try{let t=JSON.parse(e.text);t.pages&&Array.isArray(t.pages)?R({pages:t.pages,total:t.pages.length},i):R(t,i)}catch{R({text:e.text},i)}}catch(e){throw s.stop(`Failed.`),e}}});const hr=`${i.cn}/cosyvoice-clone-design-api`,gr=[{voice:`longanyang`,name:`龙安洋`,desc:`阳光大男孩`,lang:`中文/英文`},{voice:`longanhuan_v3`,name:`龙安欢`,desc:`欢脱元气女`,lang:`中文/英文`},{voice:`longantai_v3`,name:`龙安台`,desc:`嗲甜台湾女`,lang:`中文/英文`},{voice:`longhua_v3`,name:`龙华`,desc:`元气甜美女`,lang:`中文/英文`},{voice:`longcheng_v3`,name:`龙橙`,desc:`智慧青年男`,lang:`中文/英文`},{voice:`longze_v3`,name:`龙泽`,desc:`温暖元气男`,lang:`中文/英文`},{voice:`longzhe_v3`,name:`龙哲`,desc:`呆板大暖男`,lang:`中文/英文`},{voice:`longyan_v3`,name:`龙颜`,desc:`温暖春风女`,lang:`中文/英文`},{voice:`longxing_v3`,name:`龙星`,desc:`温婉邻家女`,lang:`中文/英文`},{voice:`longtian_v3`,name:`龙天`,desc:`磁性理智男`,lang:`中文/英文`},{voice:`longwan_v3`,name:`龙婉`,desc:`细腻柔声女`,lang:`中文/英文`},{voice:`longqiang_v3`,name:`龙嫱`,desc:`浪漫风情女`,lang:`中文/英文`},{voice:`longfeifei_v3`,name:`龙菲菲`,desc:`甜美娇气女`,lang:`中文/英文`},{voice:`longhao_v3`,name:`龙浩`,desc:`多情忧郁男`,lang:`中文/英文`},{voice:`longanrou_v3`,name:`龙安柔`,desc:`温柔娴静女`,lang:`中文/英文`},{voice:`longxiaochun_v3`,name:`龙小淳`,desc:`知性积极女`,lang:`中文/英文`},{voice:`longxiaoxia_v3`,name:`龙小夏`,desc:`沉稳权威女`,lang:`中文/英文`},{voice:`longyumi_v3`,name:`YUMI`,desc:`正经青年女`,lang:`中文/英文`},{voice:`longanyun_v3`,name:`龙安昀`,desc:`居家暖男`,lang:`中文/英文`},{voice:`longanwen_v3`,name:`龙安温`,desc:`优雅知性女`,lang:`中文/英文`},{voice:`longanli_v3`,name:`龙安莉`,desc:`利落从容女`,lang:`中文/英文`},{voice:`longanlang_v3`,name:`龙安朗`,desc:`清爽利落男`,lang:`中文/英文`},{voice:`longyingmu_v3`,name:`龙应沐`,desc:`优雅知性女`,lang:`中文/英文`},{voice:`longyingxun_v3`,name:`龙应询`,desc:`年轻青涩男`,lang:`中文/英文`},{voice:`longyingjing_v3`,name:`龙应静`,desc:`低调冷静女`,lang:`中文/英文`},{voice:`longyingling_v3`,name:`龙应聆`,desc:`温和共情女`,lang:`中文/英文`},{voice:`longyingtao_v3`,name:`龙应桃`,desc:`温柔淡定女`,lang:`中文/英文`},{voice:`longyingxiao_v3`,name:`龙应笑`,desc:`清甜推销女`,lang:`中文/英文`},{voice:`longfei_v3`,name:`龙飞`,desc:`热血磁性男`,lang:`中文/英文`},{voice:`longhuhu_v3`,name:`龙呼呼`,desc:`天真烂漫女童`,lang:`中文/英文`},{voice:`longpaopao_v3`,name:`龙泡泡`,desc:`飞天泡泡音`,lang:`中文/英文`},{voice:`longjielidou_v3`,name:`龙杰力豆`,desc:`阳光顽皮男`,lang:`中文/英文`},{voice:`longxian_v3`,name:`龙仙`,desc:`豪放可爱女`,lang:`中文/英文`},{voice:`longling_v3`,name:`龙铃`,desc:`稚气呆板女`,lang:`中文/英文`},{voice:`longshanshan_v3`,name:`龙闪闪`,desc:`戏剧化童声`,lang:`中文/英文`},{voice:`longniuniu_v3`,name:`龙牛牛`,desc:`阳光男童声`,lang:`中文/英文`},{voice:`longjiaxin_v3`,name:`龙嘉欣`,desc:`优雅粤语女`,lang:`粤语/英文`},{voice:`longjiayi_v3`,name:`龙嘉怡`,desc:`知性粤语女`,lang:`粤语/英文`},{voice:`longanyue_v3`,name:`龙安粤`,desc:`欢脱粤语男`,lang:`粤语/英文`},{voice:`longlaotie_v3`,name:`龙老铁`,desc:`东北直率男`,lang:`东北话/英文`},{voice:`longshange_v3`,name:`龙陕哥`,desc:`原味陕北男`,lang:`陕西话/英文`},{voice:`longanmin_v3`,name:`龙安闽`,desc:`清纯萝莉女`,lang:`闽南话/英文`},{voice:`loongabby_v3`,name:`loongabby`,desc:`美式英文女`,lang:`美式英语`},{voice:`loongandy_v3`,name:`loongandy`,desc:`美式英文男`,lang:`美式英语`},{voice:`loongannie_v3`,name:`loongannie`,desc:`美式英文女`,lang:`美式英语`},{voice:`loongava_v3`,name:`loongava`,desc:`美式英文女`,lang:`美式英语`},{voice:`loongbeth_v3`,name:`loongbeth`,desc:`美式英文女`,lang:`美式英语`},{voice:`loongbetty_v3`,name:`loongbetty`,desc:`美式英文女`,lang:`美式英语`},{voice:`loongcally_v3`,name:`loongcally`,desc:`美式英文女`,lang:`美式英语`},{voice:`loongcindy_v3`,name:`loongcindy`,desc:`美式英文女`,lang:`美式英语`},{voice:`loongdavid_v3`,name:`loongdavid`,desc:`美式英文男`,lang:`美式英语`},{voice:`loongdonna_v3`,name:`loongdonna`,desc:`美式英文女`,lang:`美式英语`},{voice:`loongemily_v3`,name:`loongemily`,desc:`英式英文女`,lang:`英式英语`},{voice:`loongeric_v3`,name:`loongeric`,desc:`英式英文男`,lang:`英式英语`},{voice:`loongluna_v3`,name:`loongluna`,desc:`英式英文女`,lang:`英式英语`},{voice:`loongluca_v3`,name:`loongluca`,desc:`英式英文男`,lang:`英式英语`},{voice:`loongriko_v3`,name:`Riko`,desc:`二次元霓虹女`,lang:`日语`},{voice:`loongtomoka_v3`,name:`loongtomoka`,desc:`日语女`,lang:`日语`},{voice:`loongtomoya_v3`,name:`loongtomoya`,desc:`日语男`,lang:`日语`},{voice:`loongyuuna_v3`,name:`Yuuna`,desc:`日语女`,lang:`日语`},{voice:`loongyuuma_v3`,name:`Yuuma`,desc:`日语男`,lang:`日语`},{voice:`loongkyong_v3`,name:`loongkyong`,desc:`韩语女`,lang:`韩语`},{voice:`loongjihun_v3`,name:`Jihun`,desc:`韩语男`,lang:`韩语`},{voice:`loongindah_v3`,name:`loongindah`,desc:`印尼女`,lang:`印尼语`}],_r={"cosyvoice-v3-flash":gr,"cosyvoice-v3-plus":gr,"cosyvoice-v3.5-flash":[],"cosyvoice-v3.5-plus":[],"cosyvoice-v2":[]};function vr(e){let t=_r[e];if(!t){process.stdout.write(`No built-in voice list available for model: ${e}\n`),process.stdout.write(`Browse voices in the console: ${$e}\n`);return}if(t.length===0){process.stdout.write(`Model ${e} has no system voices.\n`),process.stdout.write(`Use clone or design voices created via the CosyVoice API.
|
|
37
|
+
`),process.stdout.write(`See: ${hr}\n`),process.stdout.write(`Browse voices in the console: ${$e}\n`);return}let n=(e,t)=>e.padEnd(t);process.stdout.write(`\nSystem voices for ${e}:\n`),process.stdout.write(`${n(`VOICE ID`,26)} ${n(`NAME`,10)} ${n(`DESCRIPTION`,16)} LANGUAGE\n`),process.stdout.write(`${`-`.repeat(26)} ${`-`.repeat(10)} ${`-`.repeat(16)} ${`-`.repeat(12)}\n`);for(let e of t)process.stdout.write(`${n(e.voice,26)} ${n(e.name,10)} ${n(e.desc,16)} ${e.lang}\n`);process.stdout.write(`\nTotal: ${t.length} voices\n`),process.stdout.write(`Preview and browse more voices in the console: \n${$e}\n`)}var yr=x({description:`Synthesize speech from text (CosyVoice TTS)`,auth:`apiKey`,usageArgs:`--text <text> [flags]`,flags:{text:{type:`string`,valueHint:`<text>`,description:`Text to synthesize into speech (or use --text-file)`},textFile:{type:`string`,valueHint:`<path>`,description:`Read text from a file instead of --text`},model:{type:`string`,valueHint:`<model>`,description:`Model ID (default: cosyvoice-v3-flash). System voices available for cosyvoice-v3-flash`},voice:{type:`string`,valueHint:`<voice>`,description:`Voice ID. Use --list-voices to see built-in voices for cosyvoice-v3-flash; for v3.5-flash provide a clone/design voice ID`},listVoices:{type:`switch`,description:`List built-in system voices for the selected model and exit (console link shown in output)`},format:{type:`string`,valueHint:`<format>`,description:`Audio format: mp3, pcm, wav, opus (default: mp3)`,choices:[`mp3`,`pcm`,`wav`,`opus`]},sampleRate:{type:`string`,valueHint:`<rate>`,description:`Audio sample rate in Hz (e.g. 24000)`},volume:{type:`string`,valueHint:`<volume>`,description:`Volume 0-100 (default: 50)`},rate:{type:`string`,valueHint:`<rate>`,description:`Speech rate 0.5-2.0 (default: 1.0)`},pitch:{type:`string`,valueHint:`<pitch>`,description:`Pitch multiplier 0.5-2.0 (default: 1.0)`},seed:{type:`string`,valueHint:`<seed>`,description:`Random seed 0-65535 for reproducible synthesis`},language:{type:`string`,valueHint:`<lang>`,description:`Language hint (e.g. zh, en, ja, ko, fr, de)`},instruction:{type:`string`,valueHint:`<text>`,description:`Natural language instruction to control speech style (e.g. "Use a gentle tone")`},enableSsml:{type:`switch`,description:`Enable SSML markup parsing in input text`},out:{type:`string`,valueHint:`<path>`,description:`Save audio to file (default: auto-generate in temp dir)`},stream:{type:`switch`,description:`Stream raw PCM audio to stdout (pipe to player)`},...n},exampleArgs:[`--list-voices --model cosyvoice-v3-flash`,`--text "Hello, I am Qwen" --voice <voice_id>`,`--text "Hello world" --voice <voice_id> --language en`,`--text-file script.txt --out speech.wav --voice <voice_id>`,`--text "Today is a good day" --voice <voice_id> --instruction "Use a gentle tone"`,`--text "Hello" --voice <voice_id> --format wav --sample-rate 24000`,`# Stream to audio player (macOS)`,`--text "Hello" --voice <voice_id> --stream | afplay -`,`# Pipe to ffplay`,`--text "Hello" --voice <voice_id> --stream | ffplay -nodisp -autoexit -f s16le -ar 24000 -ac 1 -`],validate:e=>{if(!e.listVoices){if(!e.text&&!e.textFile)return`Provide --text or --text-file.`;if(!e.voice)return`Missing required flag: --voice (use --list-voices; browse more voices: ${$e})`}},async run(e){let{settings:n,flags:r}=e,i=r.model||n.defaultSpeechModel||`cosyvoice-v3-flash`;if(r.listVoices){vr(i);return}let o=r.text||``;if(!o&&r.textFile){let e=r.textFile;try{o=gt(e,`utf-8`).trim()}catch{throw new t(`Cannot read text file: ${e}`,a.USAGE)}}let s=r.voice,c=r.language||void 0,l=r.instruction||void 0,u=r.format||void 0,d=r.sampleRate===void 0?void 0:Number(r.sampleRate),f=r.volume===void 0?void 0:Number(r.volume),p=r.rate===void 0?void 0:Number(r.rate),m=r.pitch===void 0?void 0:Number(r.pitch),h=r.seed===void 0?void 0:Number(r.seed),g=r.enableSsml===!0?!0:void 0,_=r.stream===!0,v=w(n.output),y={model:i,input:{text:o,voice:s,format:u,sample_rate:d,volume:f,rate:p,pitch:m,seed:h,language_hints:c?[c]:void 0,instruction:l,enable_ssml:g}};if(Be(y.input),n.dryRun){R({request:y},v);return}n.quiet||process.stderr.write(`[Model: ${i}] [Voice: ${s}]\n`),_?await xr(e.client,n,y,r,v):await br(e.client,n,y,r,v)}});async function br(e,n,r,i,o){let s=await U(B(i),n,()=>e.requestJson({path:ze(),method:`POST`,body:r})),c=s.map(e=>e.output?.audio?.url).filter(Boolean);if(c.length===0)throw new t(`API returned no audio URL.`,a.GENERAL);let l=await import(`path`),u=A(n,{subDir:`speech`}),d=await rt(c.map((e,t)=>{let n=i.out;if(!(n&&c.length===1)){let e=Date.now(),i=c.length>1?`_${String(t+1).padStart(3,`0`)}`:``,a=r.input.format??`mp3`;n=l.join(u,`tts_${e}${i}.${a}`)}return{url:e,destPath:n}}),I,{quiet:n.quiet});if(n.quiet)L(d.join(`
|
|
38
|
+
`));else if(d.length===1){let e=s[0].output?.audio?.expires_at;R({saved:d[0],audio_url:c[0],model:r.model,voice:r.input.voice,...e?{url_expires_at:e}:{}},o)}else R({saved:d,audio_urls:c,total:d.length,model:r.model,voice:r.input.voice},o)}async function xr(e,t,n,r,i){let a=await e.request({path:ze(),method:`POST`,body:n,stream:!0,headers:{Accept:`text/event-stream`,"X-DashScope-SSE":`enable`}}),o=r.out,s=o?mt(o):null,c;try{for await(let e of O(a)){if(!e.data||e.data===`[DONE]`)continue;let n;try{n=JSON.parse(e.data)}catch{continue}let r=n.output?.audio?.data;if(r){let e=Buffer.from(r,`base64`);s?s.write(e)||await new Promise(e=>s.once(`drain`,()=>e())):process.stdout.write(e)}if(n.output?.finish_reason===`stop`){c=n.output?.audio?.url,c&&!t.quiet&&process.stderr.write(`\nFull audio URL: ${c}\n`);break}}}finally{s&&(await new Promise((e,t)=>{s.on(`finish`,e),s.on(`error`,t),s.end()}),!t.quiet&&o&&process.stderr.write(`Saved: ${o}\n`))}o&&R({saved:o,...c?{audio_url:c}:{},model:n.model,voice:n.input.voice},i)}var Sr=x({description:`Recognize speech from audio files (FunAudio-ASR)`,auth:`apiKey`,usageArgs:`--url <audio-url> [flags]`,flags:{url:{type:`array`,valueHint:`<url>`,description:`Audio file URL or local file path (repeatable, max 100)`,required:!0},model:{type:`string`,valueHint:`<model>`,description:`Model ID (default: fun-asr)`},language:{type:`string`,valueHint:`<lang>`,description:`Language hint (e.g. zh, en, ja)`},diarization:{type:`switch`,description:`Enable automatic speaker diarization`},speakerCount:{type:`number`,valueHint:`<n>`,description:`Expected number of speakers (requires --diarization)`},vocabularyId:{type:`string`,valueHint:`<id>`,description:`Hot-word vocabulary ID for improved accuracy`},channelId:{type:`number`,valueHint:`<n>`,description:`Audio channel ID (default: 0)`},out:{type:`string`,valueHint:`<path>`,description:`Save full transcription result to JSON file`},...e,pollInterval:{type:`number`,valueHint:`<seconds>`,description:`Polling interval in seconds (default: 2)`}},exampleArgs:[`--url https://example.com/audio.mp3`,`--url https://example.com/a.mp3 --url https://example.com/b.mp3`,`--url https://example.com/meeting.wav --diarization --speaker-count 3`,`--url https://example.com/audio.mp3 --language zh`,`--url https://example.com/audio.mp3 --vocabulary-id vocab-abc123`,`--url https://example.com/audio.mp3 --out result.json`,`--url https://example.com/audio.mp3 --async --quiet`],async run(e){let{settings:n,flags:r}=e,i=[];Array.isArray(r.url)?i=r.url:typeof r.url==`string`&&(i=[r.url]);let o=r.speakerCount,s=r.diarization===!0;if(o!==void 0&&!s)throw new t(`--speaker-count requires --diarization to be enabled.
|
|
39
|
+
Hint: Add --diarization flag to enable speaker separation.`,a.USAGE);let c=r.model||`fun-asr`,l=w(n.output),u=await Promise.all(i.map(t=>e.client.uploadFile(t,c))),d=r.channelId,f=r.language,p=r.vocabularyId,m={model:c,input:{file_urls:u},parameters:{channel_id:d===void 0?[0]:[d],language_hints:f?[f]:void 0,diarization_enabled:s?!0:void 0,speaker_count:o,vocabulary_id:p}};if(Be(m.parameters),n.dryRun){R({request:m,mode:`async`},l);return}n.quiet||process.stderr.write(`[Model: ${c}] [Mode: async] [Files: ${u.length}]\n`),await Cr(e.client,n,m,r,l,u.length)}});async function Cr(e,n,r,i,o,s){let c=(await e.requestJson({path:Re(),method:`POST`,body:r,async:!0})).output.task_id;if(i.async){R({task_id:c},o);return}let l=i.pollInterval??2,u=await H(e,n,{url:e.url(M(c)),intervalSec:l,timeoutSec:n.timeout,isComplete:e=>e.output.task_status===`SUCCEEDED`,isFailed:e=>e.output.task_status===`FAILED`,getStatus:e=>e.output.task_status,getErrorMessage:e=>e.output.message}),d=u.output.results??[];if(d.length===0){R({task_id:c,status:u.output.task_status},o);return}let f=[];for(let e=0;e<d.length;e++){let n=d[e],r=s>1;if(r&&process.stdout.write(`=== [${e+1}/${d.length}] ${n.file_url??``} ===\n`),n.subtask_status===`FAILED`){let e=n.message??n.code??`unknown error`;process.stdout.write(`[FAILED] ${n.file_url??``} — ${e}\n`),r&&process.stdout.write(`
|
|
65
40
|
`);continue}if(!n.transcription_url){r&&process.stdout.write(`
|
|
66
|
-
`);continue}let
|
|
67
|
-
`);else
|
|
68
|
-
`)}if(
|
|
69
|
-
`),
|
|
70
|
-
`),process.
|
|
71
|
-
`),process.stdout.write(
|
|
72
|
-
`)
|
|
73
|
-
`)}}function
|
|
74
|
-
`);return}
|
|
75
|
-
`),process.
|
|
76
|
-
`);
|
|
77
|
-
`)
|
|
78
|
-
`);for(
|
|
79
|
-
`)}
|
|
80
|
-
`)}
|
|
81
|
-
`),process.exit(1));let l=ii(n);if(a===`json`){if(!l){G({period:{start:Q(c),end:Q(s),days:r},modelsCalled:0,successfulCalls:0},a);return}G({period:{start:Q(c),end:Q(s),days:r},modelsCalled:l.modelCount??0,successfulCalls:l.callSuccessCount??0,usages:(l.usages??[]).map(e=>({key:e.key,value:e.value,unit:e.unit,label:si[e.key]?.en??e.key}))},a);return}if(!l){process.stdout.write(`No usage data found.
|
|
82
|
-
`);return}li(l,c,s,r,e.noColor)}}});async function fi(e){let t=await Ot(e,`utf-8`).catch(e=>{process.stderr.write(`Error: cannot read pipeline file: ${e.message}\n`),process.exit(2)}),n=At(e).toLowerCase(),r;if(n===`.yaml`||n===`.yml`){let{parse:e}=await import(`yaml`);r=e(t)}else try{r=JSON.parse(t)}catch{let{parse:e}=await import(`yaml`);r=e(t)}return r}var pi=y({description:`Run a pipeline workflow definition`,skipDefaultApiKeySetup:!0,usageArgs:`<file> [flags]`,options:[{flag:`--input <json>`,description:`Runtime input as inline JSON`},{flag:`--input-file <path>`,description:`Runtime input from a JSON file`},{flag:`--concurrency <n>`,description:`Max parallel steps (default: 1)`,type:`number`},{flag:`--events <format>`,description:`Emit lifecycle events: jsonl`},{flag:`--timeout <seconds>`,description:`Default step timeout in seconds`,type:`number`}],exampleArgs:[`workflow.yaml --input '{"brief":"hello"}'`,`workflow.json --input-file inputs.json --concurrency 3`,`workflow.yaml --dry-run`,`workflow.json --events jsonl`,`workflow.yaml --output json`],async run(e,t){let n=(t._positional??[])[0];n||(process.stderr.write(`Error: pipeline file is required\nUsage: ${V(e,`<file>`)}\n`),process.exit(2)),lt();let r=t.events;r!==void 0&&r!==`jsonl`&&(process.stderr.write(`Error: unsupported --events format: ${r}. Supported: jsonl\n`),process.exit(2));let i=jt(n),a=await fi(i),o=await mi(t),s=kt(i);if(r===`jsonl`){for await(let e of ht(a,o,{concurrency:t.concurrency,basePath:s,dryRun:t.dryRun,timeoutSeconds:t.timeout}))process.stdout.write(JSON.stringify(e)+`
|
|
83
|
-
`);return}let c=await at(a,o,{concurrency:t.concurrency,basePath:s,dryRun:t.dryRun,timeoutSeconds:t.timeout,onEvent:t.verbose?hi:void 0});e.output===`json`?G(c,`json`):_i(c),c.status===`failed`&&(process.exitCode=1)}});async function mi(e){let t=e.input,n=e.inputFile;if(t&&n&&(process.stderr.write(`Error: use --input or --input-file, not both
|
|
84
|
-
`),process.exit(2)),t)return JSON.parse(t);if(n){let e=await Ot(jt(n),`utf-8`);return JSON.parse(e)}return{}}function hi(e){let t=`[${e.type}]`;if(`stepCount`in e){process.stderr.write(`${t} ${e.stepCount} step${e.stepCount===1?``:`s`}\n`);return}`step`in e&&e.step?process.stderr.write(`${t} ${gi(e.step)}\n`):process.stderr.write(`${t}\n`)}function gi(e){return`${e.index!==void 0&&e.total!==void 0?`${e.index}/${e.total} `:``}${e.id} (${e.type})`}function _i(e){let t=e.status===`succeeded`?`+`:e.status===`failed`?`x`:`~`;process.stdout.write(`\nPipeline ${e.status} [${t}]\n\n`);for(let t of e.steps){let e=` [${t.status===`succeeded`?`+`:t.status===`failed`?`x`:t.status===`skipped`?`-`:`~`}] ${t.id} (${t.type}) — ${t.status}`;t.skipReason&&(e+=` (${t.skipReason})`),t.error&&(e+=`: ${t.error.message}`),process.stdout.write(e+`
|
|
41
|
+
`);continue}let i=await fetch(n.transcription_url,{headers:He()});if(!i.ok)throw new t(`Failed to download transcription: HTTP ${i.status}`,a.GENERAL);let o=await i.json();f.push(o);let c=o.transcripts;if(c&&c.length>0)for(let e of c)if(e.sentences&&e.sentences.length>0)for(let t of e.sentences){let e=t.speaker_id===void 0?``:` [Speaker ${t.speaker_id}]`;process.stdout.write(`${t.text}${e}\n`)}else e.text&&process.stdout.write(e.text+`
|
|
42
|
+
`);else L(JSON.stringify(o));r&&process.stdout.write(`
|
|
43
|
+
`)}if(i.out){let e=i.out,t=f.length===1?f[0]:f;vt(e,JSON.stringify(t,null,2)+`
|
|
44
|
+
`),n.quiet||process.stderr.write(`Full result saved to: ${e}\n`)}}var wr=x({description:`Upload a local file to DashScope temporary storage (48h)`,auth:`apiKey`,usageArgs:`--file <path> --model <model>`,flags:{file:{type:`string`,valueHint:`<path>`,description:`Local file to upload (image, video, audio)`,required:!0},model:{type:`string`,valueHint:`<model>`,description:`Target model name (file is bound to this model)`,required:!0}},exampleArgs:[`--file photo.jpg --model qwen3-vl-plus`,`--file video.mp4 --model wan2.1-t2v-plus`,`--file audio.wav --model qwen3-asr-flash`,`--file cat.png --model qwen-image-2.0`],async run(e){let{settings:t,flags:n}=e,r=n.file,i=n.model,a=w(t.output);if(t.dryRun){R({action:`upload`,file:r,model:i},a);return}let o=await e.client.uploadFile(r,i);t.quiet?L(o):R({url:o,model:i,expires_in:`48 hours`,note:`When using this URL in API calls, add header: X-DashScope-OssResourceResolve: enable`},a)}}),Tr=x({description:`Call a Bailian console API via the CLI gateway`,auth:`console`,usageArgs:`--api <api> --data <json> [flags]`,flags:{api:{type:`string`,valueHint:`<api>`,description:`API name (e.g. zeldaEasy.broadscope-bailian.memory-library.getLibraries)`,required:!0},data:{type:`string`,valueHint:`<json>`,description:`Request data as JSON string`,required:!0}},exampleArgs:[`--api zeldaEasy.broadscope-bailian.freeTrial.queryFreeTierQuota --data '{"queryFreeTierQuotaRequest":{"models":["qwen3-max"]}}'`,`--api some.api.name --data '{"key":"value"}' --console-region cn-beijing`],async run(e){let{settings:t,flags:n}=e,r=n.api,i=n.data,a;try{a=JSON.parse(i)}catch{throw new u(`--data must be valid JSON`)}let o=w(t.output);if(t.dryRun){R({api:r,data:a,...te(t)},o);return}R(await e.client.console(r,a),o)}});const Er=`zeldaEasy.broadscope-bailian.freeTrial.queryFreeTierQuota`;function Dr(e){return e.toLocaleString(`en-US`)}function Or(e){let t=new Date(e);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)}`}function kr(e){return e.quotaInitTotal?`${((e.quotaInitTotal-e.quotaTotal)/e.quotaInitTotal*100).toFixed(1)}%`:`-`}const Ar={Reasoning:`Text`,TG:`Text`,VU:`Text`,IG:`Vision`,VG:`Vision`,"Realtime-Omni":`Multimodal`,"Multimodal-Omni":`Multimodal`,ASR:`Audio`,TTS:`Audio`,"Voice-Replication":`Audio`,"Realtime-Text-to-Speech":`Audio`,"Realtime-Voice-Replication":`Audio`,"Realtime-ASR":`Audio`,"Realtime-Audio-Translate":`Audio`,ME:`Embedding`,TR:`Embedding`};function jr(e){for(let t of e){let e=Ar[t];if(e)return e}return`-`}function Mr(e,t,n){let r=P(process.stdout),i=[`Model`,`Type`,`Remaining/Total`,`Usage`,`Expires`,`Auto-Stop`],a=e.map(e=>{let r=e.quotaInitTotal!=null&&e.quotaTotal!=null,i=r?Dr(e.quotaTotal):`-`,a=r?Dr(e.quotaInitTotal):`-`,o=t.get(e.model);return[e.model,n.get(e.model)||`-`,r?`${i} / ${a}`:`-`,kr(e),e.quotaValidityPeriod?Or(e.quotaValidityPeriod):`-`,e.quotaStatus===`UNKNOWN`?`Unsupported`:o===!0?`ON`:o===!1?`OFF`:`-`]}),o=i.map((e,t)=>Math.max(F(e),...a.map(e=>F(e[t])))),s=i.length-1,c=i.map((e,t)=>r.bold(V(e,o[t]))).join(` `),l=o.map(e=>r.dim(`─`.repeat(e))).join(`──`);process.stdout.write(c+`
|
|
45
|
+
`),process.stdout.write(l+`
|
|
46
|
+
`);for(let e of a){let t=e.map((e,t)=>{if(t===s){if(e===`ON`)return r.green(V(e,o[t]));if(e===`OFF`)return r.yellow(V(e,o[t]))}return V(e,o[t])});process.stdout.write(t.join(` `)+`
|
|
47
|
+
`)}}function Nr(e){let t=e.data;if(!t)return[];let n=t.DataV2;return n?n.data?.data?.freeTierQuotas||[]:t.data?.freeTierQuotas||[]}function Pr(e){let t=e.data;if(!t)return[];let n=t.DataV2;return n?n.data?.data?.freeTierOnlyStatuses||[]:t.data?.freeTierOnlyStatuses||[]}async function Fr(e){let t=[],n=1;for(;;){let r=await T((t,n)=>e.console(t,n),{pageNo:n,pageSize:50});if(t.push(...r.models),t.length>=r.total)break;n++}return t.filter(e=>typeof e.model==`string`&&e.model).map(e=>({name:e.model,type:jr(e.capabilities||[])}))}var Ir=x({description:`Query free-tier quota for models (all models if --model is omitted)`,auth:`console`,usageArgs:`[--model <model>[,model2,...]] [flags]`,flags:{model:{type:`string`,valueHint:`<model>`,description:`Model name(s) to query, comma-separated for multiple; omit for all models`},expiring:{type:`string`,valueHint:`<days>`,description:`Only show quotas expiring within N days`},sort:{type:`string`,valueHint:`<field>`,description:`Sort by: remaining (ascending), expires (ascending)`,choices:[`remaining`,`expires`]}},exampleArgs:[``,`--model qwen3-max`,`--model qwen3-max,qwen-turbo`,`--expiring 30`,`--sort remaining`,`--model qwen-turbo --output json`,`--model qwen3-max --console-region cn-beijing`],async run(e){let{settings:t,flags:n}=e,r=n.model||void 0,i=Number(n.expiring)||0,a=n.sort||void 0,o=w(t.output),s,c=new Map;s=r?[...new Set(r.split(`,`).map(e=>e.trim()).filter(Boolean))]:[];let l={queryFreeTierQuotaRequest:{models:s}};if(t.dryRun){R({api:Er,data:l},o);return}if(r){let t=await Promise.all(s.map(t=>T((t,n)=>e.client.console(t,n),{name:t,pageSize:50})));for(let e=0;e<s.length;e++){let n=t[e].models.find(t=>t.model===s[e]);n&&c.set(s[e],jr(n.capabilities||[]))}}else{let t=await Fr(e.client);s=t.map(e=>e.name);for(let e of t)c.set(e.name,e.type);l.queryFreeTierQuotaRequest.models=s}let[u,d]=await Promise.all([e.client.console(Er,l),e.client.console(`zeldaEasy.broadscope-bailian.freeTrial.queryFreeTierOnlyStatus`,{queryFreeTierOnlyStatusRequest:{models:s}})]),f=Nr(u),p=r?f:f.filter(e=>e.quotaStatus===`VALID`&&e.quotaInitTotal>0);if(i>0){let e=Date.now()+i*24*60*60*1e3;p=p.filter(t=>t.quotaValidityPeriod>0&&t.quotaValidityPeriod<=e)}a===`remaining`?p.sort((e,t)=>(e.quotaInitTotal?e.quotaTotal/e.quotaInitTotal:0)-(t.quotaInitTotal?t.quotaTotal/t.quotaInitTotal:0)):a===`expires`&&p.sort((e,t)=>(e.quotaValidityPeriod??0)-(t.quotaValidityPeriod??0));let m=Pr(d),h=new Map(m.map(e=>[e.model,e.freeTierOnly]));if(o===`json`){R(p.map(e=>{let t=e.quotaInitTotal!=null&&e.quotaTotal!=null,n=t?e.quotaInitTotal-e.quotaTotal:0,r=h.get(e.model),i=e.quotaStatus===`UNKNOWN`?`unsupported`:r===!0?!0:r===!1?!1:null;return{model:e.model,type:c.get(e.model)||null,remaining:t?e.quotaTotal:null,total:t?e.quotaInitTotal:null,usagePercent:t&&e.quotaInitTotal>0?Math.round(n/e.quotaInitTotal*1e3)/10:null,expires:e.quotaValidityPeriod?Or(e.quotaValidityPeriod):null,autoStop:i}}),o);return}if(p.length===0){process.stdout.write(`No free-tier quota found.
|
|
48
|
+
`);return}Mr(p,h,c)}});function q(e,t){let n=e[t];if(n&&typeof n==`object`&&!Array.isArray(n))return n}function Lr(e){let t=q(e,`data`);if(!t)return e;let n=q(t,`DataV2`);if(n){let e=q(n,`data`);return(e?q(e,`data`):void 0)??e??n}return q(t,`data`)??t}async function Rr(e,t,n,r){let i;for(let a=0;a<20;a++){let a={[n]:i?{taskId:i}:{models:r}},o=await e.console(t,a),s=Lr(o);if(s.taskId&&Object.keys(s).length===1){i=s.taskId,await new Promise(e=>setTimeout(e,500));continue}return o}return null}async function zr(e){let t=[],n=1;for(;;){let r=await T((t,n)=>e.console(t,n),{pageNo:n,pageSize:50});if(t.push(...r.models),t.length>=r.total)break;n++}return t.map(e=>e.model).filter(Boolean)}var Br=x({description:`Enable or disable auto-stop for free-tier models. Enables by default; use --off to disable`,auth:`console`,usageArgs:`<--model <model>[,model2,...] | --all> [--off] [flags]`,flags:{model:{type:`string`,valueHint:`<model>`,description:`Model name(s), comma-separated for multiple`},all:{type:`switch`,description:`Apply to all free-tier models`},on:{type:`switch`,description:`Enable auto-stop (default behavior)`},off:{type:`switch`,description:`Disable auto-stop`}},exampleArgs:[`--model qwen3-max`,`--model qwen3-max,qwen-turbo`,`--all`,`--on --model qwen3-max`,`--off --model qwen3-max`,`--off --all`],validate:e=>!e.model&&!e.all?`Provide --model <model>[,model2,...] or --all.`:void 0,async run(e){let{settings:t,flags:n}=e,r=n.model||void 0,i=!!n.off,a=w(t.output),o;o=r?[...new Set(r.split(`,`).map(e=>e.trim()).filter(Boolean))]:[];let s=i?`zeldaEasy.broadscope-bailian.freeTrial.batchDeactivateFreeTierOnly`:`zeldaEasy.broadscope-bailian.freeTrial.batchActivateFreeTierOnly`,c=i?`BatchDeactivateFreeTierOnlyRequest`:`BatchActivateFreeTierOnlyRequest`;if(t.dryRun){R({api:s,data:{[c]:{models:o}}},a);return}if(r||(o=await zr(e.client)),i){let[t,n]=await Promise.all([e.client.console(`zeldaEasy.broadscope-bailian.freeTrial.queryFreeTierQuota`,{queryFreeTierQuotaRequest:{models:o}}),e.client.console(`zeldaEasy.broadscope-bailian.freeTrial.queryFreeTierOnlyStatus`,{queryFreeTierOnlyStatusRequest:{models:o}})]),r=Lr(t).freeTierQuotas??[],i=new Map(r.map(e=>[e.model,e])),a=Lr(n).freeTierOnlyStatuses??[],l=new Map(a.map(e=>[e.model,e.freeTierOnly]));for(let t of o){if(l.get(t)===!1){process.stderr.write(`Auto-stop is already disabled for "${t}".\n`);continue}let n=i.get(t);if(n&&n.quotaTotal>0&&l.get(t)===!0){process.stderr.write(`Cannot disable auto-stop for "${t}": free-tier quota has not been fully consumed. Please disable auto-stop after the quota is exhausted.\n`);continue}await Rr(e.client,s,c,[t]),process.stdout.write(`Disabled auto-stop for "${t}".\n`)}return}let l=[];for(let t of o){let n=await Rr(e.client,s,c,[t]);if(a===`json`){l.push(n);continue}if(n){let e=Lr(n).failureModels??[];e.length>0?process.stderr.write(`Failed to enable auto-stop for "${t}" (${e[0].errorCode}).\n`):process.stdout.write(`Enabled auto-stop for "${t}".\n`)}else process.stderr.write(`Warning: operation timed out for "${t}".\n`)}a===`json`&&R(l,a)}});const Vr=`zeldaEasy.bailian-telemetry.model.getModelUsageStatistic`,Hr=`zeldaEasy.bailian-telemetry.model.listModelUsageStatisticData`;function J(e,t){let n=e[t];if(n&&typeof n==`object`&&!Array.isArray(n))return n}function Ur(e){let t=J(e,`data`);if(!t)return e;let n=J(t,`DataV2`);if(n){let e=J(n,`data`);return(e?J(e,`data`):void 0)??e??n}return J(t,`data`)??t}async function Wr(e,t,n){let r;for(let i=0;i<30;i++){let i=r?{reqDTO:{...n,asyncTaskId:r}}:{reqDTO:n},a=await e.console(t,i),o=Ur(a);if(o.taskId&&Object.keys(o).length===1){r=o.taskId,await new Promise(e=>setTimeout(e,500));continue}return a}return null}function Gr(e,n){if(e.workspaceId)return e.workspaceId;throw new t(`workspace-id is required. Set via --workspace-id, BAILIAN_WORKSPACE_ID, or \`${n} config set workspace_id <id>\`.`,a.GENERAL,`Run \`${n} workspace list\` to view available workspaces.`)}function Y(e){return e.toLocaleString(`en-US`)}function X(e){let t=new Date(e);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)}`}function Kr(e){let t=Ur(e);if(t.callSuccessCount!==void 0||t.usages!==void 0)return t}function qr(e){let t=Ur(e);return{list:t.list??[],totalCount:t.totalCount??0,maxResults:t.maxResults??0}}function Jr(e){let t={};if(e.usages&&Array.isArray(e.usages))for(let n of e.usages)n.key&&n.value!=null&&(t[n.key]=n.value);if(e.usage&&typeof e.usage==`object`)for(let[n,r]of Object.entries(e.usage))r!=null&&(t[n]=r);return t}const Yr={total_token:{en:`Total Tokens`,unit:`tokens`},input_token:{en:`Input Tokens`,unit:`tokens`},output_token:{en:`Output Tokens`,unit:`tokens`},input_token_cache:{en:`Cached Tokens`,unit:`tokens`},input_token_cache_read:{en:`Cache Read`,unit:`tokens`},input_token_cache_creation:{en:`Cache Creation`,unit:`tokens`},thinking_input_token:{en:`Thinking Input`,unit:`tokens`},thinking_output_token:{en:`Thinking Output`,unit:`tokens`},text_input_token:{en:`Text Input`,unit:`tokens`},purein_text_output_token:{en:`Text Output`,unit:`tokens`},embedding_token:{en:`Embedding`,unit:`tokens`},image_number:{en:`Images`,unit:`images`},video_duration:{en:`Video Duration`,unit:`sec`},content_duration:{en:`Audio Duration`,unit:`sec`},tts_text_number:{en:`TTS Chars`,unit:`chars`},total_token_avg:{en:`Avg Tokens/Req`}};function Xr(e){let t=e.unit?` [${e.unit}]`:``;return`${e.en}${t}`}function Zr(e,t,n,r){let i=P(process.stdout);process.stdout.write(`${i.dim(`Time Range Period:`)} ${X(t)} ~ ${X(n)} ${i.dim(`(${r} days)`)}\n\n`);let a=[[`Models Called`,Y(e.modelCount??0)],[`Successful Calls`,Y(e.callSuccessCount??0)]];for(let t of e.usages??[]){let e=Yr[t.key],n=e?Xr(e):t.key;a.push([n,Y(t.value)])}let o=Math.max(...a.map(([e])=>F(e)));for(let[e,t]of a)process.stdout.write(`${i.bold(V(e,o+2))}${t}\n`)}function Qr(e,t,n,r){let i=P(process.stdout);if(process.stdout.write(`${i.dim(`Time Range Period:`)} ${X(t)} ~ ${X(n)} ${i.dim(`(${r} days)`)}\n\n`),e.length===0){process.stdout.write(`No usage data found.
|
|
49
|
+
`);return}let a=new Set,o=e.map(e=>{let t=Jr(e);for(let e of Object.keys(t))a.add(e);return t}),s=[...a].sort((e,t)=>{let n=[`total_token`,`input_token`,`output_token`,`input_token_cache`,`image_number`,`video_duration`,`content_duration`,`tts_text_number`],r=n.indexOf(e),i=n.indexOf(t);return(r===-1?999:r)-(i===-1?999:i)}),c=[`Model`,`Calls`,...s.map(e=>Yr[e]?.en??e)],l=e.map((e,t)=>[e.model,Y(e.callSuccessCount??0),...s.map(e=>{let n=o[t][e];return n==null?`-`:Y(n)})]),u=c.map((e,t)=>Math.max(F(e),...l.map(e=>F(e[t])))),d=c.map((e,t)=>i.bold(V(e,u[t]))).join(` `),f=u.map(e=>i.dim(`─`.repeat(e))).join(`──`);process.stdout.write(d+`
|
|
50
|
+
`),process.stdout.write(f+`
|
|
51
|
+
`);for(let e of l){let t=e.map((e,t)=>V(e,u[t]));process.stdout.write(t.join(` `)+`
|
|
52
|
+
`)}process.stdout.write(i.dim(`\nTotal: ${e.length} models`)+`
|
|
53
|
+
`)}var $r=x({description:`Query model usage statistics`,auth:`console`,usageArgs:`[--model <model>] [--days <days>] [flags]`,flags:{model:{type:`string`,valueHint:`<model>`,description:`Model name(s), comma-separated; omit for overview`},days:{type:`string`,valueHint:`<days>`,description:`Number of days (default: 7)`},type:{type:`string`,valueHint:`<type>`,description:`Model type: Text, Vision, Multimodal, Audio, Embedding`}},exampleArgs:[``,`--days 30`,`--model qwen-turbo`,`--model qwen-turbo --days 7`,`--model qwen3.6-plus,deepseek-v4-pro`,`--type Text --days 14`,`--output json`],async run(e){let{identity:n,settings:r,flags:i}=e,o=i.model||void 0,s=Number(i.days)||7,c=i.type||void 0,l=w(r.output),u=Gr(r,n.binName),d=Date.now(),f=d-s*24*60*60*1e3;if(o){let t=[...new Set(o.split(`,`).map(e=>e.trim()).filter(Boolean))],n={startTime:f,endTime:d,modelCallSource:`Online`,filterWorkspaceId:u,maxResults:50,skip:0,sortField:`success_count`,sortOrder:`DESC`};if(c&&(n.obsModelType=c),r.dryRun){R({api:Hr,data:{reqDTO:{...n,model:t.join(`,`)}}},l);return}let i=await Promise.all(t.map(t=>Wr(e.client,Hr,{...n,model:t}))),a=[];for(let e of i){if(!e)continue;let t=qr(e);a.push(...t.list)}if(l===`json`){let e=a.map(e=>{let t=Jr(e),n={model:e.model,successfulCalls:e.callSuccessCount??0};for(let[e,r]of Object.entries(t))n[e]=r;return n});R({period:{start:X(f),end:X(d),days:s},items:e},l);return}Qr(a,f,d,s)}else{let n={startTime:f,endTime:d,modelCallSource:`Online`,filterWorkspaceId:u};if(c&&(n.obsModelType=c),r.dryRun){R({api:Vr,data:{reqDTO:n}},l);return}let i=await Wr(e.client,Vr,n);if(!i)throw new t(`Request timed out.`,a.TIMEOUT);let o=Kr(i);if(l===`json`){if(!o){R({period:{start:X(f),end:X(d),days:s},modelsCalled:0,successfulCalls:0},l);return}R({period:{start:X(f),end:X(d),days:s},modelsCalled:o.modelCount??0,successfulCalls:o.callSuccessCount??0,usages:(o.usages??[]).map(e=>({key:e.key,value:e.value,unit:e.unit,label:Yr[e.key]?.en??e.key}))},l);return}if(!o){process.stdout.write(`No usage data found.
|
|
54
|
+
`);return}Zr(o,f,d,s)}}});async function ei(e){let t=await St(e,`utf-8`).catch(e=>{throw new u(`cannot read pipeline file: ${e.message}`)}),n=wt(e).toLowerCase(),r;if(n===`.yaml`||n===`.yml`){let{parse:e}=await import(`yaml`);r=e(t)}else try{r=JSON.parse(t)}catch{let{parse:e}=await import(`yaml`);r=e(t)}return r}var ti=x({description:`Run a pipeline workflow definition`,auth:`none`,usageArgs:`--file <path> [flags]`,flags:{file:{type:`string`,valueHint:`<path>`,description:`Pipeline definition file (YAML/JSON)`,required:!0},input:{type:`string`,valueHint:`<json>`,description:`Runtime input as inline JSON`},inputFile:{type:`string`,valueHint:`<path>`,description:`Runtime input from a JSON file`},concurrency:{type:`number`,valueHint:`<n>`,description:`Max parallel steps (default: 1)`},events:{type:`string`,valueHint:`<format>`,description:`Emit lifecycle events: jsonl`,choices:[`jsonl`]},stepTimeout:{type:`number`,valueHint:`<seconds>`,description:`Default step timeout in seconds`}},exampleArgs:[`--file workflow.yaml --input '{"brief":"hello"}'`,`--file workflow.json --input-file inputs.json --concurrency 3`,`--file workflow.yaml --dry-run`,`--file workflow.json --events jsonl`,`--file workflow.yaml --output json`],validate:e=>e.input&&e.inputFile?`use --input or --input-file, not both`:void 0,async run(e){let{settings:t,flags:n}=e,r=n.file;st();let i=n.events,a=Tt(r),o=await ei(a),s=await ni(n),c=Ct(a);if(i===`jsonl`){for await(let e of lt(o,s,{concurrency:n.concurrency,basePath:c,dryRun:t.dryRun,timeoutSeconds:n.stepTimeout}))process.stdout.write(JSON.stringify(e)+`
|
|
55
|
+
`);return}let l=await it(o,s,{concurrency:n.concurrency,basePath:c,dryRun:t.dryRun,timeoutSeconds:n.stepTimeout,onEvent:t.verbose?ri:void 0});t.output===`json`?R(l,`json`):ai(l),l.status===`failed`&&(process.exitCode=1)}});async function ni(e){let t=e.input,n=e.inputFile;if(t)return JSON.parse(t);if(n){let e=await St(Tt(n),`utf-8`);return JSON.parse(e)}return{}}function ri(e){let t=`[${e.type}]`;if(`stepCount`in e){process.stderr.write(`${t} ${e.stepCount} step${e.stepCount===1?``:`s`}\n`);return}`step`in e&&e.step?process.stderr.write(`${t} ${ii(e.step)}\n`):process.stderr.write(`${t}\n`)}function ii(e){return`${e.index!==void 0&&e.total!==void 0?`${e.index}/${e.total} `:``}${e.id} (${e.type})`}function ai(e){let t=e.status===`succeeded`?`+`:e.status===`failed`?`x`:`~`;process.stdout.write(`\nPipeline ${e.status} [${t}]\n\n`);for(let t of e.steps){let e=` [${t.status===`succeeded`?`+`:t.status===`failed`?`x`:t.status===`skipped`?`-`:`~`}] ${t.id} (${t.type}) — ${t.status}`;t.skipReason&&(e+=` (${t.skipReason})`),t.error&&(e+=`: ${t.error.message}`),process.stdout.write(e+`
|
|
85
56
|
`)}process.stdout.write(`
|
|
86
|
-
`)}var
|
|
87
|
-
`);for(let e of
|
|
88
|
-
`);for(let e of
|
|
89
|
-
`),{padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:1,right:0},borderColor
|
|
90
|
-
`),{padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:1,right:0},borderColor
|
|
91
|
-
`)}function
|
|
57
|
+
`)}var oi=x({description:`Validate a pipeline definition without executing`,auth:`none`,usageArgs:`--file <path>`,flags:{file:{type:`string`,valueHint:`<path>`,description:`Pipeline definition file (YAML/JSON)`,required:!0}},exampleArgs:[`--file workflow.yaml`,`--file workflow.json --output json`],async run(e){let{settings:t,flags:n}=e,r=n.file;st();let i=await ei(Tt(r)),a=tt(i),o=a.length===0?et(i):[];if(t.output===`json`)R({valid:a.length===0,issues:a,...o.length>0?{hints:o}:{}},`json`),a.length>0&&(process.exitCode=1);else if(a.length===0){process.stdout.write(`Pipeline definition is valid.
|
|
58
|
+
`);for(let e of o)process.stderr.write(` hint: ${e}\n`)}else{process.stderr.write(`Pipeline validation failed:
|
|
59
|
+
`);for(let e of a)process.stderr.write(` - ${e}\n`);process.exitCode=1}}});function si(e){return e>=1e6?`${(e/1e6).toFixed(e%1e6==0?0:1)}M`:e>=1e3?`${(e/1e3).toFixed(e%1e3==0?0:1)}K`:String(e)}const ci={Text:`Text`,Image:`Image`,Video:`Video`,Audio:`Audio`},li={TG:`Text Gen`,VU:`Vision`,IG:`Image Gen`,VG:`Video Gen`,TTS:`Text-to-Speech`,ASR:`Speech-to-Text`,Reasoning:`Reasoning`},ui={low:`Cost-Effective`,medium:`Balanced`,high:`High Investment`},di={flagship:`Flagship`,balanced:`Balanced`,"cost-optimized":`Value`},fi={scoped:`Scoped`,comparison:`Comparison`,alternative:`Alternative`};function pi(e){return ut(e)?Dt:new Ot({level:0})}function mi(e){let t=pi(process.stdout),n=ut(process.stdout),r=[];r.push(t.cyan.bold(`Intent Analysis`)),e.taskSummary&&(r.push(``),r.push(e.taskSummary)),e.scenarioHints.length&&(r.push(``),r.push(`${t.dim(`Scenario`)} ${e.scenarioHints.join(` · `)}`));let i=e.inputModality.map(e=>ci[e]??e),a=e.outputModality.map(e=>ci[e]??e);if(i.length||a.length){r.push(``);let e=[];i.length&&e.push(`${t.dim(`Input`)} ${i.join(`, `)}`),a.length&&e.push(`${t.dim(`Output`)} ${a.join(`, `)}`),r.push(e.join(` `))}let o=e.requiredCapabilities.map(e=>li[e]??e);o.length&&r.push(`${t.dim(`Capabilities`)} ${o.join(`, `)}`);let s=ui[e.budget]??e.budget,c=di[e.qualityPreference]??e.qualityPreference;r.push(``),r.push(`${t.dim(`Budget`)} ${s} ${t.dim(`Quality`)} ${c}`);let l=e.modelPreference;if(l&&l.mode!==`unconstrained`){r.push(``);let e=fi[l.mode]??l.mode,n=[t.dim(`Mode`)+` ${t.yellow(e)}`];l.targets?.length&&n.push(t.dim(`Targets`)+` ${l.targets.join(`, `)}`),l.excludes?.length&&n.push(t.dim(`Excludes`)+` ${l.excludes.join(`, `)}`),r.push(n.join(` `))}if(e.segments?.length){r.push(``),r.push(t.dim(`Pipeline`));for(let[n,i]of e.segments.entries()){let e=i.outputModality.map(e=>ci[e]??e).join(`, `);r.push(` ${t.dim(`${n+1}.`)} ${i.step}${e?t.dim(` → ${e}`):``}`)}}return Et(r.join(`
|
|
60
|
+
`),{padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:1,right:0},borderColor:n?`cyan`:void 0,borderStyle:`round`,dimBorder:n})}const hi=[`Best Pick`,`Runner-Up`,`Alternative`];function gi(e,t,n,r){let i=[n.green.bold,n.blue.bold,n.magenta.bold][t]??n.white.bold,a=hi[t]??`#${t+1}`,o=[];o.push(i(`⬢ #${t+1} — ${a}`)),o.push(``),o.push(`${n.bold(e.name)} ${n.dim(`(${e.model})`)}`),o.push(``),o.push(`${n.cyan(`Why`)} ${e.reason}`),e.highlights.length&&(o.push(``),o.push(e.highlights.map(e=>n.bgGray.white(` ${e} `)).join(` `)));let s=[];e.contextWindow&&s.push(`Context ${si(e.contextWindow)}`),e.maxOutputTokens&&s.push(`Max Output ${si(e.maxOutputTokens)}`),s.length&&(o.push(``),o.push(n.dim(s.join(` · `))));let c=h(e.docUrl);return c&&(o.push(``),o.push(n.dim(`Docs ${c}`))),Et(o.join(`
|
|
61
|
+
`),{padding:{top:0,bottom:0,left:1,right:1},margin:{top:0,bottom:0,left:1,right:0},borderColor:r?`gray`:void 0,borderStyle:`round`,dimBorder:r})}function _i(e){let t=pi(process.stdout),n=ut(process.stdout);return e.map((e,r)=>gi(e,r,t,n)).join(`
|
|
62
|
+
`)}function vi(e,t){let n=pi(process.stdout),r=ut(process.stdout),i=[];i.push(` ${n.yellow.bold(`⚡ Pipeline`)} ${e}`);for(let[e,{step:a,recommendations:o,warnings:s}]of t.entries()){if(i.push(``),i.push(n.bold(` ━━━ Step ${e+1}: ${a} ━━━`)),s?.length)for(let e of s)i.push(` ${n.yellow(`⚠`)} ${n.yellow(e)}`);i.push(``),i.push(o.map((e,t)=>gi(e,t,n,r)).join(`
|
|
92
63
|
`))}return i.join(`
|
|
93
|
-
`)}function
|
|
94
|
-
`),
|
|
95
|
-
`)
|
|
96
|
-
`);let
|
|
97
|
-
`)
|
|
98
|
-
`)
|
|
99
|
-
`),process.stdout.write(
|
|
100
|
-
`);
|
|
101
|
-
`)
|
|
102
|
-
`)
|
|
103
|
-
`);
|
|
104
|
-
`);return}let o=i.map((e,t)=>Math.max(
|
|
105
|
-
`),process.stdout.write(
|
|
106
|
-
`);for(let e of
|
|
107
|
-
`);process.stdout.write(
|
|
108
|
-
`)}var Ki=
|
|
109
|
-
`),
|
|
110
|
-
`)
|
|
111
|
-
`),process.
|
|
112
|
-
`)
|
|
113
|
-
`)
|
|
114
|
-
`)
|
|
115
|
-
`);
|
|
116
|
-
`)}
|
|
117
|
-
`)
|
|
118
|
-
`);return}let l=s.map((e,t)=>Math.max(H(e),...c.map(e=>H(e.cells[t])))),u=s.map((e,t)=>n(J(e,l[t]))).join(` `),d=l.map(e=>r(`─`.repeat(e))).join(`──`);process.stdout.write(u+`
|
|
119
|
-
`),process.stdout.write(d+`
|
|
120
|
-
|
|
121
|
-
`)}process.stdout.write(r(`\nTotal: ${e.length} models`)+`
|
|
122
|
-
`)}var va=y({description:`Check current usage against rate limits`,skipDefaultApiKeySetup:!0,usageArgs:`[--model <model>] [flags]`,options:[{flag:`--model <model>`,description:`Model name(s), comma-separated`},{flag:`--period <minutes>`,description:`Query usage for the last N minutes (default: 2)`},{flag:`--console-region <region>`,description:`Console region`},{flag:`--console-site <site>`,description:`Console site: domestic, international`},{flag:`--console-switch-agent <uid>`,description:`Switch agent UID`,type:`number`}],exampleArgs:[``,`--model qwen3.6-plus`,`--period 5`,`--model qwen3.6-plus,qwen-turbo`,`--output json`],async run(e,t){let n=t.model||void 0,r=Number(t.period)||2;r<1&&(process.stderr.write(`Error: --period must be at least 1 minute.
|
|
123
|
-
`),process.exit(1));let i=r,a=C(e.output);if(e.dryRun){G({apis:[oa,sa],...w(e)},a);return}let o=await P(e),s=await ha(e,o.token);if(n){let e=new Set(n.split(`,`).map(e=>e.trim()).filter(Boolean));s=s.filter(t=>e.has(t.model))}if(s=s.filter(e=>e.qpmInfo),s.length===0){process.stdout.write(`No models found.
|
|
124
|
-
`);return}let c=await Promise.all(s.map(t=>ga(e,o.token,t.model,i))),l=s.map((e,t)=>{let n=e.qpmInfo,r=n[`model-default`],i=n[`user-spec`],a=ca(i,r?.count_limit_period)||ca(r),o=la(i,r?.usage_limit_period)||la(r);return{model:e.model,rpmUsage:c[t].rpm,rpmLimit:a,tpmUsage:c[t].tpm,tpmLimit:o}});if(a===`json`){G(l,a);return}_a(l,e.noColor)}}),ya=y({description:`Upload a dataset file (.jsonl) to Bailian`,usageArgs:`--file <path> [--purpose <name>] [--schema <chatml|dpo|cpt>] [--no-validate] [--full-validate]`,options:[{flag:`--file <path>`,description:`Local .jsonl dataset file (≤300MB)`,required:!0},{flag:`--purpose <name>`,description:`Dataset purpose tag (default: "fine-tune"; e.g. "evaluation")`},{flag:`--schema <s>`,description:`Record schema: "chatml" (SFT), "dpo" (chosen/rejected), or "cpt" (raw text). Default auto-detects per record.`},{flag:`--no-validate`,description:`Skip the local JSONL pre-flight check (not recommended)`,type:`boolean`},{flag:`--full-validate`,description:`JSON.parse every line instead of sampling (slower)`,type:`boolean`}],exampleArgs:[`--file train.jsonl`,`--file dpo.jsonl --schema dpo`,`--file cpt.jsonl --schema cpt`,`--file eval.jsonl --purpose evaluation`,`--file train.jsonl --full-validate`,`--file train.jsonl --no-validate`],notes:[`Only .jsonl is supported in this release. Three record schemas are`,`recognized: chatml = {messages:[...]} (SFT); dpo = {messages:[...],`,`chosen, rejected} where chosen/rejected are single assistant messages;`,`cpt = {text:"..."} (continual pre-training, raw text). With no --schema,`,`a record carrying chosen/rejected is validated as DPO, one with text (and`,`no messages) as CPT, otherwise as ChatML. Pass --schema dpo / cpt to`,`require that shape on every record, or --schema chatml to ignore the`,`preference / text fields. Other purposes may carry a different schema in`,`the future and would be served by a purpose-specific validator.`,`The dataset upload cap is 300MB per file.`,`Upload uses the OpenAI-compatible /compatible-mode/v1/files endpoint so`,`the purpose tag is persisted (the DashScope-native /api/v1/files drops it).`],async run(t,n){let r=n.file;r||K(`file`,`bl dataset upload --file <path>`);let o=n.purpose||`fine-tune`,s=!!n.noValidate,c=!!n.fullValidate,l=ke(n.schema),u=C(t.output);if(!s){let n=await Ke(r,{fullValidate:c,schema:l});if(!n.valid){let t=[`Dataset validation failed for ${r}`,...n.errors.slice(0,10).map(E)];throw n.errors.length>10&&t.push(` … and ${n.errors.length-10} more error(s).`),t.push(``,"Hint: re-run `bl dataset validate --file <path>` for the full report,",` or pass --no-validate to skip this check at your own risk.`),new e(t.join(`
|
|
125
|
-
`),i.GENERAL)}if(n.warnings.length>0&&!t.quiet){process.stderr.write(`Dataset validation passed with ${n.warnings.length} warning(s):\n`);for(let e of n.warnings.slice(0,5))process.stderr.write(`${E(e)}\n`);n.warnings.length>5&&process.stderr.write(` … and ${n.warnings.length-5} more.\n`)}}if(t.dryRun){G({action:`dataset.upload`,file:r,purpose:o,max_bytes:a,validate:!s,schema:l??`auto`},u);return}let d=await Ue(t,{filePath:r,purpose:o});t.quiet?W(d.file_id):u===`text`?W(`Uploaded ${d.name} → file_id=${d.file_id}`):G(d,u)}}),ba=y({description:`List uploaded dataset files`,usageArgs:`[--page <n>] [--page-size <n>] [--purpose <name>]`,options:[{flag:`--page <n>`,description:`Page number (default: 1)`,type:`number`},{flag:`--page-size <n>`,description:`Results per page (default: 10, max 100)`,type:`number`},{flag:`--purpose <name>`,description:`Filter by purpose (e.g. "fine-tune", "evaluation"). Omit to list all.`}],exampleArgs:[``,`--purpose fine-tune`,`--purpose evaluation --page-size 20`,`--output json`],async run(e,t){let n=C(e.output),r=t.page===void 0?void 0:t.page,i=t.pageSize===void 0?void 0:t.pageSize,a=t.purpose||void 0;if(e.dryRun){G({action:`dataset.list`,page:r,page_size:i,purpose:a},n);return}let o=await ve(e,{pageNo:r,pageSize:i,purpose:a}),s=o.data?.files??[],c=o.data?.total,l=s.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(n===`json`){G({items:l,total:c},n);return}if(l.length===0){W(`No dataset files found.`);return}let u=[`FILE_ID`,`NAME`,`SIZE`,`PURPOSE`],d=l.map(e=>[e.file_id,e.name,e.size,e.purpose]);for(let e of q(u,d))W(e);c!==void 0&&W(`\nTotal: ${c}`)}}),xa=y({description:`Get details of a single dataset file`,usageArgs:`--file-id <id>`,options:[{flag:`--file-id <id>`,description:`Dataset file ID (required)`,required:!0}],exampleArgs:[`--file-id file-xxx`,`--file-id file-xxx --output json`],async run(e,t){let n=t.fileId;n||K(`file-id`,`bl dataset get --file-id <id>`);let r=C(e.output);if(e.dryRun){G({action:`dataset.get`,file_id:n},r);return}let i=(await ae(e,n)).data;if(!i){W(`No data returned for ${n}`);return}let a=i.size===void 0?`?`:`${(i.size/1024).toFixed(1)} KB`,o={file_id:i.file_id??n,name:i.name??``,size:a,md5:i.md5??``,purpose:i.purpose??``,created_at:i.gmt_create??``,description:i.description??``};if(r===`json`){G(o,r);return}W(`file_id: ${o.file_id}`),W(`name: ${o.name}`),W(`size: ${o.size}`),o.md5&&W(`md5: ${o.md5}`),o.purpose&&W(`purpose: ${o.purpose}`),o.created_at&&W(`created_at: ${o.created_at}`),o.description&&W(`description: ${o.description}`)}}),Sa=y({description:`Delete a dataset file by ID`,usageArgs:`--file-id <id> [--yes]`,options:[{flag:`--file-id <id>`,description:`Dataset file ID (required)`,required:!0},{flag:`--yes`,description:`Skip the confirmation prompt`,type:`boolean`}],exampleArgs:[`--file-id file-id-xxx`,`--file-id file-id-xxx --yes`],async run(t,n){let r=n.fileId;r||K(`file-id`,`bl dataset delete --file-id <id>`);let a=C(t.output),o=!!n.yes;if(t.dryRun){G({action:`dataset.delete`,file_id:r},a);return}if(!o)if(D({nonInteractive:t.nonInteractive})){if(!await X({message:`Permanently delete dataset file ${r}? This cannot be undone.`,initialValue:!1})){W(`Aborted.`);return}}else throw new e(`Refusing to delete ${r} without --yes in non-interactive mode.`,i.USAGE,`Pass --yes to skip the confirmation prompt.`);let s=await b(t,r);t.quiet||a===`text`?W(`Deleted ${r}.`):G(s,a)}});function Ca(e){let t=[];return e.stats.totalRecords!==void 0&&t.push(`records: ${e.stats.totalRecords}`),e.stats.sampledRecords!==void 0&&t.push(`sampled: ${e.stats.sampledRecords}`),e.stats.bytes!==void 0&&t.push(`bytes: ${e.stats.bytes}`),e.stats.durationMs!==void 0&&t.push(`took: ${e.stats.durationMs}ms`),t}var wa=y({description:`Locally validate a dataset file (.jsonl) without uploading`,skipDefaultApiKeySetup:!0,usageArgs:`--file <path> [--full-validate] [--schema <chatml|dpo|cpt>]`,options:[{flag:`--file <path>`,description:`Local .jsonl dataset file`,required:!0},{flag:`--full-validate`,description:`JSON.parse every line instead of sampling (slower)`,type:`boolean`},{flag:`--schema <s>`,description:`Record schema: "chatml" (SFT), "dpo" (chosen/rejected), or "cpt" (raw text). Default auto-detects per record.`}],exampleArgs:[`--file train.jsonl`,`--file dpo.jsonl --schema dpo`,`--file cpt.jsonl --schema cpt`,`--file eval.jsonl --full-validate`,`--file train.jsonl --output json`],notes:[`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.`,`Schemas: chatml = {messages:[...]} (SFT); dpo = {messages:[...], chosen,`,`rejected} where chosen/rejected are single assistant messages; cpt =`,`{text:"..."} (continual pre-training, raw text). With no --schema, a`,`record carrying chosen/rejected is validated as DPO, one with text (and no`,`messages) as CPT, otherwise as ChatML. Pass --schema dpo / cpt to require`,`that shape on every record (strict), or --schema chatml to ignore the`,`preference / text fields. Use --full-validate to JSON.parse every line.`],async run(t,n){let r=n.file;r||K(`file`,`bl dataset validate --file <path>`);let a=!!n.fullValidate,o=ke(n.schema),s=C(t.output);if(t.dryRun){G({action:`dataset.validate`,file:r,full:a,schema:o??`auto`},s);return}let c=await Ke(r,{fullValidate:a,schema:o});if(s===`json`)G(c,s);else if(t.quiet)W(c.valid?`ok`:`fail`);else{W(`Dataset validation ${c.valid?`PASSED`:`FAILED`} for ${c.filePath}`);let e=Ca(c);if(e.length&&W(` ${e.join(` · `)}`),c.errors.length){W(`Errors (${c.errors.length}):`);for(let e of c.errors.slice(0,20))W(E(e));c.errors.length>20&&W(` … and ${c.errors.length-20} more.`)}if(c.warnings.length){W(`Warnings (${c.warnings.length}):`);for(let e of c.warnings.slice(0,10))W(E(e));c.warnings.length>10&&W(` … and ${c.warnings.length-10} more.`)}}if(!c.valid)throw new e(`Dataset validation failed: ${c.errors.length} error(s).`,i.GENERAL)}});function Ta(e){return bt(e)&&St(e).isFile()}async function Ea(t,n,r,a){let o=n.split(`,`).map(e=>e.trim()).filter(Boolean);if(o.length===0)throw new e(`--${r} must contain at least one entry.`,i.USAGE);let s=[],c=[],l,u,d=!0;for(let n of o){if(!Ta(n)){s.push(n),d=!1;continue}if(s.push(n),c.push(n),t.dryRun)continue;let r=await Ke(n,{schema:a});if(!r.valid){let t=[`Dataset validation failed for ${n}`,...r.errors.slice(0,10).map(E)];throw r.errors.length>10&&t.push(` … and ${r.errors.length-10} more error(s).`),t.push(``,"Hint: re-run `bl dataset validate --file <path>` for the full report,"," or upload manually with `bl dataset upload --no-validate` and",` pass the resulting file-id here.`),new e(t.join(`
|
|
126
|
-
`),i.GENERAL)}if(r.warnings.length>0&&!t.quiet){process.stderr.write(`Dataset validation passed with ${r.warnings.length} warning(s) for ${n}:\n`);for(let e of r.warnings.slice(0,5))process.stderr.write(`${E(e)}\n`);r.warnings.length>5&&process.stderr.write(` … and ${r.warnings.length-5} more.\n`)}let o=r.stats.totalRecords;typeof o==`number`&&(u=(u??0)+o),l===void 0&&(l=St(n).size)}return{fileIds:s,localPaths:c,firstSize:l,recordCount:d?u:void 0}}async function Da(t,n,r,a){let o=[];for(let[s,c]of n.fileIds.entries()){if(!Ta(c))continue;let l=await Ue(t,{filePath:c,purpose:r});if(!l.file_id)throw new e(`Upload of ${c} succeeded but no file_id was returned.`,i.GENERAL);o.push(l),n.fileIds[s]=l.file_id,t.quiet||process.stderr.write(`Uploaded ${wt(c)} → ${l.file_id} (auto from --${a})\n`)}return o}var Oa=y({description:`Create a fine-tune job (sft | sft-lora | dpo | dpo-lora | cpt)`,usageArgs:`--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>] [--yes]`,options:[{flag:`--model <model>`,description:`Base model to fine-tune (e.g. qwen3-8b, qwen3-14b)`,required:!0},{flag:`--datasets <ids|paths>`,description:`Comma-separated dataset file IDs or local .jsonl paths. Local paths are uploaded (validated) first, then their file-ids are used.`,required:!0},{flag:`--validations <ids|paths>`,description:`Comma-separated validation dataset file IDs or local .jsonl paths (auto-uploaded like --datasets).`},{flag:`--model-name <name>`,description:`Output model name (after training)`},{flag:`--suffix <text>`,description:`Output suffix appended by the platform (finetuned_output_suffix)`},{flag:`--training-type <t>`,description:`Training type: ${c.join(` | `)} (default: ${n}). Mapping to the server happens at the interface boundary (e.g. sft-lora -> efficient_sft, dpo -> dpo_full).`},{flag:`--n-epochs <n>`,description:`Number of epochs (default: 3)`,type:`number`},{flag:`--batch-size <n>`,description:`Per-device batch size (clamped to [8, 1024]). Auto-set to 8 for small datasets (<100KB)`,type:`number`},{flag:`--learning-rate <str>`,description:`Learning rate as a string to preserve precision (e.g. "1.6e-5")`},{flag:`--max-length <n>`,description:`Max sequence length`,type:`number`},{flag:`--yes`,description:`Skip the confirmation prompt`,type:`boolean`}],exampleArgs:[`--model qwen3-8b --datasets file-xxx`,`--model qwen3-8b --datasets ./train.jsonl`,`--model qwen3-8b --datasets ./train.jsonl --validations ./eval.jsonl`,`--model qwen3-8b --datasets file-aaa,./extra.jsonl`,`--model qwen3-8b --datasets ./train.jsonl --training-type sft`,`bl finetune create --model qwen3-8b --datasets file-xxx --learning-rate "1.6e-5" --n-epochs 4`,`--model qwen3-8b --datasets file-xxx --yes --output json`],notes:["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.`,`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.`,`n_epochs defaults to 3. Other hyper-parameters are platform defaults unless set.`,`Learning rate is forwarded as a string to avoid JSON-number precision loss.`,"--datasets / --validations accept either file-ids (from `bl dataset","upload`) or local .jsonl paths. Local paths are validated and uploaded",`first, then their file-ids are submitted — a one-step upload-and-train.`,`Dataset record schema is chosen from --training-type: dpo* → {messages,`,`chosen, rejected}; cpt → {text} (raw pre-training text); else {messages}.`,`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).`],async run(t,r){let a=r.model;a||K(`model`,`bl finetune create --model <model>`);let o=r.datasets;o||K(`datasets`,`bl finetune create --datasets <ids|paths>`);let s=r.trainingType||n;if(!pe(s))throw new e(`--training-type "${s}" is not supported.`,i.USAGE,`Supported values: ${c.join(`, `)} (default: ${n}).`);let l=s.startsWith(`dpo`)?`dpo`:s===`cpt`?`cpt`:`chatml`,u=await Ea(t,o,`datasets`,l),d=u.fileIds,f=r.validations,p=f?await Ea(t,f,`validations`,l):void 0,m=p?.fileIds,h=r.modelName,g=r.suffix,_={};if(_.n_epochs=r.nEpochs===void 0?3:r.nEpochs,r.learningRate!==void 0&&(_.learning_rate=r.learningRate),r.maxLength!==void 0&&(_.max_length=r.maxLength),r.batchSize!==void 0){let e=r.batchSize,n=e;n<8&&(n=8),n>1024&&(n=1024),n!==e&&!t.quiet&&process.stderr.write(`warning: --batch-size ${e} clamped to ${n} (server range [8, 1024] for the common training types).\n`),_.batch_size=n}let y=!1;if(_.batch_size===void 0&&!t.dryRun){let e=u.firstSize??0;if(e===0)try{e=(await ae(t,d[0])).data?.size??0}catch{}e>0&&e<100*1024&&(_.batch_size=8,y=!0)}if(!t.dryRun&&u.recordCount!==void 0){let t=_.batch_size??16,n=Ae({recordCount:u.recordCount,batchSize:t});if(!n.ok&&n.issue)throw new e(n.issue.message,i.GENERAL,n.hint)}if(!t.dryRun){let n;try{n=await te(t,a)}catch(e){t.quiet||process.stderr.write(`warning: model capability lookup failed (${e.message}); proceeding without local pre-flight.
|
|
127
|
-
`)}if(n&&!Se(n).includes(s)){let t=Se(n);throw new e(`Model "${a}" does not support training type "${s}".`,i.USAGE,t.length?`This model supports: ${t.join(`, `)}.`:`This model reports no supported training types.`)}}if(!t.dryRun&&!r.yes&&t.nonInteractive)throw new e(`Pass --yes to confirm fine-tune creation in non-interactive mode.`,i.USAGE);let b=[],x=[];t.dryRun||(b=await Da(t,u,`fine-tune`,`datasets`),p&&(x=await Da(t,p,`fine-tune`,`validations`)));let S={model:a,training_file_ids:d,training_type:ze(s),hyper_parameters:_};m&&m.length>0&&(S.validation_file_ids=m),h&&(S.model_name=h),g&&(S.finetuned_output_suffix=g);let w=C(t.output);if(t.dryRun){let e=[...u.localPaths.map(e=>({field:`datasets`,path:e})),...(p?.localPaths??[]).map(e=>({field:`validations`,path:e}))];G(e.length>0?{action:`finetune.create`,body:S,pending_uploads:e}:{action:`finetune.create`,body:S},w);return}if(!r.yes&&!t.nonInteractive&&!t.quiet){process.stderr.write(`Create fine-tune job:
|
|
128
|
-
`),process.stderr.write(` Model: ${S.model}\n`),process.stderr.write(` Training type: ${s}\n`),process.stderr.write(` Training files: ${d.join(`, `)}\n`),m&&process.stderr.write(` Validation: ${m.join(`, `)}\n`);for(let e of b)process.stderr.write(` Uploaded: ${e.name} → ${e.file_id}\n`);for(let e of x)process.stderr.write(` Uploaded: ${e.name} → ${e.file_id} (validation)\n`);if(process.stderr.write(` n_epochs: ${_.n_epochs}\n`),_.batch_size!==void 0){let e=y?` (auto: small dataset)`:``;process.stderr.write(` batch_size: ${_.batch_size}${e}\n`)}if(_.learning_rate!==void 0&&process.stderr.write(` learning_rate: ${_.learning_rate}\n`),_.max_length!==void 0&&process.stderr.write(` max_length: ${_.max_length}\n`),h&&process.stderr.write(` model_name: ${h}\n`),g&&process.stderr.write(` suffix: ${g}\n`),!await X({message:`Submit this job?`,initialValue:!1})){W(`Cancelled.`);return}}let ee=await v(t,S),T=ee.output??ee.data;t.quiet?T?.job_id&&W(T.job_id):w===`text`&&T?.job_id?(W(`Created fine-tune job: ${T.job_id}`),T.status&&W(`Status: ${T.status}`)):G(ee,w)}}),ka=y({description:`List fine-tune jobs`,usageArgs:`[--page <n>] [--page-size <n>] [--status <s>]`,options:[{flag:`--page <n>`,description:`Page number (default: 1)`,type:`number`},{flag:`--page-size <n>`,description:`Results per page (default: 10, max 100)`,type:`number`},{flag:`--status <s>`,description:`Filter by status (PENDING / RUNNING / SUCCEEDED / FAILED / CANCELED)`}],exampleArgs:[``,`--status RUNNING`,`--page-size 20 --output json`],async run(e,t){let n=C(e.output),r=t.page===void 0?void 0:t.page,i=t.pageSize===void 0?void 0:t.pageSize,a=t.status||void 0;if(e.dryRun){G({action:`finetune.list`,page:r,page_size:i,status:a},n);return}let o=await xe(e,{pageNo:r,pageSize:i,status:a}),s=o.output??o.data,c=s?.jobs??[],l=s?.total,u=c.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??``}));if(n===`json`){G({items:u,total:l},n);return}if(u.length===0){W(`No fine-tune jobs found.`);return}let d=[`JOB_ID`,`BASE_MODEL`,`STATUS`,`TRAINING_TYPE`,`OUTPUT_MODEL`,`CREATED_AT`],f=u.map(e=>[e.job_id,e.base_model,e.status,e.training_type,e.output_model,e.created_at]);for(let e of q(d,f))W(e);l!==void 0&&W(`\nTotal: ${l}`),W("Tip: OUTPUT_MODEL is the input for `bl deploy create --model`")}}),Aa=y({description:`Get details of a single fine-tune job`,usageArgs:`--job-id <id>`,options:[{flag:`--job-id <id>`,description:`Fine-tune job ID (required)`,required:!0}],exampleArgs:[`bl finetune get --job-id ft-xxx`,`bl finetune get --job-id ft-xxx --output json`],async run(e,t){let n=t.jobId;n||K(`job-id`,`bl finetune get --job-id <id>`);let r=C(e.output);if(e.dryRun){G({action:`finetune.get`,job_id:n},r);return}let i=await se(e,n),a=i.output??i.data;if(!a){W(`No data returned for ${n}`);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={job_id:a.job_id??n,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??``};if(r===`json`){G(c,r);return}W(`job_id: ${c.job_id}`),c.base_model&&W(`base_model: ${c.base_model}`),c.status&&W(`status: ${c.status}`),c.training_type&&W(`training_type: ${c.training_type}`),c.training_files.length&&W(`training_files: ${c.training_files.join(`, `)}`),c.validation_files.length&&W(`validation_files: ${c.validation_files.join(`, `)}`),c.hyper_params&&W(`hyper_params: ${c.hyper_params}`),c.output_model&&W(`output_model: ${c.output_model} (→ bl deploy create --model)`),c.model_name&&W(`model_name: ${c.model_name}`),c.created_at&&W(`created_at: ${c.created_at}`),c.updated_at&&W(`updated_at: ${c.updated_at}`)}}),ja=y({description:`Cancel a running fine-tune job`,usageArgs:`--job-id <id> [--yes]`,options:[{flag:`--job-id <id>`,description:`Fine-tune job ID (required)`,required:!0},{flag:`--yes`,description:`Skip the confirmation prompt`,type:`boolean`}],exampleArgs:[`bl finetune cancel --job-id ft-xxx`,`bl finetune cancel --job-id ft-xxx --yes`],notes:[`Only PENDING / RUNNING jobs can be cancelled. Completed / failed / already-`,`cancelled jobs return a server-side error (passed through verbatim).`],async run(t,n){let r=n.jobId;r||K(`job-id`,`bl finetune cancel --job-id <id>`);let a=C(t.output);if(t.dryRun){G({action:`finetune.cancel`,job_id:r},a);return}if(!n.yes&&!t.nonInteractive&&!t.quiet){if(process.stderr.write(`Cancel fine-tune job ${r}?\n`),!await X({message:`Proceed?`,initialValue:!1})){W(`Cancelled.`);return}}else if(!n.yes&&t.nonInteractive)throw new e(`Pass --yes to confirm cancellation in non-interactive mode.`,i.USAGE);let o=await m(t,r),s=o.output??o.data;t.quiet?W(r):a===`text`?W(`Cancelled ${r}${s?.status?` (status=${s.status})`:``}.`):G(o,a)}}),Ma=y({description:`Delete a fine-tune job record`,usageArgs:`--job-id <id> [--yes]`,options:[{flag:`--job-id <id>`,description:`Fine-tune job ID (required)`,required:!0},{flag:`--yes`,description:`Skip the confirmation prompt`,type:`boolean`}],exampleArgs:[`bl finetune delete --job-id ft-xxx`,`bl finetune delete --job-id ft-xxx --yes`],notes:["Cancel a RUNNING job first via `bl finetune cancel` — the platform refuses",`to delete jobs that are still in flight.`],async run(t,n){let r=n.jobId;r||K(`job-id`,`bl finetune delete --job-id <id>`);let a=C(t.output);if(t.dryRun){G({action:`finetune.delete`,job_id:r},a);return}if(!n.yes&&!t.nonInteractive&&!t.quiet){if(process.stderr.write(`Permanently delete fine-tune job ${r}?\n`),!await X({message:`Proceed?`,initialValue:!1})){W(`Cancelled.`);return}}else if(!n.yes&&t.nonInteractive)throw new e(`Pass --yes to confirm deletion in non-interactive mode.`,i.USAGE);let o=await S(t,r);t.quiet?W(r):a===`text`?W(`Deleted ${r}.`):G(o,a)}});function Na(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 Pa(e,t){return Na(e).toLowerCase().includes(t)}async function Fa(e,t,n){let r=[],i=1,a=0;for(let o=0;o<200;o++){let o=await ce(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 Ia=y({description:`Fetch training logs for a fine-tune job`,usageArgs:`--job-id <id> [--page <n>] [--page-size <n>] [--search <keyword>] [--tail <n>]`,options:[{flag:`--job-id <id>`,description:`Fine-tune job ID (required)`,required:!0},{flag:`--page <n>`,description:`Page number (default: 1)`,type:`number`},{flag:`--page-size <n>`,description:`Lines per page (default: server-defined)`,type:`number`},{flag:`--search <keyword>`,description:`Case-insensitive substring filter. When set, all log pages are fetched and filtered client-side (--page is ignored).`},{flag:`--tail <n>`,description:`Keep only the last N entries. When set, all log pages are fetched and the trailing N are kept (--page is ignored).`,type:`number`}],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,t){let n=t.jobId;n||K(`job-id`,`bl finetune logs --job-id <id>`);let r=t.page===void 0?void 0:t.page,i=t.pageSize===void 0?void 0:t.pageSize,a=t.search||void 0,o=t.tail===void 0?void 0:t.tail,s=C(e.output);if(e.dryRun){G({action:`finetune.logs`,job_id:n,page:r,page_size:i,search:a,tail:o},s);return}if(a||o!==void 0){let{entries:t,total:r}=await Fa(e,n,i??100),c=t,l;if(a){let e=a.toLowerCase();c=t.filter(t=>Pa(t,e)),l=c.length}let u=o!==void 0&&o>=0?Math.min(o,c.length):void 0,d=u===void 0?c:c.slice(c.length-u);if(e.quiet||s===`text`){if(d.length===0){W(a?`No logs matched "${a}".`:`No logs returned.`);return}for(let e of d)W(Na(e));let e=[`${d.length} shown`];l!==void 0&&e.push(`matched ${l}`),e.push(`of ${t.length}`+(r?` (total ${r})`:``)),W(`\n${e.join(`, `)}`);return}G({...l===void 0?{}:{matched:l},scanned:t.length,total:r||t.length,...a?{search:a}:{},...u===void 0?{}:{tail:u},logs:d},s);return}let c=await ce(e,n,{pageNo:r,pageSize:i}),l=c.output??c.data,u=l?.logs??[];if(e.quiet||s===`text`){if(u.length===0){W(`No logs returned.`);return}for(let e of u)W(Na(e));l?.total!==void 0&&W(`\nTotal: ${l.total}`)}else G(c,s)}}),La=y({description:`List checkpoints produced by a fine-tune job`,usageArgs:`--job-id <id>`,options:[{flag:`--job-id <id>`,description:`Fine-tune job ID (required)`,required:!0}],exampleArgs:[`--job-id ft-xxx`,`--job-id ft-xxx --output json`],notes:["Use the returned `checkpoint` value with `bl finetune export` to publish",`a deployable model.`],async run(e,t){let n=t.jobId;n||K(`job-id`,`bl finetune checkpoints --job-id <id>`);let r=C(e.output);if(e.dryRun){G({action:`finetune.checkpoints`,job_id:n},r);return}let i=await _e(e,n),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??``}));if(r===`json`){G({items:c,total:s},r);return}if(c.length===0){W(`No checkpoints found.`);return}let l=[`CHECKPOINT`,`STEP`,`STATUS`],u=c.map(e=>[e.checkpoint,e.step,e.status]);for(let e of q(l,u))W(e);W(`\nTotal: ${s}`)}}),Ra=y({description:`Publish a checkpoint as a deployable model`,usageArgs:`--job-id <id> --checkpoint <name> --model-name <name>`,options:[{flag:`--job-id <id>`,description:`Fine-tune job ID (required)`,required:!0},{flag:`--checkpoint <name>`,description:"Checkpoint identifier from `bl finetune checkpoints`",required:!0},{flag:`--model-name <name>`,description:`Deployable model name (required)`,required:!0}],exampleArgs:[`bl finetune export --job-id ft-xxx --checkpoint ckpt-3 --model-name my-qwen-sft`],notes:["Required before `bl deploy 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.`],async run(e,t){let n=t.jobId;n||K(`job-id`,`bl finetune export --job-id <id>`);let r=t.checkpoint;r||K(`checkpoint`,`bl finetune export --checkpoint <name>`);let i=t.modelName;i||K(`model-name`,`bl finetune export --model-name <name>`);let a=C(e.output);if(e.dryRun){G({action:`finetune.export`,job_id:n,checkpoint:r,model_name:i},a);return}let o=await ee(e,n,r,i),s=(o.output??o.data)?.model_name??i;e.quiet?W(s):a===`text`?(W(`Exported ${n} / ${r} → model_name=${s}`),W(`Next: bl deploy create --model `+s+` --name <display-name>`)):G(o,a)}});const za=new Set([`SUCCEEDED`,`FAILED`,`CANCELED`]);function Ba(){let e=new Date,t=e=>String(e).padStart(2,`0`);return`${t(e.getHours())}:${t(e.getMinutes())}:${t(e.getSeconds())}`}function Va(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 Ha(e){return e===`SUCCEEDED`?0:za.has(e)?1:3}function Ua(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 Wa=y({description:`Probe a fine-tune job's status (default: single non-blocking fetch). Pass --follow to poll until terminal.`,usageArgs:`--job-id <id> [--follow] [--interval <sec>] [--timeout <sec>]`,options:[{flag:`--job-id <id>`,description:`Fine-tune job ID (required)`,required:!0},{flag:`--follow`,description:`Block and poll until a terminal state (the legacy behavior). Without it, a single status probe is performed and the command returns immediately.`,type:`boolean`},{flag:`--interval <sec>`,description:`Seconds between polls with --follow (default: 10, min: 1). Ignored without --follow.`,type:`number`},{flag:`--timeout <sec>`,description:`With --follow, stop polling after this many seconds (default: no limit). Ignored without --follow.`,type:`number`}],exampleArgs:[`--job-id ft-xxx # single probe, returns immediately`,`--job-id ft-xxx --output json # status probe for agents`,`--job-id ft-xxx --follow # block until terminal`,`--job-id ft-xxx --follow --interval 5`,`--job-id ft-xxx --follow --timeout 3600`],notes:[`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.`,`Exit codes (both modes): 0 SUCCEEDED | 1 FAILED/CANCELED | 2 --follow timeout`,`| 3 still running (non-terminal, default mode) | 130 interrupted (Ctrl-C).`,`Use --follow for the blocking, human-terminal-follow experience; use the`,`default mode when driving the loop yourself (e.g. from an agent).`,"For per-step training output (not status), use `bl finetune logs`."],async run(e,t){let n=t.jobId;n||K(`job-id`,`bl finetune watch --job-id <id>`);let r=!!t.follow,i=Math.max(1,t.interval===void 0?10:t.interval),a=t.timeout===void 0?void 0:t.timeout,o=C(e.output);if(e.dryRun){G({action:`finetune.watch`,job_id:n,follow:r,interval:i,timeout:a},o);return}if(!r){let t=await se(e,n),r=t.output??t.data,i=String(r?.status??``).toUpperCase(),a=za.has(i),s=Ha(i);e.quiet?W(i||`UNKNOWN`):o===`text`?(W(`${Ba()} ${n} ${i||`UNKNOWN`}`),a&&W(`${i===`SUCCEEDED`?`✓`:`✗`} ${n} ${i}`)):G({job_id:n,status:i||`UNKNOWN`,terminal:a},o),process.exit(s)}let s=new AbortController,c=()=>s.abort();process.on(`SIGINT`,c);try{let t=``,r=Date.now();for(;;){let c=await se(e,n,s.signal),l=c.output??c.data,u=String(l?.status??``).toUpperCase();if(o===`text`&&!e.quiet&&u!==t&&(W(`${Ba()} ${n} ${u||`UNKNOWN`}`),t=u),za.has(u)){let t=Date.now()-r;o!==`text`||e.quiet?G(c,o):W(`\n${u===`SUCCEEDED`?`✓`:`✗`} ${n} ${u} (elapsed ${Va(t)})`),process.exit(Ha(u))}a!==void 0&&(Date.now()-r)/1e3>=a&&(o===`text`&&!e.quiet&&W(`\n⏼ ${n} timed out after ${Va(Date.now()-r)} (last status: ${u||`UNKNOWN`})`),process.exit(2)),await Ua(i*1e3,s.signal)}}catch(e){throw s.signal.aborted&&(W(`
|
|
129
|
-
Interrupted.`),process.exit(130)),e}finally{process.off(`SIGINT`,c)}}});async function Ga(e){let t=await T(e,``,{pageNo:1,pageSize:50}),n=[...t.models],r=Math.ceil(t.total/50);for(let t=2;t<=r;t++){let r=await T(e,``,{pageNo:t,pageSize:50});n.push(...r.models)}return n}const Ka={full:`full-parameter`,lora:`LoRA`};function qa(e){if(!pe(e))return e;let{method:t,variant:n}=Ve(e);return`${Ka[n]??n} ${t.toUpperCase()}`}var Ja=y({description:`Query fine-tune training capability — by model (which training types it supports) or by training type (which models support it)`,usageArgs:`--model <m> | --training-type <t>`,options:[{flag:`--model <m>`,description:`List training types supported by this base model.`},{flag:`--training-type <t>`,description:`List models supporting this training type: ${c.join(` | `)}.`}],exampleArgs:[`--model qwen3-8b`,`--training-type sft-lora`,`--training-type cpt --output json`,`--training-type sft --quiet`],notes:[`Exactly one of --model / --training-type is required.`,"Training-type values use the `<method>` / `<method>-lora` convention:",`sft | sft-lora | dpo | dpo-lora | cpt. (cpt has no -lora variant server-side.)`,`Queries listFoundationModels, a public API — no console login needed.`],async run(e,t){let n=t.model||void 0,r=t.trainingType||void 0;if(n&&r)throw Error(`--model and --training-type are mutually exclusive; pass one.`);!n&&!r&&K(`model or training-type`,`--model <m> | --training-type <t>`);let i=C(e.output);if(e.dryRun){G({action:`finetune.capability`,model:n,training_type:r},i);return}if(n){let t=await te(e,n);if(!t){W(`No foundation model found matching "${n}".`);return}let r=Se(t);if(e.quiet){for(let e of r)W(e);return}if(i!==`text`){G({model:t.model??n,supported:r,supports:t.supports,trainingTypes:t.trainingTypes},i);return}W(`${t.model??n}`),W(r.length?`Supported training types:`:`No supported training types.`);for(let e of r)W(` ${e.padEnd(10)} ${qa(e)}`);return}if(!pe(r))throw Error(`--training-type "${r}" is not supported. Valid: ${c.join(`, `)}.`);let{method:a,variant:o}=Ve(r),s=(await Ga(e)).filter(e=>Oe(e,r)).map(e=>({model:e.model,name:e.name??e.model})).filter(e=>!!e.model).sort((e,t)=>e.model.localeCompare(t.model));if(e.quiet){for(let e of s)W(e.model);return}if(i!==`text`){G({training_type:r,method:a,variant:o,count:s.length,models:s},i);return}W(`Models supporting ${r} (${a} / ${o}): ${s.length}`);for(let e of s)W(` ${e.model}`)}});const Ya={lora:{name:`lora`,validateFlags(){},async resolve(){return{body:{capacity:1},confirmRows:[],planLabelSuffix:` (Token-billed)`}}},ptu:{name:`ptu`,validateFlags(e){let t=`bl deploy create --plan ptu --model <m> --name <n> --input-tpm <n> --output-tpm <n>`;e.inputTpm===void 0&&K(`input-tpm`,t),e.outputTpm===void 0&&K(`output-tpm`,t)},async resolve(e){let t=e.flags.inputTpm,n=e.flags.outputTpm,r=e.flags.thinkingOutputTpm,i={input_tpm:t,output_tpm:n};r!==void 0&&(i.thinking_output_tpm=r);let a=[` input_tpm: ${t}`,` output_tpm: ${n}`];return r!==void 0&&a.push(` thinking_output_tpm: ${r}`),{body:{ptu_capacity:i},confirmRows:a,planLabelSuffix:` (Token-billed, provisioned throughput)`}}},mu:{name:`mu`,validateFlags(){},async resolve(t){let n=t.flags.billingMethod||`POST_PAY`,r=t.flags.templateId,a=t.flags.capacity,o=!1;if(!t.config.dryRun&&!r)try{let s=await ye(t.config,{modelSource:`base`,pageSize:100,version:`v1.0`}),c=((s.output??s.data)?.models??[]).find(e=>e.model_name===t.model)?.plans?.find(e=>e.plan===`mu`)?.templates??[];if(c.length===0)throw new e(`No mu-plan template found for model "${t.model}". Run \`bl deploy models --source base\` to inspect available models, or pass --template-id explicitly.`,i.USAGE);let l=n===`POST_PAY`?`post_paid`:`pre_paid`,u=c.find(e=>e.charge_type===l)??c[0];if(!u?.template_id)throw new e(`No mu-plan template found for model "${t.model}". Run \`bl deploy models --source base\` to inspect available models, or pass --template-id explicitly.`,i.USAGE);r=u.template_id,o=!0,a===void 0&&(a=u.roles?.unified?.capacity_unit_per_instance??1)}catch(t){throw t instanceof e?t:new e(`Failed to auto-pick template for plan=mu: ${t.message}. Pass --template-id explicitly.`,i.USAGE)}let s={capacity:a??1,billing_method:n};r&&(s.template_id=r);let c=[];if(r){let e=o?` (auto-picked)`:``;c.push(` template_id: ${r}${e}`)}return c.push(` capacity: ${a??1}`),c.push(` billing_method: ${n}`),{body:s,confirmRows:c}}}};function Xa(t){let n=Ya[t];if(!n)throw new e(`Unsupported plan "${t}". Supported plans: ${Object.keys(Ya).join(`, `)}.`,i.USAGE);return n}var Za=y({description:`Create a model deployment`,usageArgs:`--model <model_name> --name <display_name> [--plan <plan>] [--template-id <id>] [--capacity <n>] [--billing-method <m>] [--input-tpm <n>] [--output-tpm <n>] [--thinking-output-tpm <n>] [--yes]`,options:[{flag:`--model <name>`,description:`Model name (catalog model or fine-tuned output) (required)`,required:!0},{flag:`--name <display_name>`,description:`Console display name for the deployment (required)`,required:!0},{flag:`--plan <plan>`,description:`Billing plan: lora (default, Token-billed) | ptu (Token-billed) | mu`},{flag:`--template-id <id>`,description:`Template id (only used by plan=mu; auto-picked if omitted)`},{flag:`--capacity <n>`,description:`Resource units (plan=mu only; required by API; defaults to the template's unit)`,type:`number`},{flag:`--billing-method <m>`,description:`Billing method (plan=mu only; default "POST_PAY", the only supported value)`},{flag:`--input-tpm <n>`,description:`PTU max input tokens/min (required for plan=ptu)`,type:`number`},{flag:`--output-tpm <n>`,description:`PTU max output tokens/min (required for plan=ptu)`,type:`number`},{flag:`--thinking-output-tpm <n>`,description:`PTU max thinking-output tokens/min (optional, some models)`,type:`number`},{flag:`--yes`,description:`Skip the confirmation prompt`,type:`boolean`}],exampleArgs:[`--model my-qwen-sft --name my-sft-test`,`--model qwen3.6-flash-2026-04-16 --name my-flash --plan ptu --input-tpm 10000 --output-tpm 1000`,`--model qwen3-8b --name my-qwen3-mu --plan mu`,`--model qwen3-8b --name my-qwen3 --plan mu --template-id MU1 --capacity 2 --yes`],notes:["Plan defaults to `lora` (Token-billed). Pass --plan to override.",`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).`,"For plan=mu, `capacity`, `billing_method` and `template_id` are required.",`billing_method defaults to POST_PAY (only supported value); template_id`,`and capacity are auto-picked from GET /deployments/models when omitted.`,"Use `bl deploy models --source base` to inspect available templates.",`After creation, status starts at PENDING and transitions to RUNNING.`,`Invoke the deployed model with: bl text chat --model <deployed_model>`,`WARNING: --model is overloaded across commands and refers to DIFFERENT`,"values. `bl deploy create --model` takes the exported model_name (e.g.","`qwen3-8b-ft-...`), but the create response also returns a `deployed_model`","field (the deployment instance id, e.g. `qwen3-8b-5ecb5f068d79`). The","inference call `bl text chat --model` must use the `deployed_model` from","the create response — NOT the `model_name` you passed to `deploy create`.",`Do not reuse the value across the two commands.`],async run(t,n){let r=n.model,a=n.name;r||K(`model`,`bl deploy create --model <model_name> --name <display_name>`),a||K(`name`,`bl deploy create --model <model_name> --name <display_name>`);let o=n.plan||`lora`,s=C(t.output),c=Xa(o);c.validateFlags(n);let l=await c.resolve({config:t,flags:n,model:r,name:a}),u={model_name:r,name:a,plan:o,...l.body};if(t.dryRun){G({action:`deploy.create`,body:u},s);return}if(!n.yes&&!t.nonInteractive&&!t.quiet){let e=[`Create deployment:`,` model: ${r}`,` name: ${a}`,` plan: ${o}${l.planLabelSuffix??``}`,...l.confirmRows];if(process.stderr.write(e.join(`
|
|
130
|
-
`)+`
|
|
131
|
-
`),!await X({message:`Proceed?`,initialValue:!0})){W(`Cancelled.`);return}}else if(!n.yes&&t.nonInteractive)throw new e(`Pass --yes to confirm deployment creation in non-interactive mode.`,i.USAGE);let d=await _(t,u),f=d.output??d.data;t.quiet?W(f?.deployed_model??``):s===`text`?(W(`Created deployment.`),f?.deployed_model&&W(` deployed_model: ${f.deployed_model}`),f?.status&&W(` status: ${f.status}`),f?.plan&&W(` plan: ${f.plan}`),W(`\nNext: track readiness with: bl deploy get --deployed-model ${f?.deployed_model??`<id>`}`)):G(d,s)}}),Qa=y({description:`List model deployments`,usageArgs:`[--page <n>] [--page-size <n>] [--status <s>]`,options:[{flag:`--page <n>`,description:`Page number (default: 1)`,type:`number`},{flag:`--page-size <n>`,description:`Results per page (default: 10, max 100)`,type:`number`},{flag:`--status <s>`,description:`Filter by status (PENDING / RUNNING / STOPPED / FAILED)`}],exampleArgs:[``,`--status RUNNING`,`--page-size 20 --output json`],async run(e,t){let n=C(e.output),r=t.page===void 0?void 0:t.page,i=t.pageSize===void 0?void 0:t.pageSize,a=t.status||void 0;if(e.dryRun){G({action:`deploy.list`,page:r,page_size:i,status:a},n);return}let o=await be(e,{pageNo:r,pageSize:i,status:a}),s=o.output??o.data,c=s?.deployments??[],l=s?.total,u=c.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??``}));if(n===`json`){G({items:u,total:l},n);return}if(u.length===0){W(`No deployments found.`);return}let d=[`DEPLOYED_MODEL`,`MODEL_NAME`,`STATUS`,`PLAN`,`CAPACITY`,`CREATED_AT`],f=u.map(e=>[e.deployed_model,e.model_name,e.status,e.plan,e.capacity,e.created_at]);for(let e of q(d,f))W(e);l!==void 0&&W(`\nTotal: ${l}`)}}),$a=y({description:`Get details of a single model deployment`,usageArgs:`--deployed-model <id>`,options:[{flag:`--deployed-model <id>`,description:`Deployed model identifier (required)`,required:!0}],exampleArgs:[`--deployed-model qwen-plus-2025-12-01-b6d61c71`,`--deployed-model qwen-plus-2025-12-01-b6d61c71 --output json`],async run(e,t){let n=t.deployedModel;n||K(`deployed-model`,`bl deploy get --deployed-model <id>`);let r=C(e.output);if(e.dryRun){G({action:`deploy.get`,deployed_model:n},r);return}let i=await oe(e,n),a=i.output??i.data;if(!a){W(`No data returned for ${n}`);return}let o={deployed_model:a.deployed_model??n,deployed_name:a.name??``,model_name:a.model_name??``,base_model:a.base_model??``,status:a.status??``,plan:a.plan??``};if(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),r===`json`){G(o,r);return}let s=e=>`${e}:`.padEnd(18);for(let[e,t]of Object.entries(o)){if(t===``||t===void 0)continue;let n=typeof t==`string`?t:JSON.stringify(t);W(`${s(e)}${n}`)}}}),eo=y({description:`List models available for deployment`,usageArgs:`[--page <n>] [--page-size <n>] [--version <v>] [--source <custom|public>]`,options:[{flag:`--page <n>`,description:`Page number (default: 1)`,type:`number`},{flag:`--page-size <n>`,description:`Results per page (default: 100)`,type:`number`},{flag:`--version <v>`,description:`Catalog version filter (default: v1.0; required for new catalog models)`},{flag:`--source <s>`,description:`Model source filter: custom (fine-tuned) | base (catalog) | public`}],exampleArgs:[``,`--source base`,`--source custom --page-size 50`,`--version v1.0 --output json`],async run(e,t){let n=C(e.output),r=t.page===void 0?void 0:t.page,i=t.pageSize===void 0?void 0:t.pageSize,a=t.version===``?void 0:t.version??`v1.0`,o=t.source||void 0;if(e.dryRun){G({action:`deploy.models`,page:r,page_size:i,version:a,model_source:o},n);return}let s=await ye(e,{pageNo:r,pageSize:i,version:a,modelSource:o}),c=s.output??s.data,l=c?.models??[],u=c?.total;if(n===`json`){G({items:l.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:u},n);return}let d=l.map(e=>{let t=``;return t=e.supported_plans&&e.supported_plans.length>0?e.supported_plans.join(`,`):e.plans&&e.plans.length>0?e.plans.map(e=>{let t=e.plan??`?`;return e.templates&&e.templates.length>0?`${t}(${e.templates.length}t)`:e.cu_specs&&e.cu_specs.length>0?`${t}(${e.cu_specs.join(`/`)})`:t}).join(`,`):`-`,{model_name:e.model_name??``,base_model:e.base_model??``,source:e.model_source??``,plans:t}});if(d.length===0){W(`No deployable models found.`);return}let f=[`MODEL_NAME`,`BASE_MODEL`,`SOURCE`,`PLANS`],p=d.map(e=>[e.model_name,e.base_model,e.source,e.plans]);for(let e of q(f,p))W(e);u!==void 0&&W(`\nTotal: ${u}`)}}),to=y({description:`Scale a deployment's capacity`,usageArgs:`--deployed-model <id> --capacity <n> [--input-tpm <n>] [--output-tpm <n>] [--yes]`,options:[{flag:`--deployed-model <id>`,description:`Deployed model identifier (required)`,required:!0},{flag:`--capacity <n>`,description:`New capacity in plan units (must be a multiple of base_capacity)`,type:`number`},{flag:`--input-tpm <n>`,description:`PTU only — input tokens per minute`,type:`number`},{flag:`--output-tpm <n>`,description:`PTU only — output tokens per minute`,type:`number`},{flag:`--yes`,description:`Skip the confirmation prompt`,type:`boolean`}],exampleArgs:[`--deployed-model qwen-plus-...-b6d61c71 --capacity 8`,`--deployed-model dep-... --capacity 2 --yes`],async run(t,n){let r=n.deployedModel;r||K(`deployed-model`,`bl deploy scale --deployed-model <id> --capacity <n>`);let a=n.capacity===void 0?void 0:n.capacity,o=n.inputTpm===void 0?void 0:n.inputTpm,s=n.outputTpm===void 0?void 0:n.outputTpm;if(a===void 0&&o===void 0&&s===void 0)throw new e(`Provide at least one of --capacity / --input-tpm / --output-tpm.`,i.USAGE);let c=C(t.output),l={};if(a!==void 0&&(l.capacity=a),o!==void 0&&(l.input_tpm=o),s!==void 0&&(l.output_tpm=s),t.dryRun){G({action:`deploy.scale`,deployed_model:r,body:l},c);return}if(!n.yes&&!t.nonInteractive&&!t.quiet){let e=[];if(a!==void 0&&e.push(`capacity=${a}`),o!==void 0&&e.push(`input_tpm=${o}`),s!==void 0&&e.push(`output_tpm=${s}`),process.stderr.write(`Scale deployment ${r} (${e.join(`, `)})?\n`),!await X({message:`Proceed?`,initialValue:!1})){W(`Cancelled.`);return}}else if(!n.yes&&t.nonInteractive)throw new e(`Pass --yes to confirm scaling in non-interactive mode.`,i.USAGE);let u=await Pe(t,r,l),d=u.output??u.data;t.quiet?W(r):c===`text`?W(`Scaled ${r}${d?.capacity===void 0?``:` (capacity=${d.capacity})`}.`):G(u,c)}}),no=y({description:`Update a deployment's rate limits (rpm_limit / tpm_limit)`,usageArgs:`--deployed-model <id> [--rpm-limit <n>] [--tpm-limit <n>] [--yes]`,options:[{flag:`--deployed-model <id>`,description:`Deployed model identifier (required)`,required:!0},{flag:`--rpm-limit <n>`,description:`Requests per minute`,type:`number`},{flag:`--tpm-limit <n>`,description:`Tokens per minute`,type:`number`},{flag:`--yes`,description:`Skip the confirmation prompt`,type:`boolean`}],exampleArgs:[`--deployed-model dep-... --rpm-limit 1000`,`--deployed-model dep-... --rpm-limit 1000 --tpm-limit 200000 --yes`],notes:[`At least one of --rpm-limit / --tpm-limit must be provided.`],async run(t,n){let r=n.deployedModel;r||K(`deployed-model`,`--deployed-model <id> [--rpm-limit <n>] [--tpm-limit <n>]`);let a=n.rpmLimit===void 0?void 0:n.rpmLimit,o=n.tpmLimit===void 0?void 0:n.tpmLimit;if(a===void 0&&o===void 0)throw new e(`Provide at least one of --rpm-limit / --tpm-limit.`,i.USAGE);let s=C(t.output),c={};if(a!==void 0&&(c.rpm_limit=a),o!==void 0&&(c.tpm_limit=o),t.dryRun){G({action:`deploy.update`,deployed_model:r,body:c},s);return}if(!n.yes&&!t.nonInteractive&&!t.quiet){let e=[];if(a!==void 0&&e.push(`rpm_limit=${a}`),o!==void 0&&e.push(`tpm_limit=${o}`),process.stderr.write(`Update rate limits for ${r} (${e.join(`, `)})?\n`),!await X({message:`Proceed?`,initialValue:!1})){W(`Cancelled.`);return}}else if(!n.yes&&t.nonInteractive)throw new e(`Pass --yes to confirm rate-limit update in non-interactive mode.`,i.USAGE);let l=await He(t,r,c),u=l.output??l.data;if(t.quiet)W(r);else if(s===`text`){let e=[];u?.rpm_limit!==void 0&&e.push(`rpm_limit=${u.rpm_limit}`),u?.tpm_limit!==void 0&&e.push(`tpm_limit=${u.tpm_limit}`),W(`Updated ${r}${e.length?` (${e.join(`, `)})`:``}.`)}else G(l,s)}}),ro=y({description:`Delete a model deployment (must be STOPPED or FAILED)`,usageArgs:`--deployed-model <id> [--yes] [--skip-precheck]`,options:[{flag:`--deployed-model <id>`,description:`Deployed model identifier (required)`,required:!0},{flag:`--yes`,description:`Skip the confirmation prompt`,type:`boolean`},{flag:`--skip-precheck`,description:`Skip the local STOPPED/FAILED status precheck`,type:`boolean`}],exampleArgs:[`--deployed-model dep-...`,`--deployed-model dep-... --yes`],async run(t,n){let r=n.deployedModel;r||K(`deployed-model`,`bl deploy delete --deployed-model <id>`);let a=C(t.output);if(t.dryRun){G({action:`deploy.delete`,deployed_model:r},a);return}if(!n.skipPrecheck)try{let n=await oe(t,r),a=((n.output??n.data)?.status??``).toUpperCase();if(a&&a!==`STOPPED`&&a!==`FAILED`)throw new e(`Deployment ${r} is ${a}. Only STOPPED / FAILED deployments can be deleted. Stop it first via the platform console, or pass --skip-precheck to attempt deletion anyway.`,i.USAGE)}catch(t){if(t instanceof e)throw t}if(!n.yes&&!t.nonInteractive&&!t.quiet){if(process.stderr.write(`Delete deployment ${r}?\n`),!await X({message:`Proceed?`,initialValue:!1})){W(`Cancelled.`);return}}else if(!n.yes&&t.nonInteractive)throw new e(`Pass --yes to confirm deletion in non-interactive mode.`,i.USAGE);let o=await x(t,r);t.quiet?W(r):a===`text`?W(`Deleted ${r}.`):G(o,a)}});function io(e){let t=[];for(let[n,r]of Object.entries(e))if(!(r===void 0||r===``))if(Array.isArray(r))for(let e=0;e<r.length;e++){let i=r[e];i!==``&&t.push([`${n}.${e+1}`,i])}else t.push([n,r]);return t.sort(([e],[t])=>e<t?-1:+(e>t)),t.map(([e,t])=>`${ao(e)}=${ao(t)}`).join(`&`)}function ao(e){return encodeURIComponent(e).replace(/[!'()*]/g,e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`)}function oo(e){let t=e.method??`POST`,n=new Date().toISOString().replace(/\.\d{3}Z$/,`Z`),r=Lt(),i=so(e.body),a={host:e.host,"x-acs-action":e.action,"x-acs-version":e.version,"x-acs-date":n,"x-acs-signature-nonce":r,"x-acs-content-sha256":i,"content-type":`application/json`},o=Object.keys(a).filter(e=>e===`host`||e===`content-type`||e.startsWith(`x-acs-`)).sort(),s=o.map(e=>`${e}:${a[e]}`).join(`
|
|
132
|
-
`)+`
|
|
133
|
-
`,c=o.join(`;`),l=e.queryString??``,u=[t,e.pathname,l,s,c,i].join(`
|
|
134
|
-
`),d=`ACS3-HMAC-SHA256`,f=`${d}\n${so(u)}`,p=co(e.accessKeySecret,f);return a.authorization=`${d} Credential=${e.accessKeyId},SignedHeaders=${c},Signature=${p}`,a}function so(e){return Ft(`sha256`).update(e,`utf8`).digest(`hex`)}function co(e,t){return It(`sha256`,e).update(t,`utf8`).digest(`hex`)}const lo=[{flag:`--access-key-id <key>`,description:`Alibaba Cloud Access Key ID (deprecated)`},{flag:`--access-key-secret <key>`,description:`Alibaba Cloud Access Key Secret (deprecated)`}],uo=[{flag:`--caller-uac-account-id <id>`,description:`Caller UAC account ID`},{flag:`--namespace-id <id>`,description:`Product namespace ID (Token Plan default: namespace-1)`}],fo={flag:`--workspace-id <id>`,description:`Workspace ID (env: BAILIAN_WORKSPACE_ID, config: workspace_id)`},po={cn:`modelstudio.cn-beijing.aliyuncs.com`,intl:`modelstudio.ap-southeast-1.aliyuncs.com`};function mo(e){for(let[t,n]of Object.entries(s))if(e===n||e.startsWith(`${n}/`))return t;return`cn`}function ho(e){return po[mo(e)]??po.cn}function go(t,n){let r=n.accessKeyId||t.accessKeyId,a=n.accessKeySecret||t.accessKeySecret;if(!r||!a)throw new e(`No credentials found.
|
|
135
|
-
Set ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET.`,i.AUTH);return{accessKeyId:r,accessKeySecret:a}}function _o(t,n){let r=n.workspaceId||t.workspaceId;if(!r)throw new e(`Missing workspace ID.
|
|
136
|
-
Set via: --workspace-id flag, env: BAILIAN_WORKSPACE_ID, or config: bl config set workspace_id <id>`,i.USAGE);return r}function vo(e,t){t.callerUacAccountId&&(e.CallerUacAccountId=t.callerUacAccountId),t.namespaceId&&(e.NamespaceId=t.namespaceId)}function $(e,t,n){let r=io(n),i=ho(e.baseUrl);return{host:i,endpoint:`https://${i}${t}${r?`?${r}`:``}`,queryString:r,queryParams:n}}async function yo(t){let{config:n,credentials:r,action:a,path:o,method:s,queryParams:c}=t,{host:l,endpoint:u,queryString:d}=$(n,o,c),f=oo({accessKeyId:r.accessKeyId,accessKeySecret:r.accessKeySecret,action:a,version:`2026-02-10`,body:``,host:l,pathname:o,method:s,queryString:d});n.verbose&&(process.stderr.write(`> ${s} ${u}\n`),process.stderr.write(`> AK: ${O(r.accessKeyId)}\n`));let p=n.timeout*1e3,m=await fetch(u,{method:s,headers:{...f,...Be()},signal:AbortSignal.timeout(p)});n.verbose&&process.stderr.write(`< ${m.status} ${m.statusText}\n`);let h=await m.json();if(!m.ok||h.Success===!1)throw new e(`${h.Code||m.status} - ${h.Message||m.statusText}`,i.GENERAL);return h}const bo=`/tokenplan/subscription/seat-detail`;var xo=y({description:`List Token Plan subscription seat details`,usageArgs:`[flags]`,options:[{flag:`--page-no <n>`,description:`Page number (default: 1)`,type:`number`},{flag:`--page-size <n>`,description:`Page size (default: 10)`,type:`number`},...uo,{flag:`--status <status>`,description:`Seat status filter (repeatable): CREATING, NORMAL, LIMIT, RELEASE, STOP, REFUNDED`,type:`array`},{flag:`--status-list-str <json>`,description:`StatusList as JSON string, e.g. '["NORMAL"]'`},{flag:`--seat-id <id>`,description:`Filter by seat ID`},{flag:`--seat-type <type>`,description:`Seat tier: standard, pro, or max`},{flag:`--query-assigned <bool>`,description:`Filter by assignment: true=assigned, false=unassigned`},...lo],exampleArgs:[``,`--page-size 20 --status NORMAL`,`--query-assigned true --seat-type standard`],async run(e,t){let n=C(e.output),r=go(e,t),i=So(t);if(e.dryRun){let{endpoint:t,queryParams:r}=$(e,bo,i);G({endpoint:t,query:r},n);return}let a=await yo({config:e,credentials:r,action:`GetSubscriptionSeatDetails`,path:bo,method:`GET`,queryParams:i}),o=a.Data?.Items??[];e.quiet||n===`text`?Co(o,a.Data?.Total,a.Data?.PageNo,a.Data?.PageSize):G(a,n)}});function So(t){let n={};t.pageNo!==void 0&&(n.PageNo=String(t.pageNo)),t.pageSize!==void 0&&(n.PageSize=String(t.pageSize)),vo(n,t),t.statusListStr&&(n.StatusListStr=t.statusListStr);let r=t.status;if(r&&r.length>0&&(n.StatusList=r),t.seatId&&(n.SeatId=t.seatId),t.seatType&&(n.SeatType=t.seatType),typeof t.queryAssigned==`string`&&t.queryAssigned.length>0){let r=t.queryAssigned.toLowerCase();if(r!==`true`&&r!==`false`)throw new e(`--query-assigned must be 'true' or 'false'.`,i.USAGE);n.QueryAssigned=r}return n}function Co(e,t,n,r){if(e.length===0){W(`No seats found.`);return}let i=[J(`SeatId`,18),J(`Type`,10),J(`Status`,10),J(`Assigned`,12),J(`Account`,20)].join(` `);W(i),W(`-`.repeat(i.length));for(let t of e)W([J(t.SeatId??`-`,18),J(t.SpecType??`-`,10),J(t.Status??`-`,10),J(t.AssignedStatus??`-`,12),J(t.AccountName??t.AccountId??`-`,20)].join(` `));t!==void 0&&(W(``),W(`Total: ${t}${n===void 0?``:` | Page: ${n}`}${r===void 0?``:` | PageSize: ${r}`}`))}const wo=`/tokenplan/api-keys`;var To=y({description:`Create a Token Plan API key for a seat`,usageArgs:`--account-id <id> --workspace-id <id> [flags]`,options:[{flag:`--account-id <id>`,description:`Target member account ID`,required:!0},fo,{flag:`--description <text>`,description:`API key description`},...uo,...lo],exampleArgs:[`--account-id acc_123 --workspace-id ws_456`,`--account-id acc_123 --workspace-id ws_456 --description 'Dev key'`],async run(t,n){let r=C(t.output),a=go(t,n),o=n.accountId,s=_o(t,n);if(!o)throw new e(`Missing required argument --account-id.`,i.USAGE);let c=Eo(n,{accountId:o,workspaceId:s});if(t.dryRun){let{endpoint:e,queryParams:n}=$(t,wo,c);G({endpoint:e,query:n},r);return}let l=await yo({config:t,credentials:a,action:`CreateTokenPlanKey`,path:wo,method:`POST`,queryParams:c});t.quiet||r===`text`?Do(l):G(l,r)}});function Eo(e,t){let n={};return n.AccountId=t.accountId,n.WorkspaceId=t.workspaceId,e.description&&(n.Description=e.description),vo(n,e),n}function Do(e){let t=e.Data;if(!t){W(`API key created.`);return}W(`${J(`ApiKeyId`,14)} ${t.ApiKeyId??`-`}`),W(`${J(`MaskedApiKey`,14)} ${t.MaskedApiKey??`-`}`),t.Description&&W(`${J(`Description`,14)} ${t.Description}`),t.PlainApiKey&&(W(``),W(`PlainApiKey (shown once): ${t.PlainApiKey}`))}const Oo=`/tokenplan/subscription/seat-assignments`;var ko=y({description:`Batch assign Token Plan seats to members`,usageArgs:`--workspace-id <id> --seat-type <type> --account-id <id> [flags]`,options:[fo,{flag:`--seat-type <type>`,description:`Seat tier: standard, pro, or max`,required:!0},{flag:`--account-id <id>`,description:`Target member account ID (repeatable)`,type:`array`},...uo,{flag:`--locale <locale>`,description:`Language: zh-CN or en-US`},...lo],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`],async run(t,n){let r=C(t.output),a=go(t,n),o=_o(t,n);if(!n.seatType)throw new e(`Missing required argument --seat-type.`,i.USAGE);let s=n.accountId;if(!s||s.length===0)throw new e(`Missing required argument --account-id.`,i.USAGE);let c=Ao(n,o);if(t.dryRun){let{endpoint:e,queryParams:n}=$(t,Oo,c);G({endpoint:e,query:n},r);return}let l=await yo({config:t,credentials:a,action:`BatchAssignSeats`,path:Oo,method:`POST`,queryParams:c});t.quiet||r===`text`?W(`Seats assigned successfully.`):G(l,r)}});function Ao(e,t){let n={};n.WorkspaceId=t,e.seatType&&(n.SeatType=e.seatType),vo(n,e),e.locale&&(n.Locale=e.locale);let r=e.accountId;return r&&r.length>0&&(n.AccountIds=r),n}const jo=`/tokenplan/organization/member-additions`;var Mo=y({description:`Add a member to a Token Plan organization`,usageArgs:`--account-name <name> --org-id <id> [flags]`,options:[{flag:`--account-name <name>`,description:`Member display name`,required:!0},{flag:`--org-id <id>`,description:`Organization ID`,required:!0},{flag:`--org-role-code <code>`,description:`Organization role: ORG_ADMIN or ORG_MEMBER (default: ORG_MEMBER)`},{flag:`--spec-type <type>`,description:`Seat tier to assign on creation: standard, pro, or max`},...uo,...lo],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(t,n){let r=C(t.output),a=go(t,n),o=n.accountName,s=n.orgId;if(!o)throw new e(`Missing required argument --account-name.`,i.USAGE);if(!s)throw new e(`Missing required argument --org-id.`,i.USAGE);let c=No(n);if(t.dryRun){let{endpoint:e,queryParams:n}=$(t,jo,c);G({endpoint:e,query:n},r);return}let l=await yo({config:t,credentials:a,action:`AddOrganizationMember`,path:jo,method:`POST`,queryParams:c});t.quiet||r===`text`?Po(l):G(l,r)}});function No(e){let t={};return e.accountName&&(t.AccountName=e.accountName),e.orgId&&(t.OrgId=e.orgId),t.OrgRoleCode=typeof e.orgRoleCode==`string`&&e.orgRoleCode.length>0?e.orgRoleCode:`ORG_MEMBER`,e.specType&&(t.SpecType=e.specType),vo(t,e),t}function Po(e){let t=e.Data;if(!t){W(`Member added.`);return}W(`${J(`AccountId`,14)} ${t.AccountId??`-`}`),W(`${J(`SeatAssigned`,14)} ${String(t.SeatAssigned??`-`)}`)}export{Mi as advisorRecommend,Zn as appCall,$n as appList,an as authLogin,hn as authLogout,pn as authStatus,Kn as configSet,Hn as configShow,Pr as consoleCall,Sa as datasetDelete,xa as datasetGet,ba as datasetList,ya as datasetUpload,wa as datasetValidate,Za as deployCreate,ro as deployDelete,$a as deployGet,Qa as deployList,eo as deployModels,to as deployScale,no as deployUpdate,Nr as fileUpload,ja as finetuneCancel,Ja as finetuneCapability,La as finetuneCheckpoints,Oa as finetuneCreate,Ma as finetuneDelete,Ra as finetuneExport,Aa as finetuneGet,ka as finetuneList,Ia as finetuneLogs,Wa as finetuneWatch,jn as imageEdit,Dn as imageGenerate,_r as knowledgeChat,cr as knowledgeRetrieve,fr as knowledgeSearch,yr as mcpCall,xr as mcpList,Sr as mcpTools,er as memoryAdd,ir as memoryDelete,nr as memoryList,ar as memoryProfileCreate,or as memoryProfileGet,tr as memorySearch,rr as memoryUpdate,pi as pipelineRun,vi as pipelineValidate,va as quotaCheck,aa as quotaHistory,Ki as quotaList,Qi as quotaRequest,Cr as searchWeb,jr as speechRecognize,Or as speechSynthesize,_n as textChat,wn as textOmni,Mo as tokenPlanAddMember,ko as tokenPlanAssignSeats,To as tokenPlanCreateKey,xo as tokenPlanListSeats,Xn as update,Gr as usageFree,Xr as usageFreetier,di as usageStats,In as videoDownload,Nn as videoEdit,Mn as videoGenerate,Pn as videoRef,Fn as videoTaskGet,Vn as visionDescribe,Li as workspaceList};
|
|
64
|
+
`)}function yi(e){return e.type===`pipeline`?vi(e.summary,e.steps):_i(e.recommendations)}function bi(e){return e.type===`pipeline`?e.steps.length===0:e.recommendations.length===0}var xi=x({description:`Recommend the best models for your use case (intent analysis → candidate recall → LLM ranking)`,auth:`apiKey`,usageArgs:`--message <text> [flags]`,flags:{message:{type:`string`,valueHint:`<text>`,description:`Describe your requirements`,required:!0}},exampleArgs:[`--message "I need a visual-understanding chatbot"`,`--message "Build an Agent that auto-generates animations"`,`--message "Legal contract review, high precision required"`,`--message "Low-cost high-concurrency online customer service" --output text`,`--message "Long document summarization" --dry-run`],async run(e){let{settings:t,flags:n}=e,r=n.message,i=t.outputExplicit?w(t.output):`json`,a=nt(`Agent: Loading model data & analyzing intent...`);a.start();let o={onPrepareStart:()=>{}},s=!1,l=!1,u=de(t,o).then(e=>(s=!0,l||a.update(`Agent: Model data loaded, analyzing intent...`),e)),f=d(e.client,r,{intentDetectBaseUrl:t.intentDetectBaseUrl}).then(e=>(l=!0,s||a.update(`Agent: Intent analyzed, loading model data...`),e)),[p,m]=await Promise.all([u,f]);a.stop(),m.confidence===0&&process.stderr.write(`Intent analysis timed out, using defaults...
|
|
65
|
+
`),a.update(`Agent: Recalling candidates...`),a.start();let h=await Fe(e.client,p,r,c,m);if(a.stop(),t.dryRun){R({userInput:r,intent:{taskSummary:m.taskSummary,scenarioHints:m.scenarioHints,complexity:m.complexity,inputModality:m.inputModality,outputModality:m.outputModality,requiredCapabilities:m.requiredCapabilities,budget:m.budget,qualityPreference:m.qualityPreference,modelPreference:m.modelPreference?.mode===`unconstrained`?void 0:m.modelPreference,segments:m.segments,semanticQuery:m.semanticQuery},candidateCount:h.length,candidates:h.map(({model:e,score:t,hardScore:n,softScore:r})=>({model:e.model,score:t,hardScore:n,softScore:r})),top:3},i);return}a.update(`Agent: Ranking models...`),a.start();let g=await Pe(e.client,h,m,r,3);if(a.stop(),bi(g)){L(`No suitable models found for this request.`);return}if(i!==`text`){R({intent:{taskSummary:m.taskSummary,scenarioHints:m.scenarioHints,complexity:m.complexity,inputModality:m.inputModality,outputModality:m.outputModality,requiredCapabilities:m.requiredCapabilities,budget:m.budget,qualityPreference:m.qualityPreference,modelPreference:m.modelPreference?.mode===`unconstrained`?void 0:m.modelPreference,segments:m.segments,semanticQuery:m.semanticQuery},result:g,candidates:h.length},i);return}L(mi(m)),L(``),L(yi(g))}});const Si=`zeldaEasy.bailian-dash-workspace.space.listWorkspaces`;function Z(e,t){let n=e[t];if(n&&typeof n==`object`&&!Array.isArray(n))return n}function Ci(e){let t=Z(e,`data`);if(!t)return e;let n=Z(t,`DataV2`);if(n){let e=Z(n,`data`);return(e?Z(e,`data`):void 0)??e??n}return Z(t,`data`)??t}function wi(e){let t=P(process.stdout),n=[`Name`,`Workspace ID`,`Default`],r=e.map(e=>[e.agentName,e.workspaceId,e.defaultAgent?`Yes`:`-`]),i=n.map((e,t)=>Math.max(F(e),...r.map(e=>F(e[t])))),a=n.map((e,n)=>t.bold(V(e,i[n]))).join(` `),o=i.map(e=>t.dim(`─`.repeat(e))).join(`──`);process.stdout.write(a+`
|
|
66
|
+
`),process.stdout.write(o+`
|
|
67
|
+
`);for(let e of r){let n=e.map((e,n)=>n===2&&e===`Yes`?t.green(V(e,i[n])):V(e,i[n]));process.stdout.write(n.join(` `)+`
|
|
68
|
+
`)}process.stdout.write(t.dim(`\nTotal: ${e.length}`)+`
|
|
69
|
+
`)}var Ti=x({description:`List all workspaces`,auth:`console`,usageArgs:`[flags]`,flags:{list:{type:`string`,valueHint:`<n>`,description:`Limit number of results`}},exampleArgs:[``,`--list 5`,`--output json`],async run(e){let{settings:t,flags:n}=e,r=Number(n.list)||0,i=w(t.output);if(t.dryRun){R({api:Si,data:{}},i);return}let a=Ci(await e.client.console(Si,{})).data;if(!Array.isArray(a)||a.length===0){i===`json`?R([],i):process.stdout.write(`No workspace found.
|
|
70
|
+
`);return}let o=a;if(r>0&&(o=o.slice(0,r)),i===`json`){R(o.map(e=>({workspaceId:e.workspaceId,name:e.agentName,default:e.defaultAgent})),i);return}wi(o)}});const Ei=`zeldaHttp.dashscopeModel./zelda/api/v1/modelCenter/listFoundationModels`;function Di(e,t){if(!e)return 0;let n=e.count_limit_period||t;return n?Math.floor(e.count_limit*60/n):0}function Oi(e,t){if(!e)return 0;let n=e.usage_limit_period||t;return n?Math.floor(e.usage_limit*60/n):0}function ki(e){return e.toLocaleString(`en-US`)}function Q(e,t){let n=e[t];if(n&&typeof n==`object`&&!Array.isArray(n))return n}function Ai(e){let t=Q(e,`data`);if(!t)return e;let n=Q(t,`DataV2`);if(n){let e=Q(n,`data`);return(e?Q(e,`data`):void 0)??e??n}return Q(t,`data`)??t}async function ji(e,t){let n=[],r=1;for(;;){let i={pageNo:r,pageSize:50,group:!1,queryQpmInfo:!0,ignoreWorkspaceServiceSite:!0};t&&(i.supports={selfServiceLimitIncrease:!0});let a=Ai(await e.console(Ei,{input:i})),o=a.list??[],s=a.total??0;if(n.push(...o),n.length>=s||o.length===0)break;r++}return n}function Mi(e){let t=P(process.stdout),n=[`Model`,`Req/min`,`Token/min`,`Max TPM`],r=e.map(e=>{let t=e.qpmInfo,n=t?.[`model-default`],r=t?.[`user-spec`],i=Di(n),a=Oi(n),o=Di(r,n?.count_limit_period)||i,s=Oi(r,n?.usage_limit_period)||a,c=a*2;return[e.model,o>0?ki(o):`-`,s>0?ki(s):`-`,c>0?ki(c):`-`]});if(r.length===0){process.stdout.write(`No models found.
|
|
71
|
+
`);return}let i=n.map((e,t)=>Math.max(F(e),...r.map(e=>F(e[t])))),a=n.map((e,n)=>t.bold(V(e,i[n]))).join(` `),o=i.map(e=>t.dim(`─`.repeat(e))).join(`──`);process.stdout.write(a+`
|
|
72
|
+
`),process.stdout.write(o+`
|
|
73
|
+
`);for(let e of r)process.stdout.write(e.map((e,t)=>V(e,i[t])).join(` `)+`
|
|
74
|
+
`);process.stdout.write(t.dim(`\nTotal: ${e.length} models`)+`
|
|
75
|
+
`)}var Ni=x({description:`View model RPM/TPM rate limits`,auth:`console`,usageArgs:`[--model <model>] [flags]`,flags:{model:{type:`string`,valueHint:`<model>`,description:`Model name(s), comma-separated`},all:{type:`switch`,description:`Show all models, not just self-service ones`}},exampleArgs:[``,`--model qwen3.6-plus`,`--model qwen3.6-plus,qwen-turbo`,`--all`,`--output json`],async run(e){let{settings:n,flags:r}=e,i=r.model||void 0,a=!!r.all,o=w(n.output);if(n.dryRun){let e={pageNo:1,pageSize:50,group:!1,queryQpmInfo:!0,ignoreWorkspaceServiceSite:!0};a||(e.supports={selfServiceLimitIncrease:!0}),R({api:Ei,data:{input:e}},o);return}let s=await ji(e.client,!a);if(i){let e=new Set(i.split(`,`).map(e=>e.trim()).filter(Boolean));if(s=s.filter(t=>e.has(t.model)),s.length===0)throw new t(`no matching models found for "${i}".`)}if(o===`json`){R(s.map(e=>{let t=e.qpmInfo,n=t?.[`model-default`],r=t?.[`user-spec`],i=Di(n),a=Oi(n),o=Di(r,n?.count_limit_period)||i,s=Oi(r,n?.usage_limit_period)||a,c=a*2;return{model:e.model,rpm:o>0?o:null,tpm:s>0?s:null,maxTPM:c>0?c:null}}),o);return}Mi(s)}});const Pi=`zeldaEasy.broadscope-platform.modelInstance.updateFoundationModelLimits`;function Fi(e,t){if(!e)return 0;let n=e.usage_limit_period||t;return n?Math.floor(e.usage_limit*60/n):0}function Ii(e,t){let n=e[t];if(n&&typeof n==`object`&&!Array.isArray(n))return n}function Li(e){let t=Ii(e,`data`);if(!t)return e;let n=Ii(t,`DataV2`);if(n){let e=Ii(n,`data`);return(e?Ii(e,`data`):void 0)??e??n}return Ii(t,`data`)??t}async function Ri(e,t){return(Li(await e.console(`zeldaHttp.dashscopeModel./zelda/api/v1/modelCenter/listFoundationModels`,{input:{pageNo:1,pageSize:50,name:t,group:!1,queryQpmInfo:!0,ignoreWorkspaceServiceSite:!0,supports:{selfServiceLimitIncrease:!0}}})).list??[]).find(e=>e.model===t&&e.qpmInfo)}var zi=x({description:`Request a temporary quota increase`,auth:`console`,usageArgs:`--model <model> --tpm <value> [flags]`,flags:{model:{type:`string`,valueHint:`<model>`,description:`Model name (required)`,required:!0},tpm:{type:`string`,valueHint:`<value>`,description:`Target TPM value (required)`,required:!0}},exampleArgs:[`--model qwen-turbo --tpm 100000`,`--model qwen3.6-plus --tpm 8000000`,`--model qwen-turbo --tpm 100000 --output json`],validate:e=>Number(e.tpm)>0?void 0:`--tpm must be a positive number.`,async run(e){let{identity:n,settings:r,flags:i}=e,o=i.model,s=Number(i.tpm),c=w(r.output);if(r.dryRun){R({api:Pi,data:{input:{model:o,limit:{usage_limit:s}}}},c);return}let l=await Ri(e.client,o);if(!l)throw new t(`model "${o}" not found or does not support self-service quota increase.`,a.GENERAL,`Run \`${n.binName} quota list\` to view available models.`);let d=l.qpmInfo[`model-default`],f=l.qpmInfo[`user-spec`],p=Fi(d),m=Fi(f,d?.usage_limit_period)||p,h=p*2;if(s<p||s>h)throw new u(`TPM value ${s.toLocaleString()} is out of range. Current: ${m.toLocaleString()}, Range: ${p.toLocaleString()} ~ ${h.toLocaleString()}.`);let g={input:{model:o,limit:{usage_limit:s},originalQpmInfo:l.qpmInfo}},_=async r=>{r&&(g.input.confirmedDowngrade=!0);try{return await e.client.console(Pi,g)}catch(e){throw e instanceof t&&e.message.includes(`NotLogined`)?new t(`session expired.`,a.AUTH,`Run \`${n.binName} auth login --console\` to re-authenticate.`):e}},v=await _(),y=Li(v);if(y.needConfirm){let e=y.confirmCode;if(e===`Refresh_Required`)throw new t(`rate limit has been updated externally. Please retry.`);e===`Downgrade`&&(v=await _(!0))}if(c===`json`){R(v,c);return}process.stdout.write(`Quota updated for "${o}": TPM ${m.toLocaleString()} → ${s.toLocaleString()}\n`)}});const Bi=`zeldaEasy.broadscope-platform.modelInstance.listModelLimitApplications`;function Vi(e,t){let n=e[t];if(n&&typeof n==`object`&&!Array.isArray(n))return n}function Hi(e){let t=Vi(e,`data`);if(!t)return e;let n=Vi(t,`DataV2`);if(n){let e=Vi(n,`data`);return(e?Vi(e,`data`):void 0)??e??n}return Vi(t,`data`)??t}function Ui(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 Wi(e){return e.toLocaleString(`en-US`)}function Gi(e,t){let n=P(process.stdout),r=[`Model`,`Token Limit`,`Applied At`],i=e.map(e=>[e.deployedModel,Wi(e.usageLimit),Ui(e.gmtCreate)]),a=r.map((e,t)=>Math.max(F(e),...i.map(e=>F(e[t])))),o=r.map((e,t)=>n.bold(V(e,a[t]))).join(` `),s=a.map(e=>n.dim(`─`.repeat(e))).join(`──`);process.stdout.write(o+`
|
|
76
|
+
`),process.stdout.write(s+`
|
|
77
|
+
`);for(let e of i)process.stdout.write(e.map((e,t)=>V(e,a[t])).join(` `)+`
|
|
78
|
+
`);process.stdout.write(n.dim(`\nTotal: ${t} records`)+`
|
|
79
|
+
`)}var Ki=x({description:`View quota change history`,auth:`console`,usageArgs:`[flags]`,flags:{page:{type:`string`,valueHint:`<n>`,description:`Page number (default: 1)`},pageSize:{type:`string`,valueHint:`<n>`,description:`Page size (default: 10)`},model:{type:`string`,valueHint:`<model>`,description:`Filter by model name`}},exampleArgs:[``,`--page 2`,`--page-size 20`,`--model qwen-turbo`,`--output json`],async run(e){let{identity:n,settings:r,flags:i}=e,o=Number(i.page)||1,s=Number(i.pageSize)||10,c=i.model||void 0,l=w(r.output),u={input:{pageNo:o,pageSize:s}};if(r.dryRun){R({api:Bi,data:u},l);return}let d;try{d=await e.client.console(Bi,u)}catch(e){throw e instanceof t&&e.message.includes(`NotLogined`)?new t(`session expired.`,a.AUTH,`Run \`${n.binName} auth login --console\` to re-authenticate.`):e}let f=Hi(d),p=f.records??[],m=f.items??p.length;if(c&&(p=p.filter(e=>e.deployedModel===c)),l===`json`){R({records:p.map(e=>({model:e.deployedModel,tokenLimit:e.usageLimit,appliedAt:Ui(e.gmtCreate)})),total:c?p.length:m},l);return}if(p.length===0){process.stdout.write(`No quota change history found.
|
|
80
|
+
`);return}Gi(p,c?p.length:m)}});const qi=`zeldaHttp.dashscopeModel./zelda/api/v1/modelCenter/listFoundationModels`,Ji=`zeldaEasy.bailian-telemetry.monitor.getMonitorData`;function Yi(e,t){if(!e)return 0;let n=e.count_limit_period||t;return n?Math.floor(e.count_limit*60/n):0}function Xi(e,t){if(!e)return 0;let n=e.usage_limit_period||t;return n?Math.floor(e.usage_limit*60/n):0}function Zi(e){return e.toLocaleString(`en-US`)}function Qi(e,t){if(t<=0)return`-`;let n=Math.round(e/t*100);return`${Zi(e)}/${Zi(t)} (${n}%)`}function $i(e,t){if(t<=0)return`-`;let n=e/t*100;return n>=100?`Rate Limited`:n>=80?`Near limit`:`Normal`}function ea(e,t){let n=e[t];if(n&&typeof n==`object`&&!Array.isArray(n))return n}function ta(e){let t=ea(e,`data`);if(!t)return e;let n=ea(t,`DataV2`);if(n){let e=ea(n,`data`);return(e?ea(e,`data`):void 0)??e??n}return ea(t,`data`)??t}async function na(e){let t=[],n=1;for(;;){let r=ta(await e.console(qi,{input:{pageNo:n,pageSize:50,group:!1,queryQpmInfo:!0,ignoreWorkspaceServiceSite:!0,supports:{selfServiceLimitIncrease:!0}}})),i=r.list??[],a=r.total??0;if(t.push(...i),t.length>=a||i.length===0)break;n++}return t}async function ra(e,t,n){let r=Date.now(),i=r-n*60*1e3;try{let n=ta(await e.console(Ji,{reqDTO:{monitorType:`Advanced`,metricFilters:[{aggMethod:`sum_pm`,metricName:`model_total_amount`},{aggMethod:`sum_pm`,metricName:`model_call_count`}],labelFilters:{resourceId:t,resourceType:`model`},startTime:i,endTime:r}})),a=n.data??n;if(!Array.isArray(a))return{rpm:0,tpm:0};let o=0,s=0;for(let e of a){if(e.aggMethod!==`sum_pm`||!e.points?.length)continue;let t=e.points[e.points.length-1].value??0;e.metricName===`model_call_count`&&(o=Math.round(t)),e.metricName===`model_total_amount`&&(s=Math.round(t))}return{rpm:o,tpm:s}}catch{return{rpm:-1,tpm:-1}}}function ia(e){let t=P(process.stdout),n=[`Model`,`RPM Usage/Limit`,`TPM Usage/Limit`,`Status`],r=e.map(e=>{let t=e.rpmUsage<0?`-`:Qi(e.rpmUsage,e.rpmLimit),n=e.tpmUsage<0?`-`:Qi(e.tpmUsage,e.tpmLimit),r=Math.max(e.rpmLimit>0?e.rpmUsage/e.rpmLimit*100:0,e.tpmLimit>0?e.tpmUsage/e.tpmLimit*100:0),i=e.rpmUsage<0?`-`:$i(Math.max(e.rpmUsage,e.tpmUsage),Math.max(e.rpmLimit,e.tpmLimit));return{cells:[e.model,t,n,i],maxPct:r}});if(r.length===0){process.stdout.write(`No models found.
|
|
81
|
+
`);return}let i=n.map((e,t)=>Math.max(F(e),...r.map(e=>F(e.cells[t])))),a=n.map((e,n)=>t.bold(V(e,i[n]))).join(` `),o=i.map(e=>t.dim(`─`.repeat(e))).join(`──`);process.stdout.write(a+`
|
|
82
|
+
`),process.stdout.write(o+`
|
|
83
|
+
`);for(let e of r){let n=e.cells.map((e,n)=>{if(n===3){if(e===`Rate Limited`)return t.red(V(e,i[n]));if(e===`Near limit`)return t.yellow(V(e,i[n]));if(e===`Normal`)return t.green(V(e,i[n]))}return V(e,i[n])});process.stdout.write(n.join(` `)+`
|
|
84
|
+
`)}process.stdout.write(t.dim(`\nTotal: ${e.length} models`)+`
|
|
85
|
+
`)}var aa=x({description:`Check current usage against rate limits`,auth:`console`,usageArgs:`[--model <model>] [flags]`,flags:{model:{type:`string`,valueHint:`<model>`,description:`Model name(s), comma-separated`},period:{type:`string`,valueHint:`<minutes>`,description:`Query usage for the last N minutes (default: 2)`}},exampleArgs:[``,`--model qwen3.6-plus`,`--period 5`,`--model qwen3.6-plus,qwen-turbo`,`--output json`],validate:e=>(Number(e.period)||2)<1?`--period must be at least 1 minute.`:void 0,async run(e){let{settings:t,flags:n}=e,r=n.model||void 0,i=Number(n.period)||2,a=w(t.output);if(t.dryRun){R({apis:[qi,Ji],...te(t)},a);return}let o=await na(e.client);if(r){let e=new Set(r.split(`,`).map(e=>e.trim()).filter(Boolean));o=o.filter(t=>e.has(t.model))}if(o=o.filter(e=>e.qpmInfo),o.length===0){process.stdout.write(`No models found.
|
|
86
|
+
`);return}let s=await Promise.all(o.map(t=>ra(e.client,t.model,i))),c=o.map((e,t)=>{let n=e.qpmInfo,r=n[`model-default`],i=n[`user-spec`],a=Yi(i,r?.count_limit_period)||Yi(r),o=Xi(i,r?.usage_limit_period)||Xi(r);return{model:e.model,rpmUsage:s[t].rpm,rpmLimit:a,tpmUsage:s[t].tpm,tpmLimit:o}});if(a===`json`){R(c,a);return}ia(c)}}),oa=x({description:`Upload a dataset file (.jsonl) to Bailian`,auth:`apiKey`,usageArgs:`--file <path> [--purpose <name>] [--schema <chatml|dpo|cpt>] [--no-validate] [--full-validate]`,flags:{file:{type:`string`,valueHint:`<path>`,description:`Local .jsonl dataset file (≤300MB)`,required:!0},purpose:{type:`string`,valueHint:`<name>`,description:`Dataset purpose tag (default: "fine-tune"; e.g. "evaluation")`},schema:{type:`string`,valueHint:`<s>`,description:`Record schema: "chatml" (SFT), "dpo" (chosen/rejected), or "cpt" (raw text). Default auto-detects per record.`},noValidate:{type:`switch`,description:`Skip the local JSONL pre-flight check (not recommended)`},fullValidate:{type:`switch`,description:`JSON.parse every line instead of sampling (slower)`}},exampleArgs:[`--file train.jsonl`,`--file dpo.jsonl --schema dpo`,`--file cpt.jsonl --schema cpt`,`--file eval.jsonl --purpose evaluation`,`--file train.jsonl --full-validate`,`--file train.jsonl --no-validate`],notes:[`Only .jsonl is supported in this release. Three record schemas are`,`recognized: chatml = {messages:[...]} (SFT); dpo = {messages:[...],`,`chosen, rejected} where chosen/rejected are single assistant messages;`,`cpt = {text:"..."} (continual pre-training, raw text). With no --schema,`,`a record carrying chosen/rejected is validated as DPO, one with text (and`,`no messages) as CPT, otherwise as ChatML. Pass --schema dpo / cpt to`,`require that shape on every record, or --schema chatml to ignore the`,`preference / text fields. Other purposes may carry a different schema in`,`the future and would be served by a purpose-specific validator.`,`The dataset upload cap is 300MB per file.`,`Upload uses the OpenAI-compatible /compatible-mode/v1/files endpoint so`,`the purpose tag is persisted (the DashScope-native /api/v1/files drops it).`],async run(e){let{identity:n,settings:r,flags:i}=e,s=i.file,c=i.purpose||`fine-tune`,l=je(i.schema),u=w(r.output);if(!i.noValidate){let e=await qe(s,{fullValidate:i.fullValidate,schema:l});if(!e.valid){let r=[`Dataset validation failed for ${s}`,...e.errors.slice(0,10).map(E)];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(`
|
|
87
|
+
`),a.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(`${E(t)}\n`);e.warnings.length>5&&process.stderr.write(` … and ${e.warnings.length-5} more.\n`)}}if(r.dryRun){R({action:`dataset.upload`,file:s,purpose:c,max_bytes:o,validate:!i.noValidate,schema:l??`auto`},u);return}let d=await Ge(e.client,{filePath:s,purpose:c});r.quiet?L(d.file_id):u===`text`?L(`Uploaded ${d.name} → file_id=${d.file_id}`):R(d,u)}}),sa=x({description:`List uploaded dataset files`,auth:`apiKey`,usageArgs:`[--page <n>] [--page-size <n>] [--purpose <name>]`,flags:{page:{type:`number`,valueHint:`<n>`,description:`Page number (default: 1)`},pageSize:{type:`number`,valueHint:`<n>`,description:`Results per page (default: 10, max 100)`},purpose:{type:`string`,valueHint:`<name>`,description:`Filter by purpose (e.g. "fine-tune", "evaluation"). Omit to list all.`}},exampleArgs:[``,`--purpose fine-tune`,`--purpose evaluation --page-size 20`,`--output json`],async run(e){let{settings:t,flags:n}=e,r=w(t.output);if(t.dryRun){R({action:`dataset.list`,page:n.page,page_size:n.pageSize,purpose:n.purpose},r);return}let i=await be(e.client,{pageNo:n.page,pageSize:n.pageSize,purpose:n.purpose||void 0}),a=i.data?.files??[],o=i.data?.total,s=a.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(r===`json`){R({items:s,total:o},r);return}if(s.length===0){L(`No dataset files found.`);return}let c=[`FILE_ID`,`NAME`,`SIZE`,`PURPOSE`],l=s.map(e=>[e.file_id,e.name,e.size,e.purpose]);for(let e of z(c,l))L(e);o!==void 0&&L(`\nTotal: ${o}`)}}),ca=x({description:`Get details of a single dataset file`,auth:`apiKey`,usageArgs:`--file-id <id>`,flags:{fileId:{type:`string`,valueHint:`<id>`,description:`Dataset file ID (required)`,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,i=w(t.output);if(t.dryRun){R({action:`dataset.get`,file_id:r},i);return}let a=(await se(e.client,r)).data;if(!a){L(`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??``};if(i===`json`){R(s,i);return}L(`file_id: ${s.file_id}`),L(`name: ${s.name}`),L(`size: ${s.size}`),s.md5&&L(`md5: ${s.md5}`),s.purpose&&L(`purpose: ${s.purpose}`),s.created_at&&L(`created_at: ${s.created_at}`),s.description&&L(`description: ${s.description}`)}}),la=x({description:`Delete a dataset file by ID`,auth:`apiKey`,usageArgs:`--file-id <id>`,flags:{fileId:{type:`string`,valueHint:`<id>`,description:`Dataset file ID (required)`,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,i=w(t.output);if(t.dryRun){R({action:`dataset.delete`,file_id:r},i);return}let a=await S(e.client,r);t.quiet||i===`text`?L(`Deleted ${r}.`):R(a,i)}});function ua(e){let t=[];return e.stats.totalRecords!==void 0&&t.push(`records: ${e.stats.totalRecords}`),e.stats.sampledRecords!==void 0&&t.push(`sampled: ${e.stats.sampledRecords}`),e.stats.bytes!==void 0&&t.push(`bytes: ${e.stats.bytes}`),e.stats.durationMs!==void 0&&t.push(`took: ${e.stats.durationMs}ms`),t}var da=x({description:`Locally validate a dataset file (.jsonl) without uploading`,auth:`none`,usageArgs:`--file <path> [--full-validate] [--schema <chatml|dpo|cpt>]`,flags:{file:{type:`string`,valueHint:`<path>`,description:`Local .jsonl dataset file`,required:!0},fullValidate:{type:`switch`,description:`JSON.parse every line instead of sampling (slower)`},schema:{type:`string`,valueHint:`<s>`,description:`Record schema: "chatml" (SFT), "dpo" (chosen/rejected), or "cpt" (raw text). Default auto-detects per record.`}},exampleArgs:[`--file train.jsonl`,`--file dpo.jsonl --schema dpo`,`--file cpt.jsonl --schema cpt`,`--file eval.jsonl --full-validate`,`--file train.jsonl --output json`],notes:[`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.`,`Schemas: chatml = {messages:[...]} (SFT); dpo = {messages:[...], chosen,`,`rejected} where chosen/rejected are single assistant messages; cpt =`,`{text:"..."} (continual pre-training, raw text). With no --schema, a`,`record carrying chosen/rejected is validated as DPO, one with text (and no`,`messages) as CPT, otherwise as ChatML. Pass --schema dpo / cpt to require`,`that shape on every record (strict), or --schema chatml to ignore the`,`preference / text fields. Use --full-validate to JSON.parse every line.`],async run(e){let{settings:n,flags:r}=e,i=r.file,o=je(r.schema),s=w(n.output);if(n.dryRun){R({action:`dataset.validate`,file:i,full:r.fullValidate,schema:o??`auto`},s);return}let c=await qe(i,{fullValidate:r.fullValidate,schema:o});if(s===`json`)R(c,s);else if(n.quiet)L(c.valid?`ok`:`fail`);else{L(`Dataset validation ${c.valid?`PASSED`:`FAILED`} for ${c.filePath}`);let e=ua(c);if(e.length&&L(` ${e.join(` · `)}`),c.errors.length){L(`Errors (${c.errors.length}):`);for(let e of c.errors.slice(0,20))L(E(e));c.errors.length>20&&L(` … and ${c.errors.length-20} more.`)}if(c.warnings.length){L(`Warnings (${c.warnings.length}):`);for(let e of c.warnings.slice(0,10))L(E(e));c.warnings.length>10&&L(` … and ${c.warnings.length-10} more.`)}}if(!c.valid)throw new t(`Dataset validation failed: ${c.errors.length} error(s).`,a.GENERAL)}});function fa(e){return ht(e)&&_t(e).isFile()}async function pa(e,n,r,i,o){let s=r.split(`,`).map(e=>e.trim()).filter(Boolean);if(s.length===0)throw new t(`--${i} must contain at least one entry.`,a.USAGE);let c=[],l=[],u,d,f=!0;for(let r of s){if(!fa(r)){c.push(r),f=!1;continue}if(c.push(r),l.push(r),e.dryRun)continue;let i=await qe(r,{schema:o});if(!i.valid){let e=[`Dataset validation failed for ${r}`,...i.errors.slice(0,10).map(E)];throw i.errors.length>10&&e.push(` … and ${i.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(`
|
|
88
|
+
`),a.GENERAL)}if(i.warnings.length>0&&!e.quiet){process.stderr.write(`Dataset validation passed with ${i.warnings.length} warning(s) for ${r}:\n`);for(let e of i.warnings.slice(0,5))process.stderr.write(`${E(e)}\n`);i.warnings.length>5&&process.stderr.write(` … and ${i.warnings.length-5} more.\n`)}let s=i.stats.totalRecords;typeof s==`number`&&(d=(d??0)+s),u===void 0&&(u=_t(r).size)}return{fileIds:c,localPaths:l,firstSize:u,recordCount:f?d:void 0}}async function ma(e,n,r,i,o){let s=[];for(let[c,l]of r.fileIds.entries()){if(!fa(l))continue;let u=await Ge(e,{filePath:l,purpose:i});if(!u.file_id)throw new t(`Upload of ${l} succeeded but no file_id was returned.`,a.GENERAL);s.push(u),r.fileIds[c]=u.file_id,n.quiet||process.stderr.write(`Uploaded ${yt(l)} → ${u.file_id} (auto from --${o})\n`)}return s}var ha=x({description:`Create a fine-tune job (sft | sft-lora | dpo | dpo-lora | cpt)`,auth:`apiKey`,usageArgs:`--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:{model:{type:`string`,valueHint:`<model>`,description:`Base model to fine-tune (e.g. qwen3-8b, qwen3-14b)`,required:!0},datasets:{type:`string`,valueHint:`<ids|paths>`,description:`Comma-separated dataset file IDs or local .jsonl paths. Local paths are uploaded (validated) first, then their file-ids are used.`,required:!0},validations:{type:`string`,valueHint:`<ids|paths>`,description:`Comma-separated validation dataset file IDs or local .jsonl paths (auto-uploaded like --datasets).`},modelName:{type:`string`,valueHint:`<name>`,description:`Output model name (after training)`},suffix:{type:`string`,valueHint:`<text>`,description:`Output suffix appended by the platform (finetuned_output_suffix)`},trainingType:{type:`string`,valueHint:`<t>`,description:`Training type: ${l.join(` | `)} (default: ${r}). Mapping to the server happens at the interface boundary (e.g. sft-lora -> efficient_sft, dpo -> dpo_full).`},nEpochs:{type:`number`,valueHint:`<n>`,description:`Number of epochs (default: 3)`},batchSize:{type:`number`,valueHint:`<n>`,description:`Per-device batch size (clamped to [8, 1024]). Auto-set to 8 for small datasets (<100KB)`},learningRate:{type:`string`,valueHint:`<str>`,description:`Learning rate as a string to preserve precision (e.g. "1.6e-5")`},maxLength:{type:`number`,valueHint:`<n>`,description:`Max sequence length`}},exampleArgs:[`--model qwen3-8b --datasets file-xxx`,`--model qwen3-8b --datasets ./train.jsonl`,`--model qwen3-8b --datasets ./train.jsonl --validations ./eval.jsonl`,`--model qwen3-8b --datasets file-aaa,./extra.jsonl`,`--model qwen3-8b --datasets ./train.jsonl --training-type sft`,`--model qwen3-8b --datasets file-xxx --learning-rate "1.6e-5" --n-epochs 4`,`--model qwen3-8b --datasets file-xxx --output json`,`--model qwen3-8b --datasets file-xxx --dry-run`],notes:[`Creating a job uploads any local datasets and consumes training quota.`,`Use --dry-run to preview the request body without submitting.`,"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.`,`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.`,`n_epochs defaults to 3. Other hyper-parameters are platform defaults unless set.`,`Learning rate is forwarded as a string to avoid JSON-number precision loss.`,"--datasets / --validations accept either file-ids (from `dataset upload`)",`or local .jsonl paths. Local paths are validated and uploaded first, then`,`their file-ids are submitted — a one-step upload-and-train.`,`Dataset record schema is chosen from --training-type: dpo* → {messages,`,`chosen, rejected}; cpt → {text} (raw pre-training text); else {messages}.`,`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).`],async run(e){let{identity:n,settings:i,flags:o}=e,s=o.model,c=o.datasets,u=o.trainingType||r;if(!he(u))throw new t(`--training-type "${u}" is not supported.`,a.USAGE,`Supported values: ${l.join(`, `)} (default: ${r}).`);let d=u.startsWith(`dpo`)?`dpo`:u===`cpt`?`cpt`:`chatml`,f=await pa(i,n.binName,c,`datasets`,d),p=f.fileIds,m=o.validations?await pa(i,n.binName,o.validations,`validations`,d):void 0,h=m?.fileIds,g=o.modelName,_=o.suffix,v={};if(v.n_epochs=o.nEpochs??3,o.learningRate!==void 0&&(v.learning_rate=o.learningRate),o.maxLength!==void 0&&(v.max_length=o.maxLength),o.batchSize!==void 0){let e=o.batchSize,t=e;t<8&&(t=8),t>1024&&(t=1024),t!==e&&!i.quiet&&process.stderr.write(`warning: --batch-size ${e} clamped to ${t} (server range [8, 1024] for the common training types).\n`),v.batch_size=t}if(v.batch_size===void 0&&!i.dryRun){let t=f.firstSize??0;if(t===0)try{t=(await se(e.client,p[0])).data?.size??0}catch{}t>0&&t<100*1024&&(v.batch_size=8)}if(!i.dryRun&&f.recordCount!==void 0){let e=v.batch_size??16,n=Me({recordCount:f.recordCount,batchSize:e});if(!n.ok&&n.issue)throw new t(n.issue.message,a.GENERAL,n.hint)}if(!i.dryRun){let e;try{e=await re(i,s)}catch(e){i.quiet||process.stderr.write(`warning: model capability lookup failed (${e.message}); proceeding without local pre-flight.
|
|
89
|
+
`)}if(e&&!we(e).includes(u)){let n=we(e);throw new t(`Model "${s}" does not support training type "${u}".`,a.USAGE,n.length?`This model supports: ${n.join(`, `)}.`:`This model reports no supported training types.`)}}i.dryRun||(await ma(e.client,i,f,`fine-tune`,`datasets`),m&&await ma(e.client,i,m,`fine-tune`,`validations`));let y={model:s,training_file_ids:p,training_type:Ve(u),hyper_parameters:v};h&&h.length>0&&(y.validation_file_ids=h),g&&(y.model_name=g),_&&(y.finetuned_output_suffix=_);let x=w(i.output);if(i.dryRun){let e=[...f.localPaths.map(e=>({field:`datasets`,path:e})),...(m?.localPaths??[]).map(e=>({field:`validations`,path:e}))];R(e.length>0?{action:`finetune.create`,body:y,pending_uploads:e}:{action:`finetune.create`,body:y},x);return}let S=await b(e.client,y),C=S.output??S.data;i.quiet?C?.job_id&&L(C.job_id):x===`text`&&C?.job_id?(L(`Created fine-tune job: ${C.job_id}`),C.status&&L(`Status: ${C.status}`)):R(S,x)}}),ga=x({description:`List fine-tune jobs`,auth:`apiKey`,usageArgs:`[--page <n>] [--page-size <n>] [--status <s>]`,flags:{page:{type:`number`,valueHint:`<n>`,description:`Page number (default: 1)`},pageSize:{type:`number`,valueHint:`<n>`,description:`Results per page (default: 10, max 100)`},status:{type:`string`,valueHint:`<s>`,description:`Filter by status (PENDING / RUNNING / SUCCEEDED / FAILED / CANCELED)`}},exampleArgs:[``,`--status RUNNING`,`--page-size 20 --output json`],async run(e){let{identity:t,settings:n,flags:r}=e,i=w(n.output),a=r.page,o=r.pageSize,s=r.status||void 0;if(n.dryRun){R({action:`finetune.list`,page:a,page_size:o,status:s},i);return}let c=await Ce(e.client,{pageNo:a,pageSize:o,status:s}),l=c.output??c.data,u=l?.jobs??[],d=l?.total,f=u.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??``}));if(i===`json`){R({items:f,total:d},i);return}if(f.length===0){L(`No fine-tune jobs found.`);return}let p=[`JOB_ID`,`BASE_MODEL`,`STATUS`,`TRAINING_TYPE`,`OUTPUT_MODEL`,`CREATED_AT`],m=f.map(e=>[e.job_id,e.base_model,e.status,e.training_type,e.output_model,e.created_at]);for(let e of z(p,m))L(e);d!==void 0&&L(`\nTotal: ${d}`),L(`Tip: OUTPUT_MODEL is the input for \`${t.binName} deploy create --model\``)}}),_a=x({description:`Get details of a single fine-tune job`,auth:`apiKey`,usageArgs:`--job-id <id>`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:`Fine-tune job ID (required)`,required:!0}},exampleArgs:[`--job-id ft-xxx`,`--job-id ft-xxx --output json`],async run(e){let{identity:t,settings:n,flags:r}=e,i=r.jobId,a=w(n.output);if(n.dryRun){R({action:`finetune.get`,job_id:i},a);return}let o=await le(e.client,i),s=o.output??o.data;if(!s){L(`No data returned for ${i}`);return}let c=s.hyper_parameters,l=[];c?.n_epochs!==void 0&&l.push(`n_epochs=${c.n_epochs}`),c?.batch_size!==void 0&&l.push(`batch_size=${c.batch_size}`),c?.learning_rate!==void 0&&l.push(`learning_rate=${c.learning_rate}`),c?.max_length!==void 0&&l.push(`max_length=${c.max_length}`);let u={job_id:s.job_id??i,base_model:s.model??``,status:s.status??``,training_type:s.training_type??``,training_files:s.training_file_ids??[],validation_files:s.validation_file_ids??[],hyper_params:l.length?l.join(` · `):``,output_model:s.finetuned_output??``,model_name:s.model_name??``,created_at:s.create_time??s.gmt_create??``,updated_at:s.end_time??s.gmt_modified??``};if(a===`json`){R(u,a);return}L(`job_id: ${u.job_id}`),u.base_model&&L(`base_model: ${u.base_model}`),u.status&&L(`status: ${u.status}`),u.training_type&&L(`training_type: ${u.training_type}`),u.training_files.length&&L(`training_files: ${u.training_files.join(`, `)}`),u.validation_files.length&&L(`validation_files: ${u.validation_files.join(`, `)}`),u.hyper_params&&L(`hyper_params: ${u.hyper_params}`),u.output_model&&L(`output_model: ${u.output_model} (→ ${t.binName} deploy create --model)`),u.model_name&&L(`model_name: ${u.model_name}`),u.created_at&&L(`created_at: ${u.created_at}`),u.updated_at&&L(`updated_at: ${u.updated_at}`)}}),va=x({description:`Cancel a running fine-tune job`,auth:`apiKey`,usageArgs:`--job-id <id>`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:`Fine-tune job ID (required)`,required:!0}},exampleArgs:[`--job-id ft-xxx`,`--job-id ft-xxx --dry-run`],notes:[`Only PENDING / RUNNING jobs can be cancelled. Completed / failed / already-`,`cancelled jobs return a server-side error (passed through verbatim).`],async run(e){let{settings:t,flags:n}=e,r=n.jobId,i=w(t.output);if(t.dryRun){R({action:`finetune.cancel`,job_id:r},i);return}let a=await _(e.client,r),o=a.output??a.data;t.quiet?L(r):i===`text`?L(`Cancelled ${r}${o?.status?` (status=${o.status})`:``}.`):R(a,i)}}),ya=x({description:`Delete a fine-tune job record`,auth:`apiKey`,usageArgs:`--job-id <id>`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:`Fine-tune job ID (required)`,required:!0}},exampleArgs:[`--job-id ft-xxx`,`--job-id ft-xxx --dry-run`],notes:["Cancel a RUNNING job first via `finetune cancel` — the platform refuses",`to delete jobs that are still in flight.`],async run(e){let{settings:t,flags:n}=e,r=n.jobId,i=w(t.output);if(t.dryRun){R({action:`finetune.delete`,job_id:r},i);return}let a=await ee(e.client,r);t.quiet?L(r):i===`text`?L(`Deleted ${r}.`):R(a,i)}});function ba(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 xa(e,t){return ba(e).toLowerCase().includes(t)}async function Sa(e,t,n){let r=[],i=1,a=0;for(let o=0;o<200;o++){let o=await ue(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 Ca=x({description:`Fetch training logs for a fine-tune job`,auth:`apiKey`,usageArgs:`--job-id <id> [--page <n>] [--page-size <n>] [--search <keyword>] [--tail <n>]`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:`Fine-tune job ID (required)`,required:!0},page:{type:`number`,valueHint:`<n>`,description:`Page number (default: 1)`},pageSize:{type:`number`,valueHint:`<n>`,description:`Lines per page (default: server-defined)`},search:{type:`string`,valueHint:`<keyword>`,description:`Case-insensitive substring filter. When set, all log pages are fetched and filtered client-side (--page is ignored).`},tail:{type:`number`,valueHint:`<n>`,description:`Keep only the last N entries. When set, all log pages are fetched and the trailing N are kept (--page is ignored).`}},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,c=w(t.output);if(t.dryRun){R({action:`finetune.logs`,job_id:r,page:i,page_size:a,search:o,tail:s},c);return}if(o||s!==void 0){let{entries:n,total:i}=await Sa(e.client,r,a??100),l=n,u;if(o){let e=o.toLowerCase();l=n.filter(t=>xa(t,e)),u=l.length}let d=s!==void 0&&s>=0?Math.min(s,l.length):void 0,f=d===void 0?l:l.slice(l.length-d);if(t.quiet||c===`text`){if(f.length===0){L(o?`No logs matched "${o}".`:`No logs returned.`);return}for(let e of f)L(ba(e));let e=[`${f.length} shown`];u!==void 0&&e.push(`matched ${u}`),e.push(`of ${n.length}`+(i?` (total ${i})`:``)),L(`\n${e.join(`, `)}`);return}R({...u===void 0?{}:{matched:u},scanned:n.length,total:i||n.length,...o?{search:o}:{},...d===void 0?{}:{tail:d},logs:f},c);return}let l=await ue(e.client,r,{pageNo:i,pageSize:a}),u=l.output??l.data,d=u?.logs??[];if(t.quiet||c===`text`){if(d.length===0){L(`No logs returned.`);return}for(let e of d)L(ba(e));u?.total!==void 0&&L(`\nTotal: ${u.total}`)}else R(l,c)}}),wa=x({description:`List checkpoints produced by a fine-tune job`,auth:`apiKey`,usageArgs:`--job-id <id>`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:`Fine-tune job ID (required)`,required:!0}},exampleArgs:[`--job-id ft-xxx`,`--job-id ft-xxx --output json`],notes:["Use the returned `checkpoint` value with `finetune export` to publish",`a deployable model.`],async run(e){let{settings:t,flags:n}=e,r=n.jobId,i=w(t.output);if(t.dryRun){R({action:`finetune.checkpoints`,job_id:r},i);return}let a=await ye(e.client,r),o=a.output??a.data,s=Array.isArray(o)?o:o?.checkpoints??[],c=Array.isArray(o)?o.length:o?.total??s.length,l=s.map(e=>({checkpoint:e.checkpoint??e.checkpoint_id??``,step:e.step===void 0?``:String(e.step),status:e.status??``}));if(i===`json`){R({items:l,total:c},i);return}if(l.length===0){L(`No checkpoints found.`);return}let u=[`CHECKPOINT`,`STEP`,`STATUS`],d=l.map(e=>[e.checkpoint,e.step,e.status]);for(let e of z(u,d))L(e);L(`\nTotal: ${c}`)}}),Ta=x({description:`Publish a checkpoint as a deployable model`,auth:`apiKey`,usageArgs:`--job-id <id> --checkpoint <name> --model-name <name>`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:`Fine-tune job ID (required)`,required:!0},checkpoint:{type:`string`,valueHint:`<name>`,description:"Checkpoint identifier from `finetune checkpoints` (required)",required:!0},modelName:{type:`string`,valueHint:`<name>`,description:`Deployable model name (required)`,required:!0}},exampleArgs:[`--job-id ft-xxx --checkpoint ckpt-3 --model-name my-qwen-sft`],notes:["Required before `deploy 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.`],async run(e){let{identity:t,settings:n,flags:r}=e,i=r.jobId,a=r.checkpoint,o=r.modelName,s=w(n.output);if(n.dryRun){R({action:`finetune.export`,job_id:i,checkpoint:a,model_name:o},s);return}let c=await ne(e.client,i,a,o),l=(c.output??c.data)?.model_name??o;n.quiet?L(l):s===`text`?(L(`Exported ${i} / ${a} → model_name=${l}`),L(`Next: ${t.binName} deploy create --model ${l} --name <display-name>`)):R(c,s)}});const Ea=new Set([`SUCCEEDED`,`FAILED`,`CANCELED`]);function Da(){let e=new Date,t=e=>String(e).padStart(2,`0`);return`${t(e.getHours())}:${t(e.getMinutes())}:${t(e.getSeconds())}`}function Oa(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 ka(e){return e===`SUCCEEDED`?0:Ea.has(e)?1:3}function Aa(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 ja=x({description:`Probe a fine-tune job's status (default: single non-blocking fetch). Pass --follow to poll until terminal.`,auth:`apiKey`,usageArgs:`--job-id <id> [--follow] [--interval <sec>] [--poll-timeout <sec>]`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:`Fine-tune job ID (required)`,required:!0},follow:{type:`switch`,description:`Block and poll until a terminal state (the legacy behavior). Without it, a single status probe is performed and the command returns immediately.`},interval:{type:`number`,valueHint:`<sec>`,description:`Seconds between polls with --follow (default: 10, min: 1). Ignored without --follow.`},pollTimeout:{type:`number`,valueHint:`<sec>`,description:`With --follow, stop polling after this many seconds (default: no limit). Ignored without --follow.`}},exampleArgs:[`--job-id ft-xxx # single probe, returns immediately`,`--job-id ft-xxx --output json # status probe for agents`,`--job-id ft-xxx --follow # block until terminal`,`--job-id ft-xxx --follow --interval 5`,`--job-id ft-xxx --follow --poll-timeout 3600`],notes:[`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.`,`Exit codes (both modes): 0 SUCCEEDED | 1 FAILED/CANCELED | 2 --poll-timeout`,`exceeded (--follow) | 3 still running (non-terminal, default mode) | 130`,`interrupted (Ctrl-C).`,`Use --follow for the blocking, human-terminal-follow experience; use the`,`default mode when driving the loop yourself (e.g. from an agent).`,"For per-step training output (not status), use `finetune logs`."],async run(e){let{settings:t,flags:n}=e,r=n.jobId,i=n.follow,a=Math.max(1,n.interval??10),o=n.pollTimeout,s=w(t.output);if(t.dryRun){R({action:`finetune.watch`,job_id:r,follow:i,interval:a,timeout:o},s);return}if(!i){let n=await le(e.client,r),i=n.output??n.data,a=String(i?.status??``).toUpperCase(),o=Ea.has(a),c=ka(a);t.quiet?L(a||`UNKNOWN`):s===`text`?(L(`${Da()} ${r} ${a||`UNKNOWN`}`),o&&L(`${a===`SUCCEEDED`?`✓`:`✗`} ${r} ${a}`)):R({job_id:r,status:a||`UNKNOWN`,terminal:o},s),process.exit(c)}let c=new AbortController,l=()=>c.abort();process.on(`SIGINT`,l);try{let n=``,i=Date.now();for(;;){let l=await le(e.client,r,c.signal),u=l.output??l.data,d=String(u?.status??``).toUpperCase();if(s===`text`&&!t.quiet&&d!==n&&(L(`${Da()} ${r} ${d||`UNKNOWN`}`),n=d),Ea.has(d)){let e=Date.now()-i;s!==`text`||t.quiet?R(l,s):L(`\n${d===`SUCCEEDED`?`✓`:`✗`} ${r} ${d} (elapsed ${Oa(e)})`),process.exit(ka(d))}o!==void 0&&(Date.now()-i)/1e3>=o&&(s===`text`&&!t.quiet&&L(`\n⏼ ${r} timed out after ${Oa(Date.now()-i)} (last status: ${d||`UNKNOWN`})`),process.exit(2)),await Aa(a*1e3,c.signal)}}catch(e){throw c.signal.aborted&&(L(`
|
|
90
|
+
Interrupted.`),process.exit(130)),e}finally{process.off(`SIGINT`,l)}}});async function Ma(e){let t=te(e),n=(n,r)=>g({region:t.consoleRegion,site:t.consoleSite,switchAgent:t.consoleSwitchAgent},e.timeout,{api:n,data:r}),r=await T(n,{pageNo:1,pageSize:50}),i=[...r.models],a=Math.ceil(r.total/50);for(let e=2;e<=a;e++){let t=await T(n,{pageNo:e,pageSize:50});i.push(...t.models)}return i}const Na={full:`full-parameter`,lora:`LoRA`};function Pa(e){if(!he(e))return e;let{method:t,variant:n}=Ue(e);return`${Na[n]??n} ${t.toUpperCase()}`}var Fa=x({description:`Query fine-tune training capability — by model (which training types it supports) or by training type (which models support it)`,auth:`none`,usageArgs:`--model <m> | --training-type <t>`,flags:{model:{type:`string`,valueHint:`<m>`,description:`List training types supported by this base model.`},trainingType:{type:`string`,valueHint:`<t>`,description:`List models supporting this training type: ${l.join(` | `)}.`}},exampleArgs:[`--model qwen3-8b`,`--training-type sft-lora`,`--training-type cpt --output json`,`--training-type sft --quiet`],notes:[`Exactly one of --model / --training-type is required.`,"Training-type values use the `<method>` / `<method>-lora` convention:",`sft | sft-lora | dpo | dpo-lora | cpt. (cpt has no -lora variant server-side.)`,`Queries listFoundationModels, a public API — no console login needed.`],validate:e=>{if(e.model&&e.trainingType)return`--model and --training-type are mutually exclusive; pass one.`;if(!e.model&&!e.trainingType)return`one of --model / --training-type is required.`},async run(e){let{settings:t,flags:n}=e,r=n.model||void 0,i=n.trainingType||void 0,a=w(t.output);if(t.dryRun){R({action:`finetune.capability`,model:r,training_type:i},a);return}if(r){let e=await re(t,r);if(!e){L(`No foundation model found matching "${r}".`);return}let n=we(e);if(t.quiet){for(let e of n)L(e);return}if(a!==`text`){R({model:e.model??r,supported:n,supports:e.supports,trainingTypes:e.trainingTypes},a);return}L(`${e.model??r}`),L(n.length?`Supported training types:`:`No supported training types.`);for(let e of n)L(` ${e.padEnd(10)} ${Pa(e)}`);return}if(!i||!he(i))throw new u(`--training-type "${i}" is not supported. Valid: ${l.join(`, `)}.`);let{method:o,variant:s}=Ue(i),c=(await Ma(t)).filter(e=>Ae(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 c)L(e.model);return}if(a!==`text`){R({training_type:i,method:o,variant:s,count:c.length,models:c},a);return}L(`Models supporting ${i} (${o} / ${s}): ${c.length}`);for(let e of c)L(` ${e.model}`)}});const Ia={lora:{name:`lora`,validateFlags(){},async resolve(){return{body:{capacity:1}}}},ptu:{name:`ptu`,validateFlags(e){if(e.inputTpm===void 0||e.outputTpm===void 0)return`--input-tpm and --output-tpm are required for plan=ptu.`},async resolve(e){let t={input_tpm:e.flags.inputTpm,output_tpm:e.flags.outputTpm};return e.flags.thinkingOutputTpm!==void 0&&(t.thinking_output_tpm=e.flags.thinkingOutputTpm),{body:{ptu_capacity:t}}}},mu:{name:`mu`,validateFlags(){},async resolve(e){let n=e.flags.billingMethod||`POST_PAY`,r=e.flags.templateId,i=e.flags.capacity;if(!e.dryRun&&!r){let o=()=>new t(`No mu-plan template found for model "${e.model}". Run \`${e.binName} deploy models --source base\` to inspect available models, or pass --template-id explicitly.`,a.USAGE);try{let t=await xe(e.client,{modelSource:`base`,pageSize:100,version:`v1.0`}),a=((t.output??t.data)?.models??[]).find(t=>t.model_name===e.model)?.plans?.find(e=>e.plan===`mu`)?.templates??[];if(a.length===0)throw o();let s=n===`POST_PAY`?`post_paid`:`pre_paid`,c=a.find(e=>e.charge_type===s)??a[0];if(!c?.template_id)throw o();r=c.template_id,i===void 0&&(i=c.roles?.unified?.capacity_unit_per_instance??1)}catch(e){throw e instanceof t?e:new t(`Failed to auto-pick template for plan=mu: ${e.message}. Pass --template-id explicitly.`,a.USAGE)}}let o={capacity:i??1,billing_method:n};return r&&(o.template_id=r),{body:o}}}};function La(e){let n=Ia[e];if(!n)throw new t(`Unsupported plan "${e}". Supported plans: ${Object.keys(Ia).join(`, `)}.`,a.USAGE);return n}var Ra=x({description:`Create a model deployment`,auth:`apiKey`,usageArgs:`--model <model_name> --name <display_name> [--plan <plan>] [--template-id <id>] [--capacity <n>] [--billing-method <m>] [--input-tpm <n>] [--output-tpm <n>] [--thinking-output-tpm <n>]`,flags:{model:{type:`string`,valueHint:`<name>`,description:`Model name (catalog model or fine-tuned output) (required)`,required:!0},name:{type:`string`,valueHint:`<display_name>`,description:`Console display name for the deployment (required)`,required:!0},plan:{type:`string`,valueHint:`<plan>`,description:`Billing plan: lora (default, Token-billed) | ptu (Token-billed) | mu`},templateId:{type:`string`,valueHint:`<id>`,description:`Template id (only used by plan=mu; auto-picked if omitted)`},capacity:{type:`number`,valueHint:`<n>`,description:`Resource units (plan=mu only; required by API; defaults to the template's unit)`},billingMethod:{type:`string`,valueHint:`<m>`,description:`Billing method (plan=mu only; default "POST_PAY", the only supported value)`},inputTpm:{type:`number`,valueHint:`<n>`,description:`PTU max input tokens/min (required for plan=ptu)`},outputTpm:{type:`number`,valueHint:`<n>`,description:`PTU max output tokens/min (required for plan=ptu)`},thinkingOutputTpm:{type:`number`,valueHint:`<n>`,description:`PTU max thinking-output tokens/min (optional, some models)`}},exampleArgs:[`--model my-qwen-sft --name my-sft-test`,`--model qwen3.6-flash-2026-04-16 --name my-flash --plan ptu --input-tpm 10000 --output-tpm 1000`,`--model qwen3-8b --name my-qwen3-mu --plan mu`,`--model qwen3-8b --name my-qwen3 --plan mu --template-id MU1 --capacity 2`],notes:["Plan defaults to `lora` (Token-billed). Pass --plan to override.",`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).`,"For plan=mu, `capacity`, `billing_method` and `template_id` are required.",`billing_method defaults to POST_PAY (only supported value); template_id`,`and capacity are auto-picked from GET /deployments/models when omitted.`,"Use `bl deploy models --source base` to inspect available templates.",`After creation, status starts at PENDING and transitions to RUNNING.`,`Invoke the deployed model with: bl text chat --model <deployed_model>`,`WARNING: --model is overloaded across commands and refers to DIFFERENT`,"values. `bl deploy create --model` takes the exported model_name (e.g.","`qwen3-8b-ft-...`), but the create response also returns a `deployed_model`","field (the deployment instance id, e.g. `qwen3-8b-5ecb5f068d79`). The","inference call `bl text chat --model` must use the `deployed_model` from","the create response — NOT the `model_name` you passed to `deploy create`.",`Do not reuse the value across the two commands.`],validate:e=>{let t=e.plan||`lora`,n=Ia[t];return n?n.validateFlags(e):`Unsupported plan "${t}". Supported plans: ${Object.keys(Ia).join(`, `)}.`},async run(e){let{identity:t,settings:n,flags:r}=e,i=r.model,a=r.name,o=r.plan||`lora`,s=w(n.output),c={model_name:i,name:a,plan:o,...(await La(o).resolve({client:e.client,dryRun:n.dryRun,binName:t.binName,flags:r,model:i,name:a})).body};if(n.dryRun){R({action:`deploy.create`,body:c},s);return}let l=await y(e.client,c),u=l.output??l.data;n.quiet?L(u?.deployed_model??``):s===`text`?(L(`Created deployment.`),u?.deployed_model&&L(` deployed_model: ${u.deployed_model}`),u?.status&&L(` status: ${u.status}`),u?.plan&&L(` plan: ${u.plan}`),L(`\nNext: track readiness with: ${t.binName} deploy get --deployed-model ${u?.deployed_model??`<id>`}`)):R(l,s)}}),za=x({description:`List model deployments`,auth:`apiKey`,usageArgs:`[--page <n>] [--page-size <n>] [--status <s>]`,flags:{page:{type:`number`,valueHint:`<n>`,description:`Page number (default: 1)`},pageSize:{type:`number`,valueHint:`<n>`,description:`Results per page (default: 10, max 100)`},status:{type:`string`,valueHint:`<s>`,description:`Filter by status (PENDING / RUNNING / STOPPED / FAILED)`}},exampleArgs:[``,`--status RUNNING`,`--page-size 20 --output json`],async run(e){let{settings:t,flags:n}=e,r=w(t.output),i=n.status||void 0;if(t.dryRun){R({action:`deploy.list`,page:n.page,page_size:n.pageSize,status:i},r);return}let a=await Se(e.client,{pageNo:n.page,pageSize:n.pageSize,status:i}),o=a.output??a.data,s=o?.deployments??[],c=o?.total,l=s.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??``}));if(r===`json`){R({items:l,total:c},r);return}if(l.length===0){L(`No deployments found.`);return}let u=[`DEPLOYED_MODEL`,`MODEL_NAME`,`STATUS`,`PLAN`,`CAPACITY`,`CREATED_AT`],d=l.map(e=>[e.deployed_model,e.model_name,e.status,e.plan,e.capacity,e.created_at]);for(let e of z(u,d))L(e);c!==void 0&&L(`\nTotal: ${c}`)}}),Ba=x({description:`Get details of a single model deployment`,auth:`apiKey`,usageArgs:`--deployed-model <id>`,flags:{deployedModel:{type:`string`,valueHint:`<id>`,description:`Deployed model identifier (required)`,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,i=w(t.output);if(t.dryRun){R({action:`deploy.get`,deployed_model:r},i);return}let a=await ce(e.client,r),o=a.output??a.data;if(!o){L(`No data returned for ${r}`);return}let s={deployed_model:o.deployed_model??r,deployed_name:o.name??``,model_name:o.model_name??``,base_model:o.base_model??``,status:o.status??``,plan:o.plan??``};if(o.model_unit_spec&&(s.model_unit_spec=o.model_unit_spec),o.charge_type&&(s.charge_type=o.charge_type),o.capacity!==void 0&&(s.capacity=o.capacity),o.base_capacity!==void 0&&(s.base_capacity=o.base_capacity),o.ready_capacity!==void 0&&(s.ready_capacity=o.ready_capacity),o.rpm_limit!==void 0&&(s.rpm_limit=o.rpm_limit),o.tpm_limit!==void 0&&(s.tpm_limit=o.tpm_limit),o.input_tpm!==void 0&&(s.input_tpm=o.input_tpm),o.output_tpm!==void 0&&(s.output_tpm=o.output_tpm),o.gmt_create&&(s.created_at=o.gmt_create),o.gmt_modified&&(s.updated_at=o.gmt_modified),i===`json`){R(s,i);return}let c=e=>`${e}:`.padEnd(18);for(let[e,t]of Object.entries(s)){if(t===``||t===void 0)continue;let n=typeof t==`string`?t:JSON.stringify(t);L(`${c(e)}${n}`)}}}),Va=x({description:`List models available for deployment`,auth:`apiKey`,usageArgs:`[--page <n>] [--page-size <n>] [--catalog-version <v>] [--source <custom|public>]`,flags:{page:{type:`number`,valueHint:`<n>`,description:`Page number (default: 1)`},pageSize:{type:`number`,valueHint:`<n>`,description:`Results per page (default: 100)`},catalogVersion:{type:`string`,valueHint:`<v>`,description:`Catalog version filter (default: v1.0; required for new catalog models)`},source:{type:`string`,valueHint:`<s>`,description:`Model source filter: custom (fine-tuned) | base (catalog) | 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=w(t.output),i=n.catalogVersion===``?void 0:n.catalogVersion??`v1.0`,a=n.source||void 0;if(t.dryRun){R({action:`deploy.models`,page:n.page,page_size:n.pageSize,version:i,model_source:a},r);return}let o=await xe(e.client,{pageNo:n.page,pageSize:n.pageSize,version:i,modelSource:a}),s=o.output??o.data,c=s?.models??[],l=s?.total;if(r===`json`){R({items:c.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:l},r);return}let u=c.map(e=>{let t=``;return t=e.supported_plans&&e.supported_plans.length>0?e.supported_plans.join(`,`):e.plans&&e.plans.length>0?e.plans.map(e=>{let t=e.plan??`?`;return e.templates&&e.templates.length>0?`${t}(${e.templates.length}t)`:e.cu_specs&&e.cu_specs.length>0?`${t}(${e.cu_specs.join(`/`)})`:t}).join(`,`):`-`,{model_name:e.model_name??``,base_model:e.base_model??``,source:e.model_source??``,plans:t}});if(u.length===0){L(`No deployable models found.`);return}let d=[`MODEL_NAME`,`BASE_MODEL`,`SOURCE`,`PLANS`],f=u.map(e=>[e.model_name,e.base_model,e.source,e.plans]);for(let e of z(d,f))L(e);l!==void 0&&L(`\nTotal: ${l}`)}}),Ha=x({description:`Scale a deployment's capacity`,auth:`apiKey`,usageArgs:`--deployed-model <id> --capacity <n> [--input-tpm <n>] [--output-tpm <n>]`,flags:{deployedModel:{type:`string`,valueHint:`<id>`,description:`Deployed model identifier (required)`,required:!0},capacity:{type:`number`,valueHint:`<n>`,description:`New capacity in plan units (must be a multiple of base_capacity)`},inputTpm:{type:`number`,valueHint:`<n>`,description:`PTU only — input tokens per minute`},outputTpm:{type:`number`,valueHint:`<n>`,description:`PTU only — output tokens per minute`}},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=w(t.output),a={};if(n.capacity!==void 0&&(a.capacity=n.capacity),n.inputTpm!==void 0&&(a.input_tpm=n.inputTpm),n.outputTpm!==void 0&&(a.output_tpm=n.outputTpm),t.dryRun){R({action:`deploy.scale`,deployed_model:r,body:a},i);return}let o=await Le(e.client,r,a),s=o.output??o.data;t.quiet?L(r):i===`text`?L(`Scaled ${r}${s?.capacity===void 0?``:` (capacity=${s.capacity})`}.`):R(o,i)}}),Ua=x({description:`Update a deployment's rate limits (rpm_limit / tpm_limit)`,auth:`apiKey`,usageArgs:`--deployed-model <id> [--rpm-limit <n>] [--tpm-limit <n>]`,flags:{deployedModel:{type:`string`,valueHint:`<id>`,description:`Deployed model identifier (required)`,required:!0},rpmLimit:{type:`number`,valueHint:`<n>`,description:`Requests per minute`},tpmLimit:{type:`number`,valueHint:`<n>`,description:`Tokens per minute`}},exampleArgs:[`--deployed-model dep-... --rpm-limit 1000`,`--deployed-model dep-... --rpm-limit 1000 --tpm-limit 200000`],notes:[`At least one of --rpm-limit / --tpm-limit must be provided.`],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=w(t.output),a={};if(n.rpmLimit!==void 0&&(a.rpm_limit=n.rpmLimit),n.tpmLimit!==void 0&&(a.tpm_limit=n.tpmLimit),t.dryRun){R({action:`deploy.update`,deployed_model:r,body:a},i);return}let o=await We(e.client,r,a),s=o.output??o.data;if(t.quiet)L(r);else if(i===`text`){let e=[];s?.rpm_limit!==void 0&&e.push(`rpm_limit=${s.rpm_limit}`),s?.tpm_limit!==void 0&&e.push(`tpm_limit=${s.tpm_limit}`),L(`Updated ${r}${e.length?` (${e.join(`, `)})`:``}.`)}else R(o,i)}}),Wa=x({description:`Delete a model deployment (must be STOPPED or FAILED)`,auth:`apiKey`,usageArgs:`--deployed-model <id> [--skip-precheck]`,flags:{deployedModel:{type:`string`,valueHint:`<id>`,description:`Deployed model identifier (required)`,required:!0},skipPrecheck:{type:`switch`,description:`Skip the local STOPPED/FAILED status precheck`}},exampleArgs:[`--deployed-model dep-...`,`--deployed-model dep-... --dry-run`],async run(e){let{settings:n,flags:r}=e,i=r.deployedModel,o=w(n.output);if(n.dryRun){R({action:`deploy.delete`,deployed_model:i},o);return}if(!r.skipPrecheck)try{let n=await ce(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. Stop it first via the platform console, or pass --skip-precheck to attempt deletion anyway.`,a.USAGE)}catch(e){if(e instanceof t)throw e}let s=await C(e.client,i);n.quiet?L(i):o===`text`?L(`Deleted ${i}.`):R(s,o)}});const Ga={callerUacAccountId:{type:`string`,valueHint:`<id>`,description:`Caller UAC account ID`},namespaceId:{type:`string`,valueHint:`<id>`,description:`Product namespace ID (Token Plan default: namespace-1)`}},Ka={workspaceId:{type:`string`,valueHint:`<id>`,description:`Workspace ID (env: BAILIAN_WORKSPACE_ID, config: workspace_id)`}},qa={cn:`modelstudio.cn-beijing.aliyuncs.com`,intl:`modelstudio.ap-southeast-1.aliyuncs.com`};function Ja(e){for(let[t,n]of Object.entries(s))if(e===n||e.startsWith(`${n}/`))return t;return`cn`}function Ya(e){return qa[Ja(e)]??qa.cn}function Xa(e,n,r){let i=n.workspaceId||e.workspaceId;if(!i)throw new t(`Missing workspace ID.
|
|
91
|
+
Set via: --workspace-id flag, env: BAILIAN_WORKSPACE_ID, or config: ${r} config set workspace_id <id>`,a.USAGE);return i}function Za(e,t){t.callerUacAccountId&&(e.CallerUacAccountId=t.callerUacAccountId),t.namespaceId&&(e.NamespaceId=t.namespaceId)}function $(e,t,n){let r=m(n),i=Ya(e);return{host:i,endpoint:`https://${i}${t}${r?`?${r}`:``}`,queryString:r,queryParams:n}}async function Qa(e){let{client:t,baseUrl:n,action:r,path:i,method:a,queryParams:o}=e,{host:s}=$(n,i,o);return t.openApiQueryJson({host:s,path:i,action:r,version:`2026-02-10`,method:a,queryParams:o})}const $a=`/tokenplan/subscription/seat-detail`;var eo=x({description:`List Token Plan subscription seat details`,auth:`openapi`,usageArgs:`[flags]`,flags:{pageNo:{type:`number`,valueHint:`<n>`,description:`Page number (default: 1)`},pageSize:{type:`number`,valueHint:`<n>`,description:`Page size (default: 10)`},...Ga,status:{type:`array`,valueHint:`<status>`,description:`Seat status filter (repeatable): CREATING, NORMAL, LIMIT, RELEASE, STOP, REFUNDED`},statusListStr:{type:`string`,valueHint:`<json>`,description:`StatusList as JSON string, e.g. '["NORMAL"]'`},seatId:{type:`string`,valueHint:`<id>`,description:`Filter by seat ID`},seatType:{type:`string`,valueHint:`<type>`,description:`Seat tier: standard, pro, or max`},queryAssigned:{type:`string`,valueHint:`<bool>`,description:`Filter by assignment: true=assigned, false=unassigned`}},exampleArgs:[``,`--page-size 20 --status NORMAL`,`--query-assigned true --seat-type standard`],async run(e){let{settings:t,flags:n}=e,r=w(t.output),i=to(n);if(t.dryRun){let{endpoint:t,queryParams:n}=$(e.client.baseUrl,$a,i);R({endpoint:t,query:n},r);return}let a=await Qa({client:e.client,baseUrl:e.client.baseUrl,action:`GetSubscriptionSeatDetails`,path:$a,method:`GET`,queryParams:i}),o=a.Data?.Items??[];t.quiet||r===`text`?no(o,a.Data?.Total,a.Data?.PageNo,a.Data?.PageSize):R(a,r)}});function to(e){let n={};if(e.pageNo!==void 0&&(n.PageNo=String(e.pageNo)),e.pageSize!==void 0&&(n.PageSize=String(e.pageSize)),Za(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'.`,a.USAGE);n.QueryAssigned=r}return n}function no(e,t,n,r){if(e.length===0){L(`No seats found.`);return}let i=[V(`SeatId`,18),V(`Type`,10),V(`Status`,10),V(`Assigned`,12),V(`Account`,20)].join(` `);L(i),L(`-`.repeat(i.length));for(let t of e)L([V(t.SeatId??`-`,18),V(t.SpecType??`-`,10),V(t.Status??`-`,10),V(t.AssignedStatus??`-`,12),V(t.AccountName??t.AccountId??`-`,20)].join(` `));t!==void 0&&(L(``),L(`Total: ${t}${n===void 0?``:` | Page: ${n}`}${r===void 0?``:` | PageSize: ${r}`}`))}const ro=`/tokenplan/api-keys`;var io=x({description:`Create a Token Plan API key for a seat`,auth:`openapi`,usageArgs:`--account-id <id> --workspace-id <id> [flags]`,flags:{accountId:{type:`string`,valueHint:`<id>`,description:`Target member account ID`,required:!0},...Ka,description:{type:`string`,valueHint:`<text>`,description:`API key description`},...Ga},exampleArgs:[`--account-id acc_123 --workspace-id ws_456`,`--account-id acc_123 --workspace-id ws_456 --description 'Dev key'`],async run(e){let{identity:t,settings:n,flags:r}=e,i=w(n.output),a=Xa(n,r,t.binName),o=ao(r,{accountId:r.accountId,workspaceId:a});if(n.dryRun){let{endpoint:t,queryParams:n}=$(e.client.baseUrl,ro,o);R({endpoint:t,query:n},i);return}let s=await Qa({client:e.client,baseUrl:e.client.baseUrl,action:`CreateTokenPlanKey`,path:ro,method:`POST`,queryParams:o});n.quiet||i===`text`?oo(s):R(s,i)}});function ao(e,t){let n={};return n.AccountId=t.accountId,n.WorkspaceId=t.workspaceId,e.description&&(n.Description=e.description),Za(n,e),n}function oo(e){let t=e.Data;if(!t){L(`API key created.`);return}L(`${V(`ApiKeyId`,14)} ${t.ApiKeyId??`-`}`),L(`${V(`MaskedApiKey`,14)} ${t.MaskedApiKey??`-`}`),t.Description&&L(`${V(`Description`,14)} ${t.Description}`),t.PlainApiKey&&(L(``),L(`PlainApiKey (shown once): ${t.PlainApiKey}`))}const so=`/tokenplan/subscription/seat-assignments`;var co=x({description:`Batch assign Token Plan seats to members`,auth:`openapi`,usageArgs:`--workspace-id <id> --seat-type <type> --account-id <id> [flags]`,flags:{...Ka,seatType:{type:`string`,valueHint:`<type>`,description:`Seat tier: standard, pro, or max`,required:!0},accountId:{type:`array`,valueHint:`<id>`,description:`Target member account ID (repeatable)`},...Ga,locale:{type:`string`,valueHint:`<locale>`,description:`Language: zh-CN or 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=w(n.output),a=lo(r,Xa(n,r,t.binName));if(n.dryRun){let{endpoint:t,queryParams:n}=$(e.client.baseUrl,so,a);R({endpoint:t,query:n},i);return}let o=await Qa({client:e.client,baseUrl:e.client.baseUrl,action:`BatchAssignSeats`,path:so,method:`POST`,queryParams:a});n.quiet||i===`text`?L(`Seats assigned successfully.`):R(o,i)}});function lo(e,t){let n={};return n.WorkspaceId=t,e.seatType&&(n.SeatType=e.seatType),Za(n,e),e.locale&&(n.Locale=e.locale),e.accountId&&e.accountId.length>0&&(n.AccountIds=e.accountId),n}const uo=`/tokenplan/organization/member-additions`;var fo=x({description:`Add a member to a Token Plan organization`,auth:`openapi`,usageArgs:`--account-name <name> --org-id <id> [flags]`,flags:{accountName:{type:`string`,valueHint:`<name>`,description:`Member display name`,required:!0},orgId:{type:`string`,valueHint:`<id>`,description:`Organization ID`,required:!0},orgRoleCode:{type:`string`,valueHint:`<code>`,description:`Organization role: ORG_ADMIN or ORG_MEMBER (default: ORG_MEMBER)`},specType:{type:`string`,valueHint:`<type>`,description:`Seat tier to assign on creation: standard, pro, or max`},...Ga},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=w(t.output),i=po(n);if(t.dryRun){let{endpoint:t,queryParams:n}=$(e.client.baseUrl,uo,i);R({endpoint:t,query:n},r);return}let a=await Qa({client:e.client,baseUrl:e.client.baseUrl,action:`AddOrganizationMember`,path:uo,method:`POST`,queryParams:i});t.quiet||r===`text`?mo(a):R(a,r)}});function po(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),Za(t,e),t}function mo(e){let t=e.Data;if(!t){L(`Member added.`);return}L(`${V(`AccountId`,14)} ${t.AccountId??`-`}`),L(`${V(`SeatAssigned`,14)} ${String(t.SeatAssigned??`-`)}`)}export{xi as advisorRecommend,zn as appCall,Vn as appList,Jt as authLogin,Xt as authLogout,Yt as authStatus,Pn as configSet,An as configShow,Tr as consoleCall,la as datasetDelete,ca as datasetGet,sa as datasetList,oa as datasetUpload,da as datasetValidate,Ra as deployCreate,Wa as deployDelete,Ba as deployGet,za as deployList,Va as deployModels,Ha as deployScale,Ua as deployUpdate,wr as fileUpload,va as finetuneCancel,Fa as finetuneCapability,wa as finetuneCheckpoints,ha as finetuneCreate,ya as finetuneDelete,Ta as finetuneExport,_a as finetuneGet,ga as finetuneList,Ca as finetuneLogs,ja as finetuneWatch,gn as imageEdit,un as imageGenerate,rr as knowledgeChat,Yn as knowledgeRetrieve,Zn as knowledgeSearch,ur as mcpCall,fr as mcpList,pr as mcpTools,Hn as memoryAdd,Kn as memoryDelete,Wn as memoryList,qn as memoryProfileCreate,Jn as memoryProfileGet,Un as memorySearch,Gn as memoryUpdate,ti as pipelineRun,oi as pipelineValidate,aa as quotaCheck,Ki as quotaHistory,Ni as quotaList,zi as quotaRequest,mr as searchWeb,Sr as speechRecognize,yr as speechSynthesize,$t as textChat,sn as textOmni,fo as tokenPlanAddMember,co as tokenPlanAssignSeats,io as tokenPlanCreateKey,eo as tokenPlanListSeats,Rn as update,Ir as usageFree,Br as usageFreetier,$r as usageStats,wn as videoDownload,xn as videoEdit,bn as videoGenerate,Sn as videoRef,Cn as videoTaskGet,kn as visionDescribe,Ti as workspaceList};
|