e10-data 0.1.34 → 0.1.35
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/CHANGELOG.md +51 -0
- package/README.md +14 -0
- package/bin/e10-data.mjs +108 -36
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,56 @@
|
|
|
1
1
|
# 变更记录
|
|
2
2
|
|
|
3
|
+
## 0.1.35(2026-11-02)—— `scene search` 改为「后端 keyword 过滤优先」(召回修复)
|
|
4
|
+
|
|
5
|
+
### 1. 背景
|
|
6
|
+
|
|
7
|
+
`scene search` 自 0.1.33 引入起一直是「本地字面打分」补丁,代码注释与 0.1.33 变更记录
|
|
8
|
+
均写「后端无对应接口」。**该说法有误**:`GET /api/dw/newetl/chatBi/getSceneGroups`
|
|
9
|
+
支持 `keyword`(**单数**)query 参数,且返回体里直接带回已过滤的 `datasets`。
|
|
10
|
+
|
|
11
|
+
因为关键词从未发给后端,本地打分只能看 `groupName` / `groupDesc`,
|
|
12
|
+
**完全丢掉了「关键词只落在条目名/条目描述里」的场景**,典型症状:
|
|
13
|
+
`--keywords 未结案`、`--keywords 请假` 直接 0 候选;问「excel 表」时凭「表」字硬凑无关分组。
|
|
14
|
+
|
|
15
|
+
### 2. 后端 `keyword` 的命中规则(实测)
|
|
16
|
+
|
|
17
|
+
| 情形 | 判据 | 返回 |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| ① 分组级命中 | 关键词在 `groupName` 或 `groupDesc` | 该分组 **+ 全部条目** |
|
|
20
|
+
| ② 仅条目级命中 | 分组名/描述都不含,关键词在 `datasetName` 或 `datasetDesc` | **只返命中条目 + 父分组** |
|
|
21
|
+
| ③ 全不命中 | — | **空数组**(不回落全量骨架) |
|
|
22
|
+
|
|
23
|
+
多个关键词逗号分隔,后端按 **OR** 取并集;整句不切词(`keyword=整句话` → 0 组)。
|
|
24
|
+
|
|
25
|
+
### 3. 改动
|
|
26
|
+
|
|
27
|
+
- `cmdSceneSearch` 重写:
|
|
28
|
+
- 默认先发 **1 次** `getSceneGroups?datasetClient=…&keyword=词1,词2`,命中则直接使用响应
|
|
29
|
+
里的 `datasets`,**不再逐组拉 items**(请求数从 `1+maxGroups` 降到 `1`);
|
|
30
|
+
- 未命中 / 请求失败且 `--server-filter=auto` 时回退原本地打分逻辑(老服务端可用);
|
|
31
|
+
- 条目层:后端已经给过的条目**只排序、不再按 `score>0` 过滤**(分组级命中时组内条目
|
|
32
|
+
未必含关键词字面,过滤会丢量:`业绩` 实测 57 条只剩 20 条);后端未做条目级过滤
|
|
33
|
+
(`datasets` 条数 = `itemCount`)时按 `--max-items` 截断,避免整组几十条 `datasetDesc` 撑爆上下文;
|
|
34
|
+
- stderr 增印「请求 N 次 | 过滤方式 后端 keyword / 本地打分」,便于排查召回来源。
|
|
35
|
+
- 新增 `--server-filter auto|on|off`(默认 `auto`):`on` = 只认后端、不回退;`off` = 只走旧本地打分。
|
|
36
|
+
- 更正文件头注释、`cmdSceneSearch` 文档注释、`usage()` 中「后端无此接口/本地补丁」的过时说法。
|
|
37
|
+
|
|
38
|
+
### 4. 效果(同一账号、同一环境实测)
|
|
39
|
+
|
|
40
|
+
| 命令 | 0.1.34 | 本改动 |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| `--keywords 未结案` | 0 候选 | 项目收支 **18 条**(PMO 项目情况系列),1 次请求 |
|
|
43
|
+
| `--keywords 请假` | 0 候选 | 2 组 2 条(人事绩效 + 人事考勤),1 次请求 |
|
|
44
|
+
| `--keywords 业绩` | 12 条(本地打分+截断) | **57 条全量**(`--max-items 999`),1 次请求 |
|
|
45
|
+
| `--keywords excel,表,字段` | 3 个无关组 ×12 条 | 3 组 25 条(后端命中条目),1 次请求 |
|
|
46
|
+
|
|
47
|
+
### 5. 兼容
|
|
48
|
+
|
|
49
|
+
- 默认 `auto`:后端不可用/未命中时行为与 0.1.34 一致;`--server-filter off` 完全等价旧版。
|
|
50
|
+
- `--max-groups` / `--max-items` / `--scope-group-id` 语义不变。
|
|
51
|
+
- 后端场景目录会变(同一天 `keyword=excel` 命中的分组从「全部」→「专项经营」→ 整条消失),
|
|
52
|
+
故代码与文档**不得写死 groupId**,一律按 keyword 召回复核。
|
|
53
|
+
|
|
3
54
|
## 0.1.34(2026-10-29)—— `ds fields` / `ds describe` 改走 `getFields`(扁平返回)
|
|
4
55
|
|
|
5
56
|
### 1. 背景
|
package/README.md
CHANGED
|
@@ -460,6 +460,20 @@ e10-data scene groups [--client agent|all|connector] [--json]
|
|
|
460
460
|
] }]
|
|
461
461
|
```
|
|
462
462
|
|
|
463
|
+
**关键词召回(`scene search`,未发布改动起改为后端过滤)**:
|
|
464
|
+
|
|
465
|
+
```bash
|
|
466
|
+
e10-data scene search --keywords "未结案" [--client agent] [--json]
|
|
467
|
+
[--max-groups 3] [--max-items 12] [--scope-group-id <gid>]
|
|
468
|
+
[--server-filter auto|on|off]
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
后端 `getSceneGroups` **支持 `keyword`(单数)**,命中规则:分组名/描述命中 ⇒ **整组全返**;
|
|
472
|
+
仅条目名/描述命中 ⇒ **只返命中条目 + 父分组**;都不命中 ⇒ **空数组**;多词逗号分隔按 OR。
|
|
473
|
+
因此本命令默认把关键词直接交给后端,**命中时全程只发 1 次请求**并直接使用返回的 `datasets`;
|
|
474
|
+
未命中才回退本地字面打分(`--server-filter auto` 默认 / `on` 只走后端 / `off` 只走本地)。
|
|
475
|
+
stderr 会打印「请求 N 次 | 过滤方式 后端 keyword / 本地打分」,可用于判断召回是否走了后端。
|
|
476
|
+
|
|
463
477
|
**分流(拿到条目后)**:
|
|
464
478
|
|
|
465
479
|
- `datasetType=interface` → `e10-data module call --conf-key <sourceId> --group <moduleName>`(`moduleName` 随条目下发,勿用 confKey 拆段猜);
|
package/bin/e10-data.mjs
CHANGED
|
@@ -3056,7 +3056,7 @@ async function cmdRefusalRules(args, json) {
|
|
|
3056
3056
|
// 端点:/api/dw/newetl/chatBi/getSceneGroups(别名 /getAgentSceneGroups,等价)
|
|
3057
3057
|
// ① scene groups → 分组骨架(不传 groupId;每个分组带 groupDesc 三段式)
|
|
3058
3058
|
// ② scene items --group <groupId> → 该分组的条目(传 groupId;datasetType = interface / datasource)
|
|
3059
|
-
// ③ scene search --keywords <词> →
|
|
3059
|
+
// ③ scene search --keywords <词> → 关键词候选召回(把 keyword 交给后端过滤;未命中回退本地打分)
|
|
3060
3060
|
// 来源:由技能 `references/scene-locate/scripts/locate.mjs` **整体迁入**(scene-locate.md §6 原计划的 CLI 替换),
|
|
3061
3061
|
// 迁入后技能侧不再直连接口。参数与输出口径与脚本保持一致(`--client` 默认 agent、精简字段集、计数走 stderr)。
|
|
3062
3062
|
// 形状口径(2026-10-14 修订):**默认输出顶层一律为数组** —— ① groups = 分组数组;② items = 分组数组
|
|
@@ -3164,15 +3164,23 @@ async function cmdSceneItems(args, json) {
|
|
|
3164
3164
|
console.log(JSON.stringify(out, null, 1));
|
|
3165
3165
|
}
|
|
3166
3166
|
|
|
3167
|
-
/** ③ 关键词候选召回(2026-10-
|
|
3168
|
-
* 数据源 = getSceneGroups
|
|
3169
|
-
* ①
|
|
3170
|
-
* ②
|
|
3171
|
-
* ③
|
|
3172
|
-
*
|
|
3167
|
+
/** ③ 关键词候选召回(2026-10-29 改为「后端 keyword 过滤优先,本地打分兜底」)
|
|
3168
|
+
* 数据源 = getSceneGroups 元数据。后端**支持** `keyword`(单数)query 参数,命中规则:
|
|
3169
|
+
* ① 分组级命中(关键词落在 groupName / groupDesc)→ 返回该分组**及其全部条目**;
|
|
3170
|
+
* ② 仅条目级命中(分组名/描述都不含,关键词落在 datasetName / datasetDesc)→ 只返回命中条目 + 父分组;
|
|
3171
|
+
* ③ 全不命中 → 空数组(不返回全量骨架);多个关键词逗号分隔,后端按 OR 取并集。
|
|
3172
|
+
* 因此本命令的正确姿势是**把关键词交给后端**,只有后端未命中/老服务端不支持时才回退本地打分:
|
|
3173
|
+
* ① server-filter≠off 时先发 1 次 `getSceneGroups?datasetClient=…&keyword=词1,词2`,
|
|
3174
|
+
* 命中则直接采用响应里的 datasets(不再逐组拉 items)→ 全程 1 次请求;
|
|
3175
|
+
* ② 未命中或请求失败且 --server-filter=auto → 回退旧逻辑:拉骨架 + 入选组各拉一次 items,
|
|
3176
|
+
* 按 groupName×3 + groupDesc×1 选组(前 --max-groups),条目按 datasetName×3 + datasetDesc×1 排序,
|
|
3177
|
+
* 组命中但条目全 0 分时回退「条目原序前 --max-items 条」;
|
|
3178
|
+
* ③ 条目裁剪:后端已做条目级过滤(组内 datasets 条数 < itemCount)时全保留;
|
|
3179
|
+
* 分组级命中(后端回了全量)才按 --max-items 截断,避免整组几十条 datasetDesc 撑爆上下文。
|
|
3173
3180
|
* 形状:顶层数组,与 `scene items` 同构(分组 + datasets);`--json` 输出同一结构
|
|
3174
3181
|
* (本命令无「原样透传对象」可言,--json 与默认输出一致)。
|
|
3175
|
-
*
|
|
3182
|
+
* 注意:后端与本地判据都是**字面包含**(不做语义裁决);仍建议调用方对候选做一次语义判断。
|
|
3183
|
+
* stderr 会打印一行「请求 N 次 | 过滤方式 后端 keyword / 本地打分」,便于排查召回来源。
|
|
3176
3184
|
*/
|
|
3177
3185
|
function sceneKeywords(raw) {
|
|
3178
3186
|
return String(raw ?? "")
|
|
@@ -3215,40 +3223,98 @@ async function cmdSceneSearch(args, json) {
|
|
|
3215
3223
|
const maxGroups = Math.max(1, Number(args["max-groups"] ?? 3) || 3);
|
|
3216
3224
|
const maxItems = Math.max(1, Number(args["max-items"] ?? 12) || 12);
|
|
3217
3225
|
const scope = args["scope-group-id"] == null ? "" : String(args["scope-group-id"]).trim();
|
|
3226
|
+
const serverFilter = String(args["server-filter"] ?? "auto").trim().toLowerCase();
|
|
3227
|
+
if (!["auto", "on", "off"].includes(serverFilter)) {
|
|
3228
|
+
throw new Error("--server-filter 值必须为 auto|on|off(当前: " + args["server-filter"] + ")");
|
|
3229
|
+
}
|
|
3230
|
+
|
|
3231
|
+
const inScope = (g) => !scope || String(g.groupId) === scope;
|
|
3232
|
+
const kw = keywords.join(",");
|
|
3218
3233
|
|
|
3219
|
-
|
|
3220
|
-
let requests =
|
|
3221
|
-
|
|
3222
|
-
const pool = all.filter((g) => g && g.groupId !== undefined);
|
|
3234
|
+
let pool = [];
|
|
3235
|
+
let requests = 0;
|
|
3236
|
+
let usedServer = false;
|
|
3223
3237
|
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3238
|
+
// ① 优先把关键词交给后端过滤:GET getSceneGroups?datasetClient=…&keyword=词1,词2
|
|
3239
|
+
if (serverFilter !== "off") {
|
|
3240
|
+
try {
|
|
3241
|
+
const raw = await sceneRequest({ datasetClient: client, keyword: kw });
|
|
3242
|
+
requests += 1;
|
|
3243
|
+
const arr = Array.isArray(raw) ? raw : (raw == null ? [] : [raw]);
|
|
3244
|
+
const hit = arr.filter((g) => g && g.groupId !== undefined && inScope(g));
|
|
3245
|
+
if (hit.length) {
|
|
3246
|
+
pool = hit;
|
|
3247
|
+
usedServer = true;
|
|
3248
|
+
} else if (serverFilter === "auto") {
|
|
3249
|
+
process.stderr.write("# 后端 keyword 未命中,回退本地打分(keyword=" + kw + ")\n");
|
|
3250
|
+
}
|
|
3251
|
+
} catch (e) {
|
|
3252
|
+
if (serverFilter === "on") throw e;
|
|
3253
|
+
process.stderr.write("# [warn] 带 keyword 的召回失败,回退本地打分:" + ((e && e.message) || e) + "\n");
|
|
3254
|
+
}
|
|
3255
|
+
}
|
|
3256
|
+
|
|
3257
|
+
// ② 决定候选分组:后端命中 → 直接用(只排序不筛);否则回退旧的本地打分
|
|
3258
|
+
let scored;
|
|
3259
|
+
if (usedServer) {
|
|
3260
|
+
scored = pool
|
|
3261
|
+
.map((g) => ({
|
|
3262
|
+
g,
|
|
3263
|
+
score: sceneHitScore(g.groupName, keywords) * 3 + sceneHitScore(g.groupDesc, keywords),
|
|
3264
|
+
items: Array.isArray(g.datasets) ? g.datasets : null,
|
|
3265
|
+
}))
|
|
3266
|
+
.sort((a, b) => (b.score - a.score) || ((b.items || []).length - (a.items || []).length))
|
|
3267
|
+
.slice(0, maxGroups);
|
|
3268
|
+
} else if (serverFilter === "on") {
|
|
3269
|
+
scored = [];
|
|
3270
|
+
} else {
|
|
3271
|
+
// 回退本地打分:必须拿到完整分组骨架(后端未命中时 pool 为空,不能复用)
|
|
3272
|
+
if (!pool.length) {
|
|
3273
|
+
const raw = await sceneRequest({ datasetClient: client });
|
|
3274
|
+
requests += 1;
|
|
3275
|
+
const arr = Array.isArray(raw) ? raw : (raw == null ? [] : [raw]);
|
|
3276
|
+
pool = arr.filter((g) => g && g.groupId !== undefined && inScope(g));
|
|
3277
|
+
}
|
|
3278
|
+
scored = pool
|
|
3279
|
+
.map((g) => ({
|
|
3280
|
+
g,
|
|
3281
|
+
score: sceneHitScore(g.groupName, keywords) * 3 + sceneHitScore(g.groupDesc, keywords),
|
|
3282
|
+
items: null,
|
|
3283
|
+
}))
|
|
3227
3284
|
.filter((x) => x.score > 0)
|
|
3228
3285
|
.sort((a, b) => b.score - a.score)
|
|
3229
3286
|
.slice(0, maxGroups);
|
|
3287
|
+
}
|
|
3230
3288
|
|
|
3231
3289
|
const out = [];
|
|
3232
|
-
for (const
|
|
3233
|
-
|
|
3290
|
+
for (const cand of scored) {
|
|
3291
|
+
const g = cand.g;
|
|
3292
|
+
let items = cand.items;
|
|
3234
3293
|
if (!items) {
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3294
|
+
const one = await sceneRequest({ datasetClient: client, groupId: String(g.groupId) });
|
|
3295
|
+
requests += 1;
|
|
3296
|
+
const arr = Array.isArray(one) ? one : (one == null ? [] : [one]);
|
|
3297
|
+
const hit = arr.find((x) => x && String(x.groupId) === String(g.groupId)) || arr[0] || {};
|
|
3298
|
+
items = Array.isArray(hit.datasets) ? hit.datasets : [];
|
|
3240
3299
|
}
|
|
3241
3300
|
const ranked = items
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3301
|
+
.map((d) => ({ d, score: sceneHitScore(d.datasetName, keywords) * 3 + sceneHitScore(d.datasetDesc, keywords) }))
|
|
3302
|
+
.sort((a, b) => b.score - a.score);
|
|
3303
|
+
// 后端过滤过 ⇒ 条目是「后端给的」,本地只排序不筛:
|
|
3304
|
+
// ① 仅条目级命中(serverPartial)时后端已筛好,全部保留;
|
|
3305
|
+
// ② 分组级命中时后端返回整组,其中未命中关键词的条目**同样可能相关**(关键词只是落在组描述里),
|
|
3306
|
+
// 不能再按 datasetName/datasetDesc 字面分把它们剔掉,否则会出现「57 条只剩 20 条」的丢量。
|
|
3307
|
+
// 只有「回退本地打分」这条路径才需要 score>0 过滤。
|
|
3308
|
+
const ordered = usedServer ? ranked
|
|
3309
|
+
: (() => { const m = ranked.filter((x) => x.score > 0); return m.length ? m : ranked; })();
|
|
3310
|
+
const serverPartial = usedServer && Number(g.itemCount ?? items.length) > items.length;
|
|
3311
|
+
const keep = usedServer && serverPartial ? ordered : ordered.slice(0, maxItems);
|
|
3246
3312
|
const group = {
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3313
|
+
groupId: String(g.groupId),
|
|
3314
|
+
groupName: g.groupName ?? "",
|
|
3315
|
+
groupDesc: g.groupDesc ?? "",
|
|
3316
|
+
itemCount: Number(g.itemCount ?? items.length),
|
|
3317
|
+
datasets: keep.map((x) => sceneSlimItem(x.d)),
|
|
3252
3318
|
};
|
|
3253
3319
|
// 前向兼容:后端下发 groupLogic 时自动带出
|
|
3254
3320
|
if (g.groupLogic !== undefined) group.groupLogic = g.groupLogic;
|
|
@@ -3256,11 +3322,14 @@ async function cmdSceneSearch(args, json) {
|
|
|
3256
3322
|
}
|
|
3257
3323
|
|
|
3258
3324
|
const itemTotal = out.reduce((n, g) => n + g.datasets.length, 0);
|
|
3325
|
+
const filterMode = usedServer ? "后端 keyword" : (serverFilter === "on" ? "后端 keyword(无命中)" : "本地打分");
|
|
3259
3326
|
if (!out.length) {
|
|
3260
|
-
process.stderr.write("# 未命中任何分组(关键词:" + keywords.join(",") + "
|
|
3327
|
+
process.stderr.write("# 未命中任何分组(关键词:" + keywords.join(",") + ";"
|
|
3328
|
+
+ (serverFilter === "on" ? "后端 keyword 无命中,已按 --server-filter on 不回退" : "候选池 " + pool.length + " 组") + ")\n");
|
|
3261
3329
|
}
|
|
3262
3330
|
process.stderr.write("# 关键词 " + keywords.join(",")
|
|
3263
|
-
+ " | 候选分组 " + out.length + " 个 | 条目 " + itemTotal + " 条 | 请求 " + requests + "
|
|
3331
|
+
+ " | 候选分组 " + out.length + " 个 | 条目 " + itemTotal + " 条 | 请求 " + requests + " 次"
|
|
3332
|
+
+ " | 过滤方式 " + filterMode + "\n");
|
|
3264
3333
|
return out;
|
|
3265
3334
|
}
|
|
3266
3335
|
|
|
@@ -3396,9 +3465,12 @@ refusal 拒答话术(chatBi,2026-10-13 新增)
|
|
|
3396
3465
|
scene 场景定位元数据(chatBi getSceneGroups,2026-10-14 新增;**不取业务数据**,只做「分组 → 条目」定位)
|
|
3397
3466
|
scene groups [--client agent|all|connector] # ① 分组骨架(groupDesc =【场景】【触发词】【取数顺序】)
|
|
3398
3467
|
scene items --group <groupId> [--client …] # ② 组内条目(每组带 datasetDesc;datasetType 决定分流)
|
|
3399
|
-
scene search --keywords <词1,词2> [--client …] # ③
|
|
3400
|
-
[--max-groups 3] [--max-items 12] [--scope-group-id <gid>]
|
|
3401
|
-
#
|
|
3468
|
+
scene search --keywords <词1,词2> [--client …] # ③ 关键词候选召回(后端 keyword 过滤优先,miss 回退本地打分)
|
|
3469
|
+
[--max-groups 3] [--max-items 12] [--scope-group-id <gid>] [--server-filter auto|on|off]
|
|
3470
|
+
# 后端支持 keyword(单数,逗号分隔多词按 OR):分组级命中→整组全返;
|
|
3471
|
+
# 仅条目级命中→只返命中条目 + 父分组;全不命中→空数组
|
|
3472
|
+
# auto(默认)= 先发 keyword,未命中再回退本地打分;on = 只走后端;off = 只走本地
|
|
3473
|
+
# 命中后端时全程 1 次请求(不再逐组拉 items);stderr 会注明「过滤方式」
|
|
3402
3474
|
# 输出与 ② items 同构(分组 + datasets);--json 同结构(非原样透传)
|
|
3403
3475
|
# 端点 /api/dw/newetl/chatBi/getSceneGroups(别名 getAgentSceneGroups,等价)
|
|
3404
3476
|
# 默认输出**精简 JSON**(groups: groupId/groupName/itemCount/groupDesc;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "e10-data",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.35",
|
|
4
4
|
"description": "泛微 E10 数据接口统一 CLI(data-assistant 专家配套):DSL 查询/数据源/文档/词库/关联字段翻译/环境参数配置中心(conf,支持 confGroup 分组)/专家包版本管理;ds 取数(list/chart/stat/count)的 appId 由调用方显式传入 --app-id(v0.1.14 起 CLI 不再自动反查;EB 建模表单 weaver-ebuilder-form-service 必须带,appId 取自 ebdf_obj.app_id;2026-10-09 起不再做 EB 权限前置校验);认证凭据**唯一来源 = weaver-work-cli**(通过 `auth export-weaver-env` 命令出口取明文凭据,**不设 e10-login 回退**;加解密由该 CLI 自行负责,本 CLI 不实现任何加解密;登录命令不在本 CLI 内,一律用 weaver-work-cli auth login)。v0.1.17 性能改造:免凭据命令(--version/--help/未知命令)提前返回、直连 e10-login JS 入口(去掉 shell:true 的 cmd.exe 开销)、新增凭据进程间 TTL 缓存(不落明文);v0.1.19(2026-09-24)新增 ds 发现层聚合 groups/find/describe(进程内并发,全 58 分组扫表实测 ~5.5s),并修复 ds tables --name 因 listByPage 端点切换导致的关键词过滤静默失效;v0.1.18(2026-09-24)新增 ds fields-dsl(接口 /api/dw/newetl/chatBi/ds/fieldsForDSL),并移除凭据明文镜像同步(不再写 ~/.workbuddy/e10-login-cache.md);v0.1.20(2026-09-24)凭据来源切换为 weaver-work-cli 唯一来源、移除 e10-login 回退,并补齐 userId/tenantKey 传递(修复 attend statis 等命令报「缺少查询人员」的问题)。v0.1.21(2026-09-28)新增 module call —— 模块配置接口调用(配置中心驱动):已确定「哪个模块的哪条具体接口」之后的一条命令取数入口(精取该条 confAttrs → 按 http_method/input_params 组参 → 发请求(自动禁代理 + Cookie/eteamsid/UA 三件套)→ 提取精简结果),与技能自带 script/call_module.py 等价(参数名/退出码/提取口径全对齐),复用本 CLI 凭据缓存与 conf 通道、零临时文件;同时 auth 归一化与凭据缓存补齐 userAgent(供 AgentType UA 使用,缺失时从 cookie 的 agentType= 推导)。v0.1.22(2026-10-10):移除 `eb perm-page` 命令(EB 建模表单取数不再做权限前置校验,appId 直接取 ebdf_obj.app_id);`--fields`/`--group-by`/`--order` 等逗号列表支持 `@文件`(逗号字符串或 JSON 数组,与 --where/--stat/--dsl 一致,规避 shell 拆分导致的静默丢列/0 行)。v0.1.23(2026-10-13)新增 `refusal get` —— 拒答话术 getRefusalSpeechTechnique(入参仅 type,返回对象的 data = 话术字符串;默认 auto 通道 = POST multipart 表单优先、返回不含 data 时自动回退 GET ?type=,可用 --http post|get 锁定单通道)。v0.1.25(2026-10-14)新增 `scene groups|items` —— 场景定位元数据 getSceneGroups(① groups 分组骨架 / ② items --group <groupId> 组内条目),由技能 references/scene-locate/scripts/locate.mjs 整体迁入(属元数据定位接口、不取业务数据):默认输出精简 JSON(groups: groupId/groupName/itemCount/groupDesc;items: id/datasetName/datasetType/sourceId[/moduleName/sourceType/sourceGroupId/appId]/datasetDesc),--json 原样输出接口返回,计数走 stderr;--client agent|all|connector 默认 agent。v0.1.26(2026-10-15)新增 `refusal rules` —— 拒答话术规则 getRefusalSpeechRules(**无入参**,返回对象的 data = 对象数组;调用方式与 refusal get 同口径:默认 auto 通道 = POST 空 multipart 表单优先、返回不含 data 时回退 GET,可用 --http post|get 锁定单通道;人读直接打印 data 数组,--json 原样输出整个响应对象)。v0.1.27(2026-10-15)新增 `noun scope --ids <id1,id2|@ids.json>` —— 词库**按生效范围批量检索**(端点 /api/dw/newetl/chatBi/doc/getChatBiDocByScopeId,POST body = 数据集 id 的 JSON 数组;入参 = 数据集 id 列表 = `scene items --group <分组id>` 里每个条目的 `id`;命中 = allScope=1 全局词库 ∪ scopeEffectId 含任一传入 id;id 按字符串下发,避免 19 位雪花号超 2^53 丢精度)。属**新增通道**,原 `noun list --skill <skillKey>`(getChatDocsBySkillKey)行为**完全不变**。 v0.1.28(2026-10-17):`module call` 支持 `--type <confType>`(自定义 confType / 域级配置分组,默认 `api`,不传时行为与旧版一致)与 `--show-params` 精简模式(默认省略 `request_example`,`--full` / `--with-example` 回显,`--no-example` 显式精简),`--show-params` 输出新增 `conf_type` 字段。v0.1.29(2026-10-19)本地增强:`module call` 新增 `--conf-file <文件|@文件>`——直接读本地 confAttrs 跳过 `conf get`(同一 confKey 一次问数只取一次配置),兼容模板缓存与 `conf get --json` 原样输出,带该参数时 `--group`/`--conf-key` 可从文件回填,stderr 提示「未请求配置中心」;缓存缺失/过期时去掉该参数即回退原路径。 v0.1.30(2026-10-19):query 透传后端 executeQueryDsl 新增的 4 个 @RequestParam(dimension=后端 confKey / confGroup / username / startDate,恒定发送、值允许为空,缺键即失败),并显式声明 Content-Type=application/json;charset=utf-8。v0.1.31(2026-10-21)凭据直读快路径(providerAuthFileDirect 直读 weaver-work-cli auth 文件解密,省 2 个子进程约 5.6s→~0.1s)+ cred-helper stale socket 自愈。v0.1.32(2026-10-22)新增 `field options` —— Select/下拉框字段的选项值清单 {id,name,archive}(GET /api/ebuilder/common/ds/options?fieldName=&objId=&sourceType=&groupId=,通用下拉框选项方法,不限 DSL/宽表:EB 表单与 ETEAMS 宽表均适用;--field-name 用 ds fields 的 name,--source-type 需显式传参 LOGIC|ETEAMS、代码缺省 LOGIC 兜底;Select 列存 value_key 时用它做显示映射,替代已停用的 id2name/字典表直查)。v0.1.33(2026-10-23):**移除 `login xiaoe-env`**(含别名 `xiaoe-env`)——登录链路统一交 weaver-work-cli(`auth login/status/export-weaver-env`),本 CLI 不再提供任何登录命令,未登录时提示执行 `weaver-work-cli auth login --base-url <域名>`;同版本新增 `scene search --keywords <词1,词2>` —— 场景关键词候选召回(本地打分:拉一次 groups + 每个入选分组各拉一次 items,按 groupName/datasetName 命中×3 + 描述命中×1 排序,输出与 `scene items` 同构,支持 `--max-groups 3` / `--max-items 12` / `--scope-group-id`)。",
|
|
5
5
|
"author": "e10-dw",
|
|
6
6
|
"license": "MIT",
|