From 2cf6106b9790835465e980747955ab10af116ffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=95=85=E7=92=83?= Date: Fri, 6 Nov 2026 18:27:54 +0800 Subject: [PATCH 1/2] feat: add model training params cli command --- packages/cli/src/commands.ts | 4 + .../commands/src/commands/finetune/metrics.ts | 109 ++++++++++ .../commands/src/commands/finetune/params.ts | 192 ++++++++++++++++++ packages/commands/src/index.ts | 2 + .../commands/tests/e2e/finetune.e2e.test.ts | 160 +++++++++++++++ packages/commands/tests/e2e/topic-routes.ts | 2 + packages/core/src/client/endpoints.ts | 10 + packages/core/src/finetune/api.ts | 83 ++++++++ packages/core/src/finetune/types.ts | 59 ++++++ .../tests/finetune-params-metrics-api.test.ts | 86 ++++++++ skills/bailian-finetune/reference/finetune.md | 105 ++++++++++ skills/bailian-finetune/reference/index.md | 12 +- 12 files changed, 819 insertions(+), 5 deletions(-) create mode 100644 packages/commands/src/commands/finetune/metrics.ts create mode 100644 packages/commands/src/commands/finetune/params.ts create mode 100644 packages/core/tests/finetune-params-metrics-api.test.ts diff --git a/packages/cli/src/commands.ts b/packages/cli/src/commands.ts index 79d07710c..ff6a457b3 100644 --- a/packages/cli/src/commands.ts +++ b/packages/cli/src/commands.ts @@ -179,6 +179,8 @@ import { finetuneWatch, finetuneCapability, finetunePrice, + finetuneParams, + finetuneMetrics, finetuneCompressTemplates, finetuneCompressCreate, finetuneCompressList, @@ -519,6 +521,8 @@ export const commands: Record = { "finetune watch": finetuneWatch, "finetune capability": finetuneCapability, "finetune price": finetunePrice, + "finetune params": finetuneParams, + "finetune metrics": finetuneMetrics, "finetune compress templates": finetuneCompressTemplates, "finetune compress create": finetuneCompressCreate, "finetune compress list": finetuneCompressList, diff --git a/packages/commands/src/commands/finetune/metrics.ts b/packages/commands/src/commands/finetune/metrics.ts new file mode 100644 index 000000000..ba77426a2 --- /dev/null +++ b/packages/commands/src/commands/finetune/metrics.ts @@ -0,0 +1,109 @@ +import { defineCommand, listBasicMetrics, type FlagsDef } from "bailian-cli-core"; + +/** + * The old Zelda metric API defaulted to 100 records per page; the OpenAPI + * defaults to 1000. Send 100 explicitly unless the user overrides, so page + * shape stays the same across the switch. + */ +const LEGACY_DEFAULT_PAGE_SIZE = 100; + +const METRICS_FLAGS = { + jobId: { + type: "string", + valueHint: "", + description: { + "en-US": "Fine-tune job ID (required)", + "zh-CN": "微调任务 ID(必填)", + }, + required: true, + }, + page: { + type: "number", + valueHint: "", + description: { + "en-US": "Page number, starting at 1 (default: 1)", + "zh-CN": "页码,从 1 开始(默认:1)", + }, + }, + pageSize: { + type: "number", + valueHint: "", + description: { + "en-US": `Records per page (default: ${LEGACY_DEFAULT_PAGE_SIZE})`, + "zh-CN": `每页记录数(默认:${LEGACY_DEFAULT_PAGE_SIZE})`, + }, + }, + workspaceId: { + type: "string", + valueHint: "", + description: { + "en-US": + "Workspace ID sent as X-DashScope-WorkSpace; use the job's owning workspace. Omit when your API key is already workspace-bound.", + "zh-CN": + "以 X-DashScope-WorkSpace 头发送的业务空间 ID,使用任务所属空间;API Key 已绑定空间时可省略。", + }, + }, +} satisfies FlagsDef; + +export default defineCommand({ + defaultOutput: "json", + description: { + "en-US": "Query the training metrics of a fine-tune job", + "zh-CN": "查询微调任务的训练指标", + }, + auth: "apiKey", + usageArgs: "--job-id [--page ] [--page-size ] [--workspace-id ]", + flags: METRICS_FLAGS, + exampleArgs: [ + "--job-id ft-xxx", + "--job-id ft-xxx --page 2 --page-size 100", + "--job-id ft-xxx --output json", + "--job-id ft-xxx --dry-run", + ], + notes: [ + { + "en-US": + "Queries GET /api/v1/fine-tunes/{job_id}/basic_metrics. Each metrics record is returned verbatim (step + dynamic metric fields); an empty list is a normal result.", + "zh-CN": + "调用 GET /api/v1/fine-tunes/{job_id}/basic_metrics。每条指标记录原样返回(step + 动态指标字段);空列表是正常结果。", + }, + { + "en-US": + "Metrics are not filtered server-side; the full result is returned and callers pick the metric keys from each record. Use --page/--page-size for paging.", + "zh-CN": + "指标不在服务端过滤;返回全量记录,调用方从记录中自行选取指标 key 展示。翻页用 --page/--page-size。", + }, + ], + async run(ctx) { + const { settings, flags } = ctx; + const jobId = flags.jobId; + const pageNo = flags.page ?? 1; + const pageSize = flags.pageSize ?? LEGACY_DEFAULT_PAGE_SIZE; + + if (settings.dryRun) { + const resultData = { + action: "finetune.metrics", + job_id: jobId, + page_no: pageNo, + page_size: pageSize, + ...(flags.workspaceId ? { workspace_id: flags.workspaceId } : {}), + }; + ctx.output.result( + resultData, + ctx.settings.output === "text" ? { text: JSON.stringify(resultData, null, 2) } : undefined, + ); + return; + } + + const response = await listBasicMetrics(ctx.client, jobId, { + pageNo, + pageSize, + workspaceId: flags.workspaceId || undefined, + }); + + ctx.output.result( + response, + ctx.settings.output === "text" ? { text: JSON.stringify(response, null, 2) } : undefined, + ); + }, +}); diff --git a/packages/commands/src/commands/finetune/params.ts b/packages/commands/src/commands/finetune/params.ts new file mode 100644 index 000000000..ab4952e23 --- /dev/null +++ b/packages/commands/src/commands/finetune/params.ts @@ -0,0 +1,192 @@ +import { + defineCommand, + getFineTuneParams, + isTrainingTypeCli, + TRAINING_TYPES_CLI, + DEFAULT_TRAINING_TYPE, + TRAINING_TYPE_MAP, + BailianError, + ExitCode, + type FlagsDef, +} from "bailian-cli-core"; + +/** + * Build the training-option context from the dedicated flags. The OpenAPI + * expects it as one `hyper_parameters` query parameter holding a JSON string + * (e.g. {"modality":"vision","reasoning_mode":"thinking"}); models without + * dynamic train options simply omit it. + */ +function buildTrainOptions( + modality: string | undefined, + reasoningMode: string | undefined, +): Record { + const options: Record = {}; + if (modality) options.modality = modality; + if (reasoningMode) options.reasoning_mode = reasoningMode; + return options; +} + +const PARAMS_FLAGS = { + baseModel: { + type: "string", + valueHint: "", + description: { + "en-US": "Base model to query training parameters for (e.g. qwen3-8b)", + "zh-CN": "要查询训练参数的基础模型(例如 qwen3-8b)", + }, + required: true, + }, + trainingType: { + type: "string", + valueHint: "", + description: { + "en-US": `Training type: ${TRAINING_TYPES_CLI.join(" | ")} (default: ${DEFAULT_TRAINING_TYPE}). Mapped to the server's training_type (e.g. sft-lora -> efficient_sft).`, + "zh-CN": `训练类型:${TRAINING_TYPES_CLI.join(" | ")}(默认:${DEFAULT_TRAINING_TYPE})。会映射为服务端 training_type(例如 sft-lora -> efficient_sft)。`, + }, + }, + mtuSpecCode: { + type: "string", + valueHint: "", + description: { + "en-US": "MTU spec code, required for resource-group queries (e.g. MTU2)", + "zh-CN": "训练单元(MTU)规格编码,查询资源类参数时需要(例如 MTU2)", + }, + }, + paramType: { + type: "string", + valueHint: "", + description: { + "en-US": "Parameter group: hyper | resource. Omit to return all groups.", + "zh-CN": "参数类别:hyper | resource。不传返回全部分类。", + }, + choices: ["hyper", "resource"] as const, + }, + modality: { + type: "string", + valueHint: "", + description: { + "en-US": + "Training modality: text | vision. Only meaningful for models with dynamic train options; sent as modality inside hyper_parameters.", + "zh-CN": + "训练模态:text | vision。仅对配置了动态训练选项的模型有意义;作为 hyper_parameters 中的 modality 发送。", + }, + choices: ["text", "vision"] as const, + }, + reasoningMode: { + type: "string", + valueHint: "", + description: { + "en-US": + "Reasoning mode: instruct (non-thinking) | thinking. Only meaningful for models with dynamic train options; sent as reasoning_mode inside hyper_parameters.", + "zh-CN": + "思考模式:instruct(非思考)| thinking(思考)。仅对配置了动态训练选项的模型有意义;作为 hyper_parameters 中的 reasoning_mode 发送。", + }, + choices: ["instruct", "thinking"] as const, + }, + lang: { + type: "string", + valueHint: "", + description: { + "en-US": "Locale for server-side display text (e.g. en, zh). Omit for the server default.", + "zh-CN": "服务端展示文案的语言(例如 en、zh)。不传由服务端决定。", + }, + }, + workspaceId: { + type: "string", + valueHint: "", + description: { + "en-US": + "Workspace ID sent as X-DashScope-WorkSpace; omit when your API key is already workspace-bound.", + "zh-CN": "以 X-DashScope-WorkSpace 头发送的业务空间 ID;API Key 已绑定空间时可省略。", + }, + }, +} satisfies FlagsDef; + +export default defineCommand({ + defaultOutput: "json", + description: { + "en-US": "Query the training hyper-parameter configuration for a base model", + "zh-CN": "查询基础模型的训练超参配置", + }, + auth: "apiKey", + usageArgs: + "--base-model [--training-type ] [--param-type ] [--mtu-spec-code ] [--modality ] [--reasoning-mode ] [--lang ] [--workspace-id ]", + flags: PARAMS_FLAGS, + exampleArgs: [ + "--base-model qwen3-8b", + "--base-model qwen3-8b --training-type sft", + "--base-model qwen3-8b --training-type dpo-lora --param-type hyper", + "--base-model qwen3.7-plus-2026-05-26 --modality vision --reasoning-mode thinking", + "--base-model qwen3-8b --param-type resource --mtu-spec-code MTU2", + "--base-model qwen3-8b --output json", + "--base-model qwen3-8b --dry-run", + ], + notes: [ + { + "en-US": + "Queries GET /api/v1/fine-tunes/fine-tunes-params. Each hyper_params entry keeps server field names verbatim (recommend_value, defaultValue, is_advanced_parameter, ...).", + "zh-CN": + "调用 GET /api/v1/fine-tunes/fine-tunes-params。每条 hyper_params 原样保留服务端字段名(recommend_value、defaultValue、is_advanced_parameter 等)。", + }, + { + "en-US": + "--modality / --reasoning-mode travel as one hyper_parameters query parameter (JSON). Supported values and combinations vary per model; invalid combinations are rejected by the server and surfaced as-is. Models without dynamic train options ignore these flags.", + "zh-CN": + "--modality / --reasoning-mode 会合并为单个 hyper_parameters query 参数(JSON)发送。各模型支持的取值与组合不同;非法组合由服务端拒绝并原样透传错误。未配置动态训练选项的模型可忽略这两个 flag。", + }, + { + "en-US": + "resume_from_checkpoint in the output reports whether the training type supports resuming training.", + "zh-CN": "输出中的 resume_from_checkpoint 表示该训练类型是否支持断点续训。", + }, + ], + async run(ctx) { + const { settings, flags } = ctx; + + const trainingTypeCli = flags.trainingType || DEFAULT_TRAINING_TYPE; + if (!isTrainingTypeCli(trainingTypeCli)) { + throw new BailianError( + `--training-type "${trainingTypeCli}" is not supported.`, + ExitCode.USAGE, + `Supported values: ${TRAINING_TYPES_CLI.join(", ")} (default: ${DEFAULT_TRAINING_TYPE}).`, + ); + } + const trainingType = TRAINING_TYPE_MAP[trainingTypeCli].server; + const trainOptions = buildTrainOptions(flags.modality, flags.reasoningMode); + + if (settings.dryRun) { + const resultData = { + action: "finetune.params", + base_model: flags.baseModel, + training_type: trainingType, + ...(flags.paramType ? { param_type: flags.paramType } : {}), + ...(flags.mtuSpecCode ? { mtu_spec_code: flags.mtuSpecCode } : {}), + ...(Object.keys(trainOptions).length > 0 + ? { hyper_parameters: JSON.stringify(trainOptions) } + : {}), + ...(flags.lang ? { lang: flags.lang } : {}), + ...(flags.workspaceId ? { workspace_id: flags.workspaceId } : {}), + }; + ctx.output.result( + resultData, + ctx.settings.output === "text" ? { text: JSON.stringify(resultData, null, 2) } : undefined, + ); + return; + } + + const response = await getFineTuneParams(ctx.client, { + inputModel: flags.baseModel, + trainingType, + mtuSpecCode: flags.mtuSpecCode || undefined, + paramType: flags.paramType || undefined, + trainOptions, + lang: flags.lang || undefined, + workspaceId: flags.workspaceId || undefined, + }); + + ctx.output.result( + response, + ctx.settings.output === "text" ? { text: JSON.stringify(response, null, 2) } : undefined, + ); + }, +}); diff --git a/packages/commands/src/index.ts b/packages/commands/src/index.ts index b06422ab3..cf1d3c344 100644 --- a/packages/commands/src/index.ts +++ b/packages/commands/src/index.ts @@ -182,6 +182,8 @@ export { default as finetuneExport } from "./commands/finetune/export.ts"; export { default as finetuneWatch } from "./commands/finetune/watch.ts"; export { default as finetuneCapability } from "./commands/finetune/capability.ts"; export { default as finetunePrice } from "./commands/finetune/price.ts"; +export { default as finetuneParams } from "./commands/finetune/params.ts"; +export { default as finetuneMetrics } from "./commands/finetune/metrics.ts"; export { default as finetuneCompressTemplates } from "./commands/finetune/compress-templates.ts"; export { default as finetuneCompressCreate } from "./commands/finetune/compress-create.ts"; export { default as finetuneCompressList } from "./commands/finetune/compress-list.ts"; diff --git a/packages/commands/tests/e2e/finetune.e2e.test.ts b/packages/commands/tests/e2e/finetune.e2e.test.ts index 3d2f19d6c..673c917eb 100644 --- a/packages/commands/tests/e2e/finetune.e2e.test.ts +++ b/packages/commands/tests/e2e/finetune.e2e.test.ts @@ -280,6 +280,8 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: finetune (offline)", () => { ["delete", ["--job-id", "ft-xxx"]], ["watch", ["--job-id", "ft-xxx"]], ["capability", ["--base-model", "qwen3-8b"]], + ["params", ["--base-model", "qwen3-8b"]], + ["metrics", ["--job-id", "ft-xxx"]], ])("finetune %s --dry-run 发出结构化动作", async (sub, extra) => { const { stdout, stderr, exitCode } = await runCommandE2e(FINETUNE_ROUTES, [ "finetune", @@ -304,6 +306,164 @@ describe.skipIf(!isDashScopeE2EReady())("e2e: finetune (offline)", () => { expect(stderr).toMatch(/--yes/i); }); + test("finetune params --dry-run 映射训练类型并合并 modality/reasoning-mode", async () => { + // sft-lora → efficient_sft at the interface boundary; --modality and + // --reasoning-mode merge into one hyper_parameters JSON query string. + const { stdout, stderr, exitCode } = await runCommandE2e(FINETUNE_ROUTES, [ + "finetune", + "params", + "--base-model", + "qwen3-8b", + "--modality", + "text", + "--reasoning-mode", + "thinking", + "--param-type", + "hyper", + "--mtu-spec-code", + "MTU2", + "--workspace-id", + "ws-123", + "--dry-run", + "--output", + "json", + ]); + expect(exitCode, stderr).toBe(0); + const data = parseStdoutJson<{ + action: string; + base_model: string; + training_type: string; + param_type: string; + mtu_spec_code: string; + hyper_parameters: string; + workspace_id: string; + }>(stdout); + expect(data.action).toBe("finetune.params"); + expect(data.base_model).toBe("qwen3-8b"); + expect(data.training_type).toBe("efficient_sft"); + expect(data.param_type).toBe("hyper"); + expect(data.mtu_spec_code).toBe("MTU2"); + expect(data.hyper_parameters).toBe('{"modality":"text","reasoning_mode":"thinking"}'); + expect(data.workspace_id).toBe("ws-123"); + }); + + test("finetune params --dry-run 显式训练类型按映射表转换", async () => { + const { stdout, stderr, exitCode } = await runCommandE2e(FINETUNE_ROUTES, [ + "finetune", + "params", + "--base-model", + "qwen3-8b", + "--training-type", + "dpo", + "--dry-run", + "--output", + "json", + ]); + expect(exitCode, stderr).toBe(0); + const data = parseStdoutJson<{ training_type: string }>(stdout); + expect(data.training_type).toBe("dpo_full"); + }); + + test("finetune params 非法训练类型退出为用法错误 (2)", async () => { + const { stderr, exitCode } = await runCommandE2e(FINETUNE_ROUTES, [ + "finetune", + "params", + "--base-model", + "qwen3-8b", + "--training-type", + "nope", + "--dry-run", + ]); + expect(exitCode).toBe(2); + expect(stderr).toMatch(/--training-type|nope/); + }); + + test("finetune params 非法 modality 枚举值退出为用法错误 (2)", async () => { + const { stderr, exitCode } = await runCommandE2e(FINETUNE_ROUTES, [ + "finetune", + "params", + "--base-model", + "qwen3-8b", + "--modality", + "audio", + "--dry-run", + ]); + expect(exitCode).toBe(2); + expect(stderr).toMatch(/--modality|modality|audio/i); + }); + + test("finetune params 缺少 --base-model 时退出为用法错误 (2)", async () => { + const { stderr, exitCode } = await runCommandE2e(FINETUNE_ROUTES, [ + "finetune", + "params", + "--quiet", + ]); + expect(exitCode).toBe(2); + expect(stderr).toMatch(/--base-model|Missing required argument/i); + }); + + test("finetune metrics --dry-run 默认 page_no=1 且显式 page_size=100", async () => { + // The OpenAPI default is 1000 per page; the CLI keeps the legacy 100-page + // shape by sending page_size explicitly unless the user overrides it. + const { stdout, stderr, exitCode } = await runCommandE2e(FINETUNE_ROUTES, [ + "finetune", + "metrics", + "--job-id", + "ft-xxx", + "--dry-run", + "--output", + "json", + ]); + expect(exitCode, stderr).toBe(0); + const data = parseStdoutJson<{ + action: string; + job_id: string; + page_no: number; + page_size: number; + }>(stdout); + expect(data.action).toBe("finetune.metrics"); + expect(data.job_id).toBe("ft-xxx"); + expect(data.page_no).toBe(1); + expect(data.page_size).toBe(100); + }); + + test("finetune metrics --dry-run 转发 page/page-size/workspace 覆盖值", async () => { + const { stdout, stderr, exitCode } = await runCommandE2e(FINETUNE_ROUTES, [ + "finetune", + "metrics", + "--job-id", + "ft-xxx", + "--page", + "3", + "--page-size", + "50", + "--workspace-id", + "ws-123", + "--dry-run", + "--output", + "json", + ]); + expect(exitCode, stderr).toBe(0); + const data = parseStdoutJson<{ + page_no: number; + page_size: number; + workspace_id?: string; + }>(stdout); + expect(data.page_no).toBe(3); + expect(data.page_size).toBe(50); + expect(data.workspace_id).toBe("ws-123"); + }); + + test("finetune metrics 缺少 --job-id 时退出为用法错误 (2)", async () => { + const { stderr, exitCode } = await runCommandE2e(FINETUNE_ROUTES, [ + "finetune", + "metrics", + "--quiet", + ]); + expect(exitCode).toBe(2); + expect(stderr).toMatch(/--job-id|Missing required argument/i); + }); + test("finetune create --dry-run 解析多 datasets 中的空白", async () => { const { stdout, stderr, exitCode } = await runCommandE2e(FINETUNE_ROUTES, [ "finetune", diff --git a/packages/commands/tests/e2e/topic-routes.ts b/packages/commands/tests/e2e/topic-routes.ts index 34a6dbfc0..dc6a9f3a6 100644 --- a/packages/commands/tests/e2e/topic-routes.ts +++ b/packages/commands/tests/e2e/topic-routes.ts @@ -301,6 +301,8 @@ export const FINETUNE_ROUTES: E2eRouteExports = { "finetune export": "finetuneExport", "finetune watch": "finetuneWatch", "finetune capability": "finetuneCapability", + "finetune params": "finetuneParams", + "finetune metrics": "finetuneMetrics", "finetune compress templates": "finetuneCompressTemplates", "finetune compress create": "finetuneCompressCreate", "finetune compress list": "finetuneCompressList", diff --git a/packages/core/src/client/endpoints.ts b/packages/core/src/client/endpoints.ts index c6f80f170..aa6846112 100644 --- a/packages/core/src/client/endpoints.ts +++ b/packages/core/src/client/endpoints.ts @@ -309,6 +309,16 @@ export function finetuneLogsPath(jobId: string): string { return `/api/v1/fine-tunes/${encodeURIComponent(jobId)}/logs`; } +/** GET /api/v1/fine-tunes/fine-tunes-params — training hyper-parameter config. */ +export function finetuneParamsPath(): string { + return "/api/v1/fine-tunes/fine-tunes-params"; +} + +/** GET /api/v1/fine-tunes/{job_id}/basic_metrics — training metrics. */ +export function finetuneBasicMetricsPath(jobId: string): string { + return `/api/v1/fine-tunes/${encodeURIComponent(jobId)}/basic_metrics`; +} + /** GET /api/v1/fine-tunes/{job_id}/checkpoints */ export function finetuneCheckpointsPath(jobId: string): string { return `/api/v1/fine-tunes/${encodeURIComponent(jobId)}/checkpoints`; diff --git a/packages/core/src/finetune/api.ts b/packages/core/src/finetune/api.ts index 757c04406..0de254fe1 100644 --- a/packages/core/src/finetune/api.ts +++ b/packages/core/src/finetune/api.ts @@ -11,6 +11,8 @@ import { finetuneLogsPath, finetuneCheckpointsPath, finetuneExportPath, + finetuneParamsPath, + finetuneBasicMetricsPath, } from "../client/endpoints.ts"; import type { Client } from "../client/client.ts"; import type { @@ -23,6 +25,8 @@ import type { GetFineTuneLogsResponse, ListCheckpointsResponse, ExportCheckpointResponse, + GetFineTuneParamsResponse, + ListBasicMetricsResponse, } from "./types.ts"; /** POST /api/v1/fine-tunes */ @@ -130,6 +134,85 @@ export async function getFineTuneLogs( }); } +export interface GetFineTuneParamsParams { + /** Base model ID, e.g. qwen3-14b. */ + inputModel: string; + /** Server training_type: sft | efficient_sft | dpo_full | dpo_lora | cpt. */ + trainingType: string; + /** MTU spec code; forwarded when present (resource params queries). */ + mtuSpecCode?: string; + /** `hyper` / `resource`; omit to return all groups. */ + paramType?: string; + /** + * Training-option context, sent as a single `hyper_parameters` query + * parameter holding the JSON-serialized object (e.g. modality / + * reasoning_mode). Omit when the model has no dynamic train options. + */ + trainOptions?: Record; + /** Explicit locale for server-side display text; omit for the server default. */ + lang?: string; + /** Sent as X-DashScope-WorkSpace; use the job's owning workspace. */ + workspaceId?: string; + signal?: AbortSignal; +} + +/** + * GET /api/v1/fine-tunes/fine-tunes-params — training hyper-parameter config. + * Empty/absent optional fields in each hyper_params entry are not failures. + */ +export async function getFineTuneParams( + client: Client, + params: GetFineTuneParamsParams, +): Promise { + const qs = new URLSearchParams(); + qs.set("input_model", params.inputModel); + qs.set("training_type", params.trainingType); + if (params.mtuSpecCode) qs.set("mtu_spec_code", params.mtuSpecCode); + if (params.paramType) qs.set("param_type", params.paramType); + if (params.trainOptions && Object.keys(params.trainOptions).length > 0) { + qs.set("hyper_parameters", JSON.stringify(params.trainOptions)); + } + if (params.lang) qs.set("lang", params.lang); + const path = `${finetuneParamsPath()}?${qs.toString()}`; + return client.requestJson({ + path, + method: "GET", + headers: params.workspaceId ? { "X-DashScope-WorkSpace": params.workspaceId } : undefined, + signal: params.signal, + }); +} + +export interface ListBasicMetricsParams { + pageNo?: number; + pageSize?: number; + /** Sent as X-DashScope-WorkSpace; use the job's owning workspace. */ + workspaceId?: string; + signal?: AbortSignal; +} + +/** + * GET /api/v1/fine-tunes/{job_id}/basic_metrics — training metrics. + * An empty `output.metrics` list is a normal result. No server-side metric + * type filter: the full result is returned and callers pick metric keys. + */ +export async function listBasicMetrics( + client: Client, + jobId: string, + params: ListBasicMetricsParams = {}, +): Promise { + const qs = new URLSearchParams(); + if (params.pageNo !== undefined) qs.set("page_no", String(params.pageNo)); + if (params.pageSize !== undefined) qs.set("page_size", String(params.pageSize)); + const base = finetuneBasicMetricsPath(jobId); + const path = qs.toString() ? `${base}?${qs.toString()}` : base; + return client.requestJson({ + path, + method: "GET", + headers: params.workspaceId ? { "X-DashScope-WorkSpace": params.workspaceId } : undefined, + signal: params.signal, + }); +} + /** GET /api/v1/fine-tunes/{job_id}/checkpoints */ export async function listCheckpoints( client: Client, diff --git a/packages/core/src/finetune/types.ts b/packages/core/src/finetune/types.ts index 416ff39d1..b0a816017 100644 --- a/packages/core/src/finetune/types.ts +++ b/packages/core/src/finetune/types.ts @@ -201,6 +201,65 @@ export interface GetFineTuneResponse { data?: FineTuneJob; } +// ---- Training params / metrics (DashScope OpenAPI) ---- + +/** + * GET /api/v1/fine-tunes/fine-tunes-params 的 `output.hyper_params[]` 元素。 + * `defaultValue` 是服务端保留的兼容字段名(与 recommend_value 同值),不改名为 + * default_value。`visibility` / `required` 等其他可选字段不在此依赖,缺失不算失败。 + */ +export interface FineTuneParamHyperParam { + name?: string; + recommend_value?: string; + defaultValue?: string; + is_advanced_parameter?: boolean; + display_name?: string; + description?: string; + type?: string; + data_range?: string[]; + left_range?: string; + right_range?: string; + step?: number; + support_values?: string[]; + editable?: boolean; + /** `hyper` / `resource` */ + group?: string; + [k: string]: unknown; +} + +/** GET /api/v1/fine-tunes/fine-tunes-params response. */ +export interface GetFineTuneParamsResponse { + request_id?: string; + output?: { + hyper_params?: FineTuneParamHyperParam[]; + /** Whether the training type supports resuming from a checkpoint. */ + resume_from_checkpoint?: boolean; + [k: string]: unknown; + }; + [k: string]: unknown; +} + +/** + * GET /api/v1/fine-tunes/{job_id}/basic_metrics 的 `output.metrics[]` 元素。 + * 每条指标记录的 JSON 原样返回(step + 动态指标字段),内部 key 不做改名。 + */ +export interface BasicMetricRecord { + [key: string]: unknown; +} + +/** GET /api/v1/fine-tunes/{job_id}/basic_metrics response. 空指标列表是正常结果。 */ +export interface ListBasicMetricsResponse { + request_id?: string; + output?: { + page_no?: number; + page_size?: number; + total?: number; + metrics?: BasicMetricRecord[]; + [k: string]: unknown; + }; + [k: string]: unknown; +} + // ---- Model Compression (DashScope /api/v1/fine-tunes/compress) ---- /** A tunable hyper-parameter declared by a compression template. */ diff --git a/packages/core/tests/finetune-params-metrics-api.test.ts b/packages/core/tests/finetune-params-metrics-api.test.ts new file mode 100644 index 000000000..f4f229077 --- /dev/null +++ b/packages/core/tests/finetune-params-metrics-api.test.ts @@ -0,0 +1,86 @@ +import { describe, expect, test, vi } from "vite-plus/test"; +import { getFineTuneParams, listBasicMetrics, type Client } from "../src/index.ts"; + +function mockClient(response: unknown = {}) { + const requestJson = vi.fn().mockResolvedValue(response); + return { client: { requestJson } as unknown as Client, requestJson }; +} + +describe("fine-tune params / basic metrics API", () => { + test("getFineTuneParams serializes train options as one hyper_parameters query param", async () => { + const { client, requestJson } = mockClient(); + await getFineTuneParams(client, { + inputModel: "qwen3.5-27b", + trainingType: "sft", + paramType: "hyper", + trainOptions: { modality: "text", reasoning_mode: "thinking" }, + lang: "zh", + }); + expect(requestJson).toHaveBeenCalledWith({ + path: "/api/v1/fine-tunes/fine-tunes-params?input_model=qwen3.5-27b&training_type=sft¶m_type=hyper&hyper_parameters=%7B%22modality%22%3A%22text%22%2C%22reasoning_mode%22%3A%22thinking%22%7D&lang=zh", + method: "GET", + headers: undefined, + signal: undefined, + }); + }); + + test("getFineTuneParams omits optional query params and sends mtu_spec_code", async () => { + const { client, requestJson } = mockClient(); + await getFineTuneParams(client, { + inputModel: "qwen3-8b", + trainingType: "efficient_sft", + mtuSpecCode: "MTU2", + }); + expect(requestJson.mock.calls[0]?.[0].path).toBe( + "/api/v1/fine-tunes/fine-tunes-params?input_model=qwen3-8b&training_type=efficient_sft&mtu_spec_code=MTU2", + ); + }); + + test("getFineTuneParams sends the workspace header only when provided", async () => { + const withWorkspace = mockClient(); + await getFineTuneParams(withWorkspace.client, { + inputModel: "qwen3-8b", + trainingType: "sft", + workspaceId: "ws-123", + }); + expect(withWorkspace.requestJson.mock.calls[0]?.[0].headers).toEqual({ + "X-DashScope-WorkSpace": "ws-123", + }); + + const withoutWorkspace = mockClient(); + await getFineTuneParams(withoutWorkspace.client, { + inputModel: "qwen3-8b", + trainingType: "sft", + }); + expect(withoutWorkspace.requestJson.mock.calls[0]?.[0].headers).toBeUndefined(); + }); + + test("listBasicMetrics encodes the job id and serializes pagination query", async () => { + const { client, requestJson } = mockClient(); + await listBasicMetrics(client, "ft /?#job", { + pageNo: 2, + pageSize: 100, + }); + expect(requestJson).toHaveBeenCalledWith({ + path: "/api/v1/fine-tunes/ft%20%2F%3F%23job/basic_metrics?page_no=2&page_size=100", + method: "GET", + headers: undefined, + signal: undefined, + }); + }); + + test("listBasicMetrics sends a bare path when no params are set", async () => { + const { client, requestJson } = mockClient(); + await listBasicMetrics(client, "ft-xxx"); + expect(requestJson.mock.calls[0]?.[0].path).toBe("/api/v1/fine-tunes/ft-xxx/basic_metrics"); + expect(requestJson.mock.calls[0]?.[0].headers).toBeUndefined(); + }); + + test("listBasicMetrics sends the workspace header when provided", async () => { + const { client, requestJson } = mockClient(); + await listBasicMetrics(client, "ft-xxx", { workspaceId: "ws-123" }); + expect(requestJson.mock.calls[0]?.[0].headers).toEqual({ + "X-DashScope-WorkSpace": "ws-123", + }); + }); +}); diff --git a/skills/bailian-finetune/reference/finetune.md b/skills/bailian-finetune/reference/finetune.md index e14af2242..81234fadc 100644 --- a/skills/bailian-finetune/reference/finetune.md +++ b/skills/bailian-finetune/reference/finetune.md @@ -27,6 +27,8 @@ Index: [index.md](index.md) | `bl finetune image create` | API Key | Create an image generation model fine-tune job (sft-lora) | | `bl finetune list` | API Key | List fine-tune jobs | | `bl finetune logs` | API Key | Fetch training logs for a fine-tune job | +| `bl finetune metrics` | API Key | Query the training metrics of a fine-tune job | +| `bl finetune params` | API Key | Query the training hyper-parameter configuration for a base model | | `bl finetune price` | Console | Estimate the training cost for a fine-tune job (token billing) | | `bl finetune text create` | API Key | Create a text model fine-tune job (sft \| sft-lora \| dpo \| dpo-lora \| cpt) | | `bl finetune video create` | API Key | Create a video generation model fine-tune job (Wan i2v/kf2v, efficient_sft) | @@ -712,6 +714,109 @@ bl finetune logs --job-id ft-xxx --tail 20 bl finetune logs --job-id ft-xxx --search checkpoint --tail 5 ``` +### `bl finetune metrics` + +| Field | Value | +| ------------------ | ---------------------------------------------------------------------------------------- | +| **Name** | `finetune metrics` | +| **Description** | Query the training metrics of a fine-tune job | +| **Authentication** | API Key | +| **Usage** | `bl finetune metrics --job-id [--page ] [--page-size ] [--workspace-id ]` | + +#### Flags + +| Flag | Type | Required | Description | +| --------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------ | +| `--job-id ` | string | yes | Fine-tune job ID (required) | +| `--page ` | number | no | Page number, starting at 1 (default: 1) | +| `--page-size ` | number | no | Records per page (default: 100) | +| `--workspace-id ` | string | no | Workspace ID sent as X-DashScope-WorkSpace; use the job's owning workspace. Omit when your API key is already workspace-bound. | +| `--api-key ` | string | no | API key | +| `--base-url ` | string | no | API base URL | + +#### Notes + +- Queries GET /api/v1/fine-tunes/{job_id}/basic_metrics. Each metrics record is returned verbatim (step + dynamic metric fields); an empty list is a normal result. +- Metrics are not filtered server-side; the full result is returned and callers pick the metric keys from each record. Use --page/--page-size for paging. + +#### Examples + +```bash +bl finetune metrics --job-id ft-xxx +``` + +```bash +bl finetune metrics --job-id ft-xxx --page 2 --page-size 100 +``` + +```bash +bl finetune metrics --job-id ft-xxx --output json +``` + +```bash +bl finetune metrics --job-id ft-xxx --dry-run +``` + +### `bl finetune params` + +| Field | Value | +| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Name** | `finetune params` | +| **Description** | Query the training hyper-parameter configuration for a base model | +| **Authentication** | API Key | +| **Usage** | `bl finetune params --base-model [--training-type ] [--param-type ] [--mtu-spec-code ] [--modality ] [--reasoning-mode ] [--lang ] [--workspace-id ]` | + +#### Flags + +| Flag | Type | Required | Description | +| --------------------------------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `--base-model ` | string | yes | Base model to query training parameters for (e.g. qwen3-8b) | +| `--training-type ` | string | no | Training type: sft \| sft-lora \| dpo \| dpo-lora \| cpt (default: sft-lora). Mapped to the server's training_type (e.g. sft-lora -> efficient_sft). | +| `--mtu-spec-code ` | string | no | MTU spec code, required for resource-group queries (e.g. MTU2) | +| `--param-type ` | string | no | Parameter group: hyper \| resource. Omit to return all groups. | +| `--modality ` | string | no | Training modality: text \| vision. Only meaningful for models with dynamic train options; sent as modality inside hyper_parameters. | +| `--reasoning-mode ` | string | no | Reasoning mode: instruct (non-thinking) \| thinking. Only meaningful for models with dynamic train options; sent as reasoning_mode inside hyper_parameters. | +| `--lang ` | string | no | Locale for server-side display text (e.g. en, zh). Omit for the server default. | +| `--workspace-id ` | string | no | Workspace ID sent as X-DashScope-WorkSpace; omit when your API key is already workspace-bound. | +| `--api-key ` | string | no | API key | +| `--base-url ` | string | no | API base URL | + +#### Notes + +- Queries GET /api/v1/fine-tunes/fine-tunes-params. Each hyper_params entry keeps server field names verbatim (recommend_value, defaultValue, is_advanced_parameter, ...). +- --modality / --reasoning-mode travel as one hyper_parameters query parameter (JSON). Supported values and combinations vary per model; invalid combinations are rejected by the server and surfaced as-is. Models without dynamic train options ignore these flags. +- resume_from_checkpoint in the output reports whether the training type supports resuming training. + +#### Examples + +```bash +bl finetune params --base-model qwen3-8b +``` + +```bash +bl finetune params --base-model qwen3-8b --training-type sft +``` + +```bash +bl finetune params --base-model qwen3-8b --training-type dpo-lora --param-type hyper +``` + +```bash +bl finetune params --base-model qwen3.7-plus-2026-05-26 --modality vision --reasoning-mode thinking +``` + +```bash +bl finetune params --base-model qwen3-8b --param-type resource --mtu-spec-code MTU2 +``` + +```bash +bl finetune params --base-model qwen3-8b --output json +``` + +```bash +bl finetune params --base-model qwen3-8b --dry-run +``` + ### `bl finetune price` | Field | Value | diff --git a/skills/bailian-finetune/reference/index.md b/skills/bailian-finetune/reference/index.md index f48966b93..ea1fc9ce1 100644 --- a/skills/bailian-finetune/reference/index.md +++ b/skills/bailian-finetune/reference/index.md @@ -55,6 +55,8 @@ Use this index for the skill-scoped quick index and global flags. | `bl finetune image create` | API Key | Create an image generation model fine-tune job (sft-lora) | [finetune.md](finetune.md) | | `bl finetune list` | API Key | List fine-tune jobs | [finetune.md](finetune.md) | | `bl finetune logs` | API Key | Fetch training logs for a fine-tune job | [finetune.md](finetune.md) | +| `bl finetune metrics` | API Key | Query the training metrics of a fine-tune job | [finetune.md](finetune.md) | +| `bl finetune params` | API Key | Query the training hyper-parameter configuration for a base model | [finetune.md](finetune.md) | | `bl finetune price` | Console | Estimate the training cost for a fine-tune job (token billing) | [finetune.md](finetune.md) | | `bl finetune text create` | API Key | Create a text model fine-tune job (sft \| sft-lora \| dpo \| dpo-lora \| cpt) | [finetune.md](finetune.md) | | `bl finetune video create` | API Key | Create a video generation model fine-tune job (Wan i2v/kf2v, efficient_sft) | [finetune.md](finetune.md) | @@ -62,11 +64,11 @@ Use this index for the skill-scoped quick index and global flags. ## By group -| Group | Commands | Reference | -| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | -| `dataset` | `delete`, `get`, `list`, `upload`, `validate` | [dataset.md](dataset.md) | -| `deploy` | `audio create`, `capacity create`, `capacity delete`, `capacity get`, `capacity list`, `capacity renew`, `capacity scale`, `capacity unsubscribe`, `delete`, `get`, `image create`, `list`, `models`, `operation get`, `operation wait`, `overflow`, `pause`, `resume`, `scale`, `text create`, `update` | [deploy.md](deploy.md) | -| `finetune` | `audio create`, `cancel`, `capability`, `checkpoints`, `compress cancel`, `compress create`, `compress delete`, `compress get`, `compress list`, `compress logs`, `compress templates`, `compress watch`, `delete`, `export`, `get`, `image create`, `list`, `logs`, `price`, `text create`, `video create`, `watch` | [finetune.md](finetune.md) | +| Group | Commands | Reference | +| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | +| `dataset` | `delete`, `get`, `list`, `upload`, `validate` | [dataset.md](dataset.md) | +| `deploy` | `audio create`, `capacity create`, `capacity delete`, `capacity get`, `capacity list`, `capacity renew`, `capacity scale`, `capacity unsubscribe`, `delete`, `get`, `image create`, `list`, `models`, `operation get`, `operation wait`, `overflow`, `pause`, `resume`, `scale`, `text create`, `update` | [deploy.md](deploy.md) | +| `finetune` | `audio create`, `cancel`, `capability`, `checkpoints`, `compress cancel`, `compress create`, `compress delete`, `compress get`, `compress list`, `compress logs`, `compress templates`, `compress watch`, `delete`, `export`, `get`, `image create`, `list`, `logs`, `metrics`, `params`, `price`, `text create`, `video create`, `watch` | [finetune.md](finetune.md) | ## Global flags From e546dba0aca99120b89d9ed8197f53e34541e38f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=95=85=E7=92=83?= Date: Fri, 6 Nov 2026 18:33:11 +0800 Subject: [PATCH 2/2] chore(release): prepare 2.8.4 --- CHANGELOG.md | 7 +++++++ CHANGELOG.zh.md | 7 +++++++ packages/bailian-kb-dsh/package.json | 2 +- packages/bailian-memo-dsh/package.json | 2 +- packages/cli/package.json | 2 +- packages/commands/package.json | 2 +- packages/core/package.json | 2 +- packages/kscli/package.json | 2 +- packages/runtime/package.json | 2 +- skills/bailian-cli/SKILL.md | 2 +- skills/bailian-finetune/SKILL.md | 2 +- skills/bailian-gen/SKILL.md | 2 +- skills/bailian-knowledge/SKILL.md | 2 +- skills/bailian-managed-agent/SKILL.md | 2 +- skills/bailian-memory/SKILL.md | 2 +- skills/bailian-protocol/SKILL.md | 2 +- skills/bailian-sandbox/SKILL.md | 2 +- skills/bailian-web-search/SKILL.md | 2 +- 18 files changed, 30 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13acb1d00..46e8baa15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and [中文版](CHANGELOG.zh.md) · [README](README.md) · [Contributing](CONTRIBUTING.md) +## [2.8.4] - 2026-11-06 + +### Added + +- **Fine-tune training params**: New `bl finetune params` command queries the training hyper-parameter configuration for a base model, with `--training-type`, `--param-type`, `--mtu-spec-code` filters and `--modality` / `--reasoning-mode` dynamic train options. +- **Fine-tune training metrics**: New `bl finetune metrics` command queries the training metrics of a fine-tune job, with explicit paging via `--page` / `--page-size`. + ## [2.8.3] - 2026-11-06 ### Added diff --git a/CHANGELOG.zh.md b/CHANGELOG.zh.md index d34887a8d..044122e24 100644 --- a/CHANGELOG.zh.md +++ b/CHANGELOG.zh.md @@ -6,6 +6,13 @@ [English](CHANGELOG.md) · [README](README.zh.md) · [参与贡献](CONTRIBUTING.zh.md) +## [2.8.4] - 2026-11-06 + +### 新增 + +- **精调训练参数查询**:新增 `bl finetune params` 命令,查询基础模型的训练超参配置,支持 `--training-type`、`--param-type`、`--mtu-spec-code` 筛选及 `--modality` / `--reasoning-mode` 动态训练选项。 +- **精调训练指标查询**:新增 `bl finetune metrics` 命令,查询微调任务的训练指标,支持 `--page` / `--page-size` 显式分页。 + ## [2.8.3] - 2026-11-06 ### 新增 diff --git a/packages/bailian-kb-dsh/package.json b/packages/bailian-kb-dsh/package.json index 7e1b1734c..8b36b17fc 100644 --- a/packages/bailian-kb-dsh/package.json +++ b/packages/bailian-kb-dsh/package.json @@ -1,6 +1,6 @@ { "name": "bailian-kb-dsh", - "version": "2.8.3", + "version": "2.8.4", "description": "Bailian knowledge-base tools for DeepSeek Harness: kb_search and kb_chat over the DashScope RAG API, plus the bl CLI management skill.", "keywords": [ "alibaba-cloud", diff --git a/packages/bailian-memo-dsh/package.json b/packages/bailian-memo-dsh/package.json index 63e538faf..649e8b35c 100644 --- a/packages/bailian-memo-dsh/package.json +++ b/packages/bailian-memo-dsh/package.json @@ -1,6 +1,6 @@ { "name": "bailian-memo-dsh", - "version": "2.8.3", + "version": "2.8.4", "description": "Bailian personal memory for DeepSeek Harness: automatic recall, silent curation, and user-controlled remember/forget.", "keywords": [ "alibaba-cloud", diff --git a/packages/cli/package.json b/packages/cli/package.json index df104826c..31df47954 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "bailian-cli", - "version": "2.8.3", + "version": "2.8.4", "description": "CLI for Aliyun Model Studio (DashScope) AI Platform.", "keywords": [ "agent", diff --git a/packages/commands/package.json b/packages/commands/package.json index 48029c745..71b0ad52b 100644 --- a/packages/commands/package.json +++ b/packages/commands/package.json @@ -1,6 +1,6 @@ { "name": "bailian-cli-commands", - "version": "2.8.3", + "version": "2.8.4", "description": "Command library for bailian-cli products (knowledge, memory, media, …). See https://www.npmjs.com/package/bailian-cli for usage.", "homepage": "https://bailian.console.aliyun.com/cli", "bugs": { diff --git a/packages/core/package.json b/packages/core/package.json index fe12a150f..8acdc7a9d 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "bailian-cli-core", - "version": "2.8.3", + "version": "2.8.4", "description": "Core SDK for bailian-cli. See https://www.npmjs.com/package/bailian-cli for usage.", "homepage": "https://bailian.console.aliyun.com/cli", "bugs": { diff --git a/packages/kscli/package.json b/packages/kscli/package.json index 2d47e2d91..9fac71f1e 100644 --- a/packages/kscli/package.json +++ b/packages/kscli/package.json @@ -1,6 +1,6 @@ { "name": "knowledge-studio-cli", - "version": "2.8.3", + "version": "2.8.4", "description": "Lightweight RAG CLI for Aliyun Model Studio — focused on knowledge-base retrieval.", "keywords": [ "alibaba-cloud", diff --git a/packages/runtime/package.json b/packages/runtime/package.json index d0ef59eec..fd5c58310 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -1,6 +1,6 @@ { "name": "bailian-cli-runtime", - "version": "2.8.3", + "version": "2.8.4", "description": "Runtime framework for bailian-cli (createCli, registry, args, output, pipeline). See https://www.npmjs.com/package/bailian-cli for usage.", "homepage": "https://bailian.console.aliyun.com/cli", "bugs": { diff --git a/skills/bailian-cli/SKILL.md b/skills/bailian-cli/SKILL.md index 22c4b3ac0..2f0e49cff 100644 --- a/skills/bailian-cli/SKILL.md +++ b/skills/bailian-cli/SKILL.md @@ -1,7 +1,7 @@ --- name: bailian-cli metadata: - version: "2.8.3" + version: "2.8.4" requires: bins: ["bl"] description: >- diff --git a/skills/bailian-finetune/SKILL.md b/skills/bailian-finetune/SKILL.md index b881ffbfb..3d4f1f39d 100644 --- a/skills/bailian-finetune/SKILL.md +++ b/skills/bailian-finetune/SKILL.md @@ -1,7 +1,7 @@ --- name: bailian-finetune metadata: - version: "2.8.3" + version: "2.8.4" requires: bins: ["bl"] description: >- diff --git a/skills/bailian-gen/SKILL.md b/skills/bailian-gen/SKILL.md index 1189a019b..64f55592c 100644 --- a/skills/bailian-gen/SKILL.md +++ b/skills/bailian-gen/SKILL.md @@ -1,7 +1,7 @@ --- name: bailian-gen metadata: - version: "2.8.3" + version: "2.8.4" requires: bins: ["bl"] description: >- diff --git a/skills/bailian-knowledge/SKILL.md b/skills/bailian-knowledge/SKILL.md index b47c6e052..09093c130 100644 --- a/skills/bailian-knowledge/SKILL.md +++ b/skills/bailian-knowledge/SKILL.md @@ -1,7 +1,7 @@ --- name: bailian-knowledge metadata: - version: "2.8.3" + version: "2.8.4" requires: bins: ["bl"] description: >- diff --git a/skills/bailian-managed-agent/SKILL.md b/skills/bailian-managed-agent/SKILL.md index e9de66db2..3082558fe 100644 --- a/skills/bailian-managed-agent/SKILL.md +++ b/skills/bailian-managed-agent/SKILL.md @@ -1,7 +1,7 @@ --- name: bailian-managed-agent metadata: - version: "2.8.3" + version: "2.8.4" requires: bins: ["bl"] description: >- diff --git a/skills/bailian-memory/SKILL.md b/skills/bailian-memory/SKILL.md index d95ec2623..65c11181a 100644 --- a/skills/bailian-memory/SKILL.md +++ b/skills/bailian-memory/SKILL.md @@ -1,7 +1,7 @@ --- name: bailian-memory metadata: - version: "2.8.3" + version: "2.8.4" requires: bins: ["bl"] description: >- diff --git a/skills/bailian-protocol/SKILL.md b/skills/bailian-protocol/SKILL.md index a113094ef..1ea125e44 100644 --- a/skills/bailian-protocol/SKILL.md +++ b/skills/bailian-protocol/SKILL.md @@ -1,7 +1,7 @@ --- name: bailian-protocol metadata: - version: "2.8.3" + version: "2.8.4" requires: bins: ["bl"] description: >- diff --git a/skills/bailian-sandbox/SKILL.md b/skills/bailian-sandbox/SKILL.md index 43e0df22d..fc2bd3f69 100644 --- a/skills/bailian-sandbox/SKILL.md +++ b/skills/bailian-sandbox/SKILL.md @@ -1,7 +1,7 @@ --- name: bailian-sandbox metadata: - version: "2.8.3" + version: "2.8.4" requires: bins: ["bl"] description: >- diff --git a/skills/bailian-web-search/SKILL.md b/skills/bailian-web-search/SKILL.md index 9f49f1a6d..38c72d384 100644 --- a/skills/bailian-web-search/SKILL.md +++ b/skills/bailian-web-search/SKILL.md @@ -1,7 +1,7 @@ --- name: bailian-web-search metadata: - version: "2.8.3" + version: "2.8.4" requires: bins: ["bl"] description: >-