yuanflow-cli 0.1.7 → 0.1.8
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/README.md +5 -5
- package/package.json +1 -1
- package/skills/yuanflow-skill//350/207/252/345/252/222/344/275/223/347/237/245/350/257/206/345/272/223/SKILL.md +7 -4
- package/src/agent-protocol.js +15 -0
- package/src/atomic-request.js +39 -0
- package/src/cli.js +1 -1
- package/src/knowledge-tools.js +4 -2
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ yuanflow-cli works download --platform douyin --target "https://v.douyin.com/xxx
|
|
|
36
36
|
yuanflow-cli search content --platform xiaohongshu --keyword "美妆" --format agent-json
|
|
37
37
|
yuanflow-cli search users --platform instagram --keyword "nasa" --format agent-json
|
|
38
38
|
yuanflow-cli knowledge docs --format agent-json
|
|
39
|
-
yuanflow-cli knowledge entry --
|
|
39
|
+
yuanflow-cli knowledge entry --output-format short_video_script --domain 自媒体运营 --content-goal "写一个创业者短视频选题" --target-audience 创业者 --format agent-json
|
|
40
40
|
yuanflow-cli oss signed-url --key path/to/file.png --ttl-seconds 1800 --format agent-json
|
|
41
41
|
yuanflow-cli list douyin
|
|
42
42
|
```
|
|
@@ -96,12 +96,12 @@ Agent 不确定参数时先执行 `commands list`,再用 `schema works.douyin.
|
|
|
96
96
|
|
|
97
97
|
```bash
|
|
98
98
|
yuanflow-cli knowledge docs --format agent-json
|
|
99
|
-
yuanflow-cli knowledge entry --
|
|
100
|
-
yuanflow-cli knowledge rules --pack-code topic_pain_point_pack --
|
|
101
|
-
yuanflow-cli knowledge rule-detail --rule-code some_rule_code --
|
|
99
|
+
yuanflow-cli knowledge entry --output-format short_video_script --domain 自媒体运营 --content-goal "写一个创业者短视频选题" --target-audience 创业者 --format agent-json
|
|
100
|
+
yuanflow-cli knowledge rules --pack-code topic_pain_point_pack --output-format short_video_script --content-goal "写一个创业者短视频选题" --target-audience 创业者 --format agent-json
|
|
101
|
+
yuanflow-cli knowledge rule-detail --rule-code some_rule_code --output-format short_video_script --content-goal "写一个创业者短视频选题" --target-audience 创业者 --format agent-json
|
|
102
102
|
```
|
|
103
103
|
|
|
104
|
-
Agent 应先查看 `knowledge docs`,再把用户需求整理成 `task_frame`,按接口返回的 `next_actions` 渐进查询。
|
|
104
|
+
Agent 应先查看 `knowledge docs`,再把用户需求整理成 `task_frame`,按接口返回的 `next_actions` 渐进查询。v2 接口不要求 `task_intent`;旧字段仅保留兼容。`packs`、`rules` 的 `data` 可能直接是数组,Agent 不应假设固定对象结构,应优先读取 `next_actions` 继续下钻。
|
|
105
105
|
|
|
106
106
|
### OSS 原子能力
|
|
107
107
|
|
package/package.json
CHANGED
|
@@ -50,10 +50,10 @@ yuanflow-cli knowledge docs --format agent-json
|
|
|
50
50
|
|
|
51
51
|
```bash
|
|
52
52
|
yuanflow-cli knowledge entry \
|
|
53
|
-
--task-intent generate_script \
|
|
54
53
|
--output-format short_video_script \
|
|
55
54
|
--domain 自媒体运营 \
|
|
56
55
|
--content-goal "写一个面向创业者的短视频选题" \
|
|
56
|
+
--target-audience 创业者 \
|
|
57
57
|
--tone 清晰直接 \
|
|
58
58
|
--communication-mode 口播 \
|
|
59
59
|
--format agent-json
|
|
@@ -64,8 +64,9 @@ yuanflow-cli knowledge entry \
|
|
|
64
64
|
```bash
|
|
65
65
|
yuanflow-cli knowledge rules \
|
|
66
66
|
--pack-code topic_pain_point_pack \
|
|
67
|
-
--
|
|
67
|
+
--output-format short_video_script \
|
|
68
68
|
--content-goal "写一个面向创业者的短视频选题" \
|
|
69
|
+
--target-audience 创业者 \
|
|
69
70
|
--format agent-json
|
|
70
71
|
```
|
|
71
72
|
|
|
@@ -80,14 +81,14 @@ yuanflow-cli knowledge rules \
|
|
|
80
81
|
"args": [
|
|
81
82
|
"knowledge",
|
|
82
83
|
"entry",
|
|
83
|
-
"--task-intent",
|
|
84
|
-
"generate_script",
|
|
85
84
|
"--output-format",
|
|
86
85
|
"short_video_script",
|
|
87
86
|
"--domain",
|
|
88
87
|
"自媒体运营",
|
|
89
88
|
"--content-goal",
|
|
90
89
|
"写一个面向创业者的短视频选题",
|
|
90
|
+
"--target-audience",
|
|
91
|
+
"创业者",
|
|
91
92
|
"--format",
|
|
92
93
|
"agent-json"
|
|
93
94
|
]
|
|
@@ -100,4 +101,6 @@ yuanflow-cli knowledge rules \
|
|
|
100
101
|
- 不要使用 `/atomic/aliyun-db/query` 查询知识库内部表。
|
|
101
102
|
- 不要把知识库核心方法论静态写入回复,只按接口返回内容使用。
|
|
102
103
|
- 如果接口返回 `next_actions`,优先按它推荐的动作继续查询。
|
|
104
|
+
- v2 接口不要求 `task_intent`;旧字段只作为兼容字段,不要在新调用里默认填写。
|
|
105
|
+
- `packs`、`rules` 的 `data` 可能直接是数组,不要假设固定 `{ packs: [] }` 或 `{ rules: [] }` 结构。
|
|
103
106
|
- 如果用户只是在问“有什么知识库方向”,先用 `knowledge docs`。
|
package/src/agent-protocol.js
CHANGED
|
@@ -29,12 +29,27 @@ const ERROR_MAP = [
|
|
|
29
29
|
retryable: false,
|
|
30
30
|
test: (message) => message.includes('HTTP 401') || message.includes('HTTP 403'),
|
|
31
31
|
},
|
|
32
|
+
{
|
|
33
|
+
code: 'UPSTREAM_CONFIG_ERROR',
|
|
34
|
+
exitCode: 4,
|
|
35
|
+
retryable: false,
|
|
36
|
+
test: (message) => message.includes('原子能力主站令牌未配置'),
|
|
37
|
+
},
|
|
32
38
|
{
|
|
33
39
|
code: 'UPSTREAM_ERROR',
|
|
34
40
|
exitCode: 4,
|
|
35
41
|
retryable: true,
|
|
36
42
|
test: (message) => /HTTP 5\d\d/.test(message),
|
|
37
43
|
},
|
|
44
|
+
{
|
|
45
|
+
code: 'UPSTREAM_ROUTE_MISSING',
|
|
46
|
+
exitCode: 4,
|
|
47
|
+
retryable: false,
|
|
48
|
+
test: (message) =>
|
|
49
|
+
message.includes('Invalid URL') ||
|
|
50
|
+
message.includes('接口返回了前端 HTML 页面') ||
|
|
51
|
+
message.includes('接口返回了非 JSON 内容'),
|
|
52
|
+
},
|
|
38
53
|
{
|
|
39
54
|
code: 'NETWORK_ERROR',
|
|
40
55
|
exitCode: 5,
|
package/src/atomic-request.js
CHANGED
|
@@ -45,11 +45,22 @@ export async function callAtomic(path, options = {}) {
|
|
|
45
45
|
});
|
|
46
46
|
|
|
47
47
|
const text = await response.text();
|
|
48
|
+
const contentType = response.headers.get('content-type') || '';
|
|
48
49
|
const payload = parseMaybeJson(text);
|
|
49
50
|
if (!response.ok) {
|
|
50
51
|
const message = typeof payload === 'object' ? JSON.stringify(payload) : text;
|
|
51
52
|
throw new Error(`请求失败:HTTP ${response.status} ${message}`);
|
|
52
53
|
}
|
|
54
|
+
if (options.expectJson !== false) {
|
|
55
|
+
assertJsonResponse({
|
|
56
|
+
contentType,
|
|
57
|
+
method,
|
|
58
|
+
path: normalizedPath,
|
|
59
|
+
status: response.status,
|
|
60
|
+
payload,
|
|
61
|
+
text,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
53
64
|
return payload;
|
|
54
65
|
}
|
|
55
66
|
|
|
@@ -95,6 +106,34 @@ function parseMaybeJson(text) {
|
|
|
95
106
|
}
|
|
96
107
|
}
|
|
97
108
|
|
|
109
|
+
function assertJsonResponse({ contentType, method, path, status, payload, text }) {
|
|
110
|
+
if (payload !== null && typeof payload === 'object') {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const preview = compactPreview(text);
|
|
114
|
+
const isHtml = looksLikeHtml(text) || contentType.toLowerCase().includes('text/html');
|
|
115
|
+
if (isHtml) {
|
|
116
|
+
throw new Error(
|
|
117
|
+
`接口返回了前端 HTML 页面,不是结构化 JSON。请检查云端接口是否已部署或路径是否正确:HTTP ${status} ${method} ${path}。返回预览:${preview}`,
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
throw new Error(
|
|
121
|
+
`接口返回了非 JSON 内容。请检查云端接口是否已部署或路径是否正确:HTTP ${status} ${method} ${path}。返回预览:${preview}`,
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function looksLikeHtml(text) {
|
|
126
|
+
const normalized = String(text || '').trim().toLowerCase();
|
|
127
|
+
return normalized.startsWith('<!doctype') || normalized.startsWith('<html') || normalized.includes('<html');
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function compactPreview(text) {
|
|
131
|
+
return String(text || '')
|
|
132
|
+
.replace(/\s+/g, ' ')
|
|
133
|
+
.trim()
|
|
134
|
+
.slice(0, 160);
|
|
135
|
+
}
|
|
136
|
+
|
|
98
137
|
function maskToken(token) {
|
|
99
138
|
if (!token) {
|
|
100
139
|
return '';
|
package/src/cli.js
CHANGED
|
@@ -539,7 +539,7 @@ function printHelp() {
|
|
|
539
539
|
yuanflow-cli search content --platform xiaohongshu --keyword "美妆" --dry-run
|
|
540
540
|
yuanflow-cli search users --platform instagram --keyword "nasa" --dry-run
|
|
541
541
|
yuanflow-cli knowledge docs --dry-run
|
|
542
|
-
yuanflow-cli knowledge entry --
|
|
542
|
+
yuanflow-cli knowledge entry --output-format short_video_script --domain 自媒体运营 --content-goal "写一个创业者短视频选题" --target-audience 创业者 --format agent-json
|
|
543
543
|
yuanflow-cli oss signed-url --key path/to/file.png --ttl-seconds 1800 --format agent-json
|
|
544
544
|
yuanflow-cli list douyin
|
|
545
545
|
|
package/src/knowledge-tools.js
CHANGED
|
@@ -92,10 +92,11 @@ function knowledgeCommand(action, description, extraOptions = []) {
|
|
|
92
92
|
|
|
93
93
|
function taskFrameOptions() {
|
|
94
94
|
return [
|
|
95
|
-
{ flag: '--task-intent', name: 'taskIntent', required: false, label: '
|
|
95
|
+
{ flag: '--task-intent', name: 'taskIntent', required: false, label: '兼容旧字段;v2 接口不要求填写。' },
|
|
96
96
|
{ flag: '--output-format', name: 'outputFormat', required: false, label: '输出格式,例如 short_video_script、social_post、any。' },
|
|
97
97
|
{ flag: '--domain', name: 'domain', required: false, label: '内容领域。' },
|
|
98
98
|
{ flag: '--content-goal', name: 'contentGoal', required: false, label: '具体创作或评估目标。' },
|
|
99
|
+
{ flag: '--target-audience', name: 'targetAudience', required: false, label: '目标受众,例如 创业者、宝妈、普通用户。' },
|
|
99
100
|
{ flag: '--tone', name: 'tone', required: false, label: '语气风格。' },
|
|
100
101
|
{ flag: '--communication-mode', name: 'communicationMode', required: false, label: '表达方式,例如 口播、图文、文章。' },
|
|
101
102
|
{ flag: '--task-frame-file', name: 'taskFrameFile', required: false, label: '读取 task_frame JSON 文件。' },
|
|
@@ -116,10 +117,11 @@ async function buildTaskFrame(options) {
|
|
|
116
117
|
: {};
|
|
117
118
|
return removeUndefined({
|
|
118
119
|
...fromFile,
|
|
119
|
-
task_intent: pick(options, 'task-intent', fromFile.task_intent
|
|
120
|
+
task_intent: pick(options, 'task-intent', fromFile.task_intent),
|
|
120
121
|
output_format: pick(options, 'output-format', fromFile.output_format || 'any'),
|
|
121
122
|
domain: pick(options, 'domain', fromFile.domain || '自媒体运营'),
|
|
122
123
|
content_goal: pick(options, 'content-goal', fromFile.content_goal || ''),
|
|
124
|
+
target_audience: pick(options, 'target-audience', fromFile.target_audience || ''),
|
|
123
125
|
tone: pick(options, 'tone', fromFile.tone || ''),
|
|
124
126
|
communication_mode: pick(options, 'communication-mode', fromFile.communication_mode || ''),
|
|
125
127
|
});
|