yuanflow-cli 0.1.0 → 0.1.1
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/LICENSE +1 -1
- package/README.md +34 -50
- package/bin/yuanflow-cli.js +26 -0
- package/bin/yuanflow-skill.cjs +334 -0
- package/generated/registry.json +24641 -0
- package/lib/skill-installer/agents.cjs +203 -0
- package/lib/skill-installer/discover-skills.cjs +79 -0
- package/lib/skill-installer/installer.cjs +300 -0
- package/lib/skill-installer/publish.cjs +53 -0
- package/lib/skill-installer/repo-source.cjs +157 -0
- package/package.json +56 -6
- package/scripts/generate-registry.js +174 -0
- package/src/agent-protocol.js +169 -0
- package/src/cli.js +382 -0
- package/src/config.js +31 -0
- package/src/registry.js +45 -0
- package/src/request.js +97 -0
- package/src/shortcuts.js +346 -0
- package/cli.js +0 -3
- package/src/ycloud/cli.js +0 -29
- package/src/ycloud/commands/analysis.js +0 -82
- package/src/ycloud/commands/auth.js +0 -191
- package/src/ycloud/commands/commands.js +0 -262
- package/src/ycloud/commands/compliance.js +0 -146
- package/src/ycloud/commands/config.js +0 -103
- package/src/ycloud/commands/health.js +0 -35
- package/src/ycloud/commands/index.js +0 -381
- package/src/ycloud/commands/kb.js +0 -82
- package/src/ycloud/commands/schema.js +0 -229
- package/src/ycloud/commands/shared.js +0 -30
- package/src/ycloud/commands/tool-registry.js +0 -209
- package/src/ycloud/commands/tool-runner.js +0 -226
- package/src/ycloud/commands/tool.js +0 -178
- package/src/ycloud/commands/version.js +0 -84
- package/src/ycloud/core/config.js +0 -78
- package/src/ycloud/core/http.js +0 -133
- package/src/ycloud/core/token.js +0 -30
- package/src/ycloud/resources/.gitkeep +0 -1
- package/src/ycloud/resources/tool_catalog_full.json +0 -1
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
export function getGlobalFlagsHelp() {
|
|
2
|
-
return `Global Flags:
|
|
3
|
-
--output string output format: json (default) | text
|
|
4
|
-
--trace-id string optional request trace id
|
|
5
|
-
--timeout int request timeout in milliseconds
|
|
6
|
-
--base-url string override API base URL`;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function parseInteger(value) {
|
|
10
|
-
if (value === undefined) {
|
|
11
|
-
return undefined;
|
|
12
|
-
}
|
|
13
|
-
const parsed = Number.parseInt(String(value), 10);
|
|
14
|
-
return Number.isNaN(parsed) ? undefined : parsed;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function parseFloatNumber(value) {
|
|
18
|
-
if (value === undefined) {
|
|
19
|
-
return undefined;
|
|
20
|
-
}
|
|
21
|
-
const parsed = Number.parseFloat(String(value));
|
|
22
|
-
return Number.isNaN(parsed) ? undefined : parsed;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function parseJsonString(value) {
|
|
26
|
-
if (!value) {
|
|
27
|
-
return undefined;
|
|
28
|
-
}
|
|
29
|
-
return JSON.parse(value);
|
|
30
|
-
}
|
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
const STATIC_TOOL_REGISTRY = {
|
|
2
|
-
content: {
|
|
3
|
-
title: "content creation tools",
|
|
4
|
-
commands: {
|
|
5
|
-
"knowledge-base-search": {
|
|
6
|
-
toolId: "knowledge_base_search",
|
|
7
|
-
commandName: "content knowledge-base-search",
|
|
8
|
-
description: "Search knowledge base content via wrapped tool",
|
|
9
|
-
requiredFlags: ["query"],
|
|
10
|
-
},
|
|
11
|
-
"copywriting-generate": {
|
|
12
|
-
toolId: "copywriting_generate",
|
|
13
|
-
commandName: "content copywriting-generate",
|
|
14
|
-
description: "Generate short video copywriting",
|
|
15
|
-
requiredFlags: ["task"],
|
|
16
|
-
},
|
|
17
|
-
"douyin-topic-generate": {
|
|
18
|
-
toolId: "douyin_topic_generate",
|
|
19
|
-
commandName: "content douyin-topic-generate",
|
|
20
|
-
description: "Generate Douyin topic ideas",
|
|
21
|
-
requiredFlags: ["prompt"],
|
|
22
|
-
},
|
|
23
|
-
"doubao-image-generate": {
|
|
24
|
-
toolId: "doubao_image_generate",
|
|
25
|
-
commandName: "content doubao-image-generate",
|
|
26
|
-
description: "Generate image assets with Doubao image model",
|
|
27
|
-
requiredFlags: ["prompt"],
|
|
28
|
-
},
|
|
29
|
-
"script-generate": {
|
|
30
|
-
toolId: "script_generate",
|
|
31
|
-
commandName: "content script-generate",
|
|
32
|
-
description: "Generate video script content",
|
|
33
|
-
requiredFlags: ["task", "duration-seconds"],
|
|
34
|
-
},
|
|
35
|
-
"xiaohongshu-content-generate": {
|
|
36
|
-
toolId: "xiaohongshu_content_generate",
|
|
37
|
-
commandName: "content xiaohongshu-content-generate",
|
|
38
|
-
description: "Generate Xiaohongshu content and images",
|
|
39
|
-
requiredFlags: ["prompt"],
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
oss: {
|
|
44
|
-
title: "oss tools",
|
|
45
|
-
commands: {
|
|
46
|
-
"temp-policy": {
|
|
47
|
-
toolId: "oss_temp_policy_get",
|
|
48
|
-
commandName: "oss temp-policy",
|
|
49
|
-
description: "Get OSS temporary object policy",
|
|
50
|
-
requiredFlags: [],
|
|
51
|
-
},
|
|
52
|
-
"upload-base64": {
|
|
53
|
-
toolId: "oss_upload_base64",
|
|
54
|
-
commandName: "oss upload-base64",
|
|
55
|
-
description: "Upload Base64 payload to OSS",
|
|
56
|
-
requiredFlags: ["filename", "content-base64"],
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
speech: {
|
|
61
|
-
title: "speech tools",
|
|
62
|
-
commands: {
|
|
63
|
-
recognition: {
|
|
64
|
-
toolId: "speech_recognition",
|
|
65
|
-
commandName: "speech recognition",
|
|
66
|
-
description: "Recognize speech from audio file",
|
|
67
|
-
requiredFlags: ["audio-url"],
|
|
68
|
-
},
|
|
69
|
-
synthesis: {
|
|
70
|
-
toolId: "speech_synthesis",
|
|
71
|
-
commandName: "speech synthesis",
|
|
72
|
-
description: "Synthesize speech audio from text",
|
|
73
|
-
requiredFlags: ["text"],
|
|
74
|
-
},
|
|
75
|
-
"disfluency-trim-plan": {
|
|
76
|
-
toolId: "speech_disfluency_trim_plan",
|
|
77
|
-
commandName: "speech disfluency-trim-plan",
|
|
78
|
-
description: "Generate disfluency trim plan for speech",
|
|
79
|
-
requiredFlags: ["audio-url", "script-text"],
|
|
80
|
-
},
|
|
81
|
-
},
|
|
82
|
-
},
|
|
83
|
-
social: {
|
|
84
|
-
title: "social media atomic tools",
|
|
85
|
-
commands: {
|
|
86
|
-
"xiaohongshu-search-notes": {
|
|
87
|
-
toolId: "social_search_notes_v3",
|
|
88
|
-
commandName: "social xiaohongshu-search-notes",
|
|
89
|
-
description: "Search Xiaohongshu notes",
|
|
90
|
-
requiredFlags: ["keyword"],
|
|
91
|
-
aliases: { keywords: "keyword" },
|
|
92
|
-
},
|
|
93
|
-
"xiaohongshu-search-users": {
|
|
94
|
-
toolId: "social_search_users_v1",
|
|
95
|
-
commandName: "social xiaohongshu-search-users",
|
|
96
|
-
description: "Search Xiaohongshu users",
|
|
97
|
-
requiredFlags: ["keyword"],
|
|
98
|
-
aliases: { keywords: "keyword" },
|
|
99
|
-
},
|
|
100
|
-
"xiaohongshu-note-info": {
|
|
101
|
-
toolId: "social_get_note_info_v2",
|
|
102
|
-
commandName: "social xiaohongshu-note-info",
|
|
103
|
-
description: "Get Xiaohongshu note detail",
|
|
104
|
-
requiredFlags: [],
|
|
105
|
-
},
|
|
106
|
-
"douyin-video-search": {
|
|
107
|
-
toolId: "social_get_video_search_results",
|
|
108
|
-
commandName: "social douyin-video-search",
|
|
109
|
-
description: "Search Douyin videos",
|
|
110
|
-
requiredFlags: ["keyword"],
|
|
111
|
-
},
|
|
112
|
-
"douyin-general-search": {
|
|
113
|
-
toolId: "social_get_general_search_results",
|
|
114
|
-
commandName: "social douyin-general-search",
|
|
115
|
-
description: "Run Douyin general search",
|
|
116
|
-
requiredFlags: ["keyword"],
|
|
117
|
-
},
|
|
118
|
-
"douyin-hot-search": {
|
|
119
|
-
toolId: "social_get_hot_search_list",
|
|
120
|
-
commandName: "social douyin-hot-search",
|
|
121
|
-
description: "Get Douyin hot search list",
|
|
122
|
-
requiredFlags: [],
|
|
123
|
-
},
|
|
124
|
-
"douyin-user-info": {
|
|
125
|
-
toolId: "social_get_user_info_by_sec_user_id",
|
|
126
|
-
commandName: "social douyin-user-info",
|
|
127
|
-
description: "Get Douyin user info by sec_user_id",
|
|
128
|
-
requiredFlags: ["sec-user-id"],
|
|
129
|
-
},
|
|
130
|
-
"douyin-homepage-videos": {
|
|
131
|
-
toolId: "social_get_user_homepage_video_data",
|
|
132
|
-
commandName: "social douyin-homepage-videos",
|
|
133
|
-
description: "Get Douyin user homepage videos",
|
|
134
|
-
requiredFlags: ["sec-user-id"],
|
|
135
|
-
},
|
|
136
|
-
"douyin-video-detail": {
|
|
137
|
-
toolId: "social_get_single_video_data_v2",
|
|
138
|
-
commandName: "social douyin-video-detail",
|
|
139
|
-
description: "Get Douyin single video detail",
|
|
140
|
-
requiredFlags: ["aweme-id"],
|
|
141
|
-
},
|
|
142
|
-
},
|
|
143
|
-
},
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
function toKebabCase(value) {
|
|
147
|
-
return value
|
|
148
|
-
.replace(/^social_/, "")
|
|
149
|
-
.replace(/_/g, "-");
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
function toFlagName(value) {
|
|
153
|
-
return value.replace(/_/g, "-");
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
function inferAliases(toolId, schemaProperties) {
|
|
157
|
-
const aliases = {};
|
|
158
|
-
if (toolId === "social_search_notes_v3" || toolId === "social_search_users_v1") {
|
|
159
|
-
aliases.keywords = "keyword";
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
if (schemaProperties.sec_uid && !schemaProperties.sec_user_id) {
|
|
163
|
-
aliases["sec-user-id"] = "sec-uid";
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
if (schemaProperties.url && schemaProperties.share_link) {
|
|
167
|
-
aliases.url = "share-link";
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
return Object.keys(aliases).length > 0 ? aliases : undefined;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
function buildSocialCommandConfig(item) {
|
|
174
|
-
const properties = item.schema?.properties || {};
|
|
175
|
-
const required = (item.schema?.required || []).map(toFlagName);
|
|
176
|
-
return {
|
|
177
|
-
toolId: item.tool_id,
|
|
178
|
-
commandName: `social ${toKebabCase(item.tool_id)}`,
|
|
179
|
-
description: item.description || `Execute ${item.tool_id}`,
|
|
180
|
-
requiredFlags: required,
|
|
181
|
-
aliases: inferAliases(item.tool_id, properties),
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
export function buildToolRegistry(catalogMap) {
|
|
186
|
-
const registry = structuredClone(STATIC_TOOL_REGISTRY);
|
|
187
|
-
const socialCommands = { ...registry.social.commands };
|
|
188
|
-
|
|
189
|
-
for (const item of catalogMap.values()) {
|
|
190
|
-
if (!item.tool_id?.startsWith("social_")) {
|
|
191
|
-
continue;
|
|
192
|
-
}
|
|
193
|
-
const subcommand = toKebabCase(item.tool_id);
|
|
194
|
-
if (socialCommands[subcommand]) {
|
|
195
|
-
continue;
|
|
196
|
-
}
|
|
197
|
-
socialCommands[subcommand] = buildSocialCommandConfig(item);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
registry.social.commands = Object.fromEntries(
|
|
201
|
-
Object.entries(socialCommands).sort(([left], [right]) =>
|
|
202
|
-
left.localeCompare(right),
|
|
203
|
-
),
|
|
204
|
-
);
|
|
205
|
-
|
|
206
|
-
return registry;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
export const TOOL_REGISTRY = STATIC_TOOL_REGISTRY;
|
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
import { apiPost } from "../core/http.js";
|
|
2
|
-
import { getToken } from "../core/token.js";
|
|
3
|
-
import { getGlobalFlagsHelp, parseFloatNumber, parseInteger, parseJsonString } from "./shared.js";
|
|
4
|
-
|
|
5
|
-
function toFlagName(property) {
|
|
6
|
-
return property.replace(/_/g, "-");
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
function parsePrimitiveBySchema(name, schema, value) {
|
|
10
|
-
if (value === undefined) {
|
|
11
|
-
return undefined;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const type = schema?.type;
|
|
15
|
-
if (type === "integer") {
|
|
16
|
-
return parseInteger(value);
|
|
17
|
-
}
|
|
18
|
-
if (type === "number") {
|
|
19
|
-
return parseFloatNumber(value);
|
|
20
|
-
}
|
|
21
|
-
if (type === "boolean") {
|
|
22
|
-
return value === true || value === "true";
|
|
23
|
-
}
|
|
24
|
-
if (type === "object") {
|
|
25
|
-
if (typeof value === "string") {
|
|
26
|
-
return parseJsonString(value);
|
|
27
|
-
}
|
|
28
|
-
return value;
|
|
29
|
-
}
|
|
30
|
-
if (type === "array") {
|
|
31
|
-
if (Array.isArray(value)) {
|
|
32
|
-
return value;
|
|
33
|
-
}
|
|
34
|
-
if (typeof value === "string") {
|
|
35
|
-
const trimmed = value.trim();
|
|
36
|
-
if (trimmed.startsWith("[")) {
|
|
37
|
-
return parseJsonString(trimmed);
|
|
38
|
-
}
|
|
39
|
-
return trimmed
|
|
40
|
-
.split(",")
|
|
41
|
-
.map((item) => item.trim())
|
|
42
|
-
.filter(Boolean);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return value;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function normalizeFlagValue(name, schema, value) {
|
|
49
|
-
if (value === undefined) {
|
|
50
|
-
return undefined;
|
|
51
|
-
}
|
|
52
|
-
if (schema?.type) {
|
|
53
|
-
return parsePrimitiveBySchema(name, schema, value);
|
|
54
|
-
}
|
|
55
|
-
if (name.endsWith("_count") || name.endsWith("_limit") || name.endsWith("_seconds") || name === "page" || name === "page_size" || name === "top_k" || name === "sample_rate" || name === "count" || name === "image_count" || name === "copy_length" || name === "duration_seconds" || name === "ai_mode") {
|
|
56
|
-
return parseInteger(value);
|
|
57
|
-
}
|
|
58
|
-
if (name === "min_score") {
|
|
59
|
-
return parseFloatNumber(value);
|
|
60
|
-
}
|
|
61
|
-
if (name === "enable_timestamp" || name === "return_raw") {
|
|
62
|
-
return value === true || value === "true";
|
|
63
|
-
}
|
|
64
|
-
if (name === "constraints" || name === "context" || name === "body") {
|
|
65
|
-
return typeof value === "string" ? parseJsonString(value) : value;
|
|
66
|
-
}
|
|
67
|
-
return value;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function mapFlagsToBody(rawOptions, commandConfig, schemaProperties = {}) {
|
|
71
|
-
const options = { ...rawOptions };
|
|
72
|
-
for (const [from, to] of Object.entries(commandConfig.aliases || {})) {
|
|
73
|
-
if (options[from] !== undefined && options[to] === undefined) {
|
|
74
|
-
options[to] = options[from];
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const body = {};
|
|
79
|
-
for (const property of Object.keys(schemaProperties)) {
|
|
80
|
-
const flag = toFlagName(property);
|
|
81
|
-
const rawValue = options[flag];
|
|
82
|
-
if (rawValue !== undefined) {
|
|
83
|
-
body[property] = normalizeFlagValue(property, schemaProperties[property], rawValue);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return body;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
async function requireToken(context) {
|
|
90
|
-
const token = await getToken();
|
|
91
|
-
if (!token) {
|
|
92
|
-
return context.fail(
|
|
93
|
-
context.commandName,
|
|
94
|
-
"TOKEN_MISSING",
|
|
95
|
-
"缺少 YUANCHUANG_API_TOKEN",
|
|
96
|
-
3,
|
|
97
|
-
false,
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
return token;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export function createDomainHelp(domain, registry, catalogMap) {
|
|
104
|
-
const items = Object.entries(registry.commands).map(([subcommand, config]) => {
|
|
105
|
-
const item = catalogMap.get(config.toolId);
|
|
106
|
-
const description = item?.description || config.description;
|
|
107
|
-
return ` ${subcommand.padEnd(28)} ${description}`;
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
return `${registry.title}
|
|
111
|
-
|
|
112
|
-
Usage:
|
|
113
|
-
ycloud ${domain} <subcommand> [flags]
|
|
114
|
-
|
|
115
|
-
Available Subcommands:
|
|
116
|
-
${items.join("\n")}
|
|
117
|
-
|
|
118
|
-
${getGlobalFlagsHelp()}`;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export function createToolCommandHelp(domain, subcommand, config, catalogItem) {
|
|
122
|
-
const properties = catalogItem?.schema?.properties || {};
|
|
123
|
-
const required = new Set(config.requiredFlags || []);
|
|
124
|
-
const propertyLines = [];
|
|
125
|
-
const optionalLines = [];
|
|
126
|
-
|
|
127
|
-
for (const property of Object.keys(properties)) {
|
|
128
|
-
const flag = `--${toFlagName(property)}`;
|
|
129
|
-
const type = properties[property].type || "string";
|
|
130
|
-
const desc = properties[property].description || "";
|
|
131
|
-
const line = ` ${flag} ${type}`.padEnd(28) + desc;
|
|
132
|
-
if (required.has(toFlagName(property))) {
|
|
133
|
-
propertyLines.push(line);
|
|
134
|
-
} else {
|
|
135
|
-
optionalLines.push(line);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return `${config.description}
|
|
140
|
-
|
|
141
|
-
Usage:
|
|
142
|
-
ycloud ${domain} ${subcommand} [flags]
|
|
143
|
-
|
|
144
|
-
Required Flags:
|
|
145
|
-
${propertyLines.length ? propertyLines.join("\n") : " none"}
|
|
146
|
-
|
|
147
|
-
Optional Flags:
|
|
148
|
-
${optionalLines.length ? optionalLines.join("\n") : " none"}
|
|
149
|
-
|
|
150
|
-
${getGlobalFlagsHelp()}
|
|
151
|
-
|
|
152
|
-
Examples:
|
|
153
|
-
ycloud ${domain} ${subcommand} --output json
|
|
154
|
-
|
|
155
|
-
Read on success:
|
|
156
|
-
data
|
|
157
|
-
|
|
158
|
-
Read on error:
|
|
159
|
-
error.code
|
|
160
|
-
error.message
|
|
161
|
-
error.retryable`;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
export async function executeRegisteredTool(
|
|
165
|
-
context,
|
|
166
|
-
tokens,
|
|
167
|
-
domain,
|
|
168
|
-
registry,
|
|
169
|
-
catalogMap,
|
|
170
|
-
) {
|
|
171
|
-
const subcommand = tokens[0];
|
|
172
|
-
const config = registry.commands[subcommand];
|
|
173
|
-
if (!config) {
|
|
174
|
-
return context.fail(
|
|
175
|
-
context.commandName,
|
|
176
|
-
"UNKNOWN_COMMAND",
|
|
177
|
-
"未知命令",
|
|
178
|
-
1,
|
|
179
|
-
false,
|
|
180
|
-
);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const options = context.parseCommandFlags(tokens.slice(1));
|
|
184
|
-
for (const requiredFlag of config.requiredFlags || []) {
|
|
185
|
-
const aliasSource = Object.entries(config.aliases || {}).find(
|
|
186
|
-
([from, to]) => to === requiredFlag && options[from] !== undefined,
|
|
187
|
-
);
|
|
188
|
-
if (options[requiredFlag] === undefined && !aliasSource) {
|
|
189
|
-
return context.fail(
|
|
190
|
-
config.commandName,
|
|
191
|
-
"BAD_ARGUMENT",
|
|
192
|
-
`缺少必填参数 --${requiredFlag}`,
|
|
193
|
-
2,
|
|
194
|
-
false,
|
|
195
|
-
);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
const token = await requireToken(context);
|
|
200
|
-
if (typeof token !== "string") {
|
|
201
|
-
return token;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
const catalogItem = catalogMap.get(config.toolId);
|
|
205
|
-
const body = mapFlagsToBody(
|
|
206
|
-
options,
|
|
207
|
-
config,
|
|
208
|
-
catalogItem?.schema?.properties || {},
|
|
209
|
-
);
|
|
210
|
-
|
|
211
|
-
const data = await apiPost("/v1/tools/execute", {
|
|
212
|
-
token,
|
|
213
|
-
traceId: context.globalOptions.traceId,
|
|
214
|
-
timeout: context.globalOptions.timeout,
|
|
215
|
-
baseUrl: context.globalOptions.baseUrl,
|
|
216
|
-
body: {
|
|
217
|
-
tool_id: config.toolId,
|
|
218
|
-
params: body,
|
|
219
|
-
trace_id: context.globalOptions.traceId,
|
|
220
|
-
},
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
return context.ok(config.commandName, data, {
|
|
224
|
-
tool_id: config.toolId,
|
|
225
|
-
});
|
|
226
|
-
}
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
import { apiGet, apiPost } from "../core/http.js";
|
|
2
|
-
import { getToken } from "../core/token.js";
|
|
3
|
-
import { getGlobalFlagsHelp, parseJsonString } from "./shared.js";
|
|
4
|
-
|
|
5
|
-
export function getToolHelp(subcommand) {
|
|
6
|
-
if (subcommand === "catalog") {
|
|
7
|
-
return `List available tool catalog
|
|
8
|
-
|
|
9
|
-
Usage:
|
|
10
|
-
ycloud tool catalog [flags]
|
|
11
|
-
|
|
12
|
-
Optional Flags:
|
|
13
|
-
none
|
|
14
|
-
|
|
15
|
-
${getGlobalFlagsHelp()}
|
|
16
|
-
|
|
17
|
-
Examples:
|
|
18
|
-
ycloud tool catalog --output json
|
|
19
|
-
|
|
20
|
-
Read on success:
|
|
21
|
-
data.tools
|
|
22
|
-
|
|
23
|
-
Read on error:
|
|
24
|
-
error.code
|
|
25
|
-
error.message
|
|
26
|
-
error.retryable`;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (subcommand === "execute") {
|
|
30
|
-
return `Execute a server-side tool
|
|
31
|
-
|
|
32
|
-
Usage:
|
|
33
|
-
ycloud tool execute [flags]
|
|
34
|
-
|
|
35
|
-
Required Flags:
|
|
36
|
-
--tool-id string tool id to execute
|
|
37
|
-
|
|
38
|
-
Optional Flags:
|
|
39
|
-
--params string JSON object string
|
|
40
|
-
--params-file string local JSON file path
|
|
41
|
-
--session-id string optional session id
|
|
42
|
-
--idempotency-key string request idempotency key
|
|
43
|
-
|
|
44
|
-
${getGlobalFlagsHelp()}
|
|
45
|
-
|
|
46
|
-
Examples:
|
|
47
|
-
ycloud tool execute --tool-id copywriting_generate --params "{\"topic\":\"短视频文案\"}" --output json
|
|
48
|
-
|
|
49
|
-
Read on success:
|
|
50
|
-
data
|
|
51
|
-
meta.tool_id
|
|
52
|
-
|
|
53
|
-
Read on error:
|
|
54
|
-
error.code
|
|
55
|
-
error.message
|
|
56
|
-
error.retryable`;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return `Tool commands
|
|
60
|
-
|
|
61
|
-
Usage:
|
|
62
|
-
ycloud tool <catalog|execute> [flags]`;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function requireToken(context) {
|
|
66
|
-
return getToken().then((token) => {
|
|
67
|
-
if (!token) {
|
|
68
|
-
return context.fail(
|
|
69
|
-
context.commandName,
|
|
70
|
-
"TOKEN_MISSING",
|
|
71
|
-
"缺少 YUANCHUANG_API_TOKEN",
|
|
72
|
-
3,
|
|
73
|
-
false,
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
return token;
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export async function executeToolCatalog(context) {
|
|
81
|
-
const token = await requireToken(context);
|
|
82
|
-
if (typeof token !== "string") {
|
|
83
|
-
return token;
|
|
84
|
-
}
|
|
85
|
-
const data = await apiGet("/v1/tools/catalog", {
|
|
86
|
-
token,
|
|
87
|
-
traceId: context.globalOptions.traceId,
|
|
88
|
-
timeout: context.globalOptions.timeout,
|
|
89
|
-
baseUrl: context.globalOptions.baseUrl,
|
|
90
|
-
});
|
|
91
|
-
return context.ok("tool catalog", data);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export async function executeToolExecute(context, tokens, allowedToolIds = new Set()) {
|
|
95
|
-
const options = context.parseCommandFlags(tokens);
|
|
96
|
-
if (!options["tool-id"]) {
|
|
97
|
-
return context.fail(
|
|
98
|
-
"tool execute",
|
|
99
|
-
"BAD_ARGUMENT",
|
|
100
|
-
"缺少必填参数 --tool-id",
|
|
101
|
-
2,
|
|
102
|
-
false,
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
if (options.params && options["params-file"]) {
|
|
106
|
-
return context.fail(
|
|
107
|
-
"tool execute",
|
|
108
|
-
"BAD_ARGUMENT",
|
|
109
|
-
"--params 和 --params-file 只能二选一",
|
|
110
|
-
2,
|
|
111
|
-
false,
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
if (allowedToolIds.size > 0 && !allowedToolIds.has(options["tool-id"])) {
|
|
115
|
-
return context.fail(
|
|
116
|
-
"tool execute",
|
|
117
|
-
"BAD_ARGUMENT",
|
|
118
|
-
`tool_id 未注册到当前 CLI 暴露面: ${options["tool-id"]}`,
|
|
119
|
-
2,
|
|
120
|
-
false,
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const token = await requireToken(context);
|
|
125
|
-
if (typeof token !== "string") {
|
|
126
|
-
return token;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
let params = undefined;
|
|
130
|
-
if (options.params) {
|
|
131
|
-
try {
|
|
132
|
-
params = parseJsonString(options.params);
|
|
133
|
-
} catch {
|
|
134
|
-
return context.fail(
|
|
135
|
-
"tool execute",
|
|
136
|
-
"BAD_ARGUMENT",
|
|
137
|
-
"--params 必须是合法 JSON",
|
|
138
|
-
2,
|
|
139
|
-
false,
|
|
140
|
-
);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if (options["params-file"]) {
|
|
145
|
-
const { readFile } = await import("node:fs/promises");
|
|
146
|
-
try {
|
|
147
|
-
params = JSON.parse(
|
|
148
|
-
await readFile(options["params-file"], { encoding: "utf-8" }),
|
|
149
|
-
);
|
|
150
|
-
} catch {
|
|
151
|
-
return context.fail(
|
|
152
|
-
"tool execute",
|
|
153
|
-
"BAD_ARGUMENT",
|
|
154
|
-
"--params-file 必须是合法 JSON 文件",
|
|
155
|
-
2,
|
|
156
|
-
false,
|
|
157
|
-
);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
const data = await apiPost("/v1/tools/execute", {
|
|
162
|
-
token,
|
|
163
|
-
traceId: context.globalOptions.traceId,
|
|
164
|
-
timeout: context.globalOptions.timeout,
|
|
165
|
-
baseUrl: context.globalOptions.baseUrl,
|
|
166
|
-
body: {
|
|
167
|
-
tool_id: options["tool-id"],
|
|
168
|
-
params,
|
|
169
|
-
session_id: options["session-id"],
|
|
170
|
-
trace_id: context.globalOptions.traceId,
|
|
171
|
-
idempotency_key: options["idempotency-key"],
|
|
172
|
-
},
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
return context.ok("tool execute", data, {
|
|
176
|
-
tool_id: options["tool-id"],
|
|
177
|
-
});
|
|
178
|
-
}
|