Skip to content

Commit e65954a

Browse files
committed
feat(app): add control-plane commands for agents and workflows
Sync app-center console APIs via console gateway: app create/get/update/publish/delete/copy/versions and app workflow get/save/publish/export; app list gains --type. Read-merge-write config updates; high-risk delete (--yes). Flags: --config-json/--agent-version/--flow-version. Adds app-control e2e; regenerates skill reference/READMEs.
1 parent 0f870ab commit e65954a

22 files changed

Lines changed: 2490 additions & 22 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ _Built for AI Agents. Every command works as a structured tool call._
2525

2626
- **Model generation** — Full-modality generation across text, image, video, and speech, with editing and reference-based generation
2727
- **Asset understanding** — Parse and ask questions about images, documents, audio, and long videos
28-
- **App orchestration** — Call Managed Agents, agents, and workflows published on Aliyun Model Studio, wired to knowledge bases, memory, web search, and MCP tools
28+
- **App orchestration** — Call Managed Agents, agents, and workflows published on Aliyun Model Studio, wired to knowledge bases, memory, web search, and MCP tools; create, update, publish, copy, and delete agents/workflows, and edit workflow canvases from the CLI
2929
- **Native MCP setup** — Register Bailian MCP servers in Codex, Claude Code, Cursor, Qoder, Qoder Work, QwenWork (千问办公), Qwen Code, Gemini CLI, or Pi
3030
- **Training & deployment** — Validate and upload datasets, fine-tune models, deploy dedicated models as endpoints
3131
- **Batch inference** — Prepare CSV/JSONL, create and follow asynchronous Chat/Embedding tasks, download original results/errors with optional CSV, or send one synchronous Batch Chat request

‎README.zh.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ _专为 AI Agent 打造,每个命令均可作为结构化工具调用。_
2424

2525
- **模型生成** — 文本、图像、视频、语音全模态生成,支持编辑与参考生成
2626
- **素材理解** — 图像、文档、音频、长视频的解析与问答
27-
- **应用编排** — 调用百炼已发布的 Managed Agent、智能体和工作流,接入知识库、记忆库、联网搜索与 MCP 工具
27+
- **应用编排** — 调用百炼已发布的 Managed Agent、智能体和工作流,接入知识库、记忆库、联网搜索与 MCP 工具;并可在命令行创建/更新/发布/复制/删除智能体与工作流、编辑工作流画布
2828
- **原生 MCP 接入** — 将百炼 MCP 服务注册到 Codex、Claude Code、Cursor、Qoder、Qoder Work、千问办公(QwenWork)、Qwen Code、Gemini CLI 或 Pi
2929
- **模型训推** — 数据集校验上传、模型精调、专属模型部署上线
3030
- **批量推理** — CSV/JSONL 构造、异步 Chat/Embedding 任务创建与跟踪、原始结果/错误下载及可选 CSV,或同步单请求 Batch Chat

