bailian-cli-commands 1.16.0 → 1.17.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 +2676 -669
- package/dist/index.mjs +274 -193
- package/package.json +4 -4
package/dist/index.mjs
CHANGED
|
@@ -1,35 +1,31 @@
|
|
|
1
|
-
import{ASYNC_FLAG as e,BailianError as t,CONCURRENT_FLAG as n,DEFAULT_INSTALL_PS1_URL as r,DEFAULT_INSTALL_SCRIPT_URL as i,
|
|
1
|
+
import{ASYNC_FLAG as e,BailianError as t,CONCURRENT_FLAG as n,DEFAULT_INSTALL_PS1_URL as r,DEFAULT_INSTALL_SCRIPT_URL as i,DEFAULT_LANGUAGE as a,DEFAULT_TRAINING_TYPE as o,DOCS_HOSTS as s,ExitCode as c,MAX_CPT_BYTES as l,MAX_DATASET_BYTES as u,MAX_MEDIA_ZIP_BYTES as d,MODEL_LIST_API as f,RAG_PATHS as p,REGIONS as m,SEMANTIC_TOP_K as h,STRATEGIES as g,SUPPORTED_LANGUAGES as _,TRAINING_TYPES_CLI as v,UsageError as y,analyzeIntent as b,anonymousConsoleCall as x,appCompletionPath as S,bailianMcpPath as C,buildAcsCanonicalQuery as ee,buildAsrFlashRequest as te,buildAsyncAsrLanguageFields as ne,buildDocLink as re,callConsoleGateway as ie,cancelFineTune as ae,chatPath as oe,collectAsrTranscriptionItems as se,computeSkillStatuses as ce,createBailianControlUser as le,createDeployment as ue,createFineTune as de,createInstrumentedFetch as fe,defaultDeployPlan as pe,defineCommand as w,deleteConfigProfile as me,deleteDataset as he,deleteDeployment as ge,deleteFineTune as _e,detectInstalledAgents as ve,detectModality as ye,detectOutputFormat as T,effectiveConsoleGatewayConfig as be,estimateCptTokens as xe,estimateSftDpoTokens as Se,exportCheckpoint as Ce,extractAsrFlashText as we,fanOutSkillToAgents as Te,fetchModelCapability as Ee,fetchModelDetail as De,fetchModelGroups as Oe,fetchModelListAll as ke,fetchPredictConfig as Ae,fetchSkillsIndex as je,fetchTrainingModelPrice as Me,findDeploymentEntry as Ne,findModelByName as Pe,formatIssue as Fe,generateCLIAccessToken as Ie,generateFilename as Le,getConfigDir as Re,getDataset as ze,getDeployment as Be,getFineTune as Ve,getFineTuneLogs as He,getModelProfilePreset as Ue,getModels as We,getProfile as Ge,getSkillRegistryBaseUrl as Ke,getUpdateInstallMethod as qe,image2videoPath as Je,imageFileToDataUri as Ye,installSkillWithFanout as Xe,isLocalFile as Ze,isStreamableHttpUnsupported as Qe,isTrainingTypeCli as $e,knowledgeChatEndpoint as et,knowledgeRetrievePath as tt,knowledgeSearchEndpoint as nt,listBailianControlWorkspaces as rt,listCheckpoints as it,listDatasets as at,listDeployableModels as ot,listDeployments as st,listFineTunes as ct,listIndependentDeployedModels as lt,listSkillDirsOnDisk as ut,listSupportedTrainingTypes as dt,mapApiError as ft,maskToken as pt,maybeSyncWikiData as mt,mcpWebSearchPath as ht,memoryAddPath as gt,memoryListPath as _t,memoryNodePath as vt,memorySearchPath as yt,modelSupportsTrainingType as bt,modelsLimitsPath as xt,modelsPermissionsPath as St,normalizeConfigName as Ct,normalizeModelBaseUrl as wt,parseDatasetSchemaFlag as Tt,parseSSE as Et,parseSkillNames as Dt,pickPlanStrategy as Ot,preflightBatchSizeGate as kt,profileSchemaPath as At,ragEndpoint as E,rankModels as jt,readConfigFile as Mt,readSkillLock as Nt,readTextFromPathOrStdin as Pt,recallSemantic as Ft,redactDataUri as D,removeSkillDir as It,requestJson as Lt,resetBailianControlPolicies4Agent as Rt,resolveAsrApi as zt,resolveBooleanFlag as Bt,resolveImageEditApi as Vt,resolveImageGenerateApi as Ht,resolveOutputDir as Ut,resolveWatermark as Wt,responsesPath as Gt,runWithConcurrency as Kt,scaleDeployment as qt,speechRecognizePath as Jt,speechSynthesizePath as Yt,startModelService as Xt,stopModelService as Zt,stripUndefined as Qt,taskPath as $t,trainingTypeMethodVariant as en,unlinkSkillFromAgents as tn,unwrapResponse as nn,updateDeployment as rn,uploadDataset as an,userProfilePath as on,validateDataset as sn,videoGeneratePath as cn,writeConfigFile as ln,writeSkillLock as un}from"bailian-cli-core";import{API_KEY_PAGE as dn,BOOL_FLAG_PROMPT_EXTEND_API_DEFAULT as fn,BOOL_FLAG_PROMPT_EXTEND_CLI_TRUE as pn,BOOL_FLAG_PROMPT_EXTEND_IMAGE_GENERATE as mn,BOOL_FLAG_WATERMARK as hn,VOICE_TTS_PAGE as gn,ansi as O,collectPipelineHints as _n,collectPipelineIssues as vn,confirmDangerousAction as yn,createSpinner as bn,displayWidth as xn,downloadFile as Sn,downloadParallel as Cn,emitBare as k,emitResult as A,executePipeline as wn,fetchBinaryChannelVersion as Tn,fetchLatestVersion as En,formatBytes as Dn,formatTable as j,getConcurrency as On,initPipelineSteps as kn,isValidUpdateTargetVersion as An,mcpMarketplaceDetailPage as jn,normalizeBinaryVersion as Mn,padEnd as M,performBinaryUpdate as Nn,poll as Pn,renderBoxTable as Fn,renderGauge as In,resolveImageSize as Ln,runConcurrent as Rn,streamPipelineEvents as zn,supportsColor as Bn}from"bailian-cli-runtime";import{createHash as Vn,randomBytes as Hn,timingSafeEqual as Un}from"node:crypto";import Wn from"node:http";import{execFile as Gn}from"node:child_process";import{copyFileSync as Kn,createWriteStream as qn,existsSync as Jn,mkdirSync as Yn,readFileSync as Xn,renameSync as Zn,statSync as Qn,writeFileSync as $n}from"fs";import{basename as er,dirname as tr,extname as nr,join as N}from"path";import{createReadStream as rr,existsSync as P,mkdirSync as ir,readFileSync as ar,readdirSync as or,statSync as sr,unlinkSync as cr,writeFileSync as lr}from"node:fs";import{basename as F,dirname as ur,extname as dr,join as I,relative as fr,resolve as pr,sep as mr}from"node:path";import{homedir as hr}from"node:os";import{inflateRawSync as gr}from"node:zlib";import _r from"yaml";import{parse as vr,stringify as yr}from"smol-toml";import{homedir as br,platform as xr}from"os";import{execSync as Sr}from"child_process";import{readFile as Cr,writeFile as wr}from"node:fs/promises";import Tr from"boxen";import Er,{Chalk as Dr}from"chalk";import*as Or from"@openagentpack/sdk";import{AGENTS_PROVIDER_FIELDS as kr,LocalFileStateBackend as Ar,StateManager as jr,UserError as Mr,bootstrapRuntimeCredentialsSync as Nr,createProjectRuntime as Pr,createSessionForAgent as Fr,deleteSession as Ir,destroyPlannedProjectResources as Lr,executePlannedProject as Rr,getSession as zr,importResource as Br,isTerminalSessionStatus as Vr,listSessionEvents as Hr,listSessionSummaries as Ur,listSkills as Wr,parseStateAddress as Gr,planDestroyProjectContext as Kr,planProjectContext as qr,resolveProjectConfig as Jr,sendSessionMessagePolling as Yr,sendSessionMessageStreaming as Xr,startSessionRun as Zr,startSessionRunPolling as Qr,validateProjectConfig as $r}from"@openagentpack/sdk";import{sanitizeSessionEvents as ei}from"@openagentpack/sdk/session-events";function ti(e){if(e instanceof t){if(e.exitCode===c.NETWORK||e.exitCode===c.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 ni(e,t,n){process.stderr.write(`Testing key... `);let r={identity:e.identity,settings:e.settings},i=wt(n.baseUrl),a=n.persistBaseUrl?wt(n.persistBaseUrl):void 0,o={url:i+oe(),method:`POST`,headers:{Authorization:`Bearer ${t}`},timeout:Math.min(e.settings.timeout,30),body:{model:`qwen3.8-max`,messages:[{role:`user`,content:`hi`}],max_tokens:1,stream:!1}};for(let e=1;e<=3;e++)try{await Lt(r,o);break}catch(t){if(e>=3||!ti(t))throw process.stderr.write(`Failed
|
|
2
2
|
`),t;let n=500*2**(e-1);await new Promise(e=>setTimeout(e,n))}process.stderr.write(`Valid
|
|
3
|
-
`),await e.authStore.login({...n.persistPatch,api_key:t,base_url:a,default_text_model:n.defaultTextModel,default_video_model:n.defaultVideoModel,default_image_to_video_model:n.defaultImageToVideoModel,default_reference_to_video_model:n.defaultReferenceToVideoModel,default_image_model:n.defaultImageModel})}function
|
|
3
|
+
`),await e.authStore.login({...n.persistPatch,api_key:t,base_url:a,default_text_model:n.defaultTextModel,default_video_model:n.defaultVideoModel,default_image_to_video_model:n.defaultImageToVideoModel,default_reference_to_video_model:n.defaultReferenceToVideoModel,default_image_model:n.defaultImageModel})}function ri(e,t=0){return new Promise((n,r)=>{let i=e=>r(e);e.once(`error`,i),e.listen({port:t,host:`127.0.0.1`,exclusive:!0},()=>{e.off(`error`,i);let t=e.address();if(!t||typeof t==`string`){r(Error(`Expected TCP socket address`));return}n(t.port)})})}function ii(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)=>{Gn(n,r,{windowsHide:!0},n=>{n?t(n):e()})})}function ai(e){return ii(e)}const oi=RegExp(`\r
|
|
4
4
|
\r
|
|
5
5
|
|
|
|
6
6
|
|
|
7
|
-
`),
|
|
8
|
-
`);return}let{accessToken:r,apiKey:s,baseUrl:c,consoleSite:l,consoleRegion:u,consoleSwitchAgent:d,workspaceId:f}=await
|
|
7
|
+
`),si={domestic:`https://bailian.console.aliyun.com`,international:`https://modelstudio.console.alibabacloud.com`};function ci(e){return e&&si[e]||si.domestic}function li(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 ui(e){let t=e.headers[`content-type`];return Array.isArray(t)?t[0]??``:typeof t==`string`?t:``}function di(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 fi(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(oi);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 pi(e){for(let t of[`access_token`,`accessToken`]){let n=e[t];if(typeof n==`string`&&n.trim())return n.trim()}return null}function mi(e){for(let t of[`api_key`,`apiKey`]){let n=e[t];if(typeof n==`string`&&n.trim())return n.trim()}return null}function hi(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=pi(r);if(i)return i;let a=r.data;if(a&&typeof a==`object`&&!Array.isArray(a)){let e=pi(a);if(e)return e}return null}function gi(e,t){let n=t.toLowerCase();if(!e.trim())return null;if(n.includes(`multipart/form-data`)){let n=di(t);if(n){let t=fi(e,n);if(t)return t}}if(n.includes(`application/json`)||n.includes(`text/json`)){let t=hi(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=hi(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=di(t);if(i){let t=fi(e,i);if(t)return t}return null}function _i(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=mi(r);if(i)return i;let a=r.data;if(a&&typeof a==`object`&&!Array.isArray(a)){let e=mi(a);if(e)return e}return null}function vi(e,t){let n=t.toLowerCase();if(!e.trim())return null;if(n.includes(`application/json`)||n.includes(`text/json`)){let t=_i(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=_i(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 yi(e,...t){for(let n of t){let t=e[n];if(typeof t==`string`&&t.trim())return t.trim()}return null}function bi(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:yi(r,`base_url`,`baseUrl`),consoleSite:yi(r,`console_site`,`consoleSite`),consoleRegion:yi(r,`console_region`,`consoleRegion`),consoleSwitchAgent:yi(r,`console_switch_agent`,`consoleSwitchAgent`),workspaceId:yi(r,`workspace_id`,`workspaceId`)}:n}async function xi(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=ui(e),f;try{f=await li(e)}catch{return{accessToken:n?.trim()||null,apiKey:r?.trim()||null,...l}}let p=n?.trim()||gi(f,d),m=r?.trim()||vi(f,d),h=bi(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 Si(e){return ri(e)}async function Ci(e,n,r){let i=Hn(16).toString(`hex`),a,o=Wn.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
|
|
8
|
+
`);return}let{accessToken:r,apiKey:s,baseUrl:c,consoleSite:l,consoleRegion:u,consoleSwitchAgent:d,workspaceId:f}=await xi(e),p=r||c||l||u||d||f;if(p||s)try{let e={access_token:r||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};s?(await ni(n,s,{baseUrl:c||n.authStore.resolveBaseUrl(),persistBaseUrl:c||void 0,persistPatch:e}),process.stderr.write(`Config saved to ${n.authStore.path}\n`)):p&&(await n.authStore.login({...e,base_url:c||void 0}),process.stderr.write(`Config saved to ${n.authStore.path}\n`))}catch(e){a=e,t.writeHead(500,{"Content-Type":`text/plain; charset=utf-8`}),t.end(`Failed to save credentials
|
|
9
9
|
`),o.close();return}t.writeHead(200,{"Content-Type":`text/plain; charset=utf-8`,"Access-Control-Allow-Origin":`*`}),t.end(`OK
|
|
10
|
-
`),(p||s)&&o.close()}catch{t.statusCode=500,t.end()}}),
|
|
10
|
+
`),(p||s)&&o.close()}catch{t.statusCode=500,t.end()}}),s;try{s=await Si(o)}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)}`,c.USAGE)}let l=`${e}/console-login?notice=127.0.0.1:${s}?state=${encodeURIComponent(i)}`;r?.needApiKey&&(l+=`&needapikey=true`);try{await ai(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).
|
|
11
11
|
`)}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(`
|
|
12
12
|
This process keeps the local port open for the console; press Ctrl+C when finished (or wait for idle timeout).
|
|
13
|
-
`)}if(await new Promise((e,t)=>{let n=!1,r=()=>{n||(n=!0,clearTimeout(i),e())},i=setTimeout(()=>{o.close()},9e5);o.once(`close`,r),o.once(`error`,e=>{clearTimeout(i),n||(n=!0,t(e))})}),a)throw a}function
|
|
14
|
-
`)},r);return}if(r!==`text`){A({authenticated:!0,config:l,config_file:u,api_key:a,console:o,openapi:s},r);return}k(`Config: ${l}`),k(`Config file: ${u}`),k(`Authentication Status:`),k(a?` API key (model): ${a.source} ${a.masked}`:` API key (model): not configured`),k(o?` Console gateway: ${o.source} ${o.masked} (${o.region}, ${o.site})`:` Console gateway: not configured (run ${t.binName} auth login --console)`),k(s?` OpenAPI (AK/SK): ${s.source} ${s.access_key_id}`:` OpenAPI (AK/SK): not configured (run ${t.binName} auth login --open-api)`)}}),
|
|
13
|
+
`)}if(await new Promise((e,t)=>{let n=!1,r=()=>{n||(n=!0,clearTimeout(i),e())},i=setTimeout(()=>{o.close()},9e5);o.once(`close`,r),o.once(`error`,e=>{clearTimeout(i),n||(n=!0,t(e))})}),a)throw a}function wi(e){return typeof e==`string`&&e.trim().length>0}var Ti=w({description:{"en-US":`Authenticate with API key, console browser login, or OpenAPI AK/SK (credentials can coexist)`,"zh-CN":`使用 API Key、控制台浏览器登录或 OpenAPI AK/SK 进行认证(多种凭证可共存)`},auth:`none`,usageArgs:`--api-key <key> | --console | --open-api --access-key-id <id> --access-key-secret <secret>`,flags:{apiKey:{type:`string`,valueHint:`<key>`,description:{"en-US":`Model API key to store`,"zh-CN":`要保存的模型 API Key`}},baseUrl:{type:`string`,valueHint:`<url>`,description:{"en-US":`Model API base URL (used with --api-key for validation)`,"zh-CN":`模型 API Base URL(用于配合 --api-key 进行验证)`}},console:{type:`switch`,description:{"en-US":`Sign in via browser; use --console-site to choose domestic (default) or international`,"zh-CN":`通过浏览器登录;使用 --console-site 选择国内站(默认)或国际站`}},consoleSite:{type:`string`,valueHint:`<site>`,description:{"en-US":`Console site: domestic, international`,"zh-CN":`控制台站点:domestic、international`}},openApi:{type:`switch`,description:{"en-US":`Store Alibaba Cloud OpenAPI AK/SK credentials`,"zh-CN":`保存阿里云 OpenAPI AK/SK 凭证`}},accessKeyId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Alibaba Cloud Access Key ID to store`,"zh-CN":`要保存的阿里云 Access Key ID`}},accessKeySecret:{type:`string`,valueHint:`<secret>`,description:{"en-US":`Alibaba Cloud Access Key Secret to store`,"zh-CN":`要保存的阿里云 Access Key Secret`}}},exampleArgs:[`--api-key sk-xxxxx`,`--config token-plan --api-key sk-sp-xxxxx`,`--console`,`--open-api --access-key-id LTAIxxxxx --access-key-secret xxxxx`],validate:e=>{let t=wi(e.apiKey),n=e.console===!0,r=e.openApi===!0;if(!t&&wi(e.baseUrl))return`Use --base-url only with --api-key`;if(!n&&wi(e.consoleSite))return`Use --console-site only with --console`;if(!r&&(wi(e.accessKeyId)||wi(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&&(!wi(e.accessKeyId)||!wi(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?wt(r.baseUrl):void 0;if(r.console){if(n.dryRun){k(`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 Ci(ci(r.consoleSite||n.consoleSite||`domestic`),a,{needApiKey:!e});return}if(r.openApi){if(n.dryRun){k(`Would save OpenAPI AK/SK credentials and generate CLI access token.`);return}let e=i.resolveBaseUrl();process.stderr.write(`Generating CLI access token... `);let a=(await Ie({identity:t,settings:n,baseUrl:e,accessKeyId:r.accessKeyId,accessKeySecret:r.accessKeySecret})).cliAccessToken;await i.login({access_key_id:r.accessKeyId,access_key_secret:r.accessKeySecret,access_token:a}),process.stderr.write(`OpenAPI credentials saved to ${i.path}\n`);return}if(!o)return;if(n.dryRun){k(`Would validate and save API key.`);return}let c=Ue(n.configName),l=i.stored().baseUrl;await ni(a,o,{baseUrl:s||i.resolveBaseUrl(c?.baseUrl),persistBaseUrl:s||(l?void 0:c?.baseUrl),defaultTextModel:c?.defaultTextModel,defaultVideoModel:c?.defaultVideoModel,defaultImageToVideoModel:c?.defaultImageToVideoModel,defaultReferenceToVideoModel:c?.defaultReferenceToVideoModel,defaultImageModel:c?.defaultImageModel})}}),Ei=w({description:{"en-US":`Show current authentication state`,"zh-CN":`显示当前认证状态`},auth:`none`,exampleArgs:[``,`--output json`],async run(e){let{identity:t,settings:n}=e,r=T(n.output),i=e.authStore.describe(),a=i.apiKey?{source:i.apiKey.source,masked:pt(i.apiKey.token),base_url:i.apiKey.baseUrl}:void 0,o=i.console?{source:i.console.source,masked:pt(i.console.token),region:i.console.region,site:i.console.site}:void 0,s=i.openapi?{source:i.openapi.source,access_key_id:pt(i.openapi.accessKeyId),access_key_secret:pt(i.openapi.accessKeySecret)}:void 0,c=!!(a||o||s),l=n.configName??`default`,u=e.authStore.path;if(!c){A({authenticated:!1,config:l,config_file:u,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: ${dn}`].join(`
|
|
14
|
+
`)},r);return}if(r!==`text`){A({authenticated:!0,config:l,config_file:u,api_key:a,console:o,openapi:s},r);return}k(`Config: ${l}`),k(`Config file: ${u}`),k(`Authentication Status:`),k(a?` API key (model): ${a.source} ${a.masked}`:` API key (model): not configured`),k(o?` Console gateway: ${o.source} ${o.masked} (${o.region}, ${o.site})`:` Console gateway: not configured (run ${t.binName} auth login --console)`),k(s?` OpenAPI (AK/SK): ${s.source} ${s.access_key_id}`:` OpenAPI (AK/SK): not configured (run ${t.binName} auth login --open-api)`)}}),Di=w({description:{"en-US":`Clear stored credentials; full logout also clears the model Base URL`,"zh-CN":`清除已保存的凭证;完整退出还会清除模型 Base URL`},auth:`none`,usageArgs:`[--console | --open-api] [--dry-run]`,flags:{console:{type:`switch`,description:{"en-US":`Only clear the console access_token, keep api_key intact`,"zh-CN":`仅清除控制台 access_token,保留 api_key`}},openApi:{type:`switch`,description:{"en-US":`Only clear OpenAPI AK/SK/STS credentials, keep other credentials intact`,"zh-CN":`仅清除 OpenAPI AK/SK/STS 凭证,保留其他凭证`}}},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?k(`Would clear access_token from ${r.path}`):k(`No console access_token to clear.`),k(`No changes made.`);return}await r.logout(`console`)?(process.stderr.write(`Cleared access_token from ${r.path}\n`),i.apiKey&&process.stderr.write(`api_key is still configured and will be used for authentication.
|
|
15
15
|
`)):process.stderr.write(`No console access_token to clear.
|
|
16
16
|
`);return}if(n.openApi){if(t.dryRun){i.openapi?k(`Would clear access_key_id / access_key_secret / security_token from ${r.path}`):k(`No OpenAPI AK/SK credentials to clear.`),k(`No changes made.`);return}await r.logout(`openapi`)?(process.stderr.write(`Cleared access_key_id / access_key_secret / security_token from ${r.path}\n`),(i.apiKey||i.console)&&process.stderr.write(`Other credentials are still configured and will be used for authentication.
|
|
17
17
|
`)):process.stderr.write(`No OpenAPI AK/SK credentials to clear.
|
|
18
18
|
`);return}let a=i.apiKey||i.console||i.openapi||!!i.baseUrl;if(t.dryRun){k(a?`Would clear api_key / base_url / access_token / access_key_id / access_key_secret / security_token from ${r.path}`:`No credentials or model Base URL to clear.`),k(`No changes made.`);return}await r.logout(`all`)?process.stderr.write(`Cleared api_key / base_url / access_token / access_key_id / access_key_secret / security_token from ${r.path}\n`):process.stderr.write(`No credentials or model Base URL to clear.
|
|
19
|
-
`)}}),
|
|
20
|
-
`))),o&&l.write(t.reasoning_content)),t.content&&(o&&r&&(l.write(`${f.reset}\n\nResponse:\n`),r=!1),n+=t.content,o&&d.write(t.content))}}catch{}}a===`responses`&&
|
|
21
|
-
`)}else if(a===`responses`){let n=await e.client.requestJson({path:
|
|
19
|
+
`)}}),Oi=w({description:{"en-US":`Generate a CLI access token using OpenAPI AK/SK`,"zh-CN":`使用 OpenAPI AK/SK 生成 CLI Access Token`},auth:`none`,usageArgs:`--access-key-id <id> --access-key-secret <secret> --security-token <token>`,flags:{accessKeyId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Alibaba Cloud Access Key ID`,"zh-CN":`阿里云 Access Key ID`},required:!0},accessKeySecret:{type:`string`,valueHint:`<secret>`,description:{"en-US":`Alibaba Cloud Access Key Secret`,"zh-CN":`阿里云 Access Key Secret`},required:!0},securityToken:{type:`string`,valueHint:`<token>`,description:{"en-US":`Alibaba Cloud STS Security Token to store (optional)`,"zh-CN":`要保存的阿里云 STS Security Token(可选)`}}},exampleArgs:[`--access-key-id LTAIxxxxx --access-key-secret xxxxx --security-token <token>`],async run(e){let{identity:t,settings:n,flags:r}=e,i=T(n.output);A(await Ie({identity:t,settings:n,baseUrl:e.client.baseUrl,accessKeyId:r.accessKeyId,accessKeySecret:r.accessKeySecret,securityToken:r.securityToken||void 0}),i)}});function ki(e){return e.output.filter(e=>e.type===`message`).flatMap(e=>e.content??[]).filter(e=>e.type===`output_text`).map(e=>e.text??``).join(``)}function Ai(e){return e.type===`response.output_text.delta`?e.delta??``:``}function ji(e){return typeof e==`object`&&e?e:void 0}function Mi(e,t){let n=e?.[t];return typeof n==`string`&&n.trim()?n:void 0}function Ni(e){let t=ji(ji(e.response)?.error),n=ji(e.error);return Mi(t,`message`)??Mi(n,`message`)??Mi(e,`message`)}function Pi(e){if(e.type===`response.failed`||e.type===`error`)throw new t(Ni(e)??`Response failed.`,c.GENERAL);if(e.type===`response.incomplete`){let n=Mi(ji(ji(e.response)?.incomplete_details),`reason`);throw new t(Ni(e)??(n?`Response incomplete: ${n}`:`Response incomplete.`),c.GENERAL)}return{delta:Ai(e),completed:e.type===`response.completed`}}function Fi(e){if(!e)throw new t(`Stream disconnected before completion: stream closed before response.completed.`,c.GENERAL)}const Ii={api:{type:`string`,valueHint:`<chat|responses>`,choices:[`chat`,`responses`],description:{"en-US":`API to call (default: chat)`,"zh-CN":`调用的 API(默认:chat)`}},model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Model ID (default: qwen3.8-max)`,"zh-CN":`模型 ID(默认:qwen3.8-max)`}},message:{type:`array`,valueHint:`<text>`,description:{"en-US":`Message text (repeatable, prefix role: to set role); or use --messages-file`,"zh-CN":`消息文本(可重复;可使用 role: 前缀指定角色),也可使用 --messages-file`}},messagesFile:{type:`string`,valueHint:`<path>`,description:{"en-US":`JSON file with messages array (use - for stdin)`,"zh-CN":`包含 messages 数组的 JSON 文件(使用 - 从 stdin 读取)`}},system:{type:`string`,valueHint:`<text>`,description:{"en-US":`System prompt`,"zh-CN":`系统提示词`}},maxTokens:{type:`number`,valueHint:`<n>`,description:{"en-US":`Maximum tokens to generate (default: 4096)`,"zh-CN":`最大生成 Token 数(默认:4096)`}},temperature:{type:`number`,valueHint:`<n>`,description:{"en-US":`Sampling temperature (0.0, 2.0]`,"zh-CN":`采样温度 (0.0, 2.0]`}},topP:{type:`number`,valueHint:`<n>`,description:{"en-US":`Nucleus sampling threshold`,"zh-CN":`核采样阈值`}},stream:{type:`switch`,description:{"en-US":`Stream response tokens (default: on in TTY)`,"zh-CN":`流式输出响应 Token(TTY 中默认开启)`}},tool:{type:`array`,valueHint:`<json-or-path>`,description:{"en-US":`Tool definition as JSON or file path (repeatable)`,"zh-CN":`JSON 格式的工具定义或文件路径(可重复)`}},enableThinking:{type:`switch`,description:{"en-US":`Enable thinking/reasoning mode (for qwen3/qwq models)`,"zh-CN":`启用思考/推理模式(适用于 qwen3/qwq 模型)`}},thinkingBudget:{type:`number`,valueHint:`<n>`,description:{"en-US":`Max tokens for thinking (default: 4096)`,"zh-CN":`思考过程最大 Token 数(默认:4096)`}}};function Li(e){let t=[],n;if(e.system&&(n=e.system),e.messagesFile){let r=Pt(e.messagesFile),i=JSON.parse(r);for(let e of i)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 Ri=w({description:{"en-US":`Send a text model request (OpenAI compatible, DashScope)`,"zh-CN":`发送文本模型请求(OpenAI 兼容,DashScope)`},auth:`apiKey`,usageArgs:`--message <text> [flags]`,flags:Ii,exampleArgs:[{"en-US":`--message "What is Qwen?"`,"zh-CN":`--message "通义千问是什么?"`},{"en-US":`--api responses --model qwen3.8-max --tool '{"type":"web_search"}' --message "Search for recent Alibaba Cloud news"`,"zh-CN":`--api responses --model qwen3.8-max --tool '{"type":"web_search"}' --message "搜索近期的阿里云新闻"`},{"en-US":`--model qwen-max --system "You are a coding assistant." --message "Write fizzbuzz in Python"`,"zh-CN":`--model qwen-max --system "你是一名编程助手。" --message "用 Python 编写 FizzBuzz"`},{"en-US":`--message "Hello" --message "assistant:Hi!" --message "How are you?"`,"zh-CN":`--message "你好" --message "assistant:你好!" --message "你好吗?"`},`--messages-file - --stream`,{"en-US":`--message "Hello" --output json`,"zh-CN":`--message "你好" --output json`},{"en-US":`--model qwq-plus --message "Solve 1+1" --enable-thinking`,"zh-CN":`--model qwq-plus --message "计算 1+1" --enable-thinking`}],validate:e=>{if(!e.message&&!e.messagesFile)return`Provide --message or --messages-file.`;if(e.api===`responses`&&e.thinkingBudget!==void 0)return`--thinking-budget is not supported by the Responses API.`},async run(e){let{settings:t,flags:n}=e,{system:r,messages:i}=Li(n),a=n.api??`chat`,o=n.model||t.defaultTextModel||`qwen3.8-max`,s=n.stream||process.stdout.isTTY,c=T(t.output),l=[];r&&l.push({role:`system`,content:r}),l.push(...i);let u;if(u=a===`responses`?{model:o,input:l,max_output_tokens:n.maxTokens??4096,stream:s}:{model:o,messages:l,max_tokens:n.maxTokens??4096,stream:s},n.temperature!==void 0&&(u.temperature=n.temperature),n.topP!==void 0&&(u.top_p=n.topP),n.enableThinking&&(u.enable_thinking=!0,a===`chat`&&`messages`in u&&n.thinkingBudget!==void 0&&(u.thinking_budget=n.thinkingBudget)),n.tool){let e=n.tool.map(e=>{try{return JSON.parse(e)}catch{let t=Xn(e,`utf-8`);return JSON.parse(t)}});u.tools=e}if(t.dryRun){A({request:u},c);return}if(s){let t=await e.client.request({path:a===`responses`?Gt():oe(),method:`POST`,body:u,stream:!0}),n=``,r=!1,i=!1,o=c===`text`,s=process.stdout.isTTY,l=c===`json`?process.stderr:s?process.stdout:process.stderr,d=process.stdout,f=O(l);for await(let e of Et(t)){if(e.data===`[DONE]`)break;if(a===`responses`){let t;try{t=JSON.parse(e.data)}catch{continue}let r=Pi(t);if(r.delta&&(n+=r.delta,o&&d.write(r.delta)),r.completed){i=!0;break}continue}try{let t=JSON.parse(e.data);for(let e of t.choices){let t=e.delta;t.reasoning_content&&(o&&!r&&(r=!0,l.write(f.dim(`Thinking:
|
|
20
|
+
`))),o&&l.write(t.reasoning_content)),t.content&&(o&&r&&(l.write(`${f.reset}\n\nResponse:\n`),r=!1),n+=t.content,o&&d.write(t.content))}}catch{}}a===`responses`&&Fi(i),r&&l.write(f.reset),c===`json`?A({content:n},c):d.write(`
|
|
21
|
+
`)}else if(a===`responses`){let n=await e.client.requestJson({path:Gt(),method:`POST`,body:u}),r=ki(n);t.quiet||c===`text`?k(r):A(n,c)}else{let n=await e.client.requestJson({path:oe(),method:`POST`,body:u}),r=n.choices?.[0]?.message?.content??``;t.quiet||c===`text`?k(r):A(n,c)}}});const zi=[{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 Bi(){let e=(e,t)=>e.padEnd(t);process.stdout.write(`
|
|
22
22
|
Omni output voices:
|
|
23
|
-
`),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
|
|
24
|
-
`);let C;if(b&&!s){let e=Buffer.from(b,`base64`),r=
|
|
25
|
-
`));else{let t={urls:e,saved:l,total:e.length};i&&(t.task_id=i),a&&a.length>1&&(t.task_ids=a),A(t,r)}}var
|
|
26
|
-
`)):A({urls:e,saved:o,total:e.length},r)}var
|
|
27
|
-
`)),r.async){A(m.length===1?{task_id:m[0]}:{task_ids:m},
|
|
28
|
-
`)),r.async){A(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=>Mn(e.client,n,{url:e.client.url(Zt(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.`,s.GENERAL);if(r.download){let e=r.download,{size:t}=await bn(b[0].videoUrl,e,{quiet:n.quiet});n.quiet?k(e):A({task_id:b[0].taskId,video_url:b[0].videoUrl,status:`SUCCEEDED`,saved:e,size:Tn(t)},d);return}let{join:x}=await import(`path`),S=Vt(n,{subDir:`videos`}),C=[];await Promise.all(b.map(async({taskId:e,videoUrl:t})=>{let r=x(S,`${e}.mp4`);await bn(t,r,{quiet:n.quiet}),C.push({task_id:e,video_url:t,saved:r})})),C.length===1?A(C[0],d):A({videos:C,total:C.length},d)}}),ta=w({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=T(t.output);if(t.dryRun){A({task_id:r},i);return}let a=await e.client.requestJson({path:Zt(r)});if(t.quiet){k(a.output.task_status);return}A({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)}}),na=w({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,a=r.out,o=T(n.output);if(n.dryRun){A({task_id:i,action:`download`,out:a},o);return}let c=await e.client.requestJson({path:Zt(i)});if(c.output.task_status!==`SUCCEEDED`)throw new t(`Task is not complete (status: ${c.output.task_status}).`,s.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.`,s.GENERAL);let{size:u}=await bn(l,a,{quiet:n.quiet});if(n.quiet){k(a);return}A({saved:a,size:Tn(u)},o)}});const ra=new Set([`.mp4`,`.mov`,`.avi`,`.mkv`,`.webm`,`.flv`,`.wmv`]);function ia(e){let t=er(e).toLowerCase().split(`?`)[0];return!!(ra.has(t)||/\.(mp4|mov|avi|mkv|webm|flv|wmv)(\?|$)/i.test(e))}async function aa(e){return e.startsWith(`data:`)||e.startsWith(`http://`)||e.startsWith(`https://`)||e.startsWith(`oss://`)?e:qe(e)}var oa=w({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,a=r.video??[],o=r.model||(e.client.usesTokenPlanEndpoint()?n.defaultTextModel:void 0)||`qwen3-vl-plus`;i&&ia(i)&&(a.push(i),i=void 0);let c=a.length>0?`Describe the video.`:`Describe the image.`,l=r.prompt||c,u=T(n.output);if(n.dryRun){A({request:{prompt:l,image:i?D(i):void 0,video:a.length?a.map(D):void 0,model:o}},u);return}let d=[];if(a.length>0)for(let n of a){let r=n;if(Ye(n)){if(!Kn(n))throw new t(`Video file not found: ${n}`,s.USAGE);r=await e.client.uploadFile(n,o)}d.push({type:`video_url`,video_url:{url:r}})}if(i){let t=await aa(i),n=t;Ye(i)&&t.startsWith(`data:`)&&Xn(i).size>5*1024*1024&&(n=await e.client.resolveImageInput(i,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 e.client.requestJson({path:ie(),method:`POST`,body:f}),m=p.choices?.[0]?.message?.content;if(u!==`text`){A(p,u);return}k(m||``)}});const sa=[`base_url`,`output`,`output_dir`,`timeout`,`api_key`,`access_token`,`access_key_id`,`access_key_secret`,`security_token`,`default_text_model`,`default_video_model`,`default_image_to_video_model`,`default_reference_to_video_model`,`default_image_model`,`default_speech_model`,`default_omni_model`,`workspace_id`],ca=new Set([`api_key`,`access_token`,`access_key_id`,`access_key_secret`,`security_token`]),la=[`console_site`,`console_region`,`console_switch_agent`,`telemetry`],ua=[...sa,...la],da={output:[`text`,`json`],console_site:[`domestic`,`international`]},fa=new Set([`telemetry`]),pa={default_text_model:`qwen3.8-max`,default_image_model:`qwen-image-3.0`,default_video_model:`happyhorse-1.1-t2v`,default_speech_model:`cosyvoice-v3-flash`,default_omni_model:`qwen3.5-omni-plus`},ma={default_text_model:[{id:`qwen3.8-max`,role:`text/chat default`},{id:`qwen3-coder-plus`,role:`coding-oriented (agent config)`},{id:`qwen-flash`,role:`fast · advisor ranking`},{id:`qwen3.6-flash`,role:`fast · advisor intent`}],default_image_model:[{id:`qwen-image-3.0`,role:`image/generate default · sync`},{id:`qwen-image-2.0`,role:`image/generate · sync`},{id:`qwen-image-max`,role:`image/generate · sync`},{id:`qwen-image-edit-2.0`,role:`image/edit · sync`},{id:`wanx2.x`,role:`image/generate · async series`}],default_video_model:[{id:`happyhorse-1.1-t2v`,role:`video/generate default · text-to-video`},{id:`happyhorse-1.1-i2v`,role:`video/generate · image-to-video`}],default_speech_model:[{id:`cosyvoice-v3-flash`,role:`speech/synthesize (TTS) default`},{id:`fun-asr`,role:`speech/recognize (ASR)`}],default_omni_model:[{id:`qwen3.5-omni-plus`,role:`omni/chat default`},{id:`qwen3-vl-plus`,role:`vision/describe · multimodal input`}]},ha={"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`,"security-token":`security_token`,"default-text-model":`default_text_model`,"default-video-model":`default_video_model`,"default-image-to-video-model":`default_image_to_video_model`,"default-reference-to-video-model":`default_reference_to_video_model`,"default-image-model":`default_image_model`,"default-speech-model":`default_speech_model`,"default-omni-model":`default_omni_model`,"workspace-id":`workspace_id`};function ga(e){return ha[e]||e}function _a(e,n){let r=ga(e);if(!sa.includes(r))throw new t(`Invalid config key "${e}". Valid keys: ${sa.join(`, `)}`,s.USAGE);if(r===`output`&&![`text`,`json`].includes(n))throw new t(`Invalid output format "${n}". Valid values: text, json`,s.USAGE);if(r===`timeout`){let e=Number(n);if(isNaN(e)||e<=0)throw new t(`Invalid timeout "${n}". Must be a positive number.`,s.USAGE);return e}return r===`base_url`?St(n):n}function va(e,n){let r=ga(e);if(sa.includes(r))return _a(e,n);if(r===`console_site`){if(![`domestic`,`international`].includes(n))throw new t(`Invalid console_site "${n}". Valid values: domestic, international`,s.USAGE);return n}if(r===`console_region`)return n;if(r===`console_switch_agent`){let e=Number(n);if(!Number.isFinite(e)||e<=0)throw new t(`Invalid console_switch_agent "${n}". Must be a positive number.`,s.USAGE);return e}if(r===`telemetry`){if(n!==`true`&&n!==`false`)throw new t(`Invalid telemetry "${n}". Valid values: true, false`,s.USAGE);return n===`true`}throw new t(`Invalid config key "${e}". Valid keys: ${ua.join(`, `)}`,s.USAGE)}var ya=w({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=T(t.output),o={...i,base_url:n.baseUrl,output:t.output,timeout:t.timeout,config:t.configName??`default`,config_file:r.path};for(let e of ca)typeof o[e]==`string`&&(o[e]=dt(o[e]));A(o,a)}}),ba=w({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, security_token, 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:t,flags:n}=e,r=n.key,i=n.value,a=ga(r),o=_a(r,i),s=T(t.output);if(t.dryRun){A({would_set:{[a]:o},config:t.configName??`default`,config_file:e.configStore.path},s);return}if(await e.configStore.write({[a]:o}),!t.quiet){let n=ca.has(a)?dt(String(o)):o;A({[a]:n,config:t.configName??`default`,config_file:e.configStore.path},s)}}}),xa=w({description:`List config profiles and show the active profile`,auth:`none`,exampleArgs:[``,`--output json`],async run(e){let t=e.configStore.profiles(),n=[`default`,...Object.keys(t.named).sort()],r=T(e.settings.output);if(r===`json`){A({active_config:t.active,profiles:n,config_file:e.configStore.path},r);return}let i=Math.max(4,...n.map(e=>e.length));k(`${`NAME`.padEnd(i)} ACTIVE`);for(let e of n)k(`${e.padEnd(i)} ${e===t.active?`*`:``}`)}}),Sa=w({description:`Set the active config profile`,auth:`none`,usageArgs:`--name <name>`,flags:{name:{type:`string`,valueHint:`<name>`,description:`Existing profile name, or default`,required:!0}},exampleArgs:[`--name token-plan`,`--name default`],async run(e){let t=T(e.settings.output);if(e.settings.dryRun){A({would_activate:e.configStore.validateActivation(e.flags.name),config_file:e.configStore.path},t);return}let n=await e.configStore.activate(e.flags.name);e.settings.quiet||A({active_config:n,config_file:e.configStore.path},t)}});function Ca(e){try{return rr(e,`utf-8`)}catch{return}}function L(e){let t=Ca(e);if(t!==void 0)try{let e=JSON.parse(t);return e&&typeof e==`object`&&!Array.isArray(e)?e:void 0}catch{return}}function R(e){return e&&typeof e==`object`&&!Array.isArray(e)?e:void 0}function wa(e){let t=/^---\s*\n([\s\S]*?)\n---/.exec(e);if(!t)return{};try{return R(hr.parse(t[1]))??{}}catch{return{}}}function Ta(e,t=500){let n=0,r=e=>{if(n>=t)return;let i;try{i=ir(e,{withFileTypes:!0})}catch{return}for(let a of i){if(n>=t)return;let i=I(e,a.name);a.isDirectory()?r(i):n+=1}};return r(e),n}function Ea(e){return[{source:`global`,dir:I(e,`.agents`,`skills`)},{source:`claude-code`,dir:I(e,`.claude`,`skills`)},{source:`cursor`,dir:I(e,`.cursor`,`skills`)},{source:`qwen-code`,dir:I(e,`.qwen`,`skills`)},{source:`codex`,dir:I(e,`.codex`,`skills`)},{source:`opencode`,dir:I(e,`.config`,`opencode`,`skills`)},{source:`openclaw`,dir:I(e,`.openclaw`,`skills`)},{source:`openclaw`,dir:I(e,`.openclaw`,`workspace`,`skills`)},{source:`hermes`,dir:I(e,`.hermes`,`skills`)},{source:`gemini`,dir:I(e,`.gemini`,`skills`)},{source:`antigravity`,dir:I(e,`.gemini`,`antigravity`,`skills`)},{source:`windsurf`,dir:I(e,`.windsurf`,`skills`)},{source:`windsurf`,dir:I(e,`.codeium`,`windsurf`,`skills`)},{source:`qoderwork`,dir:I(e,`.qoderwork`,`skills`)},{source:`workbuddy`,dir:I(e,`.workbuddy`,`skills`)}]}function Da(e=pr()){let t=new Map;for(let{source:n,dir:r}of Ea(e)){let e;try{e=ir(r,{withFileTypes:!0})}catch{continue}for(let i of e){if(!i.isDirectory()&&!i.isSymbolicLink())continue;let e=I(r,i.name),a=I(e,`SKILL.md`);if(!P(a))continue;let o=t.get(i.name);if(o){o.sources.includes(n)||o.sources.push(n);continue}let s=wa(Ca(a)??``),c=R(s.metadata),l=typeof s.description==`string`?s.description.trim():``,u=c&&typeof c.version==`string`?c.version:typeof s.version==`string`?s.version:void 0;t.set(i.name,{id:i.name,name:typeof s.name==`string`&&s.name?s.name:i.name,description:l,version:u,fileCount:Ta(e),path:e,sources:[n],origin:`local`})}}return[...t.values()].sort((e,t)=>e.name.localeCompare(t.name))}function Oa(e,t=pr()){let n=Da(t).find(t=>t.id===e);if(!n)return null;let r=Ca(I(n.path,`SKILL.md`))??``;return{...n,content:r}}const ka=[{source:`global`,label:`All agents (~/.agents/skills)`,sub:[`.agents`,`skills`]},{source:`claude-code`,label:`Claude Code`,sub:[`.claude`,`skills`]},{source:`qwen-code`,label:`Qwen Code`,sub:[`.qwen`,`skills`]},{source:`codex`,label:`Codex`,sub:[`.codex`,`skills`]},{source:`opencode`,label:`OpenCode`,sub:[`.config`,`opencode`,`skills`]},{source:`openclaw`,label:`OpenClaw`,sub:[`.openclaw`,`skills`]},{source:`qoderwork`,label:`QoderWork`,sub:[`.qoderwork`,`skills`]},{source:`windsurf`,label:`Windsurf`,sub:[`.codeium`,`windsurf`,`skills`]},{source:`gemini`,label:`Gemini`,sub:[`.gemini`,`skills`]}];function Aa(e,t){let n=ka.find(t=>t.source===e);return n?I(t,...n.sub):null}function ja(e){let t=-1,n=Math.max(0,e.length-22-65535);for(let r=e.length-22;r>=n;r--)if(e.readUInt32LE(r)===101010256){t=r;break}if(t<0)throw Error(`Not a valid .zip archive.`);let r=e.readUInt16LE(t+10),i=e.readUInt32LE(t+16),a=[];for(let t=0;t<r&&!(i+46>e.length||e.readUInt32LE(i)!==33639248);t++){let t=e.readUInt16LE(i+10),n=e.readUInt32LE(i+20),r=e.readUInt16LE(i+28),o=e.readUInt16LE(i+30),s=e.readUInt16LE(i+32),c=e.readUInt32LE(i+42),l=e.toString(`utf8`,i+46,i+46+r);if(i+=46+r+o+s,l.endsWith(`/`)||c+30>e.length||e.readUInt32LE(c)!==67324752)continue;let u=e.readUInt16LE(c+26),d=e.readUInt16LE(c+28),f=c+30+u+d,p=e.subarray(f,f+n),m;if(t===0)m=Buffer.from(p);else if(t===8)m=mr(p);else throw Error(`Unsupported compression in archive (entry: `+l+`).`);a.push({name:l,data:m})}return a}function Ma(e,t,n,r=pr()){let i=Aa(e,r);if(!i)throw Error(`Unknown skill install target.`);let a=ja(t).map(e=>({name:e.name.replace(/\\/g,`/`).replace(/^\.\//,``).replace(/^\/+/,``),data:e.data})).filter(e=>e.name&&!e.name.endsWith(`/`)&&!e.name.split(`/`).includes(`..`));if(!a.length)throw Error(`The archive contains no usable files.`);let o=a.find(e=>e.name===`SKILL.md`||e.name.endsWith(`/SKILL.md`));if(!o)throw Error(`No SKILL.md found in the archive (root or a top-level folder).`);let s=o.name.lastIndexOf(`/`),c,l;if(s<0){if(c=(n||``).trim(),!c)throw Error(`SKILL.md is at the archive root — please provide a skill name.`);l=``}else l=o.name.slice(0,s+1),c=(n||``).trim()||l.split(`/`)[0];if(!/^[A-Za-z0-9._-]+$/.test(c))throw Error(`Invalid skill name: `+c);let u=I(i,c),d=dr(u),f=0;for(let e of a){let t=e.name;if(l){if(!e.name.startsWith(l))continue;t=e.name.slice(l.length)}if(!t)continue;let n=dr(I(u,t));n!==d&&!n.startsWith(d+fr)||(nr(cr(n),{recursive:!0}),sr(n,e.data),f++)}if(f===0)throw Error(`Nothing was extracted from the archive.`);return{installed:c,files:f,dir:u}}function Na(e){if(typeof e.command==`string`){let t=Array.isArray(e.args)?e.args.join(` `):``;return{transport:`stdio`,detail:`${e.command} ${t}`.trim()}}let t=typeof e.url==`string`?e.url:void 0;return t?{transport:(typeof e.type==`string`?e.type.toLowerCase():``)===`sse`?`sse`:`http`,detail:t}:{transport:`unknown`,detail:``}}function z(e,t,n,r,i){let a=R(e);if(a)for(let[e,o]of Object.entries(a)){let a=R(o)??{},{transport:s,detail:c}=Na(a);r.push({name:e,source:t,transport:s,detail:c,scope:n,origin:`local`,config:Ga(a),editable:i})}}function Pa(e=pr()){let t=[],n=L(I(e,`.claude.json`));if(n){z(n.mcpServers,`claude-code`,`global`,t,!0);let e=R(n.projects);if(e)for(let[n,r]of Object.entries(e)){let e=R(r);e?.mcpServers&&z(e.mcpServers,`claude-code`,n,t,!0)}}let r=L(I(e,`.qwen`,`settings.json`));r&&z(r.mcpServers,`qwen-code`,`global`,t,!0);let i=L(I(e,`.config`,`opencode`,`opencode.json`));i&&z(i.mcp,`opencode`,`global`,t,!0);let a=L(I(e,`.cursor`,`mcp.json`));a&&z(a.mcpServers,`cursor`,`global`,t,!0);let o=L(I(e,`.codeium`,`windsurf`,`mcp_config.json`));o&&z(o.mcpServers,`windsurf`,`global`,t,!0);let s=L(I(e,`.gemini`,`settings.json`));s&&z(s.mcpServers,`gemini`,`global`,t,!0);let c=L(I(e,`.qoderwork`,`mcp.json`));c&&z(c.mcpServers,`qoderwork`,`global`,t,!0);let l=L(I(e,`.openclaw`,`openclaw.json`));l&&z(l.mcpServers,`openclaw`,`global`,t,!0);let u=L(Fa(e));u&&z(u.mcpServers,`claude-desktop`,`global`,t,!0);let d=Ca(I(e,`.codex`,`config.toml`));if(d)try{z(gr(d).mcp_servers,`codex`,`global`,t,!1)}catch{}return t.sort((e,t)=>e.name.localeCompare(t.name)||e.source.localeCompare(t.source))}function Fa(e){return process.platform===`darwin`?I(e,`Library`,`Application Support`,`Claude`,`claude_desktop_config.json`):process.platform===`win32`?I(process.env.APPDATA??I(e,`AppData`,`Roaming`),`Claude`,`claude_desktop_config.json`):I(e,`.config`,`Claude`,`claude_desktop_config.json`)}function Ia(e,t,n){return e===`claude-code`?{file:I(n,`.claude.json`),mapKey:`mcpServers`,projectScoped:t!==`global`}:e===`qwen-code`?{file:I(n,`.qwen`,`settings.json`),mapKey:`mcpServers`,projectScoped:!1}:e===`opencode`?{file:I(n,`.config`,`opencode`,`opencode.json`),mapKey:`mcp`,projectScoped:!1}:e===`cursor`?{file:I(n,`.cursor`,`mcp.json`),mapKey:`mcpServers`,projectScoped:!1}:e===`windsurf`?{file:I(n,`.codeium`,`windsurf`,`mcp_config.json`),mapKey:`mcpServers`,projectScoped:!1}:e===`gemini`?{file:I(n,`.gemini`,`settings.json`),mapKey:`mcpServers`,projectScoped:!1}:e===`qoderwork`?{file:I(n,`.qoderwork`,`mcp.json`),mapKey:`mcpServers`,projectScoped:!1}:e===`openclaw`?{file:I(n,`.openclaw`,`openclaw.json`),mapKey:`mcpServers`,projectScoped:!1}:e===`claude-desktop`?{file:Fa(n),mapKey:`mcpServers`,projectScoped:!1}:null}function La(e,t){if(typeof e==`string`){if(e.includes(`•`)){if(typeof t==`string`)return t;throw Error(`Replace masked values (•••) with the real value before saving.`)}return e}if(Array.isArray(e)){let n=Array.isArray(t)?t:[];return e.map((e,t)=>La(e,n[t]))}let n=R(e);if(n){let e=R(t)??{},r={};for(let[t,i]of Object.entries(n))r[t]=La(i,e[t]);return r}return e}function Ra(e,t,n,r,i=pr()){let a=Ia(e,t,i);if(!a)throw Error(`This MCP source is read-only and cannot be edited here.`);let o=n.trim();if(!o)throw Error(`Server name is required.`);let s=R(r);if(!s)throw Error(`Config must be a JSON object.`);let c=L(a.file)??{},l=c;if(a.projectScoped){let e=R(c.projects)??{};c.projects=e;let n=R(e[t])??{};e[t]=n,l=n}let u=R(l[a.mapKey])??{};l[a.mapKey]=u,u[o]=La(s,R(u[o])),nr(cr(a.file),{recursive:!0}),sr(a.file,JSON.stringify(c,null,2)+`
|
|
29
|
-
`,`utf-8`)}function za(e,t,n,r=pr()){let i=Ia(e,t,r);if(!i)throw Error(`This MCP source is read-only and cannot be edited here.`);let a=L(i.file);if(!a)throw Error(`Config file not found.`);let o=a;if(i.projectScoped){let e=R(a.projects);o=e?R(e[t]):void 0}let s=o?R(o[i.mapKey]):void 0;if(!s||!(n in s))throw Error(`Server not found: `+n);delete s[n],o&&Object.keys(s).length===0&&delete o[i.mapKey],sr(i.file,JSON.stringify(a,null,2)+`
|
|
30
|
-
`,`utf-8`)}const Ba=[{id:`claude-code`,label:`Claude Code`,paths:e=>[I(process.env.CLAUDE_CONFIG_DIR||I(e,`.claude`),`settings.json`),I(e,`.claude.json`)],detect:e=>{let t=R(L(I(process.env.CLAUDE_CONFIG_DIR||I(e,`.claude`),`settings.json`))?.env),n=t&&typeof t.ANTHROPIC_BASE_URL==`string`?t.ANTHROPIC_BASE_URL:void 0,r=t&&typeof t.ANTHROPIC_MODEL==`string`?t.ANTHROPIC_MODEL:void 0;return{configured:!!n,model:r}}},{id:`qwen-code`,label:`Qwen Code`,paths:e=>[I(e,`.qwen`,`settings.json`)],detect:e=>{let t=L(I(e,`.qwen`,`settings.json`)),n=R(t?.modelProviders),r=n?Object.values(n).some(e=>Array.isArray(e)&&e.some(e=>{let t=R(e)?.name;return typeof t==`string`&&(t===`bailian-cli`||t.startsWith(`[Bailian]`))})):!1,i=R(t?.model);return{configured:r,model:i&&typeof i.name==`string`?i.name:void 0}}},{id:`opencode`,label:`OpenCode`,paths:e=>[I(e,`.config`,`opencode`,`opencode.json`)],detect:e=>{let t=R(R(L(I(e,`.config`,`opencode`,`opencode.json`))?.provider)?.[`bailian-cli`]),n=R(t?.models);return{configured:!!t,model:n?Object.keys(n)[0]:void 0}}},{id:`openclaw`,label:`OpenClaw`,paths:e=>[I(e,`.openclaw`,`openclaw.json`)],detect:e=>{let t=R(R(R(L(I(e,`.openclaw`,`openclaw.json`))?.models)?.providers)?.[`bailian-cli`]),n=R((Array.isArray(t?.models)?t.models:[])[0]);return{configured:!!t,model:n&&typeof n.id==`string`?n.id:void 0}}},{id:`hermes`,label:`Hermes Agent`,paths:e=>[I(e,`.hermes`,`config.yaml`)],detect:e=>{let t=Ca(I(e,`.hermes`,`config.yaml`));if(!t)return{configured:!1};let n;try{n=R(hr.parse(t))}catch{return{configured:!1}}let r=(Array.isArray(n?.custom_providers)?n.custom_providers:[]).some(e=>R(e)?.name===`bailian-cli`),i=R(n?.model),a=!!(i&&i.provider===`custom`&&typeof i.base_url==`string`&&i.base_url.includes(`aliyuncs.com`));return{configured:r||a,model:i&&typeof i.default==`string`?i.default:void 0}}},{id:`codex`,label:`Codex`,paths:e=>[I(e,`.codex`,`config.toml`),I(e,`.codex`,`auth.json`)],detect:e=>{let t=Ca(I(e,`.codex`,`config.toml`));if(!t)return{configured:!1};let n={};try{n=gr(t)}catch{return{configured:!1}}return{configured:!!R(n.model_providers)?.[`bailian-cli`],model:typeof n.model==`string`?n.model:void 0}}}];function Va(e=pr()){return Ba.map(t=>{let n=t.paths(e),r=n.some(e=>P(e)),{configured:i,model:a}=r?t.detect(e):{configured:!1,model:void 0};return{id:t.id,label:t.label,installed:r,configured:i,model:a,paths:n,origin:`local`}})}function B(e,t,n,r=!1){typeof n==`string`&&n.trim()&&e.push({label:t,value:n.trim(),secret:r})}function Ha(e,t){let n=[];if(e===`claude-code`){let e=R(L(I(t,`.claude`,`settings.json`))?.env);B(n,`Model`,e?.ANTHROPIC_MODEL),B(n,`Base URL`,e?.ANTHROPIC_BASE_URL),B(n,`Auth Token`,e?.ANTHROPIC_AUTH_TOKEN,!0)}else if(e===`qwen-code`){let e=L(I(t,`.qwen`,`settings.json`)),r=R(e?.model),i=R(R(e?.security)?.auth),a=R(e?.env);B(n,`Model`,r?.name),B(n,`Base URL`,i?.baseUrl??r?.baseUrl),B(n,`Protocol`,i?.selectedType),B(n,`API Key`,i?.apiKey??a?.BAILIAN_CLI_API_KEY,!0)}else if(e===`opencode`){let e=R(R(L(I(t,`.config`,`opencode`,`opencode.json`))?.provider)?.[`bailian-cli`]),r=R(e?.options),i=R(e?.models);B(n,`Model`,i?Object.keys(i)[0]:void 0),B(n,`Base URL`,r?.baseURL),B(n,`Provider`,e?.npm),B(n,`API Key`,r?.apiKey,!0)}else if(e===`openclaw`){let e=R(R(R(L(I(t,`.openclaw`,`openclaw.json`))?.models)?.providers)?.[`bailian-cli`]);B(n,`Model`,R((Array.isArray(e?.models)?e.models:[])[0])?.id),B(n,`Base URL`,e?.baseUrl),B(n,`API`,e?.api),B(n,`API Key`,e?.apiKey,!0)}else if(e===`hermes`){let e=Ca(I(t,`.hermes`,`config.yaml`)),r;if(e)try{r=R(hr.parse(e))}catch{r=void 0}let i=R((Array.isArray(r?.custom_providers)?r.custom_providers:[]).find(e=>R(e)?.name===`bailian-cli`));B(n,`Model`,R((Array.isArray(i?.models)?i.models:[])[0])?.id??R(r?.model)?.default),B(n,`Base URL`,i?.base_url),B(n,`API Mode`,i?.api_mode),B(n,`API Key`,i?.api_key,!0)}else if(e===`codex`){let e=Ca(I(t,`.codex`,`config.toml`)),r={};if(e)try{r=gr(e)}catch{r={}}let i=R(R(r.model_providers)?.[`bailian-cli`]),a=L(I(t,`.codex`,`auth.json`));B(n,`Model`,r.model),B(n,`Base URL`,i?.base_url),B(n,`Wire API`,i?.wire_api),B(n,`API Key`,a?.OPENAI_API_KEY,!0)}return n}function Ua(e){let t=e.trim();return t.length<=8?`•`.repeat(Math.max(t.length,4)):t.slice(0,3)+`•`.repeat(Math.min(t.length-3,16))}const Wa=/key|token|secret|password|passwd|auth|credential/i;function Ga(e,t=``){if(typeof e==`string`)return t&&Wa.test(t)&&e.trim()?Ua(e):e;if(Array.isArray(e))return e.map(e=>Ga(e));let n=R(e);if(n){let e={};for(let[t,r]of Object.entries(n))e[t]=Ga(r,t);return e}return e}function Ka(e){return e.endsWith(`.json`)?`json`:e.endsWith(`.yaml`)||e.endsWith(`.yml`)?`yaml`:e.endsWith(`.toml`)?`toml`:`text`}function qa(e,t=pr()){let n=Ba.find(t=>t.id===e);if(!n)return null;let r=n.paths(t),i=r.some(e=>P(e)),{configured:a,model:o}=i?n.detect(t):{configured:!1,model:void 0},s=i?Ha(e,t).map(e=>e.secret?{...e,raw:e.value,value:Ua(e.value)}:e):[],c=r.map(e=>({path:e,exists:P(e)})),l=i?r.filter(e=>P(e)).map(e=>({path:e,lang:Ka(e),text:Ca(e)??``})).filter(e=>e.text.trim()):[];return{id:n.id,label:n.label,installed:i,configured:a,model:o,paths:r,origin:`local`,fields:s,files:c,settings:l}}const Ja={"claude-code":`claude`,"qwen-code":`qwen`,opencode:`opencode`,openclaw:`openclaw`,hermes:`hermes`,codex:`codex`};function Ya(e){return Object.prototype.hasOwnProperty.call(Ja,e)?Ja[e]:void 0}const Xa={"qwen-code":e=>[`-i`,e],"claude-code":e=>[e],codex:e=>[e]};function Za(e){return Object.prototype.hasOwnProperty.call(Xa,e)}function Qa(e){let t=process.platform===`win32`?`where`:`which`;return new Promise(n=>{Un(t,[e],{windowsHide:!0},e=>n(!e))})}function $a(e){let t=Ya(e);return t?Qa(t):Promise.resolve(!1)}function eo(e){return`'${e.replace(/'/g,`'\\''`)}'`}function to(e,t){let n=process.platform;return new Promise((r,i)=>{if(n===`darwin`){Un(`osascript`,[`-e`,`tell application "Terminal" to do script "${`cd ${eo(t)} && ${e}`.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`)}"`,`-e`,`tell application "Terminal" to activate`],{windowsHide:!0},e=>e?i(e):r());return}if(n===`win32`){Un(`cmd`,[`/c`,`start`,``,`cmd`,`/k`,`cd /d ${t} && ${e}`],{windowsHide:!0},e=>e?i(e):r());return}Un(`x-terminal-emulator`,[`-e`,`bash`,`-lc`,`cd ${eo(t)} && ${e}; exec $SHELL`],{windowsHide:!0},e=>e?i(Error(`No supported terminal emulator was found`)):r())})}async function no(e,t=process.cwd(),n){let r=Ya(e);if(!r)throw Error(`Unknown agent: ${e}`);if(!await Qa(r))throw Error(`\`${r}\` was not found on your PATH — install ${e} first.`);let i=r,a=(n??``).trim();if(a){let t=Xa[e];if(!t)throw Error(`${e} does not support dispatching a task prompt.`);i=[r,...t(a).map(eo)].join(` `)}return await to(i,t),{launched:!0,command:i}}const ro=[{id:`image-generate`,title:`文生图`,description:`一键生成一张示例图片并保存到输出目录。`,category:`图像`,prompt:"请使用 bl 的图像生成能力(如 `bl image generate` 命令)生成一张示例图片:一只在雨中撑伞的柯基,水彩风格,光线柔和。保存到输出目录后告诉我文件路径。"},{id:`image-describe`,title:`图片理解`,description:`从输出目录任选一张图片,详细描述内容与风格。`,category:`图像`,prompt:`请在输出目录(默认 output/images)中任选一张图片,用中文详细描述它的内容、主体、构图、色彩与风格,并推测它适合的使用场景。若目录为空请说明。`},{id:`image-alt-batch`,title:`批量 Alt 文本`,description:`为输出目录下的图片批量生成无障碍 alt 文本。`,category:`图像`,prompt:`请扫描输出目录(默认 output/images)下的所有图片,逐张生成简洁、准确的 alt 无障碍描述,最后以「文件名 → alt 文本」的表格汇总。若目录为空请说明。`},{id:`image-to-code`,title:`截图转代码`,description:`把输出目录里的界面截图还原成 HTML+CSS。`,category:`图像`,prompt:`请在输出目录(默认 output/images)中查找一张界面截图,用 HTML + CSS 尽可能还原它的布局、间距与配色,输出为一个可直接在浏览器打开的单文件,并简述还原思路。若没有找到截图请说明。`},{id:`speech-generate`,title:`文字转语音`,description:`把一句示例文字合成为自然语音。`,category:`音频`,prompt:"请使用 bl 的语音合成能力(如 `bl speech` 相关命令)把下面这句话合成为自然语音,保存到输出目录,并告诉我音频文件路径:欢迎使用阿里云百炼命令行工具,让多模态创作更简单。"},{id:`audio-summarize`,title:`音频转写总结`,description:`转写输出目录里的音频并提炼要点。`,category:`音频`,prompt:`请在输出目录(默认 output/speech)中找到一个音频文件,转写其内容,先给出完整文字,再用要点列表总结关键信息。若目录为空或缺少转写能力,请说明并尝试用可用的能力完成。`},{id:`video-generate`,title:`文生视频`,description:`一键生成一段示例短视频。`,category:`视频`,prompt:"请使用 bl 的视频生成能力(如 `bl video generate` 命令)生成一段示例短视频:日落时分海边奔跑的少年,电影质感,慢动作。保存到输出目录后告诉我视频文件路径。"},{id:`video-storyboard`,title:`视频分镜脚本`,description:`围绕示例主题产出可用于文生视频的分镜。`,category:`视频`,prompt:`围绕主题「城市清晨的第一杯咖啡」,为一支 15-30 秒的短视频撰写分镜脚本:逐镜头给出画面描述、时长、字幕或旁白,并为每个镜头附上可直接用于文生视频的英文 prompt。`},{id:`media-prompt-craft`,title:`多模态提示词`,description:`把一个示例创意扩展成图/视频/语音提示词。`,category:`多模态`,prompt:`把创意「未来赛博城市的夜市」扩展成三组高质量生成提示词:1) 文生图;2) 文生视频;3) 语音风格描述。每组给出中英对照,并简要说明关键参数建议。`},{id:`image-story-narration`,title:`图片配音文案`,description:`为输出目录里的图片写解说词并给出可合成文本。`,category:`多模态`,prompt:`请在输出目录(默认 output/images)中任选一张图片,为它撰写一段 60 秒左右的中文解说词(适合配音),语气生动。随后给出可直接用于语音合成的纯文本版本。若目录为空请说明。`},{id:`summarize-project`,title:`总结当前项目`,description:`让 agent 阅读当前目录,总结架构、技术栈与主要模块。`,category:`代码`,prompt:`请阅读当前工作目录的项目结构和关键源码,用简洁的中文总结:1) 它是做什么的;2) 技术栈;3) 主要模块及其职责;4) 值得注意的设计。先浏览再下结论,不要臆测。`},{id:`write-tests`,title:`为核心模块写单测`,description:`自动挑选缺测试的核心模块并补全单元测试。`,category:`代码`,prompt:`请在当前项目中挑选一个核心且缺少测试(或测试薄弱)的模块,为它编写全面的单元测试,覆盖主要逻辑分支和边界情况,并遵循本项目现有的测试框架与风格。先阅读相关文件及其依赖,再编写测试。`},{id:`code-review`,title:`代码审查`,description:`审查当前项目核心代码,指出问题与改进建议。`,category:`代码`,prompt:`请审查当前项目的核心源码,指出潜在的 bug、安全隐患、性能与可维护性问题,并给出具体、可操作的改进建议,按严重程度排序。先浏览项目结构,选取关键文件再审查。`},{id:`explain-code`,title:`解释核心代码`,description:`挑选入口或核心模块,解释其实现与依赖。`,category:`代码`,prompt:`请挑选当前项目的入口文件或核心模块,解释它的实现:职责是什么、关键流程如何运转、依赖了哪些模块。用清晰的中文说明,必要时给出调用关系。`},{id:`generate-readme`,title:`生成 README`,description:`阅读代码后生成结构清晰、与实现一致的 README.md。`,category:`文档`,prompt:`为当前工作目录的项目生成一个结构清晰的 README.md,包含:项目简介、安装步骤、使用示例、目录结构说明。请先阅读现有代码与配置再撰写,内容必须与实际实现一致。`}];function io(e){return ro.find(t=>t.id===e)}function ao(e,t){return e.prompt.replace(/\{\{(\w+)\}\}/g,(e,n)=>{let r=t[n];return typeof r==`string`?r.trim():``})}const oo=new Uint8Array(512),so=new Uint8Array(256);(()=>{let e=1;for(let t=0;t<255;t++)oo[t]=e,so[e]=t,e<<=1,e&256&&(e^=285);for(let e=255;e<512;e++)oo[e]=oo[e-255]})();function co(e,t){return e===0||t===0?0:oo[so[e]+so[t]]}function lo(e){let t=[1];for(let n=0;n<e;n++){let e=Array.from({length:t.length+1},()=>0);for(let r=0;r<t.length;r++)e[r]^=t[r],e[r+1]^=co(t[r],oo[n]);t=e}return t.map(e=>so[e])}function uo(e,t){let n=lo(t),r=new Uint8Array(e.length+t);r.set(e,0);for(let t=0;t<e.length;t++){let e=r[t];if(e!==0){let i=so[e];for(let e=0;e<n.length;e++)r[t+e]^=oo[(n[e]+i)%255]}}return Array.from(r.slice(e.length))}const fo=[[19,7],[34,10],[55,15],[80,20],[108,26]];function po(e){let t=12+e*8;for(let e=0;e<fo.length;e++)if(fo[e][0]*8>=t)return e+1;throw Error(`qr: data too large for supported versions (max 108 bytes)`)}function mo(e,t){let[n]=fo[t-1],r=[],i=(e,t)=>{for(let n=t-1;n>=0;n--)r.push(e>>n&1)};i(4,4),i(e.length,8);for(let t of e)i(t,8);let a=n*8;for(i(0,Math.min(4,a-r.length));r.length%8!=0;)r.push(0);let o=[];for(let e=0;e<r.length;e+=8){let t=0;for(let n=0;n<8;n++)t=t<<1|r[e+n];o.push(t)}let s=[236,17];for(let e=0;o.length<n;e++)o.push(s[e%2]);return o.concat(uo(o,fo[t-1][1]))}function ho(e){return{size:e,mod:new Uint8Array(e*e),fn:new Uint8Array(e*e)}}function go(e,t,n,r){e.mod[t*e.size+n]=r,e.fn[t*e.size+n]=1}function _o(e,t,n){for(let r=-1;r<=7;r++)for(let i=-1;i<=7;i++){let a=t+r,o=n+i;a<0||a>=e.size||o<0||o>=e.size||go(e,a,o,+(r>=0&&r<=6&&i>=0&&i<=6&&(r===0||r===6||i===0||i===6||r>=2&&r<=4&&i>=2&&i<=4)))}}function vo(e,t,n){for(let r=-2;r<=2;r++)for(let i=-2;i<=2;i++){let a=Math.max(Math.abs(r),Math.abs(i));go(e,t+r,n+i,a===1?0:1)}}function yo(e,t){let n=e.size;for(let t=0;t<n;t++)go(e,6,t,+(t%2==0)),go(e,t,6,+(t%2==0));if(_o(e,0,0),_o(e,0,n-7),_o(e,n-7,0),t>=2){let t=n-7;vo(e,t,t)}for(let t=0;t<9;t++)t!==6&&(e.fn[8*n+t]=1),t!==6&&(e.fn[t*n+8]=1);e.fn[8*n+6]=1,e.fn[6*n+8]=1;for(let t=0;t<8;t++)e.fn[(n-1-t)*n+8]=1;for(let t=0;t<8;t++)e.fn[8*n+(n-1-t)]=1;go(e,n-8,8,1)}function bo(e,t){let n=e.size,r=[];for(let e of t)for(let t=7;t>=0;t--)r.push(e>>t&1);let i=0,a=!0;for(let t=n-1;t>=1;t-=2){t===6&&(t=5);for(let o=0;o<n;o++){let s=a?n-1-o:o;for(let a of[0,1]){let o=t-a;e.fn[s*n+o]||(e.mod[s*n+o]=i<r.length?r[i++]:0)}}a=!a}}const xo=[(e,t)=>(e+t)%2==0,e=>e%2==0,(e,t)=>t%3==0,(e,t)=>(e+t)%3==0,(e,t)=>(Math.floor(e/2)+Math.floor(t/3))%2==0,(e,t)=>e*t%2+e*t%3==0,(e,t)=>(e*t%2+e*t%3)%2==0,(e,t)=>((e+t)%2+e*t%3)%2==0];function So(e,t){let n=xo[t];for(let t=0;t<e.size;t++)for(let r=0;r<e.size;r++)!e.fn[t*e.size+r]&&n(t,r)&&(e.mod[t*e.size+r]^=1)}function Co(e){let t=e.size,n=(n,r)=>e.mod[n*t+r],r=0;for(let e=0;e<t;e++){let i=1,a=1;for(let o=1;o<t;o++)n(e,o)===n(e,o-1)?i++:(i>=5&&(r+=i-2),i=1),n(o,e)===n(o-1,e)?a++:(a>=5&&(r+=a-2),a=1);i>=5&&(r+=i-2),a>=5&&(r+=a-2)}for(let e=0;e<t-1;e++)for(let i=0;i<t-1;i++){let t=n(e,i);t===n(e,i+1)&&t===n(e+1,i)&&t===n(e+1,i+1)&&(r+=3)}let i=[1,0,1,1,1,0,1,0,0,0,0],a=[0,0,0,0,1,0,1,1,1,0,1],o=(e,t,n)=>{for(let r=0;r<n.length;r++)if(e(t+r)!==n[r])return!1;return!0};for(let e=0;e<t;e++)for(let s=0;s<=t-11;s++)(o(t=>n(e,t),s,i)||o(t=>n(e,t),s,a))&&(r+=40),(o(t=>n(t,e),s,i)||o(t=>n(t,e),s,a))&&(r+=40);let s=0;for(let n=0;n<t*t;n++)s+=e.mod[n];let c=s*100/(t*t),l=Math.floor(Math.abs(c-50)/5);return r+=l*10,r}function wo(e){let t=8|e,n=t<<10;for(let e=14;e>=10;e--)n>>e&1&&(n^=1335<<e-10);return(t<<10|n)^21522}function To(e,t){let n=e.size,r=wo(t),i=e=>r>>e&1;for(let t=0;t<=5;t++)e.mod[t*n+8]=i(t);e.mod[7*n+8]=i(6),e.mod[8*n+8]=i(7),e.mod[8*n+7]=i(8);for(let t=9;t<15;t++)e.mod[8*n+(14-t)]=i(t);for(let t=0;t<8;t++)e.mod[(n-1-t)*n+8]=i(t);for(let t=8;t<15;t++)e.mod[8*n+(n-15+t)]=i(t);e.mod[(n-8)*n+8]=1}function Eo(e){let t=new TextEncoder().encode(e),n=po(t.length),r=mo(t,n),i=ho(17+4*n);yo(i,n),bo(i,r);let a=0,o=1/0;for(let e=0;e<8;e++){So(i,e),To(i,e);let t=Co(i);t<o&&(o=t,a=e),So(i,e)}So(i,a),To(i,a);let s=[];for(let e=0;e<i.size;e++){let t=[];for(let n=0;n<i.size;n++)t.push(i.mod[e*i.size+n]===1);s.push(t)}return s}function Do(e){let t=Eo(e),n=t.length,r=n+8,i=``;for(let e=0;e<n;e++)for(let r=0;r<n;r++)t[e][r]&&(i+=`<rect x="${r+4}" y="${e+4}" width="1" height="1"/>`);return`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${r} ${r}" shape-rendering="crispEdges" role="img" aria-label="QR code"><rect width="${r}" height="${r}" fill="#ffffff"/><g fill="#000000">${i}</g></svg>`}function Oo(e){let{identity:t,settings:n,authStore:r}=e;return{status(){let e=r.describe(),t={apiKey:!!e.apiKey,console:!!e.console,openapi:!!e.openapi},n;e.console?n=dt(e.console.token):e.apiKey?n=dt(e.apiKey.token):e.openapi&&(n=dt(e.openapi.accessKeyId));let i=e.console?`console`:e.apiKey?`apiKey`:e.openapi?`openapi`:null;return{authenticated:t.apiKey||t.console||t.openapi,methods:t,primary:i,region:e.console?.region,site:e.console?.site,masked:n}},startConsoleLogin(){let e=oi(r.describe().console?.site),i=!!r.stored().apiKey;xi(e,{identity:t,settings:n,authStore:r},{needApiKey:!i}).catch(e=>{let t=e instanceof Error?e.message:String(e);process.stderr.write(`console login failed: ${t}\n`)})},logout(){return r.logout(`all`)}}}const ko={".png":`image`,".jpg":`image`,".jpeg":`image`,".webp":`image`,".gif":`image`,".bmp":`image`,".svg":`image`,".mp4":`video`,".mov":`video`,".webm":`video`,".mkv":`video`,".avi":`video`,".mp3":`audio`,".wav":`audio`,".m4a":`audio`,".aac":`audio`,".flac":`audio`,".ogg":`audio`},Ao={".png":`image/png`,".jpg":`image/jpeg`,".jpeg":`image/jpeg`,".webp":`image/webp`,".gif":`image/gif`,".bmp":`image/bmp`,".svg":`image/svg+xml`,".mp4":`video/mp4`,".mov":`video/quicktime`,".webm":`video/webm`,".mkv":`video/x-matroska`,".avi":`video/x-msvideo`,".mp3":`audio/mpeg`,".wav":`audio/wav`,".m4a":`audio/mp4`,".aac":`audio/aac`,".flac":`audio/flac`,".ogg":`audio/ogg`};function jo(e=pr()){return I(e,`bailian-output`)}function Mo(e){return ko[e.toLowerCase()]??`other`}function No(e){return Ao[e.toLowerCase()]??`application/octet-stream`}function Po(e,t,n){let r;try{r=ir(e,{withFileTypes:!0})}catch{return}for(let i of r){let r=I(e,i.name);i.isDirectory()?t>0&&Po(r,t-1,n):(i.isFile()||i.isSymbolicLink())&&n.push(r)}}function Fo(e=jo()){let t=[];if(!P(e))return{base:e,assets:t};let n=[];Po(e,8,n);for(let r of n){let n;try{n=ar(r)}catch{continue}if(!n.isFile())continue;let i=ur(e,r),a=i.split(fr),o=a.length>1?a[0]:`other`,s=lr(r);t.push({name:r.split(fr).pop()??r,category:o,kind:Mo(s),relPath:i,size:n.size,mtime:n.mtimeMs,ext:s.replace(/^\./,``).toLowerCase()})}return t.sort((e,t)=>t.mtime-e.mtime),{base:e,assets:t}}function Io(e,t){if(typeof t!=`string`||t.length===0)return null;let n=dr(e),r=dr(n,t);return r!==n&&!r.startsWith(n+fr)?null:r}const Lo={port:{type:`number`,valueHint:`<port>`,description:`Port to listen on (default: random free port)`},noOpen:{type:`switch`,description:`Do not open the browser automatically`}};function V(e){return e instanceof t||e instanceof Error?e.message:String(e)}function H(e,t,n){e.writeHead(t,{"Content-Type":`application/json; charset=utf-8`}),e.end(JSON.stringify(n))}function Ro(e){return new Promise((t,n)=>{let r=0,i=[];e.on(`data`,t=>{if(r+=t.length,r>1048576){n(Error(`payload too large`)),e.destroy();return}i.push(t)}),e.on(`end`,()=>t(Buffer.concat(i).toString(`utf8`))),e.on(`error`,n)})}function zo(e,t){return new Promise((n,r)=>{let i=0,a=[];e.on(`data`,n=>{if(i+=n.length,i>t){r(Error(`payload too large`)),e.destroy();return}a.push(n)}),e.on(`end`,()=>n(Buffer.concat(a))),e.on(`error`,r)})}function Bo(e,t){if(!e)return!1;let n=Buffer.from(e),r=Buffer.from(t);return n.length===r.length&&Vn(n,r)}function Vo(e){let t={};for(let[n,r]of Object.entries(e)){let e=``;typeof r==`string`?e=r:(typeof r==`number`||typeof r==`boolean`)&&(e=String(r)),e!==``&&(t[ga(n)]=va(n,e))}return t}function Ho(e,t){let n=new Set(ua),r={};for(let[t,i]of Object.entries(e))n.has(t)||(r[t]=i);return{...r,...t}}function Uo(e,t,n=jo(),r){return Hn.createServer(async(i,a)=>{try{let o=(i.headers.host||``).split(`:`)[0];if(o!==`127.0.0.1`&&o!==`localhost`){a.writeHead(403,{"Content-Type":`text/plain; charset=utf-8`}),a.end(`forbidden host
|
|
31
|
-
`);return}let s=new URL(i.url??`/`,`http://127.0.0.1`);if(!Bo(s.searchParams.get(`token`),e)){a.writeHead(401,{"Content-Type":`text/plain; charset=utf-8`}),a.end(`unauthorized
|
|
32
|
-
`);return}let c=i.method??`GET`,l=s.pathname;if(l===`/`&&c===`GET`){a.writeHead(200,{"Content-Type":`text/html; charset=utf-8`,"Cache-Control":`no-store`,"X-Content-Type-Options":`nosniff`,"Content-Security-Policy":`default-src 'self'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; img-src 'self' data: https://img.alicdn.com https://oss.aliyuncs.com; media-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'`}),a.end(`<!doctype html>
|
|
23
|
+
`),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 zi)process.stdout.write(`${e(t.voice,12)} ${e(t.name,14)} ${e(t.desc,14)} ${t.lang}\n`);process.stdout.write(`\nTotal: ${zi.length} voices\n`)}const Vi={wav:`wav`,mp3:`mp3`,amr:`amr`,aac:`aac`,m4a:`aac`,ogg:`ogg`,"3gp":`3gp`,"3gpp":`3gpp`},Hi=Object.keys(Vi);function Ui(e){let n=e.split(`?`)[0].split(`#`)[0],r=nr(n).slice(1).toLowerCase();if(!r)throw new t(`Cannot infer audio format from "${e}". Use a file/URL whose path ends with: ${Hi.join(`, `)}.`,c.USAGE);let i=Vi[r];if(!i)throw new t(`Unsupported audio extension ".${r}" for "${e}". Supported extensions: ${Hi.join(`, `)}.`,c.USAGE);return i}function Wi(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 Gi=w({description:{"en-US":`Multimodal chat with text + audio output (Qwen-Omni)`,"zh-CN":`支持文本输入与音频输出的多模态对话(Qwen-Omni)`},auth:`apiKey`,usageArgs:`--message <text> [flags]`,flags:{message:{type:`array`,valueHint:`<text>`,description:{"en-US":`Message text (repeatable, prefix role: to set role)`,"zh-CN":`消息文本(可重复;可使用 role: 前缀指定角色)`}},model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Model ID (default: qwen3.5-omni-plus)`,"zh-CN":`模型 ID(默认:qwen3.5-omni-plus)`}},system:{type:`string`,valueHint:`<text>`,description:{"en-US":`System prompt`,"zh-CN":`系统提示词`}},image:{type:`array`,valueHint:`<url>`,description:{"en-US":`Image URL or local file (repeatable)`,"zh-CN":`图片 URL 或本地文件(可重复)`}},audio:{type:`array`,valueHint:`<url>`,description:{"en-US":`Audio URL or local file (.wav/.mp3/.amr/.aac/.m4a/.ogg/.3gp/.3gpp)`,"zh-CN":`音频 URL 或本地文件(.wav/.mp3/.amr/.aac/.m4a/.ogg/.3gp/.3gpp)`}},video:{type:`array`,valueHint:`<url>`,description:{"en-US":`Video file URL / local path, or comma-separated frame URLs`,"zh-CN":`视频文件 URL / 本地路径,或以逗号分隔的帧 URL`}},voice:{type:`string`,valueHint:`<voice>`,description:{"en-US":`Output voice ID (default: Tina). Use --list-voices to see all options`,"zh-CN":`输出音色 ID(默认:Tina)。使用 --list-voices 查看所有选项`}},listVoices:{type:`switch`,description:{"en-US":`List available output voices and exit`,"zh-CN":`列出可用的输出音色并退出`}},audioFormat:{type:`string`,valueHint:`<fmt>`,description:{"en-US":`Audio output format (default: wav)`,"zh-CN":`音频输出格式(默认:wav)`}},audioOut:{type:`string`,valueHint:`<path>`,description:{"en-US":`Save audio to file (default: auto-generate)`,"zh-CN":`将音频保存到文件(默认:自动生成路径)`}},textOnly:{type:`switch`,description:{"en-US":`Output text only, no audio generation`,"zh-CN":`仅输出文本,不生成音频`}},maxTokens:{type:`number`,valueHint:`<n>`,description:{"en-US":`Maximum tokens to generate`,"zh-CN":`最大生成 Token 数`}},temperature:{type:`number`,valueHint:`<n>`,description:{"en-US":`Sampling temperature (0.0, 2.0]`,"zh-CN":`采样温度 (0.0, 2.0]`}}},exampleArgs:[`--list-voices`,{"en-US":`--message "Hello, who are you?"`,"zh-CN":`--message "你好,你是谁?"`},{"en-US":`--message "Describe this image" --image ./photo.jpg`,"zh-CN":`--message "描述这张图片" --image ./photo.jpg`},{"en-US":`--message "What is this audio saying?" --audio https://example.com/audio.wav`,"zh-CN":`--message "这段音频说了什么?" --audio https://example.com/audio.wav`},{"en-US":`--message "Summarize this video" --video https://example.com/video.mp4`,"zh-CN":`--message "总结这段视频" --video https://example.com/video.mp4`},{"en-US":`--message "What is this video about?" --video ./local-video.mp4 --text-only`,"zh-CN":`--message "这段视频讲了什么?" --video ./local-video.mp4 --text-only`},{"en-US":`--message "Answer in Sichuan dialect: How's the weather today?" --voice Sunny`,"zh-CN":`--message "请用四川话回答:今天天气怎么样?" --voice Sunny`},{"en-US":`--message "Hello" --text-only --output json`,"zh-CN":`--message "你好" --text-only --output json`},{"en-US":`--message "Read this passage aloud" --audio-out greeting.wav`,"zh-CN":`--message "朗读这段文字" --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){Bi();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=T(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:Ui(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){A({request:_},c);return}if(!t.quiet){let e=s?`text-only`:`text+audio, voice: ${a}`;process.stderr.write(`[Model: ${i}] [${e}]\n`)}let v=await e.client.request({path:oe(),method:`POST`,body:_,stream:!0}),y=``,b=``,x=process.stdout.isTTY,S=process.stdout;for await(let e of Et(v)){if(e.data===`[DONE]`)break;try{let t=JSON.parse(e.data);for(let e of t.choices){let t=e.delta;t.content&&(y+=t.content,x&&S.write(t.content)),t.audio?.data&&(b+=t.audio.data)}}catch{}}x&&y&&S.write(`
|
|
24
|
+
`);let C;if(b&&!s){let e=Buffer.from(b,`base64`),r=Wi(e.length),i=Buffer.concat([r,e]),a=n.audioOut;if(!a){let{join:e}=await import(`path`);a=e(Ut(t,{subDir:`omni`}),`omni_${Date.now()}.wav`)}$n(a,i),C=a,t.quiet||process.stderr.write(`Audio saved: ${a}\n`)}if(!x||c===`json`){let e={content:y};C&&(e.audio_saved=C,e.voice=a),A(e,c)}}}),Ki=w({description:{"en-US":`Generate images (Qwen-Image / wan2.x)`,"zh-CN":`生成图片(Qwen-Image / wan2.x)`},auth:`apiKey`,usageArgs:`--prompt <text> [flags]`,flags:{prompt:{type:`string`,valueHint:`<text>`,description:{"en-US":`Image description`,"zh-CN":`图片描述`},required:!0},model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Model ID (default: qwen-image-3.0)`,"zh-CN":`模型 ID(默认:qwen-image-3.0)`}},size:{type:`string`,valueHint:`<W*H>`,description:{"en-US":`Image size: ratio (3:4, 16:9, 1:1) or pixels (2048*2048)`,"zh-CN":`图片尺寸:比例(3:4、16:9、1:1)或像素(2048*2048)`}},n:{type:`number`,valueHint:`<count>`,description:{"en-US":`Number of images per request (default: 1, max: 6)`,"zh-CN":`每次请求生成的图片数量(默认:1,最多:6)`}},seed:{type:`number`,valueHint:`<n>`,description:{"en-US":`Random seed for reproducible generation`,"zh-CN":`用于复现生成结果的随机种子`}},negativePrompt:{type:`string`,valueHint:`<text>`,description:{"en-US":`Negative prompt to exclude unwanted content`,"zh-CN":`负向提示词,用于排除不需要的内容`}},promptExtend:{type:`boolean`,valueHint:`<bool>`,description:mn},watermark:{type:`boolean`,valueHint:`<bool>`,description:hn},...e,...n,outDir:{type:`string`,valueHint:`<dir>`,description:{"en-US":`Download images to directory`,"zh-CN":`将图片下载到指定目录`}},outPrefix:{type:`string`,valueHint:`<prefix>`,description:{"en-US":`Filename prefix (default: image)`,"zh-CN":`文件名前缀(默认:image)`}},pollInterval:{type:`number`,valueHint:`<seconds>`,description:{"en-US":`Polling interval when waiting (default: 3)`,"zh-CN":`等待任务时的轮询间隔(默认:3 秒)`}}},exampleArgs:[{"en-US":`--prompt "A cat in a spacesuit on Mars"`,"zh-CN":`--prompt "一只穿着宇航服的猫站在火星上"`},{"en-US":`--prompt "Logo design" --n 3 --out-dir ./generated/`,"zh-CN":`--prompt "Logo 设计" --n 3 --out-dir ./generated/`},{"en-US":`--prompt "Mountain landscape" --size 2688*1536`,"zh-CN":`--prompt "山地景观" --size 2688*1536`},{"en-US":`--prompt "A castle" --seed 42 --prompt-extend false`,"zh-CN":`--prompt "一座城堡" --seed 42 --prompt-extend false`},{"en-US":`--prompt "Logo" --watermark false`,"zh-CN":`--prompt "Logo" --watermark false`},{"en-US":`--prompt "An alien in the space" --watermark false`,"zh-CN":`--prompt "太空中的外星人" --watermark false`},{"en-US":`--prompt "sunset" --model wan2.6-t2i --async --quiet`,"zh-CN":`--prompt "日落" --model wan2.6-t2i --async --quiet`},{"en-US":`--prompt "plush doll" --model z-image-turbo --size 1024*1024`,"zh-CN":`--prompt "毛绒玩偶" --model z-image-turbo --size 1024*1024`},{"en-US":`--prompt "sunset" --model wanx2.0-t2i-turbo --size 1024*1024`,"zh-CN":`--prompt "日落" --model wanx2.0-t2i-turbo --size 1024*1024`},{"en-US":`--prompt "Pro quality" --model qwen-image-2.0-pro`,"zh-CN":`--prompt "专业品质" --model qwen-image-2.0-pro`},{"en-US":`--prompt "Product shots" --n 2 --concurrent 3 # 6 images in parallel`,"zh-CN":`--prompt "产品摄影" --n 2 --concurrent 3 # 并行生成 6 张图片`}],async run(e){let{settings:t,flags:n}=e,r=n.prompt,i=n.model||t.defaultImageModel||`qwen-image-3.0`,a=Ht(i),o=Ln(n.size||`1:1`,a.sizeProfile),s=n.n??1,c=On(n),l=Bt(n.promptExtend,a.promptExtendDefault,`prompt-extend`),u=Wt(n.watermark),d={size:o,n:s,seed:n.seed,prompt_extend:l,watermark:u},f=a.inputStyle===`prompt`?{model:i,input:{prompt:r,negative_prompt:n.negativePrompt||void 0},parameters:d}:{model:i,input:{messages:[{role:`user`,content:[{text:r}]}]},parameters:{...d,negative_prompt:n.negativePrompt||void 0}},p=T(t.output);if(t.dryRun){A({request:f,mode:a.useSync?`sync`:`async`,path:a.path},p);return}t.quiet||process.stderr.write(`[Model: ${i}] [Mode: ${a.useSync?`sync`:`async`}]\n`),a.useSync?await qi(e.client,t,a.path,f,n,p,c):await Ji(e.client,t,a.path,f,n,p,c)}});async function qi(e,n,r,i,a,o,s){let l=(await Rn(s,n,()=>e.requestJson({path:r,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.`,c.GENERAL);await Yi(l,a,n,o)}async function Ji(e,n,r,i,a,o,s){let l=(await Rn(s,n,()=>e.requestJson({path:r,method:`POST`,body:i,async:!0}),`tasks`)).map(e=>e.output.task_id);if(a.async){A({task_ids:l},o);return}let u=a.pollInterval??3,d=l.map(t=>Pn(e,n,{url:e.url($t(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.`,c.GENERAL);await Yi(p,a,n,o,l.length===1?l[0]:void 0,l)}async function Yi(e,t,n,r,i,a){let o=Ut(n,{flagDir:t.outDir,subDir:t.outDir?void 0:`images`}),s=t.prompt||``,c=t.outPrefix||Le(`image`,s),l=await Cn(e.length>1?e.map((e,t)=>({url:e,destPath:N(o,`${c}_${String(t+1).padStart(3,`0`)}.png`)})):[{url:e[0],destPath:N(o,`${c}.png`)}],Sn,{quiet:n.quiet});if(n.quiet)k(l.join(`
|
|
25
|
+
`));else{let t={urls:e,saved:l,total:e.length};i&&(t.task_id=i),a&&a.length>1&&(t.task_ids=a),A(t,r)}}var Xi=w({description:{"en-US":`Edit an existing image with text instructions (Qwen-Image / Wan 2.7)`,"zh-CN":`使用文本指令编辑现有图片(Qwen-Image / Wan 2.7)`},auth:`apiKey`,usageArgs:`--image <url> --prompt <text> [flags]`,flags:{image:{type:`array`,valueHint:`<url>`,description:{"en-US":`Source image URL or local file path (repeatable for multi-image merge)`,"zh-CN":`源图片 URL 或本地文件路径(多图融合时可重复)`},required:!0},prompt:{type:`string`,valueHint:`<text>`,description:{"en-US":`Edit instruction text`,"zh-CN":`编辑指令文本`},required:!0},model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Model ID (default: qwen-image-3.0)`,"zh-CN":`模型 ID(默认:qwen-image-3.0)`}},size:{type:`string`,valueHint:`<W*H>`,description:{"en-US":`Output image size: ratio (3:4, 16:9) or pixels (2048*2048)`,"zh-CN":`输出图片尺寸:比例(3:4、16:9)或像素(2048*2048)`}},n:{type:`number`,valueHint:`<count>`,description:{"en-US":`Number of images (default: 1, max: 6)`,"zh-CN":`图片数量(默认:1,最多:6)`}},seed:{type:`number`,valueHint:`<n>`,description:{"en-US":`Random seed for reproducible results`,"zh-CN":`用于复现结果的随机种子`}},negativePrompt:{type:`string`,valueHint:`<text>`,description:{"en-US":`Negative prompt to exclude unwanted content`,"zh-CN":`负向提示词,用于排除不需要的内容`}},function:{type:`string`,valueHint:`<name>`,description:{"en-US":`wanx*-imageedit function (default: description_edit). Examples: stylization_all, description_edit`,"zh-CN":`wanx*-imageedit 功能(默认:description_edit)。例如:stylization_all、description_edit`}},promptExtend:{type:`boolean`,valueHint:`<bool>`,description:pn},watermark:{type:`boolean`,valueHint:`<bool>`,description:hn},outDir:{type:`string`,valueHint:`<dir>`,description:{"en-US":`Download images to directory`,"zh-CN":`将图片下载到指定目录`}},outPrefix:{type:`string`,valueHint:`<prefix>`,description:{"en-US":`Filename prefix (default: edited)`,"zh-CN":`文件名前缀(默认:edited)`}},...e,...n,pollInterval:{type:`number`,valueHint:`<seconds>`,description:{"en-US":`Polling interval when waiting (default: 3)`,"zh-CN":`等待任务时的轮询间隔(默认:3 秒)`}}},exampleArgs:[{"en-US":`--image ./photo.png --prompt "Replace the background with a beach"`,"zh-CN":`--image ./photo.png --prompt "将背景替换为海滩"`},{"en-US":`--image https://example.com/logo.png --prompt "Change color to blue" --n 3`,"zh-CN":`--image https://example.com/logo.png --prompt "将颜色改为蓝色" --n 3`},{"en-US":`--image ./a.png --image ./b.png --prompt "Merge two images into one collage"`,"zh-CN":`--image ./a.png --image ./b.png --prompt "将两张图片合并成一张拼贴图"`},{"en-US":`--image https://example.com/photo.png --prompt "Remove the person" --model qwen-image-2.0-pro`,"zh-CN":`--image https://example.com/photo.png --prompt "移除人物" --model qwen-image-2.0-pro`},{"en-US":`--image ./photo.png --prompt "Change the style" --model wan2.7-image`,"zh-CN":`--image ./photo.png --prompt "更改图片风格" --model wan2.7-image`},{"en-US":`--image ./photo.png --prompt "Place the subject on a table" --model wan2.5-i2i-preview`,"zh-CN":`--image ./photo.png --prompt "将主体放在桌面上" --model wan2.5-i2i-preview`},{"en-US":`--image ./photo.png --prompt "Convert to a picture-book style" --model wanx2.1-imageedit --function stylization_all`,"zh-CN":`--image ./photo.png --prompt "转换成绘本风格" --model wanx2.1-imageedit --function stylization_all`},{"en-US":`--image ./photo.png --prompt "Replace the background with a beach" --watermark false`,"zh-CN":`--image ./photo.png --prompt "将背景替换为海滩" --watermark false`}],async run(e){let{settings:n,flags:r}=e,i=[];Array.isArray(r.image)?i=r.image:typeof r.image==`string`&&(i=[r.image]);let a=r.prompt,o=r.model||n.defaultImageModel||`qwen-image-3.0`,s=Vt(o),l=await Promise.all(i.map(t=>e.client.resolveImageInput(t,o))),u=r.n??1,d=Bt(r.promptExtend,s.promptExtendDefault,`prompt-extend`),f=Wt(r.watermark),p={size:Ln(r.size,s.sizeProfile),n:u,seed:r.seed,prompt_extend:d,watermark:f},m;if(s.inputStyle===`function-base-image`){let e=l[0];if(!e)throw new t(`wanx*-imageedit requires at least one --image as base_image_url.`,c.USAGE);m={model:o,input:{function:r.function||`description_edit`,prompt:a,base_image_url:e},parameters:p}}else if(s.inputStyle===`prompt-images`)m={model:o,input:{prompt:a,images:l,negative_prompt:r.negativePrompt||void 0},parameters:p};else{let e=l.map(e=>({image:e}));e.push({text:a}),m={model:o,input:{messages:[{role:`user`,content:e}]},parameters:{...p,negative_prompt:r.negativePrompt||void 0}}}Qt(m.parameters);let h=T(n.output);if(n.dryRun){let e=m;`messages`in m.input?e={...m,input:{messages:m.input.messages.map(e=>({...e,content:e.content.map(e=>e.image?{...e,image:D(e.image)}:e)}))}}:`images`in m.input?e={...m,input:{...m.input,images:m.input.images?.map(e=>D(e))}}:`base_image_url`in m.input&&(e={...m,input:{...m.input,base_image_url:D(m.input.base_image_url),mask_image_url:m.input.mask_image_url?D(m.input.mask_image_url):void 0}}),A({request:e,mode:s.useSync?`sync`:`async`,path:s.path},h);return}n.quiet||process.stderr.write(`[Model: ${o}] [Mode: ${s.useSync?`sync`:`async`}] [Images: ${l.length}]\n`);let g=On(r);s.useSync?await Zi(e.client,n,s.path,m,r,h,g):await Qi(e.client,n,s.path,m,r,h,g)}});async function Zi(e,n,r,i,a,o,s){let l=(await Rn(s,n,()=>e.requestJson({path:r,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(`Edit completed but no images returned.`,c.GENERAL);await $i(l,a,n,o)}async function Qi(e,n,r,i,a,o,s){let l=(await Rn(s,n,()=>e.requestJson({path:r,method:`POST`,body:i,async:!0}),`tasks`)).map(e=>e.output.task_id);if(a.async){A({task_ids:l},o);return}let u=a.pollInterval??3,d=l.map(t=>Pn(e,n,{url:e.url($t(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.`,c.GENERAL);await $i(p,a,n,o)}async function $i(e,t,n,r){let i=Ut(n,{flagDir:t.outDir,subDir:t.outDir?void 0:`images`}),a=t.outPrefix||Le(`edited`,t.prompt),o=await Cn(e.length>1?e.map((e,t)=>({url:e,destPath:N(i,`${a}_${String(t+1).padStart(3,`0`)}.png`)})):[{url:e[0],destPath:N(i,`${a}.png`)}],Sn,{quiet:n.quiet});n.quiet?k(o.join(`
|
|
26
|
+
`)):A({urls:e,saved:o,total:e.length},r)}var ea=w({description:{"en-US":`Generate a video from text or image (happyhorse-1.1-t2v / happyhorse-1.1-i2v / wan2.6-t2v)`,"zh-CN":`根据文本或图片生成视频(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:{"en-US":`Model ID (default: happyhorse-1.1-t2v, or happyhorse-1.1-i2v with --image)`,"zh-CN":`模型 ID(默认:happyhorse-1.1-t2v;使用 --image 时为 happyhorse-1.1-i2v)`}},prompt:{type:`string`,valueHint:`<text>`,description:{"en-US":`Video description`,"zh-CN":`视频描述`},required:!0},image:{type:`string`,valueHint:`<url>`,description:{"en-US":`Input image URL for image-to-video generation`,"zh-CN":`图生视频使用的输入图片 URL`}},lastFrame:{type:`string`,valueHint:`<url>`,description:{"en-US":`Last frame image URL (with --image, enables kf2v first+last frame mode)`,"zh-CN":`尾帧图片 URL(与 --image 配合,启用 kf2v 首尾帧模式)`}},negativePrompt:{type:`string`,valueHint:`<text>`,description:{"en-US":`Negative prompt to exclude unwanted content`,"zh-CN":`负向提示词,用于排除不需要的内容`}},resolution:{type:`string`,valueHint:`<res>`,description:{"en-US":`Resolution: 720P or 1080P (default: 1080P)`,"zh-CN":`分辨率:720P 或 1080P(默认:1080P)`}},ratio:{type:`string`,valueHint:`<ratio>`,description:{"en-US":`Aspect ratio (e.g. 16:9, 9:16, 1:1)`,"zh-CN":`宽高比(例如 16:9、9:16、1:1)`}},duration:{type:`number`,valueHint:`<seconds>`,description:{"en-US":`Video duration in seconds (default: 5)`,"zh-CN":`视频时长,单位为秒(默认:5)`}},promptExtend:{type:`boolean`,valueHint:`<bool>`,description:fn},watermark:{type:`boolean`,valueHint:`<bool>`,description:hn},seed:{type:`number`,valueHint:`<n>`,description:{"en-US":`Random seed for reproducible generation`,"zh-CN":`用于复现生成结果的随机种子`}},download:{type:`string`,valueHint:`<path>`,description:{"en-US":`Save video to file on completion`,"zh-CN":`完成后将视频保存到文件`}},...e,...n,pollInterval:{type:`number`,valueHint:`<seconds>`,description:{"en-US":`Polling interval when waiting (default: 5)`,"zh-CN":`等待任务时的轮询间隔(默认:5 秒)`}}},exampleArgs:[{"en-US":`--prompt "A person reading a book, static shot"`,"zh-CN":`--prompt "一个人正在读书,固定镜头"`},{"en-US":`--prompt "Ocean waves at sunset." --download sunset.mp4`,"zh-CN":`--prompt "日落时的海浪。" --download sunset.mp4`},{"en-US":`--image https://example.com/cat.png --prompt "Make the cat in the scene move"`,"zh-CN":`--image https://example.com/cat.png --prompt "让画面中的猫动起来"`},{"en-US":`--prompt "Mountain landscape" --resolution 720P --duration 5`,"zh-CN":`--prompt "山地景观" --resolution 720P --duration 5`},{"en-US":`--prompt "A cat playing with a ball" --watermark false`,"zh-CN":`--prompt "一只正在玩球的猫" --watermark false`}],async run(e){let{settings:n,flags:r}=e,i=r.prompt,a=r.model||(r.image?n.defaultImageToVideoModel||`happyhorse-1.1-i2v`:n.defaultVideoModel||`happyhorse-1.1-t2v`),o=T(n.output),s=r.image,l=r.lastFrame,u;s&&(u=await e.client.resolveImageInput(s,a));let d;l&&(d=await e.client.resolveImageInput(l,a));let f=!!(u&&d),p=Wt(r.watermark),m=Bt(r.promptExtend,void 0,`prompt-extend`),h={model:a,input:{prompt:i,negative_prompt:r.negativePrompt||void 0,...f?{first_frame_url:u,last_frame_url:d}:u?/wan[x]?2\.[1-6]/i.test(a)?{img_url:u}:{media:[{type:`first_frame`,url:u}]}:{}},parameters:{resolution:r.resolution||void 0,ratio:r.ratio||void 0,duration:r.duration||void 0,prompt_extend:m,watermark:p,seed:r.seed}};if(n.dryRun){let e=h;if(f)e={...h,input:{...h.input,first_frame_url:D(u??``),last_frame_url:D(d??``)}};else if(u){let t=D(u);e={...h,input:{...h.input,.../wan[x]?2\.[1-6]/i.test(a)?{img_url:t}:{media:[{type:`first_frame`,url:t}]}}}}A({request:e},o);return}let g=(await Rn(On(r),n,()=>e.client.requestJson({path:f?Je():cn(),method:`POST`,body:h,async:!0}),`tasks`)).map(e=>e.output.task_id);if(n.quiet||process.stderr.write(`[Model: ${a}]\n`),r.async){A(g.length===1?{task_id:g[0]}:{task_ids:g},o);return}let _=r.pollInterval??5,v=g.map(t=>{let r=e.client.url($t(t));return Pn(e.client,n,{url:r,intervalSec:_,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}})}),y=await Promise.all(v),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.`,c.GENERAL);if(r.download){let e=r.download,{size:t}=await Sn(b[0].videoUrl,e,{quiet:n.quiet});n.quiet?k(e):A({task_id:b[0].taskId,video_url:b[0].videoUrl,status:`SUCCEEDED`,saved:e,size:Dn(t)},o);return}let x=Ut(n,{subDir:`videos`}),{join:S}=await import(`path`),C=[];await Promise.all(b.map(async({taskId:e,videoUrl:t})=>{let r=S(x,`${e}.mp4`);await Sn(t,r,{quiet:n.quiet}),C.push({task_id:e,video_url:t,saved:r})})),C.length===1?A(C[0],o):A({videos:C,total:C.length},o)}}),ta=w({description:{"en-US":`Edit a video with happyhorse-1.0-video-edit (style transfer, object replacement, etc.)`,"zh-CN":`使用 happyhorse-1.0-video-edit 编辑视频(风格转换、对象替换等)`},auth:`apiKey`,usageArgs:`--video <url> --prompt <text> [flags]`,flags:{model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Model ID (default: happyhorse-1.0-video-edit)`,"zh-CN":`模型 ID(默认:happyhorse-1.0-video-edit)`}},video:{type:`string`,valueHint:`<url>`,description:{"en-US":`Input video URL or local file (mp4/mov, 2-10s)`,"zh-CN":`输入视频 URL 或本地文件(mp4/mov,2–10 秒)`},required:!0},prompt:{type:`string`,valueHint:`<text>`,description:{"en-US":`Edit instruction (e.g. "Convert the scene to a claymation style")`,"zh-CN":`编辑指令(例如“将场景转换为黏土动画风格”)`}},refImage:{type:`string`,valueHint:`<url>`,description:{"en-US":`Reference image URL (up to 4, comma-separated)`,"zh-CN":`参考图片 URL(最多 4 个,以逗号分隔)`}},negativePrompt:{type:`string`,valueHint:`<text>`,description:{"en-US":`Negative prompt to exclude unwanted content`,"zh-CN":`负向提示词,用于排除不需要的内容`}},resolution:{type:`string`,valueHint:`<res>`,description:{"en-US":`Resolution: 720P or 1080P (default: 1080P)`,"zh-CN":`分辨率:720P 或 1080P(默认:1080P)`}},ratio:{type:`string`,valueHint:`<ratio>`,description:{"en-US":`Aspect ratio (16:9, 9:16, 1:1, 4:3, 3:4)`,"zh-CN":`宽高比(16:9、9:16、1:1、4:3、3:4)`}},duration:{type:`number`,valueHint:`<seconds>`,description:{"en-US":`Output video duration in seconds (2-10)`,"zh-CN":`输出视频时长,单位为秒(2–10)`}},audioSetting:{type:`string`,valueHint:`<mode>`,description:{"en-US":`Audio: auto (default) or origin (keep original)`,"zh-CN":`音频:auto(默认)或 origin(保留原音频)`},choices:[`auto`,`origin`]},promptExtend:{type:`boolean`,valueHint:`<bool>`,description:fn},watermark:{type:`boolean`,valueHint:`<bool>`,description:hn},seed:{type:`number`,valueHint:`<n>`,description:{"en-US":`Random seed for reproducible generation`,"zh-CN":`用于复现生成结果的随机种子`}},download:{type:`string`,valueHint:`<path>`,description:{"en-US":`Save video to file on completion`,"zh-CN":`完成后将视频保存到文件`}},...e,...n,pollInterval:{type:`number`,valueHint:`<seconds>`,description:{"en-US":`Polling interval when waiting (default: 15)`,"zh-CN":`等待任务时的轮询间隔(默认:15 秒)`}}},exampleArgs:[{"en-US":`--video https://example.com/input.mp4 --prompt "Convert the entire scene to claymation style"`,"zh-CN":`--video https://example.com/input.mp4 --prompt "将整个场景转换为黏土动画风格"`},{"en-US":`--video https://example.com/input.mp4 --prompt "Replace the outfit with the style shown in the image" --ref-image https://example.com/clothes.png`,"zh-CN":`--video https://example.com/input.mp4 --prompt "将服装替换为参考图片中的款式" --ref-image https://example.com/clothes.png`},{"en-US":`--video https://example.com/input.mp4 --prompt "Convert to anime style" --resolution 720P --download output.mp4`,"zh-CN":`--video https://example.com/input.mp4 --prompt "转换为动漫风格" --resolution 720P --download output.mp4`},{"en-US":`--video https://example.com/input.mp4 --prompt "Put clothes on the kitten in the video" --watermark false`,"zh-CN":`--video https://example.com/input.mp4 --prompt "给视频中的小猫穿上衣服" --watermark false`}],async run(e){let{settings:n,flags:r}=e,i=r.video,a=r.prompt,o=r.model||`happyhorse-1.0-video-edit`,s=T(n.output),l=[{type:`video`,url:await e.client.uploadFile(i,o)}],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,o);l.push({type:`reference_image`,url:t})}}let d=Bt(r.promptExtend,void 0,`prompt-extend`),f=Wt(r.watermark),p={model:o,input:{prompt:a||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){A({request:p},s);return}let m=(await Rn(On(r),n,()=>e.client.requestJson({path:cn(),method:`POST`,body:p,async:!0}),`tasks`)).map(e=>e.output.task_id);if(n.quiet||(process.stderr.write(`[Model: ${o}]\n`),process.stderr.write(`Note: Video editing typically takes 5-8 minutes. Please be patient.
|
|
27
|
+
`)),r.async){A(m.length===1?{task_id:m[0]}:{task_ids:m},s);return}let h=r.pollInterval??15,g=Math.max(n.timeout,600),_=await Promise.all(m.map(t=>Pn(e.client,n,{url:e.client.url($t(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.`,c.GENERAL);if(r.download){let e=r.download,{size:t}=await Sn(v[0].videoUrl,e,{quiet:n.quiet});n.quiet?k(e):A({task_id:v[0].taskId,video_url:v[0].videoUrl,status:`SUCCEEDED`,saved:e,size:Dn(t)},s);return}let y=await import(`path`),b=Ut(n,{subDir:`videos`}),x=[];await Promise.all(v.map(async({taskId:e,videoUrl:t})=>{let r=y.join(b,`${e}.mp4`);await Sn(t,r,{quiet:n.quiet}),x.push({task_id:e,video_url:t,saved:r})})),x.length===1?A(x[0],s):A({videos:x,total:x.length},s)}}),na=w({description:{"en-US":`Reference-to-video generation (happyhorse-1.1-r2v / wan2.6-r2v): multi-subject, multi-shot with voice`,"zh-CN":`参考生视频(happyhorse-1.1-r2v / wan2.6-r2v):支持多主体、多镜头和语音`},auth:`apiKey`,usageArgs:`--prompt <text> --image <url>... [--ref-video <url>...] [flags]`,flags:{model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Model ID (default: happyhorse-1.1-r2v)`,"zh-CN":`模型 ID(默认:happyhorse-1.1-r2v)`}},prompt:{type:`string`,valueHint:`<text>`,description:{"en-US":`Video description with reference markers (image1, video1, etc.)`,"zh-CN":`包含引用标记的视频描述(image1、video1 等)`},required:!0},image:{type:`array`,valueHint:`<url>`,description:{"en-US":`Reference image URL or local file (repeatable for multiple subjects)`,"zh-CN":`参考图片 URL 或本地文件(多个主体时可重复)`}},refVideo:{type:`array`,valueHint:`<url>`,description:{"en-US":`Reference video URL or local file (repeatable)`,"zh-CN":`参考视频 URL 或本地文件(可重复)`}},imageVoice:{type:`array`,valueHint:`<url>`,description:{"en-US":`Voice URL for corresponding image (pairs by position)`,"zh-CN":`对应图片的语音 URL(按位置配对)`}},videoVoice:{type:`array`,valueHint:`<url>`,description:{"en-US":`Voice URL for corresponding ref-video (pairs by position)`,"zh-CN":`对应参考视频的语音 URL(按位置配对)`}},resolution:{type:`string`,valueHint:`<res>`,description:{"en-US":`Resolution: 720P or 1080P (default: 1080P)`,"zh-CN":`分辨率:720P 或 1080P(默认:1080P)`}},ratio:{type:`string`,valueHint:`<ratio>`,description:{"en-US":`Aspect ratio (16:9, 9:16, 1:1)`,"zh-CN":`宽高比(16:9、9:16、1:1)`}},duration:{type:`number`,valueHint:`<seconds>`,description:{"en-US":`Video duration in seconds (default: 5)`,"zh-CN":`视频时长,单位为秒(默认:5)`}},promptExtend:{type:`boolean`,valueHint:`<bool>`,description:fn},watermark:{type:`boolean`,valueHint:`<bool>`,description:hn},seed:{type:`number`,valueHint:`<n>`,description:{"en-US":`Random seed for reproducible generation`,"zh-CN":`用于复现生成结果的随机种子`}},download:{type:`string`,valueHint:`<path>`,description:{"en-US":`Save video to file on completion`,"zh-CN":`完成后将视频保存到文件`}},...e,...n,pollInterval:{type:`number`,valueHint:`<seconds>`,description:{"en-US":`Polling interval when waiting (default: 15)`,"zh-CN":`等待任务时的轮询间隔(默认:15 秒)`}}},exampleArgs:[{"en-US":`--prompt "Image1 running on the grass" --image person.jpg`,"zh-CN":`--prompt "图片 1 中的人物在草地上奔跑" --image person.jpg`},{"en-US":`--prompt "Video 1 plays guitar, Image 1 walks over" --ref-video scene.mp4 --image person.jpg`,"zh-CN":`--prompt "视频 1 中的人物弹吉他,图片 1 中的人物走过来" --ref-video scene.mp4 --image person.jpg`},{"en-US":`--prompt "Image 1 speaks" --image person.jpg --image-voice voice.mp3 --resolution 1080P`,"zh-CN":`--prompt "图片 1 中的人物说话" --image person.jpg --image-voice voice.mp3 --resolution 1080P`},{"en-US":`--prompt "Image 1 and Image 2 have a conversation" --image a.jpg --image b.jpg --image-voice va.mp3 --image-voice vb.mp3`,"zh-CN":`--prompt "图片 1 和图片 2 中的人物进行对话" --image a.jpg --image b.jpg --image-voice va.mp3 --image-voice vb.mp3`},{"en-US":`--prompt "Image 1 drinks water" --image person.jpg --watermark false`,"zh-CN":`--prompt "图片 1 中的人物喝水" --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,a=r.image||[],o=r.refVideo||[],s=r.imageVoice||[],l=r.videoVoice||[],u=r.model||n.defaultReferenceToVideoModel||`happyhorse-1.1-r2v`,d=T(n.output),f=[];for(let t=0;t<a.length;t++){let n={type:`reference_image`,url:await e.client.resolveImageInput(a[t],u)};s[t]&&(n.reference_voice=await e.client.uploadFile(s[t],u)),f.push(n)}for(let t=0;t<o.length;t++){let n={type:`reference_video`,url:await e.client.uploadFile(o[t],u)};l[t]&&(n.reference_voice=await e.client.uploadFile(l[t],u)),f.push(n)}let p=Bt(r.promptExtend,void 0,`prompt-extend`),m=Wt(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){A({request:{...h,input:{...h.input,media:h.input.media.map(e=>({...e,url:D(e.url),reference_voice:e.reference_voice?D(e.reference_voice):void 0}))}}},d);return}let g=(await Rn(On(r),n,()=>e.client.requestJson({path:cn(),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.
|
|
28
|
+
`)),r.async){A(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=>Pn(e.client,n,{url:e.client.url($t(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.`,c.GENERAL);if(r.download){let e=r.download,{size:t}=await Sn(b[0].videoUrl,e,{quiet:n.quiet});n.quiet?k(e):A({task_id:b[0].taskId,video_url:b[0].videoUrl,status:`SUCCEEDED`,saved:e,size:Dn(t)},d);return}let{join:x}=await import(`path`),S=Ut(n,{subDir:`videos`}),C=[];await Promise.all(b.map(async({taskId:e,videoUrl:t})=>{let r=x(S,`${e}.mp4`);await Sn(t,r,{quiet:n.quiet}),C.push({task_id:e,video_url:t,saved:r})})),C.length===1?A(C[0],d):A({videos:C,total:C.length},d)}}),ra=w({description:{"en-US":`Query async task status`,"zh-CN":`查询异步任务状态`},auth:`apiKey`,usageArgs:`--task-id <id>`,flags:{taskId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Async task ID`,"zh-CN":`异步任务 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=T(t.output);if(t.dryRun){A({task_id:r},i);return}let a=await e.client.requestJson({path:$t(r)});if(t.quiet){k(a.output.task_status);return}A({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)}}),ia=w({description:{"en-US":`Download a completed video by task ID`,"zh-CN":`通过任务 ID 下载已完成的视频`},auth:`apiKey`,usageArgs:`--task-id <id> --out <path>`,flags:{taskId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Task ID to download from`,"zh-CN":`要下载的任务 ID`},required:!0},out:{type:`string`,valueHint:`<path>`,description:{"en-US":`Output file path`,"zh-CN":`输出文件路径`},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,a=r.out,o=T(n.output);if(n.dryRun){A({task_id:i,action:`download`,out:a},o);return}let s=await e.client.requestJson({path:$t(i)});if(s.output.task_status!==`SUCCEEDED`)throw new t(`Task is not complete (status: ${s.output.task_status}).`,c.GENERAL,`Wait for the task to complete before downloading.`);let l=s.output.video_url||s.output.results&&s.output.results[0]?.url;if(!l)throw new t(`No download URL available for this task.`,c.GENERAL);let{size:u}=await Sn(l,a,{quiet:n.quiet});if(n.quiet){k(a);return}A({saved:a,size:Dn(u)},o)}});const aa=new Set([`.mp4`,`.mov`,`.avi`,`.mkv`,`.webm`,`.flv`,`.wmv`]);function oa(e){let t=nr(e).toLowerCase().split(`?`)[0];return!!(aa.has(t)||/\.(mp4|mov|avi|mkv|webm|flv|wmv)(\?|$)/i.test(e))}async function sa(e){return e.startsWith(`data:`)||e.startsWith(`http://`)||e.startsWith(`https://`)||e.startsWith(`oss://`)?e:Ye(e)}var ca=w({description:{"en-US":`Describe an image or video using Qwen-VL`,"zh-CN":`使用 Qwen-VL 描述图片或视频`},auth:`apiKey`,usageArgs:`--image <path-or-url> [--video <url>] [--prompt <text>]`,flags:{image:{type:`string`,valueHint:`<path-or-url>`,description:{"en-US":`Local image path or URL`,"zh-CN":`本地图片路径或 URL`}},video:{type:`array`,valueHint:`<url>`,description:{"en-US":`Video file URL or local path (mp4/mov/avi/mkv/webm)`,"zh-CN":`视频文件 URL 或本地路径(mp4/mov/avi/mkv/webm)`}},prompt:{type:`string`,valueHint:`<text>`,description:{"en-US":`Question about the content (default: auto-detected)`,"zh-CN":`针对内容的问题(默认:自动识别)`}},model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Vision model (default: qwen3-vl-plus)`,"zh-CN":`视觉模型(默认:qwen3-vl-plus)`}}},exampleArgs:[`--image photo.jpg`,{"en-US":`--image https://example.com/photo.jpg --prompt "What breed is this dog?"`,"zh-CN":`--image https://example.com/photo.jpg --prompt "这只狗是什么品种?"`},{"en-US":`--video https://example.com/video.mp4 --prompt "Summarize the video content"`,"zh-CN":`--video https://example.com/video.mp4 --prompt "总结视频内容"`},`--video ./local-video.mp4`,{"en-US":`--image photo.png --prompt "Extract the text" --model qwen3-vl-plus`,"zh-CN":`--image photo.png --prompt "提取文字" --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,a=r.video??[],o=r.model||(e.client.usesTokenPlanEndpoint()?n.defaultTextModel:void 0)||`qwen3-vl-plus`;i&&oa(i)&&(a.push(i),i=void 0);let s=a.length>0?`Describe the video.`:`Describe the image.`,l=r.prompt||s,u=T(n.output);if(n.dryRun){A({request:{prompt:l,image:i?D(i):void 0,video:a.length?a.map(D):void 0,model:o}},u);return}let d=[];if(a.length>0)for(let n of a){let r=n;if(Ze(n)){if(!Jn(n))throw new t(`Video file not found: ${n}`,c.USAGE);r=await e.client.uploadFile(n,o)}d.push({type:`video_url`,video_url:{url:r}})}if(i){let t=await sa(i),n=t;Ze(i)&&t.startsWith(`data:`)&&Qn(i).size>5*1024*1024&&(n=await e.client.resolveImageInput(i,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 e.client.requestJson({path:oe(),method:`POST`,body:f}),m=p.choices?.[0]?.message?.content;if(u!==`text`){A(p,u);return}k(m||``)}});const la=[`language`,`base_url`,`output`,`output_dir`,`timeout`,`api_key`,`access_token`,`access_key_id`,`access_key_secret`,`security_token`,`default_text_model`,`default_video_model`,`default_image_to_video_model`,`default_reference_to_video_model`,`default_image_model`,`default_speech_model`,`default_omni_model`,`workspace_id`],ua=new Set([`api_key`,`access_token`,`access_key_id`,`access_key_secret`,`security_token`]),da=[`console_site`,`console_region`,`console_switch_agent`,`telemetry`],fa=[...la,...da],pa={language:[..._],output:[`text`,`json`],console_site:[`domestic`,`international`]},ma=new Set([`telemetry`]),ha={default_text_model:`qwen3.8-max`,default_image_model:`qwen-image-3.0`,default_video_model:`happyhorse-1.1-t2v`,default_speech_model:`cosyvoice-v3-flash`,default_omni_model:`qwen3.5-omni-plus`},ga={default_text_model:[{id:`qwen3.8-max`,role:`text/chat default`},{id:`qwen3-coder-plus`,role:`coding-oriented (agent config)`},{id:`qwen-flash`,role:`fast · advisor ranking`},{id:`qwen3.6-flash`,role:`fast · advisor intent`}],default_image_model:[{id:`qwen-image-3.0`,role:`image/generate default · sync`},{id:`qwen-image-2.0`,role:`image/generate · sync`},{id:`qwen-image-max`,role:`image/generate · sync`},{id:`qwen-image-edit-2.0`,role:`image/edit · sync`},{id:`wanx2.x`,role:`image/generate · async series`}],default_video_model:[{id:`happyhorse-1.1-t2v`,role:`video/generate default · text-to-video`},{id:`happyhorse-1.1-i2v`,role:`video/generate · image-to-video`}],default_speech_model:[{id:`cosyvoice-v3-flash`,role:`speech/synthesize (TTS) default`},{id:`fun-asr`,role:`speech/recognize (ASR)`}],default_omni_model:[{id:`qwen3.5-omni-plus`,role:`omni/chat default`},{id:`qwen3-vl-plus`,role:`vision/describe · multimodal input`}]},_a={"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`,"security-token":`security_token`,"default-text-model":`default_text_model`,"default-video-model":`default_video_model`,"default-image-to-video-model":`default_image_to_video_model`,"default-reference-to-video-model":`default_reference_to_video_model`,"default-image-model":`default_image_model`,"default-speech-model":`default_speech_model`,"default-omni-model":`default_omni_model`,"workspace-id":`workspace_id`};function va(e){return _a[e]||e}function ya(e,n){let r=va(e);if(!la.includes(r))throw new t(`Invalid config key "${e}". Valid keys: ${la.join(`, `)}`,c.USAGE);if(r===`language`&&!_.includes(n))throw new t(`Invalid language "${n}". Valid values: ${_.join(`, `)}`,c.USAGE);if(r===`output`&&![`text`,`json`].includes(n))throw new t(`Invalid output format "${n}". Valid values: text, json`,c.USAGE);if(r===`timeout`){let e=Number(n);if(isNaN(e)||e<=0)throw new t(`Invalid timeout "${n}". Must be a positive number.`,c.USAGE);return e}return r===`base_url`?wt(n):n}function ba(e,n){let r=va(e);if(la.includes(r))return ya(e,n);if(r===`console_site`){if(![`domestic`,`international`].includes(n))throw new t(`Invalid console_site "${n}". Valid values: domestic, international`,c.USAGE);return n}if(r===`console_region`)return n;if(r===`console_switch_agent`){let e=Number(n);if(!Number.isFinite(e)||e<=0)throw new t(`Invalid console_switch_agent "${n}". Must be a positive number.`,c.USAGE);return e}if(r===`telemetry`){if(n!==`true`&&n!==`false`)throw new t(`Invalid telemetry "${n}". Valid values: true, false`,c.USAGE);return n===`true`}throw new t(`Invalid config key "${e}". Valid keys: ${fa.join(`, `)}`,c.USAGE)}var xa=w({description:{"en-US":`Display current configuration`,"zh-CN":`显示当前配置`},auth:`none`,exampleArgs:[``,`--output json`],async run(e){let{settings:t,client:n}=e,r=e.configStore,i=r.read(),o=T(t.output),s={...i,language:i.language??a,base_url:n.baseUrl,output:t.output,timeout:t.timeout,config:t.configName??`default`,config_file:r.path};for(let e of ua)typeof s[e]==`string`&&(s[e]=pt(s[e]));A(s,o)}}),Sa=w({description:{"en-US":`Set a config value`,"zh-CN":`设置配置项`},auth:`none`,usageArgs:`--key <key> --value <value>`,flags:{key:{type:`string`,valueHint:`<key>`,description:{"en-US":`Config key (language, base_url, output, output_dir, timeout, api_key, access_token, access_key_id, access_key_secret, security_token, default_*_model, workspace_id)`,"zh-CN":`配置项名称(language、base_url、output、output_dir、timeout、api_key、access_token、access_key_id、access_key_secret、security_token、default_*_model、workspace_id)`},required:!0},value:{type:`string`,valueHint:`<value>`,description:{"en-US":`Value to set`,"zh-CN":`要设置的值`},required:!0}},exampleArgs:[`--key language --value zh-CN`,`--key output --value json`,`--key timeout --value 600`,`--key base_url --value https://dashscope.aliyuncs.com`],async run(e){let{settings:t,flags:n}=e,r=n.key,i=n.value,a=va(r),o=ya(r,i),s=T(t.output);if(t.dryRun){A({would_set:{[a]:o},config:t.configName??`default`,config_file:e.configStore.path},s);return}if(await e.configStore.write({[a]:o}),!t.quiet){let n=ua.has(a)?pt(String(o)):o;A({[a]:n,config:t.configName??`default`,config_file:e.configStore.path},s)}}}),Ca=w({description:{"en-US":`List config profiles and show the active profile`,"zh-CN":`列出配置 Profile 并显示当前激活项`},auth:`none`,exampleArgs:[``,`--output json`],async run(e){let t=e.configStore.profiles(),n=[`default`,...Object.keys(t.named).sort()],r=T(e.settings.output);if(r===`json`){A({active_config:t.active,profiles:n,config_file:e.configStore.path},r);return}let i=Math.max(4,...n.map(e=>e.length));k(`${`NAME`.padEnd(i)} ACTIVE`);for(let e of n)k(`${e.padEnd(i)} ${e===t.active?`*`:``}`)}}),wa=w({description:{"en-US":`Set the active config profile`,"zh-CN":`设置当前激活的配置 Profile`},auth:`none`,usageArgs:`--name <name>`,flags:{name:{type:`string`,valueHint:`<name>`,description:{"en-US":`Existing profile name, or default`,"zh-CN":`已有 Profile 名称,或 default`},required:!0}},exampleArgs:[`--name token-plan`,`--name default`],async run(e){let t=T(e.settings.output);if(e.settings.dryRun){A({would_activate:e.configStore.validateActivation(e.flags.name),config_file:e.configStore.path},t);return}let n=await e.configStore.activate(e.flags.name);e.settings.quiet||A({active_config:n,config_file:e.configStore.path},t)}});const Ta=[[`Config - Alibaba Cloud Model Studio CLI`,`配置 - 阿里云百炼 CLI`],[`The login was not completed in time. Click "Log in" to try again.`,`登录未能及时完成。请点击“登录”重试。`],[`No connected agent can accept tasks yet. Install and connect qwen-code (or another supported agent) first, and make sure its CLI is on your PATH.`,`当前没有可接收任务的已连接 Agent。请先安装并连接 qwen-code(或其他受支持的 Agent),并确保其 CLI 位于 PATH 中。`],[`Complete a few steps to check your local environment and finish first-time setup: sign in to Bailian, connect a local coding agent, and run your first task. Each circle turns from gray to green as you go.`,`完成以下步骤以检查本地环境并完成首次配置:登录百炼、连接本地编程 Agent,并运行第一个任务。完成后,每个圆点会由灰色变为绿色。`],[`Pick a scenario to dispatch a preset task to a connected local coding agent, running in a new terminal. Tasks run in the directory where <code style="font-family:var(--mono)">bl config ui</code> was started.`,`选择一个场景,将预设任务发送给已连接的本地编程 Agent,并在新终端中运行。任务会在启动 <code style="font-family:var(--mono)">bl config ui</code> 的目录中执行。`],[`Pick a scenario to dispatch a preset task to a connected local coding agent, running in a new terminal. Tasks run in the directory where `,`选择一个场景,将预设任务发送给已连接的本地编程 Agent,并在新终端中运行。任务会在启动 `],[` was started.`,` 的目录中执行。`],[`Credentials and default models. The active profile (marked with a star) is used by every bl command. Click a profile to edit its settings.`,`管理凭证和默认模型。所有 bl 命令都会使用带星标的已激活 Profile。点击 Profile 可编辑其设置。`],[`Agent skills discovered across every local agent module (~/.agents/skills plus each agent's skills folder). Installed via <code style="font-family:var(--mono)">npx skills add</code>.`,`展示从本地各 Agent 模块中发现的 Skill(~/.agents/skills 以及各 Agent 的 skills 目录),可通过 <code style="font-family:var(--mono)">npx skills add</code> 安装。`],[`Agent skills discovered across every local agent module (~/.agents/skills plus each agent's skills folder). Installed via `,`展示从本地各 Agent 模块中发现的 Skill(~/.agents/skills 以及各 Agent 的 skills 目录),可通过 `],[`Media that bl writes into the output directory, grouped by type (images, videos, audio, files) and generation time.`,`bl 写入输出目录的媒体文件,按类型(图片、视频、音频、文件)和生成时间展示。`],[`Frameworks bl can configure. "Connected" means the bailian-cli provider is wired into that agent.`,`bl 可以配置的编程 Agent。"已连接"表示该 Agent 已接入 bailian-cli provider。`],[`Model Context Protocol servers declared in your local coding-agent configs.`,`本地编程 Agent 配置中声明的 Model Context Protocol 服务器。`],[`Create a named profile with its own credentials and default models.`,`创建一个拥有独立凭证和默认模型的命名 Profile。`],[`Inputs become fillable fields when dispatching. Reference each one in the prompt as {{key}}.`,`任务发送时,输入项会显示为可填写字段。请在提示词中使用 {{key}} 引用对应输入。`],[`The .zip must contain a SKILL.md at its root or inside a single top-level folder.`,`.zip 根目录或唯一的顶层目录中必须包含 SKILL.md。`],[`The active profile is used by every bl command.`,`所有 bl 命令都会使用已激活的 Profile。`],[`Delete profile "`,`删除 Profile“`],[`"? This permanently removes its credentials and default models.`,`”?这会永久删除其中的凭证和默认模型。`],[`Delete asset "`,`删除资产“`],[`"? This removes the file from disk.`,`”?这会从磁盘中删除该文件。`],[`MCP servers configured in Claude Code, Codex, Qwen Code or OpenCode will appear here.`,`在 Claude Code、Codex、Qwen Code 或 OpenCode 中配置的 MCP 服务器会显示在这里。`],[`Assets from <code>bl image</code>, <code>bl video</code>, <code>bl speech</code> and <code>bl omni</code> will appear here.`,`通过 <code>bl image</code>、<code>bl video</code>、<code>bl speech</code> 和 <code>bl omni</code> 生成的资产会显示在这里。`],[`Remote agents loaded from a URL will appear here.`,`通过 URL 加载的远程 Agent 会显示在这里。`],[`The CLI for this agent was not found on your PATH — install it before launching`,`未在 PATH 中找到该 Agent 的 CLI,请先安装再启动`],[`Connect this agent to bailian-cli before launching`,`请先将该 Agent 连接到 bailian-cli 再启动`],[`Install this agent before launching`,`请先安装该 Agent 再启动`],[`Open a new terminal and start this agent`,`在新终端中启动该 Agent`],[`Open the config file with the system default app`,`使用系统默认应用打开配置文件`],[`Task sent to `,`任务已发送至 `],[`. Check the newly opened terminal window.`,`。请查看新打开的终端窗口。`],[`Please enter a profile name.`,`请输入 Profile 名称。`],[`Only letters, numbers, - and _ are allowed.`,`仅允许使用字母、数字、- 和 _。`],[`"default" is reserved for the top-level profile.`,`“default”保留用于顶层 Profile。`],[`A profile named "`,`名为“`],[`" already exists.`,`”的 Profile 已存在。`],[`Saved, but activation failed: `,`已保存,但激活失败:`],[`Could not read runtime environment info.`,`无法读取运行环境信息。`],[`Runtime Node <code>`,`运行时 Node <code>`],[`</code> · platform <code>`,`</code> · 平台 <code>`],[`Signed in: `,`已登录:`],[`Connected: `,`已连接:`],[`All agents (~/.agents/skills)`,`所有 Agent(~/.agents/skills)`],[`Optional — folder name (defaults to the archive folder)`,`可选 — 文件夹名称(默认使用压缩包中的文件夹名称)`],[`Skill name (optional)`,`Skill 名称(可选)`],[`Skill package (.zip)`,`Skill 包(.zip)`],[`Please choose a .zip file.`,`请选择 .zip 文件。`],[`Install with <code>npx skills add modelstudioai/cli --all -g</code>`,`使用 <code>npx skills add modelstudioai/cli --all -g</code> 安装`],[`Skill "`,`Skill“`],[`MCP server "`,`MCP 服务器“`],[`" installed (`,`”已安装(`],[` files) to `,` 个文件),位置:`],[`" was updated.`,`”已更新。`],[`" was added to `,`”已添加至 `],[`Remove "`,`移除“`],[`" from `,`”(来源:`],[`? This rewrites the source config file.`,`)?此操作会重写来源配置文件。`],[`Could not delete this server.`,`无法删除该服务器。`],[`Delete MCP server?`,`删除 MCP 服务器?`],[`Config must be a JSON object.`,`配置必须是 JSON 对象。`],[`Invalid JSON: `,`无效的 JSON:`],[`Please enter a server name.`,`请输入服务器名称。`],[`No remote agents yet.`,`暂无远程 Agent。`],[`No agents in this category.`,`该分类下暂无 Agent。`],[`No agents match "`,`没有匹配“`],[`bailian-cli is not wired into this agent yet.`,`该 Agent 尚未连接 bailian-cli。`],[`This agent is not installed yet.`,`该 Agent 尚未安装。`],[`No scenarios in this category.`,`该分类下暂无场景。`],[`No scenarios match "`,`没有匹配“`],[`Click to edit this scenario`,`点击编辑此场景`],[`Dispatch this task to a local agent`,`将此任务发送至本地 Agent`],[`No connected agent available`,`没有可用的已连接 Agent`],[`Please fill in: `,`请填写:`],[`Input key "`,`输入键“`],[`" may only use letters, digits, underscore.`,`”只能使用字母、数字和下划线。`],[`Duplicate input key: `,`输入键重复:`],[`Title is required.`,`标题为必填项。`],[`Prompt template is required.`,`提示词模板为必填项。`],[`No assets match "`,`没有匹配“`],[`Toggle sort by generation time`,`切换生成时间排序`],[`↓ Newest first`,`↓ 最新优先`],[`↑ Oldest first`,`↑ 最早优先`],[`View details — `,`查看详情 — `],[`Available `,`可用的 `],[` models · click to use`,` 模型 · 点击使用`],[`Applies to <code>bl video generate</code> only (text/image-to-video). `,`仅适用于 <code>bl video generate</code>(文生视频/图生视频)。`],[`<code>bl video ref</code> (multi-image) and <code>bl video edit</code> keep their own `,`<code>bl video ref</code>(多图)和 <code>bl video edit</code> 仍使用各自的`],[`fixed models — pass <code>--model</code> to override those per run.`,`固定模型;可在每次运行时通过 <code>--model</code> 覆盖。`],[`No skills match "`,`没有匹配“`],[`No MCP servers match "`,`没有匹配“`],[`Install to`,`安装到`],[`Transport / Source`,`传输方式 / 来源`],[`Target agent config`,`目标 Agent 配置`],[`Server name`,`服务器名称`],[`Quick launch`,`快速启动`],[`Config files`,`配置文件`],[`Environment check`,`环境检查`],[`Edit preset scenario`,`编辑预设场景`],[`Edit scenario`,`编辑场景`],[`Save & Activate`,`保存并激活`],[`Are you sure?`,`确认执行此操作吗?`],[`Save failed`,`保存失败`],[`Create failed`,`创建失败`],[`Install failed`,`安装失败`],[`Launch failed`,`启动失败`],[`Dispatch failed`,`发送失败`],[`Delete failed`,`删除失败`],[`Created`,`已创建`],[`Dispatched`,`已发送`],[`Saved`,`已保存`],[`OK`,`确定`],[`Configuration`,`配置`],[`Settings`,`设置`],[`Status`,`状态`],[`Open`,`打开`],[`Remove`,`移除`],[`Show`,`显示`],[`Hide`,`隐藏`],[`All`,`全部`],[`Images`,`图片`],[`Videos`,`视频`],[`Files`,`文件`],[`Image`,`图片`],[`Video`,`视频`],[`Audio`,`音频`],[`File`,`文件`],[` files`,` 个文件`],[`MCPs`,`MCP 服务`],[`Coding`,`编程`],[`Generated`,`生成的`],[`API key`,`API 密钥`],[`Console gateway`,`控制台网关`],[`Account`,`账户`],[`(empty)`,`(空)`],[` (editable)`,`(可编辑)`],[` (missing)`,`(缺失)`],[`default (top-level)`,`default(顶层)`],[`This source is read-only here (its config is TOML). Edit it directly in `,`该来源在此处为只读(配置格式为 TOML)。请直接编辑:`],[`No connected local coding agent detected (e.g. qwen-code). Open the Agents page to install and connect one.`,`未检测到已连接的本地编程 Agent(例如 qwen-code)。请打开 Agent 页面进行安装和连接。`],[`Installed but not wired into bl: `,`已安装但尚未接入 bl:`],[`. Open the Agents page to finish connecting.`,`。请打开 Agent 页面完成连接。`],[`Finish the previous step first (connect a dispatchable agent), then come back to Playground to run your first scenario.`,`请先完成上一步(连接可接收任务的 Agent),再回到 Playground 运行第一个场景。`],[`Go to Playground, pick a scenario and click Run it to complete your first dispatch.`,`前往 Playground,选择一个场景并点击“运行”,完成首次任务发送。`],[`Sign in to the Bailian console to obtain credentials (opens a login page in your browser).`,`登录百炼控制台以获取凭证(将在浏览器中打开登录页面)。`],[`You have dispatched at least one task.`,`你已经成功发送过至少一个任务。`],[`Node 18 or newer is recommended.`,`建议使用 Node.js 18 或更高版本。`],[`Save & Activate`,`保存并激活`],[`Save scenario`,`保存场景`],[`Custom scenario`,`自定义场景`],[`+ Custom scenario`,`+ 自定义场景`],[`New profile`,`新建 Profile`],[`+ New profile`,`+ 新建 Profile`],[`Profile name`,`Profile 名称`],[`Target agent`,`目标 Agent`],[`Task to dispatch`,`要发送的任务`],[`Prompt template`,`提示词模板`],[`One-line description (optional)`,`一句话描述(可选)`],[`Use {{key}} placeholders for inputs`,`使用 {{key}} 作为输入占位符`],[`e.g. Translate docs to English`,`例如:将文档翻译成英文`],[`e.g. Image / Custom`,`例如:图像 / 自定义`],[`e.g. work, intl, test`,`例如:work、intl、test`],[`Search scenarios…`,`搜索场景…`],[`Search skills…`,`搜索 Skill…`],[`Search MCP servers…`,`搜索 MCP 服务器…`],[`Search agents…`,`搜索 Agent…`],[`Search assets…`,`搜索资产…`],[`Installed Skills`,`已安装的 Skill`],[`Coding Agents`,`编程 Agent`],[`Generated Assets`,`生成资产`],[`Get Started`,`开始使用`],[`Quick Start`,`快速开始`],[`Playground`,`Playground`],[`Extensions`,`扩展`],[`Workspace`,`工作区`],[`Skills`,`Skill`],[`Agents`,`Agent`],[`Assets`,`资产`],[`Config`,`配置`],[`Log in`,`登录`],[`Log out`,`退出登录`],[`Copy this URL`,`复制此链接`],[`QR code for this session URL`,`当前会话链接的二维码`],[`Collapse sidebar`,`收起侧边栏`],[`Expand sidebar`,`展开侧边栏`],[`Model Studio CLI home`,`百炼 CLI 首页`],[`Loading…`,`加载中…`],[`Delete profile`,`删除 Profile`],[`Delete asset`,`删除资产`],[`Open failed`,`打开失败`],[`Open locally`,`在本地打开`],[`View details`,`查看详情`],[`Jump backward 5 pages`,`向前跳转 5 页`],[`Jump forward 5 pages`,`向后跳转 5 页`],[`Items per page`,`每页数量`],[`No generated assets yet.`,`暂无生成资产。`],[`No assets in this category.`,`该分类下暂无资产。`],[`No skills installed.`,`尚未安装 Skill。`],[`No local MCP servers found.`,`未发现本地 MCP 服务器。`],[`No coding agents found.`,`未发现编程 Agent。`],[`No scenarios found.`,`未发现场景。`],[`Failed to load: `,`加载失败:`],[`Load failed: `,`加载失败:`],[`Save failed: `,`保存失败:`],[`Create failed: `,`创建失败:`],[`Install failed: `,`安装失败:`],[`Launch failed: `,`启动失败:`],[`Saving…`,`正在保存…`],[`Saved and activated.`,`已保存并激活。`],[`Saved.`,`已保存。`],[`Profile created and saved.`,`Profile 已创建并保存。`],[`Opening browser…`,`正在打开浏览器…`],[`Waiting for login…`,`等待登录…`],[`Signed in…`,`已登录…`],[`Login timed out`,`登录超时`],[`Authenticated`,`已认证`],[`Connect a local agent`,`连接本地 Agent`],[`Run your first task`,`运行第一个任务`],[`Sign in to Bailian`,`登录百炼`],[`Check local environment`,`检查本地环境`],[`Go to Playground`,`前往 Playground`],[`Go to Agents`,`前往 Agent`],[`Run it`,`运行`],[`Done`,`已完成`],[`Connected`,`已连接`],[`Not installed`,`未安装`],[`Installed`,`已安装`],[`Launching…`,`正在启动…`],[`Launched → `,`已启动 → `],[`Remote`,`远程`],[`Local`,`本地`],[`Add skill`,`添加 Skill`],[`+ Add skill`,`+ 添加 Skill`],[`Choose .zip file`,`选择 .zip 文件`],[`No file selected`,`未选择文件`],[`New MCP server`,`新建 MCP 服务器`],[`+ Add MCP`,`+ 添加 MCP`],[`Description`,`描述`],[`Installed in`,`安装位置`],[`Details`,`详情`],[`Type`,`类型`],[`Path`,`路径`],[`Scope`,`范围`],[`Title`,`标题`],[`Category`,`分类`],[`Inputs`,`输入项`],[`Add input`,`添加输入`],[`Create`,`创建`],[`Install`,`安装`],[`Delete`,`删除`],[`Cancel`,`取消`],[`Close`,`关闭`],[`Active`,`已激活`],[`Save`,`保存`],[`Copy`,`复制`],[`Copied`,`已复制`],[`show`,`显示`],[`hide`,`隐藏`],[`(unset)`,`(未设置)`],[` / page`,` / 页`]];function Ea(){return JSON.stringify([...Ta].sort(([e],[t])=>t.length-e.length)).replaceAll(`<`,`\\u003c`)}function Da(e,t){return e.replace(`<html lang="en">`,`<html lang="${t}">`).replace(`__BL_CONFIG_UI_LANGUAGE__`,t).replace(`__BL_CONFIG_UI_TRANSLATIONS__`,Ea())}function Oa(e){return Da(`<!doctype html>
|
|
33
29
|
<html lang="en">
|
|
34
30
|
<head>
|
|
35
31
|
<meta charset="utf-8" />
|
|
@@ -55,6 +51,7 @@ Omni output voices:
|
|
|
55
51
|
--t-lift: .3s cubic-bezier(.2,.7,.2,1); --t-fast: .15s ease;
|
|
56
52
|
}
|
|
57
53
|
* { box-sizing: border-box; }
|
|
54
|
+
html:not(.i18n-ready) body { visibility: hidden; }
|
|
58
55
|
body { margin: 0; font-family: var(--font); font-size: 14px; line-height: 1.5;
|
|
59
56
|
color: var(--ink); background: #fafafc; -webkit-font-smoothing: antialiased; }
|
|
60
57
|
#app { display: flex; min-height: 100vh; }
|
|
@@ -719,6 +716,8 @@ Omni output voices:
|
|
|
719
716
|
var token = new URLSearchParams(location.search).get('token') || '';
|
|
720
717
|
var KEYS = [], SECRETS = [], ENUMS = {}, BOOLEANS = [], FIELD_DEFAULTS = {}, MODEL_CATALOG = {}, DATA = { default: {}, named: {} }, CURRENT = '', ACTIVE = 'default';
|
|
721
718
|
var loaded = { skills: false, mcp: false, agents: false, assets: false, playground: false, start: false };
|
|
719
|
+
var UI_LANGUAGE = '__BL_CONFIG_UI_LANGUAGE__';
|
|
720
|
+
var UI_TRANSLATIONS = __BL_CONFIG_UI_TRANSLATIONS__;
|
|
722
721
|
var SCENARIOS = [], BUILTIN_SCENARIOS = [], DISPATCH_AGENTS = [], SCN_Q = '', SCN_FILTER = 'all', SCN_PAGE = 1, DISPATCH_SCN = null;
|
|
723
722
|
var ASSETS = [], ASSET_FILTER = 'all', ASSET_SORT = 'new', ASSET_Q = '', ASSET_PAGE = 1;
|
|
724
723
|
var AGENTS = [], AGENT_FILTER = 'all', AGENT_Q = '', AGENT_PAGE = 1;
|
|
@@ -742,6 +741,67 @@ Omni output voices:
|
|
|
742
741
|
// Signed-in avatar photo. The generated colour + person icon stay as the
|
|
743
742
|
// background fallback while the image loads or if it fails.
|
|
744
743
|
var AVATAR_URL = 'https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg';
|
|
744
|
+
var UI_STATIC_COPY = [];
|
|
745
|
+
var UI_DOCUMENT_TITLE = document.title;
|
|
746
|
+
function translateUiText(value) {
|
|
747
|
+
var text = value == null ? '' : String(value);
|
|
748
|
+
if (UI_LANGUAGE !== 'zh-CN') return text;
|
|
749
|
+
for (var translationIndex = 0; translationIndex < UI_TRANSLATIONS.length; translationIndex++) {
|
|
750
|
+
var pair = UI_TRANSLATIONS[translationIndex];
|
|
751
|
+
text = text.split(pair[0]).join(pair[1]);
|
|
752
|
+
}
|
|
753
|
+
return text;
|
|
754
|
+
}
|
|
755
|
+
function captureStaticUiCopy() {
|
|
756
|
+
var root = document.getElementById('app');
|
|
757
|
+
function visit(node) {
|
|
758
|
+
if (node.nodeType === 3) {
|
|
759
|
+
if (node.nodeValue && node.nodeValue.trim()) UI_STATIC_COPY.push({ node: node, text: node.nodeValue });
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
762
|
+
if (node.nodeType !== 1) return;
|
|
763
|
+
var tag = node.tagName;
|
|
764
|
+
if (tag === 'SCRIPT' || tag === 'STYLE' || tag === 'CODE' || tag === 'PRE') return;
|
|
765
|
+
['title', 'placeholder', 'aria-label', 'alt'].forEach(function (name) {
|
|
766
|
+
if (node.hasAttribute(name)) UI_STATIC_COPY.push({ node: node, attr: name, text: node.getAttribute(name) });
|
|
767
|
+
});
|
|
768
|
+
Array.prototype.forEach.call(node.childNodes, visit);
|
|
769
|
+
}
|
|
770
|
+
visit(root);
|
|
771
|
+
}
|
|
772
|
+
function applyStaticUiCopy() {
|
|
773
|
+
document.documentElement.lang = UI_LANGUAGE;
|
|
774
|
+
document.title = translateUiText(UI_DOCUMENT_TITLE);
|
|
775
|
+
UI_STATIC_COPY.forEach(function (entry) {
|
|
776
|
+
var value = translateUiText(entry.text);
|
|
777
|
+
if (entry.attr) entry.node.setAttribute(entry.attr, value);
|
|
778
|
+
else entry.node.nodeValue = value;
|
|
779
|
+
});
|
|
780
|
+
document.documentElement.classList.add('i18n-ready');
|
|
781
|
+
}
|
|
782
|
+
function applyUiLanguage(language) {
|
|
783
|
+
if (language !== 'en-US' && language !== 'zh-CN') return;
|
|
784
|
+
UI_LANGUAGE = language;
|
|
785
|
+
SCN_FILTER = 'all';
|
|
786
|
+
SCN_PAGE = 1;
|
|
787
|
+
applyStaticUiCopy();
|
|
788
|
+
renderProfiles();
|
|
789
|
+
renderForm();
|
|
790
|
+
if (loaded.start) loadQuickStart();
|
|
791
|
+
if (loaded.skills) renderSkills();
|
|
792
|
+
if (loaded.mcp) renderMcp();
|
|
793
|
+
if (loaded.agents) { renderAgentFilters(); renderAgents(); }
|
|
794
|
+
if (loaded.assets) { renderAssetFilters(); renderAssets(); }
|
|
795
|
+
if (loaded.playground) { loaded.playground = false; loadPlayground(); }
|
|
796
|
+
if (AUTH) renderAccount(AUTH);
|
|
797
|
+
var sidebar = document.getElementById('sidebar');
|
|
798
|
+
var sidebarToggle = document.getElementById('sidebarToggle');
|
|
799
|
+
if (sidebar && sidebarToggle) {
|
|
800
|
+
var sidebarLabel = sidebar.classList.contains('is-collapsed') ? 'Expand sidebar' : 'Collapse sidebar';
|
|
801
|
+
sidebarToggle.setAttribute('aria-label', translateUiText(sidebarLabel));
|
|
802
|
+
sidebarToggle.title = translateUiText(sidebarLabel);
|
|
803
|
+
}
|
|
804
|
+
}
|
|
745
805
|
function setAvatar(elm, seed) {
|
|
746
806
|
elm.style.background = avatarStyle(seed);
|
|
747
807
|
elm.innerHTML = PERSON_SVG;
|
|
@@ -761,13 +821,16 @@ Omni output voices:
|
|
|
761
821
|
if (text !== undefined && text !== null) e.textContent = text;
|
|
762
822
|
return e;
|
|
763
823
|
}
|
|
824
|
+
function uiEl(tag, cls, text) {
|
|
825
|
+
return el(tag, cls, translateUiText(text));
|
|
826
|
+
}
|
|
764
827
|
function originBadge(origin) {
|
|
765
828
|
var o = origin === 'remote' ? 'remote' : 'local';
|
|
766
|
-
return el('span', 'origin ' + o, o === 'remote' ? 'Remote' : 'Local');
|
|
829
|
+
return el('span', 'origin ' + o, translateUiText(o === 'remote' ? 'Remote' : 'Local'));
|
|
767
830
|
}
|
|
768
831
|
function setStatus(msg, isErr) {
|
|
769
832
|
var s = document.getElementById('status');
|
|
770
|
-
s.textContent = msg || '';
|
|
833
|
+
s.textContent = translateUiText(msg || '');
|
|
771
834
|
s.className = isErr ? 'err' : 'muted';
|
|
772
835
|
}
|
|
773
836
|
function setCount(view, n) {
|
|
@@ -811,18 +874,18 @@ Omni output voices:
|
|
|
811
874
|
renderQuickStart(HEALTH, auth, agents);
|
|
812
875
|
}).catch(function (e) { renderError(body, e); });
|
|
813
876
|
}
|
|
814
|
-
function qsDesc(html) { var p = el('p', 'qs-desc'); p.innerHTML = html; return p; }
|
|
877
|
+
function qsDesc(html) { var p = el('p', 'qs-desc'); p.innerHTML = translateUiText(html); return p; }
|
|
815
878
|
function qsBtn(label, onclick, primary) {
|
|
816
|
-
var b = el('button', primary ? 'btn-primary' : 'btn-soft', label);
|
|
879
|
+
var b = el('button', primary ? 'btn-primary' : 'btn-soft', translateUiText(label));
|
|
817
880
|
b.type = 'button'; b.onclick = onclick; return b;
|
|
818
881
|
}
|
|
819
882
|
function qsStep(n, done, locked, title, descNode, actNode) {
|
|
820
883
|
var step = el('div', 'qs-step' + (done ? ' done' : '') + (locked ? ' locked' : ''));
|
|
821
884
|
var head = el('div', 'qs-head');
|
|
822
885
|
head.appendChild(el('span', 'qs-ic', done ? '✓' : String(n)));
|
|
823
|
-
if (done) head.appendChild(el('span', 'qs-done-tag', 'Done'));
|
|
886
|
+
if (done) head.appendChild(el('span', 'qs-done-tag', translateUiText('Done')));
|
|
824
887
|
step.appendChild(head);
|
|
825
|
-
step.appendChild(el('div', 'qs-title', title));
|
|
888
|
+
step.appendChild(el('div', 'qs-title', translateUiText(title)));
|
|
826
889
|
if (descNode) step.appendChild(descNode);
|
|
827
890
|
if (actNode && !done) { var wrap = el('div', 'qs-act'); wrap.appendChild(actNode); step.appendChild(wrap); }
|
|
828
891
|
return step;
|
|
@@ -909,7 +972,7 @@ Omni output voices:
|
|
|
909
972
|
t.onclick = function () { CURRENT = name; renderProfiles(); renderForm(); setStatus(''); openDrawer(); };
|
|
910
973
|
grid.appendChild(t);
|
|
911
974
|
});
|
|
912
|
-
var add =
|
|
975
|
+
var add = uiEl('div', 'tile tile-add', '+ New profile');
|
|
913
976
|
add.onclick = newProfile;
|
|
914
977
|
grid.appendChild(add);
|
|
915
978
|
}
|
|
@@ -938,7 +1001,7 @@ Omni output voices:
|
|
|
938
1001
|
}
|
|
939
1002
|
function detailSection(label, node, action) {
|
|
940
1003
|
var sec = el('div', 'detail-sec');
|
|
941
|
-
var head = el('div', 'detail-label', label);
|
|
1004
|
+
var head = el('div', 'detail-label', translateUiText(label));
|
|
942
1005
|
if (action) { head.classList.add('detail-label-row'); head.appendChild(action); }
|
|
943
1006
|
sec.appendChild(head);
|
|
944
1007
|
sec.appendChild(node);
|
|
@@ -1047,7 +1110,7 @@ Omni output voices:
|
|
|
1047
1110
|
return html;
|
|
1048
1111
|
}
|
|
1049
1112
|
function renderMarkdownInto(container, md) {
|
|
1050
|
-
if (!md) { container.appendChild(
|
|
1113
|
+
if (!md) { container.appendChild(uiEl('div', 'loading', '(empty)')); return; }
|
|
1051
1114
|
var wrap = el('div', 'md-body');
|
|
1052
1115
|
wrap.innerHTML = renderMarkdown(md);
|
|
1053
1116
|
container.appendChild(wrap);
|
|
@@ -1064,10 +1127,10 @@ Omni output voices:
|
|
|
1064
1127
|
{ source: 'windsurf', label: 'Windsurf' },
|
|
1065
1128
|
{ source: 'gemini', label: 'Gemini' }
|
|
1066
1129
|
];
|
|
1067
|
-
function setSkillErr(msg) { var e = document.getElementById('skillErr'); if (e) e.textContent = msg || ''; }
|
|
1130
|
+
function setSkillErr(msg) { var e = document.getElementById('skillErr'); if (e) e.textContent = translateUiText(msg || ''); }
|
|
1068
1131
|
function openSkillInstall() {
|
|
1069
1132
|
var title = document.getElementById('infoTitle');
|
|
1070
|
-
title.textContent = ''; title.appendChild(
|
|
1133
|
+
title.textContent = ''; title.appendChild(uiEl('span', '', 'Add skill'));
|
|
1071
1134
|
var body = document.getElementById('infoBody'); body.innerHTML = '';
|
|
1072
1135
|
var sel = el('select', 'select'); sel.id = 'skillNewSource';
|
|
1073
1136
|
SKILL_TARGETS.forEach(function (s) { var o = el('option', '', s.label); o.value = s.source; sel.appendChild(o); });
|
|
@@ -1078,21 +1141,21 @@ Omni output voices:
|
|
|
1078
1141
|
var fileInp = el('input'); fileInp.id = 'skillFile'; fileInp.type = 'file'; fileInp.accept = '.zip,application/zip';
|
|
1079
1142
|
fileInp.style.display = 'none';
|
|
1080
1143
|
var picker = el('div', 'file-picker');
|
|
1081
|
-
var pickBtn =
|
|
1082
|
-
var fileName =
|
|
1144
|
+
var pickBtn = uiEl('button', 'file-pick-btn', 'Choose .zip file'); pickBtn.type = 'button';
|
|
1145
|
+
var fileName = uiEl('span', 'file-name', 'No file selected');
|
|
1083
1146
|
pickBtn.onclick = function () { fileInp.click(); };
|
|
1084
1147
|
fileInp.onchange = function () {
|
|
1085
1148
|
var f = fileInp.files && fileInp.files[0];
|
|
1086
|
-
fileName.textContent = f ? f.name : 'No file selected';
|
|
1149
|
+
fileName.textContent = f ? f.name : translateUiText('No file selected');
|
|
1087
1150
|
fileName.classList.toggle('has-file', !!f);
|
|
1088
1151
|
};
|
|
1089
1152
|
picker.appendChild(pickBtn); picker.appendChild(fileName); picker.appendChild(fileInp);
|
|
1090
1153
|
body.appendChild(detailSection('Skill package (.zip)', picker));
|
|
1091
|
-
body.appendChild(
|
|
1154
|
+
body.appendChild(uiEl('p', 'mcp-note', 'The .zip must contain a SKILL.md at its root or inside a single top-level folder.'));
|
|
1092
1155
|
var err = el('div', 'modal-err'); err.id = 'skillErr'; body.appendChild(err);
|
|
1093
1156
|
openInfoDrawer();
|
|
1094
1157
|
var foot = document.getElementById('infoFoot'); foot.innerHTML = ''; foot.hidden = false;
|
|
1095
|
-
var install =
|
|
1158
|
+
var install = uiEl('button', 'btn-primary', 'Install'); install.type = 'button';
|
|
1096
1159
|
install.onclick = function () { doInstallSkill(install); };
|
|
1097
1160
|
foot.appendChild(install);
|
|
1098
1161
|
}
|
|
@@ -1131,7 +1194,7 @@ Omni output voices:
|
|
|
1131
1194
|
chips.appendChild(el('span', 'chip', s.fileCount + ' files'));
|
|
1132
1195
|
body.appendChild(detailSection('Installed in', chips));
|
|
1133
1196
|
body.appendChild(detailSection('Path', el('div', 'detail-path', s.path)));
|
|
1134
|
-
var codeSec = detailSection('SKILL.md',
|
|
1197
|
+
var codeSec = detailSection('SKILL.md', uiEl('div', 'loading', 'Loading…'));
|
|
1135
1198
|
body.appendChild(codeSec);
|
|
1136
1199
|
openInfoDrawer();
|
|
1137
1200
|
api('/api/skill?id=' + encodeURIComponent(s.id)).then(function (r) { return r.json(); }).then(function (j) {
|
|
@@ -1139,14 +1202,14 @@ Omni output voices:
|
|
|
1139
1202
|
renderMarkdownInto(codeSec, (j && j.content) || '');
|
|
1140
1203
|
}).catch(function (e) {
|
|
1141
1204
|
codeSec.removeChild(codeSec.lastChild);
|
|
1142
|
-
codeSec.appendChild(
|
|
1205
|
+
codeSec.appendChild(uiEl('div', 'err', 'Failed to load: ' + e));
|
|
1143
1206
|
});
|
|
1144
1207
|
}
|
|
1145
1208
|
|
|
1146
1209
|
function makeSelect(key, options, current) {
|
|
1147
1210
|
var sel = document.createElement('select');
|
|
1148
1211
|
sel.id = 'f_' + key; sel.name = key; sel.className = 'select';
|
|
1149
|
-
var blank = document.createElement('option'); blank.value = ''; blank.textContent = '(unset)';
|
|
1212
|
+
var blank = document.createElement('option'); blank.value = ''; blank.textContent = translateUiText('(unset)');
|
|
1150
1213
|
sel.appendChild(blank);
|
|
1151
1214
|
options.forEach(function (opt) {
|
|
1152
1215
|
var o = document.createElement('option'); o.value = opt; o.textContent = opt;
|
|
@@ -1159,12 +1222,12 @@ Omni output voices:
|
|
|
1159
1222
|
function renderForm() {
|
|
1160
1223
|
var form = document.getElementById('form');
|
|
1161
1224
|
form.innerHTML = '';
|
|
1162
|
-
document.getElementById('currentName').textContent = CURRENT === '' ? 'default (top-level)' : CURRENT;
|
|
1225
|
+
document.getElementById('currentName').textContent = CURRENT === '' ? translateUiText('default (top-level)') : CURRENT;
|
|
1163
1226
|
document.getElementById('deleteBtn').style.display = CURRENT === '' ? 'none' : '';
|
|
1164
1227
|
var selectedName = CURRENT === '' ? 'default' : CURRENT;
|
|
1165
1228
|
var useBtn = document.getElementById('useBtn');
|
|
1166
1229
|
useBtn.disabled = selectedName === ACTIVE;
|
|
1167
|
-
useBtn.textContent = selectedName === ACTIVE ? 'Active' : 'Save & Activate';
|
|
1230
|
+
useBtn.textContent = translateUiText(selectedName === ACTIVE ? 'Active' : 'Save & Activate');
|
|
1168
1231
|
var data = profileData(CURRENT);
|
|
1169
1232
|
KEYS.forEach(function (key) {
|
|
1170
1233
|
var row = el('div', 'row');
|
|
@@ -1179,10 +1242,10 @@ Omni output voices:
|
|
|
1179
1242
|
// the key). 'new-password' reliably suppresses saved-credential autofill.
|
|
1180
1243
|
input.autocomplete = 'new-password';
|
|
1181
1244
|
input.setAttribute('autocorrect', 'off'); input.spellcheck = false;
|
|
1182
|
-
var toggle = el('button', 'toggle', 'show'); toggle.type = 'button';
|
|
1245
|
+
var toggle = el('button', 'toggle', translateUiText('show')); toggle.type = 'button';
|
|
1183
1246
|
toggle.onclick = function () {
|
|
1184
|
-
if (input.type === 'password') { input.type = 'text'; toggle.textContent = 'hide'; }
|
|
1185
|
-
else { input.type = 'password'; toggle.textContent = 'show'; }
|
|
1247
|
+
if (input.type === 'password') { input.type = 'text'; toggle.textContent = translateUiText('hide'); }
|
|
1248
|
+
else { input.type = 'password'; toggle.textContent = translateUiText('show'); }
|
|
1186
1249
|
};
|
|
1187
1250
|
var wrap = el('div', 'inputwrap'); wrap.appendChild(input); wrap.appendChild(toggle);
|
|
1188
1251
|
row.appendChild(label); row.appendChild(wrap);
|
|
@@ -1215,7 +1278,7 @@ Omni output voices:
|
|
|
1215
1278
|
function modelCatalogBlock(key, input) {
|
|
1216
1279
|
var opts = MODEL_CATALOG[key] || [];
|
|
1217
1280
|
var box = el('div', 'model-cat');
|
|
1218
|
-
box.appendChild(el('div', 'model-cat-hint', 'Available ' + modelCatLabel(key) + ' models · click to use'));
|
|
1281
|
+
box.appendChild(el('div', 'model-cat-hint', translateUiText('Available ' + modelCatLabel(key) + ' models · click to use')));
|
|
1219
1282
|
var chips = el('div', 'model-chips');
|
|
1220
1283
|
function mark() {
|
|
1221
1284
|
var cur = input.value.trim();
|
|
@@ -1236,7 +1299,7 @@ Omni output voices:
|
|
|
1236
1299
|
var note = modelCatNote(key);
|
|
1237
1300
|
if (note) {
|
|
1238
1301
|
var noteEl = el('div', 'model-cat-note');
|
|
1239
|
-
noteEl.innerHTML = note;
|
|
1302
|
+
noteEl.innerHTML = translateUiText(note);
|
|
1240
1303
|
box.appendChild(noteEl);
|
|
1241
1304
|
}
|
|
1242
1305
|
setTimeout(mark, 0);
|
|
@@ -1260,6 +1323,9 @@ Omni output voices:
|
|
|
1260
1323
|
if (!result.ok) throw new Error((result.json && result.json.error) || 'error');
|
|
1261
1324
|
var saved = result.json.saved || {};
|
|
1262
1325
|
if (name === '') DATA.default = saved; else DATA.named[name] = saved;
|
|
1326
|
+
if (result.json.uiLanguage && result.json.uiLanguage !== UI_LANGUAGE) {
|
|
1327
|
+
applyUiLanguage(result.json.uiLanguage);
|
|
1328
|
+
}
|
|
1263
1329
|
return saved;
|
|
1264
1330
|
});
|
|
1265
1331
|
}
|
|
@@ -1284,17 +1350,17 @@ Omni output voices:
|
|
|
1284
1350
|
}
|
|
1285
1351
|
|
|
1286
1352
|
function setModalErr(msg) {
|
|
1287
|
-
document.getElementById('modalErr').textContent = msg || '';
|
|
1353
|
+
document.getElementById('modalErr').textContent = translateUiText(msg || '');
|
|
1288
1354
|
}
|
|
1289
1355
|
|
|
1290
1356
|
var _confirmOnOk = null;
|
|
1291
1357
|
function openConfirm(opts) {
|
|
1292
1358
|
opts = opts || {};
|
|
1293
|
-
document.getElementById('confirmTitle').textContent = opts.title || 'Are you sure?';
|
|
1294
|
-
document.getElementById('confirmMsg').textContent = opts.message || '';
|
|
1359
|
+
document.getElementById('confirmTitle').textContent = translateUiText(opts.title || 'Are you sure?');
|
|
1360
|
+
document.getElementById('confirmMsg').textContent = translateUiText(opts.message || '');
|
|
1295
1361
|
var ok = document.getElementById('confirmOk');
|
|
1296
1362
|
var cancel = document.getElementById('confirmCancel');
|
|
1297
|
-
ok.textContent = opts.okLabel || 'Delete';
|
|
1363
|
+
ok.textContent = translateUiText(opts.okLabel || 'Delete');
|
|
1298
1364
|
ok.className = opts.danger === false ? 'btn-primary' : 'btn-danger-solid';
|
|
1299
1365
|
cancel.hidden = !!opts.hideCancel;
|
|
1300
1366
|
_confirmOnOk = opts.onConfirm || null;
|
|
@@ -1347,6 +1413,9 @@ Omni output voices:
|
|
|
1347
1413
|
}).then(function (result) {
|
|
1348
1414
|
if (!result.ok) throw new Error('Saved, but activation failed: ' + ((result.json && result.json.error) || 'error'));
|
|
1349
1415
|
ACTIVE = result.json.activeProfile || 'default';
|
|
1416
|
+
if (result.json.uiLanguage && result.json.uiLanguage !== UI_LANGUAGE) {
|
|
1417
|
+
applyUiLanguage(result.json.uiLanguage);
|
|
1418
|
+
}
|
|
1350
1419
|
renderProfiles(); renderForm(); setStatus('Saved and activated.');
|
|
1351
1420
|
}).catch(function (err) { setStatus(err.message || String(err), true); });
|
|
1352
1421
|
}
|
|
@@ -1375,8 +1444,8 @@ Omni output voices:
|
|
|
1375
1444
|
function renderEmpty(container, msg, hint) {
|
|
1376
1445
|
container.innerHTML = '';
|
|
1377
1446
|
var box = el('div', 'empty');
|
|
1378
|
-
box.appendChild(el('div', '', msg));
|
|
1379
|
-
if (hint) { var p = el('p', 'muted'); p.style.marginTop = '10px'; p.innerHTML = hint; box.appendChild(p); }
|
|
1447
|
+
box.appendChild(el('div', '', translateUiText(msg)));
|
|
1448
|
+
if (hint) { var p = el('p', 'muted'); p.style.marginTop = '10px'; p.innerHTML = translateUiText(hint); box.appendChild(p); }
|
|
1380
1449
|
container.appendChild(box);
|
|
1381
1450
|
}
|
|
1382
1451
|
function renderError(container, e) { renderEmpty(container, 'Failed to load: ' + e); }
|
|
@@ -1431,7 +1500,7 @@ Omni output voices:
|
|
|
1431
1500
|
}
|
|
1432
1501
|
});
|
|
1433
1502
|
bar.appendChild(navBtn('›', info.page + 1, info.page >= info.pages));
|
|
1434
|
-
var sel = el('select', 'pg-size'); sel.title = 'Items per page';
|
|
1503
|
+
var sel = el('select', 'pg-size'); sel.title = translateUiText('Items per page');
|
|
1435
1504
|
PAGE_SIZES.forEach(function (s) {
|
|
1436
1505
|
var o = el('option', '', s + ' / page'); o.value = String(s);
|
|
1437
1506
|
if (s === getPageSize(view)) o.selected = true;
|
|
@@ -1486,7 +1555,7 @@ Omni output voices:
|
|
|
1486
1555
|
if (s.description) t.appendChild(el('p', 'tile-desc', s.description));
|
|
1487
1556
|
var srcRow = el('div', 'tile-foot');
|
|
1488
1557
|
(s.sources || []).forEach(function (src) { srcRow.appendChild(el('span', 'chip blue', src)); });
|
|
1489
|
-
srcRow.appendChild(
|
|
1558
|
+
srcRow.appendChild(uiEl('span', 'chip', s.fileCount + ' files'));
|
|
1490
1559
|
t.appendChild(srcRow);
|
|
1491
1560
|
grid.appendChild(t);
|
|
1492
1561
|
});
|
|
@@ -1562,16 +1631,16 @@ Omni output voices:
|
|
|
1562
1631
|
body.appendChild(detailSection('Configuration' + (editable ? ' (editable)' : ''), block, copyButton(function () {
|
|
1563
1632
|
return editable ? document.getElementById('mcpEdit').value : json;
|
|
1564
1633
|
})));
|
|
1565
|
-
if (!editable) body.appendChild(
|
|
1634
|
+
if (!editable) body.appendChild(uiEl('p', 'mcp-note', 'This source is read-only here (its config is TOML). Edit it directly in ' + (m.source || 'its config file') + '.'));
|
|
1566
1635
|
var err = el('div', 'modal-err'); err.id = 'mcpErr'; body.appendChild(err);
|
|
1567
1636
|
openInfoDrawer();
|
|
1568
1637
|
if (editable) {
|
|
1569
1638
|
var foot = document.getElementById('infoFoot'); foot.innerHTML = ''; foot.hidden = false;
|
|
1570
|
-
var del =
|
|
1639
|
+
var del = uiEl('button', 'btn-danger', 'Delete'); del.type = 'button';
|
|
1571
1640
|
del.onclick = function () {
|
|
1572
1641
|
openConfirm({ title: 'Delete MCP server?', message: 'Remove "' + m.name + '" from ' + m.source + '? This rewrites the source config file.', onConfirm: function () { doDeleteMcp(m); } });
|
|
1573
1642
|
};
|
|
1574
|
-
var save =
|
|
1643
|
+
var save = uiEl('button', 'btn-primary', 'Save'); save.type = 'button';
|
|
1575
1644
|
save.onclick = function () { doSaveMcp(m, save); };
|
|
1576
1645
|
foot.appendChild(del); foot.appendChild(save);
|
|
1577
1646
|
}
|
|
@@ -1589,16 +1658,16 @@ Omni output voices:
|
|
|
1589
1658
|
{ id: 'qoderwork', label: 'QoderWork' }
|
|
1590
1659
|
];
|
|
1591
1660
|
function copyButton(getText) {
|
|
1592
|
-
var b =
|
|
1661
|
+
var b = uiEl('button', 'copy-btn', 'Copy'); b.type = 'button';
|
|
1593
1662
|
b.onclick = function () {
|
|
1594
1663
|
var text = getText();
|
|
1595
|
-
var done = function () { b.classList.add('copied'); b.textContent = 'Copied'; setTimeout(function () { b.classList.remove('copied'); b.textContent = 'Copy'; }, 1500); };
|
|
1664
|
+
var done = function () { b.classList.add('copied'); b.textContent = translateUiText('Copied'); setTimeout(function () { b.classList.remove('copied'); b.textContent = translateUiText('Copy'); }, 1500); };
|
|
1596
1665
|
if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(text).then(done).catch(function () { fallbackCopy(text); done(); }); }
|
|
1597
1666
|
else { fallbackCopy(text); done(); }
|
|
1598
1667
|
};
|
|
1599
1668
|
return b;
|
|
1600
1669
|
}
|
|
1601
|
-
function setMcpErr(msg) { var e = document.getElementById('mcpErr'); if (e) e.textContent = msg || ''; }
|
|
1670
|
+
function setMcpErr(msg) { var e = document.getElementById('mcpErr'); if (e) e.textContent = translateUiText(msg || ''); }
|
|
1602
1671
|
function parseMcpEditor() {
|
|
1603
1672
|
var parsed = JSON.parse(document.getElementById('mcpEdit').value);
|
|
1604
1673
|
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) throw new Error('Config must be a JSON object.');
|
|
@@ -1630,7 +1699,7 @@ Omni output voices:
|
|
|
1630
1699
|
}
|
|
1631
1700
|
function openMcpCreate() {
|
|
1632
1701
|
var title = document.getElementById('infoTitle');
|
|
1633
|
-
title.textContent = ''; title.appendChild(
|
|
1702
|
+
title.textContent = ''; title.appendChild(uiEl('span', '', 'New MCP server'));
|
|
1634
1703
|
var body = document.getElementById('infoBody'); body.innerHTML = '';
|
|
1635
1704
|
var sel = el('select', 'select'); sel.id = 'mcpNewSource';
|
|
1636
1705
|
MCP_SOURCES.forEach(function (s) { var o = el('option', '', s.label); o.value = s.id; sel.appendChild(o); });
|
|
@@ -1643,7 +1712,7 @@ Omni output voices:
|
|
|
1643
1712
|
var err = el('div', 'modal-err'); err.id = 'mcpErr'; body.appendChild(err);
|
|
1644
1713
|
openInfoDrawer();
|
|
1645
1714
|
var foot = document.getElementById('infoFoot'); foot.innerHTML = ''; foot.hidden = false;
|
|
1646
|
-
var create =
|
|
1715
|
+
var create = uiEl('button', 'btn-primary', 'Create'); create.type = 'button';
|
|
1647
1716
|
create.onclick = function () { doCreateMcp(create); };
|
|
1648
1717
|
foot.appendChild(create);
|
|
1649
1718
|
}
|
|
@@ -1689,7 +1758,7 @@ Omni output voices:
|
|
|
1689
1758
|
var labels = { all: 'All', local: 'Local', remote: 'Remote' };
|
|
1690
1759
|
['all', 'local', 'remote'].forEach(function (cat) {
|
|
1691
1760
|
var b = el('button', 'filter' + (cat === AGENT_FILTER ? ' is-active' : ''));
|
|
1692
|
-
b.appendChild(
|
|
1761
|
+
b.appendChild(uiEl('span', '', labels[cat]));
|
|
1693
1762
|
b.appendChild(el('span', 'n', String(counts[cat] || 0)));
|
|
1694
1763
|
b.onclick = function () { AGENT_FILTER = cat; AGENT_PAGE = 1; renderAgentFilters(); renderAgents(); };
|
|
1695
1764
|
bar.appendChild(b);
|
|
@@ -1726,9 +1795,9 @@ Omni output voices:
|
|
|
1726
1795
|
var meta = el('div', 'tile-meta');
|
|
1727
1796
|
meta.appendChild(originBadge(a.origin));
|
|
1728
1797
|
var pill;
|
|
1729
|
-
if (a.installed && a.configured) pill =
|
|
1730
|
-
else if (a.installed) pill =
|
|
1731
|
-
else pill =
|
|
1798
|
+
if (a.installed && a.configured) pill = uiEl('span', 'pill ok', 'Connected');
|
|
1799
|
+
else if (a.installed) pill = uiEl('span', 'pill neutral', 'Installed');
|
|
1800
|
+
else pill = uiEl('span', 'pill off', 'Not installed');
|
|
1732
1801
|
meta.appendChild(pill);
|
|
1733
1802
|
t.appendChild(meta);
|
|
1734
1803
|
var foot = el('div', 'tile-foot');
|
|
@@ -1743,17 +1812,17 @@ Omni output voices:
|
|
|
1743
1812
|
var actions = el('div', 'tile-actions');
|
|
1744
1813
|
var launch = el('button', 'icon-run');
|
|
1745
1814
|
launch.innerHTML = PLAY_SVG;
|
|
1746
|
-
launch.setAttribute('aria-label', 'Quick launch');
|
|
1815
|
+
launch.setAttribute('aria-label', translateUiText('Quick launch'));
|
|
1747
1816
|
var connected = a.installed && a.configured;
|
|
1748
1817
|
var st = el('span', 'launch-status');
|
|
1749
1818
|
if (connected && a.launchable) {
|
|
1750
|
-
launch.title = 'Open a new terminal and start this agent';
|
|
1819
|
+
launch.title = translateUiText('Open a new terminal and start this agent');
|
|
1751
1820
|
launch.onclick = function (e) { e.stopPropagation(); launchAgentCli(a, launch, st); };
|
|
1752
1821
|
} else {
|
|
1753
1822
|
launch.disabled = true;
|
|
1754
|
-
if (!a.installed) launch.title = 'Install this agent before launching';
|
|
1755
|
-
else if (!connected) launch.title = 'Connect this agent to bailian-cli before launching';
|
|
1756
|
-
else launch.title = 'The CLI for this agent was not found on your PATH — install it before launching';
|
|
1823
|
+
if (!a.installed) launch.title = translateUiText('Install this agent before launching');
|
|
1824
|
+
else if (!connected) launch.title = translateUiText('Connect this agent to bailian-cli before launching');
|
|
1825
|
+
else launch.title = translateUiText('The CLI for this agent was not found on your PATH — install it before launching');
|
|
1757
1826
|
}
|
|
1758
1827
|
actions.appendChild(st);
|
|
1759
1828
|
actions.appendChild(launch);
|
|
@@ -1766,15 +1835,15 @@ Omni output voices:
|
|
|
1766
1835
|
|
|
1767
1836
|
function launchAgentCli(a, btn, st) {
|
|
1768
1837
|
btn.disabled = true;
|
|
1769
|
-
st.textContent = 'Launching…'; st.className = 'launch-status';
|
|
1838
|
+
st.textContent = translateUiText('Launching…'); st.className = 'launch-status';
|
|
1770
1839
|
api('/api/agent/launch?id=' + encodeURIComponent(a.id), { method: 'POST' })
|
|
1771
1840
|
.then(function (r) { return r.json().then(function (j) { return { ok: r.ok, j: j }; }); })
|
|
1772
1841
|
.then(function (res) {
|
|
1773
1842
|
btn.disabled = false;
|
|
1774
|
-
if (!res.ok) { st.textContent = (res.j && res.j.error) || 'Launch failed'; st.className = 'launch-status err'; return; }
|
|
1775
|
-
st.textContent = 'Launched → ' + (res.j.command || a.id); st.className = 'launch-status ok';
|
|
1843
|
+
if (!res.ok) { st.textContent = (res.j && res.j.error) || translateUiText('Launch failed'); st.className = 'launch-status err'; return; }
|
|
1844
|
+
st.textContent = translateUiText('Launched → ') + (res.j.command || a.id); st.className = 'launch-status ok';
|
|
1776
1845
|
})
|
|
1777
|
-
.catch(function (e) { btn.disabled = false; st.textContent = 'Launch failed: ' + e; st.className = 'launch-status err'; });
|
|
1846
|
+
.catch(function (e) { btn.disabled = false; st.textContent = translateUiText('Launch failed: ') + e; st.className = 'launch-status err'; });
|
|
1778
1847
|
}
|
|
1779
1848
|
|
|
1780
1849
|
function openAgentDetail(a) {
|
|
@@ -1795,9 +1864,9 @@ Omni output voices:
|
|
|
1795
1864
|
var chips = el('div', 'detail-chips');
|
|
1796
1865
|
chips.appendChild(el('span', 'chip', d.id));
|
|
1797
1866
|
var pill;
|
|
1798
|
-
if (d.installed && d.configured) pill =
|
|
1799
|
-
else if (d.installed) pill =
|
|
1800
|
-
else pill =
|
|
1867
|
+
if (d.installed && d.configured) pill = uiEl('span', 'pill ok', 'Connected');
|
|
1868
|
+
else if (d.installed) pill = uiEl('span', 'pill neutral', 'Installed');
|
|
1869
|
+
else pill = uiEl('span', 'pill off', 'Not installed');
|
|
1801
1870
|
chips.appendChild(pill);
|
|
1802
1871
|
body.appendChild(detailSection('Status', chips));
|
|
1803
1872
|
if (d.fields && d.fields.length) {
|
|
@@ -1809,13 +1878,13 @@ Omni output voices:
|
|
|
1809
1878
|
row.appendChild(val);
|
|
1810
1879
|
if (f.secret && f.raw) {
|
|
1811
1880
|
var shown = false;
|
|
1812
|
-
var btn =
|
|
1881
|
+
var btn = uiEl('button', 'kv-reveal', 'Show');
|
|
1813
1882
|
btn.type = 'button';
|
|
1814
1883
|
btn.onclick = function () {
|
|
1815
1884
|
shown = !shown;
|
|
1816
1885
|
val.textContent = shown ? f.raw : f.value;
|
|
1817
1886
|
if (shown) { val.classList.remove('secret'); } else { val.classList.add('secret'); }
|
|
1818
|
-
btn.textContent = shown ? 'Hide' : 'Show';
|
|
1887
|
+
btn.textContent = translateUiText(shown ? 'Hide' : 'Show');
|
|
1819
1888
|
};
|
|
1820
1889
|
row.appendChild(btn);
|
|
1821
1890
|
}
|
|
@@ -1823,9 +1892,9 @@ Omni output voices:
|
|
|
1823
1892
|
});
|
|
1824
1893
|
body.appendChild(detailSection('Configuration', kv));
|
|
1825
1894
|
} else if (d.installed) {
|
|
1826
|
-
body.appendChild(detailSection('Configuration',
|
|
1895
|
+
body.appendChild(detailSection('Configuration', uiEl('div', 'detail-path', 'bailian-cli is not wired into this agent yet.')));
|
|
1827
1896
|
} else {
|
|
1828
|
-
body.appendChild(detailSection('Configuration',
|
|
1897
|
+
body.appendChild(detailSection('Configuration', uiEl('div', 'detail-path', 'This agent is not installed yet.')));
|
|
1829
1898
|
}
|
|
1830
1899
|
if (d.files && d.files.length) {
|
|
1831
1900
|
var wrap = el('div', '');
|
|
@@ -1846,9 +1915,9 @@ Omni output voices:
|
|
|
1846
1915
|
item.appendChild(el('pre', 'detail-code', fl.text));
|
|
1847
1916
|
sw.appendChild(item);
|
|
1848
1917
|
});
|
|
1849
|
-
var openBtn =
|
|
1918
|
+
var openBtn = uiEl('button', 'kv-reveal', 'Open');
|
|
1850
1919
|
openBtn.type = 'button';
|
|
1851
|
-
openBtn.title = 'Open the config file with the system default app';
|
|
1920
|
+
openBtn.title = translateUiText('Open the config file with the system default app');
|
|
1852
1921
|
openBtn.onclick = function () { openAgentSettings(d); };
|
|
1853
1922
|
body.appendChild(detailSection('Settings', sw, openBtn));
|
|
1854
1923
|
}
|
|
@@ -1873,18 +1942,23 @@ Omni output voices:
|
|
|
1873
1942
|
renderScenarios();
|
|
1874
1943
|
}).catch(function (e) { renderError(body, e); });
|
|
1875
1944
|
}
|
|
1876
|
-
|
|
1945
|
+
function scenarioOrder() {
|
|
1946
|
+
return UI_LANGUAGE === 'zh-CN'
|
|
1947
|
+
? ['图像', '音频', '视频', '多模态', '代码', '文档']
|
|
1948
|
+
: ['Image', 'Audio', 'Video', 'Multimodal', 'Code', 'Documentation'];
|
|
1949
|
+
}
|
|
1877
1950
|
function scenarioCategories() {
|
|
1878
1951
|
var present = {};
|
|
1952
|
+
var order = scenarioOrder();
|
|
1879
1953
|
SCENARIOS.forEach(function (s) { if (s.category) present[s.category] = true; });
|
|
1880
|
-
var cats =
|
|
1881
|
-
Object.keys(present).forEach(function (c) { if (
|
|
1954
|
+
var cats = order.filter(function (c) { return present[c]; });
|
|
1955
|
+
Object.keys(present).forEach(function (c) { if (order.indexOf(c) < 0) cats.push(c); });
|
|
1882
1956
|
return cats;
|
|
1883
1957
|
}
|
|
1884
1958
|
function renderScenarioFilters() {
|
|
1885
1959
|
var bar = document.getElementById('scenarioFilters');
|
|
1886
1960
|
bar.innerHTML = '';
|
|
1887
|
-
var defs = [{ key: 'all', label: 'All', n: SCENARIOS.length }];
|
|
1961
|
+
var defs = [{ key: 'all', label: translateUiText('All'), n: SCENARIOS.length }];
|
|
1888
1962
|
scenarioCategories().forEach(function (c) {
|
|
1889
1963
|
defs.push({ key: c, label: c, n: SCENARIOS.filter(function (s) { return s.category === c; }).length });
|
|
1890
1964
|
});
|
|
@@ -1900,7 +1974,7 @@ Omni output voices:
|
|
|
1900
1974
|
return matchQ(s.title, q) || matchQ(s.description, q) || matchQ(s.category, q);
|
|
1901
1975
|
}
|
|
1902
1976
|
function pgWarnNode() {
|
|
1903
|
-
return
|
|
1977
|
+
return uiEl('div', 'pg-warn', 'No connected agent can accept tasks yet. Install and connect qwen-code (or another supported agent) first, and make sure its CLI is on your PATH.');
|
|
1904
1978
|
}
|
|
1905
1979
|
function renderScenarios() {
|
|
1906
1980
|
var body = document.getElementById('playgroundBody');
|
|
@@ -1921,7 +1995,7 @@ Omni output voices:
|
|
|
1921
1995
|
var grid = el('div', 'grid');
|
|
1922
1996
|
info.items.forEach(function (s) {
|
|
1923
1997
|
var t = el('div', 'tile clickable');
|
|
1924
|
-
t.title = 'Click to edit this scenario';
|
|
1998
|
+
t.title = translateUiText('Click to edit this scenario');
|
|
1925
1999
|
t.onclick = function () { openScnDrawer(s); };
|
|
1926
2000
|
var top = el('div', 'tile-top');
|
|
1927
2001
|
top.appendChild(el('span', 'tile-name', s.title));
|
|
@@ -1933,12 +2007,12 @@ Omni output voices:
|
|
|
1933
2007
|
var actions = el('div', 'tile-actions');
|
|
1934
2008
|
var run = el('button', 'icon-run');
|
|
1935
2009
|
run.innerHTML = PLAY_SVG;
|
|
1936
|
-
run.setAttribute('aria-label', 'Run it');
|
|
2010
|
+
run.setAttribute('aria-label', translateUiText('Run it'));
|
|
1937
2011
|
if (DISPATCH_AGENTS.length) {
|
|
1938
|
-
run.title = 'Dispatch this task to a local agent';
|
|
2012
|
+
run.title = translateUiText('Dispatch this task to a local agent');
|
|
1939
2013
|
run.onclick = function (e) { e.stopPropagation(); openDispatch(s); };
|
|
1940
2014
|
} else {
|
|
1941
|
-
run.disabled = true; run.title = 'No connected agent available';
|
|
2015
|
+
run.disabled = true; run.title = translateUiText('No connected agent available');
|
|
1942
2016
|
}
|
|
1943
2017
|
actions.appendChild(run);
|
|
1944
2018
|
t.appendChild(actions);
|
|
@@ -1968,7 +2042,7 @@ Omni output voices:
|
|
|
1968
2042
|
if (!DISPATCH_SCN) return;
|
|
1969
2043
|
document.getElementById('dispatchPreview').textContent = fillPrompt(DISPATCH_SCN, dispatchValues());
|
|
1970
2044
|
}
|
|
1971
|
-
function setDispatchErr(m) { document.getElementById('dispatchErr').textContent = m || ''; }
|
|
2045
|
+
function setDispatchErr(m) { document.getElementById('dispatchErr').textContent = translateUiText(m || ''); }
|
|
1972
2046
|
var LAST_AGENT_KEY = 'bl.lastDispatchAgent';
|
|
1973
2047
|
function openDispatch(s) {
|
|
1974
2048
|
DISPATCH_SCN = s;
|
|
@@ -2077,7 +2151,7 @@ Omni output voices:
|
|
|
2077
2151
|
return arr.filter(function (s) { return s && s.id && s.title && s.prompt; }).map(function (s) {
|
|
2078
2152
|
return {
|
|
2079
2153
|
id: s.id, title: s.title, description: s.description || '',
|
|
2080
|
-
category: s.category || 'Custom', prompt: s.prompt,
|
|
2154
|
+
category: s.category || translateUiText('Custom'), prompt: s.prompt,
|
|
2081
2155
|
inputs: Array.isArray(s.inputs) ? s.inputs : [], custom: true
|
|
2082
2156
|
};
|
|
2083
2157
|
});
|
|
@@ -2097,12 +2171,12 @@ Omni output voices:
|
|
|
2097
2171
|
var l = el('input'); l.className = 'scn-l'; l.placeholder = 'label'; l.autocomplete = 'off'; l.spellcheck = false;
|
|
2098
2172
|
var p = el('input'); p.className = 'scn-p'; p.placeholder = 'placeholder (optional)'; p.autocomplete = 'off'; p.spellcheck = false;
|
|
2099
2173
|
if (inp) { k.value = inp.key || ''; l.value = inp.label || ''; p.value = inp.placeholder || ''; }
|
|
2100
|
-
var del = el('button', 'btn-mini', '×'); del.type = 'button'; del.title = 'Remove'; del.onclick = function () { row.remove(); };
|
|
2174
|
+
var del = el('button', 'btn-mini', '×'); del.type = 'button'; del.title = translateUiText('Remove'); del.onclick = function () { row.remove(); };
|
|
2101
2175
|
row.appendChild(k); row.appendChild(l); row.appendChild(p); row.appendChild(del);
|
|
2102
2176
|
return row;
|
|
2103
2177
|
}
|
|
2104
2178
|
function addScnInputRow(inp) { document.getElementById('scnInputRows').appendChild(scnInputRow(inp)); }
|
|
2105
|
-
function setScnErr(m) { document.getElementById('scnDrawerErr').textContent = m || ''; }
|
|
2179
|
+
function setScnErr(m) { document.getElementById('scnDrawerErr').textContent = translateUiText(m || ''); }
|
|
2106
2180
|
function fillScnCatList() {
|
|
2107
2181
|
var dl = document.getElementById('scnCatList'); dl.innerHTML = '';
|
|
2108
2182
|
scenarioCategories().forEach(function (c) { var o = document.createElement('option'); o.value = c; dl.appendChild(o); });
|
|
@@ -2111,9 +2185,9 @@ Omni output voices:
|
|
|
2111
2185
|
SCN_EDIT_ID = existing ? existing.id : null;
|
|
2112
2186
|
SCN_EDIT_KIND = existing ? (existing.custom ? 'custom' : 'builtin') : 'new';
|
|
2113
2187
|
var isEdit = !!existing;
|
|
2114
|
-
document.getElementById('scnDrawerTitle').textContent = isEdit ? (existing.custom ? 'Edit scenario' : 'Edit preset scenario') : 'Custom scenario';
|
|
2188
|
+
document.getElementById('scnDrawerTitle').textContent = translateUiText(isEdit ? (existing.custom ? 'Edit scenario' : 'Edit preset scenario') : 'Custom scenario');
|
|
2115
2189
|
document.getElementById('scnTitle').value = existing ? existing.title : '';
|
|
2116
|
-
document.getElementById('scnCategory').value = existing ? (existing.category || '') : 'Custom';
|
|
2190
|
+
document.getElementById('scnCategory').value = existing ? (existing.category || '') : translateUiText('Custom');
|
|
2117
2191
|
document.getElementById('scnDesc').value = existing ? (existing.description || '') : '';
|
|
2118
2192
|
document.getElementById('scnPrompt').value = existing ? existing.prompt : '';
|
|
2119
2193
|
var rows = document.getElementById('scnInputRows'); rows.innerHTML = '';
|
|
@@ -2121,7 +2195,7 @@ Omni output voices:
|
|
|
2121
2195
|
fillScnCatList();
|
|
2122
2196
|
var del = document.getElementById('scnDelete');
|
|
2123
2197
|
del.hidden = !isEdit;
|
|
2124
|
-
del.textContent = 'Delete';
|
|
2198
|
+
del.textContent = translateUiText('Delete');
|
|
2125
2199
|
setScnErr('');
|
|
2126
2200
|
document.getElementById('scnDrawer').hidden = false;
|
|
2127
2201
|
document.body.style.overflow = 'hidden';
|
|
@@ -2156,7 +2230,7 @@ Omni output voices:
|
|
|
2156
2230
|
if (!prompt) { setScnErr('Prompt template is required.'); return; }
|
|
2157
2231
|
var res = collectScnInputs();
|
|
2158
2232
|
if (res.error) { setScnErr(res.error); return; }
|
|
2159
|
-
var cat = document.getElementById('scnCategory').value.trim() || 'Custom';
|
|
2233
|
+
var cat = document.getElementById('scnCategory').value.trim() || translateUiText('Custom');
|
|
2160
2234
|
var desc = document.getElementById('scnDesc').value.trim();
|
|
2161
2235
|
if (SCN_EDIT_KIND === 'builtin' && SCN_EDIT_ID && isBuiltin(SCN_EDIT_ID)) {
|
|
2162
2236
|
var ov = loadOverrides();
|
|
@@ -2212,10 +2286,10 @@ Omni output voices:
|
|
|
2212
2286
|
return '📄';
|
|
2213
2287
|
}
|
|
2214
2288
|
function assetKindLabel(kind) {
|
|
2215
|
-
if (kind === 'image') return 'Image';
|
|
2216
|
-
if (kind === 'video') return 'Video';
|
|
2217
|
-
if (kind === 'audio') return 'Audio';
|
|
2218
|
-
return 'File';
|
|
2289
|
+
if (kind === 'image') return translateUiText('Image');
|
|
2290
|
+
if (kind === 'video') return translateUiText('Video');
|
|
2291
|
+
if (kind === 'audio') return translateUiText('Audio');
|
|
2292
|
+
return translateUiText('File');
|
|
2219
2293
|
}
|
|
2220
2294
|
|
|
2221
2295
|
function fmtDim(w, h) { return w && h ? w + ' × ' + h : ''; }
|
|
@@ -2268,14 +2342,14 @@ Omni output voices:
|
|
|
2268
2342
|
tabs.forEach(function (t) {
|
|
2269
2343
|
var cat = t[0];
|
|
2270
2344
|
var b = el('button', 'filter' + (cat === ASSET_FILTER ? ' is-active' : ''));
|
|
2271
|
-
b.appendChild(
|
|
2345
|
+
b.appendChild(uiEl('span', '', t[1]));
|
|
2272
2346
|
b.appendChild(el('span', 'n', String(counts[cat] || 0)));
|
|
2273
2347
|
b.onclick = function () { ASSET_FILTER = cat; ASSET_PAGE = 1; renderAssetFilters(); renderAssets(); };
|
|
2274
2348
|
bar.appendChild(b);
|
|
2275
2349
|
});
|
|
2276
2350
|
var sort = el('button', 'filter sort-toggle');
|
|
2277
|
-
sort.title = 'Toggle sort by generation time';
|
|
2278
|
-
sort.textContent = ASSET_SORT === 'new' ? '↓ Newest first' : '↑ Oldest first';
|
|
2351
|
+
sort.title = translateUiText('Toggle sort by generation time');
|
|
2352
|
+
sort.textContent = translateUiText(ASSET_SORT === 'new' ? '↓ Newest first' : '↑ Oldest first');
|
|
2279
2353
|
sort.onclick = function () { ASSET_SORT = ASSET_SORT === 'new' ? 'old' : 'new'; ASSET_PAGE = 1; renderAssetFilters(); renderAssets(); };
|
|
2280
2354
|
bar.appendChild(sort);
|
|
2281
2355
|
}
|
|
@@ -2310,7 +2384,7 @@ Omni output voices:
|
|
|
2310
2384
|
var mediaEl = null;
|
|
2311
2385
|
if (a.kind === 'image') {
|
|
2312
2386
|
var img = el('img'); img.src = src; img.loading = 'lazy'; img.alt = a.name;
|
|
2313
|
-
img.title = 'View details';
|
|
2387
|
+
img.title = translateUiText('View details');
|
|
2314
2388
|
media.appendChild(img); mediaEl = img;
|
|
2315
2389
|
} else if (a.kind === 'video') {
|
|
2316
2390
|
var vid = el('video'); vid.src = src; vid.controls = true; vid.preload = 'metadata';
|
|
@@ -2322,16 +2396,16 @@ Omni output voices:
|
|
|
2322
2396
|
media.appendChild(au);
|
|
2323
2397
|
} else {
|
|
2324
2398
|
var icon = el('span', 'asset-icon', assetIcon(a.kind));
|
|
2325
|
-
icon.title = 'View details';
|
|
2399
|
+
icon.title = translateUiText('View details');
|
|
2326
2400
|
media.appendChild(icon);
|
|
2327
2401
|
}
|
|
2328
2402
|
card.appendChild(media);
|
|
2329
2403
|
card.appendChild(el('span', 'asset-cat', assetKindLabel(a.kind)));
|
|
2330
|
-
var del = el('button', 'asset-del', '×'); del.title = 'Delete';
|
|
2404
|
+
var del = el('button', 'asset-del', '×'); del.title = translateUiText('Delete');
|
|
2331
2405
|
del.onclick = function (e) { e.stopPropagation(); deleteAsset(a); };
|
|
2332
2406
|
card.appendChild(del);
|
|
2333
2407
|
var b = el('div', 'asset-body');
|
|
2334
|
-
var nm = el('div', 'asset-name link', a.name); nm.title = 'View details — ' + a.relPath;
|
|
2408
|
+
var nm = el('div', 'asset-name link', a.name); nm.title = translateUiText('View details — ') + a.relPath;
|
|
2335
2409
|
b.appendChild(nm);
|
|
2336
2410
|
var folder = assetFolder(a.relPath);
|
|
2337
2411
|
if (folder) {
|
|
@@ -2388,9 +2462,9 @@ Omni output voices:
|
|
|
2388
2462
|
body.appendChild(detailSection('Details', chips));
|
|
2389
2463
|
body.appendChild(detailSection('Path', el('div', 'detail-path', a.relPath)));
|
|
2390
2464
|
openInfoDrawer();
|
|
2391
|
-
var openBtn =
|
|
2465
|
+
var openBtn = uiEl('button', 'btn-primary', 'Open locally');
|
|
2392
2466
|
openBtn.onclick = function () { openAsset(a); };
|
|
2393
|
-
var delBtn =
|
|
2467
|
+
var delBtn = uiEl('button', 'btn-danger', 'Delete');
|
|
2394
2468
|
delBtn.onclick = function () { deleteAsset(a, true); };
|
|
2395
2469
|
var foot = document.getElementById('infoFoot');
|
|
2396
2470
|
foot.appendChild(openBtn); foot.appendChild(delBtn);
|
|
@@ -2418,6 +2492,8 @@ Omni output voices:
|
|
|
2418
2492
|
}
|
|
2419
2493
|
|
|
2420
2494
|
/* ---------- wiring ---------- */
|
|
2495
|
+
captureStaticUiCopy();
|
|
2496
|
+
applyStaticUiCopy();
|
|
2421
2497
|
var navItems = document.querySelectorAll('.nav-item');
|
|
2422
2498
|
for (var n = 0; n < navItems.length; n++) {
|
|
2423
2499
|
navItems[n].onclick = function () { showView(this.getAttribute('data-view')); };
|
|
@@ -2493,8 +2569,8 @@ Omni output voices:
|
|
|
2493
2569
|
var btn = document.getElementById('copyUrl');
|
|
2494
2570
|
btn.onclick = function () {
|
|
2495
2571
|
var done = function () {
|
|
2496
|
-
btn.textContent = 'Copied'; btn.classList.add('copied');
|
|
2497
|
-
setTimeout(function () { btn.textContent = 'Copy'; btn.classList.remove('copied'); }, 1400);
|
|
2572
|
+
btn.textContent = translateUiText('Copied'); btn.classList.add('copied');
|
|
2573
|
+
setTimeout(function () { btn.textContent = translateUiText('Copy'); btn.classList.remove('copied'); }, 1400);
|
|
2498
2574
|
};
|
|
2499
2575
|
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
2500
2576
|
navigator.clipboard.writeText(url).then(done).catch(function () { fallbackCopy(url); done(); });
|
|
@@ -2510,10 +2586,10 @@ Omni output voices:
|
|
|
2510
2586
|
}
|
|
2511
2587
|
|
|
2512
2588
|
function authMethodLabel(p) {
|
|
2513
|
-
if (p === 'console') return 'Console gateway';
|
|
2514
|
-
if (p === 'apiKey') return 'API key';
|
|
2589
|
+
if (p === 'console') return translateUiText('Console gateway');
|
|
2590
|
+
if (p === 'apiKey') return translateUiText('API key');
|
|
2515
2591
|
if (p === 'openapi') return 'OpenAPI (AK/SK)';
|
|
2516
|
-
return 'Account';
|
|
2592
|
+
return translateUiText('Account');
|
|
2517
2593
|
}
|
|
2518
2594
|
function acctHue(seed) {
|
|
2519
2595
|
var h = 0, s = seed || 'bl';
|
|
@@ -2558,7 +2634,7 @@ Omni output voices:
|
|
|
2558
2634
|
var meta = [];
|
|
2559
2635
|
if (st.region) meta.push(st.region);
|
|
2560
2636
|
if (st.site) meta.push(st.site);
|
|
2561
|
-
document.getElementById('acctMeta').textContent = meta.join(' · ') || 'Authenticated';
|
|
2637
|
+
document.getElementById('acctMeta').textContent = meta.join(' · ') || translateUiText('Authenticated');
|
|
2562
2638
|
var tok = document.getElementById('acctToken');
|
|
2563
2639
|
tok.textContent = st.masked || '';
|
|
2564
2640
|
tok.hidden = !st.masked;
|
|
@@ -2567,7 +2643,7 @@ Omni output voices:
|
|
|
2567
2643
|
closeAcctMenu();
|
|
2568
2644
|
loginBtn.hidden = false;
|
|
2569
2645
|
loginBtn.disabled = false;
|
|
2570
|
-
loginBtn.querySelector('span').textContent = 'Log in';
|
|
2646
|
+
loginBtn.querySelector('span').textContent = translateUiText('Log in');
|
|
2571
2647
|
}
|
|
2572
2648
|
}
|
|
2573
2649
|
function toggleAcctMenu() {
|
|
@@ -2585,8 +2661,9 @@ Omni output voices:
|
|
|
2585
2661
|
}
|
|
2586
2662
|
function setLoginUi(busy, label) {
|
|
2587
2663
|
var b = document.getElementById('loginBtn');
|
|
2588
|
-
|
|
2589
|
-
if (
|
|
2664
|
+
var translatedLabel = translateUiText(label);
|
|
2665
|
+
if (b) { b.disabled = busy; b.querySelector('span').textContent = translatedLabel; }
|
|
2666
|
+
if (QS_LOGIN_BTN && document.body.contains(QS_LOGIN_BTN)) { QS_LOGIN_BTN.disabled = busy; QS_LOGIN_BTN.textContent = translatedLabel; }
|
|
2590
2667
|
}
|
|
2591
2668
|
function startLogin() {
|
|
2592
2669
|
setLoginUi(true, 'Opening browser…');
|
|
@@ -2631,104 +2708,108 @@ Omni output voices:
|
|
|
2631
2708
|
<\/script>
|
|
2632
2709
|
</body>
|
|
2633
2710
|
</html>
|
|
2634
|
-
`)
|
|
2635
|
-
`)}
|
|
2636
|
-
`;)n+=1;continue}if(i===`/`&&a===`*`){for(n+=2;n<e.length&&!(e[n]===`*`&&e[n+1]===`/`);)n+=1;n+=2;continue}t+=i,n+=1}let i=``;for(n=0,r=!1;n<t.length;){let e=t[n];if(r){if(i+=e,e===`\\`){i+=t[n+1]??``,n+=2;continue}e===`"`&&(r=!1),n+=1;continue}if(e===`"`&&(r=!0),e===`,`){let e=n+1;for(;e<t.length&&/\s/.test(t[e]);)e+=1;if(t[e]===`}`||t[e]===`]`){n+=1;continue}}i+=e,n+=1}return i}function Ko(e){if(!Kn(e))return{};try{return JSON.parse(Jn(e,`utf-8`))}catch{return{}}}function qo(e){if(!Kn(e))return{};try{return JSON.parse(Go(Jn(e,`utf-8`)))}catch{return{}}}function Jo(e,t){qn($n(e),{recursive:!0});let n=e+`.tmp`;Zn(n,JSON.stringify(t,null,2)+`
|
|
2637
|
-
|
|
2638
|
-
`);let
|
|
2639
|
-
`),
|
|
2711
|
+
`,e)}function ka(e){try{return ar(e,`utf-8`)}catch{return}}function L(e){let t=ka(e);if(t!==void 0)try{let e=JSON.parse(t);return e&&typeof e==`object`&&!Array.isArray(e)?e:void 0}catch{return}}function R(e){return e&&typeof e==`object`&&!Array.isArray(e)?e:void 0}function Aa(e){let t=/^---\s*\n([\s\S]*?)\n---/.exec(e);if(!t)return{};try{return R(_r.parse(t[1]))??{}}catch{return{}}}function ja(e,t=500){let n=0,r=e=>{if(n>=t)return;let i;try{i=or(e,{withFileTypes:!0})}catch{return}for(let a of i){if(n>=t)return;let i=I(e,a.name);a.isDirectory()?r(i):n+=1}};return r(e),n}function Ma(e){return[{source:`global`,dir:I(e,`.agents`,`skills`)},{source:`claude-code`,dir:I(e,`.claude`,`skills`)},{source:`cursor`,dir:I(e,`.cursor`,`skills`)},{source:`qwen-code`,dir:I(e,`.qwen`,`skills`)},{source:`codex`,dir:I(e,`.codex`,`skills`)},{source:`opencode`,dir:I(e,`.config`,`opencode`,`skills`)},{source:`openclaw`,dir:I(e,`.openclaw`,`skills`)},{source:`openclaw`,dir:I(e,`.openclaw`,`workspace`,`skills`)},{source:`hermes`,dir:I(e,`.hermes`,`skills`)},{source:`gemini`,dir:I(e,`.gemini`,`skills`)},{source:`antigravity`,dir:I(e,`.gemini`,`antigravity`,`skills`)},{source:`windsurf`,dir:I(e,`.windsurf`,`skills`)},{source:`windsurf`,dir:I(e,`.codeium`,`windsurf`,`skills`)},{source:`qoderwork`,dir:I(e,`.qoderwork`,`skills`)},{source:`workbuddy`,dir:I(e,`.workbuddy`,`skills`)}]}function Na(e=hr()){let t=new Map;for(let{source:n,dir:r}of Ma(e)){let e;try{e=or(r,{withFileTypes:!0})}catch{continue}for(let i of e){if(!i.isDirectory()&&!i.isSymbolicLink())continue;let e=I(r,i.name),a=I(e,`SKILL.md`);if(!P(a))continue;let o=t.get(i.name);if(o){o.sources.includes(n)||o.sources.push(n);continue}let s=Aa(ka(a)??``),c=R(s.metadata),l=typeof s.description==`string`?s.description.trim():``,u=c&&typeof c.version==`string`?c.version:typeof s.version==`string`?s.version:void 0;t.set(i.name,{id:i.name,name:typeof s.name==`string`&&s.name?s.name:i.name,description:l,version:u,fileCount:ja(e),path:e,sources:[n],origin:`local`})}}return[...t.values()].sort((e,t)=>e.name.localeCompare(t.name))}function Pa(e,t=hr()){let n=Na(t).find(t=>t.id===e);if(!n)return null;let r=ka(I(n.path,`SKILL.md`))??``;return{...n,content:r}}const Fa=[{source:`global`,label:`All agents (~/.agents/skills)`,sub:[`.agents`,`skills`]},{source:`claude-code`,label:`Claude Code`,sub:[`.claude`,`skills`]},{source:`qwen-code`,label:`Qwen Code`,sub:[`.qwen`,`skills`]},{source:`codex`,label:`Codex`,sub:[`.codex`,`skills`]},{source:`opencode`,label:`OpenCode`,sub:[`.config`,`opencode`,`skills`]},{source:`openclaw`,label:`OpenClaw`,sub:[`.openclaw`,`skills`]},{source:`qoderwork`,label:`QoderWork`,sub:[`.qoderwork`,`skills`]},{source:`windsurf`,label:`Windsurf`,sub:[`.codeium`,`windsurf`,`skills`]},{source:`gemini`,label:`Gemini`,sub:[`.gemini`,`skills`]}];function Ia(e,t){let n=Fa.find(t=>t.source===e);return n?I(t,...n.sub):null}function La(e){let t=-1,n=Math.max(0,e.length-22-65535);for(let r=e.length-22;r>=n;r--)if(e.readUInt32LE(r)===101010256){t=r;break}if(t<0)throw Error(`Not a valid .zip archive.`);let r=e.readUInt16LE(t+10),i=e.readUInt32LE(t+16),a=[];for(let t=0;t<r&&!(i+46>e.length||e.readUInt32LE(i)!==33639248);t++){let t=e.readUInt16LE(i+10),n=e.readUInt32LE(i+20),r=e.readUInt16LE(i+28),o=e.readUInt16LE(i+30),s=e.readUInt16LE(i+32),c=e.readUInt32LE(i+42),l=e.toString(`utf8`,i+46,i+46+r);if(i+=46+r+o+s,l.endsWith(`/`)||c+30>e.length||e.readUInt32LE(c)!==67324752)continue;let u=e.readUInt16LE(c+26),d=e.readUInt16LE(c+28),f=c+30+u+d,p=e.subarray(f,f+n),m;if(t===0)m=Buffer.from(p);else if(t===8)m=gr(p);else throw Error(`Unsupported compression in archive (entry: `+l+`).`);a.push({name:l,data:m})}return a}function Ra(e,t,n,r=hr()){let i=Ia(e,r);if(!i)throw Error(`Unknown skill install target.`);let a=La(t).map(e=>({name:e.name.replace(/\\/g,`/`).replace(/^\.\//,``).replace(/^\/+/,``),data:e.data})).filter(e=>e.name&&!e.name.endsWith(`/`)&&!e.name.split(`/`).includes(`..`));if(!a.length)throw Error(`The archive contains no usable files.`);let o=a.find(e=>e.name===`SKILL.md`||e.name.endsWith(`/SKILL.md`));if(!o)throw Error(`No SKILL.md found in the archive (root or a top-level folder).`);let s=o.name.lastIndexOf(`/`),c,l;if(s<0){if(c=(n||``).trim(),!c)throw Error(`SKILL.md is at the archive root — please provide a skill name.`);l=``}else l=o.name.slice(0,s+1),c=(n||``).trim()||l.split(`/`)[0];if(!/^[A-Za-z0-9._-]+$/.test(c))throw Error(`Invalid skill name: `+c);let u=I(i,c),d=pr(u),f=0;for(let e of a){let t=e.name;if(l){if(!e.name.startsWith(l))continue;t=e.name.slice(l.length)}if(!t)continue;let n=pr(I(u,t));n!==d&&!n.startsWith(d+mr)||(ir(ur(n),{recursive:!0}),lr(n,e.data),f++)}if(f===0)throw Error(`Nothing was extracted from the archive.`);return{installed:c,files:f,dir:u}}function za(e){if(typeof e.command==`string`){let t=Array.isArray(e.args)?e.args.join(` `):``;return{transport:`stdio`,detail:`${e.command} ${t}`.trim()}}let t=typeof e.url==`string`?e.url:void 0;return t?{transport:(typeof e.type==`string`?e.type.toLowerCase():``)===`sse`?`sse`:`http`,detail:t}:{transport:`unknown`,detail:``}}function z(e,t,n,r,i){let a=R(e);if(a)for(let[e,o]of Object.entries(a)){let a=R(o)??{},{transport:s,detail:c}=za(a);r.push({name:e,source:t,transport:s,detail:c,scope:n,origin:`local`,config:Za(a),editable:i})}}function Ba(e=hr()){let t=[],n=L(I(e,`.claude.json`));if(n){z(n.mcpServers,`claude-code`,`global`,t,!0);let e=R(n.projects);if(e)for(let[n,r]of Object.entries(e)){let e=R(r);e?.mcpServers&&z(e.mcpServers,`claude-code`,n,t,!0)}}let r=L(I(e,`.qwen`,`settings.json`));r&&z(r.mcpServers,`qwen-code`,`global`,t,!0);let i=L(I(e,`.config`,`opencode`,`opencode.json`));i&&z(i.mcp,`opencode`,`global`,t,!0);let a=L(I(e,`.cursor`,`mcp.json`));a&&z(a.mcpServers,`cursor`,`global`,t,!0);let o=L(I(e,`.codeium`,`windsurf`,`mcp_config.json`));o&&z(o.mcpServers,`windsurf`,`global`,t,!0);let s=L(I(e,`.gemini`,`settings.json`));s&&z(s.mcpServers,`gemini`,`global`,t,!0);let c=L(I(e,`.qoderwork`,`mcp.json`));c&&z(c.mcpServers,`qoderwork`,`global`,t,!0);let l=L(I(e,`.openclaw`,`openclaw.json`));l&&z(l.mcpServers,`openclaw`,`global`,t,!0);let u=L(Va(e));u&&z(u.mcpServers,`claude-desktop`,`global`,t,!0);let d=ka(I(e,`.codex`,`config.toml`));if(d)try{z(vr(d).mcp_servers,`codex`,`global`,t,!1)}catch{}return t.sort((e,t)=>e.name.localeCompare(t.name)||e.source.localeCompare(t.source))}function Va(e){return process.platform===`darwin`?I(e,`Library`,`Application Support`,`Claude`,`claude_desktop_config.json`):process.platform===`win32`?I(process.env.APPDATA??I(e,`AppData`,`Roaming`),`Claude`,`claude_desktop_config.json`):I(e,`.config`,`Claude`,`claude_desktop_config.json`)}function Ha(e,t,n){return e===`claude-code`?{file:I(n,`.claude.json`),mapKey:`mcpServers`,projectScoped:t!==`global`}:e===`qwen-code`?{file:I(n,`.qwen`,`settings.json`),mapKey:`mcpServers`,projectScoped:!1}:e===`opencode`?{file:I(n,`.config`,`opencode`,`opencode.json`),mapKey:`mcp`,projectScoped:!1}:e===`cursor`?{file:I(n,`.cursor`,`mcp.json`),mapKey:`mcpServers`,projectScoped:!1}:e===`windsurf`?{file:I(n,`.codeium`,`windsurf`,`mcp_config.json`),mapKey:`mcpServers`,projectScoped:!1}:e===`gemini`?{file:I(n,`.gemini`,`settings.json`),mapKey:`mcpServers`,projectScoped:!1}:e===`qoderwork`?{file:I(n,`.qoderwork`,`mcp.json`),mapKey:`mcpServers`,projectScoped:!1}:e===`openclaw`?{file:I(n,`.openclaw`,`openclaw.json`),mapKey:`mcpServers`,projectScoped:!1}:e===`claude-desktop`?{file:Va(n),mapKey:`mcpServers`,projectScoped:!1}:null}function Ua(e,t){if(typeof e==`string`){if(e.includes(`•`)){if(typeof t==`string`)return t;throw Error(`Replace masked values (•••) with the real value before saving.`)}return e}if(Array.isArray(e)){let n=Array.isArray(t)?t:[];return e.map((e,t)=>Ua(e,n[t]))}let n=R(e);if(n){let e=R(t)??{},r={};for(let[t,i]of Object.entries(n))r[t]=Ua(i,e[t]);return r}return e}function Wa(e,t,n,r,i=hr()){let a=Ha(e,t,i);if(!a)throw Error(`This MCP source is read-only and cannot be edited here.`);let o=n.trim();if(!o)throw Error(`Server name is required.`);let s=R(r);if(!s)throw Error(`Config must be a JSON object.`);let c=L(a.file)??{},l=c;if(a.projectScoped){let e=R(c.projects)??{};c.projects=e;let n=R(e[t])??{};e[t]=n,l=n}let u=R(l[a.mapKey])??{};l[a.mapKey]=u,u[o]=Ua(s,R(u[o])),ir(ur(a.file),{recursive:!0}),lr(a.file,JSON.stringify(c,null,2)+`
|
|
2712
|
+
`,`utf-8`)}function Ga(e,t,n,r=hr()){let i=Ha(e,t,r);if(!i)throw Error(`This MCP source is read-only and cannot be edited here.`);let a=L(i.file);if(!a)throw Error(`Config file not found.`);let o=a;if(i.projectScoped){let e=R(a.projects);o=e?R(e[t]):void 0}let s=o?R(o[i.mapKey]):void 0;if(!s||!(n in s))throw Error(`Server not found: `+n);delete s[n],o&&Object.keys(s).length===0&&delete o[i.mapKey],lr(i.file,JSON.stringify(a,null,2)+`
|
|
2713
|
+
`,`utf-8`)}const Ka=[{id:`claude-code`,label:`Claude Code`,paths:e=>[I(process.env.CLAUDE_CONFIG_DIR||I(e,`.claude`),`settings.json`),I(e,`.claude.json`)],detect:e=>{let t=R(L(I(process.env.CLAUDE_CONFIG_DIR||I(e,`.claude`),`settings.json`))?.env),n=t&&typeof t.ANTHROPIC_BASE_URL==`string`?t.ANTHROPIC_BASE_URL:void 0,r=t&&typeof t.ANTHROPIC_MODEL==`string`?t.ANTHROPIC_MODEL:void 0;return{configured:!!n,model:r}}},{id:`qwen-code`,label:`Qwen Code`,paths:e=>[I(e,`.qwen`,`settings.json`)],detect:e=>{let t=L(I(e,`.qwen`,`settings.json`)),n=R(t?.modelProviders),r=n?Object.values(n).some(e=>Array.isArray(e)&&e.some(e=>{let t=R(e)?.name;return typeof t==`string`&&(t===`bailian-cli`||t.startsWith(`[Bailian]`))})):!1,i=R(t?.model);return{configured:r,model:i&&typeof i.name==`string`?i.name:void 0}}},{id:`opencode`,label:`OpenCode`,paths:e=>[I(e,`.config`,`opencode`,`opencode.json`)],detect:e=>{let t=R(R(L(I(e,`.config`,`opencode`,`opencode.json`))?.provider)?.[`bailian-cli`]),n=R(t?.models);return{configured:!!t,model:n?Object.keys(n)[0]:void 0}}},{id:`openclaw`,label:`OpenClaw`,paths:e=>[I(e,`.openclaw`,`openclaw.json`)],detect:e=>{let t=R(R(R(L(I(e,`.openclaw`,`openclaw.json`))?.models)?.providers)?.[`bailian-cli`]),n=R((Array.isArray(t?.models)?t.models:[])[0]);return{configured:!!t,model:n&&typeof n.id==`string`?n.id:void 0}}},{id:`hermes`,label:`Hermes Agent`,paths:e=>[I(e,`.hermes`,`config.yaml`)],detect:e=>{let t=ka(I(e,`.hermes`,`config.yaml`));if(!t)return{configured:!1};let n;try{n=R(_r.parse(t))}catch{return{configured:!1}}let r=(Array.isArray(n?.custom_providers)?n.custom_providers:[]).some(e=>R(e)?.name===`bailian-cli`),i=R(n?.model),a=!!(i&&i.provider===`custom`&&typeof i.base_url==`string`&&i.base_url.includes(`aliyuncs.com`));return{configured:r||a,model:i&&typeof i.default==`string`?i.default:void 0}}},{id:`codex`,label:`Codex`,paths:e=>[I(e,`.codex`,`config.toml`),I(e,`.codex`,`auth.json`)],detect:e=>{let t=ka(I(e,`.codex`,`config.toml`));if(!t)return{configured:!1};let n={};try{n=vr(t)}catch{return{configured:!1}}return{configured:!!R(n.model_providers)?.[`bailian-cli`],model:typeof n.model==`string`?n.model:void 0}}}];function qa(e=hr()){return Ka.map(t=>{let n=t.paths(e),r=n.some(e=>P(e)),{configured:i,model:a}=r?t.detect(e):{configured:!1,model:void 0};return{id:t.id,label:t.label,installed:r,configured:i,model:a,paths:n,origin:`local`}})}function B(e,t,n,r=!1){typeof n==`string`&&n.trim()&&e.push({label:t,value:n.trim(),secret:r})}function Ja(e,t){let n=[];if(e===`claude-code`){let e=R(L(I(t,`.claude`,`settings.json`))?.env);B(n,`Model`,e?.ANTHROPIC_MODEL),B(n,`Base URL`,e?.ANTHROPIC_BASE_URL),B(n,`Auth Token`,e?.ANTHROPIC_AUTH_TOKEN,!0)}else if(e===`qwen-code`){let e=L(I(t,`.qwen`,`settings.json`)),r=R(e?.model),i=R(R(e?.security)?.auth),a=R(e?.env);B(n,`Model`,r?.name),B(n,`Base URL`,i?.baseUrl??r?.baseUrl),B(n,`Protocol`,i?.selectedType),B(n,`API Key`,i?.apiKey??a?.BAILIAN_CLI_API_KEY,!0)}else if(e===`opencode`){let e=R(R(L(I(t,`.config`,`opencode`,`opencode.json`))?.provider)?.[`bailian-cli`]),r=R(e?.options),i=R(e?.models);B(n,`Model`,i?Object.keys(i)[0]:void 0),B(n,`Base URL`,r?.baseURL),B(n,`Provider`,e?.npm),B(n,`API Key`,r?.apiKey,!0)}else if(e===`openclaw`){let e=R(R(R(L(I(t,`.openclaw`,`openclaw.json`))?.models)?.providers)?.[`bailian-cli`]);B(n,`Model`,R((Array.isArray(e?.models)?e.models:[])[0])?.id),B(n,`Base URL`,e?.baseUrl),B(n,`API`,e?.api),B(n,`API Key`,e?.apiKey,!0)}else if(e===`hermes`){let e=ka(I(t,`.hermes`,`config.yaml`)),r;if(e)try{r=R(_r.parse(e))}catch{r=void 0}let i=R((Array.isArray(r?.custom_providers)?r.custom_providers:[]).find(e=>R(e)?.name===`bailian-cli`));B(n,`Model`,R((Array.isArray(i?.models)?i.models:[])[0])?.id??R(r?.model)?.default),B(n,`Base URL`,i?.base_url),B(n,`API Mode`,i?.api_mode),B(n,`API Key`,i?.api_key,!0)}else if(e===`codex`){let e=ka(I(t,`.codex`,`config.toml`)),r={};if(e)try{r=vr(e)}catch{r={}}let i=R(R(r.model_providers)?.[`bailian-cli`]),a=L(I(t,`.codex`,`auth.json`));B(n,`Model`,r.model),B(n,`Base URL`,i?.base_url),B(n,`Wire API`,i?.wire_api),B(n,`API Key`,a?.OPENAI_API_KEY,!0)}return n}function Ya(e){let t=e.trim();return t.length<=8?`•`.repeat(Math.max(t.length,4)):t.slice(0,3)+`•`.repeat(Math.min(t.length-3,16))}const Xa=/key|token|secret|password|passwd|auth|credential/i;function Za(e,t=``){if(typeof e==`string`)return t&&Xa.test(t)&&e.trim()?Ya(e):e;if(Array.isArray(e))return e.map(e=>Za(e));let n=R(e);if(n){let e={};for(let[t,r]of Object.entries(n))e[t]=Za(r,t);return e}return e}function Qa(e){return e.endsWith(`.json`)?`json`:e.endsWith(`.yaml`)||e.endsWith(`.yml`)?`yaml`:e.endsWith(`.toml`)?`toml`:`text`}function $a(e,t=hr()){let n=Ka.find(t=>t.id===e);if(!n)return null;let r=n.paths(t),i=r.some(e=>P(e)),{configured:a,model:o}=i?n.detect(t):{configured:!1,model:void 0},s=i?Ja(e,t).map(e=>e.secret?{...e,raw:e.value,value:Ya(e.value)}:e):[],c=r.map(e=>({path:e,exists:P(e)})),l=i?r.filter(e=>P(e)).map(e=>({path:e,lang:Qa(e),text:ka(e)??``})).filter(e=>e.text.trim()):[];return{id:n.id,label:n.label,installed:i,configured:a,model:o,paths:r,origin:`local`,fields:s,files:c,settings:l}}const eo={"claude-code":`claude`,"qwen-code":`qwen`,opencode:`opencode`,openclaw:`openclaw`,hermes:`hermes`,codex:`codex`};function to(e){return Object.prototype.hasOwnProperty.call(eo,e)?eo[e]:void 0}const no={"qwen-code":e=>[`-i`,e],"claude-code":e=>[e],codex:e=>[e]};function ro(e){return Object.prototype.hasOwnProperty.call(no,e)}function io(e){let t=process.platform===`win32`?`where`:`which`;return new Promise(n=>{Gn(t,[e],{windowsHide:!0},e=>n(!e))})}function ao(e){let t=to(e);return t?io(t):Promise.resolve(!1)}function oo(e){return`'${e.replace(/'/g,`'\\''`)}'`}function so(e,t){let n=process.platform;return new Promise((r,i)=>{if(n===`darwin`){Gn(`osascript`,[`-e`,`tell application "Terminal" to do script "${`cd ${oo(t)} && ${e}`.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`)}"`,`-e`,`tell application "Terminal" to activate`],{windowsHide:!0},e=>e?i(e):r());return}if(n===`win32`){Gn(`cmd`,[`/c`,`start`,``,`cmd`,`/k`,`cd /d ${t} && ${e}`],{windowsHide:!0},e=>e?i(e):r());return}Gn(`x-terminal-emulator`,[`-e`,`bash`,`-lc`,`cd ${oo(t)} && ${e}; exec $SHELL`],{windowsHide:!0},e=>e?i(Error(`No supported terminal emulator was found`)):r())})}async function co(e,t=process.cwd(),n){let r=to(e);if(!r)throw Error(`Unknown agent: ${e}`);if(!await io(r))throw Error(`\`${r}\` was not found on your PATH — install ${e} first.`);let i=r,a=(n??``).trim();if(a){let t=no[e];if(!t)throw Error(`${e} does not support dispatching a task prompt.`);i=[r,...t(a).map(oo)].join(` `)}return await so(i,t),{launched:!0,command:i}}const lo=[{id:`image-generate`,title:`文生图`,description:`一键生成一张示例图片并保存到输出目录。`,category:`图像`,prompt:"请使用 bl 的图像生成能力(如 `bl image generate` 命令)生成一张示例图片:一只在雨中撑伞的柯基,水彩风格,光线柔和。保存到输出目录后告诉我文件路径。"},{id:`image-describe`,title:`图片理解`,description:`从输出目录任选一张图片,详细描述内容与风格。`,category:`图像`,prompt:`请在输出目录(默认 output/images)中任选一张图片,用中文详细描述它的内容、主体、构图、色彩与风格,并推测它适合的使用场景。若目录为空请说明。`},{id:`image-alt-batch`,title:`批量 Alt 文本`,description:`为输出目录下的图片批量生成无障碍 alt 文本。`,category:`图像`,prompt:`请扫描输出目录(默认 output/images)下的所有图片,逐张生成简洁、准确的 alt 无障碍描述,最后以「文件名 → alt 文本」的表格汇总。若目录为空请说明。`},{id:`image-to-code`,title:`截图转代码`,description:`把输出目录里的界面截图还原成 HTML+CSS。`,category:`图像`,prompt:`请在输出目录(默认 output/images)中查找一张界面截图,用 HTML + CSS 尽可能还原它的布局、间距与配色,输出为一个可直接在浏览器打开的单文件,并简述还原思路。若没有找到截图请说明。`},{id:`speech-generate`,title:`文字转语音`,description:`把一句示例文字合成为自然语音。`,category:`音频`,prompt:"请使用 bl 的语音合成能力(如 `bl speech` 相关命令)把下面这句话合成为自然语音,保存到输出目录,并告诉我音频文件路径:欢迎使用阿里云百炼命令行工具,让多模态创作更简单。"},{id:`audio-summarize`,title:`音频转写总结`,description:`转写输出目录里的音频并提炼要点。`,category:`音频`,prompt:`请在输出目录(默认 output/speech)中找到一个音频文件,转写其内容,先给出完整文字,再用要点列表总结关键信息。若目录为空或缺少转写能力,请说明并尝试用可用的能力完成。`},{id:`video-generate`,title:`文生视频`,description:`一键生成一段示例短视频。`,category:`视频`,prompt:"请使用 bl 的视频生成能力(如 `bl video generate` 命令)生成一段示例短视频:日落时分海边奔跑的少年,电影质感,慢动作。保存到输出目录后告诉我视频文件路径。"},{id:`video-storyboard`,title:`视频分镜脚本`,description:`围绕示例主题产出可用于文生视频的分镜。`,category:`视频`,prompt:`围绕主题「城市清晨的第一杯咖啡」,为一支 15-30 秒的短视频撰写分镜脚本:逐镜头给出画面描述、时长、字幕或旁白,并为每个镜头附上可直接用于文生视频的英文 prompt。`},{id:`media-prompt-craft`,title:`多模态提示词`,description:`把一个示例创意扩展成图/视频/语音提示词。`,category:`多模态`,prompt:`把创意「未来赛博城市的夜市」扩展成三组高质量生成提示词:1) 文生图;2) 文生视频;3) 语音风格描述。每组给出中英对照,并简要说明关键参数建议。`},{id:`image-story-narration`,title:`图片配音文案`,description:`为输出目录里的图片写解说词并给出可合成文本。`,category:`多模态`,prompt:`请在输出目录(默认 output/images)中任选一张图片,为它撰写一段 60 秒左右的中文解说词(适合配音),语气生动。随后给出可直接用于语音合成的纯文本版本。若目录为空请说明。`},{id:`summarize-project`,title:`总结当前项目`,description:`让 agent 阅读当前目录,总结架构、技术栈与主要模块。`,category:`代码`,prompt:`请阅读当前工作目录的项目结构和关键源码,用简洁的中文总结:1) 它是做什么的;2) 技术栈;3) 主要模块及其职责;4) 值得注意的设计。先浏览再下结论,不要臆测。`},{id:`write-tests`,title:`为核心模块写单测`,description:`自动挑选缺测试的核心模块并补全单元测试。`,category:`代码`,prompt:`请在当前项目中挑选一个核心且缺少测试(或测试薄弱)的模块,为它编写全面的单元测试,覆盖主要逻辑分支和边界情况,并遵循本项目现有的测试框架与风格。先阅读相关文件及其依赖,再编写测试。`},{id:`code-review`,title:`代码审查`,description:`审查当前项目核心代码,指出问题与改进建议。`,category:`代码`,prompt:`请审查当前项目的核心源码,指出潜在的 bug、安全隐患、性能与可维护性问题,并给出具体、可操作的改进建议,按严重程度排序。先浏览项目结构,选取关键文件再审查。`},{id:`explain-code`,title:`解释核心代码`,description:`挑选入口或核心模块,解释其实现与依赖。`,category:`代码`,prompt:`请挑选当前项目的入口文件或核心模块,解释它的实现:职责是什么、关键流程如何运转、依赖了哪些模块。用清晰的中文说明,必要时给出调用关系。`},{id:`generate-readme`,title:`生成 README`,description:`阅读代码后生成结构清晰、与实现一致的 README.md。`,category:`文档`,prompt:`为当前工作目录的项目生成一个结构清晰的 README.md,包含:项目简介、安装步骤、使用示例、目录结构说明。请先阅读现有代码与配置再撰写,内容必须与实际实现一致。`}],uo={"image-generate":{title:`Text to image`,description:`Generate a sample image and save it to the output directory.`,category:`Image`,prompt:"Use bl's image generation capability (such as `bl image generate`) to create a sample image: a corgi holding an umbrella in the rain, watercolor style, with soft lighting. Save it to the output directory and tell me the file path."},"image-describe":{title:`Image understanding`,description:`Pick an image from the output directory and describe its content and style.`,category:`Image`,prompt:`Pick an image from the output directory (output/images by default). Describe its subject, composition, colors, and style in detail, then suggest suitable use cases. If the directory is empty, say so.`},"image-alt-batch":{title:`Batch alt text`,description:`Generate accessible alt text for images in the output directory.`,category:`Image`,prompt:`Scan all images in the output directory (output/images by default) and write concise, accurate accessibility alt text for each one. Summarize the results in a File name -> Alt text table. If the directory is empty, say so.`},"image-to-code":{title:`Screenshot to code`,description:`Recreate a UI screenshot from the output directory with HTML and CSS.`,category:`Image`,prompt:`Find a UI screenshot in the output directory (output/images by default) and recreate its layout, spacing, and colors as closely as possible with HTML and CSS. Save it as a single file that opens directly in a browser and briefly explain your approach. If no screenshot is available, say so.`},"speech-generate":{title:`Text to speech`,description:`Turn a sample sentence into natural speech.`,category:`Audio`,prompt:"Use bl's speech synthesis capability (such as a `bl speech` command) to turn this sentence into natural speech: Welcome to Alibaba Cloud Model Studio CLI, making multimodal creation easier. Save the audio to the output directory and tell me the file path."},"audio-summarize":{title:`Transcribe and summarize audio`,description:`Transcribe an audio file from the output directory and summarize its key points.`,category:`Audio`,prompt:`Find an audio file in the output directory (output/speech by default), transcribe it, provide the full transcript, and then summarize the key points as a list. If the directory is empty or transcription is unavailable, explain that and try to complete the task with the capabilities available.`},"video-generate":{title:`Text to video`,description:`Generate a sample short video.`,category:`Video`,prompt:"Use bl's video generation capability (such as `bl video generate`) to create a sample short video: a teenager running along the beach at sunset, cinematic, in slow motion. Save it to the output directory and tell me the file path."},"video-storyboard":{title:`Video storyboard`,description:`Create a storyboard suitable for text-to-video generation.`,category:`Video`,prompt:`Create a storyboard for a 15-30 second short video themed The first cup of coffee in the city at dawn. For each shot, provide the visual description, duration, subtitles or narration, and an English prompt ready for text-to-video generation.`},"media-prompt-craft":{title:`Multimodal prompts`,description:`Expand a sample idea into image, video, and speech prompts.`,category:`Multimodal`,prompt:`Expand the idea A night market in a futuristic cyber city into three high-quality generation prompts: 1) text to image, 2) text to video, and 3) speech style. Provide each prompt in both Chinese and English, with brief parameter recommendations.`},"image-story-narration":{title:`Image narration`,description:`Write narration for an image in the output directory.`,category:`Multimodal`,prompt:`Pick an image from the output directory (output/images by default) and write an engaging English narration of about 60 seconds. Then provide a plain-text version ready for speech synthesis. If the directory is empty, say so.`},"summarize-project":{title:`Summarize this project`,description:`Read the current directory and summarize its architecture, stack, and main modules.`,category:`Code`,prompt:`Inspect the project structure and key source files in the current working directory, then concisely summarize: 1) what it does, 2) its technology stack, 3) its main modules and their responsibilities, and 4) notable design choices. Inspect the code before drawing conclusions; do not guess.`},"write-tests":{title:`Add tests for a core module`,description:`Choose an under-tested core module and add unit tests.`,category:`Code`,prompt:`Choose a core module in the current project that has no tests or weak coverage. Add comprehensive unit tests for its main branches and edge cases, following the project's existing test framework and style. Read the relevant files and dependencies before writing tests.`},"code-review":{title:`Code review`,description:`Review core project code and identify concrete improvements.`,category:`Code`,prompt:`Review the current project's core source code for potential bugs, security risks, performance issues, and maintainability problems. Give specific, actionable recommendations ordered by severity. Inspect the project structure and select the key files before reviewing them.`},"explain-code":{title:`Explain core code`,description:`Choose an entry point or core module and explain how it works.`,category:`Code`,prompt:`Choose the current project's entry point or a core module and explain its responsibilities, key execution flow, and dependencies. Use clear English and include the call relationships when useful.`},"generate-readme":{title:`Generate README`,description:`Generate a clear README.md that matches the implementation.`,category:`Documentation`,prompt:`Generate a clear README.md for the project in the current working directory. Include an overview, installation steps, usage examples, and a directory structure guide. Read the existing source code and configuration first; the content must match the actual implementation.`}};function fo(e){return e===`zh-CN`?lo.map(e=>({...e})):lo.map(e=>({...e,...uo[e.id]}))}function po(e,t){return fo(t).find(t=>t.id===e)}function mo(e,t){return e.prompt.replace(/\{\{(\w+)\}\}/g,(e,n)=>{let r=t[n];return typeof r==`string`?r.trim():``})}const ho=new Uint8Array(512),go=new Uint8Array(256);(()=>{let e=1;for(let t=0;t<255;t++)ho[t]=e,go[e]=t,e<<=1,e&256&&(e^=285);for(let e=255;e<512;e++)ho[e]=ho[e-255]})();function _o(e,t){return e===0||t===0?0:ho[go[e]+go[t]]}function vo(e){let t=[1];for(let n=0;n<e;n++){let e=Array.from({length:t.length+1},()=>0);for(let r=0;r<t.length;r++)e[r]^=t[r],e[r+1]^=_o(t[r],ho[n]);t=e}return t.map(e=>go[e])}function yo(e,t){let n=vo(t),r=new Uint8Array(e.length+t);r.set(e,0);for(let t=0;t<e.length;t++){let e=r[t];if(e!==0){let i=go[e];for(let e=0;e<n.length;e++)r[t+e]^=ho[(n[e]+i)%255]}}return Array.from(r.slice(e.length))}const bo=[[19,7],[34,10],[55,15],[80,20],[108,26]];function xo(e){let t=12+e*8;for(let e=0;e<bo.length;e++)if(bo[e][0]*8>=t)return e+1;throw Error(`qr: data too large for supported versions (max 108 bytes)`)}function So(e,t){let[n]=bo[t-1],r=[],i=(e,t)=>{for(let n=t-1;n>=0;n--)r.push(e>>n&1)};i(4,4),i(e.length,8);for(let t of e)i(t,8);let a=n*8;for(i(0,Math.min(4,a-r.length));r.length%8!=0;)r.push(0);let o=[];for(let e=0;e<r.length;e+=8){let t=0;for(let n=0;n<8;n++)t=t<<1|r[e+n];o.push(t)}let s=[236,17];for(let e=0;o.length<n;e++)o.push(s[e%2]);return o.concat(yo(o,bo[t-1][1]))}function Co(e){return{size:e,mod:new Uint8Array(e*e),fn:new Uint8Array(e*e)}}function wo(e,t,n,r){e.mod[t*e.size+n]=r,e.fn[t*e.size+n]=1}function To(e,t,n){for(let r=-1;r<=7;r++)for(let i=-1;i<=7;i++){let a=t+r,o=n+i;a<0||a>=e.size||o<0||o>=e.size||wo(e,a,o,+(r>=0&&r<=6&&i>=0&&i<=6&&(r===0||r===6||i===0||i===6||r>=2&&r<=4&&i>=2&&i<=4)))}}function Eo(e,t,n){for(let r=-2;r<=2;r++)for(let i=-2;i<=2;i++){let a=Math.max(Math.abs(r),Math.abs(i));wo(e,t+r,n+i,a===1?0:1)}}function Do(e,t){let n=e.size;for(let t=0;t<n;t++)wo(e,6,t,+(t%2==0)),wo(e,t,6,+(t%2==0));if(To(e,0,0),To(e,0,n-7),To(e,n-7,0),t>=2){let t=n-7;Eo(e,t,t)}for(let t=0;t<9;t++)t!==6&&(e.fn[8*n+t]=1),t!==6&&(e.fn[t*n+8]=1);e.fn[8*n+6]=1,e.fn[6*n+8]=1;for(let t=0;t<8;t++)e.fn[(n-1-t)*n+8]=1;for(let t=0;t<8;t++)e.fn[8*n+(n-1-t)]=1;wo(e,n-8,8,1)}function Oo(e,t){let n=e.size,r=[];for(let e of t)for(let t=7;t>=0;t--)r.push(e>>t&1);let i=0,a=!0;for(let t=n-1;t>=1;t-=2){t===6&&(t=5);for(let o=0;o<n;o++){let s=a?n-1-o:o;for(let a of[0,1]){let o=t-a;e.fn[s*n+o]||(e.mod[s*n+o]=i<r.length?r[i++]:0)}}a=!a}}const ko=[(e,t)=>(e+t)%2==0,e=>e%2==0,(e,t)=>t%3==0,(e,t)=>(e+t)%3==0,(e,t)=>(Math.floor(e/2)+Math.floor(t/3))%2==0,(e,t)=>e*t%2+e*t%3==0,(e,t)=>(e*t%2+e*t%3)%2==0,(e,t)=>((e+t)%2+e*t%3)%2==0];function Ao(e,t){let n=ko[t];for(let t=0;t<e.size;t++)for(let r=0;r<e.size;r++)!e.fn[t*e.size+r]&&n(t,r)&&(e.mod[t*e.size+r]^=1)}function jo(e){let t=e.size,n=(n,r)=>e.mod[n*t+r],r=0;for(let e=0;e<t;e++){let i=1,a=1;for(let o=1;o<t;o++)n(e,o)===n(e,o-1)?i++:(i>=5&&(r+=i-2),i=1),n(o,e)===n(o-1,e)?a++:(a>=5&&(r+=a-2),a=1);i>=5&&(r+=i-2),a>=5&&(r+=a-2)}for(let e=0;e<t-1;e++)for(let i=0;i<t-1;i++){let t=n(e,i);t===n(e,i+1)&&t===n(e+1,i)&&t===n(e+1,i+1)&&(r+=3)}let i=[1,0,1,1,1,0,1,0,0,0,0],a=[0,0,0,0,1,0,1,1,1,0,1],o=(e,t,n)=>{for(let r=0;r<n.length;r++)if(e(t+r)!==n[r])return!1;return!0};for(let e=0;e<t;e++)for(let s=0;s<=t-11;s++)(o(t=>n(e,t),s,i)||o(t=>n(e,t),s,a))&&(r+=40),(o(t=>n(t,e),s,i)||o(t=>n(t,e),s,a))&&(r+=40);let s=0;for(let n=0;n<t*t;n++)s+=e.mod[n];let c=s*100/(t*t),l=Math.floor(Math.abs(c-50)/5);return r+=l*10,r}function Mo(e){let t=8|e,n=t<<10;for(let e=14;e>=10;e--)n>>e&1&&(n^=1335<<e-10);return(t<<10|n)^21522}function No(e,t){let n=e.size,r=Mo(t),i=e=>r>>e&1;for(let t=0;t<=5;t++)e.mod[t*n+8]=i(t);e.mod[7*n+8]=i(6),e.mod[8*n+8]=i(7),e.mod[8*n+7]=i(8);for(let t=9;t<15;t++)e.mod[8*n+(14-t)]=i(t);for(let t=0;t<8;t++)e.mod[(n-1-t)*n+8]=i(t);for(let t=8;t<15;t++)e.mod[8*n+(n-15+t)]=i(t);e.mod[(n-8)*n+8]=1}function Po(e){let t=new TextEncoder().encode(e),n=xo(t.length),r=So(t,n),i=Co(17+4*n);Do(i,n),Oo(i,r);let a=0,o=1/0;for(let e=0;e<8;e++){Ao(i,e),No(i,e);let t=jo(i);t<o&&(o=t,a=e),Ao(i,e)}Ao(i,a),No(i,a);let s=[];for(let e=0;e<i.size;e++){let t=[];for(let n=0;n<i.size;n++)t.push(i.mod[e*i.size+n]===1);s.push(t)}return s}function Fo(e){let t=Po(e),n=t.length,r=n+8,i=``;for(let e=0;e<n;e++)for(let r=0;r<n;r++)t[e][r]&&(i+=`<rect x="${r+4}" y="${e+4}" width="1" height="1"/>`);return`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${r} ${r}" shape-rendering="crispEdges" role="img" aria-label="QR code"><rect width="${r}" height="${r}" fill="#ffffff"/><g fill="#000000">${i}</g></svg>`}function Io(e){let{identity:t,settings:n,authStore:r}=e;return{status(){let e=r.describe(),t={apiKey:!!e.apiKey,console:!!e.console,openapi:!!e.openapi},n;e.console?n=pt(e.console.token):e.apiKey?n=pt(e.apiKey.token):e.openapi&&(n=pt(e.openapi.accessKeyId));let i=e.console?`console`:e.apiKey?`apiKey`:e.openapi?`openapi`:null;return{authenticated:t.apiKey||t.console||t.openapi,methods:t,primary:i,region:e.console?.region,site:e.console?.site,masked:n}},startConsoleLogin(){let e=ci(r.describe().console?.site),i=!!r.stored().apiKey;Ci(e,{identity:t,settings:n,authStore:r},{needApiKey:!i}).catch(e=>{let t=e instanceof Error?e.message:String(e);process.stderr.write(`console login failed: ${t}\n`)})},logout(){return r.logout(`all`)}}}const Lo={".png":`image`,".jpg":`image`,".jpeg":`image`,".webp":`image`,".gif":`image`,".bmp":`image`,".svg":`image`,".mp4":`video`,".mov":`video`,".webm":`video`,".mkv":`video`,".avi":`video`,".mp3":`audio`,".wav":`audio`,".m4a":`audio`,".aac":`audio`,".flac":`audio`,".ogg":`audio`},Ro={".png":`image/png`,".jpg":`image/jpeg`,".jpeg":`image/jpeg`,".webp":`image/webp`,".gif":`image/gif`,".bmp":`image/bmp`,".svg":`image/svg+xml`,".mp4":`video/mp4`,".mov":`video/quicktime`,".webm":`video/webm`,".mkv":`video/x-matroska`,".avi":`video/x-msvideo`,".mp3":`audio/mpeg`,".wav":`audio/wav`,".m4a":`audio/mp4`,".aac":`audio/aac`,".flac":`audio/flac`,".ogg":`audio/ogg`};function zo(e=hr()){return I(e,`bailian-output`)}function Bo(e){return Lo[e.toLowerCase()]??`other`}function Vo(e){return Ro[e.toLowerCase()]??`application/octet-stream`}function Ho(e,t,n){let r;try{r=or(e,{withFileTypes:!0})}catch{return}for(let i of r){let r=I(e,i.name);i.isDirectory()?t>0&&Ho(r,t-1,n):(i.isFile()||i.isSymbolicLink())&&n.push(r)}}function Uo(e=zo()){let t=[];if(!P(e))return{base:e,assets:t};let n=[];Ho(e,8,n);for(let r of n){let n;try{n=sr(r)}catch{continue}if(!n.isFile())continue;let i=fr(e,r),a=i.split(mr),o=a.length>1?a[0]:`other`,s=dr(r);t.push({name:r.split(mr).pop()??r,category:o,kind:Bo(s),relPath:i,size:n.size,mtime:n.mtimeMs,ext:s.replace(/^\./,``).toLowerCase()})}return t.sort((e,t)=>t.mtime-e.mtime),{base:e,assets:t}}function Wo(e,t){if(typeof t!=`string`||t.length===0)return null;let n=pr(e),r=pr(n,t);return r!==n&&!r.startsWith(n+mr)?null:r}const Go={port:{type:`number`,valueHint:`<port>`,description:{"en-US":`Port to listen on (default: random free port)`,"zh-CN":`监听端口(默认:随机可用端口)`}},noOpen:{type:`switch`,description:{"en-US":`Do not open the browser automatically`,"zh-CN":`不自动打开浏览器`}}};function V(e){return e instanceof t||e instanceof Error?e.message:String(e)}function H(e,t,n){e.writeHead(t,{"Content-Type":`application/json; charset=utf-8`}),e.end(JSON.stringify(n))}function Ko(e){return e.read().language??a}function qo(e){return new Promise((t,n)=>{let r=0,i=[];e.on(`data`,t=>{if(r+=t.length,r>1048576){n(Error(`payload too large`)),e.destroy();return}i.push(t)}),e.on(`end`,()=>t(Buffer.concat(i).toString(`utf8`))),e.on(`error`,n)})}function Jo(e,t){return new Promise((n,r)=>{let i=0,a=[];e.on(`data`,n=>{if(i+=n.length,i>t){r(Error(`payload too large`)),e.destroy();return}a.push(n)}),e.on(`end`,()=>n(Buffer.concat(a))),e.on(`error`,r)})}function Yo(e,t){if(!e)return!1;let n=Buffer.from(e),r=Buffer.from(t);return n.length===r.length&&Un(n,r)}function Xo(e){let t={};for(let[n,r]of Object.entries(e)){let e=``;typeof r==`string`?e=r:(typeof r==`number`||typeof r==`boolean`)&&(e=String(r)),e!==``&&(t[va(n)]=ba(n,e))}return t}function Zo(e,t){let n=new Set(fa),r={};for(let[t,i]of Object.entries(e))n.has(t)||(r[t]=i);return{...r,...t}}function Qo(e,t,n=zo(),r){let i=null,o=()=>i===null?Ko(t):Mt(i===`default`?void 0:i).language??a;return Wn.createServer(async(a,s)=>{try{let c=(a.headers.host||``).split(`:`)[0];if(c!==`127.0.0.1`&&c!==`localhost`){s.writeHead(403,{"Content-Type":`text/plain; charset=utf-8`}),s.end(`forbidden host
|
|
2714
|
+
`);return}let l=new URL(a.url??`/`,`http://127.0.0.1`);if(!Yo(l.searchParams.get(`token`),e)){s.writeHead(401,{"Content-Type":`text/plain; charset=utf-8`}),s.end(`unauthorized
|
|
2715
|
+
`);return}let u=a.method??`GET`,d=l.pathname;if(d===`/`&&u===`GET`){s.writeHead(200,{"Content-Type":`text/html; charset=utf-8`,"Cache-Control":`no-store`,"X-Content-Type-Options":`nosniff`,"Content-Security-Policy":`default-src 'self'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; img-src 'self' data: https://img.alicdn.com https://oss.aliyuncs.com; media-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'`}),s.end(Oa(o()));return}if(d===`/api/qr`&&u===`GET`){let e=(l.searchParams.get(`data`)??``).slice(0,512);if(!e){H(s,400,{error:`missing data`});return}try{let t=Fo(e);s.writeHead(200,{"Content-Type":`image/svg+xml; charset=utf-8`,"Cache-Control":`no-store`}),s.end(t)}catch(e){H(s,400,{error:V(e)})}return}if(d===`/api/config`&&u===`GET`){let e=t.profiles();H(s,200,{configFile:t.path,keys:fa,secretKeys:[...ua],enums:pa,booleanKeys:[...ma],fieldDefaults:{...ha,base_url:m.cn,output_dir:zo(),timeout:`300`},modelCatalog:ga,activeProfile:e.active,default:e.default,named:e.named});return}if(d===`/api/skills`&&u===`GET`){H(s,200,{skills:Na()});return}if(d===`/api/skill`&&u===`GET`){let e=Pa(l.searchParams.get(`id`)??``);if(!e){H(s,404,{error:`not found`});return}H(s,200,e);return}if(d===`/api/skill/install`&&u===`POST`){let e=l.searchParams.get(`source`)??``,t=l.searchParams.get(`name`)??``;try{H(s,200,Ra(e,await Jo(a,25165824),t))}catch(e){H(s,400,{error:V(e)})}return}if(d===`/api/mcp`&&u===`GET`){H(s,200,{servers:Ba()});return}if(d===`/api/mcp`&&u===`POST`){let e=await qo(a),t;try{t=JSON.parse(e)}catch{H(s,400,{error:`invalid JSON body`});return}let n=t,r=typeof n.source==`string`?n.source:``,i=typeof n.scope==`string`&&n.scope?n.scope:`global`,o=typeof n.name==`string`?n.name:``;try{Wa(r,i,o,n.config),H(s,200,{saved:o.trim()})}catch(e){H(s,400,{error:V(e)})}return}if(d===`/api/mcp`&&u===`DELETE`){let e=l.searchParams.get(`source`)??``,t=l.searchParams.get(`scope`)||`global`,n=l.searchParams.get(`name`)??``;try{Ga(e,t,n),H(s,200,{deleted:n})}catch(e){H(s,400,{error:V(e)})}return}if(d===`/api/health`&&u===`GET`){let e=Number(process.versions.node.split(`.`)[0]);H(s,200,{node:process.version,nodeOk:Number.isFinite(e)&&e>=18,platform:process.platform,cwd:process.cwd()});return}if(d===`/api/agents`&&u===`GET`){let e=qa(),t=await Promise.all(e.map(e=>ao(e.id)));H(s,200,{agents:e.map((e,n)=>({...e,launchable:t[n],dispatchable:t[n]&&ro(e.id)}))});return}if(d===`/api/agent`&&u===`GET`){let e=$a(l.searchParams.get(`id`)??``);if(!e){H(s,404,{error:`not found`});return}H(s,200,e);return}if(d===`/api/agent/open`&&u===`POST`){let e=$a(l.searchParams.get(`id`)??``),t=l.searchParams.get(`path`)??``,n=e?.settings.some(e=>e.path===t)??!1;if(!e||!n||!P(t)){H(s,404,{error:`not found`});return}try{await ii(t),H(s,200,{opened:t})}catch(e){H(s,400,{error:V(e)})}return}if(d===`/api/scenarios`&&u===`GET`){let e=qa(),t=await Promise.all(e.map(e=>ao(e.id))),n=e.map((e,n)=>({id:e.id,label:e.label,dispatchable:t[n]&&ro(e.id)})).filter(e=>e.dispatchable);H(s,200,{scenarios:fo(o()),agents:n});return}if(d===`/api/auth/status`&&u===`GET`){H(s,200,r?r.status():{authenticated:!1,methods:{apiKey:!1,console:!1,openapi:!1},primary:null});return}if(d===`/api/auth/login`&&u===`POST`){if(!r){H(s,400,{error:`login unavailable`});return}r.startConsoleLogin(),H(s,200,{started:!0});return}if(d===`/api/auth/logout`&&u===`POST`){if(!r){H(s,400,{error:`logout unavailable`});return}try{H(s,200,{loggedOut:await r.logout()})}catch(e){H(s,400,{error:V(e)})}return}if(d===`/api/assets`&&u===`GET`){H(s,200,Uo(n));return}if(d===`/api/asset/file`&&u===`GET`){let e=Wo(n,l.searchParams.get(`path`)??``),t=e&&P(e)?sr(e):null;if(!e||!t||!t.isFile()){H(s,404,{error:`not found`});return}s.writeHead(200,{"Content-Type":Vo(dr(e)),"Content-Length":t.size,"Cache-Control":`no-store`});let r=rr(e);r.on(`error`,()=>{s.headersSent||s.writeHead(500),s.end()}),r.pipe(s);return}if(d===`/api/asset`&&u===`DELETE`){let e=l.searchParams.get(`path`)??``,t=Wo(n,e);if(!t||!P(t)||!sr(t).isFile()){H(s,404,{error:`not found`});return}try{cr(t),H(s,200,{deleted:e})}catch(e){H(s,400,{error:V(e)})}return}if(d===`/api/asset/open`&&u===`POST`){let e=l.searchParams.get(`path`)??``,t=Wo(n,e);if(!t||!P(t)||!sr(t).isFile()){H(s,404,{error:`not found`});return}try{await ii(t),H(s,200,{opened:e})}catch(e){H(s,400,{error:V(e)})}return}if(d===`/api/agent/launch`&&u===`POST`){try{H(s,200,await co(l.searchParams.get(`id`)??``))}catch(e){H(s,400,{error:V(e)})}return}if(d===`/api/agent/dispatch`&&u===`POST`){let e=await qo(a),t;try{t=JSON.parse(e)}catch{H(s,400,{error:`invalid JSON body`});return}let n=t,r=typeof n.agent==`string`?n.agent:``;if(!ro(r)){H(s,400,{error:`agent cannot be dispatched a prompt`});return}let i,c=n.custom;if(c&&typeof c==`object`&&!Array.isArray(c)){let e=c,t=typeof e.prompt==`string`?e.prompt.trim():``;if(!t){H(s,400,{error:`custom scenario needs a prompt`});return}let n=[];if(Array.isArray(e.inputs)){for(let t of e.inputs)if(t&&typeof t==`object`){let e=t,r=typeof e.key==`string`?e.key.trim():``;if(r){let t=typeof e.label==`string`&&e.label.trim()?e.label.trim():r;n.push({key:r,label:t})}}}i={id:`custom`,title:typeof e.title==`string`&&e.title.trim()?e.title.trim():`Custom`,description:``,category:`自定义`,prompt:t,inputs:n}}else i=typeof n.scenario==`string`?po(n.scenario,o()):void 0;if(!i){H(s,400,{error:`unknown scenario`});return}let l={};if(n.values&&typeof n.values==`object`&&!Array.isArray(n.values))for(let[e,t]of Object.entries(n.values))typeof t==`string`&&(l[e]=t);for(let e of i.inputs??[])if(!l[e.key]||!l[e.key].trim()){H(s,400,{error:`Missing input: ${e.label}`});return}let u=mo(i,l);try{let e=await co(r,process.cwd(),u);H(s,200,{launched:!0,agent:r,scenario:i.id,command:e.command})}catch(e){H(s,400,{error:V(e)})}return}if(d===`/api/active`&&u===`POST`){let e=await qo(a),n;try{n=JSON.parse(e)}catch{H(s,400,{error:`invalid JSON body`});return}let r=n;try{let e=await t.activate(r.name);i=e,H(s,200,{activeProfile:e,uiLanguage:o()})}catch(e){H(s,400,{error:V(e)})}return}if(d===`/api/profile`&&u===`POST`){let e=await qo(a),t;try{t=JSON.parse(e)}catch{H(s,400,{error:`invalid JSON body`});return}let n=t;if(!n.data||typeof n.data!=`object`||Array.isArray(n.data)){H(s,400,{error:`missing or invalid 'data'`});return}let r,i;try{r=Ct(n.name),i=Xo(n.data)}catch(e){H(s,400,{error:V(e)});return}let c=Zo(Mt(r),i);await ln(c,r),H(s,200,{saved:c,uiLanguage:o()});return}if(d===`/api/profile`&&u===`DELETE`){try{H(s,200,{deleted:await me(l.searchParams.get(`name`)??void 0),activeProfile:t.profiles().active})}catch(e){H(s,400,{error:V(e)})}return}s.writeHead(404,{"Content-Type":`text/plain; charset=utf-8`}),s.end(`not found
|
|
2716
|
+
`)}catch(e){if(console.error(`[config ui] request failed:`,e),s.headersSent){s.end();return}H(s,500,{error:V(e)})}})}var $o=w({description:{"en-US":`Open a local web UI to manage config profiles`,"zh-CN":`打开用于管理配置 Profile 的本地 Web UI`},auth:`none`,usageArgs:`[--port <port>] [--no-open]`,flags:Go,exampleArgs:[``,`--port 8787`,`--no-open`],async run(e){let{settings:n,flags:r}=e,i=T(n.output);if(n.dryRun){A({host:`127.0.0.1`,port:r.port??`random free port`,config_file:e.configStore.path,routes:[`GET / -> web UI`,`GET /api/config -> read all profiles`,`GET /api/skills -> list installed agent skills`,`GET /api/skill -> read one skill's SKILL.md detail`,`POST /api/skill/install -> install a skill from an uploaded .zip into a skills root`,`GET /api/mcp -> list local MCP servers`,`POST /api/mcp -> create or update one MCP server (writes its source config)`,`DELETE /api/mcp -> remove one MCP server from its source config`,`GET /api/health -> runtime environment info (node, platform, cwd)`,`GET /api/agents -> list coding agent frameworks`,`GET /api/agent -> one agent's config detail (secrets masked)`,`POST /api/agent/open -> open one agent's config file with the OS default app`,`GET /api/auth/status -> current auth state`,`POST /api/auth/login -> start console login (opens browser)`,`POST /api/auth/logout -> clear all stored credentials`,`GET /api/assets -> list generated assets`,`GET /api/asset/file -> stream one asset file`,`POST /api/asset/open -> open one asset with the OS default app`,`POST /api/agent/launch -> launch a coding agent CLI in a new terminal`,`GET /api/scenarios -> list Playground scenarios and dispatchable agents`,`POST /api/agent/dispatch -> dispatch a scenario prompt to a connected agent`,`POST /api/profile -> save a profile`,`POST /api/active -> activate a profile`,`DELETE /api/profile -> delete a named profile`,`DELETE /api/asset -> delete one asset file`]},i);return}let a=Hn(16).toString(`hex`),o=n.outputDir||zo(),s=Qo(a,e.configStore,o,Io(e)),l;try{l=await ri(s,r.port??0)}catch(e){throw new t(`Could not bind to 127.0.0.1 (no free port or permission denied): ${V(e)}`,c.USAGE)}let u=`http://127.0.0.1:${l}/?token=${a}`;if(!r.noOpen)try{await ai(u),k(`Opened the config UI in your default browser.`)}catch{k(`Could not open the browser automatically. Open the URL below manually.`)}k(`Config UI running at ${u}`),k(`Note: credentials are shown in cleartext in the browser (localhost only).`),k(`Press Ctrl+C to stop.`),await new Promise(e=>{let t=()=>s.close(()=>e());process.once(`SIGINT`,t),process.once(`SIGTERM`,t),s.once(`close`,()=>e())})}});function es(e){let t=``,n=0,r=!1;for(;n<e.length;){let i=e[n],a=e[n+1];if(r){if(t+=i,i===`\\`){t+=a??``,n+=2;continue}i===`"`&&(r=!1),n+=1;continue}if(i===`"`){r=!0,t+=i,n+=1;continue}if(i===`/`&&a===`/`){for(;n<e.length&&e[n]!==`
|
|
2717
|
+
`;)n+=1;continue}if(i===`/`&&a===`*`){for(n+=2;n<e.length&&!(e[n]===`*`&&e[n+1]===`/`);)n+=1;n+=2;continue}t+=i,n+=1}let i=``;for(n=0,r=!1;n<t.length;){let e=t[n];if(r){if(i+=e,e===`\\`){i+=t[n+1]??``,n+=2;continue}e===`"`&&(r=!1),n+=1;continue}if(e===`"`&&(r=!0),e===`,`){let e=n+1;for(;e<t.length&&/\s/.test(t[e]);)e+=1;if(t[e]===`}`||t[e]===`]`){n+=1;continue}}i+=e,n+=1}return i}function ts(e){if(!Jn(e))return{};try{return JSON.parse(Xn(e,`utf-8`))}catch{return{}}}function ns(e){if(!Jn(e))return{};try{return JSON.parse(es(Xn(e,`utf-8`)))}catch{return{}}}function rs(e,t){Yn(tr(e),{recursive:!0});let n=e+`.tmp`;$n(n,JSON.stringify(t,null,2)+`
|
|
2718
|
+
`,{mode:384}),Zn(n,e)}function is(e,t){Yn(tr(e),{recursive:!0});let n=e+`.tmp`;$n(n,t,{mode:384}),Zn(n,e)}function as(e){Jn(e)&&Kn(e,`${e}.bak.${Math.floor(Date.now()/1e3)}`)}function os(e){return e.includes(`/apps/anthropic`)}function ss(e){let n=e.trim().replace(/\/+$/,``);if(os(n))return{url:n};if(n.includes(`/compatible-mode`))return{url:n.replace(/\/compatible-mode(?:\/v\d+)?/,`/apps/anthropic`),rewrittenFrom:e.trim()};try{let t=new URL(n),r=t.hostname;if((r.includes(`dashscope`)||r.includes(`maas.aliyuncs.com`)||r.includes(`token-plan`))&&(t.pathname===`/`||t.pathname===``))return{url:`${t.origin}/apps/anthropic`,rewrittenFrom:e.trim()}}catch{}throw new t(`Claude Code requires an Anthropic-compatible base URL, got "${e}".`,c.USAGE,`Use a URL ending in /apps/anthropic (not /compatible-mode/v1). Example: https://dashscope.aliyuncs.com/apps/anthropic`)}function cs(e){let n=e.trim();if(!/^[a-z0-9-]+$/.test(n))throw new t(`Invalid --region "${e}".`,c.USAGE,`Use a Model Studio region id, e.g. cn-beijing or ap-southeast-1.`);return`https://token-plan.${n}.maas.aliyuncs.com/compatible-mode/v1`}function ls(e,t,n){let r=e[t];(r===void 0||r.trim()===``)&&(e[t]=n)}var us={label:`Claude Code`,write({baseUrl:e,apiKey:t,model:n}){let r=N(process.env.CLAUDE_CONFIG_DIR||N(br(),`.claude`),`settings.json`),i=N(br(),`.claude.json`),a=[],o=ss(e);o.rewrittenFrom&&a.push(`Rewrote base URL for Claude Code: "${o.rewrittenFrom}" → "${o.url}" (Claude Code needs /apps/anthropic, not OpenAI compatible-mode).`),as(r);let s=ts(r),c=s.env??{};c.ANTHROPIC_BASE_URL=o.url,c.ANTHROPIC_AUTH_TOKEN=t,delete c.ANTHROPIC_API_KEY,c.ANTHROPIC_MODEL=n,ls(c,`ANTHROPIC_DEFAULT_HAIKU_MODEL`,n),ls(c,`ANTHROPIC_DEFAULT_SONNET_MODEL`,n),ls(c,`ANTHROPIC_DEFAULT_OPUS_MODEL`,n),ls(c,`CLAUDE_CODE_SUBAGENT_MODEL`,n),s.env=c,rs(r,s),as(i);let l=ts(i);return l.hasCompletedOnboarding=!0,rs(i,l),{paths:[r,i],nextStep:"Run `claude` to start using Claude Code with DashScope.",warnings:a.length>0?a:void 0}}};const ds=`DASHSCOPE_API_KEY`;function fs(e){return`[Bailian] ${e}`}function ps(e){if(e.envKey===ds)return!0;let t=typeof e.name==`string`?e.name:``;return t===`bailian-cli`||t.startsWith(`[Bailian]`)}var ms={label:`Qwen Code`,write({baseUrl:e,apiKey:t,model:n}){let r=N(br(),`.qwen`,`settings.json`),i=os(e)?`anthropic`:`openai`,a=[];as(r);let o=ts(r);o.$version=3;let s=o.env??{};s[ds]=t,o.env=s;let c=process.env[ds];c!==void 0&&c!==t&&a.push(`Shell/environment ${ds} is set and overrides settings.json. Unset it (e.g. \`unset ${ds}\`) so the key written here takes effect.`);let l=o.modelProviders??{},u=l[i]??[],d=u.find(e=>ps(e)&&e.id===n),f=u.find(e=>!ps(e)&&e.id===n);if(d){d.baseUrl=e,d.envKey=ds;let t=typeof d.name==`string`?d.name.trim():``;(!t||t===`bailian-cli`)&&(d.name=fs(n))}else if(f){let e=typeof f.name==`string`&&f.name.length>0?f.name:String(f.id);a.push(`Model id "${n}" already exists as "${e}"; left unchanged (Qwen Code loads only the first entry per id). Remove or rename that entry if you want bailian-cli to own this model.`)}else u.push({id:n,name:fs(n),baseUrl:e,envKey:ds});l[i]=u,o.modelProviders=l;let p=o.security??{};return p.auth={selectedType:i,apiKey:t,baseUrl:e},o.security=p,o.model={name:n,baseUrl:e},rs(r,o),{paths:[r],nextStep:"Run `qwen` to start using Qwen Code with DashScope.",warnings:a.length>0?a:void 0}}},hs={label:`OpenCode`,write({baseUrl:e,apiKey:t,model:n}){let r=N(br(),`.config`,`opencode`,`opencode.json`);as(r);let i=ns(r);i.$schema||=`https://opencode.ai/config.json`;let a=i.provider??{};return a[`bailian-cli`]={npm:os(e)?`@ai-sdk/anthropic`:`@ai-sdk/openai-compatible`,name:`Alibaba Cloud Model Studio`,options:{baseURL:e,apiKey:t,setCacheKey:!0},models:{[n]:{name:n}}},i.provider=a,rs(r,i),{paths:[r],nextStep:"Run `opencode` then type `/models` to select your model."}}};const gs=`bailian-cli`;function _s(e){let t=e.model;if(!t||typeof t!=`object`)return;let n=t.primary;return typeof n==`string`&&n.trim()!==``?n.trim():void 0}var vs={label:`OpenClaw`,write({baseUrl:e,apiKey:t,model:n,contextWindow:r}){let i=N(br(),`.openclaw`,`openclaw.json`),a=[],o=`${gs}/${n}`;as(i);let s=ts(i),c=s.models??{};c.mode=`merge`;let l=c.providers??{};l[gs]={baseUrl:e,apiKey:t,api:os(e)?`anthropic-messages`:`openai-completions`,models:[{id:n,name:n,contextWindow:r??256e3,cost:{input:0,output:0,cacheRead:0,cacheWrite:0}}]},c.providers=l,s.models=c;let u=s.agents??{},d=u.defaults??{},f=d.models??{};f[o]=f[o]??{},d.models=f;let p=_s(d);return p?p.startsWith(`${gs}/`)?d.model={primary:o}:a.push(`Left existing primary model unchanged ("${p}"). Added provider "${gs}" — switch to "${o}" in OpenClaw if you want to use it.`):d.model={primary:o},u.defaults=d,s.agents=u,rs(i,s),{paths:[i],nextStep:"Run `openclaw gateway restart`, then `openclaw` to start using OpenClaw with DashScope.",warnings:a.length>0?a:void 0}}},ys={label:`Hermes Agent`,write({baseUrl:e,apiKey:t,model:n}){let r=N(br(),`.hermes`,`config.yaml`);as(r);let i={};if(Jn(r))try{i=_r.parse(Xn(r,`utf-8`))??{}}catch{i={}}let a={default:n,provider:`custom`,base_url:e,api_key:t};return os(e)&&(a.api_mode=`anthropic_messages`),i.model=a,is(r,_r.stringify(i)),{paths:[r],nextStep:'Run `hermes chat -q "hello"` to verify.'}}};const bs=`bailian-cli`,xs={"claude-code":us,"qwen-code":ms,opencode:hs,openclaw:vs,hermes:ys,codex:{label:`Codex`,write({baseUrl:e,apiKey:t,model:n,wireApi:r}){let i=N(br(),`.codex`,`config.toml`),a=[];as(i);let o={};if(Jn(i))try{o=vr(Xn(i,`utf-8`))}catch{o={}}o.model_provider=bs,o.model=n;let s=r===`chat`?`chat`:`responses`;s===`chat`&&a.push('Current Codex releases refuse to load `wire_api = "chat"`; only use --wire-api chat with legacy Codex <= 0.80.0 (e.g. `npm install -g @openai/codex@0.80.0`).');let c=o.model_providers??{};c[bs]={...c[bs]??{},name:bs,base_url:e,env_key:`OPENAI_API_KEY`,wire_api:s,requires_openai_auth:!0},o.model_providers=c,is(i,yr(o)+`
|
|
2719
|
+
`);let l=N(br(),`.codex`,`auth.json`);as(l);let u=ts(l);return u.OPENAI_API_KEY=t,rs(l,u),{paths:[i,l],nextStep:"Run `codex` to start using Codex with DashScope.",warnings:a.length>0?a:void 0}}}},Ss=Object.keys(xs),Cs=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.`,ws=new Map(Cs.split(``).map((e,t)=>[e,t])),Ts=/^[A-Za-z0-9._-]+$/;function Es(){return new t(`Invalid obfuscated API key.`,c.USAGE,`--key expects the obfuscated key copied from the web console (starts with "o1_").`)}function Ds(e){let t=[];for(let n of e){let e=ws.get(n);if(e===void 0)throw Es();t.push(e)}return t}function Os(e){return e.map(e=>Cs[e]).join(``)}function ks(e,t){return Math.imul((e^t)>>>0,16777619)>>>0}function As(e){let t=e>>>0;return t^=t<<13,t^=t>>>17,t^=t<<5,t>>>0}function js(e,t,n,r){let i=(2166136261^Math.imul(n+1,2654435761))>>>0;i=ks(i,e.length),i=ks(i,r);for(let e of t)i=ks(i,(ws.get(e)??-1)+1);for(let t of e)i=ks(i,t+1);i^=i>>>16,i=Math.imul(i,2246822507)>>>0,i^=i>>>13,i=Math.imul(i,3266489909)>>>0,i^=i>>>16,i=i>>>0||1831565813;let a=[];for(let e=0;e<r;e+=1)i=i+Math.imul(e+1,2654435761)>>>0,i=As(i),a.push(i%65);return a}function Ms(e,t){let n=Ds(e),r=Math.floor(n.length/2),i=n.slice(0,r),a=n.slice(r);for(let e=7;e>=0;--e){let n=i,r=js(n,t,e,a.length);i=a.map((e,t)=>(e-r[t]+65)%65),a=n}return Os([...i,...a])}function Ns(e){let t=4294967295;for(let n=0;n<e.length;n+=1){t^=e.charCodeAt(n);for(let e=0;e<8;e+=1){let e=-(t&1);t=t>>>1^3988292384&e}}return(t^4294967295)>>>0}function Ps(e,t){let n=e>>>0,r=Array(t).fill(Cs[0]);for(let e=t-1;e>=0;--e)r[e]=Cs[n%65],n=Math.floor(n/65);if(n!==0)throw Es();return r.join(``)}function Fs(e){if(e.length!==6||!Ts.test(e))throw Es()}function Is(e){if(e.length<16||!e.startsWith(`o1_`))throw Es();let t=e.slice(3);if(!Ts.test(t))throw Es();let n=t.slice(0,6),r=t.slice(6,-6),i=t.slice(-6);if(Fs(n),!r)throw Es();let a=Ms(r,n);if(!Ts.test(a)||i!==Ps(Ns(a),6))throw Es();return a}var Ls=w({description:{"en-US":`Configure a coding agent to use DashScope API`,"zh-CN":`配置编程 Agent 使用 DashScope API`},auth:`none`,usageArgs:`--agent <name> (--base-url <url> | --region <region>) (--api-key <key> | --key <encoded>) --model <model>`,flags:{agent:{type:`string`,valueHint:`<name>`,description:{"en-US":`Target agent: ${Ss.join(`, `)}`,"zh-CN":`目标 Agent:${Ss.join(`, `)}`},required:!0,choices:Ss},baseUrl:{type:`string`,valueHint:`<url>`,description:{"en-US":`API base URL`,"zh-CN":`API Base URL`}},region:{type:`string`,valueHint:`<region>`,description:{"en-US":`Model Studio region (e.g. cn-beijing, ap-southeast-1); converted into --base-url. Token Plan only`,"zh-CN":`模型服务地域(例如 cn-beijing、ap-southeast-1);将转换为 --base-url。仅用于 Token Plan`}},apiKey:{type:`string`,valueHint:`<key>`,description:{"en-US":`API key`,"zh-CN":`API Key`}},key:{type:`string`,valueHint:`<encoded>`,description:{"en-US":`Obfuscated API key from the web console (starts with "o1_"); decoded into --api-key`,"zh-CN":`来自 Web 控制台的混淆 API Key(以 "o1_" 开头);将解码为 --api-key`}},model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Default model name`,"zh-CN":`默认模型名称`},required:!0},contextWindow:{type:`number`,valueHint:`<tokens>`,description:{"en-US":`OpenClaw only: model context window in tokens (default: 256000)`,"zh-CN":`仅 OpenClaw:模型上下文窗口 Token 数(默认:256000)`}},wireApi:{type:`string`,valueHint:`<api>`,description:{"en-US":`Codex only: wire protocol (default: responses). "chat" only works with legacy Codex <= 0.80.0`,"zh-CN":`仅 Codex:通信协议(默认:responses)。"chat" 仅适用于旧版 Codex <= 0.80.0`},choices:[`chat`,`responses`]}},exampleArgs:[`--agent claude-code --base-url https://dashscope.aliyuncs.com/apps/anthropic --api-key sk-xxxxx --model qwen3-max`,`--agent qwen-code --base-url https://dashscope.aliyuncs.com/compatible-mode/v1 --api-key sk-xxxxx --model qwen3-coder-plus`,`--agent codex --base-url https://dashscope.aliyuncs.com/compatible-mode/v1 --api-key sk-xxxxx --model qwen3-coder-plus`],validate(e){if(!e.baseUrl&&!e.region)return`one of --base-url or --region is required`;if(e.baseUrl&&e.region)return`--base-url and --region are mutually exclusive`;if(!e.apiKey&&!e.key)return`one of --api-key or --key is required`;if(e.apiKey&&e.key)return`--api-key and --key are mutually exclusive`},async run(e){let{settings:t,flags:n}=e,r=n.agent,{model:i,contextWindow:a,wireApi:o}=n,s=n.region?cs(n.region):n.baseUrl,c=n.key?Is(n.key):n.apiKey,l=xs[r],u=T(t.output);if(r===`hermes`&&xr()===`win32`&&process.stderr.write(`Warning: Hermes Agent does not support native Windows. Please use WSL2.
|
|
2720
|
+
`),t.dryRun){A({agent:r,label:l.label,base_url:s,api_key:pt(c),model:i},u);return}let d={baseUrl:s,apiKey:c,model:i,contextWindow:a,wireApi:o},f=l.write(d);if(!t.quiet){k(`${l.label} configured successfully.`);for(let e of f.paths)k(` Written: ${e}`);k(` ${f.nextStep}`);for(let e of f.warnings??[])process.stderr.write(`Warning: ${e}\n`)}}});const Rs=`bl skill init`;function zs(e){process.stderr.write(`
|
|
2640
2721
|
Updating agent skill...
|
|
2641
|
-
`);try{
|
|
2642
|
-
`),s===`brew`||s===`winget`){let e=s===`brew`?`brew upgrade bailian-cli`:`winget upgrade Aliyun.BailianCLI`;process.stderr.write(`${o.yellow(`This CLI was installed via ${s}. Update with:`)}\n ${e}\n`),l&&process.stderr.write(`${o.dim(`Note: --to is not supported for ${s} installs.`)}\n`);return}let u=l??await
|
|
2722
|
+
`);try{Sr(Rs,{stdio:`inherit`}),process.stderr.write(`${e.green(`✓ Agent skill updated.`)}\n`)}catch{process.stderr.write(`${e.yellow(`Agent skill update skipped. Run manually: ${Rs}`)}\n`)}}function Bs(e){try{$n(N(Re(),`update-state.json`),JSON.stringify({lastChecked:Date.now(),latestVersion:e}))}catch{}}async function Vs(e,t){return e===`binary`?await Tn(`latest`,5e3)??await En(5e3,t):En(5e3,t)}function Hs(){return process.platform===`win32`?` irm ${r} | iex\n`:` curl -fsSL ${i} | bash\n`}var Us=w({description:{"en-US":`Update the CLI to the latest or a specified version`,"zh-CN":`将 CLI 更新到最新版本或指定版本`},auth:`none`,usageArgs:`[--to <version>]`,flags:{to:{type:`string`,valueHint:`<version>`,description:{"en-US":`Install this exact version instead of the latest`,"zh-CN":`安装指定版本,而不是最新版本`}}},exampleArgs:[``,`--to 0.1.14`],validate(e){if(e.to!==void 0){if(!e.to.trim())return`--to requires a non-empty version`;if(!An(e.to))return`--to must be a semver version (e.g. 1.13.0, v1.13.0, 0.0.0-beta-<sha>-<YYYYMMDDHHMM>), got: ${e.to.trim()}`}},async run(e){let{identity:n}=e,r=n.npmPackage,i=n.binName,a=n.version,o=O(process.stderr),s=qe(n),c=e.flags.to?.trim(),l=c?Mn(c):void 0;if(process.stderr.write(`Current version: ${o.yellow(a)}\n`),process.stderr.write(`Install method: ${o.dim(s)}\n`),l?process.stderr.write(`Target version: ${o.green(l)}\n`):process.stderr.write(`Checking for updates...
|
|
2723
|
+
`),s===`brew`||s===`winget`){let e=s===`brew`?`brew upgrade bailian-cli`:`winget upgrade Aliyun.BailianCLI`;process.stderr.write(`${o.yellow(`This CLI was installed via ${s}. Update with:`)}\n ${e}\n`),l&&process.stderr.write(`${o.dim(`Note: --to is not supported for ${s} installs.`)}\n`);return}let u=l??await Vs(s,r);if(!u){process.stderr.write(`${o.yellow(`Could not determine the latest version.`)}\n`);return}if(u===a){let e=l?`\u2713 Already at ${a}.`:`\u2713 Already up to date (${a}).`;process.stderr.write(`${o.green(e)}\n`),s===`npm`&&zs(o);return}if(l?process.stderr.write(`
|
|
2643
2724
|
`):process.stderr.write(`Latest version: ${o.green(u)}\n\n`),s===`binary`){process.stderr.write(`Updating via binary channel...
|
|
2644
2725
|
|
|
2645
|
-
`);try{let e=await
|
|
2646
|
-
`),process.stderr.write(` ${r}\n\n`)}return}let d=`npm install -g ${l?`${r}@${l}`:`${r}@latest`}`;process.stderr.write(`Updating ${r} via npm...\n\n`);try{
|
|
2726
|
+
`);try{let e=await Nn(u);process.stderr.write(`\n${o.green(`\u2713 Update complete: ${a} \u2192 ${e}`)}\n`),Bs(e),zs(o)}catch(e){let n=e instanceof Error?e.message:String(e),r=e instanceof t&&e.hint?e.hint.replace(/^Re-run:\s*/i,``):Hs().trim();process.stderr.write(`\nAutomatic binary update failed: ${n}\n`),process.stderr.write(`Re-run the install script:
|
|
2727
|
+
`),process.stderr.write(` ${r}\n\n`)}return}let d=`npm install -g ${l?`${r}@${l}`:`${r}@latest`}`;process.stderr.write(`Updating ${r} via npm...\n\n`);try{Sr(d,{stdio:`inherit`});try{let e=Sr(`${i} --version 2>/dev/null`,{encoding:`utf-8`}).trim().replace(RegExp(`^${i}\\s+`),``);process.stderr.write(`\n${o.green(`\u2713 Update complete: ${a} \u2192 ${e}`)}\n`),Bs(e)}catch{process.stderr.write(`\n${o.green(`✓ Update complete.`)}\n`)}zs(o)}catch{process.stderr.write(`
|
|
2647
2728
|
Automatic update failed. Please run manually:
|
|
2648
|
-
`),process.stderr.write(` ${d}\n\n`)}}}),
|
|
2649
|
-
`)}else{let n=await e.client.requestJson({path:b(r),method:`POST`,body:s}),i=n.output?.text??``;t.quiet||o===`text`?k(i):A(n,o)}}});const Is=`zeldaEasy.broadscope-bailian.app-control.list`;var Ls=w({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=T(t.output),s={reqDTO:{name:r,notInTypes:[10],type:5,statuses:[1,4],page_no:i,page_size:a}};if(t.dryRun){A({api:Is,data:s},o);return}let c=await e.client.console(Is,s),l=c?.data?.DataV2?.data?.data?.list??[];A({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)}}),Rs=w({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 _(`--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=T(t.output);if(t.dryRun){A({endpoint:e.client.url(mt()),request:r},i);return}let a=await e.client.requestJson({path:mt(),method:`POST`,body:r});t.quiet||i===`text`?k(`Memory added. IDs: ${a.memory_ids?.join(`, `)||`none`}`):A(a,i)}}),zs=w({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 _(`--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=T(t.output);if(t.dryRun){A({endpoint:e.client.url(_t()),request:r},i);return}let a=await e.client.requestJson({path:_t(),method:`POST`,body:r});if(t.quiet||i===`text`)if(!a.memory_nodes||a.memory_nodes.length===0)k(`No memory nodes found.`);else for(let e of a.memory_nodes)k(`[${e.memory_node_id}] ${e.content}`);else A(a,i)}}),Bs=w({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=T(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=`${ht()}?${a.toString()}`;if(t.dryRun){A({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)k(`No memory nodes found.`);else{for(let e of s.memory_nodes)k(`[${e.memory_node_id}] ${e.content}`);s.total!==void 0&&k(`\nTotal: ${s.total}`)}else A(s,i)}}),Vs=w({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=T(t.output);if(t.dryRun){A({endpoint:e.client.url(gt(r)),method:`PATCH`,request:i},a);return}let o=await e.client.requestJson({path:gt(r),method:`PATCH`,body:i});t.quiet||a===`text`?k(`Memory node ${r} updated.`):A(o,a)}}),Hs=w({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=T(t.output),o=new URLSearchParams({user_id:i});n.memoryLibraryId&&o.set(`memory_library_id`,n.memoryLibraryId);let s=`${gt(r)}?${o.toString()}`;if(t.dryRun){A({endpoint:e.client.url(s),method:`DELETE`},a);return}let c=await e.client.requestJson({path:s,method:`DELETE`});t.quiet||a===`text`?k(`Memory node ${r} deleted.`):A(c,a)}}),Us=w({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 _(`--attributes must be valid JSON array`)}let o={name:r,attributes:a};n.description&&(o.description=n.description);let s=T(t.output);if(t.dryRun){A({endpoint:e.client.url(Ot()),request:o},s);return}let c=await e.client.requestJson({path:Ot(),method:`POST`,body:o});t.quiet||s===`text`?k(`Profile schema created: ${c.profile_schema_id}`):A(c,s)}}),Ws=w({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=T(t.output),o=new URLSearchParams({user_id:i}),s=`${rn(r)}?${o.toString()}`;if(t.dryRun){A({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)k(`${e.name}: ${e.value??`(empty)`}`);else k(`No profile data found.`);else A(c,a)}}),Gs=w({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=T(t.output);n.topK!==void 0&&n.rerankTopN===void 0&&(process.stderr.write(`Warning: --top-k is deprecated. Use --rerank-top-n instead.
|
|
2650
|
-
`),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){A({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`?Ks(o.map(e=>({text:e.text,score:e.score}))):A(a,r)}});function Ks(e){if(e.length===0)k(`No results found.`);else for(let t=0;t<e.length;t++){let n=e[t];k(`[${t+1}] (score: ${n.score.toFixed(4)})`),k(n.text),k(``)}}const U={workspaceId:{type:`string`,valueHint:`<id>`,description:`Workspace ID for API endpoint URL (or set BAILIAN_WORKSPACE_ID)`}},qs={pageNumber:{type:`number`,valueHint:`<n>`,description:`Page number (default: 1)`},pageSize:{type:`number`,valueHint:`<n>`,description:`Page size per request`}};function W(e){let n=e.flags.workspaceId||e.settings.workspaceId;if(!n)throw new t(`Workspace ID is required.`,s.USAGE,`Pass --workspace-id, set BAILIAN_WORKSPACE_ID env, or configure: ${e.identity.binName} config set workspace_id <id>`);return n}function Js(e){if(!process.stdout.isTTY)return e;let t=process.stdout.columns??120;return e.length>t?`${e.slice(0,Math.max(0,t-1))}…`:e}function Ys(e){return e.data?.ingestion_status??`UNKNOWN`}function Xs(e){return(e.data?.rows??[]).filter(e=>[e.code,e.status].some(e=>typeof e==`string`&&e.includes(`FAILED`)))}function Zs(e){let t=e.data?.rows??[];if(t.length===0)return!1;let n=e.data?.total_count;return typeof n==`number`&&t.length<n?!1:t.every(e=>{let t=e.code??e.status??``;return t===`FINISH`||t.includes(`FAILED`)})}function Qs(e,t){let n=e.data?.rows??[],r=Xs(e),i=new Set(r.map(e=>e.doc_id)),a=n.filter(e=>!i.has(e.doc_id)),o=r.map(e=>`${e.doc_name??e.doc_id??`?`}: ${e.message??e.code??`unknown`}`).join(`; `),s=a.map(e=>e.doc_name??e.doc_id??`?`).join(`, `),c=[];return o&&c.push(`failed: ${o}`),s&&c.push(`succeeded: ${s}`),c.length>0?`${t} (${c.join(`; `)})`:t}function $s(e,t,n){let r=new URL(E(e,f.indexJobStatus));return r.searchParams.set(`index_id`,t),r.searchParams.set(`job_id`,n),r}async function ec(e,t,n){return Mn(e,t,{url:n.statusUrl,intervalSec:n.intervalSec,timeoutSec:t.timeout,isComplete:e=>{let t=e;return Ys(t)===`COMPLETED`||Zs(t)},isFailed:()=>!1,getStatus:e=>{let t=e,n=Ys(t),r=Xs(t).length,i=t.data?.total_count;return typeof i==`number`&&i>0?`${n} (${r}/${i} failed)`:r>0?`${n} (${r} failed)`:n}})}function tc(e,n){return!(e instanceof t)||e.hint?e:new t(e.message,e.exitCode,n,{cause:e,api:e.api,rawResponse:e.rawResponse})}function nc(e,t){let n=e.data?.[t];if(typeof n==`string`)return n;let r=e[t];return typeof r==`string`?r:void 0}var rc=w({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},...U,agentVersion:{type:`string`,valueHint:`<version>`,description:`Service version to call: beta (draft for debugging) or a published number; default is the latest published version`},image:{type:`array`,valueHint:`<url>`,description:`Image URL for multimodal retrieval (repeatable)`}},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>`.","`--agent-version beta` calls the draft config for debugging before it is deployed."],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`],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={query:n.query,agent_id:n.agentId};n.agentVersion&&(a.agent_version=n.agentVersion),n.image&&n.image.length>0&&(a.images=n.image);let o=et(r);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=s.data?.nodes||[];if(t.quiet||i===`text`)if(c.length===0)k(`No results found.`);else for(let e=0;e<c.length;e++){let t=c[e];k(`[${e+1}] (score: ${t.score.toFixed(4)})`),k(t.text),k(``)}else A(s,i)}});const ic={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},...U,agentVersion:{type:`string`,valueHint:`<version>`,description:`Service version to call: beta (draft for debugging) or a published number; default is the latest published version`},image:{type:`array`,valueHint:`<url>`,description:`Image URL (repeatable). Attached to the last user message as multimodal content`}};function ac(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 oc(e){for(let t of e)if(Array.isArray(t.content)&&t.content.some(e=>e.type===`image_url`))return!0;return!1}function sc(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 cc={tool_calling:`🔍 Retrieving...`,plan_start:`🤔 Planning...`,generation_start:`✍️ Generating...`};var lc=w({description:`Chat with a Bailian knowledge base (RAG Q&A with streaming)`,auth:`apiKey`,usageArgs:`--message <text> --agent-id <id> [flags]`,flags:ic,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.`,"`--agent-version beta` calls the draft config for debugging before it is deployed."],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=ac(r),a=r.image,o=!!a&&a.length>0;i.length===0&&o&&(i=[{role:`user`,content:``}]);let c=W(e),l=T(n.output),u=l===`text`&&!!process.stdout.isTTY;if(o){if(oc(i))throw new t(`Cannot use --image when messages already contain embedded image_url content parts. Use one approach or the other.`,s.USAGE);sc(i,a)}let d={input:{messages:i},parameters:{agent_options:{agent_id:r.agentId,...r.agentVersion?{agent_version:r.agentVersion}:{}}},stream:!0},f=Qe(c);if(n.dryRun){A({endpoint:f,request:d},l);return}let p=await e.client.request({path:f,method:`POST`,body:d,stream:!0});if(u){let e=O(process.stdout),r=n.verbose;for await(let n of wt(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,s.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=cc[t.extra.step_change];n&&process.stdout.write(`${e.dim(n)}\n`)}if(r&&t.extra?.step_change&&process.stderr.write(O(process.stderr).dim(`[event] step_change=${t.extra.step_change} step=${t.extra?.step??``} group=${t.extra?.group??``}`)+`
|
|
2729
|
+
`),process.stderr.write(` ${d}\n\n`)}}}),Ws=w({description:{"en-US":`Call a Bailian application (agent or workflow)`,"zh-CN":`调用百炼应用(智能体或工作流)`},auth:`apiKey`,usageArgs:`--app-id <id> --prompt <text> [flags]`,flags:{appId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Application ID (required)`,"zh-CN":`应用 ID(必填)`},required:!0},prompt:{type:`string`,valueHint:`<text>`,description:{"en-US":`Input prompt text`,"zh-CN":`输入提示词文本`},required:!0},image:{type:`array`,valueHint:`<url>`,description:{"en-US":`Image URL(s) to pass to the app (repeatable)`,"zh-CN":`传给应用的图片 URL(可重复)`}},fileId:{type:`array`,valueHint:`<id>`,description:{"en-US":`Pre-uploaded file ID(s) (repeatable)`,"zh-CN":`已上传的文件 ID(可重复)`}},sessionId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Session ID for multi-turn conversation`,"zh-CN":`多轮对话的 Session ID`}},stream:{type:`switch`,description:{"en-US":`Stream response (default: on in TTY)`,"zh-CN":`流式输出响应(TTY 中默认开启)`}},pipelineIds:{type:`string`,valueHint:`<ids>`,description:{"en-US":`Knowledge base pipeline IDs (comma-separated)`,"zh-CN":`知识库 Pipeline ID(以逗号分隔)`}},memoryId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Memory ID for long-term memory`,"zh-CN":`长期记忆使用的 Memory ID`}},bizParams:{type:`string`,valueHint:`<json>`,description:{"en-US":`Business parameters JSON (workflow variables)`,"zh-CN":`业务参数 JSON(工作流变量)`}},hasThoughts:{type:`switch`,description:{"en-US":`Show agent thinking process`,"zh-CN":`显示智能体思考过程`}}},exampleArgs:[{"en-US":`--app-id abc123 --prompt "Hello"`,"zh-CN":`--app-id abc123 --prompt "你好"`},{"en-US":`--app-id abc123 --prompt "Describe this image" --image https://example.com/photo.jpg`,"zh-CN":`--app-id abc123 --prompt "描述这张图片" --image https://example.com/photo.jpg`},{"en-US":`--app-id abc123 --prompt "Analyze the image" --image img1.jpg --image img2.jpg`,"zh-CN":`--app-id abc123 --prompt "分析这些图片" --image img1.jpg --image img2.jpg`},{"en-US":`--app-id abc123 --prompt "Continue" --session-id sess_xxx --stream`,"zh-CN":`--app-id abc123 --prompt "继续" --session-id sess_xxx --stream`},{"en-US":`--app-id abc123 --prompt "Search for materials" --pipeline-ids pipe1,pipe2`,"zh-CN":`--app-id abc123 --prompt "搜索资料" --pipeline-ids pipe1,pipe2`},{"en-US":`--app-id abc123 --prompt "Start" --biz-params '{"key":"value"}'`,"zh-CN":`--app-id abc123 --prompt "开始" --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=T(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 y(`--biz-params must be valid JSON`)}if(t.dryRun){A({endpoint:e.client.url(S(r)),request:s},o);return}if(a){let i=await e.client.request({path:S(r),method:`POST`,body:s,headers:{"X-DashScope-SSE":`enable`},stream:!0}),a=``,c=``,l=o===`text`,u=O(process.stderr);for await(let e of Et(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`?A({text:a,session_id:c},o):process.stdout.write(`
|
|
2730
|
+
`)}else{let n=await e.client.requestJson({path:S(r),method:`POST`,body:s}),i=n.output?.text??``;t.quiet||o===`text`?k(i):A(n,o)}}});const Gs=`zeldaEasy.broadscope-bailian.app-control.list`;var Ks=w({description:{"en-US":`List Bailian applications`,"zh-CN":`列出百炼应用`},auth:`console`,usageArgs:`[flags]`,flags:{name:{type:`string`,valueHint:`<name>`,description:{"en-US":`Filter by app name (keyword search)`,"zh-CN":`按应用名称筛选(关键词搜索)`}},page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Results per page (default: 30)`,"zh-CN":`每页结果数(默认:30)`}}},exampleArgs:[``,{"en-US":`--name customer service`,"zh-CN":`--name 客户服务`},`--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=T(t.output),s={reqDTO:{name:r,notInTypes:[10],type:5,statuses:[1,4],page_no:i,page_size:a}};if(t.dryRun){A({api:Gs,data:s},o);return}let c=await e.client.console(Gs,s),l=c?.data?.DataV2?.data?.data?.list??[];A({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)}}),qs=w({description:{"en-US":`Add memory from messages or custom content`,"zh-CN":`从消息或自定义内容添加记忆`},auth:`apiKey`,usageArgs:`--user-id <id> [--messages <json>] [--content <text>] [flags]`,flags:{userId:{type:`string`,valueHint:`<id>`,description:{"en-US":`User ID (required)`,"zh-CN":`用户 ID(必填)`},required:!0},messages:{type:`string`,valueHint:`<json>`,description:{"en-US":`Messages JSON array: [{"role":"user","content":"..."},...]`,"zh-CN":`消息 JSON 数组:[{"role":"user","content":"..."},...]`}},content:{type:`string`,valueHint:`<text>`,description:{"en-US":`Custom content text to memorize`,"zh-CN":`要记忆的自定义内容文本`}},profileSchema:{type:`string`,valueHint:`<id>`,description:{"en-US":`Profile schema ID for user profiling`,"zh-CN":`用于用户画像的 Profile Schema ID`}},memoryLibraryId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Memory library ID (isolate memory space)`,"zh-CN":`记忆库 ID(用于隔离记忆空间)`}}},exampleArgs:[{"en-US":`--user-id user1 --content "The user likes Python programming"`,"zh-CN":`--user-id user1 --content "用户喜欢使用 Python 编程"`},{"en-US":`--user-id user1 --messages '[{"role":"user","content":"I like traveling"}]'`,"zh-CN":`--user-id user1 --messages '[{"role":"user","content":"我喜欢旅行"}]'`},{"en-US":`--user-id user1 --content "Lives in Beijing" --profile-schema schema_xxx`,"zh-CN":`--user-id user1 --content "居住在北京" --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 y(`--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=T(t.output);if(t.dryRun){A({endpoint:e.client.url(gt()),request:r},i);return}let a=await e.client.requestJson({path:gt(),method:`POST`,body:r});t.quiet||i===`text`?k(`Memory added. IDs: ${a.memory_ids?.join(`, `)||`none`}`):A(a,i)}}),Js=w({description:{"en-US":`Search memory nodes by query or messages`,"zh-CN":`通过查询文本或消息搜索记忆节点`},auth:`apiKey`,usageArgs:`--user-id <id> [--query <text>] [flags]`,flags:{userId:{type:`string`,valueHint:`<id>`,description:{"en-US":`User ID (required)`,"zh-CN":`用户 ID(必填)`},required:!0},query:{type:`string`,valueHint:`<text>`,description:{"en-US":`Search query text`,"zh-CN":`搜索查询文本`}},messages:{type:`string`,valueHint:`<json>`,description:{"en-US":`Messages JSON array for context-based search`,"zh-CN":`用于上下文搜索的消息 JSON 数组`}},topK:{type:`number`,valueHint:`<n>`,description:{"en-US":`Number of results to return (default: 10)`,"zh-CN":`返回结果数量(默认:10)`}},memoryLibraryId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Memory library ID`,"zh-CN":`记忆库 ID`}}},exampleArgs:[{"en-US":`--user-id user1 --query "programming preferences"`,"zh-CN":`--user-id user1 --query "编程偏好"`},{"en-US":`--user-id user1 --messages '[{"role":"user","content":"recommend a book"}]' --top-k 5`,"zh-CN":`--user-id user1 --messages '[{"role":"user","content":"推荐一本书"}]' --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 y(`--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=T(t.output);if(t.dryRun){A({endpoint:e.client.url(yt()),request:r},i);return}let a=await e.client.requestJson({path:yt(),method:`POST`,body:r});if(t.quiet||i===`text`)if(!a.memory_nodes||a.memory_nodes.length===0)k(`No memory nodes found.`);else for(let e of a.memory_nodes)k(`[${e.memory_node_id}] ${e.content}`);else A(a,i)}}),Ys=w({description:{"en-US":`List memory nodes for a user`,"zh-CN":`列出用户的记忆节点`},auth:`apiKey`,usageArgs:`--user-id <id> [flags]`,flags:{userId:{type:`string`,valueHint:`<id>`,description:{"en-US":`User ID (required)`,"zh-CN":`用户 ID(必填)`},required:!0},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Results per page (default: 10)`,"zh-CN":`每页结果数(默认:10)`}},page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},memoryLibraryId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Memory library ID`,"zh-CN":`记忆库 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=T(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=`${_t()}?${a.toString()}`;if(t.dryRun){A({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)k(`No memory nodes found.`);else{for(let e of s.memory_nodes)k(`[${e.memory_node_id}] ${e.content}`);s.total!==void 0&&k(`\nTotal: ${s.total}`)}else A(s,i)}}),Xs=w({description:{"en-US":`Update a memory node content`,"zh-CN":`更新记忆节点内容`},auth:`apiKey`,usageArgs:`--node-id <id> --user-id <id> --content <text>`,flags:{nodeId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Memory node ID (required)`,"zh-CN":`记忆节点 ID(必填)`},required:!0},userId:{type:`string`,valueHint:`<id>`,description:{"en-US":`User ID (required)`,"zh-CN":`用户 ID(必填)`},required:!0},content:{type:`string`,valueHint:`<text>`,description:{"en-US":`New content for the memory node (required)`,"zh-CN":`记忆节点的新内容(必填)`},required:!0},memoryLibraryId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Memory library ID (non-default library)`,"zh-CN":`记忆库 ID(非默认记忆库)`}}},exampleArgs:[{"en-US":`--node-id node_xxx --user-id user1 --content "updated memory content"`,"zh-CN":`--node-id node_xxx --user-id user1 --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=T(t.output);if(t.dryRun){A({endpoint:e.client.url(vt(r)),method:`PATCH`,request:i},a);return}let o=await e.client.requestJson({path:vt(r),method:`PATCH`,body:i});t.quiet||a===`text`?k(`Memory node ${r} updated.`):A(o,a)}}),Zs=w({description:{"en-US":`Delete a memory node`,"zh-CN":`删除记忆节点`},auth:`apiKey`,usageArgs:`--node-id <id> --user-id <id>`,flags:{nodeId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Memory node ID (required)`,"zh-CN":`记忆节点 ID(必填)`},required:!0},userId:{type:`string`,valueHint:`<id>`,description:{"en-US":`User ID (required)`,"zh-CN":`用户 ID(必填)`},required:!0},memoryLibraryId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Memory library ID (non-default library)`,"zh-CN":`记忆库 ID(非默认记忆库)`}}},exampleArgs:[`--node-id node_xxx --user-id user1`],async run(e){let{settings:t,flags:n}=e,r=n.nodeId,i=n.userId,a=T(t.output),o=new URLSearchParams({user_id:i});n.memoryLibraryId&&o.set(`memory_library_id`,n.memoryLibraryId);let s=`${vt(r)}?${o.toString()}`;if(t.dryRun){A({endpoint:e.client.url(s),method:`DELETE`},a);return}let c=await e.client.requestJson({path:s,method:`DELETE`});t.quiet||a===`text`?k(`Memory node ${r} deleted.`):A(c,a)}}),Qs=w({description:{"en-US":`Create a user profile schema for memory profiling`,"zh-CN":`创建用于记忆画像的用户 Profile Schema`},auth:`apiKey`,usageArgs:`--name <name> --attributes <json> [flags]`,flags:{name:{type:`string`,valueHint:`<name>`,description:{"en-US":`Schema name (required)`,"zh-CN":`Schema 名称(必填)`},required:!0},description:{type:`string`,valueHint:`<text>`,description:{"en-US":`Schema description`,"zh-CN":`Schema 描述`}},attributes:{type:`string`,valueHint:`<json>`,description:{"en-US":`Attributes JSON array: [{"name":"age","description":"age"}]`,"zh-CN":`属性 JSON 数组:[{"name":"age","description":"age"}]`},required:!0}},exampleArgs:[{"en-US":`--name "user_basic" --attributes '[{"name":"age","description":"age"},{"name":"hobby","description":"hobby"}]'`,"zh-CN":`--name "user_basic" --attributes '[{"name":"age","description":"年龄"},{"name":"hobby","description":"爱好"}]'`}],async run(e){let{settings:t,flags:n}=e,r=n.name,i=n.attributes,a;try{a=JSON.parse(i)}catch{throw new y(`--attributes must be valid JSON array`)}let o={name:r,attributes:a};n.description&&(o.description=n.description);let s=T(t.output);if(t.dryRun){A({endpoint:e.client.url(At()),request:o},s);return}let c=await e.client.requestJson({path:At(),method:`POST`,body:o});t.quiet||s===`text`?k(`Profile schema created: ${c.profile_schema_id}`):A(c,s)}}),$s=w({description:{"en-US":`Get user profile by schema ID and user ID`,"zh-CN":`通过 Schema ID 和用户 ID 获取用户画像`},auth:`apiKey`,usageArgs:`--schema-id <id> --user-id <id>`,flags:{schemaId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Profile schema ID (required)`,"zh-CN":`Profile Schema ID(必填)`},required:!0},userId:{type:`string`,valueHint:`<id>`,description:{"en-US":`User ID (required)`,"zh-CN":`用户 ID(必填)`},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=T(t.output),o=new URLSearchParams({user_id:i}),s=`${on(r)}?${o.toString()}`;if(t.dryRun){A({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)k(`${e.name}: ${e.value??`(empty)`}`);else k(`No profile data found.`);else A(c,a)}}),ec=w({description:{"en-US":"Retrieve from a Bailian knowledge base (deprecated, use `search` instead)","zh-CN":"从百炼知识库检索(已废弃,请改用 `search`)"},auth:`apiKey`,usageArgs:`--index-id <id> --query <text> [flags]`,flags:{indexId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Knowledge base index ID (required)`,"zh-CN":`知识库索引 ID(必填)`},required:!0},query:{type:`string`,valueHint:`<text>`,description:{"en-US":`Search query (required)`,"zh-CN":`搜索查询(必填)`},required:!0},denseSimilarityTopK:{type:`number`,valueHint:`<n>`,description:{"en-US":`Dense retrieval top K`,"zh-CN":`稠密检索 Top K`}},sparseSimilarityTopK:{type:`number`,valueHint:`<n>`,description:{"en-US":`Sparse retrieval top K`,"zh-CN":`稀疏检索 Top K`}},rerank:{type:`switch`,description:{"en-US":`Enable reranking`,"zh-CN":`启用重排序`}},rerankTopN:{type:`number`,valueHint:`<n>`,description:{"en-US":`Rerank top N results`,"zh-CN":`重排序前 N 个结果`}},rerankModel:{type:`string`,valueHint:`<name>`,description:{"en-US":`Rerank model, e.g. qwen3-rerank-hybrid`,"zh-CN":`重排序模型,例如 qwen3-rerank-hybrid`}},rerankMode:{type:`string`,valueHint:`<mode>`,description:{"en-US":`Rerank mode: qa, similar, or custom`,"zh-CN":`重排序模式:qa、similar 或 custom`}},rerankInstruct:{type:`string`,valueHint:`<text>`,description:{"en-US":`Custom rerank instruction, when mode=custom`,"zh-CN":`自定义重排序指令,仅在 mode=custom 时使用`}},topK:{type:`number`,valueHint:`<n>`,description:{"en-US":`Number of results (deprecated, use --rerank-top-n)`,"zh-CN":`结果数量(已废弃,请使用 --rerank-top-n)`}}},exampleArgs:[{"en-US":`--index-id idx_xxx --query "How to use Alibaba Cloud Bailian"`,"zh-CN":`--index-id idx_xxx --query "如何使用阿里云百炼"`},{"en-US":`--index-id idx_xxx --query "RAG retrieval" --rerank --rerank-model qwen3-rerank-hybrid`,"zh-CN":`--index-id idx_xxx --query "RAG 检索" --rerank --rerank-model qwen3-rerank-hybrid`}],async run(e){let{settings:t,flags:n}=e,r=T(t.output);n.topK!==void 0&&n.rerankTopN===void 0&&(process.stderr.write(`Warning: --top-k is deprecated. Use --rerank-top-n instead.
|
|
2731
|
+
`),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){A({endpoint:e.client.url(tt()),request:i},r);return}let a=await e.client.requestJson({path:tt(),method:`POST`,body:i}),o=a.data?.nodes||[];t.quiet||r===`text`?tc(o.map(e=>({text:e.text,score:e.score}))):A(a,r)}});function tc(e){if(e.length===0)k(`No results found.`);else for(let t=0;t<e.length;t++){let n=e[t];k(`[${t+1}] (score: ${n.score.toFixed(4)})`),k(n.text),k(``)}}const U={workspaceId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Workspace ID for API endpoint URL (or set BAILIAN_WORKSPACE_ID)`,"zh-CN":`API Endpoint URL 使用的 Workspace ID(也可设置 BAILIAN_WORKSPACE_ID)`}}},nc={pageNumber:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page size per request`,"zh-CN":`每次请求的分页大小`}}};function W(e){let n=e.flags.workspaceId||e.settings.workspaceId;if(!n)throw new t(`Workspace ID is required.`,c.USAGE,`Pass --workspace-id, set BAILIAN_WORKSPACE_ID env, or configure: ${e.identity.binName} config set workspace_id <id>`);return n}function rc(e){if(!process.stdout.isTTY)return e;let t=process.stdout.columns??120;return e.length>t?`${e.slice(0,Math.max(0,t-1))}…`:e}function ic(e){return e.data?.ingestion_status??`UNKNOWN`}function ac(e){return(e.data?.rows??[]).filter(e=>[e.code,e.status].some(e=>typeof e==`string`&&e.includes(`FAILED`)))}function oc(e){let t=e.data?.rows??[];if(t.length===0)return!1;let n=e.data?.total_count;return typeof n==`number`&&t.length<n?!1:t.every(e=>{let t=e.code??e.status??``;return t===`FINISH`||t.includes(`FAILED`)})}function sc(e,t){let n=e.data?.rows??[],r=ac(e),i=new Set(r.map(e=>e.doc_id)),a=n.filter(e=>!i.has(e.doc_id)),o=r.map(e=>`${e.doc_name??e.doc_id??`?`}: ${e.message??e.code??`unknown`}`).join(`; `),s=a.map(e=>e.doc_name??e.doc_id??`?`).join(`, `),c=[];return o&&c.push(`failed: ${o}`),s&&c.push(`succeeded: ${s}`),c.length>0?`${t} (${c.join(`; `)})`:t}function cc(e,t,n){let r=new URL(E(e,p.indexJobStatus));return r.searchParams.set(`index_id`,t),r.searchParams.set(`job_id`,n),r}async function lc(e,t,n){return Pn(e,t,{url:n.statusUrl,intervalSec:n.intervalSec,timeoutSec:t.timeout,isComplete:e=>{let t=e;return ic(t)===`COMPLETED`||oc(t)},isFailed:()=>!1,getStatus:e=>{let t=e,n=ic(t),r=ac(t).length,i=t.data?.total_count;return typeof i==`number`&&i>0?`${n} (${r}/${i} failed)`:r>0?`${n} (${r} failed)`:n}})}function uc(e,n){return!(e instanceof t)||e.hint?e:new t(e.message,e.exitCode,n,{cause:e,api:e.api,rawResponse:e.rawResponse})}function dc(e,t){let n=e.data?.[t];if(typeof n==`string`)return n;let r=e[t];return typeof r==`string`?r:void 0}var fc=w({description:{"en-US":`Search a Bailian knowledge base (RAG semantic retrieval)`,"zh-CN":`搜索百炼知识库(RAG 语义检索)`},auth:`apiKey`,usageArgs:`--query <text> --agent-id <id> [flags]`,flags:{query:{type:`string`,valueHint:`<text>`,description:{"en-US":`Search query text (required, cannot be empty)`,"zh-CN":`搜索查询文本(必填且不能为空)`},required:!0},agentId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Retrieval service ID (find in console knowledge retrieval page)`,"zh-CN":`检索服务 ID(可在控制台知识库检索页面查看)`},required:!0},...U,agentVersion:{type:`string`,valueHint:`<version>`,description:{"en-US":`Service version to call: beta (draft for debugging) or a published number; default is the latest published version`,"zh-CN":`要调用的服务版本:beta(用于调试的草稿)或已发布版本号;默认使用最新发布版本`}},image:{type:`array`,valueHint:`<url>`,description:{"en-US":`Image URL for multimodal retrieval (repeatable)`,"zh-CN":`多模态检索使用的图片 URL(可重复)`}}},notes:[{"en-US":`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.`,"zh-CN":`检索范围与策略(多索引权重、路由、重排序等)由 agent_id 服务配置决定。仅 query 和 agent_id 必填。`},{"en-US":`Auth: uses DashScope API Key (Bearer token). Get yours from the console API Key page.`,"zh-CN":`鉴权:使用 DashScope API Key(Bearer Token)。可在控制台 API Key 页面获取。`},{"en-US":"`--workspace-id` can be set via BAILIAN_WORKSPACE_ID env or `kscli config set workspace_id <id>`.","zh-CN":"`--workspace-id` 可通过 BAILIAN_WORKSPACE_ID 环境变量或 `kscli config set workspace_id <id>` 设置。"},{"en-US":"`--agent-version beta` calls the draft config for debugging before it is deployed.","zh-CN":"`--agent-version beta` 会调用尚未部署的草稿配置,便于发布前调试。"}],exampleArgs:[{"en-US":`--query "What is RAG?" --agent-id aid-xxx --workspace-id ws-xxx`,"zh-CN":`--query "什么是 RAG?" --agent-id aid-xxx --workspace-id ws-xxx`},{"en-US":`--api-key $DASHSCOPE_API_KEY --query "test search" --agent-id aid-xxx --workspace-id ws-xxx --image https://example.com/img.jpg`,"zh-CN":`--api-key $DASHSCOPE_API_KEY --query "测试搜索" --agent-id aid-xxx --workspace-id ws-xxx --image https://example.com/img.jpg`}],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={query:n.query,agent_id:n.agentId};n.agentVersion&&(a.agent_version=n.agentVersion),n.image&&n.image.length>0&&(a.images=n.image);let o=nt(r);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=s.data?.nodes||[];if(t.quiet||i===`text`)if(c.length===0)k(`No results found.`);else for(let e=0;e<c.length;e++){let t=c[e];k(`[${e+1}] (score: ${t.score.toFixed(4)})`),k(t.text),k(``)}else A(s,i)}});const pc={message:{type:`array`,valueHint:`<text>`,description:{"en-US":`Message text (repeatable). Supports role:content prefix to set role (e.g. user:hello), defaults to user. Follows OpenAI message format`,"zh-CN":`消息文本(可重复)。支持使用 role:content 前缀指定角色(例如 user:hello),默认为 user。遵循 OpenAI 消息格式`}},agentId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Q&A service ID (find in console knowledge Q&A page)`,"zh-CN":`问答服务 ID(可在控制台知识库问答页面查看)`},required:!0},...U,agentVersion:{type:`string`,valueHint:`<version>`,description:{"en-US":`Service version to call: beta (draft for debugging) or a published number; default is the latest published version`,"zh-CN":`要调用的服务版本:beta(用于调试的草稿)或已发布版本号;默认使用最新发布版本`}},image:{type:`array`,valueHint:`<url>`,description:{"en-US":`Image URL (repeatable). Attached to the last user message as multimodal content`,"zh-CN":`图片 URL(可重复)。将作为多模态内容附加到最后一条用户消息`}}};function mc(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 hc(e){for(let t of e)if(Array.isArray(t.content)&&t.content.some(e=>e.type===`image_url`))return!0;return!1}function gc(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 _c={tool_calling:`🔍 Retrieving...`,plan_start:`🤔 Planning...`,generation_start:`✍️ Generating...`};var vc=w({description:{"en-US":`Chat with a Bailian knowledge base (RAG Q&A with streaming)`,"zh-CN":`与百炼知识库对话(支持流式输出的 RAG 问答)`},auth:`apiKey`,usageArgs:`--message <text> --agent-id <id> [flags]`,flags:pc,notes:[{"en-US":`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.`,"zh-CN":`响应以 SSE 流事件返回。事件生命周期:tool_calling → tool_return → plan_start → planning → plan_end → generation_start → generating → generation_end。tool_calling → tool_return 可能循环多次。`},{"en-US":`Auth: uses DashScope API Key (Bearer token). Get yours from the console API Key page.`,"zh-CN":`鉴权:使用 DashScope API Key(Bearer Token)。可在控制台 API Key 页面获取。`},{"en-US":"`--workspace-id` can be set via BAILIAN_WORKSPACE_ID env or `kscli config set workspace_id <id>`.","zh-CN":"`--workspace-id` 可通过 BAILIAN_WORKSPACE_ID 环境变量或 `kscli config set workspace_id <id>` 设置。"},{"en-US":`Multi-turn: use --message "user:..." and --message "assistant:..." to pass conversation history.`,"zh-CN":`多轮对话:使用 --message "user:..." 和 --message "assistant:..." 传入对话历史。`},{"en-US":"`--agent-version beta` calls the draft config for debugging before it is deployed.","zh-CN":"`--agent-version beta` 会调用尚未部署的草稿配置,便于发布前调试。"}],exampleArgs:[{"en-US":`--message "What is RAG?" --agent-id aid-xxx --workspace-id ws-xxx`,"zh-CN":`--message "什么是 RAG?" --agent-id aid-xxx --workspace-id ws-xxx`},{"en-US":`--message "user:What is RAG?" --message "assistant:RAG is..." --message "How does it work?" --agent-id aid-xxx --workspace-id ws-xxx`,"zh-CN":`--message "user:什么是 RAG?" --message "assistant:RAG 是……" --message "它是如何工作的?" --agent-id aid-xxx --workspace-id ws-xxx`},{"en-US":`--message "Describe these images" --image https://example.com/a.png --image https://example.com/b.png --agent-id aid-xxx --workspace-id ws-xxx`,"zh-CN":`--message "描述这些图片" --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=mc(r),a=r.image,o=!!a&&a.length>0;i.length===0&&o&&(i=[{role:`user`,content:``}]);let s=W(e),l=T(n.output),u=l===`text`&&!!process.stdout.isTTY;if(o){if(hc(i))throw new t(`Cannot use --image when messages already contain embedded image_url content parts. Use one approach or the other.`,c.USAGE);gc(i,a)}let d={input:{messages:i},parameters:{agent_options:{agent_id:r.agentId,...r.agentVersion?{agent_version:r.agentVersion}:{}}},stream:!0},f=et(s);if(n.dryRun){A({endpoint:f,request:d},l);return}let p=await e.client.request({path:f,method:`POST`,body:d,stream:!0});if(u){let e=O(process.stdout),r=n.verbose;for await(let n of Et(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,c.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=_c[t.extra.step_change];n&&process.stdout.write(`${e.dim(n)}\n`)}if(r&&t.extra?.step_change&&process.stderr.write(O(process.stderr).dim(`[event] step_change=${t.extra.step_change} step=${t.extra?.step??``} group=${t.extra?.group??``}`)+`
|
|
2651
2732
|
`),t.content&&process.stdout.write(t.content),n.finish_reason===`stop`)break}}catch{}}process.stdout.write(`
|
|
2652
|
-
`)}else{let e=``,r=``;for await(let n of wt(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,s.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`?k(e):A({answer:e,request_id:r},l)}}}),uc=w({description:`List knowledge bases in the workspace`,auth:`apiKey`,usageArgs:`[flags]`,flags:{name:{type:`string`,valueHint:`<text>`,description:`Filter by knowledge base name (fuzzy match, 1-20 chars)`},...qs,...U},notes:[`Auth: uses DashScope API Key (Bearer token).`,"`--workspace-id` can be set via BAILIAN_WORKSPACE_ID env or config workspace_id.",`Use the returned id as --index-id in knowledge base / document management commands.`],exampleArgs:[`--workspace-id ws-xxx`,`--name demo --page-number 2 --page-size 50`],validate(e){if(e.name!==void 0&&(e.name.length<1||e.name.length>20))return`--name must be 1-20 characters`;if(e.pageSize!==void 0&&(e.pageSize<1||e.pageSize>100))return`--page-size must be between 1 and 100`},async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a=new URL(E(r,f.indexList));n.name&&a.searchParams.set(`pipeline_name`,n.name),a.searchParams.set(`page_number`,String(n.pageNumber??1)),a.searchParams.set(`page_size`,String(n.pageSize??20));let o=a.toString();if(t.dryRun){A({endpoint:o,request:null},i);return}let s=await e.client.requestJson({path:o,method:`GET`}),c=s.data?.rows??[];if(t.quiet){for(let e of c)k(e.id);return}if(i===`text`){if(c.length===0)k(`No knowledge bases found.`);else for(let e of c)k(Js([e.id,e.name,e.embeddingModelName??`-`,e.chunkSize??`-`,e.description??``].join(` `)));k(`total: ${s.data?.total??c.length}`)}else A(s,i)}});const dc={indexId:{type:`string`,valueHint:`<id>`,description:`Knowledge base ID`,required:!0},...U};function fc(e,t){let n=new URL(E(e,f.indexList));return n.searchParams.set(`pipeline_id`,t),n.searchParams.set(`page_number`,`1`),n.searchParams.set(`page_size`,`1`),n.toString()}async function pc(e,n,r){let i=(await e.requestJson({path:fc(n,r),method:`GET`})).data?.rows?.[0];if(!i)throw new t(`Knowledge base not found: ${r}`,s.GENERAL,`Check the id — list knowledge bases in this workspace to verify it.`);return i}function G(e,t){return` ${e}: ${t??`-`}`}var mc=w({description:`Show knowledge base configuration details`,auth:`apiKey`,usageArgs:`--index-id <id> [flags]`,flags:dc,notes:[`Indexing settings are immutable; changing them requires recreating the knowledge base.`],exampleArgs:[`--index-id idx-xxx --workspace-id ws-xxx`],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output);if(t.dryRun){A({endpoint:fc(r,n.indexId),request:null},i);return}let a=await pc(e.client,r,n.indexId);if(t.quiet){k(a.id??``);return}if(i!==`text`){A(a,i);return}k(`Basic:`),k(G(`id`,a.id)),k(G(`name`,a.name)),k(G(`description`,a.description)),k(G(`dataType`,a.dataType)),k(`Indexing: [immutable — recreate required to change]`),k(G(`embeddingModelName`,a.embeddingModelName)),k(G(`embeddingDimension`,a.embeddingDimension)),k(G(`chunkSize`,a.chunkSize)),k(G(`overlapSize`,a.overlapSize)),k(G(`chunkMode`,a.chunkMode)),k(G(`separator`,a.separator)),k(`Retrieval:`),k(G(`rerankModelName`,a.rerankModelName)),k(G(`rerankMinScore`,a.rerankMinScore)),k(G(`rerankTopN`,a.rerankTopN)),k(G(`rerankMode`,a.rerankMode)),k(G(`enableRewrite`,a.enableRewrite)),k(G(`denseSimilarityTopK`,a.denseSimilarityTopK)),k(G(`sparseSimilarityTopK`,a.sparseSimilarityTopK)),k(`Data:`),k(G(`sourceType`,a.sourceType)),k(G(`connectorId`,a.connectorId))}}),hc=w({description:`List documents in a knowledge base with parse/index status`,auth:`apiKey`,usageArgs:`--index-id <id> [flags]`,flags:{indexId:{type:`string`,valueHint:`<id>`,description:`Knowledge base ID`,required:!0},...qs,...U},notes:[`Documents with status FAILED are highlighted in text mode — use the import job status command to inspect failures.`,`Page size defaults to 10 (server default), max 100.`],exampleArgs:[`--index-id idx-xxx --workspace-id ws-xxx`,`--index-id idx-xxx --page-size 100`],validate(e){if(e.pageSize!==void 0&&(e.pageSize<1||e.pageSize>100))return`--page-size must be between 1 and 100`},async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a=new URL(E(r,f.indexFiles));a.searchParams.set(`index_id`,n.indexId),a.searchParams.set(`page_num`,String(n.pageNumber??1)),a.searchParams.set(`page_size`,String(n.pageSize??10));let o=a.toString();if(t.dryRun){A({endpoint:o,request:null},i);return}let s=await e.client.requestJson({path:o,method:`GET`}),c=s.data?.rows??[];if(t.quiet){for(let e of c)k(e.doc_id??``);return}if(i===`text`){let e=O(process.stdout);if(c.length===0)k(`No documents found.`);else for(let t of c){let n=Js([t.doc_id,t.status,t.doc_name,t.doc_type??`-`,t.size??`-`].join(` `));k(t.status===`FAILED`?e.red(n):n)}k(`total: ${s.data?.total_count??c.length}`)}else A(s,i)}});const gc={indexId:{type:`string`,valueHint:`<id>`,description:`Knowledge base ID`,required:!0},jobId:{type:`string`,valueHint:`<id>`,description:`Import job ID (ingestionId returned by import commands)`,required:!0},...qs,wait:{type:`switch`,description:`Poll until the job reaches a terminal state`},pollInterval:{type:`number`,valueHint:`<seconds>`,description:`Polling interval when waiting (default: 5)`},...U};function _c(e){let t=O(process.stdout);k(`status: ${e.data?.ingestion_status??`UNKNOWN`}`);for(let n of e.data?.rows??[]){let e=n.code??n.status??`?`,r=` ${n.doc_id??`?`} ${e} ${n.doc_name??``}`;k(e.includes(`FAILED`)?t.red(r):r)}}var vc=w({description:`Check knowledge base import job status`,auth:`apiKey`,usageArgs:`--index-id <id> --job-id <id> [flags]`,flags:gc,notes:[`Both --index-id and --job-id are required (passing only one returns SystemError).`,`If you see a SystemError, the job may not exist — check the ingestion id in the document list output.`,`Overall job states are PENDING / RUNNING / COMPLETED; per-document failures (for example PARSE_FAILED) exit non-zero with the error message passed through.`],exampleArgs:[`--index-id idx-xxx --job-id job-xxx --workspace-id ws-xxx`,`--index-id idx-xxx --job-id job-xxx --wait --poll-interval 10`],async run(e){let{settings:n,flags:r}=e,i=W(e),a=T(n.output),o=new URL(E(i,f.indexJobStatus));o.searchParams.set(`index_id`,r.indexId),o.searchParams.set(`job_id`,r.jobId),r.pageNumber!==void 0&&o.searchParams.set(`page_number`,String(r.pageNumber)),r.pageSize!==void 0&&o.searchParams.set(`page_size`,String(r.pageSize));let c=o.toString();if(n.dryRun){A({endpoint:c,request:null},a);return}let l;if(l=r.wait?await ec(e.client,n,{statusUrl:c,intervalSec:r.pollInterval??5}):await e.client.requestJson({path:c,method:`GET`}),Xs(l).length>0)throw new t(Qs(l,`Import job reported document failures.`),s.GENERAL);if(n.quiet){k(l.data?.ingestion_status??`UNKNOWN`);return}a===`text`?_c(l):A(l,a)}});const K=1024*1024,yc={".doc":{maxBytes:150*K,enforce:`block`},".docx":{maxBytes:150*K,enforce:`block`},".ppt":{maxBytes:150*K,enforce:`block`},".pptx":{maxBytes:150*K,enforce:`block`},".pdf":{maxBytes:150*K,enforce:`block`},".png":{maxBytes:20*K,enforce:`block`},".jpg":{maxBytes:20*K,enforce:`block`},".jpeg":{maxBytes:20*K,enforce:`block`},".bmp":{maxBytes:20*K,enforce:`block`},".gif":{maxBytes:20*K,enforce:`block`},".xls":{maxBytes:10*K,enforce:`warn`},".xlsx":{maxBytes:10*K,enforce:`warn`},".csv":{maxBytes:10*K,enforce:`warn`},".md":{maxBytes:10*K,enforce:`warn`},".txt":{maxBytes:10*K,enforce:`warn`},".html":{maxBytes:10*K,enforce:`warn`}};function bc(e){return lr(e).toLowerCase()in yc}const xc=new Set([`node_modules`,`.git`,`.svn`,`.hg`,`__pycache__`,`.venv`,`venv`,`.env`,`.tox`,`dist`,`build`,`.cache`,`.next`,`.nuxt`]);function Sc(e){let n=[],r=[];function i(e){let a;try{a=ir(e,{withFileTypes:!0})}catch(n){let r=n.code??`unknown`;throw new t(`Cannot read directory: ${e}`,s.GENERAL,`File system error (${r}) — check the path and permissions.`)}for(let t of a){let a=I(e,t.name);if(t.isDirectory()){xc.has(t.name)||i(a);continue}t.isFile()&&(bc(t.name)?n.push(a):r.push(a))}}for(let r of e){let e;try{e=ar(r)}catch(e){let n=e.code??`unknown`;throw new t(`Cannot read path: ${r}`,s.GENERAL,`File system error (${n}) — check the path and permissions.`)}e.isDirectory()?i(r):e.isFile()&&n.push(r)}return{files:n,skipped:r}}function Cc(e){let n=lr(e).toLowerCase(),r=yc[n];if(!r)throw new t(`Unsupported file type: ${n||F(e)}`,s.USAGE,`Supported formats: ${Object.keys(yc).join(` `)}`);let i;try{i=ar(e).size}catch(n){let r=n.code??`unknown`;throw new t(`Cannot read file: ${e}`,s.GENERAL,`File system error (${r}) — check the path and permissions.`)}if(i>r.maxBytes){let a=r.maxBytes/K;if(r.enforce===`block`)throw new t(`File exceeds the ${a} MB limit for ${n}: ${F(e)}`,s.USAGE);return{sizeBytes:i,warning:`${F(e)} exceeds the recommended 10 MB for ${n}; the server may reject or truncate it.`}}return{sizeBytes:i}}const wc=new Set([`.doc`,`.docx`,`.ppt`,`.pptx`,`.pdf`,`.xls`,`.xlsx`,`.png`,`.jpg`,`.jpeg`,`.bmp`,`.gif`]);function Tc(e,n){let r;try{r=rr(e)}catch(r){let i=r.code??`unknown`,a=`File system error (${i}) — check the path and permissions.`;throw n&&i===`ENOENT`&&!lr(e)&&!e.includes(`/`)&&!e.includes(`\\`)&&(a+=` If you meant to pass text content directly, use ${n} instead of --content-file.`),new t(`Cannot read file: ${e}`,s.GENERAL,a)}try{return new TextDecoder(`utf-8`,{fatal:!0}).decode(r)}catch{let n=lr(e).toLowerCase(),r=wc.has(n)?`Document formats cannot be used as chunk content. Upload documents via the document upload command; to edit a chunk, save the text as .md/.txt first.`:`Convert the file to UTF-8 encoding and retry.`;throw new t(`File is not valid UTF-8 plain text: ${F(e)}`,s.USAGE,r)}}var Ec=w({description:`Upload local files or directories to the data center and optionally import into a knowledge base`,auth:`apiKey`,usageArgs:`--file <path> [flags]`,flags:{file:{type:`array`,valueHint:`<path>`,description:`Local file or directory path (repeatable). Directories are scanned recursively; unsupported formats are skipped`,required:!0},indexId:{type:`string`,valueHint:`<id>`,description:`Import into this knowledge base after registration (one job for all files)`},categoryId:{type:`string`,valueHint:`<id>`,description:`Target data-center category; defaults to the workspace default category`},tag:{type:`array`,valueHint:`<text>`,description:`File tag (repeatable), applied to every uploaded file`},wait:{type:`switch`,description:`Poll the import job to a terminal state (needs --index-id)`},pollInterval:{type:`number`,valueHint:`<seconds>`,description:`Polling interval when waiting (default: 5)`},...U},notes:[`Pipeline: apply upload lease → PUT to OSS → register file → (with --index-id) create import job.`,`Without --category-id the workspace default category is resolved automatically.`,`Directories are scanned recursively; node_modules, .git, and similar are skipped automatically.`,`Multiple files are processed sequentially; on failure, already-registered file ids are listed in the error hint.`],exampleArgs:[`--file ./a.md --workspace-id ws-xxx`,`--file ./a.md --file ./b.pdf --index-id idx-xxx --wait`,`--file ./docs/ --workspace-id ws-xxx`,`--file ./docs/ --dry-run --verbose`],validate(e){if(e.wait&&!e.indexId)return`--wait requires --index-id`},async run(e){let{settings:n,flags:r}=e,i=W(e),a=T(n.output),{files:o,skipped:c}=Sc(r.file);if(o.length===0)throw new t(`No supported files found`,s.USAGE,`Supported formats: .pdf .doc .docx .ppt .pptx .xls .xlsx .csv .md .txt .html .png .jpg .jpeg .bmp .gif`);let l=o.map(e=>{let t=Cc(e);return t.warning&&process.stderr.write(`Warning: ${t.warning}\n`),{filePath:e,sizeBytes:t.sizeBytes}});if(n.dryRun){let e=r.categoryId??`default`,t=l.flatMap(t=>[{step:`applyFileUploadLease`,endpoint:E(i,f.applyFileUploadLease),request:{category:e,fileName:F(t.filePath),sizeBytes:String(t.sizeBytes),contentMd5:`<md5-base64>`}},{step:`ossPut`,endpoint:`<lease.param.url>`,request:{method:`PUT`,headers:`<lease.param.headers>`}},{step:`addFile`,endpoint:E(i,f.addFile),request:{leaseId:`<leaseId>`,category:e,parser:`AUTO_SELECT`,...r.tag?.length?{tags:r.tag}:{}}}]);r.indexId&&t.push({step:`createImportJob`,endpoint:E(i,f.indexJobCreate),request:{indexId:r.indexId,sourceType:`DATA_CENTER_FILE`,docIds:[`<fileId>`]}}),A({steps:t,skipped:c},a);return}let u=r.categoryId??`default`,d=[];for(let n of l)try{let a=rr(n.filePath),o=zn(`md5`).update(a).digest(`base64`),c=await e.client.requestJson({path:E(i,f.applyFileUploadLease),method:`POST`,body:{category:u,fileName:F(n.filePath),sizeBytes:String(n.sizeBytes),contentMd5:o}}),l=c.data?.leaseId,p=c.data?.param;if(!l||!p?.url)throw new t(`Upload lease response missing leaseId/url for ${n.filePath}`,s.GENERAL);let m;try{m=await fetch(p.url,{method:p.method??`PUT`,headers:p.headers,body:a})}catch(e){let r=e.cause?.code;throw new t(`OSS upload failed for ${F(n.filePath)}`,s.NETWORK,r?`Network error (${r}).`:void 0,{cause:e})}if(!m.ok){let e=await m.text().catch(()=>``);throw new t(`OSS upload rejected (HTTP ${m.status}) for ${F(n.filePath)}${e?`: ${e.slice(0,300)}`:``}`,s.GENERAL)}let h=(await e.client.requestJson({path:E(i,f.addFile),method:`POST`,body:{leaseId:l,category:u,parser:`AUTO_SELECT`,...r.tag?.length?{tags:r.tag}:{}}})).data?.fileId;if(!h)throw new t(`addFile response missing fileId for ${n.filePath}`,s.GENERAL);d.push({path:n.filePath,fileId:h})}catch(e){throw d.length>0?tc(e,`Already registered: ${d.map(e=>e.fileId).join(`, `)}`):e}let p,m;if(r.indexId&&(p=(await e.client.requestJson({path:E(i,f.indexJobCreate),method:`POST`,body:{indexId:r.indexId,sourceType:`DATA_CENTER_FILE`,docIds:d.map(e=>e.fileId)}})).data?.ingestionId,r.wait&&p)){let a=await ec(e.client,n,{statusUrl:$s(i,r.indexId,p).toString(),intervalSec:r.pollInterval??5});if(m=Ys(a),Xs(a).length>0)throw new t(Qs(a,`Import job reported document failures.`),s.GENERAL,`Registered file ids: ${d.map(e=>e.fileId).join(`, `)}`)}if(n.quiet){for(let e of d)k(e.fileId);return}if(a===`text`){for(let e of d)k(`${F(e.path)} ${e.fileId} registered`);p&&k(`job: ${p}`),m&&k(`status: ${m}`);let e=[`Uploaded ${d.length} file${d.length===1?``:`s`}`];if(c.length>0&&e.push(`skipped ${c.length} unsupported`),k(`\n${e.join(`, `)}.`),n.verbose&&c.length>0){k(`Skipped files:`);for(let e of c)k(` ${F(e)}`)}return}A({files:d.map(e=>({path:e.path,fileId:e.fileId})),skipped:c,...r.indexId?{index_id:r.indexId}:{},...p?{ingestion_id:p}:{},...m?{final_status:m}:{}},a)}});const Dc={name:{type:`string`,valueHint:`<text>`,description:`Knowledge base name (1-20 chars, unique in workspace)`,required:!0},docId:{type:`array`,valueHint:`<id>`,description:`Data-center file id to import (repeatable); mutually exclusive with --category-id`},categoryId:{type:`array`,valueHint:`<id>`,description:`Import every file under this category (repeatable); mutually exclusive with --doc-id`},embeddingModel:{type:`string`,valueHint:`<name>`,description:`Embedding model name (default: text-embedding-v4)`},chunkSize:{type:`number`,valueHint:`<n>`,description:`Chunk size in characters (default: 600, recommended 300-800)`},wait:{type:`switch`,description:`Poll the initial import job to a terminal state`},pollInterval:{type:`number`,valueHint:`<seconds>`,description:`Polling interval when waiting (default: 5)`},...U};function Oc(e){return e.docId?.length?{sourceType:`DATA_CENTER_FILE`,docIds:e.docId,dataSources:[{sourceType:`DATA_CENTER_FILE`}]}:{sourceType:`DATA_CENTER_CATEGORY`,categoryIds:e.categoryId,dataSources:[{sourceType:`DATA_CENTER_CATEGORY`}]}}var kc=w({description:`Create a knowledge base and import data-center files or categories`,auth:`apiKey`,usageArgs:`--name <text> (--doc-id <id> | --category-id <id>) [flags]`,flags:Dc,notes:[`Structure/sink types are fixed to the default document knowledge base (unstructured, BUILT_IN storage).`,`Returns the knowledge base id (pipelineId) and the initial import job id (ingestionId).`,`Use the import job status command (or --wait) to track the initial import.`],exampleArgs:[`--name demo --doc-id file-xxx --workspace-id ws-xxx`,`--name demo --category-id cate-xxx --wait`],validate(e){if(e.name.length<1||e.name.length>20)return`--name must be 1-20 characters`;let t=!!e.docId?.length,n=!!e.categoryId?.length;if(t&&n)return`Use either --doc-id or --category-id, not both`;if(!t&&!n)return`Provide --doc-id or --category-id as the data source`},async run(e){let{settings:n,flags:r}=e,i=W(e),a=T(n.output),o={name:r.name,structureType:`unstructured`,sinkType:`BUILT_IN`,embeddingModelName:r.embeddingModel??`text-embedding-v4`,chunkSize:r.chunkSize??600,...Oc(r)},c=E(i,f.indexCreateV2);if(n.dryRun){A({endpoint:c,request:o},a);return}let l=await e.client.requestJson({path:c,method:`POST`,body:o}),u=l.data?.pipelineId,d=l.data?.ingestionId,p;if(r.wait&&u&&d){let a=await ec(e.client,n,{statusUrl:$s(i,u,d).toString(),intervalSec:r.pollInterval??5});if(p=Ys(a),Xs(a).length>0)throw new t(Qs(a,`Initial import reported document failures.`),s.GENERAL,`Knowledge base created: ${u}`,{api:{requestId:a.request_id}})}if(n.quiet){k(u??``);return}if(a===`text`){k(`index_id: ${u??`-`}`),d&&k(`ingestion_id: ${d}`),p&&k(`status: ${p}`),k(`Next: check the import job status, then search against this knowledge base.`);return}A(p?{...l,final_status:p}:l,a)}}),Ac=w({description:`Update knowledge base name, description or rerank threshold`,auth:`apiKey`,usageArgs:`--index-id <id> [flags]`,flags:{indexId:{type:`string`,valueHint:`<id>`,description:`Knowledge base ID`,required:!0},name:{type:`string`,valueHint:`<text>`,description:`New knowledge base name (1-20 chars)`},description:{type:`string`,valueHint:`<text>`,description:`New knowledge base description`},rerankMinScore:{type:`number`,valueHint:`<score>`,description:`Rerank minimum score threshold, range 0-1 (chunks below are filtered)`},...U},notes:[`Indexing settings (embedding model, chunk size, etc.) are immutable — recreate the knowledge base to change them.`],exampleArgs:[`--index-id idx-xxx --description 'product docs v2' --workspace-id ws-xxx`,`--index-id idx-xxx --rerank-min-score 0.3`],validate(e){if(e.name===void 0&&e.description===void 0&&e.rerankMinScore===void 0)return`Nothing to update — pass --name, --description or --rerank-min-score`;if(e.name!==void 0&&(e.name.length<1||e.name.length>20))return`--name must be 1-20 characters`;if(e.rerankMinScore!==void 0&&(e.rerankMinScore<0||e.rerankMinScore>1))return`--rerank-min-score must be between 0 and 1`},async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={id:n.indexId,...n.name===void 0?{}:{name:n.name},...n.description===void 0?{}:{description:n.description},...n.rerankMinScore===void 0?{}:{rerankMinScore:n.rerankMinScore}},o=E(r,f.indexUpdate);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a});if(!t.quiet){if(i===`text`){k(`updated: ${n.indexId}`);return}A(s,i)}}});const jc={indexId:{type:`string`,valueHint:`<id>`,description:`Knowledge base ID`,required:!0},yes:{type:`switch`,description:`Skip the confirmation prompt`},...U};async function Mc(e,t,n){let r=``,i=``;try{r=` name: ${(await pc(e.client,t,n)).name}`}catch{}try{let r=new URL(E(t,f.indexFiles));r.searchParams.set(`index_id`,n),r.searchParams.set(`page_num`,`1`),r.searchParams.set(`page_size`,`1`);let a=(await e.client.requestJson({path:r.toString(),method:`GET`})).data?.total_count;typeof a==`number`&&(i=` documents: ${a}`)}catch{}return`Delete knowledge base ${n}${r}${i}\nThis permanently removes the knowledge base with all documents and chunks. It cannot be undone.`}var Nc=w({description:`Delete a knowledge base with all its documents and chunks`,auth:`apiKey`,usageArgs:`--index-id <id> [flags]`,flags:jc,notes:[`Irreversible — the knowledge base and all indexed content are permanently removed.`,`Files in the data center are not affected; only the knowledge base index is deleted.`],exampleArgs:[`--index-id idx-xxx --workspace-id ws-xxx`,`--index-id idx-xxx --yes`],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={index_id:n.indexId},o=E(r,f.indexDelete);if(t.dryRun){A({endpoint:o,request:a},i);return}await _n(n.yes?``:await Mc(e,r,n.indexId),n.yes??!1);let s=await e.client.requestJson({path:o,method:`POST`,body:a});if(!t.quiet){if(i===`text`){k(`deleted: ${n.indexId}`);return}A(s,i)}}});const Pc={indexId:{type:`string`,valueHint:`<id>`,description:`Knowledge base ID`,required:!0},docId:{type:`array`,valueHint:`<id>`,description:`Document ID to delete (repeatable)`,required:!0},yes:{type:`switch`,description:`Skip the confirmation prompt`},...U};function Fc(e,t){let n=t.length<=5?t.join(`
|
|
2733
|
+
`)}else{let e=``,r=``;for await(let n of Et(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,c.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`?k(e):A({answer:e,request_id:r},l)}}}),yc=w({description:{"en-US":`List knowledge bases in the workspace`,"zh-CN":`列出 Workspace 中的知识库`},auth:`apiKey`,usageArgs:`[flags]`,flags:{name:{type:`string`,valueHint:`<text>`,description:{"en-US":`Filter by knowledge base name (fuzzy match, 1-20 chars)`,"zh-CN":`按知识库名称筛选(模糊匹配,1–20 个字符)`}},...nc,...U},notes:[{"en-US":`Auth: uses DashScope API Key (Bearer token).`,"zh-CN":`鉴权:使用 DashScope API Key(Bearer Token)。`},{"en-US":"`--workspace-id` can be set via BAILIAN_WORKSPACE_ID env or config workspace_id.","zh-CN":"`--workspace-id` 可通过 BAILIAN_WORKSPACE_ID 环境变量或配置项 workspace_id 设置。"},{"en-US":`Use the returned id as --index-id in knowledge base / document management commands.`,"zh-CN":`在知识库/文档管理命令中,将返回的 ID 作为 --index-id 使用。`}],exampleArgs:[`--workspace-id ws-xxx`,`--name demo --page-number 2 --page-size 50`],validate(e){if(e.name!==void 0&&(e.name.length<1||e.name.length>20))return`--name must be 1-20 characters`;if(e.pageSize!==void 0&&(e.pageSize<1||e.pageSize>100))return`--page-size must be between 1 and 100`},async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a=new URL(E(r,p.indexList));n.name&&a.searchParams.set(`pipeline_name`,n.name),a.searchParams.set(`page_number`,String(n.pageNumber??1)),a.searchParams.set(`page_size`,String(n.pageSize??20));let o=a.toString();if(t.dryRun){A({endpoint:o,request:null},i);return}let s=await e.client.requestJson({path:o,method:`GET`}),c=s.data?.rows??[];if(t.quiet){for(let e of c)k(e.id);return}if(i===`text`){if(c.length===0)k(`No knowledge bases found.`);else for(let e of c)k(rc([e.id,e.name,e.embeddingModelName??`-`,e.chunkSize??`-`,e.description??``].join(` `)));k(`total: ${s.data?.total??c.length}`)}else A(s,i)}});const bc={indexId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Knowledge base ID`,"zh-CN":`知识库 ID`},required:!0},...U};function xc(e,t){let n=new URL(E(e,p.indexList));return n.searchParams.set(`pipeline_id`,t),n.searchParams.set(`page_number`,`1`),n.searchParams.set(`page_size`,`1`),n.toString()}async function Sc(e,n,r){let i=(await e.requestJson({path:xc(n,r),method:`GET`})).data?.rows?.[0];if(!i)throw new t(`Knowledge base not found: ${r}`,c.GENERAL,`Check the id — list knowledge bases in this workspace to verify it.`);return i}function G(e,t){return` ${e}: ${t??`-`}`}var Cc=w({description:{"en-US":`Show knowledge base configuration details`,"zh-CN":`查看知识库配置详情`},auth:`apiKey`,usageArgs:`--index-id <id> [flags]`,flags:bc,notes:[{"en-US":`Indexing settings are immutable; changing them requires recreating the knowledge base.`,"zh-CN":`索引设置不可修改;如需更改,必须重新创建知识库。`}],exampleArgs:[`--index-id idx-xxx --workspace-id ws-xxx`],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output);if(t.dryRun){A({endpoint:xc(r,n.indexId),request:null},i);return}let a=await Sc(e.client,r,n.indexId);if(t.quiet){k(a.id??``);return}if(i!==`text`){A(a,i);return}k(`Basic:`),k(G(`id`,a.id)),k(G(`name`,a.name)),k(G(`description`,a.description)),k(G(`dataType`,a.dataType)),k(`Indexing: [immutable — recreate required to change]`),k(G(`embeddingModelName`,a.embeddingModelName)),k(G(`embeddingDimension`,a.embeddingDimension)),k(G(`chunkSize`,a.chunkSize)),k(G(`overlapSize`,a.overlapSize)),k(G(`chunkMode`,a.chunkMode)),k(G(`separator`,a.separator)),k(`Retrieval:`),k(G(`rerankModelName`,a.rerankModelName)),k(G(`rerankMinScore`,a.rerankMinScore)),k(G(`rerankTopN`,a.rerankTopN)),k(G(`rerankMode`,a.rerankMode)),k(G(`enableRewrite`,a.enableRewrite)),k(G(`denseSimilarityTopK`,a.denseSimilarityTopK)),k(G(`sparseSimilarityTopK`,a.sparseSimilarityTopK)),k(`Data:`),k(G(`sourceType`,a.sourceType)),k(G(`connectorId`,a.connectorId))}}),wc=w({description:{"en-US":`List documents in a knowledge base with parse/index status`,"zh-CN":`列出知识库文档及其解析/索引状态`},auth:`apiKey`,usageArgs:`--index-id <id> [flags]`,flags:{indexId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Knowledge base ID`,"zh-CN":`知识库 ID`},required:!0},...nc,...U},notes:[{"en-US":`Documents with status FAILED are highlighted in text mode — use the import job status command to inspect failures.`,"zh-CN":`文本模式会突出显示状态为 FAILED 的文档——请使用导入任务状态命令检查失败详情。`},{"en-US":`Page size defaults to 10 (server default), max 100.`,"zh-CN":`分页大小默认为 10(服务端默认值),最大为 100。`}],exampleArgs:[`--index-id idx-xxx --workspace-id ws-xxx`,`--index-id idx-xxx --page-size 100`],validate(e){if(e.pageSize!==void 0&&(e.pageSize<1||e.pageSize>100))return`--page-size must be between 1 and 100`},async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a=new URL(E(r,p.indexFiles));a.searchParams.set(`index_id`,n.indexId),a.searchParams.set(`page_num`,String(n.pageNumber??1)),a.searchParams.set(`page_size`,String(n.pageSize??10));let o=a.toString();if(t.dryRun){A({endpoint:o,request:null},i);return}let s=await e.client.requestJson({path:o,method:`GET`}),c=s.data?.rows??[];if(t.quiet){for(let e of c)k(e.doc_id??``);return}if(i===`text`){let e=O(process.stdout);if(c.length===0)k(`No documents found.`);else for(let t of c){let n=rc([t.doc_id,t.status,t.doc_name,t.doc_type??`-`,t.size??`-`].join(` `));k(t.status===`FAILED`?e.red(n):n)}k(`total: ${s.data?.total_count??c.length}`)}else A(s,i)}});const Tc={indexId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Knowledge base ID`,"zh-CN":`知识库 ID`},required:!0},jobId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Import job ID (ingestionId returned by import commands)`,"zh-CN":`导入任务 ID(导入命令返回的 ingestionId)`},required:!0},...nc,wait:{type:`switch`,description:{"en-US":`Poll until the job reaches a terminal state`,"zh-CN":`轮询直到任务进入终态`}},pollInterval:{type:`number`,valueHint:`<seconds>`,description:{"en-US":`Polling interval when waiting (default: 5)`,"zh-CN":`等待时的轮询间隔(默认:5)`}},...U};function Ec(e){let t=O(process.stdout);k(`status: ${e.data?.ingestion_status??`UNKNOWN`}`);for(let n of e.data?.rows??[]){let e=n.code??n.status??`?`,r=` ${n.doc_id??`?`} ${e} ${n.doc_name??``}`;k(e.includes(`FAILED`)?t.red(r):r)}}var Dc=w({description:{"en-US":`Check knowledge base import job status`,"zh-CN":`检查知识库导入任务状态`},auth:`apiKey`,usageArgs:`--index-id <id> --job-id <id> [flags]`,flags:Tc,notes:[{"en-US":`Both --index-id and --job-id are required (passing only one returns SystemError).`,"zh-CN":`--index-id 和 --job-id 均为必填(只传其中一个会返回 SystemError)。`},{"en-US":`If you see a SystemError, the job may not exist — check the ingestion id in the document list output.`,"zh-CN":`如果出现 SystemError,任务可能不存在——请检查文档列表输出中的 ingestion ID。`},{"en-US":`Overall job states are PENDING / RUNNING / COMPLETED; per-document failures (for example PARSE_FAILED) exit non-zero with the error message passed through.`,"zh-CN":`任务整体状态为 PENDING / RUNNING / COMPLETED;单个文档失败(例如 PARSE_FAILED)时会以非零状态退出,并原样透传错误信息。`}],exampleArgs:[`--index-id idx-xxx --job-id job-xxx --workspace-id ws-xxx`,`--index-id idx-xxx --job-id job-xxx --wait --poll-interval 10`],async run(e){let{settings:n,flags:r}=e,i=W(e),a=T(n.output),o=new URL(E(i,p.indexJobStatus));o.searchParams.set(`index_id`,r.indexId),o.searchParams.set(`job_id`,r.jobId),r.pageNumber!==void 0&&o.searchParams.set(`page_number`,String(r.pageNumber)),r.pageSize!==void 0&&o.searchParams.set(`page_size`,String(r.pageSize));let s=o.toString();if(n.dryRun){A({endpoint:s,request:null},a);return}let l;if(l=r.wait?await lc(e.client,n,{statusUrl:s,intervalSec:r.pollInterval??5}):await e.client.requestJson({path:s,method:`GET`}),ac(l).length>0)throw new t(sc(l,`Import job reported document failures.`),c.GENERAL);if(n.quiet){k(l.data?.ingestion_status??`UNKNOWN`);return}a===`text`?Ec(l):A(l,a)}});const K=1024*1024,Oc={".doc":{maxBytes:150*K,enforce:`block`},".docx":{maxBytes:150*K,enforce:`block`},".ppt":{maxBytes:150*K,enforce:`block`},".pptx":{maxBytes:150*K,enforce:`block`},".pdf":{maxBytes:150*K,enforce:`block`},".png":{maxBytes:20*K,enforce:`block`},".jpg":{maxBytes:20*K,enforce:`block`},".jpeg":{maxBytes:20*K,enforce:`block`},".bmp":{maxBytes:20*K,enforce:`block`},".gif":{maxBytes:20*K,enforce:`block`},".xls":{maxBytes:10*K,enforce:`warn`},".xlsx":{maxBytes:10*K,enforce:`warn`},".csv":{maxBytes:10*K,enforce:`warn`},".md":{maxBytes:10*K,enforce:`warn`},".txt":{maxBytes:10*K,enforce:`warn`},".html":{maxBytes:10*K,enforce:`warn`}};function kc(e){return dr(e).toLowerCase()in Oc}const Ac=new Set([`node_modules`,`.git`,`.svn`,`.hg`,`__pycache__`,`.venv`,`venv`,`.env`,`.tox`,`dist`,`build`,`.cache`,`.next`,`.nuxt`]);function jc(e){let n=[],r=[];function i(e){let a;try{a=or(e,{withFileTypes:!0})}catch(n){let r=n.code??`unknown`;throw new t(`Cannot read directory: ${e}`,c.GENERAL,`File system error (${r}) — check the path and permissions.`)}for(let t of a){let a=I(e,t.name);if(t.isDirectory()){Ac.has(t.name)||i(a);continue}t.isFile()&&(kc(t.name)?n.push(a):r.push(a))}}for(let r of e){let e;try{e=sr(r)}catch(e){let n=e.code??`unknown`;throw new t(`Cannot read path: ${r}`,c.GENERAL,`File system error (${n}) — check the path and permissions.`)}e.isDirectory()?i(r):e.isFile()&&n.push(r)}return{files:n,skipped:r}}function Mc(e){let n=dr(e).toLowerCase(),r=Oc[n];if(!r)throw new t(`Unsupported file type: ${n||F(e)}`,c.USAGE,`Supported formats: ${Object.keys(Oc).join(` `)}`);let i;try{i=sr(e).size}catch(n){let r=n.code??`unknown`;throw new t(`Cannot read file: ${e}`,c.GENERAL,`File system error (${r}) — check the path and permissions.`)}if(i>r.maxBytes){let a=r.maxBytes/K;if(r.enforce===`block`)throw new t(`File exceeds the ${a} MB limit for ${n}: ${F(e)}`,c.USAGE);return{sizeBytes:i,warning:`${F(e)} exceeds the recommended 10 MB for ${n}; the server may reject or truncate it.`}}return{sizeBytes:i}}const Nc=new Set([`.doc`,`.docx`,`.ppt`,`.pptx`,`.pdf`,`.xls`,`.xlsx`,`.png`,`.jpg`,`.jpeg`,`.bmp`,`.gif`]);function Pc(e,n){let r;try{r=ar(e)}catch(r){let i=r.code??`unknown`,a=`File system error (${i}) — check the path and permissions.`;throw n&&i===`ENOENT`&&!dr(e)&&!e.includes(`/`)&&!e.includes(`\\`)&&(a+=` If you meant to pass text content directly, use ${n} instead of --content-file.`),new t(`Cannot read file: ${e}`,c.GENERAL,a)}try{return new TextDecoder(`utf-8`,{fatal:!0}).decode(r)}catch{let n=dr(e).toLowerCase(),r=Nc.has(n)?`Document formats cannot be used as chunk content. Upload documents via the document upload command; to edit a chunk, save the text as .md/.txt first.`:`Convert the file to UTF-8 encoding and retry.`;throw new t(`File is not valid UTF-8 plain text: ${F(e)}`,c.USAGE,r)}}var Fc=w({description:{"en-US":`Upload local files or directories to the data center and optionally import into a knowledge base`,"zh-CN":`上传本地文件或目录到数据中心,并可选择导入知识库`},auth:`apiKey`,usageArgs:`--file <path> [flags]`,flags:{file:{type:`array`,valueHint:`<path>`,description:{"en-US":`Local file or directory path (repeatable). Directories are scanned recursively; unsupported formats are skipped`,"zh-CN":`本地文件或目录路径(可重复)。目录会递归扫描,不支持的格式将被跳过`},required:!0},indexId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Import into this knowledge base after registration (one job for all files)`,"zh-CN":`文件注册后导入该知识库(所有文件共用一个任务)`}},categoryId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Target data-center category; defaults to the workspace default category`,"zh-CN":`目标数据中心类目;默认为 Workspace 的默认类目`}},tag:{type:`array`,valueHint:`<text>`,description:{"en-US":`File tag (repeatable), applied to every uploaded file`,"zh-CN":`文件标签(可重复),应用于每个上传文件`}},wait:{type:`switch`,description:{"en-US":`Poll the import job to a terminal state (needs --index-id)`,"zh-CN":`轮询导入任务直到进入终态(需要 --index-id)`}},pollInterval:{type:`number`,valueHint:`<seconds>`,description:{"en-US":`Polling interval when waiting (default: 5)`,"zh-CN":`等待时的轮询间隔(默认:5)`}},...U},notes:[{"en-US":`Pipeline: apply upload lease → PUT to OSS → register file → (with --index-id) create import job.`,"zh-CN":`处理流程:申请上传凭证 → PUT 到 OSS → 注册文件 →(传入 --index-id 时)创建导入任务。`},{"en-US":`Without --category-id the workspace default category is resolved automatically.`,"zh-CN":`未传入 --category-id 时,会自动解析 Workspace 的默认类目。`},{"en-US":`Directories are scanned recursively; node_modules, .git, and similar are skipped automatically.`,"zh-CN":`目录会递归扫描;node_modules、.git 等目录会被自动跳过。`},{"en-US":`Multiple files are processed sequentially; on failure, already-registered file ids are listed in the error hint.`,"zh-CN":`多个文件会依次处理;失败时,错误提示会列出已经注册成功的文件 ID。`}],exampleArgs:[`--file ./a.md --workspace-id ws-xxx`,`--file ./a.md --file ./b.pdf --index-id idx-xxx --wait`,`--file ./docs/ --workspace-id ws-xxx`,`--file ./docs/ --dry-run --verbose`],validate(e){if(e.wait&&!e.indexId)return`--wait requires --index-id`},async run(e){let{settings:n,flags:r}=e,i=W(e),a=T(n.output),{files:o,skipped:s}=jc(r.file);if(o.length===0)throw new t(`No supported files found`,c.USAGE,`Supported formats: .pdf .doc .docx .ppt .pptx .xls .xlsx .csv .md .txt .html .png .jpg .jpeg .bmp .gif`);let l=o.map(e=>{let t=Mc(e);return t.warning&&process.stderr.write(`Warning: ${t.warning}\n`),{filePath:e,sizeBytes:t.sizeBytes}});if(n.dryRun){let e=r.categoryId??`default`,t=l.flatMap(t=>[{step:`applyFileUploadLease`,endpoint:E(i,p.applyFileUploadLease),request:{category:e,fileName:F(t.filePath),sizeBytes:String(t.sizeBytes),contentMd5:`<md5-base64>`}},{step:`ossPut`,endpoint:`<lease.param.url>`,request:{method:`PUT`,headers:`<lease.param.headers>`}},{step:`addFile`,endpoint:E(i,p.addFile),request:{leaseId:`<leaseId>`,category:e,parser:`AUTO_SELECT`,...r.tag?.length?{tags:r.tag}:{}}}]);r.indexId&&t.push({step:`createImportJob`,endpoint:E(i,p.indexJobCreate),request:{indexId:r.indexId,sourceType:`DATA_CENTER_FILE`,docIds:[`<fileId>`]}}),A({steps:t,skipped:s},a);return}let u=r.categoryId??`default`,d=[];for(let n of l)try{let a=ar(n.filePath),o=Vn(`md5`).update(a).digest(`base64`),s=await e.client.requestJson({path:E(i,p.applyFileUploadLease),method:`POST`,body:{category:u,fileName:F(n.filePath),sizeBytes:String(n.sizeBytes),contentMd5:o}}),l=s.data?.leaseId,f=s.data?.param;if(!l||!f?.url)throw new t(`Upload lease response missing leaseId/url for ${n.filePath}`,c.GENERAL);let m;try{m=await fetch(f.url,{method:f.method??`PUT`,headers:f.headers,body:a})}catch(e){let r=e.cause?.code;throw new t(`OSS upload failed for ${F(n.filePath)}`,c.NETWORK,r?`Network error (${r}).`:void 0,{cause:e})}if(!m.ok){let e=await m.text().catch(()=>``);throw new t(`OSS upload rejected (HTTP ${m.status}) for ${F(n.filePath)}${e?`: ${e.slice(0,300)}`:``}`,c.GENERAL)}let h=(await e.client.requestJson({path:E(i,p.addFile),method:`POST`,body:{leaseId:l,category:u,parser:`AUTO_SELECT`,...r.tag?.length?{tags:r.tag}:{}}})).data?.fileId;if(!h)throw new t(`addFile response missing fileId for ${n.filePath}`,c.GENERAL);d.push({path:n.filePath,fileId:h})}catch(e){throw d.length>0?uc(e,`Already registered: ${d.map(e=>e.fileId).join(`, `)}`):e}let f,m;if(r.indexId&&(f=(await e.client.requestJson({path:E(i,p.indexJobCreate),method:`POST`,body:{indexId:r.indexId,sourceType:`DATA_CENTER_FILE`,docIds:d.map(e=>e.fileId)}})).data?.ingestionId,r.wait&&f)){let a=await lc(e.client,n,{statusUrl:cc(i,r.indexId,f).toString(),intervalSec:r.pollInterval??5});if(m=ic(a),ac(a).length>0)throw new t(sc(a,`Import job reported document failures.`),c.GENERAL,`Registered file ids: ${d.map(e=>e.fileId).join(`, `)}`)}if(n.quiet){for(let e of d)k(e.fileId);return}if(a===`text`){for(let e of d)k(`${F(e.path)} ${e.fileId} registered`);f&&k(`job: ${f}`),m&&k(`status: ${m}`);let e=[`Uploaded ${d.length} file${d.length===1?``:`s`}`];if(s.length>0&&e.push(`skipped ${s.length} unsupported`),k(`\n${e.join(`, `)}.`),n.verbose&&s.length>0){k(`Skipped files:`);for(let e of s)k(` ${F(e)}`)}return}A({files:d.map(e=>({path:e.path,fileId:e.fileId})),skipped:s,...r.indexId?{index_id:r.indexId}:{},...f?{ingestion_id:f}:{},...m?{final_status:m}:{}},a)}});const Ic={name:{type:`string`,valueHint:`<text>`,description:{"en-US":`Knowledge base name (1-20 chars, unique in workspace)`,"zh-CN":`知识库名称(1–20 个字符,在 Workspace 中唯一)`},required:!0},docId:{type:`array`,valueHint:`<id>`,description:{"en-US":`Data-center file id to import (repeatable); mutually exclusive with --category-id`,"zh-CN":`要导入的数据中心文件 ID(可重复);不能与 --category-id 同时使用`}},categoryId:{type:`array`,valueHint:`<id>`,description:{"en-US":`Import every file under this category (repeatable); mutually exclusive with --doc-id`,"zh-CN":`导入该类目下的所有文件(可重复);不能与 --doc-id 同时使用`}},embeddingModel:{type:`string`,valueHint:`<name>`,description:{"en-US":`Embedding model name (default: text-embedding-v4)`,"zh-CN":`Embedding 模型名称(默认:text-embedding-v4)`}},chunkSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Chunk size in characters (default: 600, recommended 300-800)`,"zh-CN":`Chunk 字符数(默认:600,建议:300–800)`}},wait:{type:`switch`,description:{"en-US":`Poll the initial import job to a terminal state`,"zh-CN":`轮询初始导入任务直到进入终态`}},pollInterval:{type:`number`,valueHint:`<seconds>`,description:{"en-US":`Polling interval when waiting (default: 5)`,"zh-CN":`等待时的轮询间隔(默认:5)`}},...U};function Lc(e){return e.docId?.length?{sourceType:`DATA_CENTER_FILE`,docIds:e.docId,dataSources:[{sourceType:`DATA_CENTER_FILE`}]}:{sourceType:`DATA_CENTER_CATEGORY`,categoryIds:e.categoryId,dataSources:[{sourceType:`DATA_CENTER_CATEGORY`}]}}var Rc=w({description:{"en-US":`Create a knowledge base and import data-center files or categories`,"zh-CN":`创建知识库并导入数据中心文件或类目`},auth:`apiKey`,usageArgs:`--name <text> (--doc-id <id> | --category-id <id>) [flags]`,flags:Ic,notes:[{"en-US":`Structure/sink types are fixed to the default document knowledge base (unstructured, BUILT_IN storage).`,"zh-CN":`结构和存储类型固定为默认文档知识库(unstructured、BUILT_IN 存储)。`},{"en-US":`Returns the knowledge base id (pipelineId) and the initial import job id (ingestionId).`,"zh-CN":`返回知识库 ID(pipelineId)和初始导入任务 ID(ingestionId)。`},{"en-US":`Use the import job status command (or --wait) to track the initial import.`,"zh-CN":`使用导入任务状态命令(或 --wait)跟踪初始导入。`}],exampleArgs:[`--name demo --doc-id file-xxx --workspace-id ws-xxx`,`--name demo --category-id cate-xxx --wait`],validate(e){if(e.name.length<1||e.name.length>20)return`--name must be 1-20 characters`;let t=!!e.docId?.length,n=!!e.categoryId?.length;if(t&&n)return`Use either --doc-id or --category-id, not both`;if(!t&&!n)return`Provide --doc-id or --category-id as the data source`},async run(e){let{settings:n,flags:r}=e,i=W(e),a=T(n.output),o={name:r.name,structureType:`unstructured`,sinkType:`BUILT_IN`,embeddingModelName:r.embeddingModel??`text-embedding-v4`,chunkSize:r.chunkSize??600,...Lc(r)},s=E(i,p.indexCreateV2);if(n.dryRun){A({endpoint:s,request:o},a);return}let l=await e.client.requestJson({path:s,method:`POST`,body:o}),u=l.data?.pipelineId,d=l.data?.ingestionId,f;if(r.wait&&u&&d){let a=await lc(e.client,n,{statusUrl:cc(i,u,d).toString(),intervalSec:r.pollInterval??5});if(f=ic(a),ac(a).length>0)throw new t(sc(a,`Initial import reported document failures.`),c.GENERAL,`Knowledge base created: ${u}`,{api:{requestId:a.request_id}})}if(n.quiet){k(u??``);return}if(a===`text`){k(`index_id: ${u??`-`}`),d&&k(`ingestion_id: ${d}`),f&&k(`status: ${f}`),k(`Next: check the import job status, then search against this knowledge base.`);return}A(f?{...l,final_status:f}:l,a)}}),zc=w({description:{"en-US":`Update knowledge base name, description or rerank threshold`,"zh-CN":`更新知识库名称、描述或 Rerank 阈值`},auth:`apiKey`,usageArgs:`--index-id <id> [flags]`,flags:{indexId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Knowledge base ID`,"zh-CN":`知识库 ID`},required:!0},name:{type:`string`,valueHint:`<text>`,description:{"en-US":`New knowledge base name (1-20 chars)`,"zh-CN":`新的知识库名称(1–20 个字符)`}},description:{type:`string`,valueHint:`<text>`,description:{"en-US":`New knowledge base description`,"zh-CN":`新的知识库描述`}},rerankMinScore:{type:`number`,valueHint:`<score>`,description:{"en-US":`Rerank minimum score threshold, range 0-1 (chunks below are filtered)`,"zh-CN":`Rerank 最低分数阈值,范围 0–1(低于阈值的 Chunk 会被过滤)`}},...U},notes:[{"en-US":`Indexing settings (embedding model, chunk size, etc.) are immutable — recreate the knowledge base to change them.`,"zh-CN":`索引设置(Embedding 模型、Chunk 大小等)不可修改——如需更改,请重新创建知识库。`}],exampleArgs:[{"en-US":`--index-id idx-xxx --description 'product docs v2' --workspace-id ws-xxx`,"zh-CN":`--index-id idx-xxx --description '产品文档 v2' --workspace-id ws-xxx`},`--index-id idx-xxx --rerank-min-score 0.3`],validate(e){if(e.name===void 0&&e.description===void 0&&e.rerankMinScore===void 0)return`Nothing to update — pass --name, --description or --rerank-min-score`;if(e.name!==void 0&&(e.name.length<1||e.name.length>20))return`--name must be 1-20 characters`;if(e.rerankMinScore!==void 0&&(e.rerankMinScore<0||e.rerankMinScore>1))return`--rerank-min-score must be between 0 and 1`},async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={id:n.indexId,...n.name===void 0?{}:{name:n.name},...n.description===void 0?{}:{description:n.description},...n.rerankMinScore===void 0?{}:{rerankMinScore:n.rerankMinScore}},o=E(r,p.indexUpdate);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a});if(!t.quiet){if(i===`text`){k(`updated: ${n.indexId}`);return}A(s,i)}}});const Bc={indexId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Knowledge base ID`,"zh-CN":`知识库 ID`},required:!0},yes:{type:`switch`,description:{"en-US":`Skip the confirmation prompt`,"zh-CN":`跳过确认提示`}},...U};async function Vc(e,t,n){let r=``,i=``;try{r=` name: ${(await Sc(e.client,t,n)).name}`}catch{}try{let r=new URL(E(t,p.indexFiles));r.searchParams.set(`index_id`,n),r.searchParams.set(`page_num`,`1`),r.searchParams.set(`page_size`,`1`);let a=(await e.client.requestJson({path:r.toString(),method:`GET`})).data?.total_count;typeof a==`number`&&(i=` documents: ${a}`)}catch{}return`Delete knowledge base ${n}${r}${i}\nThis permanently removes the knowledge base with all documents and chunks. It cannot be undone.`}var Hc=w({description:{"en-US":`Delete a knowledge base with all its documents and chunks`,"zh-CN":`删除知识库及其所有文档和 Chunk`},auth:`apiKey`,usageArgs:`--index-id <id> [flags]`,flags:Bc,notes:[{"en-US":`Irreversible — the knowledge base and all indexed content are permanently removed.`,"zh-CN":`该操作不可撤销——知识库及所有已索引内容将被永久删除。`},{"en-US":`Files in the data center are not affected; only the knowledge base index is deleted.`,"zh-CN":`数据中心中的文件不受影响;仅删除知识库索引。`}],exampleArgs:[`--index-id idx-xxx --workspace-id ws-xxx`,`--index-id idx-xxx --yes`],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={index_id:n.indexId},o=E(r,p.indexDelete);if(t.dryRun){A({endpoint:o,request:a},i);return}await yn(n.yes?``:await Vc(e,r,n.indexId),n.yes??!1);let s=await e.client.requestJson({path:o,method:`POST`,body:a});if(!t.quiet){if(i===`text`){k(`deleted: ${n.indexId}`);return}A(s,i)}}});const Uc={indexId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Knowledge base ID`,"zh-CN":`知识库 ID`},required:!0},docId:{type:`array`,valueHint:`<id>`,description:{"en-US":`Document ID to delete (repeatable)`,"zh-CN":`要删除的文档 ID(可重复)`},required:!0},yes:{type:`switch`,description:{"en-US":`Skip the confirmation prompt`,"zh-CN":`跳过确认提示`}},...U};function Wc(e,t){let n=t.length<=5?t.join(`
|
|
2653
2734
|
`):`${t.slice(0,5).join(`
|
|
2654
|
-
`)}\n ... (${t.length} documents total)`;return`Delete ${t.length} document(s) from knowledge base ${e}:\n ${n}\nDocuments and all their chunks are permanently removed from the index. This cannot be undone.`}var Ic=w({description:`Delete documents and their chunks from a knowledge base`,auth:`apiKey`,usageArgs:`--index-id <id> --doc-id <id> [flags]`,flags:Pc,notes:[`Removes documents from the knowledge base index only; the source files remain in the data center.`,"Use the doc_id from `knowledge doc list --quiet`, not the fileId from `knowledge doc upload`. For documents created via `knowledge create --doc-id`, the doc_id equals the fileId; for documents imported via `knowledge doc upload --index-id`, the doc_id may include a workspace suffix.",`Deletion may take up to ~30s to propagate — the document may still appear in the doc list briefly.`,`The output lists the ids actually deleted.`],exampleArgs:[`--index-id idx-xxx --doc-id file-xxx --workspace-id ws-xxx`,`--index-id idx-xxx --doc-id file-a --doc-id file-b --yes`],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={index_id:n.indexId,doc_ids:n.docId},o=E(r,f.indexDeleteFile);if(t.dryRun){A({endpoint:o,request:a},i);return}await _n(Fc(n.indexId,n.docId),n.yes??!1);let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=s.data?.deleted??[];if(t.quiet){for(let e of c)k(e);return}if(i===`text`){k(`deleted: ${c.length} document(s)`);for(let e of c)k(` ${e}`);c.length!==n.docId.length&&process.stderr.write(`Warning: requested ${n.docId.length} deletion(s) but the server reported ${c.length}.\n`);return}A(s,i)}}),Lc=w({description:`Batch update tags on data-center files`,auth:`apiKey`,usageArgs:`--doc-id <id> --tag <text> [flags]`,flags:{docId:{type:`array`,valueHint:`<id>`,description:`Data-center file ID to tag (repeatable, 1-20 per call)`,required:!0},tag:{type:`array`,valueHint:`<text>`,description:`Tag applied to every --doc-id (repeatable, each up to 32 chars)`,required:!0},mode:{type:`string`,valueHint:`<mode>`,description:`Update mode: append (default) or overwrite`},...U},notes:[`The same tag set is applied to every --doc-id; run the command multiple times for different tag sets.`,`Server limits: up to 100 tags per file, total tag length up to 700 chars, tag up to 32 chars.`],exampleArgs:[`--doc-id file-xxx --tag project-a --tag draft --workspace-id ws-xxx`,`--doc-id file-a --doc-id file-b --tag final --mode overwrite`],validate(e){if(e.docId.length>20)return`--doc-id accepts at most 20 ids per call`;if(e.mode!==void 0&&e.mode!==`append`&&e.mode!==`overwrite`)return`--mode must be append or overwrite`;if(e.tag.length>100)return`At most 100 tags per file`;let t=e.tag.find(e=>e.length>32);if(t)return`Tag exceeds 32 characters: ${t}`;if(e.tag.reduce((e,t)=>e+t.length,0)>700)return`Total tag length exceeds 700 characters`},async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={fileInfos:n.docId.map(e=>({fileId:e,tags:n.tag})),updateMode:(n.mode??`append`).toUpperCase()},o=E(r,f.batchUpdateFileTag);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a});if(!t.quiet){if(i===`text`){k(`tagged: ${n.docId.length} file(s) with [${n.tag.join(`, `)}]`);return}A(s,i)}}});const Rc={scene:{type:`string`,valueHint:`<scene>`,description:`Service scene: chat (Q&A) or search (retrieval). Required by the server`,required:!0},status:{type:`string`,valueHint:`<status>`,description:`Filter by status: draft, deployed (includes edited) or deleted`},name:{type:`string`,valueHint:`<text>`,description:`Filter by service name (fuzzy match)`},agentId:{type:`string`,valueHint:`<id>`,description:`Filter by exact agent ID`},indexId:{type:`string`,valueHint:`<id>`,description:`Filter by exact linked knowledge base (pipeline) ID`},...qs,...U},zc=[`chat`,`search`],Bc=[`draft`,`deployed`,`deleted`];var Vc=w({description:`List retrieval / Q&A services (agents) in the workspace`,auth:`apiKey`,usageArgs:`--scene <chat|search> [flags]`,flags:Rc,notes:[`A scene (chat or search) is required — run once per scene to see both.`,`Use the returned agent_id with the search or chat commands, or with service management commands.`],exampleArgs:[`--scene chat --workspace-id ws-xxx`,`--scene search --status deployed`],validate(e){if(!zc.includes(e.scene))return`--scene must be chat or search`;if(e.status!==void 0&&!Bc.includes(e.status))return`--status must be draft, deployed or deleted`;if(e.pageSize!==void 0&&(e.pageSize<1||e.pageSize>100))return`--page-size must be between 1 and 100`},async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={agent_scene:n.scene,...n.status?{agent_status:n.status}:{},...n.name?{agent_name:n.name}:{},...n.agentId?{agent_id:n.agentId}:{},...n.indexId?{pipeline_id:n.indexId}:{},page_number:n.pageNumber??1,page_size:n.pageSize??10},o=E(r,f.agentList);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=s.data?.rows??[];if(t.quiet){for(let e of c)k(e.agent_id??``);return}if(i===`text`){if(c.length===0)k(`No services found.`);else for(let e of c){let t=(e.pipeline_list??[]).map(e=>e.pipeline_name).filter(Boolean).join(`,`);k(Js([e.agent_id,e.agent_status,e.agent_version,e.agent_name,t?`(kb: ${t})`:``].filter(Boolean).join(` `)))}k(`total: ${s.data?.total_count??c.length}`),k(n.scene===`search`?`Use an agent_id above with the knowledge search command.`:`Use an agent_id above with the knowledge chat command.`)}else A(s,i)}});const Hc={agentId:{type:`string`,valueHint:`<id>`,description:`Service (agent) ID`,required:!0},agentVersion:{type:`string`,valueHint:`<version>`,description:`Specific version to inspect (beta or a published number); omit for all versions`},...U};function Uc(e){k(`Version ${e.agent_version??`?`}:`),e.agent_version_desc&&k(` desc: ${e.agent_version_desc}`),e.publish_time!==void 0&&k(` published: ${e.publish_time}`);let t=e.agent_config;if(t){t.agent_policy&&k(` policy: ${t.agent_policy}`),t.agent_model&&k(` model: ${t.agent_model}`),t.temperature!==void 0&&k(` temperature: ${t.temperature}`);for(let e of t.kb_search_configs??[])k(` kb: ${typeof e.id==`string`?e.id:`?`}${typeof e.name==`string`?` (${e.name})`:``}`)}}var Wc=w({description:`Show service (agent) details including per-version configuration`,auth:`apiKey`,usageArgs:`--agent-id <id> [flags]`,flags:Hc,notes:[`Without --agent-version all versions are returned (beta draft plus published numbers).`,`The version value is passed through as-is; the valid set is server-side state.`],exampleArgs:[`--agent-id aid-xxx --workspace-id ws-xxx`,`--agent-id aid-xxx --agent-version beta`],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={agent_id:n.agentId,...n.agentVersion?{agent_version:n.agentVersion}:{}},o=E(r,f.agentGet);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=s.data;if(t.quiet){k(c?.agent_id??``);return}if(i!==`text`){A(s,i);return}k(`Basic:`),k(` id: ${c?.agent_id??`-`}`),k(` name: ${c?.agent_name??`-`}`),k(` desc: ${c?.agent_desc??`-`}`),k(` scene: ${c?.agent_scene??`-`}`),k(` status: ${c?.agent_status??`-`}`);for(let e of c?.agent_details??[])Uc(e)}}),Gc=w({description:`Create a retrieval / Q&A service (initial status: draft, version: beta)`,auth:`apiKey`,usageArgs:`--name <text> --scene <chat|search> [flags]`,flags:{name:{type:`string`,valueHint:`<text>`,description:`Service name (up to 200 chars, unique per scene in the workspace)`,required:!0},scene:{type:`string`,valueHint:`<scene>`,description:`Service scene: chat (Q&A) or search (retrieval)`,required:!0},description:{type:`string`,valueHint:`<text>`,description:`Service description (up to 1000 chars)`},indexId:{type:`string`,valueHint:`<id>`,description:`Bind this knowledge base; other settings use server defaults`},...U},notes:[`Without an explicit configuration the server applies its default agent settings.`,`The draft (beta) version can be tested via --agent-version beta on search/chat before deploying.`,`Requires the knowledge-base create permission in the workspace.`],exampleArgs:[`--name my-qa --scene chat --workspace-id ws-xxx`,`--name my-search --scene search --index-id idx-xxx`],validate(e){if(e.name.length>200)return`--name must be at most 200 characters`;if(e.scene!==`chat`&&e.scene!==`search`)return`--scene must be chat or search`;if(e.description!==void 0&&e.description.length>1e3)return`--description must be at most 1000 characters`},async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={agent_name:n.name,agent_scene:n.scene,...n.description?{agent_desc:n.description}:{},...n.indexId?{agent_config:{kb_search_configs:[{id:n.indexId}]}}:{}},o=E(r,f.agentCreate);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=nc(s,`agent_id`);if(t.quiet){k(c??``);return}if(i===`text`){k(`created: ${c??`-`} (status: ${nc(s,`agent_status`)??`draft`}, version: ${nc(s,`agent_version`)??`beta`})`),k(`Test the draft with --agent-version beta on search/chat, then deploy it to publish.`);return}A(s,i)}});const Kc=[`true`,`false`],qc={agentId:{type:`string`,valueHint:`<id>`,description:`Service (agent) ID`,required:!0},name:{type:`string`,valueHint:`<text>`,description:`New service name (up to 200 chars)`},description:{type:`string`,valueHint:`<text>`,description:`New service description (up to 1000 chars)`},agentVersion:{type:`string`,valueHint:`<version>`,description:`Target version (default: beta draft). Published versions only accept --version-desc`},versionDesc:{type:`string`,valueHint:`<text>`,description:`Version description`},policy:{type:`string`,valueHint:`<policy>`,description:`Agent policy: turbo (fast) or agentic (multi-turn)`},model:{type:`string`,valueHint:`<name>`,description:`Generation model code (must be in the platform allowlist)`},temperature:{type:`number`,valueHint:`<n>`,description:`Sampling temperature, range 0-2`},maxLlmCalls:{type:`number`,valueHint:`<n>`,description:`Max LLM calls per request, range 1-30`},enableSessionFile:{type:`string`,valueHint:`<bool>`,description:`Enable session files: true or false`},enableRefusal:{type:`string`,valueHint:`<bool>`,description:`Enable refusal answers: true or false`},enableAntiLeak:{type:`string`,valueHint:`<bool>`,description:`Enable anti prompt-leak: true or false`},enableRichText:{type:`string`,valueHint:`<bool>`,description:`Enable rich text output: true or false`},enableCitation:{type:`string`,valueHint:`<bool>`,description:`Enable citations: true or false`},configFile:{type:`string`,valueHint:`<path>`,description:`JSON file replacing the whole agent_config (for nested settings like kb_search_configs); mutually exclusive with scalar config flags`},...U};function Jc(e){let t={};return e.policy!==void 0&&(t.agent_policy=e.policy),e.model!==void 0&&(t.agent_model=e.model),e.temperature!==void 0&&(t.temperature=e.temperature),e.maxLlmCalls!==void 0&&(t.max_num_llm_calls=e.maxLlmCalls),e.enableSessionFile!==void 0&&(t.enable_session_file=e.enableSessionFile),e.enableRefusal!==void 0&&(t.enable_refusal=e.enableRefusal),e.enableAntiLeak!==void 0&&(t.enable_anti_leak=e.enableAntiLeak),e.enableRichText!==void 0&&(t.enable_rich_text=e.enableRichText),e.enableCitation!==void 0&&(t.enable_citation=e.enableCitation),t}function Yc(e){let n;try{n=rr(e,`utf-8`)}catch(n){let r=n.code??`unknown`;throw new t(`Cannot read config file: ${e}`,s.GENERAL,`File system error (${r}) — check the path and permissions.`)}let r;try{r=JSON.parse(n)}catch{throw new t(`--config-file must contain valid JSON.`,s.USAGE)}if(typeof r!=`object`||!r||Array.isArray(r))throw new t(`--config-file must contain a JSON object.`,s.USAGE);let i=r;return Zc(i),i}const Xc=new Set([`agent_policy`,`agent_model`,`enable_session_file`,`enable_refusal`,`enable_anti_leak`,`enable_rich_text`,`enable_citation`,`temperature`,`max_num_llm_calls`,`max_completion_tokens`,`session_file_max_parse_length`,`enable_kb_router`,`kb_router_model`,`rerank_top_n`,`hybrid_rerank`,`kb_search_configs`]);function Zc(e){if(e.agent_policy!==void 0&&![`turbo`,`agentic`].includes(e.agent_policy))throw new t(`agent_policy must be turbo or agentic`,s.USAGE);if(e.temperature!==void 0&&(e.temperature<0||e.temperature>2))throw new t(`temperature must be between 0 and 2`,s.USAGE);if(e.max_num_llm_calls!==void 0&&(e.max_num_llm_calls<1||e.max_num_llm_calls>30))throw new t(`max_num_llm_calls must be between 1 and 30`,s.USAGE);if(e.rerank_top_n!==void 0&&(e.rerank_top_n<1||e.rerank_top_n>20))throw new t(`rerank_top_n must be between 1 and 20`,s.USAGE);for(let t of e.kb_search_configs??[]){let e=t.rerank;e?.rerank_instruct&&e.rerank_mode!==`custom`&&process.stderr.write(`Warning: rerank_instruct is only effective with rerank_mode=custom; the server clears it otherwise.
|
|
2655
|
-
`)}for(let t of Object.keys(e))
|
|
2656
|
-
WARNING: a published version is live — deploying replaces its behavior with the current draft.`))}catch{}return`Deploy service ${n}${r}${i}\nPublishing changes what live callers get from this service.`}var
|
|
2657
|
-
WARNING: this service is LIVE — deleting it breaks existing callers.`))}catch{}return`Delete service ${n}${r}${i}\nDeletion cannot be undone; the agent_id can no longer be used for search or chat calls.`}var al=w({description:`Delete a retrieval / Q&A service (soft delete, idempotent)`,auth:`apiKey`,usageArgs:`--agent-id <id> [flags]`,flags:rl,notes:[`Deletion cannot be undone; the agent_id becomes unusable for search and chat calls.`,`Idempotent — deleting an already-deleted service does not fail.`,`Requires the knowledge-base delete permission in the workspace.`],exampleArgs:[`--agent-id aid-xxx --workspace-id ws-xxx`,`--agent-id aid-xxx --yes`],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={agent_id:n.agentId},o=E(r,f.agentDelete);if(t.dryRun){A({endpoint:o,request:a},i);return}await _n(n.yes?``:await il(e.client,r,n.agentId),n.yes??!1);let s=await e.client.requestJson({path:o,method:`POST`,body:a});if(!t.quiet){if(i===`text`){k(`deleted: ${n.agentId} (status: ${nc(s,`agent_status`)??`deleted`})`);return}A(s,i)}}}),ol=w({description:`Copy a service into a new draft (name gets a copy_ prefix)`,auth:`apiKey`,usageArgs:`--agent-id <id> [flags]`,flags:{agentId:{type:`string`,valueHint:`<id>`,description:`Source service (agent) ID to copy`,required:!0},...U},notes:[`The copy starts as a beta draft; test it with --agent-version beta, then deploy to publish.`,`Requires the knowledge-base create permission in the workspace.`],exampleArgs:[`--agent-id aid-xxx --workspace-id ws-xxx`],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={agent_id:n.agentId},o=E(r,f.agentCopy);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=nc(s,`agent_id`);if(t.quiet){k(c??``);return}if(i===`text`){k(`new agent_id: ${c??`-`} (name: ${nc(s,`agent_name`)??`-`}, status: ${nc(s,`agent_status`)??`draft`})`),k(`Test the draft with --agent-version beta on search/chat, then deploy it to publish.`);return}A(s,i)}});const sl={indexId:{type:`string`,valueHint:`<id>`,description:`Knowledge base ID`,required:!0},docId:{type:`string`,valueHint:`<id>`,description:`Owning document ID from the doc list command; required in practice for all knowledge base types`},content:{type:`string`,valueHint:`<text>`,description:`Chunk body text, up to 6000 chars (document-type); alternative to --content-file`},contentFile:{type:`string`,valueHint:`<path>`,description:`Read chunk body from a UTF-8 plain text file (.md/.txt etc.)`},title:{type:`string`,valueHint:`<text>`,description:`Chunk title, up to 50 chars (document-type)`},imageUrl:{type:`array`,valueHint:`<url>`,description:`Chunk image URL (repeatable, up to 10; document-type)`},field:{type:`array`,valueHint:`<key=value>`,description:`Arbitrary field entry (repeatable) for table/image knowledge bases where keys are Excel column headers; mutually exclusive with content/title/image flags`},...U};function cl(e){let n={};for(let r of e){let e=r.indexOf(`=`);if(e<=0)throw new t(`--field must be key=value, got: ${r}`,s.USAGE);n[r.slice(0,e)]=r.slice(e+1)}return n}var ll=w({description:`Add a chunk directly to a knowledge base`,auth:`apiKey`,usageArgs:`--index-id <id> (--content <text> | --field <k=v>) [flags]`,flags:sl,notes:[`Document / table / image knowledge bases are supported; audio-video ones are not.`,`--doc-id is required in practice for all knowledge base types. Use the document-level id from the doc list command; the per-row doc_id in chunk list output is not accepted.`,`Image-type documents do not support text chunks. Target a text-type document (docx/pdf/txt) instead.`,`The API is idempotent but rate-limited to 10 calls per second — throttle batch scripts.`,`The response carries no chunk id; list chunks afterwards to find the new one.`,`For table/image knowledge bases use --field with Excel column headers as keys; values are passed through as strings.`],exampleArgs:[`--index-id idx-xxx --content "chunk text" --title intro --workspace-id ws-xxx`,`--index-id idx-xxx --field 列A=v1 --field 列B=v2`],validate(e){let t=e.content!==void 0||e.contentFile!==void 0||e.title!==void 0||!!e.imageUrl?.length,n=!!e.field?.length;if(t&&n)return`--field is mutually exclusive with --content/--content-file/--title/--image-url`;if(!t&&!n)return`Provide chunk content via --content/--content-file or --field entries`;if(e.content!==void 0&&e.contentFile!==void 0)return`Use either --content or --content-file, not both`;if(e.content!==void 0&&e.content.length>6e3)return`--content must be at most 6000 characters`;if(e.title!==void 0&&e.title.length>50)return`--title must be at most 50 characters`;if(e.imageUrl!==void 0&&e.imageUrl.length>10)return`--image-url accepts at most 10 entries`},async run(e){let{settings:n,flags:r}=e,i=W(e),a=T(n.output),o;if(r.field?.length)o=cl(r.field);else{let e=r.contentFile===void 0?r.content:Tc(r.contentFile,`--content`);if(typeof e==`string`&&e.length>6e3)throw new t(`Chunk content must be at most 6000 characters`,s.USAGE);o={...e===void 0?{}:{content:e},...r.title===void 0?{}:{title:r.title},...r.imageUrl?.length?{image_urls:r.imageUrl}:{}}}let c={pipelineId:r.indexId,...r.docId?{dataId:r.docId}:{},field:o},l=E(i,f.chunkCreate);if(n.dryRun){A({endpoint:l,request:c},a);return}let u=await e.client.requestJson({path:l,method:`POST`,body:c});if(!n.quiet){if(a===`text`){k(`chunk created (pipeline: ${r.indexId})`),k(`List chunks to find the new chunk id.`);return}A(u,a)}}}),ul=w({description:`List chunks in a knowledge base with content and status`,auth:`apiKey`,usageArgs:`--index-id <id> [flags]`,flags:{indexId:{type:`string`,valueHint:`<id>`,description:`Knowledge base ID`,required:!0},docId:{type:`string`,valueHint:`<id>`,description:`Only show chunks belonging to this document`},...qs,...U},notes:[`Use metadata._id as the chunk id and metadata.doc_id as the document id in chunk update/delete commands.`,`Page size defaults to 20 (server default), max 100.`],exampleArgs:[`--index-id idx-xxx --workspace-id ws-xxx`,`--index-id idx-xxx --doc-id file-xxx --page-size 50`],validate(e){if(e.pageSize!==void 0&&(e.pageSize<1||e.pageSize>100))return`--page-size must be between 1 and 100`},async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={indexId:n.indexId,pageNum:n.pageNumber??1,pageSize:n.pageSize??20,...n.docId?{docId:n.docId}:{}},o=E(r,f.chunkList);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=s.data?.nodes??[];if(t.quiet){for(let e of c)k(e.metadata?._id??``);return}if(i===`text`){if(c.length===0)k(`No chunks found.`);else for(let e of c){let t=e.metadata??{},n=t._chunk_status_message?` status: ${t._chunk_status_message}`:``,r=t.is_displayed_chunk_content===!1?` [excluded from retrieval]`:``;k(`[chunk] ${t._id??`?`} (doc: ${t.doc_name??`?`}, doc_id: ${t.doc_id??`?`})${n}${r}`);let i=t.content??e.text??``;k(` ${i.length>200?`${i.slice(0,200)}…`:i}`)}k(`total: ${s.data?.total??c.length}`)}else A(s,i)}});const dl={indexId:{type:`string`,valueHint:`<id>`,description:`Knowledge base ID`,required:!0},chunkId:{type:`string`,valueHint:`<id>`,description:`Chunk ID (metadata._id from the chunk list output)`,required:!0},docId:{type:`string`,valueHint:`<id>`,description:`Document ID owning the chunk (metadata.doc_id from the chunk list output)`,required:!0},content:{type:`string`,valueHint:`<text>`,description:`New chunk content, 10-6000 chars; alternative to --content-file`},contentFile:{type:`string`,valueHint:`<path>`,description:`Read new content from a UTF-8 plain text file (.md/.txt etc.)`},title:{type:`string`,valueHint:`<text>`,description:`Chunk title, 0-50 chars (empty string clears it; omit to keep unchanged)`},exclude:{type:`switch`,description:`Exclude this chunk from retrieval`},include:{type:`switch`,description:`Include this chunk in retrieval (default)`},...U};async function fl(e,n,r,i,a){for(let t=1;t<=10;t++){let o=(await e.requestJson({path:E(n,f.chunkList),method:`POST`,body:{indexId:r,docId:a,pageNum:t,pageSize:100}})).data?.nodes??[],s=o.find(e=>e.metadata?._id===i),c=s?.metadata?.content??s?.text;if(typeof c==`string`)return c;if(o.length<100)break}throw new t(`Chunk not found: ${i}`,s.GENERAL,`Check the chunk id via the chunk list command.`)}var pl=w({description:`Update chunk content or toggle its retrieval visibility`,auth:`apiKey`,usageArgs:`--index-id <id> --chunk-id <id> --doc-id <id> [flags]`,flags:dl,notes:[`Content must be 10-6000 characters and within the knowledge base's max chunk size.`,`--content-file expects a UTF-8 plain text file; document formats (.docx/.pdf) are not parsed here.`,`Toggling --exclude/--include without new content re-submits the existing content automatically.`],exampleArgs:[`--index-id idx-xxx --chunk-id chunk-xxx --doc-id file-xxx --content "corrected text"`,`--index-id idx-xxx --chunk-id chunk-xxx --doc-id file-xxx --exclude`],validate(e){if(e.content!==void 0&&e.contentFile!==void 0)return`Use either --content or --content-file, not both`;if(e.exclude&&e.include)return`--exclude and --include are mutually exclusive`;if(!(e.content!==void 0||e.contentFile!==void 0)&&!e.exclude&&!e.include&&e.title===void 0)return`Nothing to update — pass --content/--content-file, --title, --exclude or --include`;if(e.content!==void 0&&(e.content.length<10||e.content.length>6e3))return`--content must be 10-6000 characters`;if(e.title!==void 0&&e.title.length>50)return`--title must be at most 50 characters`},async run(e){let{settings:n,flags:r}=e,i=W(e),a=T(n.output),o=r.contentFile===void 0?r.content:Tc(r.contentFile,`--content`);if(o!==void 0&&(o.length<10||o.length>6e3))throw new t(`Chunk content must be 10-6000 characters`,s.USAGE);o===void 0&&(o=n.dryRun?`<current-content (fetched at run time)>`:await fl(e.client,i,r.indexId,r.chunkId,r.docId));let c={pipelineId:r.indexId,chunkId:r.chunkId,dataId:r.docId,content:o,isDisplayedChunkContent:!r.exclude,...r.title===void 0?{}:{title:r.title}},l=E(i,f.chunkUpdate);if(n.dryRun){A({endpoint:l,request:c},a);return}let u=await e.client.requestJson({path:l,method:`POST`,body:c});if(!n.quiet){if(a===`text`){k(`updated: ${r.chunkId}`);return}A(u,a)}}});const ml={indexId:{type:`string`,valueHint:`<id>`,description:`Knowledge base ID`,required:!0},chunkId:{type:`array`,valueHint:`<id>`,description:`Chunk ID to delete (repeatable; batches of 10 are sent automatically)`,required:!0},yes:{type:`switch`,description:`Skip the confirmation prompt`},...U};function hl(e,t=10){let n=[];for(let r=0;r<e.length;r+=t)n.push(e.slice(r,r+t));return n}var gl=w({description:`Delete chunks from a knowledge base (irreversible)`,auth:`apiKey`,usageArgs:`--index-id <id> --chunk-id <id> [flags]`,flags:ml,notes:[`Accepts at most 10 chunk ids per call; larger sets are batched automatically.`],exampleArgs:[`--index-id idx-xxx --chunk-id chunk-a --chunk-id chunk-b --workspace-id ws-xxx`,`--index-id idx-xxx --chunk-id chunk-a --yes`],async run(e){let{settings:n,flags:r}=e,i=W(e),a=T(n.output),o=hl(r.chunkId),s=E(i,f.chunkDelete);if(n.dryRun){A({endpoint:s,batches:o.map(e=>({request:{pipelineId:r.indexId,chunkIds:e}}))},a);return}await _n(`Delete ${r.chunkId.length} chunk(s) from knowledge base ${r.indexId} in ${o.length} batch(es).\nChunks are permanently removed. This cannot be undone.`,r.yes??!1);let c=0;for(let n of o)try{await e.client.requestJson({path:s,method:`POST`,body:{pipelineId:r.indexId,chunkIds:n}}),c+=n.length}catch(e){throw c>0&&e instanceof t&&!e.hint?new t(e.message,e.exitCode,`${c} chunk(s) in earlier batches were already deleted.`,{cause:e,api:e.api,rawResponse:e.rawResponse}):e}if(!n.quiet){if(a===`text`){k(`deleted: ${c} chunk(s) in ${o.length} batch(es)`);return}A({deleted_count:c,batches:o.length},a)}}});const _l={indexId:{type:`string`,valueHint:`<id>`,description:`Knowledge base ID`,required:!0},start:{type:`string`,valueHint:`<time>`,description:`Range start: Unix seconds or ISO date, must be in the past (default: 24 hours ago)`},end:{type:`string`,valueHint:`<time>`,description:`Range end: Unix seconds or ISO date, must be in the past (default: now)`},...U};function vl(e){if(/^\d+$/.test(e))return e.length>=13?String(Math.floor(Number(e)/1e3)):e;let n=/^\d{4}-\d{2}-\d{2}([T ].*)?$/.test(e)?Date.parse(e):NaN;if(Number.isNaN(n))throw new t(`Invalid time value: ${e}`,s.USAGE,`Pass Unix seconds (e.g. 1780900000) or an ISO date (e.g. 2026-07-30T00:00:00Z).`);return String(Math.floor(n/1e3))}var yl=w({description:`Show knowledge base storage and QPS monitoring data`,auth:`apiKey`,usageArgs:`--index-id <id> [flags]`,flags:_l,notes:[`Defaults to the last 24 hours when --start/--end are omitted.`,`Timestamps are normalized to epoch seconds as required by the server.`,`Future timestamps are rejected for --start and clamped to now for --end, since the monitor API only returns past data.`],exampleArgs:[`--index-id idx-xxx --workspace-id ws-xxx`,`--index-id idx-xxx --start 2026-07-30 --end 2026-07-31`],async run(e){let{settings:n,flags:r}=e,i=W(e),a=T(n.output),o=Math.floor(Date.now()/1e3),c=r.start?vl(r.start):String(o-24*3600),l=r.end?vl(r.end):String(o);if(Number(c)>o)throw new t(`Start time is in the future; the monitor API only accepts past or current timestamps.`,s.USAGE,`Use a start date/time at or before now, or omit --start to default to 24 hours ago.`);let u=Number(l)>o;u&&(l=String(o));let d={indexId:r.indexId,startTimestamp:c,endTimestamp:l},p=E(i,f.indexMonitor);if(n.dryRun){A({endpoint:p,request:d},a);return}let m=await e.client.requestJson({path:p,method:`POST`,body:d});if(a!==`text`){A(m,a);return}u&&k(`note: end time was in the future, clamped to now.`);let h=m.data?.storageMonitorData,g=m.data?.qpsMonitorData;k(`plan: ${m.data?.pipelineCommercialType??`-`}`),k(`storage: ${h?.indexStorageUsage??`-`} / ${h?.indexStorageLimit??`-`}`),k(`peak qps: ${g?.peakQps??`-`}`),k(`qps windows: ${g?.monitorData?.length??0} data point(s)`)}}),bl=w({description:`List data-center categories`,auth:`apiKey`,usageArgs:`[flags]`,flags:{collectionId:{type:`string`,valueHint:`<id>`,description:`Filter by exact collection ID`},parentId:{type:`string`,valueHint:`<id>`,description:`List sub-categories of this exact parent category`},name:{type:`string`,valueHint:`<text>`,description:`Filter by category name (exact match, unlike the knowledge base list)`},nextToken:{type:`string`,valueHint:`<token>`,description:`Cursor for the next page (from previous output)`},maxResult:{type:`number`,valueHint:`<n>`,description:`Items per page (default: 20)`},...U},notes:[`Categories marked [default] are where files land when no category is specified.`,`Pagination is cursor-based: reuse the printed next token to continue.`],exampleArgs:[`--workspace-id ws-xxx`,`--name my-category`,`--next-token <token>`],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={type:`UNSTRUCTURED`,...n.collectionId?{connectorId:n.collectionId}:{},...n.parentId?{parentId:n.parentId}:{},...n.name?{categoryName:n.name}:{},...n.nextToken?{nextToken:n.nextToken}:{},...n.maxResult===void 0?{}:{maxResult:n.maxResult}},o=E(r,f.listCategory);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=s.data?.categoryList??[];if(t.quiet){for(let e of c)k(e.categoryId??``);return}if(i===`text`){if(c.length===0)k(`No categories found.`);else for(let e of c){let t=e.isDefault?` [default]`:``;k(Js(`${e.categoryId} ${e.categoryName}${t}`))}let e=s.data?.nextToken;e&&k(`next: --next-token ${e}`)}else A(s,i)}}),xl=w({description:`Create a data-center category`,auth:`apiKey`,usageArgs:`--name <text> [flags]`,flags:{name:{type:`string`,valueHint:`<text>`,description:`Category name (1-20 chars)`,required:!0},parentId:{type:`string`,valueHint:`<id>`,description:`Create as a sub-category of this category`},collectionId:{type:`string`,valueHint:`<id>`,description:`Create under this collection (defaults to the platform collection)`},...U},notes:[`Use categories to organize data-center files by business domain.`],exampleArgs:[`--name product-docs --workspace-id ws-xxx`,`--name sub --parent-id cate-xxx`],validate(e){if(e.name.length<1||e.name.length>20)return`--name must be 1-20 characters`},async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={categoryName:n.name,categoryType:`UNSTRUCTURED`,...n.parentId?{parentCategoryId:n.parentId}:{},...n.collectionId?{connectorId:n.collectionId}:{}},o=E(r,f.addCategory);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=s.data?.categoryId;if(t.quiet){k(c??``);return}if(i===`text`){k(`created: ${c??`-`} (${n.name})`);return}A(s,i)}}),Sl=w({description:`Delete a data-center category`,auth:`apiKey`,usageArgs:`--category-id <id> [flags]`,flags:{categoryId:{type:`string`,valueHint:`<id>`,description:`Category ID to delete`,required:!0},yes:{type:`switch`,description:`Skip the confirmation prompt`},...U},notes:[`Behavior for categories containing files or sub-categories is server-defined — the server error is passed through as-is.`],exampleArgs:[`--category-id cate-xxx --workspace-id ws-xxx`,`--category-id cate-xxx --yes`],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={categoryId:n.categoryId},o=E(r,f.deleteCategory);if(t.dryRun){A({endpoint:o,request:a},i);return}await _n(`Delete category ${n.categoryId}\nThis cannot be undone.`,n.yes??!1);let s=await e.client.requestJson({path:o,method:`POST`,body:a});if(!t.quiet){if(i===`text`){k(`deleted: ${n.categoryId}`);return}A(s,i)}}}),Cl=w({description:`List files in a data-center category`,auth:`apiKey`,usageArgs:`--category-id <id> [flags]`,flags:{categoryId:{type:`string`,valueHint:`<id>`,description:`Category to list (find ids via the category list command); exact match`,required:!0},name:{type:`string`,valueHint:`<text>`,description:`Filter by exact file name without its extension (a.md → pass a)`},fileId:{type:`array`,valueHint:`<id>`,description:`Filter by exact file ID (repeatable)`},nextToken:{type:`string`,valueHint:`<token>`,description:`Cursor for the next page (from previous output)`},maxResult:{type:`number`,valueHint:`<n>`,description:`Items per page`},...U},notes:[`A real category id is required — the default value is not resolved here. Find the id via the category list command.`,`--name matches the exact file name without its extension (for a.md pass a); partial keywords return no results.`,`Pagination is cursor-based: reuse the printed next token to continue.`],exampleArgs:[`--category-id cate-xxx --workspace-id ws-xxx`,`--category-id cate-xxx --name report`],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={categoryId:n.categoryId,...n.name?{fileName:n.name}:{},...n.fileId?.length?{fileIds:n.fileId}:{},...n.nextToken?{nextToken:n.nextToken}:{},...n.maxResult===void 0?{}:{maxResult:n.maxResult}},o=E(r,f.listFile);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=s.data?.fileList??[];if(t.quiet){for(let e of c)k(e.fileId??``);return}if(i===`text`){if(c.length===0)k(`No files found.`);else for(let e of c)k(Js([e.fileId,e.status??`-`,e.fileName,e.sizeBytes??`-`].join(` `)));let e=s.data?.nextToken;e&&k(`next: --next-token ${e}`)}else A(s,i)}}),wl=w({description:`Show data-center file details (size, MD5, tags, timestamps)`,auth:`apiKey`,usageArgs:`--file-id <id> [flags]`,flags:{fileId:{type:`string`,valueHint:`<id>`,description:`Data-center file ID`,required:!0},...U},exampleArgs:[`--file-id file-xxx --workspace-id ws-xxx`],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={fileId:n.fileId},o=E(r,f.describeFile);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=s.data;if(t.quiet){k(c?.fileId??``);return}if(i!==`text`){A(s,i);return}k(`id: ${c?.fileId??`-`}`),k(`name: ${c?.fileName??`-`}`),k(`type: ${c?.fileType??`-`}`),k(`size: ${c?.sizeBytes??`-`}`),k(`status: ${c?.status??`-`}`),k(`parser: ${c?.parser??`-`}`),k(`category: ${c?.category??`-`}`),k(`uploaded: ${c?.uploadTime??`-`}`),k(`tags: ${(Array.isArray(c?.tags)?c.tags.join(`, `):c?.tags??`-`)||`-`}`)}});const Tl={fileId:{type:`string`,valueHint:`<id>`,description:`Data-center file ID to delete`,required:!0},yes:{type:`switch`,description:`Skip the confirmation prompt`},...U};async function El(e,t,n){let r=``;try{let i=await e.requestJson({path:E(t,f.describeFile),method:`POST`,body:{fileId:n}});i.data?.fileName&&(r=` name: ${i.data.fileName}`)}catch{}return`Delete data-center file ${n}${r}\nPERMANENT: if the file is referenced by knowledge bases, their document indexes break too. This differs from removing a document from one knowledge base.`}var Dl=w({description:`Permanently delete a file from the data center`,auth:`apiKey`,usageArgs:`--file-id <id> [flags]`,flags:Tl,notes:[`Irreversible. If knowledge bases reference this file, their related document indexes become invalid.`,`To remove a document from a single knowledge base only, use the document delete command instead.`],exampleArgs:[`--file-id file-xxx --workspace-id ws-xxx`,`--file-id file-xxx --yes`],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={fileId:n.fileId},o=E(r,f.deleteFile);if(t.dryRun){A({endpoint:o,request:a},i);return}await _n(n.yes?``:await El(e.client,r,n.fileId),n.yes??!1);let s=await e.client.requestJson({path:o,method:`POST`,body:a});if(!t.quiet){if(i===`text`){k(`deleted: ${n.fileId}`);return}A(s,i)}}}),Ol=w({description:`Create a FILE data collection`,auth:`apiKey`,usageArgs:`--name <text> --description <text> [flags]`,flags:{name:{type:`string`,valueHint:`<text>`,description:`Collection name`,required:!0},description:{type:`string`,valueHint:`<text>`,description:`Collection description (required by the server)`,required:!0},storeType:{type:`string`,valueHint:`<type>`,description:`Storage: platform (managed) or custom (your own OSS bucket)`},ossRegion:{type:`string`,valueHint:`<id>`,description:`OSS region id (required with --store-type custom)`},ossBucket:{type:`string`,valueHint:`<name>`,description:`OSS bucket name (required with --store-type custom)`},...U},notes:[`Store type defaults to platform (managed storage); custom uses your authorized OSS bucket.`,`Custom buckets must carry the bucket tag bailian-connector-access=ReadAndWrite (Bailian's tag-based access control); without it the server rejects creation with a misleading 'setBucketCORS failed' error.`,`There is no collection delete API — create collections deliberately.`],exampleArgs:[`--name my-collection --description 'team docs' --workspace-id ws-xxx`,`--name oss-coll --description 'own bucket' --store-type custom --oss-region cn-beijing --oss-bucket my-bucket`],validate(e){if(e.name.length<1||e.name.length>20)return`--name must be 1-20 characters`;let t=e.storeType??`platform`;if(t!==`platform`&&t!==`custom`)return`--store-type must be platform or custom`;if(t===`custom`&&(!e.ossRegion||!e.ossBucket))return`--store-type custom requires --oss-region and --oss-bucket`},async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a=(n.storeType??`platform`).toUpperCase(),o={connectorType:`FILE`,connectorName:n.name,description:n.description,fileConnectorConfig:{storeType:a,...a===`CUSTOM`?{regionId:n.ossRegion,bucketName:n.ossBucket}:{}}},s=E(r,f.addConnector);if(t.dryRun){A({endpoint:s,request:o},i);return}let c=await e.client.requestJson({path:s,method:`POST`,body:o}),l=c.data?.connectorId;if(t.quiet){k(l??``);return}if(i===`text`){k(`created: ${l??`-`} (${n.name}, ${a})`);return}A(c,i)}}),kl=w({description:`Show data collection details`,auth:`apiKey`,usageArgs:`(--collection-id <id> | --name <text>) [flags]`,flags:{collectionId:{type:`string`,valueHint:`<id>`,description:`Collection ID; alternative to --name`},name:{type:`string`,valueHint:`<text>`,description:`Collection name; alternative to --collection-id`},...U},exampleArgs:[`--collection-id conn-xxx --workspace-id ws-xxx`,`--name my-collection`],validate(e){if(!e.collectionId&&!e.name)return`Pass --collection-id or --name`;if(e.collectionId&&e.name)return`Use either --collection-id or --name, not both`},async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={...n.collectionId?{connectorId:n.collectionId}:{},...n.name?{connectorName:n.name}:{}},o=E(r,f.getConnector);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=s.data;if(t.quiet){k(c?.connectorId??``);return}if(i===`text`){k(`id: ${c?.connectorId??`-`}`),k(`name: ${c?.connectorName??`-`}`),k(`description: ${c?.description??`-`}`);return}A(s,i)}}),Al=w({description:`Batch import files from an authorized OSS bucket into the data center`,auth:`apiKey`,usageArgs:`--bucket <name> --region <id> --oss-key <key> [flags]`,flags:{bucket:{type:`string`,valueHint:`<name>`,description:`Authorized OSS bucket name`,required:!0},region:{type:`string`,valueHint:`<id>`,description:`OSS region id (e.g. cn-beijing)`,required:!0},ossKey:{type:`array`,valueHint:`<key>`,description:`OSS object key to import (repeatable, 1-10 per call)`,required:!0},categoryId:{type:`string`,valueHint:`<id>`,description:`Target data-center category (default: the default category)`},tag:{type:`array`,valueHint:`<text>`,description:`File tag applied to every imported file (repeatable, up to 10)`},overwrite:{type:`switch`,description:`Overwrite files previously imported from the same OSS keys`},...U},notes:[`The bucket must be authorized to the platform service role beforehand; permission errors from the server are passed through with a pointer to check AliyunServiceRoleForBailian in the RAM console.`,`File names are derived from the OSS key basename.`,`--overwrite replaces the previously imported file and issues a NEW fileId (the old one becomes invalid) — verified live.`],exampleArgs:[`--bucket my-bucket --region cn-beijing --oss-key docs/a.pdf --workspace-id ws-xxx`,`--bucket my-bucket --region cn-beijing --oss-key docs/a.pdf --oss-key docs/b.docx --overwrite`],validate(e){if(e.ossKey.length>10)return`--oss-key accepts at most 10 entries per call`;if(e.tag!==void 0&&e.tag.length>10)return`--tag accepts at most 10 entries`},async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={categoryId:n.categoryId??`default`,categoryType:`UNSTRUCTURED`,ossBucket:n.bucket,ossRegionId:n.region,fileDetails:n.ossKey.map(e=>({fileName:F(e),ossKey:e})),...n.tag?.length?{tags:n.tag}:{},...n.overwrite?{overWriteFileByOssKey:!0}:{}},o=E(r,f.addFilesFromAuthorizedOss);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=s.data?.addFileResultList??[],l=c.map(e=>e.fileId).filter(e=>!!e);if(t.quiet){for(let e of l)k(e);return}if(i===`text`){k(`imported: ${l.length} file(s)`);for(let e of c)k(` ${e.fileId??`-`} ${e.status??`-`} ${e.ossKey??``}`);return}A(s,i)}});function jl(e){if(!(e instanceof t))return!1;let n=e.message;return/^MCP request failed:\s*404\b/i.test(n)?/未开通|MCP不存在|MCP_IS_INVALID/i.test(n):!1}function Ml(e){let t=[`Activate (or re-activate) the ${e} MCP in the Bailian MCP marketplace, then retry.`];return e===`WebSearch`&&t.push(`If it was previously on SSE, cancel and activate again to upgrade to Streamable HTTP.`),t.push(`Open: ${kn(e)}`),t.join(`
|
|
2658
|
-
`)}function
|
|
2659
|
-
`)}`);A(s,c)}catch(e){throw r.url||
|
|
2660
|
-
`)}`);if(n.quiet||s.stop(`Done.`),i===`json`)A(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)?A({pages:t.pages,total:t.pages.length},i):A(t,i)}catch{A({text:e.text},i)}}catch(e){s.stop(`Failed.`)
|
|
2661
|
-
`),process.stdout.write(`See: ${
|
|
2662
|
-
`));else if(d.length===1){let e=o[0].output?.audio?.expires_at;A({saved:d[0],audio_url:
|
|
2663
|
-
Hint: Add --diarization flag to enable speaker separation.`,
|
|
2664
|
-
`)?u:`${u}\n`):k(JSON.stringify(l)),n.out&&(
|
|
2665
|
-
`),t.quiet||process.stderr.write(`Full result saved to: ${n.out}\n`))}async function
|
|
2735
|
+
`)}\n ... (${t.length} documents total)`;return`Delete ${t.length} document(s) from knowledge base ${e}:\n ${n}\nDocuments and all their chunks are permanently removed from the index. This cannot be undone.`}var Gc=w({description:{"en-US":`Delete documents and their chunks from a knowledge base`,"zh-CN":`从知识库中删除文档及其 Chunk`},auth:`apiKey`,usageArgs:`--index-id <id> --doc-id <id> [flags]`,flags:Uc,notes:[{"en-US":`Removes documents from the knowledge base index only; the source files remain in the data center.`,"zh-CN":`仅从知识库索引中移除文档;源文件仍保留在数据中心。`},{"en-US":"Use the doc_id from `knowledge doc list --quiet`, not the fileId from `knowledge doc upload`. For documents created via `knowledge create --doc-id`, the doc_id equals the fileId; for documents imported via `knowledge doc upload --index-id`, the doc_id may include a workspace suffix.","zh-CN":"请使用 `knowledge doc list --quiet` 返回的 doc_id,而不是 `knowledge doc upload` 返回的 fileId。通过 `knowledge create --doc-id` 创建的文档,其 doc_id 等于 fileId;通过 `knowledge doc upload --index-id` 导入的文档,其 doc_id 可能带有 Workspace 后缀。"},{"en-US":`Deletion may take up to ~30s to propagate — the document may still appear in the doc list briefly.`,"zh-CN":`删除结果最多可能需要约 30 秒才会生效——文档可能会短暂地继续出现在列表中。`},{"en-US":`The output lists the ids actually deleted.`,"zh-CN":`输出会列出实际删除的 ID。`}],exampleArgs:[`--index-id idx-xxx --doc-id file-xxx --workspace-id ws-xxx`,`--index-id idx-xxx --doc-id file-a --doc-id file-b --yes`],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={index_id:n.indexId,doc_ids:n.docId},o=E(r,p.indexDeleteFile);if(t.dryRun){A({endpoint:o,request:a},i);return}await yn(Wc(n.indexId,n.docId),n.yes??!1);let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=s.data?.deleted??[];if(t.quiet){for(let e of c)k(e);return}if(i===`text`){k(`deleted: ${c.length} document(s)`);for(let e of c)k(` ${e}`);c.length!==n.docId.length&&process.stderr.write(`Warning: requested ${n.docId.length} deletion(s) but the server reported ${c.length}.\n`);return}A(s,i)}}),Kc=w({description:{"en-US":`Batch update tags on data-center files`,"zh-CN":`批量更新数据中心文件标签`},auth:`apiKey`,usageArgs:`--doc-id <id> --tag <text> [flags]`,flags:{docId:{type:`array`,valueHint:`<id>`,description:{"en-US":`Data-center file ID to tag (repeatable, 1-20 per call)`,"zh-CN":`要添加标签的数据中心文件 ID(可重复,每次调用 1–20 个)`},required:!0},tag:{type:`array`,valueHint:`<text>`,description:{"en-US":`Tag applied to every --doc-id (repeatable, each up to 32 chars)`,"zh-CN":`应用于每个 --doc-id 的标签(可重复,每个最多 32 个字符)`},required:!0},mode:{type:`string`,valueHint:`<mode>`,description:{"en-US":`Update mode: append (default) or overwrite`,"zh-CN":`更新模式:append(默认)或 overwrite`}},...U},notes:[{"en-US":`The same tag set is applied to every --doc-id; run the command multiple times for different tag sets.`,"zh-CN":`同一组标签会应用于每个 --doc-id;若需应用不同标签组,请多次运行该命令。`},{"en-US":`Server limits: up to 100 tags per file, total tag length up to 700 chars, tag up to 32 chars.`,"zh-CN":`服务端限制:每个文件最多 100 个标签,标签总长度最多 700 个字符,单个标签最多 32 个字符。`}],exampleArgs:[`--doc-id file-xxx --tag project-a --tag draft --workspace-id ws-xxx`,`--doc-id file-a --doc-id file-b --tag final --mode overwrite`],validate(e){if(e.docId.length>20)return`--doc-id accepts at most 20 ids per call`;if(e.mode!==void 0&&e.mode!==`append`&&e.mode!==`overwrite`)return`--mode must be append or overwrite`;if(e.tag.length>100)return`At most 100 tags per file`;let t=e.tag.find(e=>e.length>32);if(t)return`Tag exceeds 32 characters: ${t}`;if(e.tag.reduce((e,t)=>e+t.length,0)>700)return`Total tag length exceeds 700 characters`},async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={fileInfos:n.docId.map(e=>({fileId:e,tags:n.tag})),updateMode:(n.mode??`append`).toUpperCase()},o=E(r,p.batchUpdateFileTag);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a});if(!t.quiet){if(i===`text`){k(`tagged: ${n.docId.length} file(s) with [${n.tag.join(`, `)}]`);return}A(s,i)}}});const qc={scene:{type:`string`,valueHint:`<scene>`,description:{"en-US":`Service scene: chat (Q&A) or search (retrieval). Required by the server`,"zh-CN":`服务场景:chat(问答)或 search(检索),服务端必填`},required:!0},status:{type:`string`,valueHint:`<status>`,description:{"en-US":`Filter by status: draft, deployed (includes edited) or deleted`,"zh-CN":`按状态筛选:draft、deployed(包含 edited)或 deleted`}},name:{type:`string`,valueHint:`<text>`,description:{"en-US":`Filter by service name (fuzzy match)`,"zh-CN":`按服务名称模糊筛选`}},agentId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Filter by exact agent ID`,"zh-CN":`按 Agent ID 精确筛选`}},indexId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Filter by exact linked knowledge base (pipeline) ID`,"zh-CN":`按关联的知识库(Pipeline)ID 精确筛选`}},...nc,...U},Jc=[`chat`,`search`],Yc=[`draft`,`deployed`,`deleted`];var Xc=w({description:{"en-US":`List retrieval / Q&A services (agents) in the workspace`,"zh-CN":`列出 Workspace 中的检索/问答服务(Agent)`},auth:`apiKey`,usageArgs:`--scene <chat|search> [flags]`,flags:qc,notes:[{"en-US":`A scene (chat or search) is required — run once per scene to see both.`,"zh-CN":`必须指定场景(chat 或 search)——要查看两类服务,请分别运行一次。`},{"en-US":`Use the returned agent_id with the search or chat commands, or with service management commands.`,"zh-CN":`将返回的 agent_id 用于 search/chat 命令或服务管理命令。`}],exampleArgs:[`--scene chat --workspace-id ws-xxx`,`--scene search --status deployed`],validate(e){if(!Jc.includes(e.scene))return`--scene must be chat or search`;if(e.status!==void 0&&!Yc.includes(e.status))return`--status must be draft, deployed or deleted`;if(e.pageSize!==void 0&&(e.pageSize<1||e.pageSize>100))return`--page-size must be between 1 and 100`},async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={agent_scene:n.scene,...n.status?{agent_status:n.status}:{},...n.name?{agent_name:n.name}:{},...n.agentId?{agent_id:n.agentId}:{},...n.indexId?{pipeline_id:n.indexId}:{},page_number:n.pageNumber??1,page_size:n.pageSize??10},o=E(r,p.agentList);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=s.data?.rows??[];if(t.quiet){for(let e of c)k(e.agent_id??``);return}if(i===`text`){if(c.length===0)k(`No services found.`);else for(let e of c){let t=(e.pipeline_list??[]).map(e=>e.pipeline_name).filter(Boolean).join(`,`);k(rc([e.agent_id,e.agent_status,e.agent_version,e.agent_name,t?`(kb: ${t})`:``].filter(Boolean).join(` `)))}k(`total: ${s.data?.total_count??c.length}`),k(n.scene===`search`?`Use an agent_id above with the knowledge search command.`:`Use an agent_id above with the knowledge chat command.`)}else A(s,i)}});const Zc={agentId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Service (agent) ID`,"zh-CN":`服务(Agent)ID`},required:!0},agentVersion:{type:`string`,valueHint:`<version>`,description:{"en-US":`Specific version to inspect (beta or a published number); omit for all versions`,"zh-CN":`要查看的指定版本(beta 或已发布版本号);省略则返回全部版本`}},...U};function Qc(e){k(`Version ${e.agent_version??`?`}:`),e.agent_version_desc&&k(` desc: ${e.agent_version_desc}`),e.publish_time!==void 0&&k(` published: ${e.publish_time}`);let t=e.agent_config;if(t){t.agent_policy&&k(` policy: ${t.agent_policy}`),t.agent_model&&k(` model: ${t.agent_model}`),t.temperature!==void 0&&k(` temperature: ${t.temperature}`);for(let e of t.kb_search_configs??[])k(` kb: ${typeof e.id==`string`?e.id:`?`}${typeof e.name==`string`?` (${e.name})`:``}`)}}var $c=w({description:{"en-US":`Show service (agent) details including per-version configuration`,"zh-CN":`查看服务(Agent)详情及各版本配置`},auth:`apiKey`,usageArgs:`--agent-id <id> [flags]`,flags:Zc,notes:[{"en-US":`Without --agent-version all versions are returned (beta draft plus published numbers).`,"zh-CN":`未传入 --agent-version 时,会返回所有版本(beta 草稿和已发布版本号)。`},{"en-US":`The version value is passed through as-is; the valid set is server-side state.`,"zh-CN":`版本值将原样传递;有效版本集合由服务端状态决定。`}],exampleArgs:[`--agent-id aid-xxx --workspace-id ws-xxx`,`--agent-id aid-xxx --agent-version beta`],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={agent_id:n.agentId,...n.agentVersion?{agent_version:n.agentVersion}:{}},o=E(r,p.agentGet);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=s.data;if(t.quiet){k(c?.agent_id??``);return}if(i!==`text`){A(s,i);return}k(`Basic:`),k(` id: ${c?.agent_id??`-`}`),k(` name: ${c?.agent_name??`-`}`),k(` desc: ${c?.agent_desc??`-`}`),k(` scene: ${c?.agent_scene??`-`}`),k(` status: ${c?.agent_status??`-`}`);for(let e of c?.agent_details??[])Qc(e)}}),el=w({description:{"en-US":`Create a retrieval / Q&A service (initial status: draft, version: beta)`,"zh-CN":`创建检索/问答服务(初始状态:draft,版本:beta)`},auth:`apiKey`,usageArgs:`--name <text> --scene <chat|search> [flags]`,flags:{name:{type:`string`,valueHint:`<text>`,description:{"en-US":`Service name (up to 200 chars, unique per scene in the workspace)`,"zh-CN":`服务名称(最多 200 个字符,在 Workspace 的同一场景中唯一)`},required:!0},scene:{type:`string`,valueHint:`<scene>`,description:{"en-US":`Service scene: chat (Q&A) or search (retrieval)`,"zh-CN":`服务场景:chat(问答)或 search(检索)`},required:!0},description:{type:`string`,valueHint:`<text>`,description:{"en-US":`Service description (up to 1000 chars)`,"zh-CN":`服务描述(最多 1000 个字符)`}},indexId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Bind this knowledge base; other settings use server defaults`,"zh-CN":`绑定该知识库;其他设置使用服务端默认值`}},...U},notes:[{"en-US":`Without an explicit configuration the server applies its default agent settings.`,"zh-CN":`未显式提供配置时,服务端会应用默认 Agent 设置。`},{"en-US":`The draft (beta) version can be tested via --agent-version beta on search/chat before deploying.`,"zh-CN":`部署前,可在 search/chat 命令中使用 --agent-version beta 测试草稿(beta)版本。`},{"en-US":`Requires the knowledge-base create permission in the workspace.`,"zh-CN":`需要 Workspace 中的知识库创建权限。`}],exampleArgs:[`--name my-qa --scene chat --workspace-id ws-xxx`,`--name my-search --scene search --index-id idx-xxx`],validate(e){if(e.name.length>200)return`--name must be at most 200 characters`;if(e.scene!==`chat`&&e.scene!==`search`)return`--scene must be chat or search`;if(e.description!==void 0&&e.description.length>1e3)return`--description must be at most 1000 characters`},async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={agent_name:n.name,agent_scene:n.scene,...n.description?{agent_desc:n.description}:{},...n.indexId?{agent_config:{kb_search_configs:[{id:n.indexId}]}}:{}},o=E(r,p.agentCreate);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=dc(s,`agent_id`);if(t.quiet){k(c??``);return}if(i===`text`){k(`created: ${c??`-`} (status: ${dc(s,`agent_status`)??`draft`}, version: ${dc(s,`agent_version`)??`beta`})`),k(`Test the draft with --agent-version beta on search/chat, then deploy it to publish.`);return}A(s,i)}});const tl=[`true`,`false`],nl={agentId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Service (agent) ID`,"zh-CN":`服务(Agent)ID`},required:!0},name:{type:`string`,valueHint:`<text>`,description:{"en-US":`New service name (up to 200 chars)`,"zh-CN":`新服务名称(最多 200 个字符)`}},description:{type:`string`,valueHint:`<text>`,description:{"en-US":`New service description (up to 1000 chars)`,"zh-CN":`新服务描述(最多 1000 个字符)`}},agentVersion:{type:`string`,valueHint:`<version>`,description:{"en-US":`Target version (default: beta draft). Published versions only accept --version-desc`,"zh-CN":`目标版本(默认:beta 草稿)。已发布版本只接受 --version-desc`}},versionDesc:{type:`string`,valueHint:`<text>`,description:{"en-US":`Version description`,"zh-CN":`版本描述`}},policy:{type:`string`,valueHint:`<policy>`,description:{"en-US":`Agent policy: turbo (fast) or agentic (multi-turn)`,"zh-CN":`Agent 策略:turbo(快速)或 agentic(多轮)`}},model:{type:`string`,valueHint:`<name>`,description:{"en-US":`Generation model code (must be in the platform allowlist)`,"zh-CN":`生成模型代码(必须在平台白名单中)`}},temperature:{type:`number`,valueHint:`<n>`,description:{"en-US":`Sampling temperature, range 0-2`,"zh-CN":`采样温度,范围 0–2`}},maxLlmCalls:{type:`number`,valueHint:`<n>`,description:{"en-US":`Max LLM calls per request, range 1-30`,"zh-CN":`每次请求最大 LLM 调用次数,范围 1–30`}},enableSessionFile:{type:`string`,valueHint:`<bool>`,description:{"en-US":`Enable session files: true or false`,"zh-CN":`启用会话文件:true 或 false`}},enableRefusal:{type:`string`,valueHint:`<bool>`,description:{"en-US":`Enable refusal answers: true or false`,"zh-CN":`启用拒答:true 或 false`}},enableAntiLeak:{type:`string`,valueHint:`<bool>`,description:{"en-US":`Enable anti prompt-leak: true or false`,"zh-CN":`启用防提示词泄露:true 或 false`}},enableRichText:{type:`string`,valueHint:`<bool>`,description:{"en-US":`Enable rich text output: true or false`,"zh-CN":`启用富文本输出:true 或 false`}},enableCitation:{type:`string`,valueHint:`<bool>`,description:{"en-US":`Enable citations: true or false`,"zh-CN":`启用引用:true 或 false`}},configFile:{type:`string`,valueHint:`<path>`,description:{"en-US":`JSON file replacing the whole agent_config (for nested settings like kb_search_configs); mutually exclusive with scalar config flags`,"zh-CN":`替换整个 agent_config 的 JSON 文件(用于 kb_search_configs 等嵌套设置);不能与标量配置选项同时使用`}},...U};function rl(e){let t={};return e.policy!==void 0&&(t.agent_policy=e.policy),e.model!==void 0&&(t.agent_model=e.model),e.temperature!==void 0&&(t.temperature=e.temperature),e.maxLlmCalls!==void 0&&(t.max_num_llm_calls=e.maxLlmCalls),e.enableSessionFile!==void 0&&(t.enable_session_file=e.enableSessionFile),e.enableRefusal!==void 0&&(t.enable_refusal=e.enableRefusal),e.enableAntiLeak!==void 0&&(t.enable_anti_leak=e.enableAntiLeak),e.enableRichText!==void 0&&(t.enable_rich_text=e.enableRichText),e.enableCitation!==void 0&&(t.enable_citation=e.enableCitation),t}function il(e){let n;try{n=ar(e,`utf-8`)}catch(n){let r=n.code??`unknown`;throw new t(`Cannot read config file: ${e}`,c.GENERAL,`File system error (${r}) — check the path and permissions.`)}let r;try{r=JSON.parse(n)}catch{throw new t(`--config-file must contain valid JSON.`,c.USAGE)}if(typeof r!=`object`||!r||Array.isArray(r))throw new t(`--config-file must contain a JSON object.`,c.USAGE);let i=r;return ol(i),i}const al=new Set([`agent_policy`,`agent_model`,`enable_session_file`,`enable_refusal`,`enable_anti_leak`,`enable_rich_text`,`enable_citation`,`temperature`,`max_num_llm_calls`,`max_completion_tokens`,`session_file_max_parse_length`,`enable_kb_router`,`kb_router_model`,`rerank_top_n`,`hybrid_rerank`,`kb_search_configs`]);function ol(e){if(e.agent_policy!==void 0&&![`turbo`,`agentic`].includes(e.agent_policy))throw new t(`agent_policy must be turbo or agentic`,c.USAGE);if(e.temperature!==void 0&&(e.temperature<0||e.temperature>2))throw new t(`temperature must be between 0 and 2`,c.USAGE);if(e.max_num_llm_calls!==void 0&&(e.max_num_llm_calls<1||e.max_num_llm_calls>30))throw new t(`max_num_llm_calls must be between 1 and 30`,c.USAGE);if(e.rerank_top_n!==void 0&&(e.rerank_top_n<1||e.rerank_top_n>20))throw new t(`rerank_top_n must be between 1 and 20`,c.USAGE);for(let t of e.kb_search_configs??[]){let e=t.rerank;e?.rerank_instruct&&e.rerank_mode!==`custom`&&process.stderr.write(`Warning: rerank_instruct is only effective with rerank_mode=custom; the server clears it otherwise.
|
|
2736
|
+
`)}for(let t of Object.keys(e))al.has(t)||process.stderr.write(`Warning: unknown agent_config field passed through: ${t}\n`)}async function sl(e,t,n){return((await e.requestJson({path:E(t,p.agentGet),method:`POST`,body:{agent_id:n,agent_version:`beta`}})).data?.agent_details??[]).find(e=>e.agent_version===`beta`)?.agent_config??{}}var cl=w({description:{"en-US":`Update service name, description or draft configuration`,"zh-CN":`更新服务名称、描述或草稿配置`},auth:`apiKey`,usageArgs:`--agent-id <id> [flags]`,flags:nl,notes:[{"en-US":`Configuration changes only apply to the beta draft; published versions accept --version-desc only.`,"zh-CN":`配置修改只应用于 beta 草稿;已发布版本只接受 --version-desc。`},{"en-US":`To change the configuration of a published version, first update the beta draft (this command without --agent-version or with --agent-version beta), then run service deploy to publish a new version.`,"zh-CN":`要修改已发布版本的配置,请先更新 beta 草稿(不传 --agent-version,或传 --agent-version beta),然后运行 service deploy 发布新版本。`},{"en-US":`Scalar config flags merge into the current draft config (read-merge-write); --config-file replaces the whole config and is mutually exclusive with them.`,"zh-CN":`标量配置选项会合并到当前草稿配置(读取-合并-写入);--config-file 会替换整个配置,且不能与标量配置选项同时使用。`},{"en-US":`After updating the draft, verify with --agent-version beta on search/chat, then deploy.`,"zh-CN":`更新草稿后,先在 search/chat 命令中使用 --agent-version beta 验证,再部署。`},{"en-US":`Requires the knowledge-base modify permission in the workspace.`,"zh-CN":`需要 Workspace 中的知识库修改权限。`}],exampleArgs:[`--agent-id aid-xxx --temperature 0.7 --workspace-id ws-xxx`,`--agent-id aid-xxx --config-file ./agent-config.json`,{"en-US":`--agent-id aid-xxx --agent-version 1 --version-desc 'first stable release'`,"zh-CN":`--agent-id aid-xxx --agent-version 1 --version-desc '首个稳定版本'`}],validate(e){let t=Object.keys(rl(e)).length>0;if(!(e.name!==void 0||e.description!==void 0||e.versionDesc!==void 0||e.configFile!==void 0||t))return`Nothing to update — pass a name/description/version-desc or config flags`;if(e.configFile!==void 0&&t)return`--config-file is mutually exclusive with scalar config flags`;if(e.agentVersion!==void 0&&e.agentVersion!==`beta`&&(t||e.configFile!==void 0))return`Published versions only accept --version-desc; update the beta draft to change config`;if(e.name!==void 0&&e.name.length>200)return`--name must be at most 200 characters`;if(e.description!==void 0&&e.description.length>1e3)return`--description must be at most 1000 characters`;if(e.policy!==void 0&&![`turbo`,`agentic`].includes(e.policy))return`--policy must be turbo or agentic`;if(e.temperature!==void 0&&(e.temperature<0||e.temperature>2))return`--temperature must be between 0 and 2`;if(e.maxLlmCalls!==void 0&&(e.maxLlmCalls<1||e.maxLlmCalls>30))return`--max-llm-calls must be between 1 and 30`;for(let[t,n]of[[`--enable-session-file`,e.enableSessionFile],[`--enable-refusal`,e.enableRefusal],[`--enable-anti-leak`,e.enableAntiLeak],[`--enable-rich-text`,e.enableRichText],[`--enable-citation`,e.enableCitation]])if(n!==void 0&&!tl.includes(n))return`${t} must be true or false`},async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a=rl(n),o=n.configFile!==void 0||Object.keys(a).length>0,s;n.configFile===void 0?Object.keys(a).length>0&&(t.dryRun?s={...a}:(s={...await sl(e.client,r,n.agentId),...a},ol(s))):s=il(n.configFile);let c={agent_id:n.agentId,...n.name===void 0?{}:{agent_name:n.name},...n.description===void 0?{}:{agent_desc:n.description},...n.agentVersion===void 0?{}:{agent_version:n.agentVersion},...n.versionDesc===void 0?{}:{agent_version_desc:n.versionDesc},...s===void 0?{}:{agent_config:s}},l=E(r,p.agentUpdate);if(t.dryRun){A({endpoint:l,request:c,...o&&n.configFile===void 0?{note:`scalar config flags are merged into the current beta config at run time`}:{}},i);return}let u=await e.client.requestJson({path:l,method:`POST`,body:c});if(!t.quiet){if(i===`text`){k(`updated: ${n.agentId}`),o&&k(`Draft config changed — verify with --agent-version beta, then deploy.`);return}A(u,i)}}});const ll={agentId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Service (agent) ID`,"zh-CN":`服务(Agent)ID`},required:!0},versionDesc:{type:`string`,valueHint:`<text>`,description:{"en-US":`Description for the newly published version`,"zh-CN":`新发布版本的描述`}},yes:{type:`switch`,description:{"en-US":`Skip the confirmation prompt`,"zh-CN":`跳过确认提示`}},...U};async function ul(e,t,n){let r=``,i=``;try{let a=await e.requestJson({path:E(t,p.agentGet),method:`POST`,body:{agent_id:n}}),o=a.data?.agent_name,s=a.data?.agent_status;o&&(r+=` name: ${o}`),s&&(r+=` status: ${s}`,s===`edited`&&(i=`
|
|
2737
|
+
WARNING: a published version is live — deploying replaces its behavior with the current draft.`))}catch{}return`Deploy service ${n}${r}${i}\nPublishing changes what live callers get from this service.`}var dl=w({description:{"en-US":`Publish the beta draft of a service as a new version`,"zh-CN":`将服务的 beta 草稿发布为新版本`},auth:`apiKey`,usageArgs:`--agent-id <id> [flags]`,flags:ll,notes:[{"en-US":`The version number auto-increments; status becomes deployed.`,"zh-CN":`版本号会自动递增;状态将变为 deployed。`},{"en-US":`Publishing affects live callers — the confirmation prompt guards against accidents.`,"zh-CN":`发布会影响线上调用方——确认提示用于避免误操作。`},{"en-US":`Requires the knowledge-base modify permission in the workspace.`,"zh-CN":`需要 Workspace 中的知识库修改权限。`}],exampleArgs:[`--agent-id aid-xxx --workspace-id ws-xxx`,{"en-US":`--agent-id aid-xxx --version-desc 'tuned rerank params' --yes`,"zh-CN":`--agent-id aid-xxx --version-desc '已调优 Rerank 参数' --yes`}],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={agent_id:n.agentId,...n.versionDesc?{agent_version_desc:n.versionDesc}:{}},o=E(r,p.agentDeploy);if(t.dryRun){A({endpoint:o,request:a},i);return}await yn(n.yes?``:await ul(e.client,r,n.agentId),n.yes??!1);let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=dc(s,`agent_version`);if(t.quiet){k(c??``);return}if(i===`text`){k(`deployed: ${n.agentId} version ${c??`-`}`);return}A(s,i)}});const fl={agentId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Service (agent) ID`,"zh-CN":`服务(Agent)ID`},required:!0},yes:{type:`switch`,description:{"en-US":`Skip the confirmation prompt`,"zh-CN":`跳过确认提示`}},...U};async function pl(e,t,n){let r=``,i=``;try{let a=await e.requestJson({path:E(t,p.agentGet),method:`POST`,body:{agent_id:n}}),o=a.data?.agent_name,s=a.data?.agent_status;o&&(r+=` name: ${o}`),s&&(r+=` status: ${s}`,(s===`deployed`||s===`edited`)&&(i=`
|
|
2738
|
+
WARNING: this service is LIVE — deleting it breaks existing callers.`))}catch{}return`Delete service ${n}${r}${i}\nDeletion cannot be undone; the agent_id can no longer be used for search or chat calls.`}var ml=w({description:{"en-US":`Delete a retrieval / Q&A service (soft delete, idempotent)`,"zh-CN":`删除检索/问答服务(软删除,幂等)`},auth:`apiKey`,usageArgs:`--agent-id <id> [flags]`,flags:fl,notes:[{"en-US":`Deletion cannot be undone; the agent_id becomes unusable for search and chat calls.`,"zh-CN":`删除无法撤销;该 agent_id 将不能再用于 search 和 chat 调用。`},{"en-US":`Idempotent — deleting an already-deleted service does not fail.`,"zh-CN":`该操作具有幂等性——重复删除已删除的服务不会失败。`},{"en-US":`Requires the knowledge-base delete permission in the workspace.`,"zh-CN":`需要 Workspace 中的知识库删除权限。`}],exampleArgs:[`--agent-id aid-xxx --workspace-id ws-xxx`,`--agent-id aid-xxx --yes`],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={agent_id:n.agentId},o=E(r,p.agentDelete);if(t.dryRun){A({endpoint:o,request:a},i);return}await yn(n.yes?``:await pl(e.client,r,n.agentId),n.yes??!1);let s=await e.client.requestJson({path:o,method:`POST`,body:a});if(!t.quiet){if(i===`text`){k(`deleted: ${n.agentId} (status: ${dc(s,`agent_status`)??`deleted`})`);return}A(s,i)}}}),hl=w({description:{"en-US":`Copy a service into a new draft (name gets a copy_ prefix)`,"zh-CN":`将服务复制为新草稿(名称会添加 copy_ 前缀)`},auth:`apiKey`,usageArgs:`--agent-id <id> [flags]`,flags:{agentId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Source service (agent) ID to copy`,"zh-CN":`要复制的源服务(Agent)ID`},required:!0},...U},notes:[{"en-US":`The copy starts as a beta draft; test it with --agent-version beta, then deploy to publish.`,"zh-CN":`副本初始为 beta 草稿;请使用 --agent-version beta 测试,然后部署发布。`},{"en-US":`Requires the knowledge-base create permission in the workspace.`,"zh-CN":`需要 Workspace 中的知识库创建权限。`}],exampleArgs:[`--agent-id aid-xxx --workspace-id ws-xxx`],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={agent_id:n.agentId},o=E(r,p.agentCopy);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=dc(s,`agent_id`);if(t.quiet){k(c??``);return}if(i===`text`){k(`new agent_id: ${c??`-`} (name: ${dc(s,`agent_name`)??`-`}, status: ${dc(s,`agent_status`)??`draft`})`),k(`Test the draft with --agent-version beta on search/chat, then deploy it to publish.`);return}A(s,i)}});const gl={indexId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Knowledge base ID`,"zh-CN":`知识库 ID`},required:!0},docId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Owning document ID from the doc list command; required in practice for all knowledge base types`,"zh-CN":`来自文档列表命令的所属文档 ID;实际使用时所有知识库类型都需要提供`}},content:{type:`string`,valueHint:`<text>`,description:{"en-US":`Chunk body text, up to 6000 chars (document-type); alternative to --content-file`,"zh-CN":`Chunk 正文,最多 6000 个字符(文档型);与 --content-file 二选一`}},contentFile:{type:`string`,valueHint:`<path>`,description:{"en-US":`Read chunk body from a UTF-8 plain text file (.md/.txt etc.)`,"zh-CN":`从 UTF-8 纯文本文件(.md/.txt 等)读取 Chunk 正文`}},title:{type:`string`,valueHint:`<text>`,description:{"en-US":`Chunk title, up to 50 chars (document-type)`,"zh-CN":`Chunk 标题,最多 50 个字符(文档型)`}},imageUrl:{type:`array`,valueHint:`<url>`,description:{"en-US":`Chunk image URL (repeatable, up to 10; document-type)`,"zh-CN":`Chunk 图片 URL(可重复,最多 10 个;文档型)`}},field:{type:`array`,valueHint:`<key=value>`,description:{"en-US":`Arbitrary field entry (repeatable) for table/image knowledge bases where keys are Excel column headers; mutually exclusive with content/title/image flags`,"zh-CN":`表格/图片知识库的自定义字段(可重复),键为 Excel 列标题;不能与 content/title/image 相关选项同时使用`}},...U};function _l(e){let n={};for(let r of e){let e=r.indexOf(`=`);if(e<=0)throw new t(`--field must be key=value, got: ${r}`,c.USAGE);n[r.slice(0,e)]=r.slice(e+1)}return n}var vl=w({description:{"en-US":`Add a chunk directly to a knowledge base`,"zh-CN":`直接向知识库添加 Chunk`},auth:`apiKey`,usageArgs:`--index-id <id> (--content <text> | --field <k=v>) [flags]`,flags:gl,notes:[{"en-US":`Document / table / image knowledge bases are supported; audio-video ones are not.`,"zh-CN":`支持文档、表格和图片知识库;不支持音视频知识库。`},{"en-US":`--doc-id is required in practice for all knowledge base types. Use the document-level id from the doc list command; the per-row doc_id in chunk list output is not accepted.`,"zh-CN":`实际使用时,所有知识库类型都需要 --doc-id。请使用文档列表命令返回的文档级 ID;Chunk 列表每行返回的 doc_id 不被接受。`},{"en-US":`Image-type documents do not support text chunks. Target a text-type document (docx/pdf/txt) instead.`,"zh-CN":`图片型文档不支持文本 Chunk;请改为操作文本型文档(docx/pdf/txt)。`},{"en-US":`The API is idempotent but rate-limited to 10 calls per second — throttle batch scripts.`,"zh-CN":`该 API 具有幂等性,但限流为每秒 10 次调用——批处理脚本需要控制速率。`},{"en-US":`The response carries no chunk id; list chunks afterwards to find the new one.`,"zh-CN":`响应不包含 Chunk ID;添加后请列出 Chunk 以查找新条目。`},{"en-US":`For table/image knowledge bases use --field with Excel column headers as keys; values are passed through as strings.`,"zh-CN":`表格/图片知识库请使用 --field,并以 Excel 列标题作为键;值将按字符串原样传递。`}],exampleArgs:[{"en-US":`--index-id idx-xxx --content "chunk text" --title intro --workspace-id ws-xxx`,"zh-CN":`--index-id idx-xxx --content "Chunk 文本" --title 简介 --workspace-id ws-xxx`},{"en-US":`--index-id idx-xxx --field columnA=v1 --field columnB=v2`,"zh-CN":`--index-id idx-xxx --field 列A=v1 --field 列B=v2`}],validate(e){let t=e.content!==void 0||e.contentFile!==void 0||e.title!==void 0||!!e.imageUrl?.length,n=!!e.field?.length;if(t&&n)return`--field is mutually exclusive with --content/--content-file/--title/--image-url`;if(!t&&!n)return`Provide chunk content via --content/--content-file or --field entries`;if(e.content!==void 0&&e.contentFile!==void 0)return`Use either --content or --content-file, not both`;if(e.content!==void 0&&e.content.length>6e3)return`--content must be at most 6000 characters`;if(e.title!==void 0&&e.title.length>50)return`--title must be at most 50 characters`;if(e.imageUrl!==void 0&&e.imageUrl.length>10)return`--image-url accepts at most 10 entries`},async run(e){let{settings:n,flags:r}=e,i=W(e),a=T(n.output),o;if(r.field?.length)o=_l(r.field);else{let e=r.contentFile===void 0?r.content:Pc(r.contentFile,`--content`);if(typeof e==`string`&&e.length>6e3)throw new t(`Chunk content must be at most 6000 characters`,c.USAGE);o={...e===void 0?{}:{content:e},...r.title===void 0?{}:{title:r.title},...r.imageUrl?.length?{image_urls:r.imageUrl}:{}}}let s={pipelineId:r.indexId,...r.docId?{dataId:r.docId}:{},field:o},l=E(i,p.chunkCreate);if(n.dryRun){A({endpoint:l,request:s},a);return}let u=await e.client.requestJson({path:l,method:`POST`,body:s});if(!n.quiet){if(a===`text`){k(`chunk created (pipeline: ${r.indexId})`),k(`List chunks to find the new chunk id.`);return}A(u,a)}}}),yl=w({description:{"en-US":`List chunks in a knowledge base with content and status`,"zh-CN":`列出知识库中的 Chunk 及其内容和状态`},auth:`apiKey`,usageArgs:`--index-id <id> [flags]`,flags:{indexId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Knowledge base ID`,"zh-CN":`知识库 ID`},required:!0},docId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Only show chunks belonging to this document`,"zh-CN":`仅显示属于该文档的 Chunk`}},...nc,...U},notes:[{"en-US":`Use metadata._id as the chunk id and metadata.doc_id as the document id in chunk update/delete commands.`,"zh-CN":`在 Chunk 更新/删除命令中,使用 metadata._id 作为 Chunk ID,使用 metadata.doc_id 作为文档 ID。`},{"en-US":`Page size defaults to 20 (server default), max 100.`,"zh-CN":`分页大小默认为 20(服务端默认值),最大为 100。`}],exampleArgs:[`--index-id idx-xxx --workspace-id ws-xxx`,`--index-id idx-xxx --doc-id file-xxx --page-size 50`],validate(e){if(e.pageSize!==void 0&&(e.pageSize<1||e.pageSize>100))return`--page-size must be between 1 and 100`},async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={indexId:n.indexId,pageNum:n.pageNumber??1,pageSize:n.pageSize??20,...n.docId?{docId:n.docId}:{}},o=E(r,p.chunkList);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=s.data?.nodes??[];if(t.quiet){for(let e of c)k(e.metadata?._id??``);return}if(i===`text`){if(c.length===0)k(`No chunks found.`);else for(let e of c){let t=e.metadata??{},n=t._chunk_status_message?` status: ${t._chunk_status_message}`:``,r=t.is_displayed_chunk_content===!1?` [excluded from retrieval]`:``;k(`[chunk] ${t._id??`?`} (doc: ${t.doc_name??`?`}, doc_id: ${t.doc_id??`?`})${n}${r}`);let i=t.content??e.text??``;k(` ${i.length>200?`${i.slice(0,200)}…`:i}`)}k(`total: ${s.data?.total??c.length}`)}else A(s,i)}});const bl={indexId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Knowledge base ID`,"zh-CN":`知识库 ID`},required:!0},chunkId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Chunk ID (metadata._id from the chunk list output)`,"zh-CN":`Chunk ID(来自 Chunk 列表输出的 metadata._id)`},required:!0},docId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Document ID owning the chunk (metadata.doc_id from the chunk list output)`,"zh-CN":`Chunk 所属文档 ID(来自 Chunk 列表输出的 metadata.doc_id)`},required:!0},content:{type:`string`,valueHint:`<text>`,description:{"en-US":`New chunk content, 10-6000 chars; alternative to --content-file`,"zh-CN":`新的 Chunk 内容,10–6000 个字符;与 --content-file 二选一`}},contentFile:{type:`string`,valueHint:`<path>`,description:{"en-US":`Read new content from a UTF-8 plain text file (.md/.txt etc.)`,"zh-CN":`从 UTF-8 纯文本文件(.md/.txt 等)读取新内容`}},title:{type:`string`,valueHint:`<text>`,description:{"en-US":`Chunk title, 0-50 chars (empty string clears it; omit to keep unchanged)`,"zh-CN":`Chunk 标题,0–50 个字符(空字符串表示清除;省略则保持不变)`}},exclude:{type:`switch`,description:{"en-US":`Exclude this chunk from retrieval`,"zh-CN":`在检索中排除该 Chunk`}},include:{type:`switch`,description:{"en-US":`Include this chunk in retrieval (default)`,"zh-CN":`在检索中包含该 Chunk(默认)`}},...U};async function xl(e,n,r,i,a){for(let t=1;t<=10;t++){let o=(await e.requestJson({path:E(n,p.chunkList),method:`POST`,body:{indexId:r,docId:a,pageNum:t,pageSize:100}})).data?.nodes??[],s=o.find(e=>e.metadata?._id===i),c=s?.metadata?.content??s?.text;if(typeof c==`string`)return c;if(o.length<100)break}throw new t(`Chunk not found: ${i}`,c.GENERAL,`Check the chunk id via the chunk list command.`)}var Sl=w({description:{"en-US":`Update chunk content or toggle its retrieval visibility`,"zh-CN":`更新 Chunk 内容或切换其检索可见性`},auth:`apiKey`,usageArgs:`--index-id <id> --chunk-id <id> --doc-id <id> [flags]`,flags:bl,notes:[{"en-US":`Content must be 10-6000 characters and within the knowledge base's max chunk size.`,"zh-CN":`内容必须为 10–6000 个字符,且不能超过知识库的最大 Chunk 大小。`},{"en-US":`--content-file expects a UTF-8 plain text file; document formats (.docx/.pdf) are not parsed here.`,"zh-CN":`--content-file 需要 UTF-8 纯文本文件;此处不会解析 .docx/.pdf 等文档格式。`},{"en-US":`Toggling --exclude/--include without new content re-submits the existing content automatically.`,"zh-CN":`仅切换 --exclude/--include 而不提供新内容时,会自动重新提交现有内容。`}],exampleArgs:[{"en-US":`--index-id idx-xxx --chunk-id chunk-xxx --doc-id file-xxx --content "corrected text"`,"zh-CN":`--index-id idx-xxx --chunk-id chunk-xxx --doc-id file-xxx --content "修正后的文本"`},`--index-id idx-xxx --chunk-id chunk-xxx --doc-id file-xxx --exclude`],validate(e){if(e.content!==void 0&&e.contentFile!==void 0)return`Use either --content or --content-file, not both`;if(e.exclude&&e.include)return`--exclude and --include are mutually exclusive`;if(!(e.content!==void 0||e.contentFile!==void 0)&&!e.exclude&&!e.include&&e.title===void 0)return`Nothing to update — pass --content/--content-file, --title, --exclude or --include`;if(e.content!==void 0&&(e.content.length<10||e.content.length>6e3))return`--content must be 10-6000 characters`;if(e.title!==void 0&&e.title.length>50)return`--title must be at most 50 characters`},async run(e){let{settings:n,flags:r}=e,i=W(e),a=T(n.output),o=r.contentFile===void 0?r.content:Pc(r.contentFile,`--content`);if(o!==void 0&&(o.length<10||o.length>6e3))throw new t(`Chunk content must be 10-6000 characters`,c.USAGE);o===void 0&&(o=n.dryRun?`<current-content (fetched at run time)>`:await xl(e.client,i,r.indexId,r.chunkId,r.docId));let s={pipelineId:r.indexId,chunkId:r.chunkId,dataId:r.docId,content:o,isDisplayedChunkContent:!r.exclude,...r.title===void 0?{}:{title:r.title}},l=E(i,p.chunkUpdate);if(n.dryRun){A({endpoint:l,request:s},a);return}let u=await e.client.requestJson({path:l,method:`POST`,body:s});if(!n.quiet){if(a===`text`){k(`updated: ${r.chunkId}`);return}A(u,a)}}});const Cl={indexId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Knowledge base ID`,"zh-CN":`知识库 ID`},required:!0},chunkId:{type:`array`,valueHint:`<id>`,description:{"en-US":`Chunk ID to delete (repeatable; batches of 10 are sent automatically)`,"zh-CN":`要删除的 Chunk ID(可重复;每 10 个自动分批发送)`},required:!0},yes:{type:`switch`,description:{"en-US":`Skip the confirmation prompt`,"zh-CN":`跳过确认提示`}},...U};function wl(e,t=10){let n=[];for(let r=0;r<e.length;r+=t)n.push(e.slice(r,r+t));return n}var Tl=w({description:{"en-US":`Delete chunks from a knowledge base (irreversible)`,"zh-CN":`从知识库中删除 Chunk(不可撤销)`},auth:`apiKey`,usageArgs:`--index-id <id> --chunk-id <id> [flags]`,flags:Cl,notes:[{"en-US":`Accepts at most 10 chunk ids per call; larger sets are batched automatically.`,"zh-CN":`每次调用最多接受 10 个 Chunk ID;更多 ID 会自动分批处理。`}],exampleArgs:[`--index-id idx-xxx --chunk-id chunk-a --chunk-id chunk-b --workspace-id ws-xxx`,`--index-id idx-xxx --chunk-id chunk-a --yes`],async run(e){let{settings:n,flags:r}=e,i=W(e),a=T(n.output),o=wl(r.chunkId),s=E(i,p.chunkDelete);if(n.dryRun){A({endpoint:s,batches:o.map(e=>({request:{pipelineId:r.indexId,chunkIds:e}}))},a);return}await yn(`Delete ${r.chunkId.length} chunk(s) from knowledge base ${r.indexId} in ${o.length} batch(es).\nChunks are permanently removed. This cannot be undone.`,r.yes??!1);let c=0;for(let n of o)try{await e.client.requestJson({path:s,method:`POST`,body:{pipelineId:r.indexId,chunkIds:n}}),c+=n.length}catch(e){throw c>0&&e instanceof t&&!e.hint?new t(e.message,e.exitCode,`${c} chunk(s) in earlier batches were already deleted.`,{cause:e,api:e.api,rawResponse:e.rawResponse}):e}if(!n.quiet){if(a===`text`){k(`deleted: ${c} chunk(s) in ${o.length} batch(es)`);return}A({deleted_count:c,batches:o.length},a)}}});const El={indexId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Knowledge base ID`,"zh-CN":`知识库 ID`},required:!0},start:{type:`string`,valueHint:`<time>`,description:{"en-US":`Range start: Unix seconds or ISO date, must be in the past (default: 24 hours ago)`,"zh-CN":`范围开始时间:Unix 秒或 ISO 日期,必须是过去时间(默认:24 小时前)`}},end:{type:`string`,valueHint:`<time>`,description:{"en-US":`Range end: Unix seconds or ISO date, must be in the past (default: now)`,"zh-CN":`范围结束时间:Unix 秒或 ISO 日期,必须是过去时间(默认:当前时间)`}},...U};function Dl(e){if(/^\d+$/.test(e))return e.length>=13?String(Math.floor(Number(e)/1e3)):e;let n=/^\d{4}-\d{2}-\d{2}([T ].*)?$/.test(e)?Date.parse(e):NaN;if(Number.isNaN(n))throw new t(`Invalid time value: ${e}`,c.USAGE,`Pass Unix seconds (e.g. 1780900000) or an ISO date (e.g. 2026-07-30T00:00:00Z).`);return String(Math.floor(n/1e3))}var Ol=w({description:{"en-US":`Show knowledge base storage and QPS monitoring data`,"zh-CN":`查看知识库存储和 QPS 监控数据`},auth:`apiKey`,usageArgs:`--index-id <id> [flags]`,flags:El,notes:[{"en-US":`Defaults to the last 24 hours when --start/--end are omitted.`,"zh-CN":`省略 --start/--end 时,默认查询最近 24 小时。`},{"en-US":`Timestamps are normalized to epoch seconds as required by the server.`,"zh-CN":`时间戳会按服务端要求归一化为 Epoch 秒。`},{"en-US":`Future timestamps are rejected for --start and clamped to now for --end, since the monitor API only returns past data.`,"zh-CN":`监控 API 只返回历史数据,因此未来的 --start 会被拒绝,未来的 --end 会被截断为当前时间。`}],exampleArgs:[`--index-id idx-xxx --workspace-id ws-xxx`,`--index-id idx-xxx --start 2026-07-30 --end 2026-07-31`],async run(e){let{settings:n,flags:r}=e,i=W(e),a=T(n.output),o=Math.floor(Date.now()/1e3),s=r.start?Dl(r.start):String(o-24*3600),l=r.end?Dl(r.end):String(o);if(Number(s)>o)throw new t(`Start time is in the future; the monitor API only accepts past or current timestamps.`,c.USAGE,`Use a start date/time at or before now, or omit --start to default to 24 hours ago.`);let u=Number(l)>o;u&&(l=String(o));let d={indexId:r.indexId,startTimestamp:s,endTimestamp:l},f=E(i,p.indexMonitor);if(n.dryRun){A({endpoint:f,request:d},a);return}let m=await e.client.requestJson({path:f,method:`POST`,body:d});if(a!==`text`){A(m,a);return}u&&k(`note: end time was in the future, clamped to now.`);let h=m.data?.storageMonitorData,g=m.data?.qpsMonitorData;k(`plan: ${m.data?.pipelineCommercialType??`-`}`),k(`storage: ${h?.indexStorageUsage??`-`} / ${h?.indexStorageLimit??`-`}`),k(`peak qps: ${g?.peakQps??`-`}`),k(`qps windows: ${g?.monitorData?.length??0} data point(s)`)}}),kl=w({description:{"en-US":`List data-center categories`,"zh-CN":`列出数据中心类目`},auth:`apiKey`,usageArgs:`[flags]`,flags:{collectionId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Filter by exact collection ID`,"zh-CN":`按数据集合 ID 精确筛选`}},parentId:{type:`string`,valueHint:`<id>`,description:{"en-US":`List sub-categories of this exact parent category`,"zh-CN":`列出该父类目下的子类目`}},name:{type:`string`,valueHint:`<text>`,description:{"en-US":`Filter by category name (exact match, unlike the knowledge base list)`,"zh-CN":`按类目名称筛选(精确匹配,与知识库列表不同)`}},nextToken:{type:`string`,valueHint:`<token>`,description:{"en-US":`Cursor for the next page (from previous output)`,"zh-CN":`下一页游标(来自上一次输出)`}},maxResult:{type:`number`,valueHint:`<n>`,description:{"en-US":`Items per page (default: 20)`,"zh-CN":`每页条目数(默认:20)`}},...U},notes:[{"en-US":`Categories marked [default] are where files land when no category is specified.`,"zh-CN":`未指定类目时,文件会进入标记为 [default] 的类目。`},{"en-US":`Pagination is cursor-based: reuse the printed next token to continue.`,"zh-CN":`分页使用游标:复用输出中的 next token 继续查询。`}],exampleArgs:[`--workspace-id ws-xxx`,`--name my-category`,`--next-token <token>`],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={type:`UNSTRUCTURED`,...n.collectionId?{connectorId:n.collectionId}:{},...n.parentId?{parentId:n.parentId}:{},...n.name?{categoryName:n.name}:{},...n.nextToken?{nextToken:n.nextToken}:{},...n.maxResult===void 0?{}:{maxResult:n.maxResult}},o=E(r,p.listCategory);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=s.data?.categoryList??[];if(t.quiet){for(let e of c)k(e.categoryId??``);return}if(i===`text`){if(c.length===0)k(`No categories found.`);else for(let e of c){let t=e.isDefault?` [default]`:``;k(rc(`${e.categoryId} ${e.categoryName}${t}`))}let e=s.data?.nextToken;e&&k(`next: --next-token ${e}`)}else A(s,i)}}),Al=w({description:{"en-US":`Create a data-center category`,"zh-CN":`创建数据中心类目`},auth:`apiKey`,usageArgs:`--name <text> [flags]`,flags:{name:{type:`string`,valueHint:`<text>`,description:{"en-US":`Category name (1-20 chars)`,"zh-CN":`类目名称(1–20 个字符)`},required:!0},parentId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Create as a sub-category of this category`,"zh-CN":`创建为该类目的子类目`}},collectionId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Create under this collection (defaults to the platform collection)`,"zh-CN":`在该数据集合下创建(默认为平台数据集合)`}},...U},notes:[{"en-US":`Use categories to organize data-center files by business domain.`,"zh-CN":`使用类目按业务领域组织数据中心文件。`}],exampleArgs:[`--name product-docs --workspace-id ws-xxx`,`--name sub --parent-id cate-xxx`],validate(e){if(e.name.length<1||e.name.length>20)return`--name must be 1-20 characters`},async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={categoryName:n.name,categoryType:`UNSTRUCTURED`,...n.parentId?{parentCategoryId:n.parentId}:{},...n.collectionId?{connectorId:n.collectionId}:{}},o=E(r,p.addCategory);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=s.data?.categoryId;if(t.quiet){k(c??``);return}if(i===`text`){k(`created: ${c??`-`} (${n.name})`);return}A(s,i)}}),jl=w({description:{"en-US":`Delete a data-center category`,"zh-CN":`删除数据中心类目`},auth:`apiKey`,usageArgs:`--category-id <id> [flags]`,flags:{categoryId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Category ID to delete`,"zh-CN":`要删除的类目 ID`},required:!0},yes:{type:`switch`,description:{"en-US":`Skip the confirmation prompt`,"zh-CN":`跳过确认提示`}},...U},notes:[{"en-US":`Behavior for categories containing files or sub-categories is server-defined — the server error is passed through as-is.`,"zh-CN":`包含文件或子类目时的处理行为由服务端定义——服务端返回的错误将原样透传。`}],exampleArgs:[`--category-id cate-xxx --workspace-id ws-xxx`,`--category-id cate-xxx --yes`],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={categoryId:n.categoryId},o=E(r,p.deleteCategory);if(t.dryRun){A({endpoint:o,request:a},i);return}await yn(`Delete category ${n.categoryId}\nThis cannot be undone.`,n.yes??!1);let s=await e.client.requestJson({path:o,method:`POST`,body:a});if(!t.quiet){if(i===`text`){k(`deleted: ${n.categoryId}`);return}A(s,i)}}}),Ml=w({description:{"en-US":`List files in a data-center category`,"zh-CN":`列出数据中心类目中的文件`},auth:`apiKey`,usageArgs:`--category-id <id> [flags]`,flags:{categoryId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Category to list (find ids via the category list command); exact match`,"zh-CN":`要列出文件的类目(通过类目列表命令查找 ID);精确匹配`},required:!0},name:{type:`string`,valueHint:`<text>`,description:{"en-US":`Filter by exact file name without its extension (a.md → pass a)`,"zh-CN":`按不含扩展名的文件名精确筛选(a.md 应传入 a)`}},fileId:{type:`array`,valueHint:`<id>`,description:{"en-US":`Filter by exact file ID (repeatable)`,"zh-CN":`按文件 ID 精确筛选(可重复)`}},nextToken:{type:`string`,valueHint:`<token>`,description:{"en-US":`Cursor for the next page (from previous output)`,"zh-CN":`下一页游标(来自上一次输出)`}},maxResult:{type:`number`,valueHint:`<n>`,description:{"en-US":`Items per page`,"zh-CN":`每页条目数`}},...U},notes:[{"en-US":`A real category id is required — the default value is not resolved here. Find the id via the category list command.`,"zh-CN":`必须提供真实的类目 ID——此处不会解析 default 值。请通过类目列表命令查找 ID。`},{"en-US":`--name matches the exact file name without its extension (for a.md pass a); partial keywords return no results.`,"zh-CN":`--name 精确匹配不含扩展名的文件名(a.md 应传入 a);部分关键字不会返回结果。`},{"en-US":`Pagination is cursor-based: reuse the printed next token to continue.`,"zh-CN":`分页使用游标:复用输出中的 next token 继续查询。`}],exampleArgs:[`--category-id cate-xxx --workspace-id ws-xxx`,{"en-US":`--category-id cate-xxx --name report`,"zh-CN":`--category-id cate-xxx --name 报告`}],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={categoryId:n.categoryId,...n.name?{fileName:n.name}:{},...n.fileId?.length?{fileIds:n.fileId}:{},...n.nextToken?{nextToken:n.nextToken}:{},...n.maxResult===void 0?{}:{maxResult:n.maxResult}},o=E(r,p.listFile);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=s.data?.fileList??[];if(t.quiet){for(let e of c)k(e.fileId??``);return}if(i===`text`){if(c.length===0)k(`No files found.`);else for(let e of c)k(rc([e.fileId,e.status??`-`,e.fileName,e.sizeBytes??`-`].join(` `)));let e=s.data?.nextToken;e&&k(`next: --next-token ${e}`)}else A(s,i)}}),Nl=w({description:{"en-US":`Show data-center file details (size, MD5, tags, timestamps)`,"zh-CN":`查看数据中心文件详情(大小、MD5、标签、时间戳)`},auth:`apiKey`,usageArgs:`--file-id <id> [flags]`,flags:{fileId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Data-center file ID`,"zh-CN":`数据中心文件 ID`},required:!0},...U},exampleArgs:[`--file-id file-xxx --workspace-id ws-xxx`],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={fileId:n.fileId},o=E(r,p.describeFile);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=s.data;if(t.quiet){k(c?.fileId??``);return}if(i!==`text`){A(s,i);return}k(`id: ${c?.fileId??`-`}`),k(`name: ${c?.fileName??`-`}`),k(`type: ${c?.fileType??`-`}`),k(`size: ${c?.sizeBytes??`-`}`),k(`status: ${c?.status??`-`}`),k(`parser: ${c?.parser??`-`}`),k(`category: ${c?.category??`-`}`),k(`uploaded: ${c?.uploadTime??`-`}`),k(`tags: ${(Array.isArray(c?.tags)?c.tags.join(`, `):c?.tags??`-`)||`-`}`)}});const Pl={fileId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Data-center file ID to delete`,"zh-CN":`要删除的数据中心文件 ID`},required:!0},yes:{type:`switch`,description:{"en-US":`Skip the confirmation prompt`,"zh-CN":`跳过确认提示`}},...U};async function Fl(e,t,n){let r=``;try{let i=await e.requestJson({path:E(t,p.describeFile),method:`POST`,body:{fileId:n}});i.data?.fileName&&(r=` name: ${i.data.fileName}`)}catch{}return`Delete data-center file ${n}${r}\nPERMANENT: if the file is referenced by knowledge bases, their document indexes break too. This differs from removing a document from one knowledge base.`}var Il=w({description:{"en-US":`Permanently delete a file from the data center`,"zh-CN":`从数据中心永久删除文件`},auth:`apiKey`,usageArgs:`--file-id <id> [flags]`,flags:Pl,notes:[{"en-US":`Irreversible. If knowledge bases reference this file, their related document indexes become invalid.`,"zh-CN":`该操作不可撤销。如果知识库引用了此文件,其相关文档索引将失效。`},{"en-US":`To remove a document from a single knowledge base only, use the document delete command instead.`,"zh-CN":`如果只需从单个知识库中移除文档,请改用文档删除命令。`}],exampleArgs:[`--file-id file-xxx --workspace-id ws-xxx`,`--file-id file-xxx --yes`],async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={fileId:n.fileId},o=E(r,p.deleteFile);if(t.dryRun){A({endpoint:o,request:a},i);return}await yn(n.yes?``:await Fl(e.client,r,n.fileId),n.yes??!1);let s=await e.client.requestJson({path:o,method:`POST`,body:a});if(!t.quiet){if(i===`text`){k(`deleted: ${n.fileId}`);return}A(s,i)}}}),Ll=w({description:{"en-US":`Create a FILE data collection`,"zh-CN":`创建 FILE 数据集合`},auth:`apiKey`,usageArgs:`--name <text> --description <text> [flags]`,flags:{name:{type:`string`,valueHint:`<text>`,description:{"en-US":`Collection name`,"zh-CN":`数据集合名称`},required:!0},description:{type:`string`,valueHint:`<text>`,description:{"en-US":`Collection description (required by the server)`,"zh-CN":`数据集合描述(服务端必填)`},required:!0},storeType:{type:`string`,valueHint:`<type>`,description:{"en-US":`Storage: platform (managed) or custom (your own OSS bucket)`,"zh-CN":`存储类型:platform(托管)或 custom(自有 OSS Bucket)`}},ossRegion:{type:`string`,valueHint:`<id>`,description:{"en-US":`OSS region id (required with --store-type custom)`,"zh-CN":`OSS Region ID(使用 --store-type custom 时必填)`}},ossBucket:{type:`string`,valueHint:`<name>`,description:{"en-US":`OSS bucket name (required with --store-type custom)`,"zh-CN":`OSS Bucket 名称(使用 --store-type custom 时必填)`}},...U},notes:[{"en-US":`Store type defaults to platform (managed storage); custom uses your authorized OSS bucket.`,"zh-CN":`存储类型默认为 platform(托管存储);custom 使用已授权的自有 OSS Bucket。`},{"en-US":`Custom buckets must carry the bucket tag bailian-connector-access=ReadAndWrite (Bailian's tag-based access control); without it the server rejects creation with a misleading 'setBucketCORS failed' error.`,"zh-CN":`自定义 Bucket 必须带有 bailian-connector-access=ReadAndWrite 标签(百炼基于标签的访问控制);缺少该标签时,服务端会以容易误解的 'setBucketCORS failed' 错误拒绝创建。`},{"en-US":`There is no collection delete API — create collections deliberately.`,"zh-CN":`目前没有删除数据集合的 API——请谨慎创建。`}],exampleArgs:[{"en-US":`--name my-collection --description 'team docs' --workspace-id ws-xxx`,"zh-CN":`--name my-collection --description '团队文档' --workspace-id ws-xxx`},{"en-US":`--name oss-coll --description 'own bucket' --store-type custom --oss-region cn-beijing --oss-bucket my-bucket`,"zh-CN":`--name oss-coll --description '自有 Bucket' --store-type custom --oss-region cn-beijing --oss-bucket my-bucket`}],validate(e){if(e.name.length<1||e.name.length>20)return`--name must be 1-20 characters`;let t=e.storeType??`platform`;if(t!==`platform`&&t!==`custom`)return`--store-type must be platform or custom`;if(t===`custom`&&(!e.ossRegion||!e.ossBucket))return`--store-type custom requires --oss-region and --oss-bucket`},async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a=(n.storeType??`platform`).toUpperCase(),o={connectorType:`FILE`,connectorName:n.name,description:n.description,fileConnectorConfig:{storeType:a,...a===`CUSTOM`?{regionId:n.ossRegion,bucketName:n.ossBucket}:{}}},s=E(r,p.addConnector);if(t.dryRun){A({endpoint:s,request:o},i);return}let c=await e.client.requestJson({path:s,method:`POST`,body:o}),l=c.data?.connectorId;if(t.quiet){k(l??``);return}if(i===`text`){k(`created: ${l??`-`} (${n.name}, ${a})`);return}A(c,i)}}),Rl=w({description:{"en-US":`Show data collection details`,"zh-CN":`查看数据集合详情`},auth:`apiKey`,usageArgs:`(--collection-id <id> | --name <text>) [flags]`,flags:{collectionId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Collection ID; alternative to --name`,"zh-CN":`数据集合 ID;与 --name 二选一`}},name:{type:`string`,valueHint:`<text>`,description:{"en-US":`Collection name; alternative to --collection-id`,"zh-CN":`数据集合名称;与 --collection-id 二选一`}},...U},exampleArgs:[`--collection-id conn-xxx --workspace-id ws-xxx`,`--name my-collection`],validate(e){if(!e.collectionId&&!e.name)return`Pass --collection-id or --name`;if(e.collectionId&&e.name)return`Use either --collection-id or --name, not both`},async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={...n.collectionId?{connectorId:n.collectionId}:{},...n.name?{connectorName:n.name}:{}},o=E(r,p.getConnector);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=s.data;if(t.quiet){k(c?.connectorId??``);return}if(i===`text`){k(`id: ${c?.connectorId??`-`}`),k(`name: ${c?.connectorName??`-`}`),k(`description: ${c?.description??`-`}`);return}A(s,i)}}),zl=w({description:{"en-US":`Batch import files from an authorized OSS bucket into the data center`,"zh-CN":`从已授权的 OSS Bucket 批量导入文件到数据中心`},auth:`apiKey`,usageArgs:`--bucket <name> --region <id> --oss-key <key> [flags]`,flags:{bucket:{type:`string`,valueHint:`<name>`,description:{"en-US":`Authorized OSS bucket name`,"zh-CN":`已授权的 OSS Bucket 名称`},required:!0},region:{type:`string`,valueHint:`<id>`,description:{"en-US":`OSS region id (e.g. cn-beijing)`,"zh-CN":`OSS Region ID(例如 cn-beijing)`},required:!0},ossKey:{type:`array`,valueHint:`<key>`,description:{"en-US":`OSS object key to import (repeatable, 1-10 per call)`,"zh-CN":`要导入的 OSS Object Key(可重复,每次调用 1–10 个)`},required:!0},categoryId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Target data-center category (default: the default category)`,"zh-CN":`目标数据中心类目(默认:默认类目)`}},tag:{type:`array`,valueHint:`<text>`,description:{"en-US":`File tag applied to every imported file (repeatable, up to 10)`,"zh-CN":`应用于每个导入文件的标签(可重复,最多 10 个)`}},overwrite:{type:`switch`,description:{"en-US":`Overwrite files previously imported from the same OSS keys`,"zh-CN":`覆盖此前从相同 OSS Key 导入的文件`}},...U},notes:[{"en-US":`The bucket must be authorized to the platform service role beforehand; permission errors from the server are passed through with a pointer to check AliyunServiceRoleForBailian in the RAM console.`,"zh-CN":`必须预先将 Bucket 授权给平台服务角色;服务端权限错误将原样透传,并提示在 RAM 控制台检查 AliyunServiceRoleForBailian。`},{"en-US":`File names are derived from the OSS key basename.`,"zh-CN":`文件名取自 OSS Key 的 basename。`},{"en-US":`--overwrite replaces the previously imported file and issues a NEW fileId (the old one becomes invalid) — verified live.`,"zh-CN":`--overwrite 会替换此前导入的文件并生成新的 fileId(旧 fileId 将失效)——已通过真实环境验证。`}],exampleArgs:[`--bucket my-bucket --region cn-beijing --oss-key docs/a.pdf --workspace-id ws-xxx`,`--bucket my-bucket --region cn-beijing --oss-key docs/a.pdf --oss-key docs/b.docx --overwrite`],validate(e){if(e.ossKey.length>10)return`--oss-key accepts at most 10 entries per call`;if(e.tag!==void 0&&e.tag.length>10)return`--tag accepts at most 10 entries`},async run(e){let{settings:t,flags:n}=e,r=W(e),i=T(t.output),a={categoryId:n.categoryId??`default`,categoryType:`UNSTRUCTURED`,ossBucket:n.bucket,ossRegionId:n.region,fileDetails:n.ossKey.map(e=>({fileName:F(e),ossKey:e})),...n.tag?.length?{tags:n.tag}:{},...n.overwrite?{overWriteFileByOssKey:!0}:{}},o=E(r,p.addFilesFromAuthorizedOss);if(t.dryRun){A({endpoint:o,request:a},i);return}let s=await e.client.requestJson({path:o,method:`POST`,body:a}),c=s.data?.addFileResultList??[],l=c.map(e=>e.fileId).filter(e=>!!e);if(t.quiet){for(let e of l)k(e);return}if(i===`text`){k(`imported: ${l.length} file(s)`);for(let e of c)k(` ${e.fileId??`-`} ${e.status??`-`} ${e.ossKey??``}`);return}A(s,i)}});function Bl(e){if(!(e instanceof t))return!1;let n=e.message;return/^MCP request failed:\s*404\b/i.test(n)?/未开通|MCP不存在|MCP_IS_INVALID/i.test(n):!1}function Vl(e){let t=[`Activate (or re-activate) the ${e} MCP in the Bailian MCP marketplace, then retry.`];return e===`WebSearch`&&t.push(`If it was previously on SSE, cancel and activate again to upgrade to Streamable HTTP.`),t.push(`Open: ${jn(e)}`),t.join(`
|
|
2739
|
+
`)}function Hl(e,n){throw!(e instanceof t)||e.hint?e:Bl(e)||n===`WebSearch`&&Qe(e)?new t(e.message,e.exitCode,Vl(n),{cause:e,api:e.api,rawResponse:e.rawResponse}):e}const Ul={target:{type:`string`,valueHint:`<server.tool>`,description:{"en-US":`Server code and tool name joined by a dot, e.g. market-cmapi00073529.SmartStockSelection`,"zh-CN":`由点号连接的 Server Code 和工具名称,例如 market-cmapi00073529.SmartStockSelection`},required:!0},arg:{type:`array`,valueHint:`<kv>`,description:{"en-US":`Tool argument (repeatable). Values parsed as JSON if possible, else string.`,"zh-CN":`工具参数(可重复)。值会优先按 JSON 解析,否则作为字符串。`}},json:{type:`string`,valueHint:`<obj>`,description:{"en-US":`Full arguments object as JSON; merged with --arg (arg wins).`,"zh-CN":`完整的 JSON 参数对象;与 --arg 合并(--arg 优先)。`}},query:{type:`string`,valueHint:`<text>`,description:{"en-US":`Shortcut for --arg query=<text> (mirrors many DashScope MCP tools).`,"zh-CN":`--arg query=<text> 的快捷方式(与许多 DashScope MCP 工具一致)。`}},url:{type:`string`,valueHint:`<url>`,description:{"en-US":`Override the MCP endpoint URL (non-Bailian). Tries Streamable HTTP first, then classic SSE on the same URL.`,"zh-CN":`覆盖 MCP Endpoint URL(非百炼)。先尝试 Streamable HTTP,再在同一 URL 上回退到传统 SSE。`}}};function Wl(e){let t=e.indexOf(`.`);if(t<=0||t===e.length-1)throw new y(`target must be <server-code>.<tool>, got "${e}".`);return{serverCode:e.slice(0,t),toolName:e.slice(t+1)}}function Gl(e){let t={};for(let n of e){let e=n.indexOf(`=`);if(e<=0)throw new y(`--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 Kl(e){let t;try{t=JSON.parse(e)}catch(e){throw new y(`--json is not valid JSON — ${e.message}`)}if(!t||typeof t!=`object`||Array.isArray(t))throw new y(`--json must decode to an object.`);return t}function ql(e){let t=e.json?Kl(e.json):{};return Object.assign(t,Gl(e.arg??[])),e.query!==void 0&&(t.query=e.query),t}function Jl(e){try{Wl(e.target),ql(e)}catch(e){if(e instanceof y)return e.message;throw e}}var Yl=w({description:{"en-US":`Call a tool on an MCP server (tools/call)`,"zh-CN":`调用 MCP 服务器上的工具(tools/call)`},auth:`apiKey`,usageArgs:`--target <server.tool> [--arg k=v ...] [--json '{...}'] [--url <url>]`,flags:Ul,exampleArgs:[{"en-US":`--target market-cmapi00073529.SmartStockSelection --query "Screen consumer stocks with ROE > 15%"`,"zh-CN":`--target market-cmapi00073529.SmartStockSelection --query "筛选 ROE 大于 15% 的消费股"`},{"en-US":`--target market-cmapi00073529.FinQuery --json '{"q":"Guizhou Maotai","limit":5}'`,"zh-CN":`--target market-cmapi00073529.FinQuery --json '{"q":"贵州茅台","limit":5}'`},`--target market-cmapi00073529.SmartFundSelection --arg riskLevel=R3 --arg minScale=10`],validate:Jl,async run(e){let{settings:n,flags:r}=e,{serverCode:i,toolName:a}=Wl(r.target),o=ql(r),s=r.url||e.client.url(C(i)),c=T(n.output);if(n.dryRun){A({server:i,url:s,tool:a,arguments:o},c);return}let l;try{let n=await e.client.connectBailianMcp(i,r.url);l=n.client;let s=await n.client.callTool(a,o);if(s.isError)throw new t(`Tool error: ${s.content.map(e=>e.text||``).join(`
|
|
2740
|
+
`)}`);A(s,c)}catch(e){throw r.url||Hl(e,i),e}finally{l?.close?.()}}});const Xl=`zeldaEasy.broadscope-bailian.mcp-server.PageList`;var Zl=w({description:{"en-US":`List MCP servers activated under your Bailian account`,"zh-CN":`列出百炼账号下已激活的 MCP 服务器`},auth:`console`,usageArgs:`[flags]`,flags:{name:{type:`string`,valueHint:`<text>`,description:{"en-US":`Filter by server name (substring match)`,"zh-CN":`按服务器名称筛选(子字符串匹配)`}},type:{type:`string`,valueHint:`<type>`,description:{"en-US":`Server type: OFFICIAL | PRIVATE (default: OFFICIAL)`,"zh-CN":`服务器类型:OFFICIAL | PRIVATE(默认:OFFICIAL)`}},page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Results per page (default: 30)`,"zh-CN":`每页结果数(默认:30)`}}},exampleArgs:[``,`--name finance`,`--output json`],async run(e){let{settings:n,identity:r,flags:i}=e,a=i.name||``,o=i.type||`OFFICIAL`,s=i.page||1,l=i.pageSize||30,u=T(n.output),d={reqDTO:{type:o,displayTools:!1,activated:1,pageNo:s,pageSize:l,serverName:a}};if(n.dryRun){A({api:Xl,data:d,...be(n)},u);return}let f=(await e.client.console(Xl,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}`,c.AUTH,i)}let p=(f.DataV2??{}).data?.data??{},m=p.mcpServerDetailList??[];A({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)}}),Ql=w({description:{"en-US":`List tools exposed by an MCP server (tools/list)`,"zh-CN":`列出 MCP 服务器提供的工具(tools/list)`},auth:`apiKey`,usageArgs:`--server <code> [--url <url>]`,flags:{server:{type:`string`,valueHint:`<code>`,description:{"en-US":"Server code from `mcp list` (e.g. market-cmapi00073529)","zh-CN":"来自 `mcp list` 的 Server Code(例如 market-cmapi00073529)"},required:!0},url:{type:`string`,valueHint:`<url>`,description:{"en-US":`Override the MCP endpoint URL (non-Bailian). Tries Streamable HTTP first, then classic SSE on the same URL.`,"zh-CN":`覆盖 MCP Endpoint URL(非百炼)。先尝试 Streamable HTTP,再在同一 URL 上回退到传统 SSE。`}}},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(C(r)),a=T(t.output);if(t.dryRun){A({server:r,url:i,action:`tools/list`},a);return}let o;try{let t=await e.client.connectBailianMcp(r,n.url);o=t.client;let i=await t.client.listTools();A({server:r,url:t.url,tools:i},a)}catch(e){throw n.url||Hl(e,r),e}finally{o?.close?.()}}});function $l(e){Hl(e,`WebSearch`)}var eu=w({description:{"en-US":`Search the web using DashScope MCP WebSearch service`,"zh-CN":`使用 DashScope MCP WebSearch 服务搜索互联网`},auth:`apiKey`,usageArgs:`--query <text> [flags]`,flags:{query:{type:`string`,valueHint:`<text>`,description:{"en-US":`Search query text`,"zh-CN":`搜索查询文本`}},count:{type:`number`,valueHint:`<n>`,description:{"en-US":`Number of search results (default: 10)`,"zh-CN":`搜索结果数量(默认:10)`}},listTools:{type:`switch`,description:{"en-US":`List available MCP tools and exit`,"zh-CN":`列出可用的 MCP 工具并退出`}}},exampleArgs:[{"en-US":`--query "Alibaba Cloud Bailian latest features"`,"zh-CN":`--query "阿里云百炼最新功能"`},{"en-US":`--query "TypeScript 5.9 new features" --count 5`,"zh-CN":`--query "TypeScript 5.9 新功能" --count 5`},{"en-US":`--query "Today's news"`,"zh-CN":`--query "今日新闻"`},`--list-tools`],validate:e=>!e.listTools&&!e.query?`Missing required flag: --query`:void 0,async run(e){let{settings:n,flags:r}=e,i=T(n.output);if(r.listTools){if(n.dryRun){A({endpoint:e.client.url(ht()),action:`tools/list`},i);return}try{let t=e.client.mcp(ht());await t.initialize(),A({tools:await t.listTools()},i)}catch(e){$l(e)}return}let a=r.query;if(n.dryRun){A({endpoint:e.client.url(ht()),action:`tools/call`,tool:`bailian_web_search`,arguments:{query:a,count:r.count||void 0}},i);return}let o=e.client.mcp(ht()),s=bn(`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(`
|
|
2741
|
+
`)}`);if(n.quiet||s.stop(`Done.`),i===`json`)A(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)?A({pages:t.pages,total:t.pages.length},i):A(t,i)}catch{A({text:e.text},i)}}catch(e){s.stop(`Failed.`),$l(e)}}});const tu=`${s.cn}/cosyvoice-clone-design-api`,nu=[{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:`印尼语`}],ru={"cosyvoice-v3-flash":nu,"cosyvoice-v3-plus":nu,"cosyvoice-v3.5-flash":[],"cosyvoice-v3.5-plus":[],"cosyvoice-v2":[]};function iu(e){let t=ru[e];if(!t){process.stdout.write(`No built-in voice list available for model: ${e}\n`),process.stdout.write(`Browse voices in the console: ${gn}\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.
|
|
2742
|
+
`),process.stdout.write(`See: ${tu}\n`),process.stdout.write(`Browse voices in the console: ${gn}\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${gn}\n`)}var au=w({description:{"en-US":`Synthesize speech from text (CosyVoice TTS)`,"zh-CN":`将文本合成为语音(CosyVoice TTS)`},auth:`apiKey`,usageArgs:`--text <text> [flags]`,flags:{text:{type:`string`,valueHint:`<text>`,description:{"en-US":`Text to synthesize into speech (or use --text-file)`,"zh-CN":`要合成为语音的文本(也可使用 --text-file)`}},textFile:{type:`string`,valueHint:`<path>`,description:{"en-US":`Read text from a file instead of --text`,"zh-CN":`从文件读取文本,而非使用 --text`}},model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Model ID (default: cosyvoice-v3-flash). System voices available for cosyvoice-v3-flash`,"zh-CN":`模型 ID(默认:cosyvoice-v3-flash)。cosyvoice-v3-flash 支持系统音色`}},voice:{type:`string`,valueHint:`<voice>`,description:{"en-US":`Voice ID. Use --list-voices to see built-in voices for cosyvoice-v3-flash; for v3.5-flash provide a clone/design voice ID`,"zh-CN":`音色 ID。使用 --list-voices 查看 cosyvoice-v3-flash 的内置音色;使用 v3.5-flash 时需提供复刻/设计音色 ID`}},listVoices:{type:`switch`,description:{"en-US":`List built-in system voices for the selected model and exit (console link shown in output)`,"zh-CN":`列出所选模型的内置系统音色并退出(输出中会显示控制台链接)`}},format:{type:`string`,valueHint:`<format>`,description:{"en-US":`Audio format: mp3, pcm, wav, opus (default: mp3)`,"zh-CN":`音频格式:mp3、pcm、wav、opus(默认:mp3)`},choices:[`mp3`,`pcm`,`wav`,`opus`]},sampleRate:{type:`string`,valueHint:`<rate>`,description:{"en-US":`Audio sample rate in Hz (e.g. 24000)`,"zh-CN":`音频采样率,单位为 Hz(例如 24000)`}},volume:{type:`string`,valueHint:`<volume>`,description:{"en-US":`Volume 0-100 (default: 50)`,"zh-CN":`音量 0–100(默认:50)`}},rate:{type:`string`,valueHint:`<rate>`,description:{"en-US":`Speech rate 0.5-2.0 (default: 1.0)`,"zh-CN":`语速 0.5–2.0(默认:1.0)`}},pitch:{type:`string`,valueHint:`<pitch>`,description:{"en-US":`Pitch multiplier 0.5-2.0 (default: 1.0)`,"zh-CN":`音高倍数 0.5–2.0(默认:1.0)`}},seed:{type:`string`,valueHint:`<seed>`,description:{"en-US":`Random seed 0-65535 for reproducible synthesis`,"zh-CN":`用于复现合成结果的随机种子 0–65535`}},language:{type:`string`,valueHint:`<lang>`,description:{"en-US":`Language hint (e.g. zh, en, ja, ko, fr, de)`,"zh-CN":`语言提示(例如 zh、en、ja、ko、fr、de)`}},instruction:{type:`string`,valueHint:`<text>`,description:{"en-US":`Natural language instruction to control speech style (e.g. "Use a gentle tone")`,"zh-CN":`用于控制语音风格的自然语言指令(例如“使用温柔的语气”)`}},enableSsml:{type:`switch`,description:{"en-US":`Enable SSML markup parsing in input text`,"zh-CN":`解析输入文本中的 SSML 标记`}},out:{type:`string`,valueHint:`<path>`,description:{"en-US":`Save audio to file (default: auto-generate in temp dir)`,"zh-CN":`将音频保存到文件(默认:在临时目录中自动生成路径)`}},stream:{type:`switch`,description:{"en-US":`Stream raw PCM audio to stdout (pipe to player)`,"zh-CN":`将原始 PCM 音频流式输出到 stdout(可通过管道传给播放器)`}},...n},exampleArgs:[`--list-voices --model cosyvoice-v3-flash`,{"en-US":`--text "Hello, I am Qwen" --voice <voice_id>`,"zh-CN":`--text "你好,我是通义千问" --voice <voice_id>`},{"en-US":`--text "Hello world" --voice <voice_id> --language en`,"zh-CN":`--text "你好,世界" --voice <voice_id> --language zh`},`--text-file script.txt --out speech.wav --voice <voice_id>`,{"en-US":`--text "Today is a good day" --voice <voice_id> --instruction "Use a gentle tone"`,"zh-CN":`--text "今天天气很好" --voice <voice_id> --instruction "使用温柔的语气"`},{"en-US":`--text "Hello" --voice <voice_id> --format wav --sample-rate 24000`,"zh-CN":`--text "你好" --voice <voice_id> --format wav --sample-rate 24000`},{"en-US":`# Stream to audio player (macOS)`,"zh-CN":`# 流式传输到音频播放器(macOS)`},{"en-US":`--text "Hello" --voice <voice_id> --stream | afplay -`,"zh-CN":`--text "你好" --voice <voice_id> --stream | afplay -`},{"en-US":`# Pipe to ffplay`,"zh-CN":`# 通过管道传输到 ffplay`},{"en-US":`--text "Hello" --voice <voice_id> --stream | ffplay -nodisp -autoexit -f s16le -ar 24000 -ac 1 -`,"zh-CN":`--text "你好" --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: ${gn})`}},async run(e){let{settings:n,flags:r}=e,i=r.model||n.defaultSpeechModel||`cosyvoice-v3-flash`;if(r.listVoices){iu(i);return}let a=r.text||``;if(!a&&r.textFile){let e=r.textFile;try{a=Xn(e,`utf-8`).trim()}catch{throw new t(`Cannot read text file: ${e}`,c.USAGE)}}let o=r.voice,s=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=T(n.output),y={model:i,input:{text:a,voice:o,format:u,sample_rate:d,volume:f,rate:p,pitch:m,seed:h,language_hints:s?[s]:void 0,instruction:l,enable_ssml:g}};if(Qt(y.input),n.dryRun){A({request:y},v);return}n.quiet||process.stderr.write(`[Model: ${i}] [Voice: ${o}]\n`),_?await su(e.client,n,y,r,v):await ou(e.client,n,y,r,v)}});async function ou(e,n,r,i,a){let o=await Rn(On(i),n,()=>e.requestJson({path:Yt(),method:`POST`,body:r})),s=o.map(e=>e.output?.audio?.url).filter(Boolean);if(s.length===0)throw new t(`API returned no audio URL.`,c.GENERAL);let l=await import(`path`),u=Ut(n,{subDir:`speech`}),d=await Cn(s.map((e,t)=>{let n=i.out;if(!(n&&s.length===1)){let e=Date.now(),i=s.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}}),Sn,{quiet:n.quiet});if(n.quiet)k(d.join(`
|
|
2743
|
+
`));else if(d.length===1){let e=o[0].output?.audio?.expires_at;A({saved:d[0],audio_url:s[0],model:r.model,voice:r.input.voice,...e?{url_expires_at:e}:{}},a)}else A({saved:d,audio_urls:s,total:d.length,model:r.model,voice:r.input.voice},a)}async function su(e,t,n,r,i){let a=await e.request({path:Yt(),method:`POST`,body:n,stream:!0,headers:{Accept:`text/event-stream`,"X-DashScope-SSE":`enable`}}),o=r.out,s=o?qn(o):null,c;try{for await(let e of Et(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&&A({saved:o,...c?{audio_url:c}:{},model:n.model,voice:n.input.voice},i)}const cu={url:{type:`array`,valueHint:`<url>`,description:{"en-US":`Audio file URL or local file path (repeatable, max 100)`,"zh-CN":`音频文件 URL 或本地文件路径(可重复,最多 100 个)`},required:!0},model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Model ID (default: fun-asr). Async: fun-asr / *-filetrans / paraformer-*; sync: qwen3-asr-flash* / fun-asr-flash* / qwen-audio-*-asr-flash`,"zh-CN":`模型 ID(默认:fun-asr)。异步:fun-asr / *-filetrans / paraformer-*;同步:qwen3-asr-flash* / fun-asr-flash* / qwen-audio-*-asr-flash`}},language:{type:`string`,valueHint:`<lang>`,description:{"en-US":`Language hint (e.g. zh, en, ja). Classic async/input-audio: language_hints; qwen3-filetrans: language; qwen3 sync: asr_options.language`,"zh-CN":`语言提示(例如 zh、en、ja)。传统异步/input-audio:language_hints;qwen3-filetrans:language;qwen3 同步:asr_options.language`}},diarization:{type:`switch`,description:{"en-US":`Enable automatic speaker diarization`,"zh-CN":`启用自动说话人分离`}},speakerCount:{type:`number`,valueHint:`<n>`,description:{"en-US":`Expected number of speakers (requires --diarization)`,"zh-CN":`预期的说话人数量(需启用 --diarization)`}},vocabularyId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Hot-word vocabulary ID for improved accuracy`,"zh-CN":`用于提升识别准确率的热词表 ID`}},channelId:{type:`number`,valueHint:`<n>`,description:{"en-US":`Audio channel ID (default: 0)`,"zh-CN":`音频声道 ID(默认:0)`}},out:{type:`string`,valueHint:`<path>`,description:{"en-US":`Save full transcription result to JSON file`,"zh-CN":`将完整转写结果保存到 JSON 文件`}},...e,pollInterval:{type:`number`,valueHint:`<seconds>`,description:{"en-US":`Polling interval in seconds (default: 2)`,"zh-CN":`轮询间隔,单位为秒(默认:2)`}}};function lu(e,n,r){let i=[];if(e.diarization===!0&&i.push(`--diarization`),e.speakerCount!==void 0&&i.push(`--speaker-count`),r===`qwen3`&&e.vocabularyId!==void 0&&i.push(`--vocabulary-id`),e.channelId!==void 0&&i.push(`--channel-id`),e.async===!0&&i.push(`--async`),e.pollInterval!==void 0&&i.push(`--poll-interval`),i.length>0)throw new t(`Model "${n}" uses sync Flash ASR and does not support: ${i.join(`, `)}.\nHint: Use an async filetrans model (e.g. fun-asr, qwen3-asr-flash-filetrans) for those flags.`,c.USAGE)}var uu=w({description:{"en-US":`Recognize speech from audio files (FunAudio-ASR / Qwen-ASR Flash)`,"zh-CN":`识别音频文件中的语音(FunAudio-ASR / Qwen-ASR Flash)`},auth:`apiKey`,usageArgs:`--url <audio-url> [flags]`,flags:cu,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`,`--url https://example.com/audio.mp3 --model qwen-audio-3.0-asr-flash --language en`],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 a=r.speakerCount,o=r.diarization===!0;if(a!==void 0&&!o)throw new t(`--speaker-count requires --diarization to be enabled.
|
|
2744
|
+
Hint: Add --diarization flag to enable speaker separation.`,c.USAGE);let s=r.model||`fun-asr`,l=zt(s);if(l.kind===`unsupported`)throw new t(l.unsupportedReason??`Unsupported ASR model: ${s}`,c.USAGE);if(l.kind===`sync-flash`&&(lu(r,s,l.flashFamily),i.length!==1))throw new t(`Model "${s}" is a sync Flash ASR model and accepts exactly one --url (got ${i.length}).\nHint: Pass a single audio URL, or use an async filetrans model for batch files.`,c.USAGE);if(l.kind===`async-filetrans`&&l.asyncInputStyle===`file_url`&&i.length!==1)throw new t(`Model "${s}" accepts exactly one --url (got ${i.length}).\nHint: qwen3-asr-flash-filetrans* requires a single file_url.`,c.USAGE);let u=T(n.output),d=await Promise.all(i.map(t=>e.client.uploadFile(t,s)));if(l.kind===`sync-flash`){await du(e.client,n,r,u,s,l,d[0]);return}let f=r.channelId,p=r.vocabularyId,m=ne(l.asyncLanguageStyle??`language_hints`,r.language),h={model:s,input:l.asyncInputStyle===`file_url`?{file_url:d[0]}:{file_urls:d},parameters:{channel_id:f===void 0?[0]:[f],...m,diarization_enabled:o?!0:void 0,speaker_count:a,vocabulary_id:p}};if(Qt(h.parameters),n.dryRun){A({request:h,mode:`async`,path:Jt()},u);return}n.quiet||process.stderr.write(`[Model: ${s}] [Mode: async] [Files: ${d.length}]\n`),await fu(e.client,n,h,r,u,d.length)}});async function du(e,t,n,r,i,a,o){let s=a.flashFamily,c=te({model:i,audioUrl:o,language:n.language,vocabularyId:n.vocabularyId,flashFamily:s});if(t.dryRun){A({request:c,mode:`sync`,path:a.path},r);return}t.quiet||process.stderr.write(`[Model: ${i}] [Mode: sync] [Files: 1]\n`);let l=await e.requestJson({path:a.path,method:`POST`,headers:{"X-DashScope-SSE":`disable`},body:c}),u=we(l,s);u?process.stdout.write(u.endsWith(`
|
|
2745
|
+
`)?u:`${u}\n`):k(JSON.stringify(l)),n.out&&($n(n.out,JSON.stringify(l,null,2)+`
|
|
2746
|
+
`),t.quiet||process.stderr.write(`Full result saved to: ${n.out}\n`))}async function fu(e,n,r,i,a,o){let s=(await e.requestJson({path:Jt(),method:`POST`,body:r,async:!0})).output.task_id;if(i.async){A({task_id:s},a);return}let l=i.pollInterval??2,u=await Pn(e,n,{url:e.url($t(s)),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=se(u.output);if(d.length===0){A({task_id:s,status:u.output.task_status},a);return}let f=[];for(let e=0;e<d.length;e++){let n=d[e],r=o>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(`
|
|
2666
2747
|
`);continue}if(!n.transcription_url){r&&process.stdout.write(`
|
|
2667
|
-
`);continue}let i=await fetch(n.transcription_url);if(!i.ok)throw new t(`Failed to download transcription: HTTP ${i.status}`,
|
|
2748
|
+
`);continue}let i=await fetch(n.transcription_url);if(!i.ok)throw new t(`Failed to download transcription: HTTP ${i.status}`,c.GENERAL);let a=await i.json();f.push(a);let s=a.transcripts;if(s&&s.length>0)for(let e of s)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+`
|
|
2668
2749
|
`);else k(JSON.stringify(a));r&&process.stdout.write(`
|
|
2669
|
-
`)}if(i.out){let e=i.out,t=f.length===1?f[0]:f
|
|
2670
|
-
`),n.quiet||process.stderr.write(`Full result saved to: ${e}\n`)}}var
|
|
2671
|
-
`);let a=[`Model`,`Type`,`Remaining`,`Total`,`Quota Left`,`Auto-Stop`],o=[],s=[],c=a.length-1,l=
|
|
2750
|
+
`)}if(i.out){let e=i.out,t=f.length===1?f[0]:f;$n(e,JSON.stringify(t,null,2)+`
|
|
2751
|
+
`),n.quiet||process.stderr.write(`Full result saved to: ${e}\n`)}}var pu=w({description:{"en-US":`Upload a local file to DashScope temporary storage (48h)`,"zh-CN":`将本地文件上传到 DashScope 临时存储(保留 48 小时)`},auth:`apiKey`,usageArgs:`--file <path> --model <model>`,flags:{file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Local file to upload (image, video, audio)`,"zh-CN":`要上传的本地文件(图片、视频或音频)`},required:!0},model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Target model name (file is bound to this model)`,"zh-CN":`目标模型名称(文件将与该模型绑定)`},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-3.0`],async run(e){let{settings:t,flags:n}=e,r=n.file,i=n.model,a=T(t.output);if(t.dryRun){A({action:`upload`,file:r,model:i},a);return}let o=await e.client.uploadFile(r,i);t.quiet?k(o):A({url:o,model:i,expires_in:`48 hours`,note:`When using this URL in API calls, add header: X-DashScope-OssResourceResolve: enable`},a)}}),mu=w({description:{"en-US":`Call a Bailian console API via the CLI gateway`,"zh-CN":`通过 CLI Gateway 调用百炼控制台 API`},auth:`console`,usageArgs:`--api <api> --data <json> [flags]`,flags:{api:{type:`string`,valueHint:`<api>`,description:{"en-US":`API name (e.g. zeldaEasy.broadscope-bailian.memory-library.getLibraries)`,"zh-CN":`API 名称(例如 zeldaEasy.broadscope-bailian.memory-library.getLibraries)`},required:!0},data:{type:`string`,valueHint:`<json>`,description:{"en-US":`Request data as JSON string`,"zh-CN":`JSON 字符串格式的请求数据`},required:!0}},exampleArgs:[`--api zeldaEasy.bailian-commerce.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 y(`--data must be valid JSON`)}let o=T(t.output);if(t.dryRun){A({api:r,data:a,...be(t)},o);return}A(await e.client.console(r,a),o)}});function q(e){return e.toLocaleString(`en-US`)}function J(e){let t=new Date(e);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)}`}function hu(e){let t=new Date(e),n=String(t.getHours()).padStart(2,`0`),r=String(t.getMinutes()).padStart(2,`0`),i=String(t.getSeconds()).padStart(2,`0`);return`${J(e)} ${n}:${r}:${i}`}function gu(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>\`.`,c.GENERAL,`Run \`${n} workspace list\` to view available workspaces.`)}function _u(e){return nn(e)}const vu={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 yu(e){for(let t of e){let e=vu[t];if(e)return e}return`-`}async function bu(e){return(await ke((t,n)=>e.console(t,n))).filter(e=>typeof e.model==`string`&&e.model).map(e=>({name:e.model,type:yu(e.capabilities||[])}))}const xu=`zeldaEasy.bailian-commerce.freeTrial.queryFreeTierQuota`,Su=`zeldaEasy.bailian-commerce.freeTrial.queryFreeTierOnlyStatus`;function Cu(e,t){let n=e.data;if(!n)return[];let r=n.DataV2;return r?r.data?.data?.[t]||[]:n.data?.[t]||[]}function wu(e){return Cu(e,`freeTierQuotas`)}function Tu(e){return Cu(e,`freeTierOnlyStatuses`)}function Eu(e){return Du(e)||e.quotaInitTotal==null||e.quotaInitTotal<=0?null:Math.round(e.quotaTotal/e.quotaInitTotal*1e3)/10}function Du(e){return e.quotaValidityPeriod>0&&e.quotaValidityPeriod<Date.now()}function Ou(e){let{quotas:t,stopMap:n,typeMap:r}=e,i=O(process.stdout);e.title&&process.stdout.write(i.purple(e.title)+`
|
|
2752
|
+
`);let a=[`Model`,`Type`,`Remaining`,`Total`,`Quota Left`,`Auto-Stop`],o=[],s=[],c=a.length-1,l=Fn({headers:a,rows:t.map(e=>{let t=e.quotaInitTotal!=null&&e.quotaTotal!=null,i=Du(e),a=t?`${q(e.quotaTotal)}${i?` (expired)`:``}`:`-`,c=t?q(e.quotaInitTotal):`-`,l=Eu(e);o.push(l),s.push(i?`expired`:l==null?`-`:null);let u=n.get(e.model),d=u===!0?`ON`:u===!1?`OFF`:e.quotaStatus===`UNKNOWN`?`Unsupported`:`-`;return[e.model,r.get(e.model)||`-`,a,c,``,d]}),align:[`left`,`left`,`right`,`right`,`left`,`left`],barColumns:[{index:4,percents:o,labels:s}],cellColor:(e,t,n)=>{if(t===c){if(n===`ON`)return i.green(n);if(n===`OFF`)return i.yellow(n)}}});for(let e of l)process.stdout.write(e+`
|
|
2672
2753
|
`);e.moreHint&&process.stdout.write(i.dim(e.moreHint)+`
|
|
2673
|
-
`)}const
|
|
2674
|
-
`);return}let y=!i&&!s?
|
|
2675
|
-
`);return}let a=new Set,o=e.map(e=>{let t=
|
|
2754
|
+
`)}const ku=`zeldaEasy.bailian-telemetry.model.getModelUsageStatistic`,Au=`zeldaEasy.bailian-telemetry.model.listModelUsageStatisticData`;async function ju(e,t,n,r=30){let i;for(let a=0;a<r;a++){let r=await e.console(t,n(i)),a=nn(r);if(a.taskId&&Object.keys(a).length===1){i=a.taskId,await new Promise(e=>setTimeout(e,500));continue}return r}return null}async function Mu(e,t,n){return ju(e,t,e=>e?{reqDTO:{...n,asyncTaskId:e}}:{reqDTO:n})}async function Nu(e,t,n,r){return ju(e,t,e=>({[n]:e?{taskId:e}:{models:r}}),20)}function Pu(e){let t=_u(e);if(t.callSuccessCount!==void 0||t.usages!==void 0)return t}function Fu(e){let t=_u(e);return{list:t.list??[],totalCount:t.totalCount??0,maxResults:t.maxResults??0}}function Iu(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 Lu={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 Ru(e){let t=Lu[e];if(!t)return e;let n=t.unit?` [${t.unit}]`:``;return`${t.en}${n}`}function zu(e,t,n,r,i=`Usage Overview`){let a=O(process.stdout);process.stdout.write(`${a.purple(i)} ${a.dim(`·`)} ${J(t)} ~ ${J(n)} ${a.dim(`(${r} days)`)}\n`);let o=[[`Models Called`,q(e.modelCount??0)],[`Successful Calls`,q(e.callSuccessCount??0)]];for(let t of e.usages??[])o.push([Ru(t.key),q(t.value)]);let s=Math.max(...o.map(([e])=>xn(e)));for(let[e,t]of o)process.stdout.write(`${a.bold(M(e,s+2))}${t}\n`)}var Bu=w({description:{"en-US":`Query free-tier quota for models (all models if --model is omitted)`,"zh-CN":`查询模型免费额度(省略 --model 时查询全部模型)`},auth:`console`,usageArgs:`[--model <model>[,model2,...]] [flags]`,flags:{model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Model name(s) to query, comma-separated for multiple; omit for all models`,"zh-CN":`要查询的模型名称;多个名称以逗号分隔,省略时查询全部模型`}},expiring:{type:`string`,valueHint:`<days>`,description:{"en-US":`Only show quotas expiring within N days`,"zh-CN":`仅显示将在 N 天内到期的额度`}},sort:{type:`string`,valueHint:`<field>`,description:{"en-US":`Sort by: remaining (ascending), expires (ascending)`,"zh-CN":`排序方式:remaining(剩余额度升序)、expires(到期时间升序)`},choices:[`remaining`,`expires`]},all:{type:`switch`,description:{"en-US":`Show all models instead of the top rows`,"zh-CN":`显示全部模型,而不只显示前几行`}}},exampleArgs:[``,`--model qwen3-max`,`--model qwen3-max,qwen-turbo`,`--expiring 30`,`--sort remaining`,`--all`,`--model qwen-turbo --output json`,`--model qwen3-max --console-region cn-beijing`],async run(e){let{identity:t,settings:n,flags:r}=e,i=r.model||void 0,a=Number(r.expiring)||0,o=r.sort||void 0,s=!!r.all,c=T(n.output),l,u=new Map;l=i?[...new Set(i.split(`,`).map(e=>e.trim()).filter(Boolean))]:[];let d={queryFreeTierQuotaRequest:{models:l}};if(n.dryRun){A({api:xu,data:d},c);return}if(i){let t=await Promise.all(l.map(t=>Pe((t,n)=>e.client.console(t,n),t)));for(let e=0;e<l.length;e++){let n=t[e];n&&u.set(l[e],yu(n.capabilities||[]))}}else{let t=await bu(e.client);l=t.map(e=>e.name);for(let e of t)u.set(e.name,e.type);d.queryFreeTierQuotaRequest.models=l}let f=wu(await e.client.console(xu,d)),p=i?f:f.filter(e=>e.quotaStatus===`VALID`&&e.quotaInitTotal>0);if(a>0){let e=Date.now()+a*24*60*60*1e3;p=p.filter(t=>t.quotaValidityPeriod>0&&t.quotaValidityPeriod<=e)}let m=o??(i?void 0:`remaining`);m===`remaining`?p.sort((e,t)=>(e.quotaInitTotal?e.quotaTotal/e.quotaInitTotal:0)-(t.quotaInitTotal?t.quotaTotal/t.quotaInitTotal:0)):m===`expires`&&p.sort((e,t)=>(e.quotaValidityPeriod??0)-(t.quotaValidityPeriod??0));let h=p.map(e=>e.model),g=h.length?await e.client.console(Su,{queryFreeTierOnlyStatusRequest:{models:h}}):null,_=g?Tu(g):[],v=new Map(_.map(e=>[e.model,e.freeTierOnly]));if(c===`json`){A(p.map(e=>{let t=e.quotaInitTotal!=null&&e.quotaTotal!=null,n=t?e.quotaInitTotal-e.quotaTotal:0,r=v.get(e.model),i=r===!0?!0:r===!1?!1:e.quotaStatus===`UNKNOWN`?`unsupported`:null;return{model:e.model,type:u.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,remainingPercent:Eu(e),expires:e.quotaValidityPeriod?J(e.quotaValidityPeriod):null,autoStop:i}}),c);return}if(p.length===0){process.stdout.write(`No free-tier quota found.
|
|
2755
|
+
`);return}let y=!i&&!s?p.slice(0,15):p,b=p.length-y.length,x=m===`remaining`?` · sorted by urgency`:``;Ou({quotas:y,stopMap:v,typeMap:u,title:`Free Tier Quota · ${p.length} models${x}`,moreHint:b>0?`+ ${b} more · ${t.binName} usage free --all to browse all`:void 0})}}),Vu=w({description:{"en-US":`Enable or disable auto-stop for free-tier models. Enables by default; use --off to disable`,"zh-CN":`启用或停用免费额度模型自动停止。默认启用,使用 --off 停用`},auth:`console`,usageArgs:`<--model <model>[,model2,...] | --all> [--off] [flags]`,flags:{model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Model name(s), comma-separated for multiple`,"zh-CN":`模型名称,多个名称以逗号分隔`}},all:{type:`switch`,description:{"en-US":`Apply to all free-tier models`,"zh-CN":`应用于全部免费额度模型`}},on:{type:`switch`,description:{"en-US":`Enable auto-stop (default behavior)`,"zh-CN":`启用自动停止(默认行为)`}},off:{type:`switch`,description:{"en-US":`Disable auto-stop`,"zh-CN":`停用自动停止`}}},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=T(t.output),o;o=r?[...new Set(r.split(`,`).map(e=>e.trim()).filter(Boolean))]:[];let s=i?`zeldaEasy.bailian-commerce.freeTrial.batchDeactivateFreeTierOnly`:`zeldaEasy.bailian-commerce.freeTrial.batchActivateFreeTierOnly`,c=i?`BatchDeactivateFreeTierOnlyRequest`:`BatchActivateFreeTierOnlyRequest`;if(t.dryRun){A({api:s,data:{[c]:{models:o}}},a);return}if(r||(o=(await bu(e.client)).map(e=>e.name)),i){let t=Tu(await e.client.console(Su,{queryFreeTierOnlyStatusRequest:{models:o}})),n=new Map(t.map(e=>[e.model,e.freeTierOnly]));for(let t of o){if(n.get(t)===!1){process.stderr.write(`Auto-stop is already disabled for "${t}".\n`);continue}await Nu(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 Nu(e.client,s,c,[t]);if(a===`json`){l.push(n);continue}if(n){let e=nn(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`&&A(l,a)}});function Hu(e){let t=e.unit?` [${e.unit}]`:``;return`${e.en}${t}`}function Uu(e,t,n,r){let i=O(process.stdout);process.stdout.write(`${i.dim(`Time Range Period:`)} ${J(t)} ~ ${J(n)} ${i.dim(`(${r} days)`)}\n\n`);let a=[[`Models Called`,q(e.modelCount??0)],[`Successful Calls`,q(e.callSuccessCount??0)]];for(let t of e.usages??[]){let e=Lu[t.key],n=e?Hu(e):t.key;a.push([n,q(t.value)])}let o=Math.max(...a.map(([e])=>xn(e)));for(let[e,t]of a)process.stdout.write(`${i.bold(M(e,o+2))}${t}\n`)}function Wu(e,t,n,r){let i=O(process.stdout);if(process.stdout.write(`${i.dim(`Time Range Period:`)} ${J(t)} ~ ${J(n)} ${i.dim(`(${r} days)`)}\n\n`),e.length===0){process.stdout.write(`No usage data found.
|
|
2756
|
+
`);return}let a=new Set,o=e.map(e=>{let t=Iu(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=>Lu[e]?.en??e)],l=e.map((e,t)=>[e.model,q(e.callSuccessCount??0),...s.map(e=>{let n=o[t][e];return n==null?`-`:q(n)})]),u=c.map((e,t)=>Math.max(xn(e),...l.map(e=>xn(e[t])))),d=c.map((e,t)=>i.bold(M(e,u[t]))).join(` `),f=u.map(e=>i.dim(`─`.repeat(e))).join(`──`);process.stdout.write(d+`
|
|
2676
2757
|
`),process.stdout.write(f+`
|
|
2677
2758
|
`);for(let e of l){let t=e.map((e,t)=>M(e,u[t]));process.stdout.write(t.join(` `)+`
|
|
2678
2759
|
`)}process.stdout.write(i.dim(`\nTotal: ${e.length} models`)+`
|
|
2679
|
-
`)}var
|
|
2680
|
-
`);return}
|
|
2681
|
-
`);else{let e=g.slice(0,10),t=g.length-e.length;
|
|
2682
|
-
`),
|
|
2760
|
+
`)}var Gu=w({description:{"en-US":`Query model usage statistics`,"zh-CN":`查询模型用量统计`},auth:`console`,usageArgs:`[--model <model>] [--days <days>] [flags]`,flags:{model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Model name(s), comma-separated; omit for overview`,"zh-CN":`模型名称,多个名称以逗号分隔;省略时查看概览`}},days:{type:`string`,valueHint:`<days>`,description:{"en-US":`Number of days (default: 7)`,"zh-CN":`天数(默认:7)`}},type:{type:`string`,valueHint:`<type>`,description:{"en-US":`Model type: Text, Vision, Multimodal, Audio, Embedding`,"zh-CN":`模型类型: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,a=i.model||void 0,o=Number(i.days)||7,s=i.type||void 0,l=T(r.output),u=gu(r,n.binName),d=Date.now(),f=d-o*24*60*60*1e3;if(a){let t=[...new Set(a.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(s&&(n.obsModelType=s),r.dryRun){A({api:Au,data:{reqDTO:{...n,model:t.join(`,`)}}},l);return}let i=await Promise.all(t.map(t=>Mu(e.client,Au,{...n,model:t}))),c=[];for(let e of i){if(!e)continue;let t=Fu(e);c.push(...t.list)}if(l===`json`){let e=c.map(e=>{let t=Iu(e),n={model:e.model,successfulCalls:e.callSuccessCount??0};for(let[e,r]of Object.entries(t))n[e]=r;return n});A({period:{start:J(f),end:J(d),days:o},items:e},l);return}Wu(c,f,d,o)}else{let n={startTime:f,endTime:d,modelCallSource:`Online`,filterWorkspaceId:u};if(s&&(n.obsModelType=s),r.dryRun){A({api:ku,data:{reqDTO:n}},l);return}let i=await Mu(e.client,ku,n);if(!i)throw new t(`Request timed out.`,c.TIMEOUT);let a=Pu(i);if(l===`json`){if(!a){A({period:{start:J(f),end:J(d),days:o},modelsCalled:0,successfulCalls:0},l);return}A({period:{start:J(f),end:J(d),days:o},modelsCalled:a.modelCount??0,successfulCalls:a.callSuccessCount??0,usages:(a.usages??[]).map(e=>({key:e.key,value:e.value,unit:e.unit,label:Lu[e.key]?.en??e.key}))},l);return}if(!a){process.stdout.write(`No usage data found.
|
|
2761
|
+
`);return}Uu(a,f,d,o)}}}),Ku=w({description:{"en-US":`Show a unified usage summary: free-tier quota and recent usage overview`,"zh-CN":`显示统一用量摘要:免费额度和近期用量概览`},auth:`console`,usageArgs:`[--days <days>] [flags]`,flags:{days:{type:`string`,valueHint:`<days>`,description:{"en-US":`Number of days for the usage overview (default: 7)`,"zh-CN":`用量概览的天数(默认:7)`}}},exampleArgs:[``,`--days 30`,`--output json`],async run(e){let{identity:n,settings:r,flags:i}=e,a=Number(i.days)||7,o=T(r.output),s=r.workspaceId,l=Date.now(),u=l-a*24*60*60*1e3;if(r.dryRun){A({freeTier:{api:xu},usage:s?{api:ku,data:{reqDTO:{startTime:u,endTime:l,modelCallSource:`Online`,filterWorkspaceId:s}}}:null},o);return}let d=await bu(e.client),f=d.map(e=>e.name),p=new Map(d.map(e=>[e.name,e.type])),[m,h]=await Promise.all([e.client.console(xu,{queryFreeTierQuotaRequest:{models:f}}),e.client.console(Su,{queryFreeTierOnlyStatusRequest:{models:f}})]),g=wu(m).filter(e=>e.quotaStatus===`VALID`&&e.quotaInitTotal>0).sort((e,t)=>(e.quotaInitTotal?e.quotaTotal/e.quotaInitTotal:0)-(t.quotaInitTotal?t.quotaTotal/t.quotaInitTotal:0)),_=Tu(h),v=new Map(_.map(e=>[e.model,e.freeTierOnly])),y;if(s){let n=await Mu(e.client,ku,{startTime:u,endTime:l,modelCallSource:`Online`,filterWorkspaceId:s});if(!n)throw new t(`Request timed out.`,c.TIMEOUT);y=Pu(n)}if(o===`json`){let e=g.map(e=>({model:e.model,type:p.get(e.model)||null,remaining:e.quotaTotal,total:e.quotaInitTotal,remainingPercent:Eu(e),expires:e.quotaValidityPeriod?J(e.quotaValidityPeriod):null}));A({period:{start:J(u),end:J(l),days:a},freeTier:e,usage:y?{modelsCalled:y.modelCount??0,successfulCalls:y.callSuccessCount??0,usages:(y.usages??[]).map(e=>({key:e.key,value:e.value,unit:e.unit,label:Lu[e.key]?.en??e.key}))}:null},o);return}let b=O(process.stdout);if(process.stdout.write(`${b.bold(`Usage Summary`)} ${b.dim(`·`)} ${J(l)}\n\n`),g.length===0)process.stdout.write(b.dim(`No active free-tier quota.`)+`
|
|
2762
|
+
`);else{let e=g.slice(0,10),t=g.length-e.length;Ou({quotas:e,stopMap:v,typeMap:p,title:`Free Tier Quota · ${g.length} models · sorted by urgency`,moreHint:t>0?`+ ${t} more · ${n.binName} usage free to browse all`:void 0})}process.stdout.write(`
|
|
2763
|
+
`),s?y?zu(y,u,l,a):process.stdout.write(b.dim(`No usage data in this period.`)+`
|
|
2683
2764
|
`):process.stdout.write(b.dim(`Usage overview skipped · set --workspace-id or \`${n.binName} config set workspace_id <id>\` to include it.`)+`
|
|
2684
|
-
`)}});function
|
|
2685
|
-
`);return}
|
|
2686
|
-
`);return}let l=await
|
|
2765
|
+
`)}});function qu(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function Ju(e){let t=Math.round(e*1e3)/10;return`${Number.isInteger(t)?t:t.toFixed(1)}%`}function Yu(e,t){let n=Math.max(0,e-t),r=Math.floor(n/6e4);if(r===0)return`now`;let i=Math.floor(r/1440),a=Math.floor(r%1440/60),o=r%60,s=[];return i>0&&s.push(`${i}d`),a>0&&s.push(`${a}h`),(o>0||s.length===0)&&s.push(`${o}m`),s.join(` `)}function Xu(e,t,n){let r=O(process.stdout),i=(e=``,t)=>{let n=Math.max(0,76-xn(` ${e}`));process.stdout.write(`│ ${t?t(e):e}${` `.repeat(n)}│\n`)},a=e=>{let t=Math.max(0,76-xn(` ${e.plain}`));process.stdout.write(`│ ${e.colored}${` `.repeat(t)}│\n`)},o=e=>{if(i(e.label,r.bold),e.percentage===void 0){i(e.emptyMessage,r.dim);return}let t=`${Ju(e.percentage)} used`;if(a(In(e.percentage*100,t)),e.detail&&i(e.detail,r.dim),e.resetTime===void 0){i(`Resets: not applicable (no usage yet)`,r.dim);return}i(`Resets: ${hu(e.resetTime)} (in ${Yu(e.resetTime,n)})`,r.dim)};process.stdout.write(`┌${`─`.repeat(76)}┐\n`),i(e,r.cyan),i(`Generated at: ${hu(n)} (local time)`,r.dim);for(let e of t)process.stdout.write(`├${`─`.repeat(76)}┤\n`),o(e);process.stdout.write(`└${`─`.repeat(76)}┘\n`)}const Zu=`zeldaHttp.apikeyMgr./tokenplan/personal/api/v2/usage`;function Qu(e){let t=nn(e),n={},r=qu(t.per5HourPercentage);r!==void 0&&(n.per5HourPercentage=r);let i=qu(t.per5HourResetTime);i!==void 0&&(n.per5HourResetTime=i);let a=qu(t.per1WeekPercentage);a!==void 0&&(n.per1WeekPercentage=a);let o=qu(t.per1WeekResetTime);return o!==void 0&&(n.per1WeekResetTime=o),n}function $u(e,t){Xu(`Token Plan Usage`,[{label:`5-hour quota`,emptyMessage:`The 5-hour limit may be unlimited; verify in the Bailian Token Plan console.`,percentage:e.per5HourPercentage,resetTime:e.per5HourResetTime},{label:`1-week quota`,emptyMessage:`The 1-week limit may be unlimited; verify in the Bailian Token Plan console.`,percentage:e.per1WeekPercentage,resetTime:e.per1WeekResetTime}],t)}var ed=w({description:{"en-US":`Show Token Plan quota usage`,"zh-CN":`查看 Token Plan 配额使用情况`},auth:`console`,usageArgs:`[flags]`,exampleArgs:[``,`--output json`],async run(e){let{settings:t}=e,n=T(t.output);if(t.dryRun){A({api:Zu,data:{}},n);return}let r=Qu(await e.client.console(Zu,{}));if(n===`json`){A(r,n);return}$u(r,Date.now())}});const td=`zeldaEasy.broadscope-bailian.codingPlan.queryCodingPlanInstanceInfoV2`,nd={domestic:`sfm_codingplan_public_cn`,international:`sfm_codingplan_public_intl`};function rd(e,t){let n={};if(!e)return n;let r=qu(e[`${t}UsedQuota`]);r!==void 0&&(n.usedQuota=r);let i=qu(e[`${t}TotalQuota`]);i!==void 0&&(n.totalQuota=i);let a=qu(e[`${t}QuotaNextRefreshTime`]);return a!==void 0&&(n.resetTime=a),r!==void 0&&i!==void 0&&i>0&&(n.percentage=r/i),n}function id(e){let t=nn(e),n=(Array.isArray(t.codingPlanInstanceInfos)?t.codingPlanInstanceInfos:[]).find(e=>e.status===`VALID`);if(!n)return;let r=n.codingPlanQuotaInfo,i={per5Hour:rd(r,`per5Hour`),perWeek:rd(r,`perWeek`),perBillMonth:rd(r,`perBillMonth`)};return typeof n.instanceType==`string`&&n.instanceType&&(i.instanceType=n.instanceType),i}function ad(e,t){let n={label:e,emptyMessage:`No quota data for this window; verify in the Bailian Coding Plan console.`,percentage:t.percentage,resetTime:t.resetTime};return t.usedQuota!==void 0&&t.totalQuota!==void 0&&(n.detail=`Used: ${q(t.usedQuota)} / ${q(t.totalQuota)}`),n}function od(e,t){Xu(`Coding Plan Usage${e.instanceType?` (${e.instanceType})`:``}`,[ad(`5-hour quota`,e.per5Hour),ad(`1-week quota`,e.perWeek),ad(`Monthly quota`,e.perBillMonth)],t)}var sd=w({description:{"en-US":`Show Coding Plan quota usage`,"zh-CN":`查看 Coding Plan 配额使用情况`},auth:`console`,usageArgs:`[flags]`,exampleArgs:[``,`--output json`],async run(e){let{settings:t}=e,n=T(t.output),r={queryCodingPlanInstanceInfoRequest:{commodityCode:nd[t.consoleSite??`domestic`],onlyLatestOne:!0}};if(t.dryRun){A({api:td,data:r},n);return}let i=id(await e.client.console(td,r));if(n===`json`){A(i??{},n);return}if(!i){process.stdout.write(`No active Coding Plan subscription found.
|
|
2766
|
+
`);return}od(i,Date.now())}});async function cd(e){let t=await Cr(e,`utf-8`).catch(e=>{throw new y(`cannot read pipeline file: ${e.message}`)}),n=dr(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 ld=w({description:{"en-US":`Run a pipeline workflow definition`,"zh-CN":`运行 Pipeline 工作流定义`},auth:`none`,usageArgs:`--file <path> [flags]`,flags:{file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Pipeline definition file (YAML/JSON)`,"zh-CN":`Pipeline 定义文件(YAML/JSON)`},required:!0},input:{type:`string`,valueHint:`<json>`,description:{"en-US":`Runtime input as inline JSON`,"zh-CN":`内联 JSON 格式的运行时输入`}},inputFile:{type:`string`,valueHint:`<path>`,description:{"en-US":`Runtime input from a JSON file`,"zh-CN":`来自 JSON 文件的运行时输入`}},concurrency:{type:`number`,valueHint:`<n>`,description:{"en-US":`Max parallel steps (default: 1)`,"zh-CN":`最大并行步骤数(默认:1)`}},events:{type:`string`,valueHint:`<format>`,description:{"en-US":`Emit lifecycle events: jsonl`,"zh-CN":`输出生命周期事件:jsonl`},choices:[`jsonl`]},stepTimeout:{type:`number`,valueHint:`<seconds>`,description:{"en-US":`Default step timeout in seconds`,"zh-CN":`默认步骤超时时间,单位为秒`}}},exampleArgs:[{"en-US":`--file workflow.yaml --input '{"brief":"hello"}'`,"zh-CN":`--file workflow.yaml --input '{"brief":"你好"}'`},`--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;kn();let i=n.events,a=pr(r),o=await cd(a),s=await ud(n),c=ur(a);if(i===`jsonl`){for await(let e of zn(o,s,{concurrency:n.concurrency,basePath:c,dryRun:t.dryRun,timeoutSeconds:n.stepTimeout}))process.stdout.write(JSON.stringify(e)+`
|
|
2767
|
+
`);return}let l=await wn(o,s,{concurrency:n.concurrency,basePath:c,dryRun:t.dryRun,timeoutSeconds:n.stepTimeout,onEvent:t.verbose?dd:void 0});t.output===`json`?A(l,`json`):pd(l),l.status===`failed`&&(process.exitCode=1)}});async function ud(e){let t=e.input,n=e.inputFile;if(t)return JSON.parse(t);if(n){let e=await Cr(pr(n),`utf-8`);return JSON.parse(e)}return{}}function dd(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} ${fd(e.step)}\n`):process.stderr.write(`${t}\n`)}function fd(e){return`${e.index!==void 0&&e.total!==void 0?`${e.index}/${e.total} `:``}${e.id} (${e.type})`}function pd(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+`
|
|
2687
2768
|
`)}process.stdout.write(`
|
|
2688
|
-
`)}var
|
|
2769
|
+
`)}var md=w({description:{"en-US":`Validate a pipeline definition without executing`,"zh-CN":`验证 Pipeline 定义但不执行`},auth:`none`,usageArgs:`--file <path>`,flags:{file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Pipeline definition file (YAML/JSON)`,"zh-CN":`Pipeline 定义文件(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;kn();let i=await cd(pr(r)),a=vn(i),o=a.length===0?_n(i):[];if(t.output===`json`)A({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.
|
|
2689
2770
|
`);for(let e of o)process.stderr.write(` hint: ${e}\n`)}else{process.stderr.write(`Pipeline validation failed:
|
|
2690
|
-
`);for(let e of a)process.stderr.write(` - ${e}\n`);process.exitCode=1}}});function
|
|
2691
|
-
`),{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
|
|
2692
|
-
`),{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
|
|
2693
|
-
`)}function
|
|
2771
|
+
`);for(let e of a)process.stderr.write(` - ${e}\n`);process.exitCode=1}}});function hd(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 gd={Text:`Text`,Image:`Image`,Video:`Video`,Audio:`Audio`},_d={TG:`Text Gen`,VU:`Vision`,IG:`Image Gen`,VG:`Video Gen`,TTS:`Text-to-Speech`,ASR:`Speech-to-Text`,Reasoning:`Reasoning`},vd={low:`Cost-Effective`,medium:`Balanced`,high:`High Investment`},yd={flagship:`Flagship`,balanced:`Balanced`,"cost-optimized":`Value`},bd={scoped:`Scoped`,comparison:`Comparison`,alternative:`Alternative`};function xd(e){return Bn(e)?Er:new Dr({level:0})}function Sd(e){let t=xd(process.stdout),n=Bn(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=>gd[e]??e),a=e.outputModality.map(e=>gd[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=>_d[e]??e);o.length&&r.push(`${t.dim(`Capabilities`)} ${o.join(`, `)}`);let s=vd[e.budget]??e.budget,c=yd[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=bd[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=>gd[e]??e).join(`, `);r.push(` ${t.dim(`${n+1}.`)} ${i.step}${e?t.dim(` → ${e}`):``}`)}}return Tr(r.join(`
|
|
2772
|
+
`),{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 Cd=[`Best Pick`,`Runner-Up`,`Alternative`];function wd(e,t,n,r){let i=[n.green.bold,n.blue.bold,n.magenta.bold][t]??n.white.bold,a=Cd[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 ${hd(e.contextWindow)}`),e.maxOutputTokens&&s.push(`Max Output ${hd(e.maxOutputTokens)}`),s.length&&(o.push(``),o.push(n.dim(s.join(` · `))));let c=re(e.docUrl);return c&&(o.push(``),o.push(n.dim(`Docs ${c}`))),Tr(o.join(`
|
|
2773
|
+
`),{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 Td(e){let t=xd(process.stdout),n=Bn(process.stdout);return e.map((e,r)=>wd(e,r,t,n)).join(`
|
|
2774
|
+
`)}function Ed(e,t){let n=xd(process.stdout),r=Bn(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)=>wd(e,t,n,r)).join(`
|
|
2694
2775
|
`))}return i.join(`
|
|
2695
|
-
`)}function
|
|
2696
|
-
`),a.update(`Agent: Recalling candidates...`),a.start();let p=await
|
|
2776
|
+
`)}function Dd(e){return e.type===`pipeline`?Ed(e.summary,e.steps):Td(e.recommendations)}function Od(e){return e.type===`pipeline`?e.steps.length===0:e.recommendations.length===0}var kd=w({description:{"en-US":`Recommend the best models for your use case (intent analysis → candidate recall → LLM ranking)`,"zh-CN":`为你的使用场景推荐最佳模型(意图分析 → 候选召回 → LLM 排序)`},auth:`apiKey`,usageArgs:`--message <text> [flags]`,flags:{message:{type:`string`,valueHint:`<text>`,description:{"en-US":`Describe your requirements`,"zh-CN":`描述你的需求`},required:!0}},exampleArgs:[{"en-US":`--message "I need a visual-understanding chatbot"`,"zh-CN":`--message "我需要一个能够理解图片的聊天机器人"`},{"en-US":`--message "Build an Agent that auto-generates animations"`,"zh-CN":`--message "构建一个可以自动生成动画的智能体"`},{"en-US":`--message "Legal contract review, high precision required"`,"zh-CN":`--message "审查法律合同,要求高准确率"`},{"en-US":`--message "Low-cost high-concurrency online customer service" --output text`,"zh-CN":`--message "低成本、高并发的在线客服" --output text`},{"en-US":`--message "Long document summarization" --dry-run`,"zh-CN":`--message "长文档摘要" --dry-run`}],async run(e){let{settings:t,flags:n}=e,r=n.message;await mt();let i=t.outputExplicit?T(t.output):`json`,a=bn(`Agent: Loading model data & analyzing intent...`);a.start();let o={onPrepareStart:()=>{}},s=!1,c=!1,l=We(t,o).then(e=>(s=!0,c||a.update(`Agent: Model data loaded, analyzing intent...`),e)),u=b(e.client,r).then(e=>(c=!0,s||a.update(`Agent: Intent analyzed, loading model data...`),e)),[d,f]=await Promise.all([l,u]);a.stop(),f.confidence===0&&process.stderr.write(`Intent analysis timed out, using defaults...
|
|
2777
|
+
`),a.update(`Agent: Recalling candidates...`),a.start();let p=await Ft(e.client,d,r,h,f);if(a.stop(),t.dryRun){A({userInput:r,intent:{taskSummary:f.taskSummary,scenarioHints:f.scenarioHints,complexity:f.complexity,inputModality:f.inputModality,outputModality:f.outputModality,requiredCapabilities:f.requiredCapabilities,budget:f.budget,qualityPreference:f.qualityPreference,modelPreference:f.modelPreference?.mode===`unconstrained`?void 0:f.modelPreference,segments:f.segments,semanticQuery:f.semanticQuery},candidateCount:p.length,candidates:p.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 m=await jt(e.client,p,f,r,3);if(a.stop(),Od(m)){k(`No suitable models found for this request.`);return}if(i!==`text`){A({intent:{taskSummary:f.taskSummary,scenarioHints:f.scenarioHints,complexity:f.complexity,inputModality:f.inputModality,outputModality:f.outputModality,requiredCapabilities:f.requiredCapabilities,budget:f.budget,qualityPreference:f.qualityPreference,modelPreference:f.modelPreference?.mode===`unconstrained`?void 0:f.modelPreference,segments:f.segments,semanticQuery:f.semanticQuery},result:m,candidates:p.length},i);return}k(Sd(f)),k(``),k(Dd(m))}});const Ad=/-\d{4}-\d{2}-\d{2}$/,jd={model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Show full details of a specific model family (switches to detail mode)`,"zh-CN":`显示指定模型系列的完整详情(切换到详情模式)`}},page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Results per page (default: 10)`,"zh-CN":`每页结果数(默认:10)`}},provider:{type:`array`,valueHint:`<p>`,description:{"en-US":`Filter by provider (repeatable, e.g. --provider alibaba --provider deepseek)`,"zh-CN":`按提供商筛选(可重复,例如 --provider alibaba --provider deepseek)`}},capability:{type:`array`,valueHint:`<c>`,description:{"en-US":`Filter by capability code (TG, Reasoning, VU, IG, VG, TTS, ASR, …)`,"zh-CN":`按能力代码筛选(TG、Reasoning、VU、IG、VG、TTS、ASR 等)`}},feature:{type:`array`,valueHint:`<f>`,description:{"en-US":`Filter by feature (function-calling, web-search, structured-outputs, …)`,"zh-CN":`按特性筛选(function-calling、web-search、structured-outputs 等)`}},contextWindow:{type:`array`,valueHint:`<w>`,description:{"en-US":`Filter by context window range bucket`,"zh-CN":`按上下文窗口范围筛选`}},enrich:{type:`switch`,description:{"en-US":`Also fetch input parameter schema (predictConfig) for trunk models (detail mode only)`,"zh-CN":`同时获取主干模型的输入参数 Schema(predictConfig,仅详情模式)`}}};function Md(e){return(e.model??``).replace(/^group-/,``)||e.name||`unknown`}function Nd(e){if(!e?.length)return`-`;let t=e.find(e=>typeof e.type==`string`&&e.type.includes(`input`))??e[0];return`${t.type??``}:${String(t.price??`?`)}/${t.priceUnit??``}`}function Pd(e){let t=new Set,n=new Set,r=0,i=0,a,o=[];for(let s of e.items??[]){s.provider&&t.add(s.provider);for(let e of s.capabilities??[])n.add(e);r++,typeof s.contextWindow==`number`&&s.contextWindow>i&&(i=s.contextWindow),s.prices?.length&&(o.push(...s.prices),a||=s.prices.find(e=>typeof e.type==`string`&&e.type.includes(`input`))??s.prices[0])}return{providers:[...t].join(`,`),capabilities:[...n].join(`,`),modelCount:r,maxContext:i>0?i:void 0,price:a?Nd([a]):void 0,prices:o}}function Fd(e){if(e.length===0)return[];let t=e.filter(e=>!Ad.test(e.model??``));return t.length>0?t:[...e].sort((e,t)=>String(t.model).localeCompare(String(e.model))).slice(0,1)}function Id(e,t){if(e.length===0){k(`No model families found.`);return}let n=[`NAME`,`PROVIDER`,`CAPABILITIES`,`MODELS`,`MAX_CONTEXT`,`PRICE`],r=e.map(e=>{let t=Pd(e);return[e.name||Md(e),t.providers||`-`,t.capabilities||`-`,String(t.modelCount),t.maxContext?String(t.maxContext):`-`,t.price??`-`]});for(let e of j(n,r))k(e);k(`\nTotal: ${t}`)}function Ld(e,t){return{items:e.map(e=>{let t=Pd(e),n=e.items?.[0];return{model:Md(e),name:e.name,description:e.description,provider:t.providers,capabilities:[...new Set((e.items??[]).flatMap(e=>e.capabilities??[]))],modelCount:t.modelCount,maxContextWindow:t.maxContext,prices:t.prices.length>0?t.prices:void 0,qpmInfo:n?.qpmInfo}}),total:t}}function Rd(e,t){let n=e.items??[],r=Fd(n),i=n.length-r.length;k(e.name??e.model),e.description&&k(` ${e.description}`),e.updateAt&&k(` Updated: ${e.updateAt}`),k(``);let a=[`MODEL`,`PROVIDER`,`CAPABILITIES`,`CONTEXT`,`OUTPUT`,`CATEGORY`,`PRICE`],o=n.map(e=>[e.model??`-`,e.provider??`-`,(e.capabilities??[]).join(`,`)||`-`,e.contextWindow?String(e.contextWindow):`-`,e.maxOutputTokens?String(e.maxOutputTokens):`-`,e.category??`-`,Nd(e.prices)]);for(let e of j(a,o))k(e);k(`\nTotal: ${n.length} models (${r.length} trunk, ${i} snapshots)`);for(let e of r){if(!e.prices?.length)continue;k(`\n── Pricing: ${e.model} ──`);let t=[`TYPE`,`PRICE`,`UNIT`],n=e.prices.map(e=>[e.type??`-`,String(e.price??`-`),e.priceUnit??`-`]);for(let e of j(t,n))k(e)}for(let e of r){if(!e.qpmInfo||Object.keys(e.qpmInfo).length===0)continue;k(`\n── Rate Limits: ${e.model} ──`);let t=[`TIER`,`RPM`,`TPM`,`TPM_FIELD`],n=Object.entries(e.qpmInfo).map(([e,t])=>{let n=t.count_limit_period||60,r=n?Math.floor((t.count_limit||0)*60/n):0,i=t.usage_limit_period||60,a=i?Math.floor((t.usage_limit||0)*60/i):0;return[e,r>0?String(r):`-`,a>0?String(a):`-`,t.usage_limit_field??`-`]});for(let e of j(t,n))k(e)}if(t)for(let e of r)!e.predictConfig||e.predictConfig.length===0||(k(`\n── predictConfig: ${e.model} ──`),Bd(e.predictConfig))}function zd(e,t){let n=e.items??[];return{model:e.model,name:e.name,description:e.description,updateAt:e.updateAt,items:n.map(e=>{let n={model:e.model,name:e.name,provider:e.provider,capabilities:e.capabilities,features:e.features,contextWindow:e.contextWindow,maxOutputTokens:e.maxOutputTokens,maxInputTokens:e.maxInputTokens,category:e.category,openSource:e.openSource,docUrl:e.docUrl,versionTag:e.versionTag};return e.prices&&(n.prices=e.prices),e.qpmInfo&&(n.qpmInfo=e.qpmInfo),t&&e.predictConfig&&(n.predictConfig=e.predictConfig),n})}}function Bd(e){let t=[`PARAM`,`KEY`,`DEFAULT`,`RANGE`],n=e.map(e=>[e.name??`-`,e.key??`-`,e.default===void 0?`-`:JSON.stringify(e.default),e.range===void 0?`-`:JSON.stringify(e.range)]);for(let e of j(t,n))k(e)}var Vd=w({description:{"en-US":`Browse model families or show detailed model info in the Bailian model marketplace`,"zh-CN":`浏览百炼模型市场中的模型系列,或查看模型详细信息`},auth:`none`,usageArgs:`[--model <model>] [--page <n>] [--page-size <n>] [--provider <p>] [--capability <c>] [--feature <f>] [--enrich]`,flags:jd,exampleArgs:[``,`--provider alibaba`,`--capability TG --capability Reasoning`,`--model qwen-max`,`--model qwen-max --enrich --output json`,`--feature function-calling --output json`],notes:[{"en-US":`Both the catalog and --enrich parameter-schema endpoints are public — no console login needed.`,"zh-CN":`模型目录和 --enrich 使用的参数 Schema Endpoint 均为公开接口,无需登录控制台。`}],async run(e){let{settings:t,flags:n}=e,r=t.outputExplicit?T(t.output):`json`,i=n.model,a=x(t);if(i){let e=!!n.enrich;if(t.dryRun){A({action:`model.detail`,model:i,enrich:e},r);return}let o=await De(a,i);if(!o){k(`Model "${i}" not found.`);return}if(e){let e=Fd(o.items??[]);await Promise.all(e.map(async e=>{if(!e.model)return;let t=await Ae(a,e.model);t&&(e.predictConfig=t)}))}if(r===`json`){A(zd(o,e),r);return}Rd(o,e);return}let o={pageNo:n.page,pageSize:n.pageSize??10,providers:n.provider?.length?n.provider:void 0,capabilities:n.capability?.length?n.capability:void 0,features:n.feature?.length?n.feature:void 0,contextWindows:n.contextWindow?.length?n.contextWindow:void 0};if(t.dryRun){A({action:`model.list`,...o},r);return}let{total:s,groups:c}=await Oe(a,o);if(r===`json`){A(Ld(c,s),r);return}Id(c,s)}});const Hd=`zeldaEasy.bailian-dash-workspace.space.listWorkspaces`;function Ud(e,t){let n=e[t];if(n&&typeof n==`object`&&!Array.isArray(n))return n}function Wd(e){let t=Ud(e,`data`);if(!t)return e;let n=Ud(t,`DataV2`);if(n){let e=Ud(n,`data`);return(e?Ud(e,`data`):void 0)??e??n}return Ud(t,`data`)??t}function Gd(e){let t=O(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(xn(e),...r.map(e=>xn(e[t])))),a=n.map((e,n)=>t.bold(M(e,i[n]))).join(` `),o=i.map(e=>t.dim(`─`.repeat(e))).join(`──`);process.stdout.write(a+`
|
|
2697
2778
|
`),process.stdout.write(o+`
|
|
2698
2779
|
`);for(let e of r){let n=e.map((e,n)=>n===2&&e===`Yes`?t.green(M(e,i[n])):M(e,i[n]));process.stdout.write(n.join(` `)+`
|
|
2699
2780
|
`)}process.stdout.write(t.dim(`\nTotal: ${e.length}`)+`
|
|
2700
|
-
`)}var
|
|
2701
|
-
`);return}let o=a;if(r>0&&(o=o.slice(0,r)),i===`json`){A(o.map(e=>({workspaceId:e.workspaceId,name:e.agentName,default:e.defaultAgent})),i);return}
|
|
2702
|
-
`);return}let n=
|
|
2703
|
-
`);process.stdout.write(`\nTotal: ${t}\n`)}var
|
|
2781
|
+
`)}var Kd=w({description:{"en-US":`List all workspaces`,"zh-CN":`列出全部 Workspace`},auth:`console`,usageArgs:`[flags]`,flags:{list:{type:`string`,valueHint:`<n>`,description:{"en-US":`Limit number of results`,"zh-CN":`限制结果数量`}}},exampleArgs:[``,`--list 5`,`--output json`],async run(e){let{settings:t,flags:n}=e,r=Number(n.list)||0,i=T(t.output);if(t.dryRun){A({api:Hd,data:{}},i);return}let a=Wd(await e.client.console(Hd,{})).data;if(!Array.isArray(a)||a.length===0){i===`json`?A([],i):process.stdout.write(`No workspace found.
|
|
2782
|
+
`);return}let o=a;if(r>0&&(o=o.slice(0,r)),i===`json`){A(o.map(e=>({workspaceId:e.workspaceId,name:e.agentName,default:e.defaultAgent})),i);return}Gd(o)}});function qd(e){return[...new Set(e.split(`,`).map(e=>e.trim()).filter(Boolean))]}function Jd(e){let t=new URLSearchParams;for(let[n,r]of Object.entries(e))r!==void 0&&r!==``&&t.set(n,String(r));let n=t.toString();return n?`?${n}`:``}function Yd(e,t){if(e==null)return`-`;let n=t??60;return n===1?`${q(e)}/s`:n===60?`${q(e)}/min`:`${q(e)}/${n}s`}function Xd(e){return e?Yd(e.request_limit,e.request_limit_period):`-`}function Zd(e){return e?Yd(e.usage_limit,e.usage_limit_period):`-`}function Qd(e){return!e||e.async_user_queue_limit==null&&e.async_user_concurrency_limit==null?`-`:`${e.async_user_queue_limit==null?`-`:q(e.async_user_queue_limit)}/${e.async_user_concurrency_limit==null?`-`:q(e.async_user_concurrency_limit)}`}function $d(e,t){if(e.length===0){process.stdout.write(`No rate limits found.
|
|
2783
|
+
`);return}let n=Fn({headers:[`Model`,`Req Limit`,`Usage Limit`,`WS Req`,`WS Usage`,`Async Q/C`],rows:e.map(e=>[e.model,Xd(e.model_limit),Zd(e.model_limit),Xd(e.workspace_limit),Zd(e.workspace_limit),Qd(e.model_limit)]),align:[`left`,`right`,`right`,`right`,`right`,`right`]});for(let e of n)process.stdout.write(e+`
|
|
2784
|
+
`);process.stdout.write(`\nTotal: ${t}\n`)}var ef=w({description:{"en-US":`View model rate limits (QPM/TPM, account and workspace level)`,"zh-CN":`查看模型限流配置(QPM/TPM,账号级和 Workspace 级)`},auth:`apiKey`,usageArgs:`[--model <model>] [--name <name>] [--page <n>] [--page-size <n>]`,flags:{model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Model name(s), comma-separated (exact match)`,"zh-CN":`模型名称,多个以逗号分隔(精确匹配)`}},name:{type:`string`,valueHint:`<name>`,description:{"en-US":`Fuzzy search by model name`,"zh-CN":`按模型名称模糊搜索`}},page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Results per page (default: 20)`,"zh-CN":`每页结果数(默认:20)`}}},exampleArgs:[``,`--model qwen3-max`,`--model qwen3-max,qwen-plus`,`--name qwen --page-size 50`,`--output json`],notes:[{"en-US":"Usage-vs-limit pressure checks live in `quota check` (console auth).","zh-CN":"用量与限流压力检查位于 `quota check`(Console 鉴权)。"}],async run(e){let{settings:t,flags:n}=e,r=n.model||void 0,i=n.name||void 0,a=T(t.output),o=e.client.url(xt());if(t.dryRun){A(r?{requests:qd(r).map(e=>({endpoint:o,method:`GET`,query:{model:e,page_size:100}}))}:{endpoint:o,method:`GET`,query:{name:i,page_no:n.page||1,page_size:n.pageSize||20}},a);return}let s,c;if(r)s=(await Promise.all(qd(r).map(t=>e.client.requestJson({path:xt()+Jd({model:t,page_size:100})})))).flatMap(e=>e.output?.quotas??[]),c=s.length;else{let t=await e.client.requestJson({path:xt()+Jd({name:i,page_no:n.page||1,page_size:n.pageSize||20})});s=t.output?.quotas??[],c=t.output?.total??s.length}if(a===`json`){A({items:s,total:c},a);return}$d(s,c)}}),tf=w({description:{"en-US":`Update model rate limits (QPM/TPM), or clear them with --delete`,"zh-CN":`更新模型限流配置(QPM/TPM),或使用 --delete 清除配置`},auth:`apiKey`,usageArgs:`--model <model> [--rpm <n>] [--tpm <n>] [--delete]`,flags:{model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Model name (required)`,"zh-CN":`模型名称(必填)`},required:!0},rpm:{type:`number`,valueHint:`<n>`,description:{"en-US":`Max requests per minute (QPM)`,"zh-CN":`每分钟最大请求数(QPM)`}},tpm:{type:`number`,valueHint:`<n>`,description:{"en-US":`Max tokens per minute (TPM)`,"zh-CN":`每分钟最大 Token 数(TPM)`}},delete:{type:`switch`,description:{"en-US":`Clear all custom rate limits for the model`,"zh-CN":`清除该模型的所有自定义限流配置`}}},exampleArgs:[`--model qwen-plus --rpm 60 --tpm 100000`,`--model qwen3-max --tpm 500000`,`--model qwen-plus --delete`,`--model qwen-plus --rpm 60 --output json`],notes:[{"en-US":`Fields you omit keep their current values (server-side OVERLAY merge); --delete clears all custom limits.`,"zh-CN":`未指定的字段将保留当前值(服务端 OVERLAY 合并);--delete 会清除所有自定义限流配置。`},{"en-US":`Setting TPM without an existing QPM limit is rejected server-side — pass --rpm first or together.`,"zh-CN":`若当前没有 QPM 限制,单独设置 TPM 会被服务端拒绝——请先设置 --rpm,或同时传入。`}],validate:e=>{if(e.delete&&(e.rpm!==void 0||e.tpm!==void 0))return`--delete cannot be combined with --rpm/--tpm.`;if(!e.delete&&e.rpm===void 0&&e.tpm===void 0)return`one of --rpm / --tpm / --delete is required.`;if(e.rpm!==void 0&&e.rpm<0)return`--rpm must be a non-negative number.`;if(e.tpm!==void 0&&e.tpm<0)return`--tpm must be a non-negative number.`},async run(e){let{settings:t,flags:n}=e,r=n.model,i=T(t.output),a={model:r};n.delete?a.operation_type=`DELETE`:(n.rpm!==void 0&&(a.request_limit=n.rpm,a.request_limit_period=60),n.tpm!==void 0&&(a.usage_limit=n.tpm,a.usage_limit_period=60));let o={models:[a]};if(t.dryRun){A({endpoint:e.client.url(xt()),method:`POST`,request:o},i);return}let s=await e.client.requestJson({path:xt(),method:`POST`,body:o});if(i===`json`){A({model:r,...s},i);return}if(n.delete){process.stdout.write(`Rate limits cleared for "${r}".\n`);return}let c=[];n.rpm!==void 0&&c.push(`QPM ${q(n.rpm)}`),n.tpm!==void 0&&c.push(`TPM ${q(n.tpm)}`),process.stdout.write(`Rate limits updated for "${r}": ${c.join(`, `)}\n`)}});const nf=`zeldaEasy.broadscope-platform.modelInstance.listModelLimitApplications`;function rf(e,t){let n=e[t];if(n&&typeof n==`object`&&!Array.isArray(n))return n}function af(e){let t=rf(e,`data`);if(!t)return e;let n=rf(t,`DataV2`);if(n){let e=rf(n,`data`);return(e?rf(e,`data`):void 0)??e??n}return rf(t,`data`)??t}function of(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 sf(e,t){let n=O(process.stdout),r=[`Model`,`Token Limit`,`Applied At`],i=e.map(e=>[e.deployedModel,q(e.usageLimit),of(e.gmtCreate)]),a=r.map((e,t)=>Math.max(xn(e),...i.map(e=>xn(e[t])))),o=r.map((e,t)=>n.bold(M(e,a[t]))).join(` `),s=a.map(e=>n.dim(`─`.repeat(e))).join(`──`);process.stdout.write(o+`
|
|
2704
2785
|
`),process.stdout.write(s+`
|
|
2705
2786
|
`);for(let e of i)process.stdout.write(e.map((e,t)=>M(e,a[t])).join(` `)+`
|
|
2706
2787
|
`);process.stdout.write(n.dim(`\nTotal: ${t} records`)+`
|
|
2707
|
-
`)}var
|
|
2708
|
-
`);return}
|
|
2709
|
-
`)}var
|
|
2710
|
-
`);return}let s=await Promise.all(o.map(t=>
|
|
2711
|
-
`);process.stdout.write(`\nTotal: ${t}\n`)}var
|
|
2788
|
+
`)}var cf=w({description:{"en-US":`View quota change history`,"zh-CN":`查看额度变更历史`},auth:`console`,usageArgs:`[flags]`,flags:{page:{type:`string`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`string`,valueHint:`<n>`,description:{"en-US":`Page size (default: 10)`,"zh-CN":`每页数量(默认:10)`}},model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Filter by model name`,"zh-CN":`按模型名称筛选`}}},exampleArgs:[``,`--page 2`,`--page-size 20`,`--model qwen-turbo`,`--output json`],async run(e){let{identity:n,settings:r,flags:i}=e,a=Number(i.page)||1,o=Number(i.pageSize)||10,s=i.model||void 0,l=T(r.output),u={input:{pageNo:a,pageSize:o}};if(r.dryRun){A({api:nf,data:u},l);return}let d;try{d=await e.client.console(nf,u)}catch(e){throw e instanceof t&&e.message.includes(`NotLogined`)?new t(`session expired.`,c.AUTH,`Run \`${n.binName} auth login --console\` to re-authenticate.`):e}let f=af(d),p=f.records??[],m=f.items??p.length;if(s&&(p=p.filter(e=>e.deployedModel===s)),l===`json`){A({records:p.map(e=>({model:e.deployedModel,tokenLimit:e.usageLimit,appliedAt:of(e.gmtCreate)})),total:s?p.length:m},l);return}if(p.length===0){process.stdout.write(`No quota change history found.
|
|
2789
|
+
`);return}sf(p,s?p.length:m)}});const lf=`zeldaEasy.bailian-telemetry.monitor.getMonitorData`;function uf(e,t){if(!e)return 0;let n=e.count_limit_period||t;return n?Math.floor(e.count_limit*60/n):0}function df(e,t){if(!e)return 0;let n=e.usage_limit_period||t;return n?Math.floor(e.usage_limit*60/n):0}async function ff(e){let t=[],n=1;for(;;){let r=nn(await e.console(f,{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 pf(e,n,r){let i=Date.now(),a=i-r*60*1e3;try{let t=nn(await e.console(lf,{reqDTO:{monitorType:`Advanced`,metricFilters:[{aggMethod:`sum_pm`,metricName:`model_total_amount`},{aggMethod:`sum_pm`,metricName:`model_call_count`}],labelFilters:{resourceId:n,resourceType:`model`},startTime:a,endTime:i}})),r=t.data??t;if(!Array.isArray(r))return{rpm:0,tpm:0};let o=0,s=0;for(let e of r){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(e){if(e instanceof t&&e.exitCode===c.AUTH)throw e;return{rpm:-1,tpm:-1}}}function mf(e){let t=O(process.stdout),n=[`Model`,`RPM Used/Limit`,`TPM Used/Limit`,`Status`,`RPM Left`,`TPM Left`],r=e.map(e=>e.rpmQuotaLeft),i=e.map(e=>e.rpmQuotaLabel),a=e.map(e=>e.tpmQuotaLeft),o=e.map(e=>e.tpmQuotaLabel),s=Fn({headers:n,rows:e.map(e=>{let t=e.rpmUsage<0?`-`:`${e.rpmUsage}/${e.rpmLimit}`,n=e.tpmUsage<0?`-`:`${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?`-`:r>=100?`Rate Limited`:r>=80?`Near limit`:`Normal`;return[e.model,t,n,i,``,``]}),align:[`left`,`right`,`right`,`left`,`left`,`left`],barColumns:[{index:4,percents:r,labels:i,width:15},{index:5,percents:a,labels:o,width:15}],cellColor:(e,n,r)=>{if(n===3){if(r===`Rate Limited`)return t.red(r);if(r===`Near limit`)return t.yellow(r);if(r===`Normal`)return t.green(r)}}});for(let e of s)process.stdout.write(e+`
|
|
2790
|
+
`)}var hf=w({description:{"en-US":`Check current usage against rate limits`,"zh-CN":`根据限流额度检查当前用量`},auth:`console`,usageArgs:`[--model <model>] [flags]`,flags:{model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Model name(s), comma-separated`,"zh-CN":`模型名称,多个名称以逗号分隔`}},period:{type:`string`,valueHint:`<minutes>`,description:{"en-US":`Query usage for the last N minutes (default: 2)`,"zh-CN":`查询最近 N 分钟的用量(默认: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=T(t.output);if(t.dryRun){A({apis:[f,lf],...be(t)},a);return}let o=await ff(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.
|
|
2791
|
+
`);return}let s=await Promise.all(o.map(t=>pf(e.client,t.model,i))),c=o.map((e,t)=>{let n=e.qpmInfo,r=n[`model-default`],i=n[`user-spec`],a=uf(i,r?.count_limit_period)||uf(r),o=df(i,r?.usage_limit_period)||df(r),c=s[t].rpm,l=s[t].tpm,u=null,d=null;c>=0&&a>0&&(u=Math.max(0,100-c/a*100),d=u.toFixed(1)+`%`);let f=null,p=null;return l>=0&&o>0&&(f=Math.max(0,100-l/o*100),p=f.toFixed(1)+`%`),{model:e.model,rpmUsage:c,rpmLimit:a,tpmUsage:l,tpmLimit:o,rpmQuotaLeft:u,tpmQuotaLeft:f,rpmQuotaLabel:d,tpmQuotaLabel:p}});if(a===`json`){A(c,a);return}mf(c)}});function gf(e){return e==null?`-`:e?`yes`:`no`}function _f(e,t,n){if(e.length===0){process.stdout.write(`No model permissions found.\n${n}\n`);return}let r=Fn({headers:[`Model`,`Name`,`Inference`,`Fine-tune`,`Deploy`],rows:e.map(e=>[e.model,e.name??`-`,gf(e.permissions?.inference),gf(e.permissions?.fine_tune),gf(e.permissions?.deploy)]),align:[`left`,`left`,`right`,`right`,`right`]});for(let e of r)process.stdout.write(e+`
|
|
2792
|
+
`);process.stdout.write(`\nTotal: ${t}\n`)}var vf=w({description:{"en-US":`List model permissions (inference / fine-tune / deploy) in the workspace`,"zh-CN":`列出 Workspace 中的模型权限(推理 / 微调 / 部署)`},auth:`apiKey`,usageArgs:`[--scope <scope>] [--model <model>] [--name <name>] [--page <n>] [--page-size <n>]`,flags:{scope:{type:`string`,valueHint:`<scope>`,choices:[`authorized`,`authorizable`],description:{"en-US":`Authorization scope: authorizable (default, full catalog), authorized`,"zh-CN":`授权范围:authorizable(默认,完整目录)、authorized(已授权)`}},model:{type:`string`,valueHint:`<model>`,description:{"en-US":`Model ID (exact match)`,"zh-CN":`模型 ID(精确匹配)`}},name:{type:`string`,valueHint:`<name>`,description:{"en-US":`Fuzzy search by model name or ID`,"zh-CN":`按模型名称或 ID 模糊搜索`}},page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Results per page (default: 20)`,"zh-CN":`每页结果数(默认:20)`}}},exampleArgs:[``,`--model qwen-plus`,`--scope authorized`,`--name qwen --page-size 50`,`--output text`],notes:[{"en-US":"Default scope is `authorizable` (the full grantable catalog); use `--scope authorized` to see only models already granted.","zh-CN":"默认范围为 `authorizable`(完整可授权目录);使用 `--scope authorized` 仅查看已授权模型。"},{"en-US":"Output defaults to JSON; pass `--output text` for a table. Permission values are tri-state: true / false / null (never set).","zh-CN":"默认输出 JSON;传入 `--output text` 可查看表格。权限值为三态:true / false / null(从未设置)。"},{"en-US":`Values mirror the server's grant records as-is for the workspace bound to your API key. A model reporting false/null can still be callable (access may come from other channels); see the Model Studio authorization docs for the exact semantics.`,"zh-CN":`这些值原样反映 API Key 所绑定 Workspace 的服务端授权记录。显示 false/null 的模型仍可能可以调用(访问权限可能来自其他渠道);准确语义请参阅百炼模型授权文档。`}],async run(e){let{settings:t,flags:n}=e,r=t.outputExplicit?T(t.output):`json`,i=n.scope??`authorizable`,a={authorization_scope:i.toUpperCase(),model:n.model||void 0,name:n.name||void 0,page_no:n.page||1,page_size:n.pageSize||20};if(t.dryRun){A({endpoint:e.client.url(St()),method:`GET`,query:a},r);return}let o=await e.client.requestJson({path:St()+Jd(a)}),s=o.output?.permissions??[],c=o.output?.total??s.length;if(r===`json`){A({items:s,total:c},r);return}let l=e.identity.binName;_f(s,c,i===`authorized`?`Nothing granted yet in this workspace. Browse grantable models with \`${l} permission list --scope authorizable\`, then grant with \`${l} permission grant --model <model>\`.`:`Adjust --name/--model filters, or check pagination with --page/--page-size.`)}});const yf=[`inference`,`finetune`,`deploy`];function bf(e){if(!e)return[`inference`];let t=qd(e);if(t.length===0)return{error:`--action must not be empty.`};for(let e of t)if(!yf.includes(e))return{error:`--action "${e}" is invalid; use ${yf.join(`, `)}.`};return t}function xf(e){if(e.all&&e.model)return`--all cannot be combined with --model.`;if(!e.all&&!e.model)return`one of --model / --all is required.`;let t=bf(e.action);if(`error`in t)return t.error;if(e.all&&(t.length!==1||t[0]!==`inference`))return`--all only supports the inference action.`;if(e.model){let t=qd(e.model);if(t.length===0)return`--model must not be empty.`;if(t.length>20)return`--model accepts at most 20 models per call.`}}async function Sf(e,t,n){let r=e.settings.outputExplicit?T(e.settings.output):`json`,i=bf(t.action),a=t.model?qd(t.model):[],o=t.all?{access_all_entities:n?`OPEN`:`CLOSE`}:{models:a.map(e=>{let t={model:e};for(let e of i)t[e]=n;return t})};if(e.settings.dryRun){A({endpoint:e.client.url(St()),method:`POST`,request:o},r);return}let s=await e.client.requestJson({path:St(),method:`POST`,body:o}),c=n?`granted`:`revoked`;if(r===`json`){A({...t.all?{all:!0,action:`inference`}:{models:a,actions:i},[c]:!0,request_id:s.request_id},r);return}if(t.all){process.stdout.write(n?`Inference permission granted for all models in the workspace (including future ones).
|
|
2712
2793
|
`:`One-key authorization closed; historical inference grants cleared.
|
|
2713
|
-
`);return}process.stdout.write(`Permissions ${c} (${i.join(`, `)}): ${a.join(`, `)}\n`)}var
|
|
2714
|
-
`),
|
|
2715
|
-
`),
|
|
2716
|
-
`)}if(e&&!lt(e).includes(u)){let n=lt(e);throw new t(`Model "${c}" does not support training type "${u}".`,s.USAGE,n.length?`This model supports: ${n.join(`, `)}.`:`This model reports no supported training types.`)}}i.dryRun||(await Cf(n.client,i,m,`fine-tune`,`datasets`),_&&await Cf(n.client,i,_,`fine-tune`,`validations`));let S={model:c,training_file_ids:h,training_type:d.serverTrainingType,hyper_parameters:x};if(v&&v.length>0&&(S.validation_file_ids=v),y&&(S.model_name=y),b&&(S.finetuned_output_suffix=b),i.dryRun){let e=[...m.localPaths.map(e=>({field:`datasets`,path:e})),...(_?.localPaths??[]).map(e=>({field:`validations`,path:e}))];A(e.length>0?{action:`finetune.create`,body:S,pending_uploads:e}:{action:`finetune.create`,body:S},`json`);return}let C=await le(n.client,S),ee=C.output??C.data;i.quiet?ee?.job_id&&k(ee.job_id):A(C,`json`)}const Pf=w({description:`Create a text model fine-tune job (sft | sft-lora | dpo | dpo-lora | cpt)`,auth:`apiKey`,usageArgs:`--base-model <model> --datasets <id|path,...> [--validations <id|path,...>] [--model-name <name>] [--suffix <text>] [--n-epochs <n>] [--batch-size <n>] [--learning-rate <str>] [--max-length <n>] [--training-type <sft|sft-lora|dpo|dpo-lora|cpt>]`,flags:Tf,exampleArgs:[`--base-model qwen3-8b --datasets file-xxx`,`--base-model qwen3-8b --datasets ./train.jsonl`,`--base-model qwen3-8b --datasets ./train.jsonl --validations ./eval.jsonl`,`--base-model qwen3-8b --datasets file-aaa,./extra.jsonl`,`--base-model qwen3-8b --datasets ./train.jsonl --training-type sft`,`--base-model qwen3-8b --datasets file-xxx --learning-rate "1.6e-5" --n-epochs 4`,`--base-model qwen3-8b --datasets file-xxx --output json`,`--base-model qwen3-8b --datasets file-xxx --dry-run`],notes:Af,run:e=>Nf(`text`,e)}),Ff=w({description:`Create an audio TTS model fine-tune job (sft-lora)`,auth:`apiKey`,usageArgs:`--base-model <model> --datasets <id|path> [--validations <id|path>] [--model-name <name>] [--suffix <text>]`,flags:Ef,exampleArgs:[`--base-model cosyvoice-v3-flash --datasets ./audio.zip`,`--base-model cosyvoice-v3-flash --datasets file-xxx`,`--base-model cosyvoice-v3-flash --datasets ./audio.zip --model-name my-tts`,`--base-model cosyvoice-v3-flash --datasets file-xxx --output json`,`--base-model cosyvoice-v3-flash --datasets ./audio.zip --dry-run`],notes:jf,run:e=>Nf(`audio`,e)}),If=w({description:`Create an image generation model fine-tune job (sft-lora)`,auth:`apiKey`,usageArgs:`--base-model <model> --datasets <id|path> [--validations <id|path>] [--model-name <name>] [--suffix <text>] [--generation-type <t2i|i2i>] [--learning-rate <str>]`,flags:Df,exampleArgs:[`--base-model wan2.7-image-pro --datasets ./images.zip`,`--base-model wan2.7-image-pro --datasets file-xxx`,`--base-model wan2.7-image-pro --datasets file-xxx --generation-type i2i`,`--base-model wan2.7-image-pro --datasets ./images.zip --model-name my-wan`,`--base-model wan2.7-image-pro --datasets file-xxx --output json`,`--base-model wan2.7-image-pro --datasets ./images.zip --dry-run`],notes:Mf,run:e=>Nf(`image`,e)}),Lf=w({description:`Create a video generation model fine-tune job (Wan i2v/kf2v, efficient_sft)`,auth:`apiKey`,usageArgs:`--base-model <model> --datasets <id|path> [--validations <id|path>] [--model-name <name>] [--suffix <text>] [--n-epochs <n>] [--batch-size <n>] [--learning-rate <str>]`,flags:Of,exampleArgs:[`--base-model wan2.7-i2v --datasets file-xxx`,`--base-model wan2.7-i2v --datasets ./i2v-data.zip`,`--base-model wan2.2-kf2v-flash --datasets file-xxx --n-epochs 100`,`--base-model wan2.7-i2v --datasets file-xxx --dry-run`],notes:[...kf,`Video generation training (Wan i2v/kf2v) runs efficient_sft with model-`,`specific defaults: wan2.7 (batch_size=1, max_pixels=102400), wan2.5/2.2`,`(batch_size=4, max_pixels per model). Override with --batch-size/--n-epochs.`,`Datasets are .zip archives with data.jsonl + frame images + videos.`,`Recommended: ≥10 training samples, 20-100 for stable results.`],run:e=>Nf(`video`,e)});var Rf=w({description:`List fine-tune jobs`,auth:`apiKey`,usageArgs:`[--page <n>] [--page-size <n>] [--status <s>] [--base-model <model>]`,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)`},baseModel:{type:`string`,valueHint:`<model>`,description:`Filter by base model ID (server-side)`}},exampleArgs:[``,`--status RUNNING`,`--base-model qwen3-8b`,`--page-size 20`],async run(e){let{settings:t,flags:n}=e,r=n.page,i=n.pageSize,a=n.status||void 0,o=n.baseModel||void 0;if(t.dryRun){A({action:`finetune.list`,page:r,page_size:i,status:a,model:o},`json`);return}let s=await ot(e.client,{pageNo:r,pageSize:i,status:a,model:o}),c=s.output??s.data,l=c?.jobs??[],u=c?.total;A({items:l.map(e=>({job_id:e.job_id??``,base_model:e.model??``,status:e.status??``,training_type:e.training_type??``,output_model:e.finetuned_output??``,created_at:e.create_time??e.gmt_create??``})),total:u,request_id:s.request_id},`json`)}});async function zf(e,t){let n=ve(e),r=en(await ne({region:n.consoleRegion,site:n.consoleSite,switchAgent:n.consoleSwitchAgent},e.timeout,{api:d,data:{input:{pageNo:1,pageSize:10,group:!0,model:t,queryPrice:!0,querySampleCode:!1,queryGroupByModel:!0,queryQuota:!1,queryQpmInfo:!1,queryApplyStatus:!1,queryPermissions:!1,queryActivationStatus:!1}}})).list??[];for(let e of r){let n=e.items??[];for(let e of n)if(e.model===t)return(e.prices??[]).find(e=>e.type===`ft`)??null;if(e.model===t)return(e.prices??[]).find(e=>e.type===`ft`)??null}return null}async function Bf(e,t,n){try{let r=await zf(e,t),i=Number(r?.price);if(!Number.isFinite(i)||i<=0)return null;let a=r?.priceUnit??`每百万tokens`,o=n/1e6*i;return{cost:Number(o.toFixed(4)),unitPrice:i,priceUnit:a}}catch{return null}}var Vf=w({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{settings:t,flags:n}=e,r=n.jobId;if(t.dryRun){A({action:`finetune.get`,job_id:r},`json`);return}let i=await ze(e.client,r),a=i.output??i.data;if(!a){A({job_id:r,error:`No data returned`},`json`);return}let o=a.hyper_parameters,s=[];o?.n_epochs!==void 0&&s.push(`n_epochs=${o.n_epochs}`),o?.batch_size!==void 0&&s.push(`batch_size=${o.batch_size}`),o?.learning_rate!==void 0&&s.push(`learning_rate=${o.learning_rate}`),o?.max_length!==void 0&&s.push(`max_length=${o.max_length}`);let c=typeof a.usage==`number`?a.usage:void 0,l={job_id:a.job_id??r,base_model:a.model??``,status:a.status??``,training_type:a.training_type??``,training_files:a.training_file_ids??[],validation_files:a.validation_file_ids??[],hyper_params:s.length?s.join(` · `):``,output_model:a.finetuned_output??``,model_name:a.model_name??``,created_at:a.create_time??a.gmt_create??``,updated_at:a.end_time??a.gmt_modified??``,usage_tokens:c??``,charge_type:typeof a.charge_type==`string`?a.charge_type:``};if(c!==void 0&&c>0&&a.model){let e=await Bf(t,a.model,c);e&&(l.training_cost=e.cost,l.cost_basis=`${e.unitPrice} 元/${e.priceUnit}`)}A({...l,request_id:i.request_id},`json`)}}),Hf=w({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;if(t.dryRun){A({action:`finetune.cancel`,job_id:r},`json`);return}let i=await re(e.client,r);t.quiet?k(r):A(i,`json`)}}),Uf=w({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;if(t.dryRun){A({action:`finetune.delete`,job_id:r},`json`);return}let i=await he(e.client,r);t.quiet?k(r):A(i,`json`)}});function Wf(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 Gf(e,t){return Wf(e).toLowerCase().includes(t)}async function Kf(e,t,n){let r=[],i=1,a=0;for(let o=0;o<200;o++){let o=await Be(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 qf=w({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;if(t.dryRun){A({action:`finetune.logs`,job_id:r,page:i,page_size:a,search:o,tail:s},`json`);return}if(o||s!==void 0){let{entries:t,total:n}=await Kf(e.client,r,a??100),i=t,c;if(o){let e=o.toLowerCase();i=t.filter(t=>Gf(t,e)),c=i.length}let l=s!==void 0&&s>=0?Math.min(s,i.length):void 0,u=l===void 0?i:i.slice(i.length-l);A({...c===void 0?{}:{matched:c},scanned:t.length,total:n||t.length,...o?{search:o}:{},...l===void 0?{}:{tail:l},logs:u},`json`);return}A(await Be(e.client,r,{pageNo:i,pageSize:a}),`json`)}}),Jf=w({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:["`model_name` (shown for SUCCEEDED checkpoints) is the direct input for `deploy create --model-name`.","Checkpoints expire ~15 days after creation; `expire_time` shows the deadline. Export or deploy before expiry."],async run(e){let{settings:t,flags:n}=e,r=n.jobId;if(t.dryRun){A({action:`finetune.checkpoints`,job_id:r},`json`);return}let i=await nt(e.client,r),a=i.output??i.data,o=Array.isArray(a)?a:a?.checkpoints??[],s=Array.isArray(a)?a.length:a?.total??o.length,c=o.map(e=>({checkpoint:e.checkpoint??e.checkpoint_id??``,step:e.step===void 0?``:String(e.step),status:e.status??``,model_name:e.model_name??``,expire_time:e.expire_time??``}));A({items:c,total:s,request_id:i.request_id},`json`);let l=Date.now(),u=c.filter(e=>{if(!e.expire_time)return!1;let t=new Date(e.expire_time).getTime();if(Number.isNaN(t))return!1;let n=t-l;return n>0&&n<2592e5});u.length>0&&process.stderr.write(`\n[warning] ${u.length} checkpoint(s) will expire within 72 hours. Export or deploy before expiry to avoid losing the model artifact.
|
|
2717
|
-
`)}}),
|
|
2794
|
+
`);return}process.stdout.write(`Permissions ${c} (${i.join(`, `)}): ${a.join(`, `)}\n`)}var Cf=w({description:{"en-US":`Grant model permissions (inference / finetune / deploy)`,"zh-CN":`授予模型权限(推理 / 微调 / 部署)`},auth:`apiKey`,usageArgs:`--model <models> [--action <actions>] | --all`,flags:{model:{type:`string`,valueHint:`<models>`,description:{"en-US":`Model ID(s), comma-separated (max 20)`,"zh-CN":`模型 ID,多个以逗号分隔(最多 20 个)`}},action:{type:`string`,valueHint:`<actions>`,description:{"en-US":`Permission action(s), comma-separated: inference, finetune, deploy (default: inference)`,"zh-CN":`权限操作,多个以逗号分隔:inference、finetune、deploy(默认:inference)`}},all:{type:`switch`,description:{"en-US":`One-key grant inference for all models in the workspace (including future ones)`,"zh-CN":`一键授予 Workspace 中所有模型的推理权限(包括未来新增模型)`}}},exampleArgs:[`--model qwen-plus`,`--model qwen-plus,qwen3-max --action inference,finetune`,`--all`,`--model qwen-plus --dry-run --output json`],notes:[{"en-US":`Grants apply to the business workspace your API key belongs to.`,"zh-CN":`授权将应用于 API Key 所属的业务 Workspace。`},{"en-US":`--all maps to the server one-key switch (access_all_entities: OPEN) and only covers inference.`,"zh-CN":`--all 对应服务端一键授权开关(access_all_entities: OPEN),仅涵盖推理权限。`},{"en-US":`Actions you omit keep their current grants (server-side tri-state patch).`,"zh-CN":`未指定的操作将保留当前授权状态(服务端三态增量更新)。`}],validate:e=>xf(e),async run(e){await Sf(e,e.flags,!0)}}),wf=w({description:{"en-US":`Revoke model permissions (inference / finetune / deploy)`,"zh-CN":`撤销模型权限(推理 / 微调 / 部署)`},auth:`apiKey`,usageArgs:`--model <models> [--action <actions>] | --all --yes`,flags:{model:{type:`string`,valueHint:`<models>`,description:{"en-US":`Model ID(s), comma-separated (max 20)`,"zh-CN":`模型 ID,多个以逗号分隔(最多 20 个)`}},action:{type:`string`,valueHint:`<actions>`,description:{"en-US":`Permission action(s), comma-separated: inference, finetune, deploy (default: inference)`,"zh-CN":`权限操作,多个以逗号分隔:inference、finetune、deploy(默认:inference)`}},all:{type:`switch`,description:{"en-US":`Close one-key authorization and clear ALL historical inference grants`,"zh-CN":`关闭一键授权并清除所有历史推理授权`}},yes:{type:`switch`,description:{"en-US":`Confirm --all without an interactive prompt (required)`,"zh-CN":`无需交互提示确认执行 --all(必填)`}}},exampleArgs:[`--model qwen-plus`,`--model qwen-plus,qwen3-max --action inference,finetune`,`--all --yes`,`--model qwen-plus --dry-run --output json`],notes:[{"en-US":`Grants apply to the business workspace your API key belongs to.`,"zh-CN":`授权将应用于 API Key 所属的业务 Workspace。`},{"en-US":`--all maps to the server one-key switch (access_all_entities: CLOSE): it clears every historical inference grant and cannot be undone, so it requires --yes.`,"zh-CN":`--all 对应服务端一键授权开关(access_all_entities: CLOSE):它会清除所有历史推理授权且无法撤销,因此必须同时传入 --yes。`},{"en-US":`Actions you omit keep their current grants (server-side tri-state patch).`,"zh-CN":`未指定的操作将保留当前授权状态(服务端三态增量更新)。`}],validate:e=>xf(e),async run(e){let{flags:n,settings:r}=e;if(n.all&&!n.yes&&!r.dryRun)throw new t(`Refusing to clear all historical inference grants without confirmation.`,c.USAGE,`Re-run with --yes to close one-key authorization (or preview with --dry-run).`);await Sf(e,n,!1)}}),Tf=w({description:{"en-US":`Upload a dataset file (.jsonl or .zip) to Bailian`,"zh-CN":`将数据集文件(.jsonl 或 .zip)上传到百炼`},auth:`apiKey`,usageArgs:`--file <path> [--purpose <name>] [--schema <chatml|dpo|cpt|tts|image|video>] [--no-validate] [--full-validate]`,flags:{file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Local dataset file (.jsonl or .zip; ≤200MB SFT/DPO, ≤300MB CPT, ≤2GB media zip)`,"zh-CN":`本地数据集文件(.jsonl 或 .zip;SFT/DPO 不超过 200MB,CPT 不超过 300MB,媒体 ZIP 不超过 2GB)`},required:!0},purpose:{type:`string`,valueHint:`<name>`,description:{"en-US":`Dataset purpose tag (default: "fine-tune"; e.g. "evaluation")`,"zh-CN":`数据集用途标签(默认:"fine-tune";例如 "evaluation")`}},schema:{type:`string`,valueHint:`<s>`,description:{"en-US":`Record schema: "chatml" (SFT), "dpo" (chosen/rejected), "cpt" (raw text), "tts" (audio), "image" (image generation), or "video" (video generation). Default auto-detects per record.`,"zh-CN":`记录 Schema:"chatml"(SFT)、"dpo"(chosen/rejected)、"cpt"(原始文本)、"tts"(音频)、"image"(图片生成)或 "video"(视频生成)。默认逐条自动识别。`}},noValidate:{type:`switch`,description:{"en-US":`Skip the local JSONL pre-flight check (not recommended)`,"zh-CN":`跳过本地 JSONL 预检查(不推荐)`}},fullValidate:{type:`switch`,description:{"en-US":`JSON.parse every line instead of sampling (slower)`,"zh-CN":`使用 JSON.parse 检查每一行,而不是抽样检查(速度较慢)`}}},exampleArgs:[`--file train.jsonl`,`--file dpo.jsonl --schema dpo`,`--file cpt.jsonl --schema cpt`,`--file audio.zip --schema tts`,`--file eval.jsonl --purpose evaluation`,`--file train.jsonl --full-validate`,`--file train.jsonl --no-validate`],notes:[{"en-US":`Supports .jsonl (text) and .zip (audio/image/video archives with a data.jsonl manifest). Six record schemas are recognized: chatml = {messages:[...]} (SFT); dpo = {messages:[...], chosen, rejected}; cpt = {text:"..."} (continual pre-training, raw text); tts = {wav_fn:"train/xxx.wav", text:"..."} (audio fine-tuning); image = {img_path:"..."} (image generation); video = {first_frame_path:...} (video generation).`,"zh-CN":`支持 .jsonl(文本)和 .zip(包含 data.jsonl 清单的音频、图片或视频归档)。可识别六种记录 Schema:chatml = {messages:[...]}(SFT);dpo = {messages:[...], chosen, rejected};cpt = {text:"..."}(持续预训练,原始文本);tts = {wav_fn:"train/xxx.wav", text:"..."}(音频微调);image = {img_path:"..."}(图片生成);video = {first_frame_path:...}(视频生成)。`},{"en-US":`With no --schema, a record carrying wav_fn is validated as TTS, img_path as image, chosen/rejected as DPO, text (no messages) as CPT, otherwise ChatML.`,"zh-CN":`未指定 --schema 时,包含 wav_fn 的记录按 TTS 验证,包含 img_path 的按 image 验证,包含 chosen/rejected 的按 DPO 验证,仅含 text(无 messages)的按 CPT 验证,其他记录按 ChatML 验证。`},{"en-US":`Upload cap: 200MB SFT/DPO text, 300MB CPT, 2GB media zip. Upload uses the OpenAI-compatible /compatible-mode/v1/files endpoint so the purpose tag is persisted (the DashScope-native /api/v1/files drops it).`,"zh-CN":`上传上限:SFT/DPO 文本 200MB、CPT 300MB、媒体 ZIP 2GB。上传使用 OpenAI 兼容的 /compatible-mode/v1/files Endpoint,以便保留 purpose 标签;DashScope 原生 /api/v1/files 会丢弃该标签。`}],async run(e){let{identity:n,settings:r,flags:i}=e,a=i.file,o=i.purpose||`fine-tune`,s=Tt(i.schema),f=s===`image`||s===`video`?d:s===`cpt`?l:u;if(!i.noValidate){let e=await sn(a,{fullValidate:i.fullValidate,schema:s,maxBytes:f});if(!e.valid){let r=[`Dataset validation failed for ${a}`,...e.errors.slice(0,10).map(Fe)];throw e.errors.length>10&&r.push(` … and ${e.errors.length-10} more error(s).`),r.push(``,`Hint: re-run \`${n.binName} dataset validate --file <path>\` for the full report,`,` or pass --no-validate to skip this check at your own risk.`),new t(r.join(`
|
|
2795
|
+
`),c.GENERAL)}if(e.warnings.length>0&&!r.quiet){process.stderr.write(`Dataset validation passed with ${e.warnings.length} warning(s):\n`);for(let t of e.warnings.slice(0,5))process.stderr.write(`${Fe(t)}\n`);e.warnings.length>5&&process.stderr.write(` … and ${e.warnings.length-5} more.\n`)}}if(r.dryRun){A({action:`dataset.upload`,file:a,purpose:o,max_bytes:f,validate:!i.noValidate,schema:s??`auto`},`json`);return}let{request_id:p,...m}=await an(e.client,{filePath:a,purpose:o});r.quiet?k(m.file_id):A({...m,request_id:p},`json`)}}),Ef=w({description:{"en-US":`List uploaded dataset files`,"zh-CN":`列出已上传的数据集文件`},auth:`apiKey`,usageArgs:`[--page <n>] [--page-size <n>] [--purpose <name>]`,flags:{page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Results per page (default: 10, max 100)`,"zh-CN":`每页结果数(默认:10,最多:100)`}},purpose:{type:`string`,valueHint:`<name>`,description:{"en-US":`Filter by purpose (e.g. "fine-tune", "evaluation"). Omit to list all.`,"zh-CN":`按用途筛选(例如 "fine-tune"、"evaluation")。省略时列出全部。`}}},exampleArgs:[``,`--purpose fine-tune`,`--purpose evaluation --page-size 20`,`--output json`],async run(e){let{settings:t,flags:n}=e;if(t.dryRun){A({action:`dataset.list`,page:n.page,page_size:n.pageSize,purpose:n.purpose},`json`);return}let r=await at(e.client,{pageNo:n.page,pageSize:n.pageSize,purpose:n.purpose||void 0}),i=r.data?.files??[],a=r.data?.total,o=i.map(e=>({file_id:e.file_id??``,name:e.name??``,size:e.size===void 0?`?`:`${(e.size/1024).toFixed(1)} KB`,purpose:e.purpose??``}));if(t.quiet)for(let e of o)k(e.file_id);else A({items:o,total:a,request_id:r.request_id},`json`)}}),Df=w({description:{"en-US":`Get details of a single dataset file`,"zh-CN":`获取单个数据集文件的详情`},auth:`apiKey`,usageArgs:`--file-id <id>`,flags:{fileId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Dataset file ID (required)`,"zh-CN":`数据集文件 ID(必填)`},required:!0}},exampleArgs:[`--file-id file-xxx`,`--file-id file-xxx --output json`],async run(e){let{settings:t,flags:n}=e,r=n.fileId;if(t.dryRun){A({action:`dataset.get`,file_id:r},`json`);return}let i=await ze(e.client,r),a=i.data;if(!a){k(`No data returned for ${r}`);return}let o=a.size===void 0?`?`:`${(a.size/1024).toFixed(1)} KB`,s={file_id:a.file_id??r,name:a.name??``,size:o,md5:a.md5??``,purpose:a.purpose??``,created_at:a.gmt_create??``,description:a.description??``};t.quiet?k(s.file_id):A({...s,request_id:i.request_id},`json`)}}),Of=w({description:{"en-US":`Delete a dataset file by ID`,"zh-CN":`通过 ID 删除数据集文件`},auth:`apiKey`,usageArgs:`--file-id <id>`,flags:{fileId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Dataset file ID (required)`,"zh-CN":`数据集文件 ID(必填)`},required:!0}},exampleArgs:[`--file-id file-id-xxx`,`--file-id file-id-xxx --dry-run`],async run(e){let{settings:t,flags:n}=e,r=n.fileId;if(t.dryRun){A({action:`dataset.delete`,file_id:r},`json`);return}let i=await he(e.client,r);t.quiet?k(r):A(i,`json`)}}),kf=w({description:{"en-US":`Locally validate a dataset file (.jsonl or .zip) without uploading`,"zh-CN":`在本地验证数据集文件(.jsonl 或 .zip),不执行上传`},auth:`none`,usageArgs:`--file <path> [--full-validate] [--schema <chatml|dpo|cpt|tts|image|video>]`,flags:{file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Local dataset file (.jsonl or .zip)`,"zh-CN":`本地数据集文件(.jsonl 或 .zip)`},required:!0},fullValidate:{type:`switch`,description:{"en-US":`JSON.parse every line instead of sampling (slower)`,"zh-CN":`使用 JSON.parse 检查每一行,而不是抽样检查(速度较慢)`}},schema:{type:`string`,valueHint:`<s>`,description:{"en-US":`Record schema: "chatml" (SFT), "dpo" (chosen/rejected), "cpt" (raw text), "tts" (audio), "image" (image generation), or "video" (video generation). Default auto-detects per record.`,"zh-CN":`记录 Schema:"chatml"(SFT)、"dpo"(chosen/rejected)、"cpt"(原始文本)、"tts"(音频)、"image"(图片生成)或 "video"(视频生成)。默认逐条自动识别。`}}},exampleArgs:[`--file train.jsonl`,`--file dpo.jsonl --schema dpo`,`--file cpt.jsonl --schema cpt`,`--file audio.zip --schema tts`,`--file wan-i2v-training-dataset.zip --schema video`,`--file eval.jsonl --full-validate`,`--file train.jsonl --output json`],notes:[{"en-US":`Default scan: every line gets a structural check, then ~160 lines (front 50, evenly spaced 100, last 10) are JSON.parsed against the active schema.`,"zh-CN":`默认扫描:先对每一行进行结构检查,再抽取约 160 行(前 50 行、均匀抽取 100 行、最后 10 行),使用 JSON.parse 按当前 Schema 验证。`},{"en-US":`Schemas: chatml = {messages:[...]} (SFT); dpo = {messages:[...], chosen, rejected}; cpt = {text:"..."} (continual pre-training, raw text); tts = {wav_fn:"train/xxx.wav", text:"..."} (audio fine-tuning); image = {img_path:"..."} (image generation); video = {first_frame_path:"...", video_path:"..."} (video generation, i2v first-frame or kf2v first+last-frame with last_frame_path).`,"zh-CN":`Schema:chatml = {messages:[...]}(SFT);dpo = {messages:[...], chosen, rejected};cpt = {text:"..."}(持续预训练,原始文本);tts = {wav_fn:"train/xxx.wav", text:"..."}(音频微调);image = {img_path:"..."}(图片生成);video = {first_frame_path:"...", video_path:"..."}(视频生成,支持 i2v 首帧或通过 last_frame_path 指定 kf2v 首尾帧)。`},{"en-US":`With no --schema, a record carrying wav_fn is validated as TTS, img_path as image, first_frame_path/video_path as video, chosen/rejected as DPO, text (no messages) as CPT, otherwise ChatML. Pass --schema to require a specific shape on every record.`,"zh-CN":`未指定 --schema 时,包含 wav_fn 的记录按 TTS 验证,包含 img_path 的按 image 验证,包含 first_frame_path/video_path 的按 video 验证,包含 chosen/rejected 的按 DPO 验证,仅含 text(无 messages)的按 CPT 验证,其他记录按 ChatML 验证。使用 --schema 要求每条记录符合指定结构。`},{"en-US":`ZIP archives (.zip) are validated structurally (data.jsonl present, media references resolve) in addition to per-record content checks. Use --full-validate to JSON.parse every line.`,"zh-CN":`ZIP 归档(.zip)除逐条检查记录内容外,还会执行结构验证(存在 data.jsonl、媒体引用可解析)。使用 --full-validate 对每一行执行 JSON.parse。`}],async run(e){let{settings:n,flags:r}=e,i=r.file,a=Tt(r.schema);if(n.dryRun){A({action:`dataset.validate`,file:i,full:r.fullValidate,schema:a??`auto`},`json`);return}let o=await sn(i,{fullValidate:r.fullValidate,schema:a});if(n.quiet?k(o.valid?`ok`:`fail`):A(o,`json`),!o.valid)throw new t(`Dataset validation failed: ${o.errors.length} error(s).`,c.GENERAL)}});function Af(e){return Jn(e)&&Qn(e).isFile()}async function jf(e,n,r,i,a,o,s,l){let u=r.split(`,`).map(e=>e.trim()).filter(Boolean);if(u.length===0)throw new t(`--${i} must contain at least one entry.`,c.USAGE);let d=[],f=[],p,m,h=!0;for(let r of u){if(!Af(r)){d.push(r),h=!1;continue}if(d.push(r),f.push(r),e.dryRun)continue;let i=l&&l.path===r?l.modality:o,u=await a.validate(r,i,{model:s});if(!u.valid){let e=[`Dataset validation failed for ${r}`,...u.errors.slice(0,10).map(Fe)];throw u.errors.length>10&&e.push(` … and ${u.errors.length-10} more error(s).`),e.push(``,`Hint: re-run \`${n} dataset validate --file <path>\` for the full report,`,` or upload manually with \`${n} dataset upload --no-validate\` and`,` pass the resulting file-id here.`),new t(e.join(`
|
|
2796
|
+
`),c.GENERAL)}if(u.warnings.length>0&&!e.quiet){process.stderr.write(`Dataset validation passed with ${u.warnings.length} warning(s) for ${r}:\n`);for(let e of u.warnings.slice(0,5))process.stderr.write(`${Fe(e)}\n`);u.warnings.length>5&&process.stderr.write(` … and ${u.warnings.length-5} more.\n`)}let g=u.stats.totalRecords;typeof g==`number`&&(m=(m??0)+g),p===void 0&&(p=Qn(r).size)}return{fileIds:d,localPaths:f,firstSize:p,recordCount:h?m:void 0}}async function Mf(e,n,r,i,a){let o=[];for(let[s,l]of r.fileIds.entries()){if(!Af(l))continue;let u=await an(e,{filePath:l,purpose:i});if(!u.file_id)throw new t(`Upload of ${l} succeeded but no file_id was returned.`,c.GENERAL);o.push(u),r.fileIds[s]=u.file_id,n.quiet||process.stderr.write(`Uploaded ${er(l)} → ${u.file_id} (auto from --${a})\n`)}return o}const Nf={baseModel:{type:`string`,valueHint:`<model>`,description:{"en-US":`Base model to fine-tune (e.g. qwen3-8b; not the output model name)`,"zh-CN":`要微调的基础模型(例如 qwen3-8b;不是输出模型名称)`},required:!0},datasets:{type:`string`,valueHint:`<ids|paths>`,description:{"en-US":`Comma-separated dataset file IDs or local paths (.jsonl for text, .zip for audio/image/video). Local paths are uploaded (validated) first, then their file-ids are used.`,"zh-CN":`数据集文件 ID 或本地路径,以逗号分隔(文本使用 .jsonl,音频、图片和视频使用 .zip)。本地路径会先验证并上传,再使用对应的 file-id。`},required:!0},validations:{type:`string`,valueHint:`<ids|paths>`,description:{"en-US":`Comma-separated validation dataset file IDs or local paths (auto-uploaded like --datasets).`,"zh-CN":`验证数据集文件 ID 或本地路径,以逗号分隔(与 --datasets 一样自动上传)。`}},modelName:{type:`string`,valueHint:`<name>`,description:{"en-US":`Output model name (after training)`,"zh-CN":`训练完成后的输出模型名称`}},suffix:{type:`string`,valueHint:`<text>`,description:{"en-US":`Output suffix appended by the platform (finetuned_output_suffix)`,"zh-CN":`平台追加的输出后缀(finetuned_output_suffix)`}}},Pf={...Nf,trainingType:{type:`string`,valueHint:`<t>`,description:{"en-US":`Training type: ${v.join(` | `)} (default: ${o}). Mapping to the server happens at the interface boundary (e.g. sft-lora -> efficient_sft, dpo -> dpo_full).`,"zh-CN":`训练类型:${v.join(` | `)}(默认:${o})。在接口边界转换为服务端值(例如 sft-lora -> efficient_sft、dpo -> dpo_full)。`}},nEpochs:{type:`number`,valueHint:`<n>`,description:{"en-US":`Number of epochs (default: 3)`,"zh-CN":`训练轮数(默认:3)`}},batchSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Per-device batch size (clamped to [8, 1024]). Auto-set to 8 for small datasets (<100KB)`,"zh-CN":`单设备 Batch Size(限制在 [8, 1024])。小数据集(<100KB)自动设为 8`}},learningRate:{type:`string`,valueHint:`<str>`,description:{"en-US":`Learning rate as a string to preserve precision (e.g. "1.6e-5")`,"zh-CN":`以字符串形式指定学习率以保留精度(例如 "1.6e-5")`}},maxLength:{type:`number`,valueHint:`<n>`,description:{"en-US":`Max sequence length`,"zh-CN":`最大序列长度`}}},Ff={...Nf},If={...Nf,generationType:{type:`string`,choices:[`t2i`,`i2i`],valueHint:`<t2i|i2i>`,description:{"en-US":`Generation type: t2i (default) | i2i. Sets generation_type/max_pixels. Required to train I2I from a file-id or with --dry-run (local data auto-detects input_img).`,"zh-CN":`生成类型:t2i(默认)| i2i。用于设置 generation_type/max_pixels。通过 file-id 训练 I2I 或使用 --dry-run 时必填(本地数据会自动识别 input_img)。`}},learningRate:{type:`string`,valueHint:`<str>`,description:{"en-US":`Learning rate as a string to preserve precision (e.g. "3e-5")`,"zh-CN":`以字符串形式指定学习率以保留精度(例如 "3e-5")`}}},Lf={...Nf,nEpochs:{type:`number`,valueHint:`<n>`,description:{"en-US":`Training epochs (default: 50)`,"zh-CN":`训练轮数(默认:50)`}},batchSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Batch size (default: model-specific, 1 for wan2.7, 4 for wan2.5/2.2)`,"zh-CN":`Batch Size(默认值因模型而异:wan2.7 为 1,wan2.5/2.2 为 4)`}},learningRate:{type:`string`,valueHint:`<str>`,description:{"en-US":`Learning rate as a string to preserve precision (default: "2e-5")`,"zh-CN":`以字符串形式指定学习率以保留精度(默认:"2e-5")`}}},Rf=[{"en-US":`Creating a job uploads any local datasets and consumes training quota.`,"zh-CN":`创建任务会上传所有本地数据集并消耗训练额度。`},{"en-US":`Use --dry-run to preview the request body without submitting.`,"zh-CN":`使用 --dry-run 预览请求体,不实际提交。`},{"en-US":"--datasets / --validations accept either file-ids (from `dataset upload`) or local paths. Local paths are validated and uploaded first, then their file-ids are submitted — a one-step upload-and-train.","zh-CN":"--datasets / --validations 可接受 file-id(来自 `dataset upload`)或本地路径。本地路径会先验证并上传,再提交对应的 file-id,实现一步上传并训练。"}],zf=[...Rf,{"en-US":"Training-type values use the `<method>` / `<method>-lora` convention: sft (full) | sft-lora (LoRA) | dpo (full) | dpo-lora (LoRA) | cpt. These map to the server's training_type at the interface boundary, so the rest of the CLI never sees the raw server strings.","zh-CN":"训练类型遵循 `<method>` / `<method>-lora` 命名约定:sft(全量)| sft-lora(LoRA)| dpo(全量)| dpo-lora(LoRA)| cpt。这些值会在接口边界映射为服务端 training_type,因此 CLI 的其他部分不会接触服务端原始字符串。"},{"en-US":`Before submitting (non dry-run) the job, the model's training capability is checked via listFoundationModels (no console login required); an unsupported training type fails fast with the list the model actually supports.`,"zh-CN":`提交任务前(非 dry-run),会通过 listFoundationModels 检查模型训练能力(无需登录控制台);如果训练类型不受支持,会立即失败并列出该模型实际支持的训练类型。`},{"en-US":`n_epochs defaults to 3. Other hyper-parameters are platform defaults unless set.`,"zh-CN":`n_epochs 默认为 3。其他超参数未设置时使用平台默认值。`},{"en-US":`Learning rate is forwarded as a string to avoid JSON-number precision loss.`,"zh-CN":`学习率以字符串形式传递,避免 JSON 数字精度损失。`},{"en-US":`Pre-submit gate: if the training dataset's sample count is not greater than batch_size, the job is rejected before upload or quota consumption (the platform would otherwise fail ~10 min in, after data processing).`,"zh-CN":`提交前检查:如果训练数据集的样本数不大于 batch_size,会在上传或消耗额度前拒绝任务(否则平台会在数据处理约 10 分钟后才失败)。`}],Bf=[...Rf,{"en-US":`Audio TTS training runs sft-lora (efficient_sft) with fixed CosyVoice hyper-parameter defaults; there are no training-type or hyper-parameter knobs to set.`,"zh-CN":`音频 TTS 训练使用 sft-lora(efficient_sft)和固定的 CosyVoice 超参数默认值;没有可设置的训练类型或超参数选项。`}],Vf=[...Rf,{"en-US":`Image generation training runs sft-lora (efficient_sft) with fixed defaults; only --learning-rate is overridable. T2I vs I2I is declared with --generation-type (default t2i), which sets generation_type/max_pixels. For local data the type is auto-detected (records with input_img train I2I); pass --generation-type explicitly to train I2I from a file-id or in --dry-run.`,"zh-CN":`图片生成训练使用 sft-lora(efficient_sft)和固定默认值;仅 --learning-rate 可覆盖。通过 --generation-type(默认 t2i)声明 T2I 或 I2I,并设置 generation_type/max_pixels。本地数据会自动识别类型(包含 input_img 的记录训练 I2I);通过 file-id 训练 I2I 或使用 --dry-run 时,请显式传入 --generation-type。`}];async function Hf(e,n){let{identity:r,settings:i}=n,a=n.flags,s=a.baseModel,l=a.datasets;if(e===`audio`){let e=l.split(`,`).map(e=>e.trim()).filter(Boolean);if(e.length>1)throw new t(`Audio (TTS) fine-tuning accepts exactly one training file, got ${e.length}.`,c.USAGE,`Merge your recordings into a single .zip (or pass one file-id).`)}let u=a.trainingType||o;if(!$e(u))throw new t(`--training-type "${u}" is not supported.`,c.USAGE,`Supported values: ${v.join(`, `)} (default: ${o}).`);let d=Ge(u),f=l.split(`,`).map(e=>e.trim()).find(e=>Af(e)),p=e;if(e===`image`){let e=a.generationType;(e===`i2i`||!e&&f&&!i.dryRun&&await ye(f)===`image-i2i`)&&(p=`image-i2i`)}e===`video`&&f&&!i.dryRun&&await ye(f)===`video-kf2v`&&(p=`video-kf2v`);let m=await jf(i,r.binName,l,`datasets`,d,p,s,f?{path:f,modality:p}:void 0),h=m.fileIds,g=a.validations?await jf(i,r.binName,a.validations,`validations`,d,p,s):void 0,_=g?.fileIds,y=a.modelName,b=a.suffix,x=d.resolveHyperParameters(p,a);if(a.batchSize!==void 0&&x.batch_size!==void 0&&!i.quiet&&!d.shouldSkipGate(`batch_size`,p)){let e=a.batchSize;x.batch_size!==e&&process.stderr.write(`warning: --batch-size ${e} clamped to ${x.batch_size} (server range [8, 1024] for the common training types).\n`)}if(a.batchSize!==void 0&&!i.quiet&&d.shouldSkipGate(`batch_size`,p)){let e=a.batchSize;x.batch_size!==void 0&&x.batch_size!==e&&process.stderr.write(`warning: --batch-size ${e} ignored for ${p} training (model uses a fixed batch_size of ${x.batch_size}).\n`)}if(p===`text`&&x.batch_size===void 0&&!i.dryRun){let e=m.firstSize??0;if(e===0)try{e=(await ze(n.client,h[0])).data?.size??0}catch{}e>0&&e<100*1024&&(x.batch_size=8)}if(!i.dryRun&&m.recordCount!==void 0&&!d.shouldSkipGate(`batch_size`,p)){let e=x.batch_size??16,n=kt({recordCount:m.recordCount,batchSize:e});if(!n.ok&&n.issue)throw new t(n.issue.message,c.GENERAL,n.hint)}if(!i.dryRun&&!d.shouldSkipCapabilityCheck(p)){let e;try{e=await Ee(i,s)}catch(e){i.quiet||process.stderr.write(`warning: model capability lookup failed (${e.message}); proceeding without local pre-flight.
|
|
2797
|
+
`)}if(e&&!dt(e).includes(u)){let n=dt(e);throw new t(`Model "${s}" does not support training type "${u}".`,c.USAGE,n.length?`This model supports: ${n.join(`, `)}.`:`This model reports no supported training types.`)}}i.dryRun||(await Mf(n.client,i,m,`fine-tune`,`datasets`),g&&await Mf(n.client,i,g,`fine-tune`,`validations`));let S={model:s,training_file_ids:h,training_type:d.serverTrainingType,hyper_parameters:x};if(_&&_.length>0&&(S.validation_file_ids=_),y&&(S.model_name=y),b&&(S.finetuned_output_suffix=b),i.dryRun){let e=[...m.localPaths.map(e=>({field:`datasets`,path:e})),...(g?.localPaths??[]).map(e=>({field:`validations`,path:e}))];A(e.length>0?{action:`finetune.create`,body:S,pending_uploads:e}:{action:`finetune.create`,body:S},`json`);return}let C=await de(n.client,S),ee=C.output??C.data;i.quiet?ee?.job_id&&k(ee.job_id):A(C,`json`)}const Uf=w({description:{"en-US":`Create a text model fine-tune job (sft | sft-lora | dpo | dpo-lora | cpt)`,"zh-CN":`创建文本模型微调任务(sft | sft-lora | dpo | dpo-lora | cpt)`},auth:`apiKey`,usageArgs:`--base-model <model> --datasets <id|path,...> [--validations <id|path,...>] [--model-name <name>] [--suffix <text>] [--n-epochs <n>] [--batch-size <n>] [--learning-rate <str>] [--max-length <n>] [--training-type <sft|sft-lora|dpo|dpo-lora|cpt>]`,flags:Pf,exampleArgs:[`--base-model qwen3-8b --datasets file-xxx`,`--base-model qwen3-8b --datasets ./train.jsonl`,`--base-model qwen3-8b --datasets ./train.jsonl --validations ./eval.jsonl`,`--base-model qwen3-8b --datasets file-aaa,./extra.jsonl`,`--base-model qwen3-8b --datasets ./train.jsonl --training-type sft`,`--base-model qwen3-8b --datasets file-xxx --learning-rate "1.6e-5" --n-epochs 4`,`--base-model qwen3-8b --datasets file-xxx --output json`,`--base-model qwen3-8b --datasets file-xxx --dry-run`],notes:zf,run:e=>Hf(`text`,e)}),Wf=w({description:{"en-US":`Create an audio TTS model fine-tune job (sft-lora)`,"zh-CN":`创建音频 TTS 模型微调任务(sft-lora)`},auth:`apiKey`,usageArgs:`--base-model <model> --datasets <id|path> [--validations <id|path>] [--model-name <name>] [--suffix <text>]`,flags:Ff,exampleArgs:[`--base-model cosyvoice-v3-flash --datasets ./audio.zip`,`--base-model cosyvoice-v3-flash --datasets file-xxx`,`--base-model cosyvoice-v3-flash --datasets ./audio.zip --model-name my-tts`,`--base-model cosyvoice-v3-flash --datasets file-xxx --output json`,`--base-model cosyvoice-v3-flash --datasets ./audio.zip --dry-run`],notes:Bf,run:e=>Hf(`audio`,e)}),Gf=w({description:{"en-US":`Create an image generation model fine-tune job (sft-lora)`,"zh-CN":`创建图片生成模型微调任务(sft-lora)`},auth:`apiKey`,usageArgs:`--base-model <model> --datasets <id|path> [--validations <id|path>] [--model-name <name>] [--suffix <text>] [--generation-type <t2i|i2i>] [--learning-rate <str>]`,flags:If,exampleArgs:[`--base-model wan2.7-image-pro --datasets ./images.zip`,`--base-model wan2.7-image-pro --datasets file-xxx`,`--base-model wan2.7-image-pro --datasets file-xxx --generation-type i2i`,`--base-model wan2.7-image-pro --datasets ./images.zip --model-name my-wan`,`--base-model wan2.7-image-pro --datasets file-xxx --output json`,`--base-model wan2.7-image-pro --datasets ./images.zip --dry-run`],notes:Vf,run:e=>Hf(`image`,e)}),Kf=w({description:{"en-US":`Create a video generation model fine-tune job (Wan i2v/kf2v, efficient_sft)`,"zh-CN":`创建视频生成模型微调任务(Wan i2v/kf2v,efficient_sft)`},auth:`apiKey`,usageArgs:`--base-model <model> --datasets <id|path> [--validations <id|path>] [--model-name <name>] [--suffix <text>] [--n-epochs <n>] [--batch-size <n>] [--learning-rate <str>]`,flags:Lf,exampleArgs:[`--base-model wan2.7-i2v --datasets file-xxx`,`--base-model wan2.7-i2v --datasets ./i2v-data.zip`,`--base-model wan2.2-kf2v-flash --datasets file-xxx --n-epochs 100`,`--base-model wan2.7-i2v --datasets file-xxx --dry-run`],notes:[...Rf,{"en-US":`Video generation training (Wan i2v/kf2v) runs efficient_sft with model-specific defaults: wan2.7 (batch_size=1, max_pixels=102400), wan2.5/2.2 (batch_size=4, max_pixels per model). Override with --batch-size/--n-epochs.`,"zh-CN":`视频生成训练(Wan i2v/kf2v)使用 efficient_sft 和模型专属默认值:wan2.7(batch_size=1、max_pixels=102400),wan2.5/2.2(batch_size=4,max_pixels 因模型而异)。可通过 --batch-size/--n-epochs 覆盖。`},{"en-US":`Datasets are .zip archives with data.jsonl + frame images + videos.`,"zh-CN":`数据集为包含 data.jsonl、帧图片和视频的 .zip 归档。`},{"en-US":`Recommended: ≥10 training samples, 20-100 for stable results.`,"zh-CN":`建议至少准备 10 个训练样本;20–100 个样本可获得更稳定的效果。`}],run:e=>Hf(`video`,e)});var qf=w({description:{"en-US":`List fine-tune jobs`,"zh-CN":`列出微调任务`},auth:`apiKey`,usageArgs:`[--page <n>] [--page-size <n>] [--status <s>] [--base-model <model>]`,flags:{page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Results per page (default: 10, max 100)`,"zh-CN":`每页结果数(默认:10,最多:100)`}},status:{type:`string`,valueHint:`<s>`,description:{"en-US":`Filter by status (PENDING / RUNNING / SUCCEEDED / FAILED / CANCELED)`,"zh-CN":`按状态筛选(PENDING / RUNNING / SUCCEEDED / FAILED / CANCELED)`}},baseModel:{type:`string`,valueHint:`<model>`,description:{"en-US":`Filter by base model ID (server-side)`,"zh-CN":`按基础模型 ID 筛选(服务端筛选)`}}},exampleArgs:[``,`--status RUNNING`,`--base-model qwen3-8b`,`--page-size 20`],async run(e){let{settings:t,flags:n}=e,r=n.page,i=n.pageSize,a=n.status||void 0,o=n.baseModel||void 0;if(t.dryRun){A({action:`finetune.list`,page:r,page_size:i,status:a,model:o},`json`);return}let s=await ct(e.client,{pageNo:r,pageSize:i,status:a,model:o}),c=s.output??s.data,l=c?.jobs??[],u=c?.total;A({items:l.map(e=>({job_id:e.job_id??``,base_model:e.model??``,status:e.status??``,training_type:e.training_type??``,output_model:e.finetuned_output??``,created_at:e.create_time??e.gmt_create??``})),total:u,request_id:s.request_id},`json`)}});async function Jf(e,t){let n=be(e),r=nn(await ie({region:n.consoleRegion,site:n.consoleSite,switchAgent:n.consoleSwitchAgent},e.timeout,{api:f,data:{input:{pageNo:1,pageSize:10,group:!0,model:t,queryPrice:!0,querySampleCode:!1,queryGroupByModel:!0,queryQuota:!1,queryQpmInfo:!1,queryApplyStatus:!1,queryPermissions:!1,queryActivationStatus:!1}}})).list??[];for(let e of r){let n=e.items??[];for(let e of n)if(e.model===t)return(e.prices??[]).find(e=>e.type===`ft`)??null;if(e.model===t)return(e.prices??[]).find(e=>e.type===`ft`)??null}return null}async function Yf(e,t,n){try{let r=await Jf(e,t),i=Number(r?.price);if(!Number.isFinite(i)||i<=0)return null;let a=r?.priceUnit??`每百万tokens`,o=n/1e6*i;return{cost:Number(o.toFixed(4)),unitPrice:i,priceUnit:a}}catch{return null}}var Xf=w({description:{"en-US":`Get details of a single fine-tune job`,"zh-CN":`获取单个微调任务的详情`},auth:`apiKey`,usageArgs:`--job-id <id>`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Fine-tune job ID (required)`,"zh-CN":`微调任务 ID(必填)`},required:!0}},exampleArgs:[`--job-id ft-xxx`,`--job-id ft-xxx --output json`],async run(e){let{settings:t,flags:n}=e,r=n.jobId;if(t.dryRun){A({action:`finetune.get`,job_id:r},`json`);return}let i=await Ve(e.client,r),a=i.output??i.data;if(!a){A({job_id:r,error:`No data returned`},`json`);return}let o=a.hyper_parameters,s=[];o?.n_epochs!==void 0&&s.push(`n_epochs=${o.n_epochs}`),o?.batch_size!==void 0&&s.push(`batch_size=${o.batch_size}`),o?.learning_rate!==void 0&&s.push(`learning_rate=${o.learning_rate}`),o?.max_length!==void 0&&s.push(`max_length=${o.max_length}`);let c=typeof a.usage==`number`?a.usage:void 0,l={job_id:a.job_id??r,base_model:a.model??``,status:a.status??``,training_type:a.training_type??``,training_files:a.training_file_ids??[],validation_files:a.validation_file_ids??[],hyper_params:s.length?s.join(` · `):``,output_model:a.finetuned_output??``,model_name:a.model_name??``,created_at:a.create_time??a.gmt_create??``,updated_at:a.end_time??a.gmt_modified??``,usage_tokens:c??``,charge_type:typeof a.charge_type==`string`?a.charge_type:``};if(c!==void 0&&c>0&&a.model){let e=await Yf(t,a.model,c);e&&(l.training_cost=e.cost,l.cost_basis=`${e.unitPrice} 元/${e.priceUnit}`)}A({...l,request_id:i.request_id},`json`)}}),Zf=w({description:{"en-US":`Cancel a running fine-tune job`,"zh-CN":`取消正在运行的微调任务`},auth:`apiKey`,usageArgs:`--job-id <id>`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Fine-tune job ID (required)`,"zh-CN":`微调任务 ID(必填)`},required:!0}},exampleArgs:[`--job-id ft-xxx`,`--job-id ft-xxx --dry-run`],notes:[{"en-US":`Only PENDING / RUNNING jobs can be cancelled. Completed / failed / already-cancelled jobs return a server-side error (passed through verbatim).`,"zh-CN":`只有 PENDING / RUNNING 状态的任务可以取消。已完成、失败或已取消的任务会返回服务端错误(原样透传)。`}],async run(e){let{settings:t,flags:n}=e,r=n.jobId;if(t.dryRun){A({action:`finetune.cancel`,job_id:r},`json`);return}let i=await ae(e.client,r);t.quiet?k(r):A(i,`json`)}}),Qf=w({description:{"en-US":`Delete a fine-tune job record`,"zh-CN":`删除微调任务记录`},auth:`apiKey`,usageArgs:`--job-id <id>`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Fine-tune job ID (required)`,"zh-CN":`微调任务 ID(必填)`},required:!0}},exampleArgs:[`--job-id ft-xxx`,`--job-id ft-xxx --dry-run`],notes:[{"en-US":"Cancel a RUNNING job first via `finetune cancel` — the platform refuses to delete jobs that are still in flight.","zh-CN":"请先通过 `finetune cancel` 取消 RUNNING 任务,平台拒绝删除仍在运行的任务。"}],async run(e){let{settings:t,flags:n}=e,r=n.jobId;if(t.dryRun){A({action:`finetune.delete`,job_id:r},`json`);return}let i=await _e(e.client,r);t.quiet?k(r):A(i,`json`)}});function $f(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 ep(e,t){return $f(e).toLowerCase().includes(t)}async function tp(e,t,n){let r=[],i=1,a=0;for(let o=0;o<200;o++){let o=await He(e,t,{pageNo:i,pageSize:n}),s=o.output??o.data,c=s?.logs??[];if(a=s?.total??a,c.length===0||(r.push(...c),a&&r.length>=a)||c.length<n)break;i++}return{entries:r,total:a}}var np=w({description:{"en-US":`Fetch training logs for a fine-tune job`,"zh-CN":`获取微调任务的训练日志`},auth:`apiKey`,usageArgs:`--job-id <id> [--page <n>] [--page-size <n>] [--search <keyword>] [--tail <n>]`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Fine-tune job ID (required)`,"zh-CN":`微调任务 ID(必填)`},required:!0},page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Lines per page (default: server-defined)`,"zh-CN":`每页行数(默认:由服务端决定)`}},search:{type:`string`,valueHint:`<keyword>`,description:{"en-US":`Case-insensitive substring filter. When set, all log pages are fetched and filtered client-side (--page is ignored).`,"zh-CN":`不区分大小写的子字符串筛选。设置后会获取全部日志页并在客户端筛选(忽略 --page)。`}},tail:{type:`number`,valueHint:`<n>`,description:{"en-US":`Keep only the last N entries. When set, all log pages are fetched and the trailing N are kept (--page is ignored).`,"zh-CN":`仅保留最后 N 条记录。设置后会获取全部日志页并保留末尾 N 条(忽略 --page)。`}}},exampleArgs:[`--job-id ft-xxx`,`--job-id ft-xxx --page-size 100 --output json`,`--job-id ft-xxx --search checkpoint`,`--job-id ft-xxx --search error --output json`,`--job-id ft-xxx --tail 20`,`--job-id ft-xxx --search checkpoint --tail 5`],async run(e){let{settings:t,flags:n}=e,r=n.jobId,i=n.page,a=n.pageSize,o=n.search||void 0,s=n.tail;if(t.dryRun){A({action:`finetune.logs`,job_id:r,page:i,page_size:a,search:o,tail:s},`json`);return}if(o||s!==void 0){let{entries:t,total:n}=await tp(e.client,r,a??100),i=t,c;if(o){let e=o.toLowerCase();i=t.filter(t=>ep(t,e)),c=i.length}let l=s!==void 0&&s>=0?Math.min(s,i.length):void 0,u=l===void 0?i:i.slice(i.length-l);A({...c===void 0?{}:{matched:c},scanned:t.length,total:n||t.length,...o?{search:o}:{},...l===void 0?{}:{tail:l},logs:u},`json`);return}A(await He(e.client,r,{pageNo:i,pageSize:a}),`json`)}}),rp=w({description:{"en-US":`List checkpoints produced by a fine-tune job`,"zh-CN":`列出微调任务生成的 Checkpoint`},auth:`apiKey`,usageArgs:`--job-id <id>`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Fine-tune job ID (required)`,"zh-CN":`微调任务 ID(必填)`},required:!0}},exampleArgs:[`--job-id ft-xxx`,`--job-id ft-xxx --output json`],notes:[{"en-US":"`model_name` (shown for SUCCEEDED checkpoints) is the direct input for `deploy create --model-name`.","zh-CN":"SUCCEEDED Checkpoint 中显示的 `model_name` 可直接作为 `deploy create --model-name` 的输入。"},{"en-US":"Checkpoints expire ~15 days after creation; `expire_time` shows the deadline. Export or deploy before expiry.","zh-CN":"Checkpoint 创建后约 15 天过期,`expire_time` 显示截止时间。请在过期前导出或部署。"}],async run(e){let{settings:t,flags:n}=e,r=n.jobId;if(t.dryRun){A({action:`finetune.checkpoints`,job_id:r},`json`);return}let i=await it(e.client,r),a=i.output??i.data,o=Array.isArray(a)?a:a?.checkpoints??[],s=Array.isArray(a)?a.length:a?.total??o.length,c=o.map(e=>({checkpoint:e.checkpoint??e.checkpoint_id??``,step:e.step===void 0?``:String(e.step),status:e.status??``,model_name:e.model_name??``,expire_time:e.expire_time??``}));A({items:c,total:s,request_id:i.request_id},`json`);let l=Date.now(),u=c.filter(e=>{if(!e.expire_time)return!1;let t=new Date(e.expire_time).getTime();if(Number.isNaN(t))return!1;let n=t-l;return n>0&&n<2592e5});u.length>0&&process.stderr.write(`\n[warning] ${u.length} checkpoint(s) will expire within 72 hours. Export or deploy before expiry to avoid losing the model artifact.
|
|
2798
|
+
`)}}),ip=w({description:{"en-US":`Publish a checkpoint as a deployable model`,"zh-CN":`将 Checkpoint 发布为可部署模型`},auth:`apiKey`,usageArgs:`--job-id <id> --checkpoint <name> --model-name <name>`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Fine-tune job ID (required)`,"zh-CN":`微调任务 ID(必填)`},required:!0},checkpoint:{type:`string`,valueHint:`<name>`,description:{"en-US":"Checkpoint identifier from `finetune checkpoints` (required)","zh-CN":"来自 `finetune checkpoints` 的 Checkpoint 标识(必填)"},required:!0},modelName:{type:`string`,valueHint:`<name>`,description:{"en-US":`Deployable model name (required)`,"zh-CN":`可部署模型名称(必填)`},required:!0}},exampleArgs:[`--job-id ft-xxx --checkpoint ckpt-3 --model-name my-qwen-sft`],notes:[{"en-US":"Required before `deploy <modality> create` can target a checkpoint. The platform may auto-export the best checkpoint when a job reaches SUCCEEDED — explicit export is the canonical path for non-best checkpoints.","zh-CN":"必须先执行此操作,`deploy <modality> create` 才能使用 Checkpoint。任务达到 SUCCEEDED 后,平台可能自动导出最佳 Checkpoint;对于非最佳 Checkpoint,显式导出是标准方式。"}],async run(e){let{settings:t,flags:n}=e,r=n.jobId,i=n.checkpoint,a=n.modelName;if(t.dryRun){A({action:`finetune.export`,job_id:r,checkpoint:i,model_name:a},`json`);return}let o=await Ce(e.client,r,i,a),s=(o.output??o.data)?.model_name??a;t.quiet?k(s):A(o,`json`)}});const ap=new Set([`SUCCEEDED`,`FAILED`,`CANCELED`]);function op(){let e=new Date,t=e=>String(e).padStart(2,`0`);return`${t(e.getHours())}:${t(e.getMinutes())}:${t(e.getSeconds())}`}function sp(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 cp(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 lp=w({description:{"en-US":`Probe a fine-tune job's status (default: single non-blocking fetch). Pass --follow to poll until terminal.`,"zh-CN":`查询微调任务状态(默认:单次非阻塞获取)。使用 --follow 持续轮询至终态。`},auth:`apiKey`,usageArgs:`--job-id <id> [--follow] [--interval <sec>] [--poll-timeout <sec>]`,flags:{jobId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Fine-tune job ID (required)`,"zh-CN":`微调任务 ID(必填)`},required:!0},follow:{type:`switch`,description:{"en-US":`Block and poll until a terminal state (the legacy behavior). Without it, a single status probe is performed and the command returns immediately.`,"zh-CN":`阻塞并轮询至终态(旧版行为)。不使用时仅查询一次状态并立即返回。`}},interval:{type:`number`,valueHint:`<sec>`,description:{"en-US":`Seconds between polls with --follow (default: 10, min: 1). Ignored without --follow.`,"zh-CN":`使用 --follow 时的轮询间隔秒数(默认:10,最小:1)。未使用 --follow 时忽略。`}},pollTimeout:{type:`number`,valueHint:`<sec>`,description:{"en-US":`With --follow, stop polling after this many seconds (default: no limit). Ignored without --follow.`,"zh-CN":`使用 --follow 时,在指定秒数后停止轮询(默认:无限制)。未使用 --follow 时忽略。`}}},exampleArgs:[{"en-US":`--job-id ft-xxx # single probe, returns immediately`,"zh-CN":`--job-id ft-xxx # 单次查询,立即返回`},{"en-US":`--job-id ft-xxx --output json # status probe for agents`,"zh-CN":`--job-id ft-xxx --output json # 供智能体查询状态`},{"en-US":`--job-id ft-xxx --follow # block until terminal`,"zh-CN":`--job-id ft-xxx --follow # 阻塞等待至终态`},`--job-id ft-xxx --follow --interval 5`,`--job-id ft-xxx --follow --poll-timeout 3600`],notes:[{"en-US":`Default (no --follow) is a NON-BLOCKING single status probe: one fetch, then return immediately. This is the mode meant for agents / scripts — the caller owns the polling cadence, so the CLI never holds the terminal.`,"zh-CN":`默认不使用 --follow,执行非阻塞的单次状态查询:获取一次后立即返回。该模式适用于 Agent / 脚本,由调用方控制轮询节奏,CLI 不会持续占用终端。`},{"en-US":`A terminal FAILED/CANCELED status raises a normal CLI error (non-zero exit); a SUCCEEDED or still-running status returns 0. With --follow, exceeding --poll-timeout raises a timeout error.`,"zh-CN":`终态 FAILED/CANCELED 会触发普通 CLI 错误(非零退出码);SUCCEEDED 或仍在运行时返回 0。使用 --follow 时,超过 --poll-timeout 会触发超时错误。`},{"en-US":`Use --follow for the blocking, human-terminal-follow experience; use the default mode when driving the loop yourself (e.g. from an agent).`,"zh-CN":`需要在人工终端中阻塞跟踪时使用 --follow;自行驱动轮询(例如通过 Agent)时使用默认模式。`},{"en-US":"For per-step training output (not status), use `finetune logs`.","zh-CN":"要查看逐步骤训练输出(而非状态),请使用 `finetune logs`。"}],async run(e){let{settings:n,flags:r}=e,i=r.jobId,a=r.follow,o=Math.max(1,r.interval??10),s=r.pollTimeout;if(n.dryRun){A({action:`finetune.watch`,job_id:i,follow:a,interval:o,timeout:s},`json`);return}if(!a){let r=await Ve(e.client,i),a=r.output??r.data,o=String(a?.status??``).toUpperCase(),s=ap.has(o);if(n.quiet)k(o||`UNKNOWN`);else{let e={job_id:i,status:o||`UNKNOWN`,terminal:s,request_id:r.request_id},t=typeof a?.usage==`number`?a.usage:void 0;if(s&&t&&t>0&&a?.model){e.usage_tokens=t;let r=await Yf(n,a.model,t);r&&(e.training_cost=r.cost,e.cost_basis=`${r.unitPrice} 元/${r.priceUnit}`)}A(e,`json`)}if(s&&o!==`SUCCEEDED`)throw new t(`Fine-tune job ${i} ended in status ${o}.`,c.GENERAL);return}let l=new AbortController,u=()=>l.abort();process.on(`SIGINT`,u);try{let r=``,a=Date.now();for(;;){let u=await Ve(e.client,i,l.signal),d=u.output??u.data,f=String(d?.status??``).toUpperCase();if(!n.quiet&&f!==r&&(process.stderr.write(`${op()} ${i} ${f||`UNKNOWN`}\n`),r=f),ap.has(f)){let e=Date.now()-a;if(n.quiet)k(f||`UNKNOWN`);else{let e=typeof d?.usage==`number`?d.usage:void 0,t={...u};if(e&&e>0&&d?.model){let r=await Yf(n,d.model,e);r&&(t.training_cost=r.cost,t.usage_tokens=e,t.cost_basis=`${r.unitPrice} 元/${r.priceUnit}`)}A(t,`json`)}if(f!==`SUCCEEDED`)throw new t(`Fine-tune job ${i} ended in status ${f} (elapsed ${sp(e)}).`,c.GENERAL);return}if(s!==void 0&&(Date.now()-a)/1e3>=s)throw new t(`Watching fine-tune job ${i} timed out after ${sp(Date.now()-a)} (last status: ${f||`UNKNOWN`}).`,c.TIMEOUT);await cp(o*1e3,l.signal)}}catch(e){if(l.signal.aborted){process.stderr.write(`
|
|
2718
2799
|
Interrupted.
|
|
2719
|
-
`);return}throw e}finally{process.off(`SIGINT`,u)}}});async function tp(e){return await De(y(e))}var np=w({description:`Query fine-tune training capability — by model (which training types it supports) or by training type (which models support it)`,auth:`none`,usageArgs:`--base-model <m> | --training-type <t>`,flags:{baseModel:{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: ${g.join(` | `)}.`}},exampleArgs:[`--base-model qwen3-8b`,`--training-type sft-lora`,`--training-type cpt --output json`,`--training-type sft --quiet`],notes:[`Exactly one of --base-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.baseModel&&e.trainingType)return`--base-model and --training-type are mutually exclusive; pass one.`;if(!e.baseModel&&!e.trainingType)return`one of --base-model / --training-type is required.`},async run(e){let{settings:t,flags:n}=e,r=n.baseModel||void 0,i=n.trainingType||void 0;if(t.dryRun){A({action:`finetune.capability`,model:r,training_type:i},`json`);return}if(r){let e=await we(t,r);if(!e){A({model:r,error:`No foundation model found matching "${r}".`},`json`);return}let n=lt(e);if(t.quiet){for(let e of n)k(e);return}A({model:e.model??r,supported:n,supports:e.supports,trainingTypes:e.trainingTypes},`json`);return}if(!i||!Ze(i))throw new _(`--training-type "${i}" is not supported. Valid: ${g.join(`, `)}.`);let{method:a,variant:o}=Qt(i),s=(await tp(t)).filter(e=>vt(e,i)).map(e=>({model:e.model,name:e.name??e.model})).filter(e=>!!e.model).sort((e,t)=>e.model.localeCompare(t.model));if(t.quiet){for(let e of s)k(e.model);return}A({training_type:i,method:a,variant:o,count:s.length,models:s},`json`)}});const rp={baseModel:{type:`string`,valueHint:`<model>`,description:`Base model to fine-tune (e.g. qwen3-8b; not the output model name)`,required:!0},datasets:{type:`string`,valueHint:`<ids>`,description:`Training dataset file IDs, comma-separated (required)`,required:!0},trainingType:{type:`string`,valueHint:`<type>`,description:`Training type: sft | dpo | cpt (default: sft)`},nEpochs:{type:`number`,valueHint:`<n>`,description:`Number of training epochs (default: 3)`}},ip=[`sft`,`dpo`,`cpt`];var ap=w({description:`Estimate the training cost for a fine-tune job (token billing)`,auth:`console`,usageArgs:`--base-model <model> --datasets <ids> [--training-type <type>] [--n-epochs <n>]`,flags:rp,exampleArgs:[`--base-model qwen3-8b --datasets file-ft-xxx`,`--base-model qwen3-8b --datasets file-ft-xxx,file-ft-yyy --n-epochs 2`,`--base-model qwen3-8b --datasets file-ft-xxx --training-type cpt`],notes:[`Estimate only — the server computes token usage from the datasets; final cost is subject to the bill.`,`Covers token billing for sft / dpo / cpt. Training-unit (MTU) billing is not supported by this command.`,`Hyper-parameters other than --n-epochs are fixed at representative defaults for estimation.`],async run(e){let{settings:n,flags:r}=e,i=r.baseModel,a=r.datasets.split(`,`).map(e=>e.trim()).filter(Boolean),o=(r.trainingType??`sft`).toLowerCase(),c=r.nEpochs??3;if(!ip.includes(o))throw new t(`Unsupported training type "${o}". Supported: ${ip.join(`, `)}.`,s.USAGE);if(a.length===0)throw new t(`--datasets must contain at least one file ID.`,s.USAGE);if(n.dryRun){A({action:`finetune.price`,model:i,datasets:a,trainingType:o,nEpochs:c},`json`);return}let l=await Ae(e.client,i),u=Number(l.price);if(!Number.isFinite(u))throw new t(`No training price found for model "${i}".`,s.GENERAL,void 0,{rawResponse:JSON.stringify(l)});let d=o===`cpt`?await ye(e.client,i,a.join(`,`),c):await be(e.client,a,{nEpochs:c,batchSize:16,maxLength:8192}),f=d.estimatedDatasetConsumedTokensMinPerEpoch??0,p=d.estimatedDatasetConsumedTokensMaxPerEpoch??0,m=d.estimatedMixedConsumedTokensMinPerEpoch??0,h=d.estimatedMixedConsumedTokensMaxPerEpoch??0,g=(f+m)*c,_=(p+h)*c,v=g/1e3*u,y=_/1e3*u;A({model:i,training_type:o,n_epochs:c,unit_price:u,price_unit:l.priceUnit??`千Token`,estimated_tokens:{min:g,max:_},estimated_fee_yuan:{min:Number(v.toFixed(4)),max:Number(y.toFixed(4))},disclaimer:`Server-side estimate; final cost is subject to the bill.`},`json`)}});const op={modelName:{type:`string`,valueHint:`<model_name>`,description:`Model to deploy — fine-tuned output name or catalog model (required)`,required:!0},displayName:{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`},deploySpec:{type:`string`,valueHint:`<id>`,description:`Deploy spec (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)`}},sp=`--model-name <model_name> --display-name <display_name> [--plan <plan>] [--deploy-spec <id>] [--capacity <n>] [--billing-method <m>] [--input-tpm <n>] [--output-tpm <n>] [--thinking-output-tpm <n>]`,cp=["Plan defaults to `lora` (Token-billed) for text/image and `mu` (model-unit-",`billed) for audio (CosyVoice TTS). 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 `deploy_spec` are required.",`billing_method defaults to POST_PAY (only supported value); deploy_spec`,`and capacity are auto-picked from GET /deployments/models when omitted.`,"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>`,"NOTE: --model-name is the model being deployed (e.g. `qwen3-8b-ft-...`).","The create response also returns a `deployed_model` field — the deployment","instance id (e.g. `qwen3-8b-5ecb5f068d79`). Use that id for inference","(`bl text chat --model <deployed_model>`) and lifecycle commands","(`deploy get/scale/pause/resume/delete --deployed-model <id>`)."];function lp(e,t){let n=t.plan||de(e),r=h[n];return r?r.validateFlags(t):`Unsupported plan "${n}". Supported plans: ${Object.keys(h).join(`, `)}.`}async function up(e,t){let{identity:n,settings:r,flags:i}=t,a=i.modelName,o=i.displayName,s=i.plan||de(e),c={model_name:a,name:o,plan:s,...(await Et(s).resolve({client:t.client,dryRun:r.dryRun,binName:n.binName,flags:i,model:a,name:o})).body};if(r.dryRun){A({action:`deploy.create`,body:c},`json`);return}let l=await ce(t.client,c),u=l.output??l.data;r.quiet?k(u?.deployed_model??``):A(l,`json`)}const dp=w({description:`Create a text model deployment`,auth:`apiKey`,usageArgs:sp,flags:op,exampleArgs:[`--model-name my-qwen-sft --display-name my-sft-test`,`--model-name qwen3.6-flash-2026-04-16 --display-name my-flash --plan ptu --input-tpm 10000 --output-tpm 1000`,`--model-name qwen3-8b --display-name my-qwen3-mu --plan mu`,`--model-name qwen3-8b --display-name my-qwen3 --plan mu --deploy-spec MU1 --capacity 2`],notes:cp,validate:e=>lp(`text`,e),run:e=>up(`text`,e)}),fp=w({description:`Create an audio (TTS) model deployment`,auth:`apiKey`,usageArgs:sp,flags:op,exampleArgs:[`--model-name my-cosyvoice-ft --display-name my-tts`,`--model-name my-cosyvoice-ft --display-name my-tts --deploy-spec dps-xxxx --capacity 1`,`--model-name my-cosyvoice-ft --display-name my-tts --dry-run`],notes:cp,validate:e=>lp(`audio`,e),run:e=>up(`audio`,e)}),pp=w({description:`Create an image generation model deployment`,auth:`apiKey`,usageArgs:sp,flags:op,exampleArgs:[`--model-name my-wan-ft --display-name my-wan`,`--model-name my-wan-ft --display-name my-wan-mu --plan mu`,`--model-name my-wan-ft --display-name my-wan --dry-run`],notes:cp,validate:e=>lp(`image`,e),run:e=>up(`image`,e)});var mp=w({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=n.status||void 0;if(t.dryRun){A({action:`deploy.list`,page:n.page,page_size:n.pageSize,status:r},`json`);return}let i=await at(e.client,{pageNo:n.page,pageSize:n.pageSize,status:r}),a=i.output??i.data,o=a?.deployments??[],s=a?.total;A({items:o.map(e=>({deployed_model:e.deployed_model??``,model_name:e.model_name??``,status:e.status??``,plan:e.plan??``,capacity:e.capacity===void 0?``:String(e.capacity),created_at:e.gmt_create??``})),total:s,request_id:i.request_id},`json`)}}),hp=w({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;if(t.dryRun){A({action:`deploy.get`,deployed_model:r},`json`);return}let i=await Re(e.client,r),a=i.output??i.data;if(!a){A({deployed_model:r,request_id:i.request_id},`json`);return}let o={deployed_model:a.deployed_model??r,deployed_name:a.name??``,model_name:a.model_name??``,base_model:a.base_model??``,status:a.status??``,plan:a.plan??``};a.model_unit_spec&&(o.model_unit_spec=a.model_unit_spec),a.charge_type&&(o.charge_type=a.charge_type),a.capacity!==void 0&&(o.capacity=a.capacity),a.base_capacity!==void 0&&(o.base_capacity=a.base_capacity),a.ready_capacity!==void 0&&(o.ready_capacity=a.ready_capacity),a.rpm_limit!==void 0&&(o.rpm_limit=a.rpm_limit),a.tpm_limit!==void 0&&(o.tpm_limit=a.tpm_limit),a.input_tpm!==void 0&&(o.input_tpm=a.input_tpm),a.output_tpm!==void 0&&(o.output_tpm=a.output_tpm),a.gmt_create&&(o.created_at=a.gmt_create),a.gmt_modified&&(o.updated_at=a.gmt_modified),A({...o,request_id:i.request_id},`json`)}}),gp=w({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=n.catalogVersion===``?void 0:n.catalogVersion??`v1.0`,i=n.source||void 0;if(t.dryRun){A({action:`deploy.models`,page:n.page,page_size:n.pageSize,version:r,model_source:i},`json`);return}let a=await it(e.client,{pageNo:n.page,pageSize:n.pageSize,version:r,modelSource:i}),o=a.output??a.data,s=o?.models??[],c=o?.total;A({items:s.map(e=>{let t={model_name:e.model_name??``};return e.base_model&&(t.base_model=e.base_model),e.model_source&&(t.model_source=e.model_source),e.supported_plans&&e.supported_plans.length>0&&(t.supported_plans=e.supported_plans),e.plans&&e.plans.length>0&&(t.plans=e.plans.map(e=>{let t={plan:e.plan??``};return e.cu_specs&&e.cu_specs.length>0&&(t.cu_specs=e.cu_specs),e.templates&&e.templates.length>0&&(t.templates=e.templates.map(e=>{let t={};e.template_id&&(t.template_id=e.template_id),e.template_name&&(t.template_name=e.template_name),e.charge_type&&(t.charge_type=e.charge_type);let n=e.roles?.unified;return n?.model_unit_spec&&(t.model_unit_spec=n.model_unit_spec),n?.capacity_unit_per_instance!==void 0&&(t.capacity_unit_per_instance=n.capacity_unit_per_instance),(e.roles?.prefill||e.roles?.decode)&&(t.roles={prefill:e.roles?.prefill,decode:e.roles?.decode}),e.template_desc&&(t.template_desc=e.template_desc),t})),t})),t}),total:c,request_id:a.request_id},`json`)}}),_p=w({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={};if(n.capacity!==void 0&&(i.capacity=n.capacity),n.inputTpm!==void 0&&(i.input_tpm=n.inputTpm),n.outputTpm!==void 0&&(i.output_tpm=n.outputTpm),t.dryRun){A({action:`deploy.scale`,deployed_model:r,body:i},`json`);return}let a=await Gt(e.client,r,i);t.quiet?k(r):A(a,`json`)}}),vp=w({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={};if(n.rpmLimit!==void 0&&(i.rpm_limit=n.rpmLimit),n.tpmLimit!==void 0&&(i.tpm_limit=n.tpmLimit),t.dryRun){A({action:`deploy.update`,deployed_model:r,body:i},`json`);return}let a=await tn(e.client,r,i);t.quiet?k(r):A(a,`json`)}}),yp=w({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;if(n.dryRun){A({action:`deploy.delete`,deployed_model:i},`json`);return}if(!r.skipPrecheck)try{let n=await Re(e.client,i),r=((n.output??n.data)?.status??``).toUpperCase();if(r&&r!==`STOPPED`&&r!==`FAILED`)throw new t(`Deployment ${i} is ${r}. Only STOPPED / FAILED deployments can be deleted. Run \`bl deploy pause --deployed-model ${i}\` to pause it first, or pass --skip-precheck to attempt deletion anyway.`,s.USAGE)}catch(e){if(e instanceof t)throw e}let a=await me(e.client,i);n.quiet?k(i):A(a,`json`)}}),bp=w({description:`Pause a running model deployment (stops billing for mu/ptu)`,auth:`console`,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 RUNNING/PENDING status precheck`}},exampleArgs:[`--deployed-model dep-...`,`--deployed-model dep-... --skip-precheck`,`--deployed-model dep-... --dry-run`],notes:["While paused, billing ceases for mu/ptu plans. Use `deploy resume` to bring it back online or `deploy delete` to remove.",`Precheck verifies status is RUNNING/PENDING before issuing the pause; pass --skip-precheck to bypass.`],async run(e){let{settings:n,flags:r}=e,i=r.deployedModel;if(n.dryRun){A({action:`deploy.pause`,deployed_model:i},`json`);return}if(!r.skipPrecheck)try{let n=je(await st(e.client),i);if(n){let e=(n.status??``).toUpperCase();if(e&&e!==`RUNNING`&&e!==`PENDING`)throw new t(`Deployment ${i} is ${e}. Only RUNNING / PENDING deployments can be paused. Pass --skip-precheck to attempt the pause anyway.`,s.USAGE)}}catch(e){if(e instanceof t)throw e}let a=await Yt(e.client,i);n.quiet?k(i):A({deployed_model:i,action:`pause`,...a},`json`)}}),xp=w({description:`Resume a paused model deployment (brings service back online)`,auth:`console`,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 status precheck`}},exampleArgs:[`--deployed-model dep-...`,`--deployed-model dep-... --skip-precheck`,`--deployed-model dep-... --dry-run`],notes:[`Precheck verifies status is STOPPED before issuing the resume; pass --skip-precheck to bypass.`,`For mu/ptu plans, billing resumes once the service is back online.`],async run(e){let{settings:n,flags:r}=e,i=r.deployedModel;if(n.dryRun){A({action:`deploy.resume`,deployed_model:i},`json`);return}if(!r.skipPrecheck)try{let n=je(await st(e.client),i);if(n){let e=(n.status??``).toUpperCase();if(e&&e!==`STOPPED`)throw new t(`Deployment ${i} is ${e}. Only STOPPED deployments can be resumed. Pass --skip-precheck to attempt the resume anyway.`,s.USAGE)}}catch(e){if(e instanceof t)throw e}let a=await Jt(e.client,i);n.quiet?k(i):A({deployed_model:i,action:`resume`,...a},`json`)}});const Sp={callerUacAccountId:{type:`string`,valueHint:`<id>`,description:`Caller UAC account ID`},namespaceId:{type:`string`,valueHint:`<id>`,description:`Product namespace ID (Token Plan default: namespace-1)`}},Cp={workspaceId:{type:`string`,valueHint:`<id>`,description:`Workspace ID (env: BAILIAN_WORKSPACE_ID, config: workspace_id)`}},wp={cn:`modelstudio.cn-beijing.aliyuncs.com`,intl:`modelstudio.ap-southeast-1.aliyuncs.com`};function Tp(e){for(let[t,n]of Object.entries(p))if(e===n||e.startsWith(`${n}/`))return t;return`cn`}function Ep(e){return wp[Tp(e)]??wp.cn}function Dp(e,n,r){let i=n.workspaceId||e.workspaceId;if(!i)throw new t(`Missing workspace ID.
|
|
2720
|
-
Set via: --workspace-id flag, env: BAILIAN_WORKSPACE_ID, or config: ${r} config set workspace_id <id>`,
|
|
2800
|
+
`);return}throw e}finally{process.off(`SIGINT`,u)}}});async function up(e){return await ke(x(e))}var dp=w({description:{"en-US":`Query fine-tune training capability — by model (which training types it supports) or by training type (which models support it)`,"zh-CN":`查询微调训练能力:按模型查询其支持的训练类型,或按训练类型查询支持它的模型`},auth:`none`,usageArgs:`--base-model <m> | --training-type <t>`,flags:{baseModel:{type:`string`,valueHint:`<m>`,description:{"en-US":`List training types supported by this base model.`,"zh-CN":`列出该基础模型支持的训练类型。`}},trainingType:{type:`string`,valueHint:`<t>`,description:{"en-US":`List models supporting this training type: ${v.join(` | `)}.`,"zh-CN":`列出支持该训练类型的模型:${v.join(` | `)}。`}}},exampleArgs:[`--base-model qwen3-8b`,`--training-type sft-lora`,`--training-type cpt --output json`,`--training-type sft --quiet`],notes:[{"en-US":`Exactly one of --base-model / --training-type is required.`,"zh-CN":`--base-model 和 --training-type 必须且只能指定一个。`},{"en-US":"Training-type values use the `<method>` / `<method>-lora` convention: sft | sft-lora | dpo | dpo-lora | cpt. (cpt has no -lora variant server-side.)","zh-CN":"训练类型遵循 `<method>` / `<method>-lora` 命名约定:sft | sft-lora | dpo | dpo-lora | cpt。(服务端没有 cpt-lora 变体。)"},{"en-US":`Queries listFoundationModels, a public API — no console login needed.`,"zh-CN":`查询公开 API listFoundationModels,无需登录控制台。`}],validate:e=>{if(e.baseModel&&e.trainingType)return`--base-model and --training-type are mutually exclusive; pass one.`;if(!e.baseModel&&!e.trainingType)return`one of --base-model / --training-type is required.`},async run(e){let{settings:t,flags:n}=e,r=n.baseModel||void 0,i=n.trainingType||void 0;if(t.dryRun){A({action:`finetune.capability`,model:r,training_type:i},`json`);return}if(r){let e=await Ee(t,r);if(!e){A({model:r,error:`No foundation model found matching "${r}".`},`json`);return}let n=dt(e);if(t.quiet){for(let e of n)k(e);return}A({model:e.model??r,supported:n,supports:e.supports,trainingTypes:e.trainingTypes},`json`);return}if(!i||!$e(i))throw new y(`--training-type "${i}" is not supported. Valid: ${v.join(`, `)}.`);let{method:a,variant:o}=en(i),s=(await up(t)).filter(e=>bt(e,i)).map(e=>({model:e.model,name:e.name??e.model})).filter(e=>!!e.model).sort((e,t)=>e.model.localeCompare(t.model));if(t.quiet){for(let e of s)k(e.model);return}A({training_type:i,method:a,variant:o,count:s.length,models:s},`json`)}});const fp={baseModel:{type:`string`,valueHint:`<model>`,description:{"en-US":`Base model to fine-tune (e.g. qwen3-8b; not the output model name)`,"zh-CN":`待微调的基座模型(例如 qwen3-8b;不是输出模型名称)`},required:!0},datasets:{type:`string`,valueHint:`<ids>`,description:{"en-US":`Training dataset file IDs, comma-separated (required)`,"zh-CN":`训练数据集文件 ID,多个以逗号分隔(必填)`},required:!0},trainingType:{type:`string`,valueHint:`<type>`,description:{"en-US":`Training type: sft | dpo | cpt (default: sft)`,"zh-CN":`训练类型:sft | dpo | cpt(默认:sft)`}},nEpochs:{type:`number`,valueHint:`<n>`,description:{"en-US":`Number of training epochs (default: 3)`,"zh-CN":`训练轮数(默认:3)`}}},pp=[`sft`,`dpo`,`cpt`];var mp=w({description:{"en-US":`Estimate the training cost for a fine-tune job (token billing)`,"zh-CN":`估算微调任务的训练费用(按 Token 计费)`},auth:`console`,usageArgs:`--base-model <model> --datasets <ids> [--training-type <type>] [--n-epochs <n>]`,flags:fp,exampleArgs:[`--base-model qwen3-8b --datasets file-ft-xxx`,`--base-model qwen3-8b --datasets file-ft-xxx,file-ft-yyy --n-epochs 2`,`--base-model qwen3-8b --datasets file-ft-xxx --training-type cpt`],notes:[{"en-US":`Estimate only — the server computes token usage from the datasets; final cost is subject to the bill.`,"zh-CN":`该结果仅为估算值——服务端根据数据集计算 Token 用量,最终费用以账单为准。`},{"en-US":`Covers token billing for sft / dpo / cpt. Training-unit (MTU) billing is not supported by this command.`,"zh-CN":`支持估算 sft / dpo / cpt 的 Token 计费;此命令不支持训练单元(MTU)计费估算。`},{"en-US":`Hyper-parameters other than --n-epochs are fixed at representative defaults for estimation.`,"zh-CN":`除 --n-epochs 外,其他超参数会使用具有代表性的固定默认值进行估算。`}],async run(e){let{settings:n,flags:r}=e,i=r.baseModel,a=r.datasets.split(`,`).map(e=>e.trim()).filter(Boolean),o=(r.trainingType??`sft`).toLowerCase(),s=r.nEpochs??3;if(!pp.includes(o))throw new t(`Unsupported training type "${o}". Supported: ${pp.join(`, `)}.`,c.USAGE);if(a.length===0)throw new t(`--datasets must contain at least one file ID.`,c.USAGE);if(n.dryRun){A({action:`finetune.price`,model:i,datasets:a,trainingType:o,nEpochs:s},`json`);return}let l=await Me(e.client,i),u=Number(l.price);if(!Number.isFinite(u))throw new t(`No training price found for model "${i}".`,c.GENERAL,void 0,{rawResponse:JSON.stringify(l)});let d=o===`cpt`?await xe(e.client,i,a.join(`,`),s):await Se(e.client,a,{nEpochs:s,batchSize:16,maxLength:8192}),f=d.estimatedDatasetConsumedTokensMinPerEpoch??0,p=d.estimatedDatasetConsumedTokensMaxPerEpoch??0,m=d.estimatedMixedConsumedTokensMinPerEpoch??0,h=d.estimatedMixedConsumedTokensMaxPerEpoch??0,g=(f+m)*s,_=(p+h)*s,v=g/1e3*u,y=_/1e3*u;A({model:i,training_type:o,n_epochs:s,unit_price:u,price_unit:l.priceUnit??`千Token`,estimated_tokens:{min:g,max:_},estimated_fee_yuan:{min:Number(v.toFixed(4)),max:Number(y.toFixed(4))},disclaimer:`Server-side estimate; final cost is subject to the bill.`},`json`)}});const hp={modelName:{type:`string`,valueHint:`<model_name>`,description:{"en-US":`Model to deploy — fine-tuned output name or catalog model (required)`,"zh-CN":`要部署的模型:微调输出模型名称或模型目录中的模型(必填)`},required:!0},displayName:{type:`string`,valueHint:`<display_name>`,description:{"en-US":`Console display name for the deployment (required)`,"zh-CN":`部署在控制台中的显示名称(必填)`},required:!0},plan:{type:`string`,valueHint:`<plan>`,description:{"en-US":`Billing plan: lora (default, Token-billed) | ptu (Token-billed) | mu`,"zh-CN":`计费方案:lora(默认,按 Token 计费)| ptu(按 Token 计费)| mu`}},deploySpec:{type:`string`,valueHint:`<id>`,description:{"en-US":`Deploy spec (only used by plan=mu; auto-picked if omitted)`,"zh-CN":`部署规格(仅 plan=mu 使用;省略时自动选择)`}},capacity:{type:`number`,valueHint:`<n>`,description:{"en-US":`Resource units (plan=mu only; required by API; defaults to the template's unit)`,"zh-CN":`资源单元数(仅 plan=mu;API 必填;默认为模板的单元数)`}},billingMethod:{type:`string`,valueHint:`<m>`,description:{"en-US":`Billing method (plan=mu only; default "POST_PAY", the only supported value)`,"zh-CN":`计费方式(仅 plan=mu;默认且仅支持 "POST_PAY")`}},inputTpm:{type:`number`,valueHint:`<n>`,description:{"en-US":`PTU max input tokens/min (required for plan=ptu)`,"zh-CN":`PTU 每分钟最大输入 Token 数(plan=ptu 时必填)`}},outputTpm:{type:`number`,valueHint:`<n>`,description:{"en-US":`PTU max output tokens/min (required for plan=ptu)`,"zh-CN":`PTU 每分钟最大输出 Token 数(plan=ptu 时必填)`}},thinkingOutputTpm:{type:`number`,valueHint:`<n>`,description:{"en-US":`PTU max thinking-output tokens/min (optional, some models)`,"zh-CN":`PTU 每分钟最大思考输出 Token 数(部分模型可选)`}}},gp=`--model-name <model_name> --display-name <display_name> [--plan <plan>] [--deploy-spec <id>] [--capacity <n>] [--billing-method <m>] [--input-tpm <n>] [--output-tpm <n>] [--thinking-output-tpm <n>]`,_p=[{"en-US":"Plan defaults to `lora` (Token-billed) for text/image and `mu` (model-unit-billed) for audio (CosyVoice TTS). Pass --plan to override.","zh-CN":"文本和图片部署默认使用 `lora`(按 Token 计费),音频(CosyVoice TTS)默认使用 `mu`(按模型单元计费)。可通过 --plan 覆盖。"},{"en-US":`For plan=ptu (Token-billed, provisioned throughput), --input-tpm and --output-tpm are required (the platform rejects creation without an explicit ptu_capacity despite the doc listing defaults).`,"zh-CN":`plan=ptu(按 Token 计费的预置吞吐)时,--input-tpm 和 --output-tpm 必填;即使文档列出了默认值,未显式传入 ptu_capacity 时平台也会拒绝创建。`},{"en-US":"For plan=mu, `capacity`, `billing_method` and `deploy_spec` are required. billing_method defaults to POST_PAY (only supported value); deploy_spec and capacity are auto-picked from GET /deployments/models when omitted.","zh-CN":"plan=mu 时,`capacity`、`billing_method` 和 `deploy_spec` 必填。billing_method 默认且仅支持 POST_PAY;省略 deploy_spec 和 capacity 时,会从 GET /deployments/models 自动选择。"},{"en-US":"Use `bl deploy models --source base` to inspect available templates.","zh-CN":"使用 `bl deploy models --source base` 查看可用模板。"},{"en-US":`After creation, status starts at PENDING and transitions to RUNNING. Invoke the deployed model with: bl text chat --model <deployed_model>`,"zh-CN":`创建后状态从 PENDING 开始,随后转为 RUNNING。调用已部署模型:bl text chat --model <deployed_model>`},{"en-US":"NOTE: --model-name is the model being deployed (e.g. `qwen3-8b-ft-...`). The create response also returns a `deployed_model` field — the deployment instance id (e.g. `qwen3-8b-5ecb5f068d79`). Use that id for inference (`bl text chat --model <deployed_model>`) and lifecycle commands (`deploy get/scale/pause/resume/delete --deployed-model <id>`).","zh-CN":"注意:--model-name 是要部署的模型(例如 `qwen3-8b-ft-...`)。创建响应中的 `deployed_model` 是部署实例 ID(例如 `qwen3-8b-5ecb5f068d79`),用于推理(`bl text chat --model <deployed_model>`)及生命周期命令(`deploy get/scale/pause/resume/delete --deployed-model <id>`)。"}];function vp(e,t){let n=t.plan||pe(e),r=g[n];return r?r.validateFlags(t):`Unsupported plan "${n}". Supported plans: ${Object.keys(g).join(`, `)}.`}async function yp(e,t){let{identity:n,settings:r,flags:i}=t,a=i.modelName,o=i.displayName,s=i.plan||pe(e),c={model_name:a,name:o,plan:s,...(await Ot(s).resolve({client:t.client,dryRun:r.dryRun,binName:n.binName,flags:i,model:a,name:o})).body};if(r.dryRun){A({action:`deploy.create`,body:c},`json`);return}let l=await ue(t.client,c),u=l.output??l.data;r.quiet?k(u?.deployed_model??``):A(l,`json`)}const bp=w({description:{"en-US":`Create a text model deployment`,"zh-CN":`创建文本模型部署`},auth:`apiKey`,usageArgs:gp,flags:hp,exampleArgs:[`--model-name my-qwen-sft --display-name my-sft-test`,`--model-name qwen3.6-flash-2026-04-16 --display-name my-flash --plan ptu --input-tpm 10000 --output-tpm 1000`,`--model-name qwen3-8b --display-name my-qwen3-mu --plan mu`,`--model-name qwen3-8b --display-name my-qwen3 --plan mu --deploy-spec MU1 --capacity 2`],notes:_p,validate:e=>vp(`text`,e),run:e=>yp(`text`,e)}),xp=w({description:{"en-US":`Create an audio (TTS) model deployment`,"zh-CN":`创建音频(TTS)模型部署`},auth:`apiKey`,usageArgs:gp,flags:hp,exampleArgs:[`--model-name my-cosyvoice-ft --display-name my-tts`,`--model-name my-cosyvoice-ft --display-name my-tts --deploy-spec dps-xxxx --capacity 1`,`--model-name my-cosyvoice-ft --display-name my-tts --dry-run`],notes:_p,validate:e=>vp(`audio`,e),run:e=>yp(`audio`,e)}),Sp=w({description:{"en-US":`Create an image generation model deployment`,"zh-CN":`创建图片生成模型部署`},auth:`apiKey`,usageArgs:gp,flags:hp,exampleArgs:[`--model-name my-wan-ft --display-name my-wan`,`--model-name my-wan-ft --display-name my-wan-mu --plan mu`,`--model-name my-wan-ft --display-name my-wan --dry-run`],notes:_p,validate:e=>vp(`image`,e),run:e=>yp(`image`,e)});var Cp=w({description:{"en-US":`List model deployments`,"zh-CN":`列出模型部署`},auth:`apiKey`,usageArgs:`[--page <n>] [--page-size <n>] [--status <s>]`,flags:{page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Results per page (default: 10, max 100)`,"zh-CN":`每页结果数(默认:10,最多:100)`}},status:{type:`string`,valueHint:`<s>`,description:{"en-US":`Filter by status (PENDING / RUNNING / STOPPED / FAILED)`,"zh-CN":`按状态筛选(PENDING / RUNNING / STOPPED / FAILED)`}}},exampleArgs:[``,`--status RUNNING`,`--page-size 20 --output json`],async run(e){let{settings:t,flags:n}=e,r=n.status||void 0;if(t.dryRun){A({action:`deploy.list`,page:n.page,page_size:n.pageSize,status:r},`json`);return}let i=await st(e.client,{pageNo:n.page,pageSize:n.pageSize,status:r}),a=i.output??i.data,o=a?.deployments??[],s=a?.total;A({items:o.map(e=>({deployed_model:e.deployed_model??``,model_name:e.model_name??``,status:e.status??``,plan:e.plan??``,capacity:e.capacity===void 0?``:String(e.capacity),created_at:e.gmt_create??``})),total:s,request_id:i.request_id},`json`)}}),wp=w({description:{"en-US":`Get details of a single model deployment`,"zh-CN":`获取单个模型部署的详情`},auth:`apiKey`,usageArgs:`--deployed-model <id>`,flags:{deployedModel:{type:`string`,valueHint:`<id>`,description:{"en-US":`Deployed model identifier (required)`,"zh-CN":`已部署模型标识(必填)`},required:!0}},exampleArgs:[`--deployed-model qwen-plus-2025-12-01-b6d61c71`,`--deployed-model qwen-plus-2025-12-01-b6d61c71 --output json`],async run(e){let{settings:t,flags:n}=e,r=n.deployedModel;if(t.dryRun){A({action:`deploy.get`,deployed_model:r},`json`);return}let i=await Be(e.client,r),a=i.output??i.data;if(!a){A({deployed_model:r,request_id:i.request_id},`json`);return}let o={deployed_model:a.deployed_model??r,deployed_name:a.name??``,model_name:a.model_name??``,base_model:a.base_model??``,status:a.status??``,plan:a.plan??``};a.model_unit_spec&&(o.model_unit_spec=a.model_unit_spec),a.charge_type&&(o.charge_type=a.charge_type),a.capacity!==void 0&&(o.capacity=a.capacity),a.base_capacity!==void 0&&(o.base_capacity=a.base_capacity),a.ready_capacity!==void 0&&(o.ready_capacity=a.ready_capacity),a.rpm_limit!==void 0&&(o.rpm_limit=a.rpm_limit),a.tpm_limit!==void 0&&(o.tpm_limit=a.tpm_limit),a.input_tpm!==void 0&&(o.input_tpm=a.input_tpm),a.output_tpm!==void 0&&(o.output_tpm=a.output_tpm),a.gmt_create&&(o.created_at=a.gmt_create),a.gmt_modified&&(o.updated_at=a.gmt_modified),A({...o,request_id:i.request_id},`json`)}}),Tp=w({description:{"en-US":`List models available for deployment`,"zh-CN":`列出可部署的模型`},auth:`apiKey`,usageArgs:`[--page <n>] [--page-size <n>] [--catalog-version <v>] [--source <custom|public>]`,flags:{page:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Results per page (default: 100)`,"zh-CN":`每页结果数(默认:100)`}},catalogVersion:{type:`string`,valueHint:`<v>`,description:{"en-US":`Catalog version filter (default: v1.0; required for new catalog models)`,"zh-CN":`模型目录版本筛选(默认:v1.0;新目录模型必填)`}},source:{type:`string`,valueHint:`<s>`,description:{"en-US":`Model source filter: custom (fine-tuned) | base (catalog) | public`,"zh-CN":`模型来源筛选:custom(微调模型)| base(模型目录)| public`}}},exampleArgs:[``,`--source base`,`--source custom --page-size 50`,`--catalog-version v1.0 --output json`],async run(e){let{settings:t,flags:n}=e,r=n.catalogVersion===``?void 0:n.catalogVersion??`v1.0`,i=n.source||void 0;if(t.dryRun){A({action:`deploy.models`,page:n.page,page_size:n.pageSize,version:r,model_source:i},`json`);return}let a=await ot(e.client,{pageNo:n.page,pageSize:n.pageSize,version:r,modelSource:i}),o=a.output??a.data,s=o?.models??[],c=o?.total;A({items:s.map(e=>{let t={model_name:e.model_name??``};return e.base_model&&(t.base_model=e.base_model),e.model_source&&(t.model_source=e.model_source),e.supported_plans&&e.supported_plans.length>0&&(t.supported_plans=e.supported_plans),e.plans&&e.plans.length>0&&(t.plans=e.plans.map(e=>{let t={plan:e.plan??``};return e.cu_specs&&e.cu_specs.length>0&&(t.cu_specs=e.cu_specs),e.templates&&e.templates.length>0&&(t.templates=e.templates.map(e=>{let t={};e.template_id&&(t.template_id=e.template_id),e.template_name&&(t.template_name=e.template_name),e.charge_type&&(t.charge_type=e.charge_type);let n=e.roles?.unified;return n?.model_unit_spec&&(t.model_unit_spec=n.model_unit_spec),n?.capacity_unit_per_instance!==void 0&&(t.capacity_unit_per_instance=n.capacity_unit_per_instance),(e.roles?.prefill||e.roles?.decode)&&(t.roles={prefill:e.roles?.prefill,decode:e.roles?.decode}),e.template_desc&&(t.template_desc=e.template_desc),t})),t})),t}),total:c,request_id:a.request_id},`json`)}}),Ep=w({description:{"en-US":`Scale a deployment's capacity`,"zh-CN":`调整部署容量`},auth:`apiKey`,usageArgs:`--deployed-model <id> --capacity <n> [--input-tpm <n>] [--output-tpm <n>]`,flags:{deployedModel:{type:`string`,valueHint:`<id>`,description:{"en-US":`Deployed model identifier (required)`,"zh-CN":`已部署模型标识(必填)`},required:!0},capacity:{type:`number`,valueHint:`<n>`,description:{"en-US":`New capacity in plan units (must be a multiple of base_capacity)`,"zh-CN":`以方案单元表示的新容量(必须是 base_capacity 的整数倍)`}},inputTpm:{type:`number`,valueHint:`<n>`,description:{"en-US":`PTU only — input tokens per minute`,"zh-CN":`仅 PTU:每分钟输入 Token 数`}},outputTpm:{type:`number`,valueHint:`<n>`,description:{"en-US":`PTU only — output tokens per minute`,"zh-CN":`仅 PTU:每分钟输出 Token 数`}}},exampleArgs:[`--deployed-model qwen-plus-...-b6d61c71 --capacity 8`,`--deployed-model dep-... --capacity 2`],validate:e=>e.capacity===void 0&&e.inputTpm===void 0&&e.outputTpm===void 0?`Provide at least one of --capacity / --input-tpm / --output-tpm.`:void 0,async run(e){let{settings:t,flags:n}=e,r=n.deployedModel,i={};if(n.capacity!==void 0&&(i.capacity=n.capacity),n.inputTpm!==void 0&&(i.input_tpm=n.inputTpm),n.outputTpm!==void 0&&(i.output_tpm=n.outputTpm),t.dryRun){A({action:`deploy.scale`,deployed_model:r,body:i},`json`);return}let a=await qt(e.client,r,i);t.quiet?k(r):A(a,`json`)}}),Dp=w({description:{"en-US":`Update a deployment's rate limits (rpm_limit / tpm_limit)`,"zh-CN":`更新部署的限流配置(rpm_limit / tpm_limit)`},auth:`apiKey`,usageArgs:`--deployed-model <id> [--rpm-limit <n>] [--tpm-limit <n>]`,flags:{deployedModel:{type:`string`,valueHint:`<id>`,description:{"en-US":`Deployed model identifier (required)`,"zh-CN":`已部署模型标识(必填)`},required:!0},rpmLimit:{type:`number`,valueHint:`<n>`,description:{"en-US":`Requests per minute`,"zh-CN":`每分钟请求数`}},tpmLimit:{type:`number`,valueHint:`<n>`,description:{"en-US":`Tokens per minute`,"zh-CN":`每分钟 Token 数`}}},exampleArgs:[`--deployed-model dep-... --rpm-limit 1000`,`--deployed-model dep-... --rpm-limit 1000 --tpm-limit 200000`],notes:[{"en-US":`At least one of --rpm-limit / --tpm-limit must be provided.`,"zh-CN":`--rpm-limit / --tpm-limit 至少需要提供一个。`}],validate:e=>e.rpmLimit===void 0&&e.tpmLimit===void 0?`Provide at least one of --rpm-limit / --tpm-limit.`:void 0,async run(e){let{settings:t,flags:n}=e,r=n.deployedModel,i={};if(n.rpmLimit!==void 0&&(i.rpm_limit=n.rpmLimit),n.tpmLimit!==void 0&&(i.tpm_limit=n.tpmLimit),t.dryRun){A({action:`deploy.update`,deployed_model:r,body:i},`json`);return}let a=await rn(e.client,r,i);t.quiet?k(r):A(a,`json`)}}),Op=w({description:{"en-US":`Delete a model deployment (must be STOPPED or FAILED)`,"zh-CN":`删除模型部署(状态必须为 STOPPED 或 FAILED)`},auth:`apiKey`,usageArgs:`--deployed-model <id> [--skip-precheck]`,flags:{deployedModel:{type:`string`,valueHint:`<id>`,description:{"en-US":`Deployed model identifier (required)`,"zh-CN":`已部署模型标识(必填)`},required:!0},skipPrecheck:{type:`switch`,description:{"en-US":`Skip the local STOPPED/FAILED status precheck`,"zh-CN":`跳过本地 STOPPED/FAILED 状态预检查`}}},exampleArgs:[`--deployed-model dep-...`,`--deployed-model dep-... --dry-run`],async run(e){let{settings:n,flags:r}=e,i=r.deployedModel;if(n.dryRun){A({action:`deploy.delete`,deployed_model:i},`json`);return}if(!r.skipPrecheck)try{let n=await Be(e.client,i),r=((n.output??n.data)?.status??``).toUpperCase();if(r&&r!==`STOPPED`&&r!==`FAILED`)throw new t(`Deployment ${i} is ${r}. Only STOPPED / FAILED deployments can be deleted. Run \`bl deploy pause --deployed-model ${i}\` to pause it first, or pass --skip-precheck to attempt deletion anyway.`,c.USAGE)}catch(e){if(e instanceof t)throw e}let a=await ge(e.client,i);n.quiet?k(i):A(a,`json`)}}),kp=w({description:{"en-US":`Pause a running model deployment (stops billing for mu/ptu)`,"zh-CN":`暂停运行中的模型部署(mu/ptu 方案将停止计费)`},auth:`console`,usageArgs:`--deployed-model <id> [--skip-precheck]`,flags:{deployedModel:{type:`string`,valueHint:`<id>`,description:{"en-US":`Deployed model identifier (required)`,"zh-CN":`已部署模型标识(必填)`},required:!0},skipPrecheck:{type:`switch`,description:{"en-US":`Skip the local RUNNING/PENDING status precheck`,"zh-CN":`跳过本地 RUNNING/PENDING 状态预检查`}}},exampleArgs:[`--deployed-model dep-...`,`--deployed-model dep-... --skip-precheck`,`--deployed-model dep-... --dry-run`],notes:[{"en-US":"While paused, billing ceases for mu/ptu plans. Use `deploy resume` to bring it back online or `deploy delete` to remove.","zh-CN":"暂停期间,mu/ptu 方案将停止计费。使用 `deploy resume` 恢复服务,或使用 `deploy delete` 删除部署。"},{"en-US":`Precheck verifies status is RUNNING/PENDING before issuing the pause; pass --skip-precheck to bypass.`,"zh-CN":`发起暂停前会预检查部署状态是否为 RUNNING/PENDING;可传入 --skip-precheck 跳过检查。`}],async run(e){let{settings:n,flags:r}=e,i=r.deployedModel;if(n.dryRun){A({action:`deploy.pause`,deployed_model:i},`json`);return}if(!r.skipPrecheck)try{let n=Ne(await lt(e.client),i);if(n){let e=(n.status??``).toUpperCase();if(e&&e!==`RUNNING`&&e!==`PENDING`)throw new t(`Deployment ${i} is ${e}. Only RUNNING / PENDING deployments can be paused. Pass --skip-precheck to attempt the pause anyway.`,c.USAGE)}}catch(e){if(e instanceof t)throw e}let a=await Zt(e.client,i);n.quiet?k(i):A({deployed_model:i,action:`pause`,...a},`json`)}}),Ap=w({description:{"en-US":`Resume a paused model deployment (brings service back online)`,"zh-CN":`恢复已暂停的模型部署(使服务重新上线)`},auth:`console`,usageArgs:`--deployed-model <id> [--skip-precheck]`,flags:{deployedModel:{type:`string`,valueHint:`<id>`,description:{"en-US":`Deployed model identifier (required)`,"zh-CN":`已部署模型标识(必填)`},required:!0},skipPrecheck:{type:`switch`,description:{"en-US":`Skip the local STOPPED status precheck`,"zh-CN":`跳过本地 STOPPED 状态预检查`}}},exampleArgs:[`--deployed-model dep-...`,`--deployed-model dep-... --skip-precheck`,`--deployed-model dep-... --dry-run`],notes:[{"en-US":`Precheck verifies status is STOPPED before issuing the resume; pass --skip-precheck to bypass.`,"zh-CN":`发起恢复前会预检查部署状态是否为 STOPPED;可传入 --skip-precheck 跳过检查。`},{"en-US":`For mu/ptu plans, billing resumes once the service is back online.`,"zh-CN":`对于 mu/ptu 方案,服务重新上线后将恢复计费。`}],async run(e){let{settings:n,flags:r}=e,i=r.deployedModel;if(n.dryRun){A({action:`deploy.resume`,deployed_model:i},`json`);return}if(!r.skipPrecheck)try{let n=Ne(await lt(e.client),i);if(n){let e=(n.status??``).toUpperCase();if(e&&e!==`STOPPED`)throw new t(`Deployment ${i} is ${e}. Only STOPPED deployments can be resumed. Pass --skip-precheck to attempt the resume anyway.`,c.USAGE)}}catch(e){if(e instanceof t)throw e}let a=await Xt(e.client,i);n.quiet?k(i):A({deployed_model:i,action:`resume`,...a},`json`)}});const jp={callerUacAccountId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Caller UAC account ID`,"zh-CN":`调用方 UAC 账号 ID`}},namespaceId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Product namespace ID (Token Plan default: namespace-1)`,"zh-CN":`产品 Namespace ID(Token Plan 默认:namespace-1)`}}},Mp={workspaceId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Workspace ID (env: BAILIAN_WORKSPACE_ID, config: workspace_id)`,"zh-CN":`Workspace ID(环境变量:BAILIAN_WORKSPACE_ID,配置项:workspace_id)`}}},Np={cn:`modelstudio.cn-beijing.aliyuncs.com`,intl:`modelstudio.ap-southeast-1.aliyuncs.com`};function Pp(e){for(let[t,n]of Object.entries(m))if(e===n||e.startsWith(`${n}/`))return t;return`cn`}function Fp(e){return Np[Pp(e)]??Np.cn}function Ip(e,n,r){let i=n.workspaceId||e.workspaceId;if(!i)throw new t(`Missing workspace ID.
|
|
2801
|
+
Set via: --workspace-id flag, env: BAILIAN_WORKSPACE_ID, or config: ${r} config set workspace_id <id>`,c.USAGE);return i}function Lp(e,t){t.callerUacAccountId&&(e.CallerUacAccountId=t.callerUacAccountId),t.namespaceId&&(e.NamespaceId=t.namespaceId)}function Rp(e,t,n){let r=ee(n),i=Fp(e);return{host:i,endpoint:`https://${i}${t}${r?`?${r}`:``}`,queryString:r,queryParams:n}}async function zp(e){let{client:t,baseUrl:n,action:r,path:i,method:a,queryParams:o}=e,{host:s}=Rp(n,i,o);return t.openApiQueryJson({host:s,path:i,action:r,version:`2026-02-10`,method:a,queryParams:o})}const Bp=`/tokenplan/subscription/seat-detail`;var Vp=w({description:{"en-US":`List Token Plan subscription seat details`,"zh-CN":`列出 Token Plan 订阅席位详情`},auth:`openapi`,usageArgs:`[flags]`,flags:{pageNo:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page number (default: 1)`,"zh-CN":`页码(默认:1)`}},pageSize:{type:`number`,valueHint:`<n>`,description:{"en-US":`Page size (default: 10)`,"zh-CN":`每页数量(默认:10)`}},...jp,status:{type:`array`,valueHint:`<status>`,description:{"en-US":`Seat status filter (repeatable): CREATING, NORMAL, LIMIT, RELEASE, STOP, REFUNDED`,"zh-CN":`席位状态筛选(可重复):CREATING、NORMAL、LIMIT、RELEASE、STOP、REFUNDED`}},statusListStr:{type:`string`,valueHint:`<json>`,description:{"en-US":`StatusList as JSON string, e.g. '["NORMAL"]'`,"zh-CN":`JSON 字符串格式的 StatusList,例如 '["NORMAL"]'`}},seatId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Filter by seat ID`,"zh-CN":`按席位 ID 筛选`}},seatType:{type:`string`,valueHint:`<type>`,description:{"en-US":`Seat tier: standard, pro, or max`,"zh-CN":`席位档位:standard、pro 或 max`}},queryAssigned:{type:`string`,valueHint:`<bool>`,description:{"en-US":`Filter by assignment: true=assigned, false=unassigned`,"zh-CN":`按分配状态筛选:true=已分配,false=未分配`}}},exampleArgs:[``,`--page-size 20 --status NORMAL`,`--query-assigned true --seat-type standard`],async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=Hp(n);if(t.dryRun){let{endpoint:t,queryParams:n}=Rp(e.client.baseUrl,Bp,i);A({endpoint:t,query:n},r);return}let a=await zp({client:e.client,baseUrl:e.client.baseUrl,action:`GetSubscriptionSeatDetails`,path:Bp,method:`GET`,queryParams:i}),o=a.Data?.Items??[];t.quiet||r===`text`?Up(o,a.Data?.Total,a.Data?.PageNo,a.Data?.PageSize):A(a,r)}});function Hp(e){let n={};if(e.pageNo!==void 0&&(n.PageNo=String(e.pageNo)),e.pageSize!==void 0&&(n.PageSize=String(e.pageSize)),Lp(n,e),e.statusListStr&&(n.StatusListStr=e.statusListStr),e.status&&e.status.length>0&&(n.StatusList=e.status),e.seatId&&(n.SeatId=e.seatId),e.seatType&&(n.SeatType=e.seatType),typeof e.queryAssigned==`string`&&e.queryAssigned.length>0){let r=e.queryAssigned.toLowerCase();if(r!==`true`&&r!==`false`)throw new t(`--query-assigned must be 'true' or 'false'.`,c.USAGE);n.QueryAssigned=r}return n}function Up(e,t,n,r){if(e.length===0){k(`No seats found.`);return}let i=[M(`SeatId`,18),M(`Type`,10),M(`Status`,10),M(`Assigned`,12),M(`Account`,20)].join(` `);k(i),k(`-`.repeat(i.length));for(let t of e)k([M(t.SeatId??`-`,18),M(t.SpecType??`-`,10),M(t.Status??`-`,10),M(t.AssignedStatus??`-`,12),M(t.AccountName??t.AccountId??`-`,20)].join(` `));t!==void 0&&(k(``),k(`Total: ${t}${n===void 0?``:` | Page: ${n}`}${r===void 0?``:` | PageSize: ${r}`}`))}const Wp=`/tokenplan/api-keys`;var Gp=w({description:{"en-US":`Create a Token Plan API key for a seat`,"zh-CN":`为席位创建 Token Plan API Key`},auth:`openapi`,usageArgs:`--account-id <id> --workspace-id <id> [flags]`,flags:{accountId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Target member account ID`,"zh-CN":`目标成员账号 ID`},required:!0},...Mp,description:{type:`string`,valueHint:`<text>`,description:{"en-US":`API key description`,"zh-CN":`API Key 描述`}},...jp},exampleArgs:[`--account-id acc_123 --workspace-id ws_456`,{"en-US":`--account-id acc_123 --workspace-id ws_456 --description 'Dev key'`,"zh-CN":`--account-id acc_123 --workspace-id ws_456 --description '开发密钥'`}],async run(e){let{identity:t,settings:n,flags:r}=e,i=T(n.output),a=Ip(n,r,t.binName),o=Kp(r,{accountId:r.accountId,workspaceId:a});if(n.dryRun){let{endpoint:t,queryParams:n}=Rp(e.client.baseUrl,Wp,o);A({endpoint:t,query:n},i);return}let s=await zp({client:e.client,baseUrl:e.client.baseUrl,action:`CreateTokenPlanKey`,path:Wp,method:`POST`,queryParams:o});n.quiet||i===`text`?qp(s):A(s,i)}});function Kp(e,t){let n={};return n.AccountId=t.accountId,n.WorkspaceId=t.workspaceId,e.description&&(n.Description=e.description),Lp(n,e),n}function qp(e){let t=e.Data;if(!t){k(`API key created.`);return}k(`${M(`ApiKeyId`,14)} ${t.ApiKeyId??`-`}`),k(`${M(`MaskedApiKey`,14)} ${t.MaskedApiKey??`-`}`),t.Description&&k(`${M(`Description`,14)} ${t.Description}`),t.PlainApiKey&&(k(``),k(`PlainApiKey (shown once): ${t.PlainApiKey}`))}const Jp=`/tokenplan/subscription/seat-assignments`;var Yp=w({description:{"en-US":`Batch assign Token Plan seats to members`,"zh-CN":`批量向成员分配 Token Plan 席位`},auth:`openapi`,usageArgs:`--workspace-id <id> --seat-type <type> --account-id <id> [flags]`,flags:{...Mp,seatType:{type:`string`,valueHint:`<type>`,description:{"en-US":`Seat tier: standard, pro, or max`,"zh-CN":`席位档位:standard、pro 或 max`},required:!0},accountId:{type:`array`,valueHint:`<id>`,description:{"en-US":`Target member account ID (repeatable)`,"zh-CN":`目标成员账号 ID(可重复)`}},...jp,locale:{type:`string`,valueHint:`<locale>`,description:{"en-US":`Language: zh-CN or en-US`,"zh-CN":`语言:zh-CN 或 en-US`}}},exampleArgs:[`--workspace-id ws_456 --seat-type standard --account-id acc_123`,`--workspace-id ws_456 --seat-type pro --account-id acc_1 --account-id acc_2`],validate:e=>e.accountId&&e.accountId.length>0?void 0:`Missing required flag: --account-id`,async run(e){let{identity:t,settings:n,flags:r}=e,i=T(n.output),a=Xp(r,Ip(n,r,t.binName));if(n.dryRun){let{endpoint:t,queryParams:n}=Rp(e.client.baseUrl,Jp,a);A({endpoint:t,query:n},i);return}let o=await zp({client:e.client,baseUrl:e.client.baseUrl,action:`BatchAssignSeats`,path:Jp,method:`POST`,queryParams:a});n.quiet||i===`text`?k(`Seats assigned successfully.`):A(o,i)}});function Xp(e,t){let n={};return n.WorkspaceId=t,e.seatType&&(n.SeatType=e.seatType),Lp(n,e),e.locale&&(n.Locale=e.locale),e.accountId&&e.accountId.length>0&&(n.AccountIds=e.accountId),n}const Zp=`/tokenplan/organization/member-additions`;var Qp=w({description:{"en-US":`Add a member to a Token Plan organization`,"zh-CN":`向 Token Plan 组织添加成员`},auth:`openapi`,usageArgs:`--account-name <name> --org-id <id> [flags]`,flags:{accountName:{type:`string`,valueHint:`<name>`,description:{"en-US":`Member display name`,"zh-CN":`成员显示名称`},required:!0},orgId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Organization ID`,"zh-CN":`组织 ID`},required:!0},orgRoleCode:{type:`string`,valueHint:`<code>`,description:{"en-US":`Organization role: ORG_ADMIN or ORG_MEMBER (default: ORG_MEMBER)`,"zh-CN":`组织角色:ORG_ADMIN 或 ORG_MEMBER(默认:ORG_MEMBER)`}},specType:{type:`string`,valueHint:`<type>`,description:{"en-US":`Seat tier to assign on creation: standard, pro, or max`,"zh-CN":`创建时分配的席位档位:standard、pro 或 max`}},...jp},exampleArgs:[`--account-name dev_user --org-id org_123`,`--account-name admin_user --org-id org_123 --org-role-code ORG_ADMIN`,`--account-name member1 --org-id org_123 --spec-type standard`],async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=$p(n);if(t.dryRun){let{endpoint:t,queryParams:n}=Rp(e.client.baseUrl,Zp,i);A({endpoint:t,query:n},r);return}let a=await zp({client:e.client,baseUrl:e.client.baseUrl,action:`AddOrganizationMember`,path:Zp,method:`POST`,queryParams:i});t.quiet||r===`text`?em(a):A(a,r)}});function $p(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),Lp(t,e),t}function em(e){let t=e.Data;if(!t){k(`Member added.`);return}k(`${M(`AccountId`,14)} ${t.AccountId??`-`}`),k(`${M(`SeatAssigned`,14)} ${String(t.SeatAssigned??`-`)}`)}const tm=[`bailian`,`claude`,`qoder`,`ark`,`all`],nm={bailian:` bailian:
|
|
2721
2802
|
# bl auth login --api-key <key> sets DASHSCOPE_API_KEY; --base-url <url> sets BAILIAN_BASE_URL
|
|
2722
2803
|
api_key: \${DASHSCOPE_API_KEY}
|
|
2723
2804
|
base_url: \${BAILIAN_BASE_URL}`,claude:` claude:
|
|
2724
2805
|
api_key: \${ANTHROPIC_API_KEY}`,qoder:` qoder:
|
|
2725
2806
|
api_key: \${QODER_PAT}
|
|
2726
2807
|
gateway: "https://api.qoder.com/api/v1/cloud"`,ark:` ark:
|
|
2727
|
-
api_key: \${ARK_API_KEY}`},
|
|
2808
|
+
api_key: \${ARK_API_KEY}`},rm={bailian:` model: qwen3.8-max`,claude:` model: claude-sonnet-4-6`,qoder:` model: ultimate`,ark:` model: doubao-seed-2-1-pro-260628`};function im(e){let t=e.provider===`all`?`${nm.bailian}\n${nm.claude}\n${nm.qoder}\n${nm.ark}`:nm[e.provider],n=e.provider===`all`?` model:
|
|
2728
2809
|
bailian: qwen3.8-max
|
|
2729
2810
|
claude: claude-sonnet-4-6
|
|
2730
2811
|
qoder: ultimate
|
|
2731
|
-
ark: doubao-seed-2-1-pro-260628`:
|
|
2812
|
+
ark: doubao-seed-2-1-pro-260628`:rm[e.provider],r=e.provider===`bailian`?`[bash, read, glob, grep]`:`[read, glob, grep, web_search, web_fetch]`;return`version: "1"
|
|
2732
2813
|
|
|
2733
2814
|
providers:
|
|
2734
2815
|
${t}
|
|
@@ -2752,15 +2833,15 @@ ${n}
|
|
|
2752
2833
|
environment: dev
|
|
2753
2834
|
tools:
|
|
2754
2835
|
builtin: ${r}
|
|
2755
|
-
`}var
|
|
2836
|
+
`}var am=w({description:{"en-US":`Create a new agents.yaml template`,"zh-CN":`创建新的 agents.yaml 模板`},auth:`none`,usageArgs:`[--provider <name>] [--agent-name <name>] [--file <path>] [--force]`,flags:{provider:{type:`string`,valueHint:`<name>`,description:{"en-US":`Provider: bailian, claude, qoder, ark, all (default: bailian)`,"zh-CN":`Provider:bailian、claude、qoder、ark、all(默认:bailian)`},choices:tm},agentName:{type:`string`,valueHint:`<name>`,description:{"en-US":`Name of the first agent (default: assistant)`,"zh-CN":`第一个 Agent 的名称(默认:assistant)`}},file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Output config path (default: agents.yaml)`,"zh-CN":`输出配置路径(默认:agents.yaml)`}},force:{type:`switch`,description:{"en-US":`Overwrite an existing config file`,"zh-CN":`覆盖已有配置文件`}}},exampleArgs:[``,`--provider bailian --agent-name assistant`,`--provider all`],async run(e){let{settings:n,flags:r}=e,i=T(n.output),a=r.provider??`bailian`,o=r.agentName??`assistant`,s=r.file??`agents.yaml`;if(P(s)&&!r.force)throw new t(`${s} already exists.`,c.USAGE,`Pass --force to overwrite.`);let l=`.gitignore`;if(n.dryRun){let e=!0;P(l)&&(e=!(await Cr(l,`utf8`)).includes(`agents.state.json`)),A({would_create:s,provider:a,agent:o,would_update_gitignore:e},i);return}if(await wr(s,im({provider:a,agentName:o}),`utf8`),P(l)){let e=await Cr(l,`utf8`);e.includes(`agents.state.json`)||await wr(l,e+`
|
|
2756
2837
|
# agents
|
|
2757
2838
|
agents.state.json
|
|
2758
2839
|
.env
|
|
2759
|
-
`,`utf8`)}else await
|
|
2840
|
+
`,`utf8`)}else await wr(l,`# agents
|
|
2760
2841
|
agents.state.json
|
|
2761
2842
|
.env
|
|
2762
|
-
`,`utf8`);i===`json`?A({created:
|
|
2843
|
+
`,`utf8`);i===`json`?A({created:s,provider:a,agent:o},i):(k(`Created ${s}`),(a===`bailian`||a===`all`)&&k("Credentials: run `bl auth login --api-key <key> --base-url <url>`, or set DASHSCOPE_API_KEY / BAILIAN_BASE_URL."),k("Next: edit agents.yaml, then run `bl managed-agent plan`."))}});const om=`/api/v1/agentstudio`,sm=[...new Set([...Object.values(kr).flatMap(e=>e.map(e=>e.key)),`BAILIAN_API_KEY`,`BAILIAN_BASE_URL`,`CLAUDE_API_KEY`,`QODER_API_KEY`])],cm={bailian:"Run `bl auth login --api-key <key>`, pass --api-key, or set DASHSCOPE_API_KEY.",claude:`Set ANTHROPIC_API_KEY (or CLAUDE_API_KEY) in your shell or .env.`,ark:`Set ARK_API_KEY in your shell or .env.`,qoder:`Set QODER_PAT (or QODER_API_KEY) in your shell or .env.`},Y=[{"en-US":"Bailian credentials come from bl's auth chain: --api-key > DASHSCOPE_API_KEY > `bl auth login` (active config profile).","zh-CN":"百炼凭证来自 bl 鉴权链:--api-key > DASHSCOPE_API_KEY > `bl auth login`(当前激活的配置 Profile)。"},{"en-US":"Other providers read the env vars referenced in agents.yaml (e.g. ${ANTHROPIC_API_KEY}), including .env and ~/.agents/config.json.","zh-CN":"其他 Provider 读取 agents.yaml 中引用的环境变量(例如 ${ANTHROPIC_API_KEY}),包括 .env 和 ~/.agents/config.json。"},{"en-US":`Resolved credentials are injected into the SDK in-memory and cleared from the environment; they never persist in process env.`,"zh-CN":`解析后的凭证仅在内存中注入 SDK,并从环境中清除;不会持久保留在进程环境变量中。`}],lm=[{"en-US":`Runs fully offline against local files: no login or provider credentials required.`,"zh-CN":`完全离线处理本地文件:无需登录或提供 Provider 凭证。`}];function um(){Nr();for(let e of sm)process.env[e]===void 0&&(process.env[e]=``)}function dm(e,t){let n=e.bailian;if(!n||typeof n!=`object`)return;let r=n,i=t.client.exportApiCredential();if(i&&(r.api_key=i.token),`base_url`in r&&!r.base_url){let e=t.client.baseUrl.replace(/\/+$/,``);r.base_url=e.endsWith(om)?e:`${e}${om}`}`workspace_id`in r&&!r.workspace_id&&t.settings.workspaceId&&(r.workspace_id=t.settings.workspaceId)}function fm(){for(let e of sm)delete process.env[e]}function pm(e){for(let t of Object.values(e)){if(!t||typeof t!=`object`)continue;let e=t;for(let[t,n]of Object.entries(e))n===null&&(e[t]=``)}}function mm(e){for(let[n,r]of Object.entries(e)){if(!r||typeof r!=`object`)continue;let e=r;if(!(`api_key`in e))continue;let i=e.api_key;if(!(typeof i==`string`&&i.trim()))throw new t(`Provider '${n}' is configured but its API key is empty.`,c.AUTH,cm[n]??`Provide credentials for provider '${n}'.`)}}function hm(e,t){let n=pr(e);return{projectId:t??F(ur(n))}}async function gm(e,t,n){let r=pr(e),i=new Ar({configPath:r,statePath:t}).getStatePath(hm(r,n));return jr.load(i)}let _m=!1;function vm(e){if(_m)return;let t=Or.setDefaultFetch;typeof t==`function`&&(t(fe(e)),_m=!0)}async function ym(e,t,n={}){um();let r=await Jr(t,n);return pm(r.config.providers),dm(r.config.providers,e),fm(),(n.credentials??`all`)!==`none`&&mm(r.config.providers),r}async function X(e,t,n={}){vm(e);let{config:r,configPath:i,projectName:a}=await ym(e,t,n);return{...Pr({projectName:a,config:r,state:await gm(i,n.statePath,a),configPath:i,providers:r.providers}),configPath:i}}function bm(e,t){if(!(!t||t===`all`)&&!e.providers.has(t))throw new Mr(`Provider '${t}' is not configured. Available providers: ${Array.from(e.providers.keys()).join(`, `)||`none`}.`)}function xm(e){let t=e;return typeof t.statusCode==`number`&&typeof t.responseBody==`string`}function Sm(e){try{let t=JSON.parse(e);if(t&&typeof t==`object`)return t}catch{}return{message:e.trim()||void 0}}function Cm(e){return/did not complete within the timeout/i.test(e.message)}async function Z(e){try{return await e()}catch(e){throw e instanceof t?e:e instanceof Mr?Cm(e)?new t(e.message,c.TIMEOUT,"The session may still be running — check `bl managed-agent session get --session-id <id>` or `session events`."):new t(e.message,c.USAGE):e instanceof Error&&xm(e)?ft(e.statusCode,Sm(e.responseBody)):e instanceof TypeError&&e.message===`fetch failed`?e:e instanceof Error?new t(e.message,c.GENERAL):e}}var wm=w({description:{"en-US":`Validate an agents.yaml configuration (offline)`,"zh-CN":`离线验证 agents.yaml 配置`},auth:`none`,usageArgs:`[--file <path>]`,flags:{file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Config file path (default: agents.yaml)`,"zh-CN":`配置文件路径(默认:agents.yaml)`}}},exampleArgs:[``,`--file agents.yaml`],notes:lm,async run(e){let{settings:n,flags:r}=e,i=T(n.output),a=r.file??`agents.yaml`,o=await Z(async()=>{let{config:t}=await ym(e,a,{credentials:`none`});return $r(t)}),s=o.filter(e=>e.severity===`error`).length;if(i===`json`)A({valid:s===0,diagnostics:o},i);else{for(let e of o){let t=e.resource?` (${e.resource.type}.${e.resource.name})`:``;k(`[${e.severity}] ${e.message}${t}`)}s===0&&k(`Configuration is valid.`)}if(s>0)throw new t(`Validation failed with ${s} error(s).`,c.GENERAL)}});function Tm(e){return`${e.type}.${e.name} (${e.provider})`}async function Q(e){let t=console.log,n=console.info,r=(...e)=>{process.stderr.write(`${e.map(e=>String(e)).join(` `)}\n`)};console.log=r,console.info=r;try{return await e()}finally{console.log=t,console.info=n}}function Em(e){process.stderr.write(`${e.message}\n`)}var Dm=w({description:{"en-US":`Show what changes would be applied to agent infrastructure`,"zh-CN":`显示将应用到 Agent 基础设施的变更`},auth:`apiKey`,usageArgs:`[--file <path>] [--provider <name>] [--no-refresh] [--refresh-only]`,flags:{file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Config file path (default: agents.yaml)`,"zh-CN":`配置文件路径(默认:agents.yaml)`}},provider:{type:`string`,valueHint:`<name>`,description:{"en-US":`Target provider (default: all configured)`,"zh-CN":`目标 Provider(默认:全部已配置项)`}},noRefresh:{type:`switch`,description:{"en-US":`Skip refreshing state from remote before planning`,"zh-CN":`规划前跳过从远端刷新状态`}},refreshOnly:{type:`switch`,description:{"en-US":`Refresh state and show drift without planning remote mutations`,"zh-CN":`刷新状态并显示漂移,不规划远端变更`}}},exampleArgs:[``,`--provider bailian`,`--no-refresh`],notes:[...Y,{"en-US":`--no-refresh and --dry-run plan offline from local config and state: no remote requests, no state writes, provider keys are not checked.`,"zh-CN":`--no-refresh 和 --dry-run 基于本地配置与 State 离线规划:不发送远端请求、不写入 State,也不检查 Provider Key。`}],async run(e){let{settings:n,flags:r}=e,i=T(n.output),a=r.file??`agents.yaml`,o=!!r.noRefresh||n.dryRun,s=(await Z(()=>Q(async()=>{let t=await X(e,a,{credentials:o?`none`:`all`});return bm(t,r.provider),qr(t,{provider:r.provider,refresh:!o,quiet:i===`json`,onFeedback:i===`json`?void 0:Em})}))).plan,l=s.diagnostics.some(e=>e.severity===`error`);if(i===`json`){if(A(s,i),l)throw new t(`Plan contains errors.`,c.GENERAL);return}for(let e of s.diagnostics)k(`[${e.severity}] ${e.code}: ${e.message}`);if(l)throw new t(`Plan contains errors.`,c.GENERAL);let u=s.actions.filter(e=>e.action===`create`),d=s.actions.filter(e=>e.action===`update`),f=s.actions.filter(e=>e.action===`delete`);if(u.length+d.length+f.length===0){k(`No changes. Infrastructure is up-to-date.`),r.refreshOnly&&k(`Refresh-only mode: no remote mutations were performed.`);return}k(`
|
|
2763
2844
|
Planned actions:
|
|
2764
|
-
`);for(let e of u)k(` + ${gm(e.address)}`);for(let e of d)k(` ~ ${gm(e.address)}`),e.reason&&k(` ${e.reason}`);for(let e of f)k(` - ${gm(e.address)}`);k(`\nPlan: ${u.length} to create, ${d.length} to update, ${f.length} to destroy.`),r.refreshOnly&&k(`Refresh-only mode: no remote mutations will be performed.`)}}),ym=w({description:`Apply planned changes to create/update/delete agent resources`,auth:`apiKey`,usageArgs:`[--file <path>] [--provider <name>] [--yes] [--concurrency <n>]`,flags:{file:{type:`string`,valueHint:`<path>`,description:`Config file path (default: agents.yaml)`},provider:{type:`string`,valueHint:`<name>`,description:`Target provider (default: all configured)`},yes:{type:`switch`,description:`Confirm and apply without an interactive prompt (required to mutate)`},noRefresh:{type:`switch`,description:`Skip refreshing state from remote before planning`},concurrency:{type:`number`,valueHint:`<n>`,description:`Max independent resources to apply in parallel (default 6, max 10)`}},exampleArgs:[`--yes`,`--provider bailian --yes`],notes:Y,async run(e){let{settings:n,flags:r}=e,i=T(n.output),a=r.file??`agents.yaml`;if(n.dryRun){A({would_apply:{provider:r.provider??`all`,refresh:!r.noRefresh,concurrency:r.concurrency},config_file:a,hint:"Run `managed-agent plan` to preview the exact resource changes."},i);return}let o=await Z(()=>Q(async()=>{let t=await X(e,a);return dm(t,r.provider),Gr(t,{provider:r.provider,refresh:!r.noRefresh,quiet:!0,onFeedback:_m})})),c=o.plan,l=e=>{i===`json`?process.stderr.write(`${e}\n`):k(e)};if(c.diagnostics.some(e=>e.severity===`error`)){for(let e of c.diagnostics)e.severity===`error`&&l(`[error] ${e.code}: ${e.message}`);throw new t(`Cannot apply: resolve the errors above first.`,s.GENERAL)}let u=c.actions.filter(e=>e.action!==`no-op`);if(u.length===0){i===`json`?A({succeeded:0,failed:0,skipped:0,results:[]},i):k(`No changes. Infrastructure is up-to-date.`);return}let d=u.filter(e=>e.action===`create`).length,f=u.filter(e=>e.action===`update`).length,p=o.destructiveActions;for(let e of u)l(` ${e.action===`create`?`+`:e.action===`update`?`~`:`-`} ${gm(e.address)}`);if(!r.yes)throw new t(`Refusing to apply ${u.length} change(s) (${d} create, ${f} update, ${p.length} destroy) without confirmation.`,s.USAGE,"Review with `bl managed-agent plan`, then re-run with --yes to apply.");let m=await Z(()=>Q(()=>Ir(o,{onFeedback:_m,policy:`force`,concurrency:r.concurrency}))),h=m.results.filter(e=>e.status===`success`).length,g=m.results.filter(e=>e.status===`failed`).length,_=m.results.filter(e=>e.status===`skipped`).length;if(i===`json`?A({succeeded:h,failed:g,skipped:_,results:m.results},i):k(`\nApply finished: ${h} succeeded, ${g} failed, ${_} skipped.`),g>0)throw new t(`Apply failed.`,s.GENERAL)}}),bm=w({description:`Destroy all managed agent resources tracked in state`,auth:`apiKey`,usageArgs:`[--file <path>] [--yes] [--cascade]`,flags:{file:{type:`string`,valueHint:`<path>`,description:`Config file path (default: agents.yaml)`},yes:{type:`switch`,description:`Confirm and destroy without an interactive prompt (required)`},cascade:{type:`switch`,description:`Auto-delete dependent resources (e.g. sessions referencing an environment)`}},exampleArgs:[`--yes`,`--yes --cascade`],notes:Y,async run(e){let{settings:n,flags:r}=e,i=T(n.output),a=r.file??`agents.yaml`;if(n.dryRun){A({would_destroy:{cascade:!!r.cascade},config_file:a,hint:"Run `managed-agent state list` to see the resources tracked in state."},i);return}let o=await Z(()=>Q(async()=>Wr(await X(e,a)))),c=o.resources;if(c.length===0){i===`json`?A({destroyed:0,total:0},i):k(`No resources in state. Nothing to destroy.`);return}for(let e of c){let t=` - ${gm(e.address)} [${e.remote_id}]`;i===`json`?process.stderr.write(`${t}\n`):k(t)}if(!r.yes)throw new t(`Refusing to destroy ${c.length} resource(s) without confirmation.`,s.USAGE,`Re-run with --yes to destroy (add --cascade to remove dependents).`);let l=await Z(()=>Q(()=>Fr(o,{cascade:r.cascade,onCascadeRequired:async()=>!!r.cascade,onResourceResult:e=>{let t=gm(e.resource.address);process.stderr.write(` ${e.status===`success`?`✓`:`✗`} ${t}\n`)}})));if(i===`json`?A({destroyed:l.destroyed,total:l.resources.length},i):k(`\n${l.partial?`Destroy incomplete`:`Destroy complete`}. ${l.destroyed}/${l.resources.length} resources removed.`),l.partial)throw new t(l.results.find(e=>e.status!==`success`)?.error||`Destroy incomplete: ${l.destroyed}/${l.resources.length} resources removed.`,s.GENERAL)}}),xm=w({description:`List resources tracked in agents state`,auth:`none`,usageArgs:`[--file <path>]`,flags:{file:{type:`string`,valueHint:`<path>`,description:`Config file path (default: agents.yaml)`}},exampleArgs:[``,`--file agents.yaml`],notes:em,async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=n.file??`agents.yaml`,a=await Z(()=>Q(async()=>(await X(e,i,{credentials:`none`})).state.listResources()));if(r===`json`){A({resources:a},r);return}if(a.length===0){k(`No resources tracked in state.`);return}let o=[`TYPE`,`NAME`,`PROVIDER`,`REMOTE ID`],s=a.map(e=>[e.address.type,e.address.name,e.address.provider,e.remote_id??`(local)`]);for(let e of j(o,s))k(e);k(`\nTotal: ${a.length}`)}}),Sm=w({description:`Show details of a resource in agents state`,auth:`none`,usageArgs:`--address <provider.type.name> [--file <path>]`,flags:{address:{type:`string`,valueHint:`<provider.type.name>`,description:`Resource state address (required)`,required:!0},file:{type:`string`,valueHint:`<path>`,description:`Config file path (default: agents.yaml)`}},exampleArgs:[`--address bailian.agent.assistant`],notes:em,async run(e){let{settings:n,flags:r}=e,i=T(n.output),a=r.file??`agents.yaml`,o=await Z(()=>Q(async()=>{let t=await X(e,a,{credentials:`none`}),n=Ur(r.address,{requireProvider:!1});return t.state.findResource(n)}));if(!o)throw new t(`Resource not found: ${r.address}`,s.GENERAL);i===`json`?A(o,i):k(JSON.stringify(o,null,2))}}),Cm=w({description:`Remove a resource from state without destroying it remotely`,auth:`none`,usageArgs:`--address <provider.type.name> [--file <path>]`,flags:{address:{type:`string`,valueHint:`<provider.type.name>`,description:`Resource state address (required)`,required:!0},file:{type:`string`,valueHint:`<path>`,description:`Config file path (default: agents.yaml)`}},exampleArgs:[`--address bailian.agent.assistant`],notes:em,async run(e){let{settings:n,flags:r}=e,i=T(n.output),a=r.file??`agents.yaml`;if(n.dryRun){await Z(async()=>{Ur(r.address,{requireProvider:!1})}),A({would_remove:r.address,config_file:a},i);return}await Z(()=>Q(async()=>{let n=await X(e,a,{credentials:`none`}),i=Ur(r.address,{requireProvider:!1}),o=n.state.findResource(i);if(!o)throw new t(`Resource not found: ${r.address}`,s.GENERAL);n.state.removeResource(o.address),await n.state.save()}));let o=`Removed ${r.address} from state (remote resource not deleted).`;i===`json`?A({removed:r.address},i):k(o)}}),wm=w({description:`Import an existing remote resource into agents state`,auth:`apiKey`,usageArgs:`--address <provider.type.name> --remote-id <id> [--resource-version <n>] [--file <path>]`,flags:{address:{type:`string`,valueHint:`<provider.type.name>`,description:`Resource state address (required)`,required:!0},remoteId:{type:`string`,valueHint:`<id>`,description:`Existing remote resource ID to import (required)`,required:!0},resourceVersion:{type:`number`,valueHint:`<n>`,description:`Resource version (for versioned resources like agents)`},file:{type:`string`,valueHint:`<path>`,description:`Config file path (default: agents.yaml)`}},exampleArgs:[`--address bailian.agent.assistant --remote-id agent-abc123`],notes:Y,async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=n.file??`agents.yaml`;if(t.dryRun){await Z(async()=>{Ur(n.address,{requireProvider:!0})}),A({would_import:n.address,remote_id:n.remoteId,resource_version:n.resourceVersion,config_file:i},r);return}await Z(()=>Q(async()=>{let t=Ur(n.address,{requireProvider:!0});await Rr(await X(e,i),t,n.remoteId,{resourceVersion:n.resourceVersion})})),r===`json`?A({imported:n.address,remote_id:n.remoteId},r):k(`Imported ${n.address} (remote_id: ${n.remoteId}) into state.`)}});function Tm(e){return e.type!==`thinking`&&!(e.type===`message`&&e.role===`user`)}function Em(e,t){t||process.stderr.write(`\n[session ${e}]\n`)}function Dm(e){for(let t=e.length-1;t>=0;t--){let n=e[t];if(n?.type===`error`&&n.content?.trim())return n.content}}function Om(e,n){if(e===`failed`)throw new t(n??`Session failed.`,s.GENERAL)}async function km(e,t,n={}){let r=[],i,a;for await(let n of e)if(t?r.push(n):Am(n),n.type===`error`&&n.content?.trim()&&(a=n.content),n.type===`status`&&zr(n.status)){i=n.status,Em(n.status??``,t);break}t&&process.stdout.write(`${JSON.stringify({...n,events:Qr(r)},null,2)}\n`),Om(i,a)}function Am(e){if(Tm(e))if(e.type===`message`&&e.content)process.stdout.write(e.content);else if(e.type===`tool_use`)process.stderr.write(`\n[tool] ${e.tool_name}\n`);else if(e.type===`tool_result`&&e.content){let t=e.content.length>200?`${e.content.slice(0,200)}...`:e.content;process.stderr.write(`${t}\n`)}else e.type===`status`?e.status===`running`&&process.stderr.write(`
|
|
2845
|
+
`);for(let e of u)k(` + ${Tm(e.address)}`);for(let e of d)k(` ~ ${Tm(e.address)}`),e.reason&&k(` ${e.reason}`);for(let e of f)k(` - ${Tm(e.address)}`);k(`\nPlan: ${u.length} to create, ${d.length} to update, ${f.length} to destroy.`),r.refreshOnly&&k(`Refresh-only mode: no remote mutations will be performed.`)}}),Om=w({description:{"en-US":`Apply planned changes to create/update/delete agent resources`,"zh-CN":`应用规划的变更,创建、更新或删除 Agent 资源`},auth:`apiKey`,usageArgs:`[--file <path>] [--provider <name>] [--yes] [--concurrency <n>]`,flags:{file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Config file path (default: agents.yaml)`,"zh-CN":`配置文件路径(默认:agents.yaml)`}},provider:{type:`string`,valueHint:`<name>`,description:{"en-US":`Target provider (default: all configured)`,"zh-CN":`目标 Provider(默认:全部已配置项)`}},yes:{type:`switch`,description:{"en-US":`Confirm and apply without an interactive prompt (required to mutate)`,"zh-CN":`无需交互提示直接确认并应用(执行变更时必填)`}},noRefresh:{type:`switch`,description:{"en-US":`Skip refreshing state from remote before planning`,"zh-CN":`规划前跳过从远端刷新状态`}},concurrency:{type:`number`,valueHint:`<n>`,description:{"en-US":`Max independent resources to apply in parallel (default 6, max 10)`,"zh-CN":`最大并行应用资源数(默认:6,最多:10)`}}},exampleArgs:[`--yes`,`--provider bailian --yes`],notes:Y,async run(e){let{settings:n,flags:r}=e,i=T(n.output),a=r.file??`agents.yaml`;if(n.dryRun){A({would_apply:{provider:r.provider??`all`,refresh:!r.noRefresh,concurrency:r.concurrency},config_file:a,hint:"Run `managed-agent plan` to preview the exact resource changes."},i);return}let o=await Z(()=>Q(async()=>{let t=await X(e,a);return bm(t,r.provider),qr(t,{provider:r.provider,refresh:!r.noRefresh,quiet:!0,onFeedback:Em})})),s=o.plan,l=e=>{i===`json`?process.stderr.write(`${e}\n`):k(e)};if(s.diagnostics.some(e=>e.severity===`error`)){for(let e of s.diagnostics)e.severity===`error`&&l(`[error] ${e.code}: ${e.message}`);throw new t(`Cannot apply: resolve the errors above first.`,c.GENERAL)}let u=s.actions.filter(e=>e.action!==`no-op`);if(u.length===0){i===`json`?A({succeeded:0,failed:0,skipped:0,results:[]},i):k(`No changes. Infrastructure is up-to-date.`);return}let d=u.filter(e=>e.action===`create`).length,f=u.filter(e=>e.action===`update`).length,p=o.destructiveActions;for(let e of u)l(` ${e.action===`create`?`+`:e.action===`update`?`~`:`-`} ${Tm(e.address)}`);if(!r.yes)throw new t(`Refusing to apply ${u.length} change(s) (${d} create, ${f} update, ${p.length} destroy) without confirmation.`,c.USAGE,"Review with `bl managed-agent plan`, then re-run with --yes to apply.");let m=await Z(()=>Q(()=>Rr(o,{onFeedback:Em,policy:`force`,concurrency:r.concurrency}))),h=m.results.filter(e=>e.status===`success`).length,g=m.results.filter(e=>e.status===`failed`).length,_=m.results.filter(e=>e.status===`skipped`).length;if(i===`json`?A({succeeded:h,failed:g,skipped:_,results:m.results},i):k(`\nApply finished: ${h} succeeded, ${g} failed, ${_} skipped.`),g>0)throw new t(`Apply failed.`,c.GENERAL)}}),km=w({description:{"en-US":`Destroy all managed agent resources tracked in state`,"zh-CN":`销毁 State 中跟踪的全部托管 Agent 资源`},auth:`apiKey`,usageArgs:`[--file <path>] [--yes] [--cascade]`,flags:{file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Config file path (default: agents.yaml)`,"zh-CN":`配置文件路径(默认:agents.yaml)`}},yes:{type:`switch`,description:{"en-US":`Confirm and destroy without an interactive prompt (required)`,"zh-CN":`无需交互提示直接确认并销毁(必填)`}},cascade:{type:`switch`,description:{"en-US":`Auto-delete dependent resources (e.g. sessions referencing an environment)`,"zh-CN":`自动删除依赖资源(例如引用某个环境的 Session)`}}},exampleArgs:[`--yes`,`--yes --cascade`],notes:Y,async run(e){let{settings:n,flags:r}=e,i=T(n.output),a=r.file??`agents.yaml`;if(n.dryRun){A({would_destroy:{cascade:!!r.cascade},config_file:a,hint:"Run `managed-agent state list` to see the resources tracked in state."},i);return}let o=await Z(()=>Q(async()=>Kr(await X(e,a)))),s=o.resources;if(s.length===0){i===`json`?A({destroyed:0,total:0},i):k(`No resources in state. Nothing to destroy.`);return}for(let e of s){let t=` - ${Tm(e.address)} [${e.remote_id}]`;i===`json`?process.stderr.write(`${t}\n`):k(t)}if(!r.yes)throw new t(`Refusing to destroy ${s.length} resource(s) without confirmation.`,c.USAGE,`Re-run with --yes to destroy (add --cascade to remove dependents).`);let l=await Z(()=>Q(()=>Lr(o,{cascade:r.cascade,onCascadeRequired:async()=>!!r.cascade,onResourceResult:e=>{let t=Tm(e.resource.address);process.stderr.write(` ${e.status===`success`?`✓`:`✗`} ${t}\n`)}})));if(i===`json`?A({destroyed:l.destroyed,total:l.resources.length},i):k(`\n${l.partial?`Destroy incomplete`:`Destroy complete`}. ${l.destroyed}/${l.resources.length} resources removed.`),l.partial)throw new t(l.results.find(e=>e.status!==`success`)?.error||`Destroy incomplete: ${l.destroyed}/${l.resources.length} resources removed.`,c.GENERAL)}}),Am=w({description:{"en-US":`List resources tracked in agents state`,"zh-CN":`列出 Agent State 中跟踪的资源`},auth:`none`,usageArgs:`[--file <path>]`,flags:{file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Config file path (default: agents.yaml)`,"zh-CN":`配置文件路径(默认:agents.yaml)`}}},exampleArgs:[``,`--file agents.yaml`],notes:lm,async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=n.file??`agents.yaml`,a=await Z(()=>Q(async()=>(await X(e,i,{credentials:`none`})).state.listResources()));if(r===`json`){A({resources:a},r);return}if(a.length===0){k(`No resources tracked in state.`);return}let o=[`TYPE`,`NAME`,`PROVIDER`,`REMOTE ID`],s=a.map(e=>[e.address.type,e.address.name,e.address.provider,e.remote_id??`(local)`]);for(let e of j(o,s))k(e);k(`\nTotal: ${a.length}`)}}),jm=w({description:{"en-US":`Show details of a resource in agents state`,"zh-CN":`显示 Agent State 中资源的详情`},auth:`none`,usageArgs:`--address <provider.type.name> [--file <path>]`,flags:{address:{type:`string`,valueHint:`<provider.type.name>`,description:{"en-US":`Resource state address (required)`,"zh-CN":`资源 State 地址(必填)`},required:!0},file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Config file path (default: agents.yaml)`,"zh-CN":`配置文件路径(默认:agents.yaml)`}}},exampleArgs:[`--address bailian.agent.assistant`],notes:lm,async run(e){let{settings:n,flags:r}=e,i=T(n.output),a=r.file??`agents.yaml`,o=await Z(()=>Q(async()=>{let t=await X(e,a,{credentials:`none`}),n=Gr(r.address,{requireProvider:!1});return t.state.findResource(n)}));if(!o)throw new t(`Resource not found: ${r.address}`,c.GENERAL);i===`json`?A(o,i):k(JSON.stringify(o,null,2))}}),Mm=w({description:{"en-US":`Remove a resource from state without destroying it remotely`,"zh-CN":`从 State 中移除资源,但不销毁远端资源`},auth:`none`,usageArgs:`--address <provider.type.name> [--file <path>]`,flags:{address:{type:`string`,valueHint:`<provider.type.name>`,description:{"en-US":`Resource state address (required)`,"zh-CN":`资源 State 地址(必填)`},required:!0},file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Config file path (default: agents.yaml)`,"zh-CN":`配置文件路径(默认:agents.yaml)`}}},exampleArgs:[`--address bailian.agent.assistant`],notes:lm,async run(e){let{settings:n,flags:r}=e,i=T(n.output),a=r.file??`agents.yaml`;if(n.dryRun){await Z(async()=>{Gr(r.address,{requireProvider:!1})}),A({would_remove:r.address,config_file:a},i);return}await Z(()=>Q(async()=>{let n=await X(e,a,{credentials:`none`}),i=Gr(r.address,{requireProvider:!1}),o=n.state.findResource(i);if(!o)throw new t(`Resource not found: ${r.address}`,c.GENERAL);n.state.removeResource(o.address),await n.state.save()}));let o=`Removed ${r.address} from state (remote resource not deleted).`;i===`json`?A({removed:r.address},i):k(o)}}),Nm=w({description:{"en-US":`Import an existing remote resource into agents state`,"zh-CN":`将已有远端资源导入 Agent State`},auth:`apiKey`,usageArgs:`--address <provider.type.name> --remote-id <id> [--resource-version <n>] [--file <path>]`,flags:{address:{type:`string`,valueHint:`<provider.type.name>`,description:{"en-US":`Resource state address (required)`,"zh-CN":`资源 State 地址(必填)`},required:!0},remoteId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Existing remote resource ID to import (required)`,"zh-CN":`要导入的已有远端资源 ID(必填)`},required:!0},resourceVersion:{type:`number`,valueHint:`<n>`,description:{"en-US":`Resource version (for versioned resources like agents)`,"zh-CN":`资源版本(用于 Agent 等带版本的资源)`}},file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Config file path (default: agents.yaml)`,"zh-CN":`配置文件路径(默认:agents.yaml)`}}},exampleArgs:[`--address bailian.agent.assistant --remote-id agent-abc123`],notes:Y,async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=n.file??`agents.yaml`;if(t.dryRun){await Z(async()=>{Gr(n.address,{requireProvider:!0})}),A({would_import:n.address,remote_id:n.remoteId,resource_version:n.resourceVersion,config_file:i},r);return}await Z(()=>Q(async()=>{let t=Gr(n.address,{requireProvider:!0});await Br(await X(e,i),t,n.remoteId,{resourceVersion:n.resourceVersion})})),r===`json`?A({imported:n.address,remote_id:n.remoteId},r):k(`Imported ${n.address} (remote_id: ${n.remoteId}) into state.`)}});function Pm(e){return e.type!==`thinking`&&!(e.type===`message`&&e.role===`user`)}function Fm(e,t){t||process.stderr.write(`\n[session ${e}]\n`)}function Im(e){for(let t=e.length-1;t>=0;t--){let n=e[t];if(n?.type===`error`&&n.content?.trim())return n.content}}function Lm(e,n){if(e===`failed`)throw new t(n??`Session failed.`,c.GENERAL)}async function Rm(e,t,n={}){let r=[],i,a;for await(let n of e)if(t?r.push(n):zm(n),n.type===`error`&&n.content?.trim()&&(a=n.content),n.type===`status`&&Vr(n.status)){i=n.status,Fm(n.status??``,t);break}t&&process.stdout.write(`${JSON.stringify({...n,events:ei(r)},null,2)}\n`),Lm(i,a)}function zm(e){if(Pm(e))if(e.type===`message`&&e.content)process.stdout.write(e.content);else if(e.type===`tool_use`)process.stderr.write(`\n[tool] ${e.tool_name}\n`);else if(e.type===`tool_result`&&e.content){let t=e.content.length>200?`${e.content.slice(0,200)}...`:e.content;process.stderr.write(`${t}\n`)}else e.type===`status`?e.status===`running`&&process.stderr.write(`
|
|
2765
2846
|
[session running]
|
|
2766
|
-
`):e.type===`error`&&process.stderr.write(`\n[error] ${e.content??`unknown error`}\n`)}function jm(e,t,n={}){if(t)process.stdout.write(`${JSON.stringify({...n,events:Qr(e.result.events),has_more:e.result.has_more,next_page:e.result.next_page},null,2)}\n`);else{for(let t of e.result.events)Am(t);Em(e.terminalStatus,t)}Om(e.terminalStatus,Dm(e.result.events))}function Mm(e){return e?e.split(`,`).map(e=>e.trim()).filter(Boolean):void 0}var Nm=w({description:`Create a new session for an agent`,auth:`apiKey`,usageArgs:`[--agent <name>] [--environment <name>] [--title <title>] [--file <path>]`,flags:{file:{type:`string`,valueHint:`<path>`,description:`Config file path (default: agents.yaml)`},agent:{type:`string`,valueHint:`<name>`,description:`Agent name (auto-detected when only one agent is configured)`},environment:{type:`string`,valueHint:`<name>`,description:`Override agent's declared environment`},vault:{type:`string`,valueHint:`<name>`,description:`Override agent's declared vault`},memoryStores:{type:`string`,valueHint:`<names>`,description:`Override agent's memory stores (comma-separated)`},title:{type:`string`,valueHint:`<title>`,description:`Session title`},provider:{type:`string`,valueHint:`<name>`,description:`Target provider (multi-provider agents)`}},exampleArgs:[``,`--agent assistant`,`--agent assistant --title 'debug run'`],notes:Y,async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=n.file??`agents.yaml`;if(t.dryRun){A({would_create_session:{agent:n.agent??`auto`,provider:n.provider??`auto`,environment:n.environment,vault:n.vault,memory_stores:Mm(n.memoryStores),title:n.title},config_file:i},r);return}let{agentName:a,session:o}=await Z(()=>Q(async()=>Nr(await X(e,i),{agent:n.agent,provider:n.provider,environment:n.environment,vault:n.vault,memoryStores:Mm(n.memoryStores),title:n.title})));if(r===`json`){A({agent:a,session:o},r);return}k(`Session created: ${o.id}`),k(` Agent: ${a}`),k(` Environment: ${o.environment_id}`),k(` Status: ${o.status}`),o.vault_ids.length&&k(` Vaults: ${o.vault_ids.join(`, `)}`),o.memory_store_ids.length&&k(` Memory: ${o.memory_store_ids.join(`, `)}`)}});async function Pm(e,t){let n=await e(),r=[...n.items],i=n.hasMore,a=n.nextPage;for(;t&&a;){let t=await e(a);r.push(...t.items),i=t.hasMore,a=t.nextPage}return{items:r,hasMore:i,nextPage:a}}var Fm=w({description:`List sessions from the provider`,auth:`apiKey`,usageArgs:`[--agent <name>] [--all] [--provider <name>] [--file <path>]`,flags:{file:{type:`string`,valueHint:`<path>`,description:`Config file path (default: agents.yaml)`},agent:{type:`string`,valueHint:`<name>`,description:`Filter by agent name`},all:{type:`switch`,description:`Fetch all pages by following the cursor`},provider:{type:`string`,valueHint:`<name>`,description:`Target provider`}},exampleArgs:[``,`--agent assistant`,`--all`],notes:Y,async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=n.file??`agents.yaml`,{items:a,hasMore:o}=await Z(()=>Q(async()=>{let t=await X(e,i);return Pm(async e=>{let r=await Vr(t,{agent:n.agent,provider:n.provider,filter:e?{page:e}:void 0});return{items:r.summaries,hasMore:r.hasMore,nextPage:r.nextPage}},n.all)})),s=a.map(e=>e.session);if(r===`json`){A({sessions:s,has_more:o},r);return}if(s.length===0){k(`No sessions found.`);return}let c=new Map(a.filter(e=>e.agentName).map(e=>[e.session.id,e.agentName])),l=[`ID`,`TITLE`,`AGENT`,`STATUS`,`CREATED`],u=s.map(e=>[e.id,(e.title??``).slice(0,20),c.get(e.id)??e.agent_id.slice(0,12),e.status,e.created_at]);for(let e of j(l,u))k(e);k(`\nTotal: ${s.length}`),o&&k(`More sessions available. Use --all to fetch all.`)}}),Im=w({description:`Get details of a session`,auth:`apiKey`,usageArgs:`--session-id <id> [--provider <name>] [--file <path>]`,flags:{sessionId:{type:`string`,valueHint:`<id>`,description:`Session ID (required)`,required:!0},file:{type:`string`,valueHint:`<path>`,description:`Config file path (default: agents.yaml)`},provider:{type:`string`,valueHint:`<name>`,description:`Target provider`}},exampleArgs:[`--session-id sess_abc123`],notes:Y,async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=n.file??`agents.yaml`,a=await Z(()=>Q(async()=>Lr(await X(e,i),n.sessionId,n.provider)));if(r===`json`){A(a,r);return}k(` ID: ${a.id}`),k(` Agent: ${a.agent_id}`),k(` Environment: ${a.environment_id}`),k(` Status: ${a.status}`),a.title&&k(` Title: ${a.title}`),k(` Created: ${a.created_at}`),k(` Updated: ${a.updated_at}`)}}),Lm=w({description:`Delete a session`,auth:`apiKey`,usageArgs:`--session-id <id> [--provider <name>] [--file <path>]`,flags:{sessionId:{type:`string`,valueHint:`<id>`,description:`Session ID (required)`,required:!0},file:{type:`string`,valueHint:`<path>`,description:`Config file path (default: agents.yaml)`},provider:{type:`string`,valueHint:`<name>`,description:`Target provider`}},exampleArgs:[`--session-id sess_abc123`],notes:Y,async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=n.file??`agents.yaml`;if(t.dryRun){A({would_delete_session:n.sessionId,provider:n.provider??`auto`,config_file:i},r);return}await Z(()=>Q(async()=>{await Pr(await X(e,i),n.sessionId,n.provider)})),r===`json`?A({deleted:n.sessionId},r):k(`Session ${n.sessionId} deleted.`)}}),Rm=w({description:`Create a session, send a message, and stream the response`,auth:`apiKey`,usageArgs:`--prompt <text> [--agent <name>] [--no-stream] [--file <path>]`,flags:{prompt:{type:`string`,valueHint:`<text>`,description:`Prompt to send (required)`,required:!0},file:{type:`string`,valueHint:`<path>`,description:`Config file path (default: agents.yaml)`},agent:{type:`string`,valueHint:`<name>`,description:`Agent name (auto-detected when only one agent is configured)`},environment:{type:`string`,valueHint:`<name>`,description:`Override agent's declared environment`},vault:{type:`string`,valueHint:`<name>`,description:`Override agent's declared vault`},memoryStores:{type:`string`,valueHint:`<names>`,description:`Override agent's memory stores (comma-separated)`},title:{type:`string`,valueHint:`<title>`,description:`Session title`},provider:{type:`string`,valueHint:`<name>`,description:`Target provider`},noStream:{type:`switch`,description:`Use polling instead of SSE streaming`}},exampleArgs:[`--prompt "hello"`,`--agent assistant --prompt "summarize this repo"`],notes:[...Y,"--output json emits one envelope: { session_id, provider, agent, events } — read session_id to chain `session send/get/events/delete`."],async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=n.file??`agents.yaml`,a=r===`json`,o={agent:n.agent,provider:n.provider,environment:n.environment,vault:n.vault,memoryStores:Mm(n.memoryStores),title:n.title};if(t.dryRun){A({would_run:{prompt:n.prompt,agent:n.agent??`auto`,provider:n.provider??`auto`,environment:n.environment,vault:n.vault,memory_stores:o.memoryStores,title:n.title,mode:n.noStream?`polling`:`streaming`},config_file:i},r);return}await Z(()=>Q(async()=>{let t=await X(e,i);if(n.noStream){let e=await Xr(t,n.prompt,o);a||process.stderr.write(`Session created: ${e.session.id}\n`),jm(e,a,{session_id:e.session.id,provider:e.provider,agent:e.agentName})}else{let e=await Yr(t,n.prompt,o);a||process.stderr.write(`Session created: ${e.session.id}\n`),await km(e.events,a,{session_id:e.session.id,provider:e.provider,agent:e.agentName})}}))}}),zm=w({description:`Send a message to an existing session and stream the response`,auth:`apiKey`,usageArgs:`--session-id <id> --message <text> [--no-stream] [--file <path>]`,flags:{sessionId:{type:`string`,valueHint:`<id>`,description:`Session ID (required)`,required:!0},message:{type:`string`,valueHint:`<text>`,description:`Message to send (required)`,required:!0},file:{type:`string`,valueHint:`<path>`,description:`Config file path (default: agents.yaml)`},provider:{type:`string`,valueHint:`<name>`,description:`Target provider`},noStream:{type:`switch`,description:`Use polling instead of SSE streaming`}},exampleArgs:[`--session-id sess_abc123 --message "continue"`],notes:Y,async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=n.file??`agents.yaml`,a=r===`json`;if(t.dryRun){A({would_send:{session_id:n.sessionId,message:n.message,provider:n.provider??`auto`,mode:n.noStream?`polling`:`streaming`},config_file:i},r);return}await Z(()=>Q(async()=>{let t=await X(e,i);n.noStream?jm(await qr(t,n.sessionId,n.message,{provider:n.provider}),a,{session_id:n.sessionId}):await km(await Jr(t,n.sessionId,n.message,{provider:n.provider}),a,{session_id:n.sessionId})}))}}),Bm=w({description:`List event history for a session`,auth:`apiKey`,usageArgs:`--session-id <id> [--limit <n>] [--all] [--file <path>]`,flags:{sessionId:{type:`string`,valueHint:`<id>`,description:`Session ID (required)`,required:!0},file:{type:`string`,valueHint:`<path>`,description:`Config file path (default: agents.yaml)`},provider:{type:`string`,valueHint:`<name>`,description:`Target provider`},limit:{type:`number`,valueHint:`<n>`,description:`Maximum number of events to fetch`},all:{type:`switch`,description:`Fetch all pages by following the cursor`}},exampleArgs:[`--session-id sess_abc123`,`--session-id sess_abc123 --all`],notes:Y,async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=n.file??`agents.yaml`,{items:a,hasMore:o}=await Z(()=>Q(async()=>{let t=await X(e,i);return Pm(async e=>{let r=await Br(t,n.sessionId,{provider:n.provider,limit:n.limit,page_token:e});return{items:r.events,hasMore:r.has_more,nextPage:r.next_page}},n.all)}));if(r===`json`){A({events:Qr(a),has_more:o},r);return}if(a.length===0){k(`No events found.`);return}let s=[`#`,`TYPE`,`CONTENT`],c=a.map((e,t)=>{let n=``;return n=e.type===`message`?(e.content??``).slice(0,60):e.type===`tool_use`?e.tool_name??``:e.type===`tool_result`?(e.content??``).slice(0,60):e.type===`status`?e.status??``:e.type===`error`?(e.content??``).slice(0,60):e.raw_type,[String(t+1),e.type,n]});for(let e of j(s,c))k(e);k(`\nTotal: ${a.length}`),o&&k(`More events available. Use --all to fetch all.`)}});const Vm=[`custom`,`official`,`all`];var Hm=w({description:`List skills from the provider's skill catalog`,auth:`apiKey`,usageArgs:`[--source custom|official|all] [--provider <name>] [--file <path>]`,flags:{file:{type:`string`,valueHint:`<path>`,description:`Config file path (default: agents.yaml)`},source:{type:`string`,valueHint:`<source>`,description:`Skill catalog: custom (workspace-uploaded, default), official (built-in), or all (both catalogs in one call)`},provider:{type:`string`,valueHint:`<name>`,description:`Target provider`}},exampleArgs:[``,`--source official`,`--source all --output json`,`--source custom --provider bailian`],notes:[...Y,`Providers without a skill listing API (e.g. ark) return an empty list.`,"For agent-driven skill selection, use `--source all --output json`: one call returns both catalogs with per-skill `source` and `description` fields to pick from.",`When generating a task that needs a suitable skill, call this command to match official or custom skills before wiring them into the task.`],validate:e=>e.source&&!Vm.includes(e.source)?`--source must be one of: custom, official, all.`:void 0,async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=n.file??`agents.yaml`,a=n.source??`custom`,o=await Z(()=>Q(async()=>{let t=await X(e,i);if(a!==`all`)return Hr(t,{provider:n.provider,source:a});let[r,o]=await Promise.all([Hr(t,{provider:n.provider,source:`custom`}),Hr(t,{provider:n.provider,source:`official`})]);return[...r,...o]}));if(r===`json`){A({source:a,skills:o},r);return}if(o.length===0){k(a===`all`?`No skills found.`:`No ${a} skills found.`);return}let s=[`ID`,`NAME`,`SOURCE`,`STATUS`,`VERSION`,`CREATED`],c=o.map(e=>[e.id,e.name.slice(0,32),e.source,e.status,e.latest_version??`-`,e.created_at??`-`]);for(let e of j(s,c))k(e);k(`\nTotal: ${o.length} (${a})`)}});const $={loginInfo:`zeldaEasy.cornerstone-portal.cs-console.loginInfo`,initSpace:`zeldaEasy.bailian-dash-workspace.space.initSpace`,queryBuyResult:`zeldaEasy.bailian-commerce.bill.queryBuyPostpaidResult`,commodityOrderInfo:`zeldaEasy.bailian-commerce.bill.postpaidCommodityOrderInfo`,buyCommodity:`zeldaEasy.bailian-commerce.bill.buyPostpaidCommodity`},Um={accessKeyId:{type:`string`,valueHint:`<id>`,description:`Alibaba Cloud Access Key ID`},accessKeySecret:{type:`string`,valueHint:`<secret>`,description:`Alibaba Cloud Access Key Secret`},securityToken:{type:`string`,valueHint:`<token>`,description:`Alibaba Cloud STS Security Token (optional)`}},Wm=1e3;function Gm(e){return new Promise(t=>setTimeout(t,e))}function Km(e){return e?.data?.DataV2?.data?.data}function qm(e){let t=e?.data?.data;if(!Array.isArray(t)||t.length===0)return;let n=(t.find(e=>e?.defaultAgent===!0)??t[0])?.tenantId,r=typeof n==`string`?Number(n):n;return typeof r==`number`&&Number.isFinite(r)?r:void 0}var Jm=w({description:`Initialize Bailian workspace and activate postpaid services`,auth:`none`,usageArgs:`--access-key-id <id> --access-key-secret <secret> [--security-token <token>]`,flags:Um,exampleArgs:[`--access-key-id LTAIxxxxx --access-key-secret xxxxx`],async run(e){let{settings:n,flags:r}=e,i=T(n.output);if(n.dryRun){A({apis:[{step:0,api:`GenerateCLIAccessToken`,description:`Generate CLI access token from AK/SK`},{step:1,api:$.loginInfo,description:`Check login & workspace status`},{step:2,api:$.initSpace,description:`Initialize workspace (if needed)`},{step:3,api:`CreateUser`,description:`Create console user via BailianControl OpenAPI (CreateUser)`},{step:4,api:`ListWorkspaces`,description:`List workspaces to resolve agentId`},{step:5,api:`ResetPolicies4Agent`,description:`Authorize user permissions`},{step:6,api:$.queryBuyResult,description:`Query postpaid order status`},{step:7,api:$.commodityOrderInfo,description:`Query commodity activation status`},{step:8,api:$.buyCommodity,description:`Activate postpaid commodities (if needed)`}]},i);return}let{accessKeyId:a,accessKeySecret:o}=r;if(!a||!o)throw new t(`workspace init requires --access-key-id and --access-key-secret.`,s.USAGE);let c=r.securityToken||void 0,l=(await Pe({identity:e.identity,settings:n,baseUrl:e.client.baseUrl,accessKeyId:a,accessKeySecret:o,securityToken:c})).cliAccessToken;if(!l)throw new t(`Failed to generate CLI access token from AK/SK.`,s.GENERAL);let u=ve(n),d={region:u.consoleRegion,site:u.consoleSite,...u.consoleSwitchAgent==null?{}:{switchAgent:u.consoleSwitchAgent},token:l},f=n.verbose,p=async(e,r={})=>{f&&process.stderr.write(`> ${e}\n`);try{let t=await ne(d,n.timeout,{api:e,data:r},n);return f&&process.stderr.write(`< ${JSON.stringify(t)}\n`),t}catch(e){if(f){let n=e instanceof t?e.rawResponse??e.message:String(e);process.stderr.write(`< ERROR: ${n}\n`)}throw e}};k(`Checking workspace status...`);let m=Km(await p($.loginInfo));m?.spaceInited===!0?k(`Workspace already initialized.`):(k(`Initializing workspace...`),await p($.initSpace),k(`Workspace initialized.`));let h=m?.aliyun?.uid;if(typeof h!=`string`||h.length===0)throw new t(`Console login info did not include aliyun.uid.`,s.GENERAL);let g={identity:e.identity,settings:n,baseUrl:e.client.baseUrl,regionId:u.consoleRegion,accessKeyId:a,accessKeySecret:o,securityToken:c};try{await se({...g,reqDTO:{outerKey:h,nickName:h,userName:h}})}catch(e){if(!(e instanceof t)||!/already exists/i.test(e.message))throw e;k(`Console user already exists, continuing.`)}k(`Resolving workspace agent...`);let _=qm(await tt(g));if(_==null)throw new t(`Could not resolve agentId from ListWorkspaces response.`,s.GENERAL,`Re-run with --verbose to inspect the ListWorkspaces response body.`);k(`Authorizing user permissions...`),await It({...g,outerKey:h,agentId:_,policyIndexList:[1]}),await Ym(p,i)}});async function Ym(e,n){k(`Checking service activation status...`);let r;for(let t=0;t<20;t++){let n=Km(await e($.queryBuyResult));if(r=typeof n==`string`?n:n?.result,r!==`buying`)break;t===0&&k(`Service activation in progress, polling...`),await Gm(Wm)}if(r===`fail`)throw new t(`Service activation failed.`,s.GENERAL);if(r===`success`){await Qm(e,n);return}await Zm(e,n)}function Xm(e){let t=Km(e);return Array.isArray(t)?t:[]}async function Zm(e,t){let n=Xm(await e($.commodityOrderInfo)),r=n.filter(e=>e.status===11);if(r.length>0){k(`Warning: Some services are overdue:`);for(let e of r)k(` - ${e.commodityCode}`)}let i=n.filter(e=>e.status===1);if(i.length>0){k(`Activating ${i.length} postpaid services...`),await e($.buyCommodity),await Qm(e,t);return}A({status:`ready`,activeServices:n.filter(e=>e.status===10).map(e=>e.commodityCode)},t)}async function Qm(e,n){k(`Waiting for services to activate...`);for(let t=0;t<20;t++){let t=Xm(await e($.commodityOrderInfo));if(t.filter(e=>e.status!==10&&e.status!==11).length===0){let e=t.filter(e=>e.status===11);if(e.length>0){k(`Warning: Some services are overdue:`);for(let t of e)k(` - ${t.commodityCode}`)}A({status:`ready`,activeServices:t.filter(e=>e.status===10).map(e=>e.commodityCode)},n);return}await Gm(Wm)}throw new t(`Timed out waiting for services to activate.`,s.TIMEOUT)}var $m=w({description:`Install or upgrade an allowlisted Command Pack`,auth:`none`,usageArgs:`--package <name[@version]>`,flags:{package:{type:`string`,valueHint:`<name[@version]>`,description:`Allowlisted Command Pack package and optional version or tag`,required:!0}},exampleArgs:[`--package @ali/bailian-plugin-agent`,`--package @ali/bailian-plugin-agent@beta`],async run(e){A({installed:await e.commandPacks.install(e.flags.package)},T(e.settings.output))}}),eh=w({description:`Link an allowlisted local Command Pack for development`,auth:`none`,usageArgs:`--path <directory>`,flags:{path:{type:`string`,valueHint:`<directory>`,description:`Local Command Pack package directory`,required:!0}},exampleArgs:[`--path ../bailian-plugin-agent`],async run(e){A({linked:await e.commandPacks.link(e.flags.path)},T(e.settings.output))}}),th=w({description:`List installed Command Packs and their load status`,auth:`none`,exampleArgs:[``,`--output json`],async run(e){let t=await e.commandPacks.list(),n=T(e.settings.output);if(n===`json`){A({command_packs:t},n);return}if(t.length===0){k(`No Command Packs installed.`);return}let r=t.map(e=>[e.name,e.version??`-`,e.source,e.status,e.commands.join(`, `)||e.error||`-`]);for(let e of j([`NAME`,`VERSION`,`SOURCE`,`STATUS`,`COMMANDS / ERROR`],r))k(e)}}),nh=w({description:`Remove an installed Command Pack`,auth:`none`,usageArgs:`--name <package>`,flags:{name:{type:`string`,valueHint:`<package>`,description:`Allowlisted Command Pack package name`,required:!0}},exampleArgs:[`--name @ali/bailian-plugin-agent`],async run(e){await e.commandPacks.remove(e.flags.name),A({removed:e.flags.name},T(e.settings.output))}}),rh=w({description:`Install skills from the Bailian skill registry into local agents`,auth:`none`,usageArgs:`--all | --name <name,...>`,flags:{all:{type:`switch`,description:`Install all skills from the registry`},name:{type:`string`,valueHint:`<name,...>`,description:`Comma-separated skill names to install`}},validate(e){if(e.all&&e.name)return`Use either --all or --name, not both`;if(!e.all&&!e.name)return`Specify --all to install everything or --name <name,...> for specific skills`},exampleArgs:[`--all`,`--name spark-video,bailian-model-recommend`],async run(e){let n=e.settings.outputExplicit?e.settings.output:`json`,r=await ke(),i=Object.keys(r.skills),a=e.flags.all?`all`:Tt(e.flags.name,!1),o=a===`all`?i:a,c=jt(),l=ge(),u=await Wt(o.map(e=>async()=>{let t=r.skills[e];if(!t)return{name:e,status:`failed`,reason:`skill not found in registry`};try{let n=await Je(e,t,l,c.skills[e]?.links??[]);return c.skills[e]=n.lockEntry,{name:e,status:`installed`,publishedAt:t.publishedAt,agents:n.linkedAgents}}catch(t){return{name:e,status:`failed`,reason:t instanceof Error?t.message:String(t)}}}),3);if(cn(c),n===`json`)A({registry:We(),agents:l.map(e=>e.id),skills:u},n);else if(u.length===0)k(`Skill registry is empty; no skills to install.`);else{let e=u.map(e=>[e.name,e.status,e.publishedAt?e.publishedAt.slice(0,10):`-`,e.status===`installed`?e.agents?.join(`, `)||`-`:e.reason??`-`]);for(let t of j([`NAME`,`STATUS`,`PUBLISHED`,`AGENTS / REASON`],e))k(t)}let d=u.filter(e=>e.status===`failed`);if(d.length>0)throw new t(`${d.length}/${u.length} skill(s) failed to install`,s.GENERAL,`Check the reason for failed skills in the output; network failures can be retried with bl skill add`)}}),ih=w({description:`Update installed skills to the latest registry versions`,auth:`none`,usageArgs:`[--all] [--name <name,...>]`,flags:{all:{type:`switch`,description:`Update all installed skills (default when neither --all nor --name is given)`},name:{type:`string`,valueHint:`<name,...>`,description:`Comma-separated skill names to update (must be already installed)`}},validate(e){if(e.all&&e.name)return`Use either --all or --name, not both`},exampleArgs:[``,`--all`,`--name spark-video`],async run(e){let n=e.settings.outputExplicit?e.settings.output:`json`,r=e.flags.all||!e.flags.name?`all`:Tt(e.flags.name,!1),i=await ke(),a=jt(),o=new Set(ct()),c=ge(),l=[],u=[];if(r===`all`)for(let[e,t]of Object.entries(a.skills)){let n=i.skills[e];if(!n){l.push({name:e,status:`skipped`,reason:`delisted from remote; local copy retained`});continue}if(n.contentHash===t.contentHash&&o.has(e)){let n=Ce(e,c,t.links??[]);a.skills[e]={...t,links:n.links},l.push({name:e,status:`up-to-date`,publishedAt:t.publishedAt});continue}u.push(e)}else for(let e of r){if(!a.skills[e]){l.push({name:e,status:`failed`,reason:`not installed; run bl skill add --name `+e+` first`});continue}u.push(e)}let d=await Wt(u.map(e=>async()=>{let t=i.skills[e];if(!t)return{name:e,status:`failed`,reason:`skill not found in registry`};try{let n=await Je(e,t,c,a.skills[e]?.links??[]);return a.skills[e]=n.lockEntry,{name:e,status:`updated`,publishedAt:t.publishedAt}}catch(t){return{name:e,status:`failed`,reason:t instanceof Error?t.message:String(t)}}}),3);if(l.push(...d),cn(a),n===`json`)A({registry:We(),skills:l},n);else if(l.length===0)k(`No skills installed locally; run bl skill add first.`);else{let e=l.map(e=>[e.name,e.status,e.publishedAt?e.publishedAt.slice(0,10):`-`]);for(let t of j([`NAME`,`STATUS`,`PUBLISHED`],e))k(t);let t=l.filter(e=>(e.status===`skipped`||e.status===`failed`)&&e.reason);if(t.length>0){k(``);for(let e of t)k(` ${e.name}: ${e.reason}`)}}let f=l.filter(e=>e.status===`failed`);if(f.length>0)throw new t(`${f.length} skill(s) failed to update`,s.GENERAL,`Check the reason for failed skills in the output; network failures can be retried with bl skill update`)}}),ah=w({description:`Remove locally installed skills (registry is untouched)`,auth:`none`,usageArgs:`--name <all|name,...>`,flags:{name:{type:`string`,valueHint:`<all|name,...>`,description:`Skills to remove: all or comma-separated skill names`,required:!0}},exampleArgs:[`--name spark-video`,`--name all`],async run(e){let n=e.settings.outputExplicit?e.settings.output:`json`,r=Tt(e.flags.name,!1),i=jt(),a=r===`all`?Object.keys(i.skills):r;if(a.length===0){A({skills:[]},n),n===`text`&&k(`No skills installed locally; nothing to remove.`);return}let o=new Set(ct()),c=[];for(let e of a){let t=i.skills[e];if(!t){c.push({name:e,status:`failed`,reason:o.has(e)?`directory not managed by bl skill (untracked); remove manually if needed`:`not installed`});continue}try{let n=$t(e,t.links??[]);Pt(e),delete i.skills[e],c.push({name:e,status:`removed`,removedLinks:n.length})}catch(t){c.push({name:e,status:`failed`,reason:t instanceof Error?t.message:String(t)})}}if(cn(i),n===`json`)A({skills:c},n);else{let e=c.map(e=>[e.name,e.status,e.status===`removed`?`reclaimed ${e.removedLinks} agent link(s)`:e.reason??`-`]);for(let t of j([`NAME`,`STATUS`,`DETAIL`],e))k(t)}let l=c.filter(e=>e.status===`failed`);if(l.length>0)throw new t(`${l.length}/${c.length} skill(s) failed to remove`,s.GENERAL,`Check the reason for failed skills in the output; use bl skill list to verify local install status`)}});function oh(e){return e?e.length>60?`${e.slice(0,59)}…`:e:`-`}var sh=w({description:`List registry skills and diff against local installs`,auth:`none`,exampleArgs:[``,`--output json`],notes:[`STATUS: installed | outdated | not-installed | missing (lock has it, dir deleted) | untracked (dir exists, not managed)`],async run(e){let t=e.settings.outputExplicit?e.settings.output:`json`,n=await ke(),r=oe(n,jt(),ct());if(t===`json`){A({registry:We(),...n.updatedAt?{updatedAt:n.updatedAt}:{},skills:r},t);return}if(r.length===0){k(`Skill registry is empty and no skills are installed locally.`);return}let i=r.map(e=>[e.name,e.status,e.publishedAt?e.publishedAt.slice(0,19).replace(`T`,` `):`-`,oh(e.description)]);for(let e of j([`NAME`,`STATUS`,`UPDATEDAT`,`DESCRIPTION`],i))k(e)}});const ch=`json`,lh={success:`success`,partial:`partial`,failed:`failed`};var uh=w({description:`Install all bailian-* skills (one-shot bootstrap for new environments)`,auth:`none`,usageArgs:``,exampleArgs:[``],notes:[`Fetches the registry index and installs every skill whose name starts with bailian-`,`Equivalent to: bl skill add --all (filtered to bailian-* skills)`],async run(e){let n=e.settings.outputExplicit?e.settings.output:ch,r=await ke(),i=Object.keys(r.skills).filter(e=>e.startsWith(`bailian-`)),a=jt(),o=ge(),c=await Wt(i.map(e=>async()=>{let t=r.skills[e];try{let n=await Je(e,t,o,a.skills[e]?.links??[]);return a.skills[e]=n.lockEntry,{name:e,status:lh.success}}catch(t){return{name:e,status:lh.failed,reason:t instanceof Error?t.message:String(t)}}}),3);cn(a);let l=c.filter(e=>e.status===lh.success),u=c.filter(e=>e.status===lh.failed),d=u.length===0?lh.success:l.length===0?lh.failed:lh.partial;if(n===ch){let e=o.map(e=>e.id),t={status:d,skills:l.map(e=>e.name)};u.length>0&&(t.failed=u.map(t=>({name:t.name,reason:t.reason,agents:e}))),A(t,n)}else if(c.length===0)k(`No bailian-* skills found in the registry.`);else if(k(d===lh.success?`Installed ${l.length} bailian-* skills.`:`Installed ${l.length}/${c.length} bailian-* skills.`),u.length>0){k(`Failed:`);for(let e of u)k(` ${e.name}: ${e.reason}`)}if(u.length>0)throw new t(`${u.length}/${c.length} skill(s) failed to install`,s.GENERAL,`Check the reason for failed skills in the output; network failures can be retried with bl skill init`)}});export{bd as advisorRecommend,Fs as appCall,Ls as appList,Ei as authGenerateAccessToken,Ci as authLogin,Ti as authLogout,wi as authStatus,Os as configAgent,xa as configList,ba as configSet,ya as configShow,Wo as configUi,Sa as configUse,au as consoleCall,yf as datasetDelete,vf as datasetGet,_f as datasetList,gf as datasetUpload,bf as datasetValidate,fp as deployAudioCreate,yp as deployDelete,hp as deployGet,pp as deployImageCreate,mp as deployList,gp as deployModels,bp as deployPause,xp as deployResume,_p as deployScale,dp as deployTextCreate,vp as deployUpdate,iu as fileUpload,Ff as finetuneAudioCreate,Hf as finetuneCancel,np as finetuneCapability,Jf as finetuneCheckpoints,Uf as finetuneDelete,Yf as finetuneExport,Vf as finetuneGet,If as finetuneImageCreate,Rf as finetuneList,qf as finetuneLogs,ap as finetunePrice,Pf as finetuneTextCreate,Lf as finetuneVideoCreate,ep as finetuneWatch,Ji as imageEdit,Wi as imageGenerate,xl as knowledgeCategoryAdd,Sl as knowledgeCategoryDelete,bl as knowledgeCategoryList,lc as knowledgeChat,ll as knowledgeChunkAdd,gl as knowledgeChunkDelete,ul as knowledgeChunkList,pl as knowledgeChunkUpdate,Ol as knowledgeCollectionCreate,kl as knowledgeCollectionGet,Ic as knowledgeDocDelete,Al as knowledgeDocImportOss,hc as knowledgeDocList,vc as knowledgeDocStatus,Lc as knowledgeDocTag,Ec as knowledgeDocUpload,Dl as knowledgeFileDelete,wl as knowledgeFileGet,Cl as knowledgeFileList,kc as knowledgeKbCreate,Nc as knowledgeKbDelete,mc as knowledgeKbInfo,uc as knowledgeKbList,yl as knowledgeKbStats,Ac as knowledgeKbUpdate,Gs as knowledgeRetrieve,rc as knowledgeSearch,ol as knowledgeServiceCopy,Gc as knowledgeServiceCreate,al as knowledgeServiceDelete,nl as knowledgeServiceDeploy,Wc as knowledgeServiceGet,Vc as knowledgeServiceList,$c as knowledgeServiceUpdate,ym as managedAgentApply,bm as managedAgentDestroy,Xp as managedAgentInit,vm as managedAgentPlan,Nm as managedAgentSessionCreate,Lm as managedAgentSessionDelete,Bm as managedAgentSessionEvents,Im as managedAgentSessionGet,Fm as managedAgentSessionList,Rm as managedAgentSessionRun,zm as managedAgentSessionSend,Hm as managedAgentSkillList,wm as managedAgentStateImport,xm as managedAgentStateList,Cm as managedAgentStateRm,Sm as managedAgentStateShow,hm as managedAgentValidate,Bl as mcpCall,Hl as mcpList,Ul as mcpTools,Rs as memoryAdd,Hs as memoryDelete,Bs as memoryList,Us as memoryProfileCreate,Ws as memoryProfileGet,zs as memorySearch,Vs as memoryUpdate,Md as modelList,mf as permissionGrant,lf as permissionList,hf as permissionRevoke,ed as pipelineRun,ad as pipelineValidate,$m as pluginInstall,eh as pluginLink,th as pluginList,nh as pluginRemove,of as quotaCheck,Qd as quotaHistory,Gd as quotaList,Kd as quotaUpdate,Gl as searchWeb,rh as skillAdd,uh as skillInit,sh as skillList,ah as skillRemove,ih as skillUpdate,tu as speechRecognize,Xl as speechSynthesize,Ii as textChat,Ui as textOmni,Up as tokenPlanAddMember,Bp as tokenPlanAssignSeats,Ip as tokenPlanCreateKey,Mp as tokenPlanListSeats,Ps as update,Qu as usageCodingPlan,ju as usageFree,Mu as usageFreetier,Iu as usageStats,Lu as usageSummary,Gu as usageTokenPlan,na as videoDownload,$i as videoEdit,Qi as videoGenerate,ea as videoRef,ta as videoTaskGet,oa as visionDescribe,Jm as workspaceInit,Ld as workspaceList};
|
|
2847
|
+
`):e.type===`error`&&process.stderr.write(`\n[error] ${e.content??`unknown error`}\n`)}function Bm(e,t,n={}){if(t)process.stdout.write(`${JSON.stringify({...n,events:ei(e.result.events),has_more:e.result.has_more,next_page:e.result.next_page},null,2)}\n`);else{for(let t of e.result.events)zm(t);Fm(e.terminalStatus,t)}Lm(e.terminalStatus,Im(e.result.events))}function Vm(e){return e?e.split(`,`).map(e=>e.trim()).filter(Boolean):void 0}var Hm=w({description:{"en-US":`Create a new session for an agent`,"zh-CN":`为 Agent 创建新 Session`},auth:`apiKey`,usageArgs:`[--agent <name>] [--environment <name>] [--title <title>] [--file <path>]`,flags:{file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Config file path (default: agents.yaml)`,"zh-CN":`配置文件路径(默认:agents.yaml)`}},agent:{type:`string`,valueHint:`<name>`,description:{"en-US":`Agent name (auto-detected when only one agent is configured)`,"zh-CN":`Agent 名称(仅配置一个 Agent 时自动识别)`}},environment:{type:`string`,valueHint:`<name>`,description:{"en-US":`Override agent's declared environment`,"zh-CN":`覆盖 Agent 声明的环境`}},vault:{type:`string`,valueHint:`<name>`,description:{"en-US":`Override agent's declared vault`,"zh-CN":`覆盖 Agent 声明的 Vault`}},memoryStores:{type:`string`,valueHint:`<names>`,description:{"en-US":`Override agent's memory stores (comma-separated)`,"zh-CN":`覆盖 Agent 的 Memory Store(以逗号分隔)`}},title:{type:`string`,valueHint:`<title>`,description:{"en-US":`Session title`,"zh-CN":`Session 标题`}},provider:{type:`string`,valueHint:`<name>`,description:{"en-US":`Target provider (multi-provider agents)`,"zh-CN":`目标 Provider(多 Provider Agent)`}}},exampleArgs:[``,`--agent assistant`,{"en-US":`--agent assistant --title 'debug run'`,"zh-CN":`--agent assistant --title '调试运行'`}],notes:Y,async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=n.file??`agents.yaml`;if(t.dryRun){A({would_create_session:{agent:n.agent??`auto`,provider:n.provider??`auto`,environment:n.environment,vault:n.vault,memory_stores:Vm(n.memoryStores),title:n.title},config_file:i},r);return}let{agentName:a,session:o}=await Z(()=>Q(async()=>Fr(await X(e,i),{agent:n.agent,provider:n.provider,environment:n.environment,vault:n.vault,memoryStores:Vm(n.memoryStores),title:n.title})));if(r===`json`){A({agent:a,session:o},r);return}k(`Session created: ${o.id}`),k(` Agent: ${a}`),k(` Environment: ${o.environment_id}`),k(` Status: ${o.status}`),o.vault_ids.length&&k(` Vaults: ${o.vault_ids.join(`, `)}`),o.memory_store_ids.length&&k(` Memory: ${o.memory_store_ids.join(`, `)}`)}});async function Um(e,t){let n=await e(),r=[...n.items],i=n.hasMore,a=n.nextPage;for(;t&&a;){let t=await e(a);r.push(...t.items),i=t.hasMore,a=t.nextPage}return{items:r,hasMore:i,nextPage:a}}var Wm=w({description:{"en-US":`List sessions from the provider`,"zh-CN":`列出 Provider 中的 Session`},auth:`apiKey`,usageArgs:`[--agent <name>] [--all] [--provider <name>] [--file <path>]`,flags:{file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Config file path (default: agents.yaml)`,"zh-CN":`配置文件路径(默认:agents.yaml)`}},agent:{type:`string`,valueHint:`<name>`,description:{"en-US":`Filter by agent name`,"zh-CN":`按 Agent 名称筛选`}},all:{type:`switch`,description:{"en-US":`Fetch all pages by following the cursor`,"zh-CN":`跟随 Cursor 获取全部分页`}},provider:{type:`string`,valueHint:`<name>`,description:{"en-US":`Target provider`,"zh-CN":`目标 Provider`}}},exampleArgs:[``,`--agent assistant`,`--all`],notes:Y,async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=n.file??`agents.yaml`,{items:a,hasMore:o}=await Z(()=>Q(async()=>{let t=await X(e,i);return Um(async e=>{let r=await Ur(t,{agent:n.agent,provider:n.provider,filter:e?{page:e}:void 0});return{items:r.summaries,hasMore:r.hasMore,nextPage:r.nextPage}},n.all)})),s=a.map(e=>e.session);if(r===`json`){A({sessions:s,has_more:o},r);return}if(s.length===0){k(`No sessions found.`);return}let c=new Map(a.filter(e=>e.agentName).map(e=>[e.session.id,e.agentName])),l=[`ID`,`TITLE`,`AGENT`,`STATUS`,`CREATED`],u=s.map(e=>[e.id,(e.title??``).slice(0,20),c.get(e.id)??e.agent_id.slice(0,12),e.status,e.created_at]);for(let e of j(l,u))k(e);k(`\nTotal: ${s.length}`),o&&k(`More sessions available. Use --all to fetch all.`)}}),Gm=w({description:{"en-US":`Get details of a session`,"zh-CN":`获取 Session 详情`},auth:`apiKey`,usageArgs:`--session-id <id> [--provider <name>] [--file <path>]`,flags:{sessionId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Session ID (required)`,"zh-CN":`Session ID(必填)`},required:!0},file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Config file path (default: agents.yaml)`,"zh-CN":`配置文件路径(默认:agents.yaml)`}},provider:{type:`string`,valueHint:`<name>`,description:{"en-US":`Target provider`,"zh-CN":`目标 Provider`}}},exampleArgs:[`--session-id sess_abc123`],notes:Y,async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=n.file??`agents.yaml`,a=await Z(()=>Q(async()=>zr(await X(e,i),n.sessionId,n.provider)));if(r===`json`){A(a,r);return}k(` ID: ${a.id}`),k(` Agent: ${a.agent_id}`),k(` Environment: ${a.environment_id}`),k(` Status: ${a.status}`),a.title&&k(` Title: ${a.title}`),k(` Created: ${a.created_at}`),k(` Updated: ${a.updated_at}`)}}),Km=w({description:{"en-US":`Delete a session`,"zh-CN":`删除 Session`},auth:`apiKey`,usageArgs:`--session-id <id> [--provider <name>] [--file <path>]`,flags:{sessionId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Session ID (required)`,"zh-CN":`Session ID(必填)`},required:!0},file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Config file path (default: agents.yaml)`,"zh-CN":`配置文件路径(默认:agents.yaml)`}},provider:{type:`string`,valueHint:`<name>`,description:{"en-US":`Target provider`,"zh-CN":`目标 Provider`}}},exampleArgs:[`--session-id sess_abc123`],notes:Y,async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=n.file??`agents.yaml`;if(t.dryRun){A({would_delete_session:n.sessionId,provider:n.provider??`auto`,config_file:i},r);return}await Z(()=>Q(async()=>{await Ir(await X(e,i),n.sessionId,n.provider)})),r===`json`?A({deleted:n.sessionId},r):k(`Session ${n.sessionId} deleted.`)}}),qm=w({description:{"en-US":`Create a session, send a message, and stream the response`,"zh-CN":`创建 Session、发送消息并流式输出响应`},auth:`apiKey`,usageArgs:`--prompt <text> [--agent <name>] [--no-stream] [--file <path>]`,flags:{prompt:{type:`string`,valueHint:`<text>`,description:{"en-US":`Prompt to send (required)`,"zh-CN":`要发送的 Prompt(必填)`},required:!0},file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Config file path (default: agents.yaml)`,"zh-CN":`配置文件路径(默认:agents.yaml)`}},agent:{type:`string`,valueHint:`<name>`,description:{"en-US":`Agent name (auto-detected when only one agent is configured)`,"zh-CN":`Agent 名称(仅配置一个 Agent 时自动识别)`}},environment:{type:`string`,valueHint:`<name>`,description:{"en-US":`Override agent's declared environment`,"zh-CN":`覆盖 Agent 声明的环境`}},vault:{type:`string`,valueHint:`<name>`,description:{"en-US":`Override agent's declared vault`,"zh-CN":`覆盖 Agent 声明的 Vault`}},memoryStores:{type:`string`,valueHint:`<names>`,description:{"en-US":`Override agent's memory stores (comma-separated)`,"zh-CN":`覆盖 Agent 的 Memory Store(以逗号分隔)`}},title:{type:`string`,valueHint:`<title>`,description:{"en-US":`Session title`,"zh-CN":`Session 标题`}},provider:{type:`string`,valueHint:`<name>`,description:{"en-US":`Target provider`,"zh-CN":`目标 Provider`}},noStream:{type:`switch`,description:{"en-US":`Use polling instead of SSE streaming`,"zh-CN":`使用轮询代替 SSE 流式传输`}}},exampleArgs:[{"en-US":`--prompt "hello"`,"zh-CN":`--prompt "你好"`},{"en-US":`--agent assistant --prompt "summarize this repo"`,"zh-CN":`--agent assistant --prompt "总结这个代码仓库"`}],notes:[...Y,{"en-US":"--output json emits one envelope: { session_id, provider, agent, events } — read session_id to chain `session send/get/events/delete`.","zh-CN":"--output json 输出一个 Envelope:{ session_id, provider, agent, events }。读取 session_id 后可串联调用 `session send/get/events/delete`。"}],async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=n.file??`agents.yaml`,a=r===`json`,o={agent:n.agent,provider:n.provider,environment:n.environment,vault:n.vault,memoryStores:Vm(n.memoryStores),title:n.title};if(t.dryRun){A({would_run:{prompt:n.prompt,agent:n.agent??`auto`,provider:n.provider??`auto`,environment:n.environment,vault:n.vault,memory_stores:o.memoryStores,title:n.title,mode:n.noStream?`polling`:`streaming`},config_file:i},r);return}await Z(()=>Q(async()=>{let t=await X(e,i);if(n.noStream){let e=await Qr(t,n.prompt,o);a||process.stderr.write(`Session created: ${e.session.id}\n`),Bm(e,a,{session_id:e.session.id,provider:e.provider,agent:e.agentName})}else{let e=await Zr(t,n.prompt,o);a||process.stderr.write(`Session created: ${e.session.id}\n`),await Rm(e.events,a,{session_id:e.session.id,provider:e.provider,agent:e.agentName})}}))}}),Jm=w({description:{"en-US":`Send a message to an existing session and stream the response`,"zh-CN":`向已有 Session 发送消息并流式输出响应`},auth:`apiKey`,usageArgs:`--session-id <id> --message <text> [--no-stream] [--file <path>]`,flags:{sessionId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Session ID (required)`,"zh-CN":`Session ID(必填)`},required:!0},message:{type:`string`,valueHint:`<text>`,description:{"en-US":`Message to send (required)`,"zh-CN":`要发送的消息(必填)`},required:!0},file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Config file path (default: agents.yaml)`,"zh-CN":`配置文件路径(默认:agents.yaml)`}},provider:{type:`string`,valueHint:`<name>`,description:{"en-US":`Target provider`,"zh-CN":`目标 Provider`}},noStream:{type:`switch`,description:{"en-US":`Use polling instead of SSE streaming`,"zh-CN":`使用轮询代替 SSE 流式传输`}}},exampleArgs:[{"en-US":`--session-id sess_abc123 --message "continue"`,"zh-CN":`--session-id sess_abc123 --message "继续"`}],notes:Y,async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=n.file??`agents.yaml`,a=r===`json`;if(t.dryRun){A({would_send:{session_id:n.sessionId,message:n.message,provider:n.provider??`auto`,mode:n.noStream?`polling`:`streaming`},config_file:i},r);return}await Z(()=>Q(async()=>{let t=await X(e,i);n.noStream?Bm(await Yr(t,n.sessionId,n.message,{provider:n.provider}),a,{session_id:n.sessionId}):await Rm(await Xr(t,n.sessionId,n.message,{provider:n.provider}),a,{session_id:n.sessionId})}))}}),Ym=w({description:{"en-US":`List event history for a session`,"zh-CN":`列出 Session 的事件历史`},auth:`apiKey`,usageArgs:`--session-id <id> [--limit <n>] [--all] [--file <path>]`,flags:{sessionId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Session ID (required)`,"zh-CN":`Session ID(必填)`},required:!0},file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Config file path (default: agents.yaml)`,"zh-CN":`配置文件路径(默认:agents.yaml)`}},provider:{type:`string`,valueHint:`<name>`,description:{"en-US":`Target provider`,"zh-CN":`目标 Provider`}},limit:{type:`number`,valueHint:`<n>`,description:{"en-US":`Maximum number of events to fetch`,"zh-CN":`要获取的最大事件数`}},all:{type:`switch`,description:{"en-US":`Fetch all pages by following the cursor`,"zh-CN":`跟随 Cursor 获取全部分页`}}},exampleArgs:[`--session-id sess_abc123`,`--session-id sess_abc123 --all`],notes:Y,async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=n.file??`agents.yaml`,{items:a,hasMore:o}=await Z(()=>Q(async()=>{let t=await X(e,i);return Um(async e=>{let r=await Hr(t,n.sessionId,{provider:n.provider,limit:n.limit,page_token:e});return{items:r.events,hasMore:r.has_more,nextPage:r.next_page}},n.all)}));if(r===`json`){A({events:ei(a),has_more:o},r);return}if(a.length===0){k(`No events found.`);return}let s=[`#`,`TYPE`,`CONTENT`],c=a.map((e,t)=>{let n=``;return n=e.type===`message`?(e.content??``).slice(0,60):e.type===`tool_use`?e.tool_name??``:e.type===`tool_result`?(e.content??``).slice(0,60):e.type===`status`?e.status??``:e.type===`error`?(e.content??``).slice(0,60):e.raw_type,[String(t+1),e.type,n]});for(let e of j(s,c))k(e);k(`\nTotal: ${a.length}`),o&&k(`More events available. Use --all to fetch all.`)}});const Xm=[`custom`,`official`,`all`];var Zm=w({description:{"en-US":`List skills from the provider's skill catalog`,"zh-CN":`列出 Provider Skill Catalog 中的 Skill`},auth:`apiKey`,usageArgs:`[--source custom|official|all] [--provider <name>] [--file <path>]`,flags:{file:{type:`string`,valueHint:`<path>`,description:{"en-US":`Config file path (default: agents.yaml)`,"zh-CN":`配置文件路径(默认:agents.yaml)`}},source:{type:`string`,valueHint:`<source>`,description:{"en-US":`Skill catalog: custom (workspace-uploaded, default), official (built-in), or all (both catalogs in one call)`,"zh-CN":`Skill Catalog:custom(Workspace 上传,默认)、official(内置)或 all(一次调用获取两类 Catalog)`}},provider:{type:`string`,valueHint:`<name>`,description:{"en-US":`Target provider`,"zh-CN":`目标 Provider`}}},exampleArgs:[``,`--source official`,`--source all --output json`,`--source custom --provider bailian`],notes:[...Y,{"en-US":`Providers without a skill listing API (e.g. ark) return an empty list.`,"zh-CN":`没有 Skill 列表 API 的 Provider(例如 ark)会返回空列表。`},{"en-US":"For agent-driven skill selection, use `--source all --output json`: one call returns both catalogs with per-skill `source` and `description` fields to pick from.","zh-CN":"由 Agent 选择 Skill 时,请使用 `--source all --output json`:一次调用返回两类 Catalog,并为每个 Skill 提供 `source` 和 `description` 字段用于选择。"},{"en-US":`When generating a task that needs a suitable skill, call this command to match official or custom skills before wiring them into the task.`,"zh-CN":`生成需要合适 Skill 的任务时,先调用此命令匹配官方或自定义 Skill,再将其接入任务。`}],validate:e=>e.source&&!Xm.includes(e.source)?`--source must be one of: custom, official, all.`:void 0,async run(e){let{settings:t,flags:n}=e,r=T(t.output),i=n.file??`agents.yaml`,a=n.source??`custom`,o=await Z(()=>Q(async()=>{let t=await X(e,i);if(a!==`all`)return Wr(t,{provider:n.provider,source:a});let[r,o]=await Promise.all([Wr(t,{provider:n.provider,source:`custom`}),Wr(t,{provider:n.provider,source:`official`})]);return[...r,...o]}));if(r===`json`){A({source:a,skills:o},r);return}if(o.length===0){k(a===`all`?`No skills found.`:`No ${a} skills found.`);return}let s=[`ID`,`NAME`,`SOURCE`,`STATUS`,`VERSION`,`CREATED`],c=o.map(e=>[e.id,e.name.slice(0,32),e.source,e.status,e.latest_version??`-`,e.created_at??`-`]);for(let e of j(s,c))k(e);k(`\nTotal: ${o.length} (${a})`)}});const $={loginInfo:`zeldaEasy.cornerstone-portal.cs-console.loginInfo`,initSpace:`zeldaEasy.bailian-dash-workspace.space.initSpace`,queryBuyResult:`zeldaEasy.bailian-commerce.bill.queryBuyPostpaidResult`,commodityOrderInfo:`zeldaEasy.bailian-commerce.bill.postpaidCommodityOrderInfo`,buyCommodity:`zeldaEasy.bailian-commerce.bill.buyPostpaidCommodity`},Qm={accessKeyId:{type:`string`,valueHint:`<id>`,description:{"en-US":`Alibaba Cloud Access Key ID`,"zh-CN":`阿里云 Access Key ID`}},accessKeySecret:{type:`string`,valueHint:`<secret>`,description:{"en-US":`Alibaba Cloud Access Key Secret`,"zh-CN":`阿里云 Access Key Secret`}},securityToken:{type:`string`,valueHint:`<token>`,description:{"en-US":`Alibaba Cloud STS Security Token (optional)`,"zh-CN":`阿里云 STS Security Token(可选)`}}},$m=1e3;function eh(e){return new Promise(t=>setTimeout(t,e))}function th(e){return e?.data?.DataV2?.data?.data}function nh(e){let t=e?.data?.data;if(!Array.isArray(t)||t.length===0)return;let n=(t.find(e=>e?.defaultAgent===!0)??t[0])?.tenantId,r=typeof n==`string`?Number(n):n;return typeof r==`number`&&Number.isFinite(r)?r:void 0}var rh=w({description:{"en-US":`Initialize Bailian workspace and activate postpaid services`,"zh-CN":`初始化百炼 Workspace 并开通后付费服务`},auth:`none`,usageArgs:`--access-key-id <id> --access-key-secret <secret> [--security-token <token>]`,flags:Qm,exampleArgs:[`--access-key-id LTAIxxxxx --access-key-secret xxxxx`],async run(e){let{settings:n,flags:r}=e,i=T(n.output);if(n.dryRun){A({apis:[{step:0,api:`GenerateCLIAccessToken`,description:`Generate CLI access token from AK/SK`},{step:1,api:$.loginInfo,description:`Check login & workspace status`},{step:2,api:$.initSpace,description:`Initialize workspace (if needed)`},{step:3,api:`CreateUser`,description:`Create console user via BailianControl OpenAPI (CreateUser)`},{step:4,api:`ListWorkspaces`,description:`List workspaces to resolve agentId`},{step:5,api:`ResetPolicies4Agent`,description:`Authorize user permissions`},{step:6,api:$.queryBuyResult,description:`Query postpaid order status`},{step:7,api:$.commodityOrderInfo,description:`Query commodity activation status`},{step:8,api:$.buyCommodity,description:`Activate postpaid commodities (if needed)`}]},i);return}let{accessKeyId:a,accessKeySecret:o}=r;if(!a||!o)throw new t(`workspace init requires --access-key-id and --access-key-secret.`,c.USAGE);let s=r.securityToken||void 0,l=(await Ie({identity:e.identity,settings:n,baseUrl:e.client.baseUrl,accessKeyId:a,accessKeySecret:o,securityToken:s})).cliAccessToken;if(!l)throw new t(`Failed to generate CLI access token from AK/SK.`,c.GENERAL);let u=be(n),d={region:u.consoleRegion,site:u.consoleSite,...u.consoleSwitchAgent==null?{}:{switchAgent:u.consoleSwitchAgent},token:l},f=n.verbose,p=async(e,r={})=>{f&&process.stderr.write(`> ${e}\n`);try{let t=await ie(d,n.timeout,{api:e,data:r},n);return f&&process.stderr.write(`< ${JSON.stringify(t)}\n`),t}catch(e){if(f){let n=e instanceof t?e.rawResponse??e.message:String(e);process.stderr.write(`< ERROR: ${n}\n`)}throw e}};k(`Checking workspace status...`);let m=th(await p($.loginInfo));m?.spaceInited===!0?k(`Workspace already initialized.`):(k(`Initializing workspace...`),await p($.initSpace),k(`Workspace initialized.`));let h=m?.aliyun?.uid;if(typeof h!=`string`||h.length===0)throw new t(`Console login info did not include aliyun.uid.`,c.GENERAL);let g={identity:e.identity,settings:n,baseUrl:e.client.baseUrl,regionId:u.consoleRegion,accessKeyId:a,accessKeySecret:o,securityToken:s};try{await le({...g,reqDTO:{outerKey:h,nickName:h,userName:h}})}catch(e){if(!(e instanceof t)||!/already exists/i.test(e.message))throw e;k(`Console user already exists, continuing.`)}k(`Resolving workspace agent...`);let _=nh(await rt(g));if(_==null)throw new t(`Could not resolve agentId from ListWorkspaces response.`,c.GENERAL,`Re-run with --verbose to inspect the ListWorkspaces response body.`);k(`Authorizing user permissions...`),await Rt({...g,outerKey:h,agentId:_,policyIndexList:[1]}),await ih(p,i)}});async function ih(e,n){k(`Checking service activation status...`);let r;for(let t=0;t<20;t++){let n=th(await e($.queryBuyResult));if(r=typeof n==`string`?n:n?.result,r!==`buying`)break;t===0&&k(`Service activation in progress, polling...`),await eh($m)}if(r===`fail`)throw new t(`Service activation failed.`,c.GENERAL);if(r===`success`){await sh(e,n);return}await oh(e,n)}function ah(e){let t=th(e);return Array.isArray(t)?t:[]}async function oh(e,t){let n=ah(await e($.commodityOrderInfo)),r=n.filter(e=>e.status===11);if(r.length>0){k(`Warning: Some services are overdue:`);for(let e of r)k(` - ${e.commodityCode}`)}let i=n.filter(e=>e.status===1);if(i.length>0){k(`Activating ${i.length} postpaid services...`),await e($.buyCommodity),await sh(e,t);return}A({status:`ready`,activeServices:n.filter(e=>e.status===10).map(e=>e.commodityCode)},t)}async function sh(e,n){k(`Waiting for services to activate...`);for(let t=0;t<20;t++){let t=ah(await e($.commodityOrderInfo));if(t.filter(e=>e.status!==10&&e.status!==11).length===0){let e=t.filter(e=>e.status===11);if(e.length>0){k(`Warning: Some services are overdue:`);for(let t of e)k(` - ${t.commodityCode}`)}A({status:`ready`,activeServices:t.filter(e=>e.status===10).map(e=>e.commodityCode)},n);return}await eh($m)}throw new t(`Timed out waiting for services to activate.`,c.TIMEOUT)}var ch=w({description:{"en-US":`Install or upgrade an allowlisted Command Pack`,"zh-CN":`安装或升级白名单内的 Command Pack`},auth:`none`,usageArgs:`--package <name[@version]>`,flags:{package:{type:`string`,valueHint:`<name[@version]>`,description:{"en-US":`Allowlisted Command Pack package and optional version or tag`,"zh-CN":`白名单内的 Command Pack 包名,以及可选的版本或 Tag`},required:!0}},exampleArgs:[`--package @ali/bailian-plugin-agent`,`--package @ali/bailian-plugin-agent@beta`],async run(e){A({installed:await e.commandPacks.install(e.flags.package)},T(e.settings.output))}}),lh=w({description:{"en-US":`Link an allowlisted local Command Pack for development`,"zh-CN":`链接白名单内的本地 Command Pack 用于开发`},auth:`none`,usageArgs:`--path <directory>`,flags:{path:{type:`string`,valueHint:`<directory>`,description:{"en-US":`Local Command Pack package directory`,"zh-CN":`本地 Command Pack 包目录`},required:!0}},exampleArgs:[`--path ../bailian-plugin-agent`],async run(e){A({linked:await e.commandPacks.link(e.flags.path)},T(e.settings.output))}}),uh=w({description:{"en-US":`List installed Command Packs and their load status`,"zh-CN":`列出已安装的 Command Pack 及其加载状态`},auth:`none`,exampleArgs:[``,`--output json`],async run(e){let t=await e.commandPacks.list(),n=T(e.settings.output);if(n===`json`){A({command_packs:t},n);return}if(t.length===0){k(`No Command Packs installed.`);return}let r=t.map(e=>[e.name,e.version??`-`,e.source,e.status,e.commands.join(`, `)||e.error||`-`]);for(let e of j([`NAME`,`VERSION`,`SOURCE`,`STATUS`,`COMMANDS / ERROR`],r))k(e)}}),dh=w({description:{"en-US":`Remove an installed Command Pack`,"zh-CN":`移除已安装的 Command Pack`},auth:`none`,usageArgs:`--name <package>`,flags:{name:{type:`string`,valueHint:`<package>`,description:{"en-US":`Allowlisted Command Pack package name`,"zh-CN":`白名单内的 Command Pack 包名`},required:!0}},exampleArgs:[`--name @ali/bailian-plugin-agent`],async run(e){await e.commandPacks.remove(e.flags.name),A({removed:e.flags.name},T(e.settings.output))}}),fh=w({description:{"en-US":`Install skills from the Bailian skill registry into local agents`,"zh-CN":`将百炼 Skill Registry 中的 Skill 安装到本地 Agent`},auth:`none`,usageArgs:`--all | --name <name,...>`,flags:{all:{type:`switch`,description:{"en-US":`Install all skills from the registry`,"zh-CN":`安装 Registry 中的全部 Skill`}},name:{type:`string`,valueHint:`<name,...>`,description:{"en-US":`Comma-separated skill names to install`,"zh-CN":`要安装的 Skill 名称,以逗号分隔`}}},validate(e){if(e.all&&e.name)return`Use either --all or --name, not both`;if(!e.all&&!e.name)return`Specify --all to install everything or --name <name,...> for specific skills`},exampleArgs:[`--all`,`--name spark-video,bailian-model-recommend`],async run(e){let n=e.settings.outputExplicit?e.settings.output:`json`,r=await je(),i=Object.keys(r.skills),a=e.flags.all?`all`:Dt(e.flags.name,!1),o=a===`all`?i:a,s=Nt(),l=ve(),u=await Kt(o.map(e=>async()=>{let t=r.skills[e];if(!t)return{name:e,status:`failed`,reason:`skill not found in registry`};try{let n=await Xe(e,t,l,s.skills[e]?.links??[]);return s.skills[e]=n.lockEntry,{name:e,status:`installed`,publishedAt:t.publishedAt,agents:n.linkedAgents}}catch(t){return{name:e,status:`failed`,reason:t instanceof Error?t.message:String(t)}}}),3);if(un(s),n===`json`)A({registry:Ke(),agents:l.map(e=>e.id),skills:u},n);else if(u.length===0)k(`Skill registry is empty; no skills to install.`);else{let e=u.map(e=>[e.name,e.status,e.publishedAt?e.publishedAt.slice(0,10):`-`,e.status===`installed`?e.agents?.join(`, `)||`-`:e.reason??`-`]);for(let t of j([`NAME`,`STATUS`,`PUBLISHED`,`AGENTS / REASON`],e))k(t)}let d=u.filter(e=>e.status===`failed`);if(d.length>0)throw new t(`${d.length}/${u.length} skill(s) failed to install`,c.GENERAL,`Check the reason for failed skills in the output; network failures can be retried with bl skill add`)}}),ph=w({description:{"en-US":`Update installed skills to the latest registry versions`,"zh-CN":`将已安装的 Skill 更新到 Registry 最新版本`},auth:`none`,usageArgs:`[--all] [--name <name,...>]`,flags:{all:{type:`switch`,description:{"en-US":`Update all installed skills (default when neither --all nor --name is given)`,"zh-CN":`更新全部已安装 Skill(未指定 --all 或 --name 时的默认行为)`}},name:{type:`string`,valueHint:`<name,...>`,description:{"en-US":`Comma-separated skill names to update (must be already installed)`,"zh-CN":`要更新的 Skill 名称,以逗号分隔(必须已安装)`}}},validate(e){if(e.all&&e.name)return`Use either --all or --name, not both`},exampleArgs:[``,`--all`,`--name spark-video`],async run(e){let n=e.settings.outputExplicit?e.settings.output:`json`,r=e.flags.all||!e.flags.name?`all`:Dt(e.flags.name,!1),i=await je(),a=Nt(),o=new Set(ut()),s=ve(),l=[],u=[];if(r===`all`)for(let[e,t]of Object.entries(a.skills)){let n=i.skills[e];if(!n){l.push({name:e,status:`skipped`,reason:`delisted from remote; local copy retained`});continue}if(n.contentHash===t.contentHash&&o.has(e)){let n=Te(e,s,t.links??[]);a.skills[e]={...t,links:n.links},l.push({name:e,status:`up-to-date`,publishedAt:t.publishedAt});continue}u.push(e)}else for(let e of r){if(!a.skills[e]){l.push({name:e,status:`failed`,reason:`not installed; run bl skill add --name `+e+` first`});continue}u.push(e)}let d=await Kt(u.map(e=>async()=>{let t=i.skills[e];if(!t)return{name:e,status:`failed`,reason:`skill not found in registry`};try{let n=await Xe(e,t,s,a.skills[e]?.links??[]);return a.skills[e]=n.lockEntry,{name:e,status:`updated`,publishedAt:t.publishedAt}}catch(t){return{name:e,status:`failed`,reason:t instanceof Error?t.message:String(t)}}}),3);if(l.push(...d),un(a),n===`json`)A({registry:Ke(),skills:l},n);else if(l.length===0)k(`No skills installed locally; run bl skill add first.`);else{let e=l.map(e=>[e.name,e.status,e.publishedAt?e.publishedAt.slice(0,10):`-`]);for(let t of j([`NAME`,`STATUS`,`PUBLISHED`],e))k(t);let t=l.filter(e=>(e.status===`skipped`||e.status===`failed`)&&e.reason);if(t.length>0){k(``);for(let e of t)k(` ${e.name}: ${e.reason}`)}}let f=l.filter(e=>e.status===`failed`);if(f.length>0)throw new t(`${f.length} skill(s) failed to update`,c.GENERAL,`Check the reason for failed skills in the output; network failures can be retried with bl skill update`)}}),mh=w({description:{"en-US":`Remove locally installed skills (registry is untouched)`,"zh-CN":`移除本地已安装的 Skill(不修改 Registry)`},auth:`none`,usageArgs:`--name <all|name,...>`,flags:{name:{type:`string`,valueHint:`<all|name,...>`,description:{"en-US":`Skills to remove: all or comma-separated skill names`,"zh-CN":`要移除的 Skill:all 或以逗号分隔的 Skill 名称`},required:!0}},exampleArgs:[`--name spark-video`,`--name all`],async run(e){let n=e.settings.outputExplicit?e.settings.output:`json`,r=Dt(e.flags.name,!1),i=Nt(),a=r===`all`?Object.keys(i.skills):r;if(a.length===0){A({skills:[]},n),n===`text`&&k(`No skills installed locally; nothing to remove.`);return}let o=new Set(ut()),s=[];for(let e of a){let t=i.skills[e];if(!t){s.push({name:e,status:`failed`,reason:o.has(e)?`directory not managed by bl skill (untracked); remove manually if needed`:`not installed`});continue}try{let n=tn(e,t.links??[]);It(e),delete i.skills[e],s.push({name:e,status:`removed`,removedLinks:n.length})}catch(t){s.push({name:e,status:`failed`,reason:t instanceof Error?t.message:String(t)})}}if(un(i),n===`json`)A({skills:s},n);else{let e=s.map(e=>[e.name,e.status,e.status===`removed`?`reclaimed ${e.removedLinks} agent link(s)`:e.reason??`-`]);for(let t of j([`NAME`,`STATUS`,`DETAIL`],e))k(t)}let l=s.filter(e=>e.status===`failed`);if(l.length>0)throw new t(`${l.length}/${s.length} skill(s) failed to remove`,c.GENERAL,`Check the reason for failed skills in the output; use bl skill list to verify local install status`)}});function hh(e){return e?e.length>60?`${e.slice(0,59)}…`:e:`-`}var gh=w({description:{"en-US":`List registry skills and diff against local installs`,"zh-CN":`列出 Registry Skill,并与本地安装结果比较`},auth:`none`,exampleArgs:[``,`--output json`],notes:[{"en-US":`STATUS: installed | outdated | not-installed | missing (lock has it, dir deleted) | untracked (dir exists, not managed)`,"zh-CN":`STATUS:installed | outdated | not-installed | missing(Lock 中存在但目录已删除)| untracked(目录存在但未被管理)`}],async run(e){let t=e.settings.outputExplicit?e.settings.output:`json`,n=await je(),r=ce(n,Nt(),ut());if(t===`json`){A({registry:Ke(),...n.updatedAt?{updatedAt:n.updatedAt}:{},skills:r},t);return}if(r.length===0){k(`Skill registry is empty and no skills are installed locally.`);return}let i=r.map(e=>[e.name,e.status,e.publishedAt?e.publishedAt.slice(0,19).replace(`T`,` `):`-`,hh(e.description)]);for(let e of j([`NAME`,`STATUS`,`UPDATEDAT`,`DESCRIPTION`],i))k(e)}});const _h=`json`,vh={success:`success`,partial:`partial`,failed:`failed`};var yh=w({description:{"en-US":`Install all bailian-* skills (one-shot bootstrap for new environments)`,"zh-CN":`安装全部 bailian-* Skill(用于新环境的一次性初始化)`},auth:`none`,usageArgs:``,exampleArgs:[``],notes:[{"en-US":"Fetches the registry index and installs every skill whose name starts with `bailian-`.","zh-CN":"获取 Registry 索引并安装名称以 `bailian-` 开头的所有 Skill。"},{"en-US":"Equivalent to: `bl skill add --all` (filtered to `bailian-*` skills).","zh-CN":"等价于:`bl skill add --all`(筛选为 `bailian-*` Skill)。"}],async run(e){let n=e.settings.outputExplicit?e.settings.output:_h,r=await je(),i=Object.keys(r.skills).filter(e=>e.startsWith(`bailian-`)),a=Nt(),o=ve(),s=await Kt(i.map(e=>async()=>{let t=r.skills[e];try{let n=await Xe(e,t,o,a.skills[e]?.links??[]);return a.skills[e]=n.lockEntry,{name:e,status:vh.success}}catch(t){return{name:e,status:vh.failed,reason:t instanceof Error?t.message:String(t)}}}),3);un(a);let l=s.filter(e=>e.status===vh.success),u=s.filter(e=>e.status===vh.failed),d=u.length===0?vh.success:l.length===0?vh.failed:vh.partial;if(n===_h){let e=o.map(e=>e.id),t={status:d,skills:l.map(e=>e.name)};u.length>0&&(t.failed=u.map(t=>({name:t.name,reason:t.reason,agents:e}))),A(t,n)}else if(s.length===0)k(`No bailian-* skills found in the registry.`);else if(k(d===vh.success?`Installed ${l.length} bailian-* skills.`:`Installed ${l.length}/${s.length} bailian-* skills.`),u.length>0){k(`Failed:`);for(let e of u)k(` ${e.name}: ${e.reason}`)}if(u.length>0)throw new t(`${u.length}/${s.length} skill(s) failed to install`,c.GENERAL,`Check the reason for failed skills in the output; network failures can be retried with bl skill init`)}});export{kd as advisorRecommend,Ws as appCall,Ks as appList,Oi as authGenerateAccessToken,Ti as authLogin,Di as authLogout,Ei as authStatus,Ls as configAgent,Ca as configList,Sa as configSet,xa as configShow,$o as configUi,wa as configUse,mu as consoleCall,Of as datasetDelete,Df as datasetGet,Ef as datasetList,Tf as datasetUpload,kf as datasetValidate,xp as deployAudioCreate,Op as deployDelete,wp as deployGet,Sp as deployImageCreate,Cp as deployList,Tp as deployModels,kp as deployPause,Ap as deployResume,Ep as deployScale,bp as deployTextCreate,Dp as deployUpdate,pu as fileUpload,Wf as finetuneAudioCreate,Zf as finetuneCancel,dp as finetuneCapability,rp as finetuneCheckpoints,Qf as finetuneDelete,ip as finetuneExport,Xf as finetuneGet,Gf as finetuneImageCreate,qf as finetuneList,np as finetuneLogs,mp as finetunePrice,Uf as finetuneTextCreate,Kf as finetuneVideoCreate,lp as finetuneWatch,Xi as imageEdit,Ki as imageGenerate,Al as knowledgeCategoryAdd,jl as knowledgeCategoryDelete,kl as knowledgeCategoryList,vc as knowledgeChat,vl as knowledgeChunkAdd,Tl as knowledgeChunkDelete,yl as knowledgeChunkList,Sl as knowledgeChunkUpdate,Ll as knowledgeCollectionCreate,Rl as knowledgeCollectionGet,Gc as knowledgeDocDelete,zl as knowledgeDocImportOss,wc as knowledgeDocList,Dc as knowledgeDocStatus,Kc as knowledgeDocTag,Fc as knowledgeDocUpload,Il as knowledgeFileDelete,Nl as knowledgeFileGet,Ml as knowledgeFileList,Rc as knowledgeKbCreate,Hc as knowledgeKbDelete,Cc as knowledgeKbInfo,yc as knowledgeKbList,Ol as knowledgeKbStats,zc as knowledgeKbUpdate,ec as knowledgeRetrieve,fc as knowledgeSearch,hl as knowledgeServiceCopy,el as knowledgeServiceCreate,ml as knowledgeServiceDelete,dl as knowledgeServiceDeploy,$c as knowledgeServiceGet,Xc as knowledgeServiceList,cl as knowledgeServiceUpdate,Om as managedAgentApply,km as managedAgentDestroy,am as managedAgentInit,Dm as managedAgentPlan,Hm as managedAgentSessionCreate,Km as managedAgentSessionDelete,Ym as managedAgentSessionEvents,Gm as managedAgentSessionGet,Wm as managedAgentSessionList,qm as managedAgentSessionRun,Jm as managedAgentSessionSend,Zm as managedAgentSkillList,Nm as managedAgentStateImport,Am as managedAgentStateList,Mm as managedAgentStateRm,jm as managedAgentStateShow,wm as managedAgentValidate,Yl as mcpCall,Zl as mcpList,Ql as mcpTools,qs as memoryAdd,Zs as memoryDelete,Ys as memoryList,Qs as memoryProfileCreate,$s as memoryProfileGet,Js as memorySearch,Xs as memoryUpdate,Vd as modelList,Cf as permissionGrant,vf as permissionList,wf as permissionRevoke,ld as pipelineRun,md as pipelineValidate,ch as pluginInstall,lh as pluginLink,uh as pluginList,dh as pluginRemove,hf as quotaCheck,cf as quotaHistory,ef as quotaList,tf as quotaUpdate,eu as searchWeb,fh as skillAdd,yh as skillInit,gh as skillList,mh as skillRemove,ph as skillUpdate,uu as speechRecognize,au as speechSynthesize,Ri as textChat,Gi as textOmni,Qp as tokenPlanAddMember,Yp as tokenPlanAssignSeats,Gp as tokenPlanCreateKey,Vp as tokenPlanListSeats,Us as update,sd as usageCodingPlan,Bu as usageFree,Vu as usageFreetier,Gu as usageStats,Ku as usageSummary,ed as usageTokenPlan,ia as videoDownload,ta as videoEdit,ea as videoGenerate,na as videoRef,ra as videoTaskGet,ca as visionDescribe,rh as workspaceInit,Kd as workspaceList};
|