‎packages/cli/src/commands.ts‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,17 @@ import {
3434
update,
3535
appCall,
3636
appList,
37+
appCreate,
38+
appGet,
39+
appUpdate,
40+
appPublish,
41+
appDelete,
42+
appCopy,
43+
appVersions,
44+
appWorkflowGet,
45+
appWorkflowSave,
46+
appWorkflowPublish,
47+
appWorkflowExport,
3748
memoryAdd,
3849
memorySearch,
3950
memoryList,
@@ -378,6 +389,17 @@ export const commands: Record<string, AnyCommand> = {
378389
update,
379390
"app call": appCall,
380391
"app list": appList,
392+
"app create": appCreate,
393+
"app get": appGet,
394+
"app update": appUpdate,
395+
"app publish": appPublish,
396+
"app delete": appDelete,
397+
"app copy": appCopy,
398+
"app versions": appVersions,
399+
"app workflow get": appWorkflowGet,
400+
"app workflow save": appWorkflowSave,
401+
"app workflow publish": appWorkflowPublish,
402+
"app workflow export": appWorkflowExport,
381403
"memory add": memoryAdd,
382404
"memory search": memorySearch,
383405
"memory list": memoryList,
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { defineCommand } from "bailian-cli-core";
2+
import {
3+
APP_CONTROL_COPY_API,
4+
APP_ID_FLAG,
5+
consoleCall,
6+
consoleDryRunPreview,
7+
extractAppCode,
8+
} from "./shared.ts";
9+
10+
export default defineCommand({
11+
description: {
12+
"en-US": "Copy a Bailian application (agent or workflow)",
13+
"zh-CN": "复制百炼应用(智能体或工作流)",
14+
},
15+
auth: "console",
16+
usageArgs: "--app-id <id> [flags]",
17+
flags: {
18+
...APP_ID_FLAG,
19+
},
20+
exampleArgs: ["--app-id abc123"],
21+
async run(ctx) {
22+
const { settings, flags } = ctx;
23+
const code = flags.appId;
24+
const data = { reqDTO: { code } };
25+
26+
if (settings.dryRun) {
27+
ctx.output.result(consoleDryRunPreview(settings, APP_CONTROL_COPY_API, data));
28+
return;
29+
}
30+
31+
const payload = await consoleCall(ctx.client, APP_CONTROL_COPY_API, data);
32+
const newAppCode = extractAppCode(payload);
33+
ctx.output.result(
34+
{ app_code: newAppCode ?? null, source_app_code: code, result: payload },
35+
settings.output === "text"
36+
? {
37+
text: ctx.localize({
38+
"en-US": `Application copied: ${newAppCode ?? "(see result)"}`,
39+
"zh-CN": `应用已复制:${newAppCode ?? "(见 result)"}`,
40+
}),
41+
}
42+
: undefined,
43+
);
44+
},
45+
});
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
import { defineCommand } from "bailian-cli-core";
2+
import {
3+
APP_CONTROL_CREATE_API,
4+
APP_DATA_CREATE_DRAFT_API,
5+
APP_TYPE_AGENT,
6+
CONFIG_FLAGS,
7+
APP_TYPE_FLAG,
8+
consoleCall,
9+
consoleDryRunPreview,
10+
extractAppCode,
11+
readConfigJson,
12+
resolveAppType,
13+
validateConfigFlags,
14+
} from "./shared.ts";
15+
16+
/** Default agent config aligned with the console create modal (new-agent). */
17+
function defaultAgentConfig(model?: string): Record<string, unknown> {
18+
return {
19+
model: model || "auto",
20+
model_config: {
21+
temperature: 0.7,
22+
enable_thinking: true,
23+
thinking_budget: 4000,
24+
},
25+
dialog_round: 3,
26+
};
27+
}
28+
29+
export default defineCommand({
30+
description: {
31+
"en-US": "Create a Bailian application (agent or workflow)",
32+
"zh-CN": "创建百炼应用(智能体或工作流)",
33+
},
34+
auth: "console",
35+
usageArgs: "--name <name> [flags]",
36+
flags: {
37+
name: {
38+
type: "string",
39+
valueHint: "<name>",
40+
description: { "en-US": "Application name (required)", "zh-CN": "应用名称(必填)" },
41+
required: true,
42+
},
43+
...APP_TYPE_FLAG,
44+
description: {
45+
type: "string",
46+
valueHint: "<text>",
47+
description: { "en-US": "Application description", "zh-CN": "应用描述" },
48+
},
49+
icon: {
50+
type: "string",
51+
valueHint: "<key>",
52+
description: { "en-US": "Application icon key", "zh-CN": "应用图标 key" },
53+
},
54+
model: {
55+
type: "string",
56+
valueHint: "<model>",
57+
description: {
58+
"en-US": "Agent model ID (default: auto; agent only)",
59+
"zh-CN": "智能体模型 ID(默认:auto;仅 agent 有效)",
60+
},
61+
},
62+
...CONFIG_FLAGS,
63+
},
64+
notes: [
65+
{
66+
"en-US":
67+
"Agent creation uses the app-control 2.0 API with a default config (model auto, dialog_round 3). --config-json/--config-file shallow-merges over the default config; --model overrides config.model.",
68+
"zh-CN":
69+
"智能体创建走 app-control 2.0 接口,携带默认配置(model auto、dialog_round 3)。--config-json/--config-file 浅合并覆盖默认配置;--model 覆盖 config.model。",
70+
},
71+
{
72+
"en-US":
73+
"Workflow creation creates an empty draft canvas; edit it with `app workflow save` and publish with `app workflow publish`.",
74+
"zh-CN":
75+
"工作流创建为空草稿画布;用 `app workflow save` 编辑画布,用 `app workflow publish` 发布。",
76+
},
77+
],
78+
exampleArgs: [
79+
{
80+
"en-US": '--name "Customer service"',
81+
"zh-CN": '--name "客户服务"',
82+
},
83+
{
84+
"en-US": '--name "Customer service" --model qwen3-max --description "After-sales bot"',
85+
"zh-CN": '--name "客户服务" --model qwen3-max --description "售后机器人"',
86+
},
87+
{
88+
"en-US": '--name "Order flow" --type workflow',
89+
"zh-CN": '--name "订单流程" --type workflow',
90+
},
91+
{
92+
"en-US": '--name "My agent" --config-file ./agent-config.json',
93+
"zh-CN": '--name "我的智能体" --config-file ./agent-config.json',
94+
},
95+
],
96+
validate: (flags) => {
97+
const conflict = validateConfigFlags(flags);
98+
if (conflict) return conflict;
99+
if (
100+
resolveAppType(flags) === "workflow" &&
101+
(flags.model !== undefined ||
102+
flags.configJson !== undefined ||
103+
flags.configFile !== undefined)
104+
) {
105+
return {
106+
"en-US":
107+
"--model/--config-json/--config-file only apply to agent creation; edit a workflow canvas with `app workflow save`",
108+
"zh-CN":
109+
"--model/--config-json/--config-file 仅适用于智能体创建;工作流画布请用 `app workflow save` 编辑",
110+
};
111+
}
112+
return undefined;
113+
},
114+
async run(ctx) {
115+
const { settings, flags } = ctx;
116+
const appType = resolveAppType(flags);
117+
const userConfig = await readConfigJson(flags);
118+
119+
let api: string;
120+
let data: Record<string, unknown>;
121+
if (appType === "workflow") {
122+
api = APP_DATA_CREATE_DRAFT_API;
123+
data = {
124+
reqDTO: {
125+
name: flags.name,
126+
appDescription: flags.description,
127+
applicationConfigDTO: {},
128+
createType: "Workflow",
129+
modelId: "",
130+
icon: flags.icon,
131+
subType: "chat",
132+
},
133+
};
134+
} else {
135+
const config = { ...defaultAgentConfig(flags.model), ...userConfig };
136+
if (flags.model) config.model = flags.model;
137+
api = APP_CONTROL_CREATE_API;
138+
data = {
139+
reqDTO: {
140+
name: flags.name,
141+
description: flags.description,
142+
icon: flags.icon,
143+
source: "console",
144+
type: APP_TYPE_AGENT,
145+
status: 1,
146+
config,
147+
},
148+
};
149+
}
150+
151+
if (settings.dryRun) {
152+
ctx.output.result(consoleDryRunPreview(settings, api, data));
153+
return;
154+
}
155+
156+
const payload = await consoleCall(ctx.client, api, data);
157+
const appCode = extractAppCode(payload);
158+
ctx.output.result(
159+
{ app_code: appCode ?? null, result: payload },
160+
settings.output === "text"
161+
? {
162+
text: ctx.localize({
163+
"en-US": `Application created: ${appCode ?? "(see result)"}`,
164+
"zh-CN": `应用已创建:${appCode ?? "(见 result)"}`,
165+
}),
166+
}
167+
: undefined,
168+
);
169+
},
170+
});
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { defineCommand } from "bailian-cli-core";
2+
import {
3+
APP_CONTROL_DELETE_API,
4+
APP_ID_FLAG,
5+
consoleCall,
6+
consoleDryRunPreview,
7+
} from "./shared.ts";
8+
9+
export default defineCommand({
10+
description: {
11+
"en-US": "Delete a Bailian application (agent or workflow)",
12+
"zh-CN": "删除百炼应用(智能体或工作流)",
13+
},
14+
auth: "console",
15+
risk: {
16+
level: "high",
17+
message: {
18+
"en-US":
19+
"This permanently deletes the application and its configuration. Confirm the app ID before proceeding.",
20+
"zh-CN": "该操作会永久删除应用及其配置,请确认应用 ID。",
21+
},
22+
},
23+
usageArgs: "--app-id <id> [flags]",
24+
flags: {
25+
...APP_ID_FLAG,
26+
},
27+
notes: [
28+
{
29+
"en-US": "Deletion is irreversible. Run `app list` or `app get` first to confirm the app ID.",
30+
"zh-CN": "删除不可撤销。建议先用 `app list` 或 `app get` 确认应用 ID。",
31+
},
32+
],
33+
exampleArgs: ["--app-id abc123", "--app-id abc123 --yes"],
34+
async run(ctx) {
35+
const { settings, flags } = ctx;
36+
const code = flags.appId;
37+
const data = { reqDTO: { code } };
38+
39+
if (settings.dryRun) {
40+
ctx.output.result(consoleDryRunPreview(settings, APP_CONTROL_DELETE_API, data));
41+
return;
42+
}
43+
44+
const payload = await consoleCall(ctx.client, APP_CONTROL_DELETE_API, data);
45+
ctx.output.result(
46+
{ app_code: code, result: payload },
47+
settings.output === "text"
48+
? {
49+
text: ctx.localize({
50+
"en-US": `Application ${code} deleted.`,
51+
"zh-CN": `应用 ${code} 已删除。`,
52+
}),
53+
}
54+
: undefined,
55+
);
56+
},
57+
});

0 commit comments

Comments
 (0)