refactor(cli): 替换所有 kscli 命令为 bl CLI 命令

- README 文档中将管理面 CLI 名称由 kscli 改为 bl CLI
- 包描述与说明中更新 CLI 名称与对应命令用法
- 技能文档及其命令参考全面替换 kscli 为 bl
- 所有子命令示例和用法文档同步改为 bl 及对应子命令路径
- 更新服务发现命令由 kscli 改为 bl knowledge service list
- 更新鉴权说明改为 bl auth login 及相关配置命令
- 维护命令结构一致性,保证用户可无缝使用 bl 替代原 kscli
This commit is contained in:
zeyu.fz
2026-08-21 00:19:29 +08:00
parent 0d8d354ddc
commit e1793e1f3a
24 changed files with 638 additions and 253 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
# bailian-kb-dsh
阿里云百炼知识库能力的 [DeepSeek Harness (dsh)](https://github.com/deepseek-ai/deepseek-harness) 插件 bundle:三个 API 直连模型工具(`kb_service_list` / `kb_search` / `kb_chat`)+ kscli 管理面 skill。
阿里云百炼知识库能力的 [DeepSeek Harness (dsh)](https://github.com/deepseek-ai/deepseek-harness) 插件 bundle:三个 API 直连模型工具(`kb_service_list` / `kb_search` / `kb_chat`)+ bl CLI 管理面 skill。
设计文档:[docs/specs/2026-08-15-bailian-kb-bundle-design.md](docs/specs/2026-08-15-bailian-kb-bundle-design.md) · 实现计划:[docs/plans/2026-08-15-bailian-kb-bundle.md](docs/plans/2026-08-15-bailian-kb-bundle.md)
+7 -4
View File
@@ -1,6 +1,6 @@
# dsh-tool-bailian-kb
百炼知识库的 dsh 插件包(同时是 dsh bundle):在 `ctx.tools` 注册两个检索模型工具(kb_search、kb_chat),并在 skills 服务可用时注册管理面 skill。服务发现通过 kscli CLI 完成。
百炼知识库的 dsh 插件包(同时是 dsh bundle):在 `ctx.tools` 注册两个检索模型工具(kb_search、kb_chat),并在 skills 服务可用时注册管理面 skill。服务发现通过 bl CLI(bailian-cli)完成。
## Bundle 声明
@@ -33,6 +33,9 @@
- **DashScope API Key** — write-only,`type=password` 遮罩输入草稿,仅显示 configured/来自环境变量 徽标;写 `~/.dsh/.credentials.yaml`
- **Bailian Workspace ID / 默认检索服务 ID / 默认对话服务 ID** — 回显:读写 `bailian-kb` settings 用户层,预填当前解析值;清空保存 = 移除用户层,回退 entry config → credential
- **自动获取(bl CLI)** — 按钮调 Host 桥接路由 `/bailian-kb/autofill`:宿主机读 `~/.bailian/config.json`(`bl auth login` 的落盘),把 `api_key` 写入凭据存储、`workspace_id` 写入 settings,明文 key 不过浏览器;文件里没有 key 时在宿主机拉起 `bl auth login --console` 浏览器登录,完成后再次点击即可回填
首次接入 seed:启动时若 API key / workspaceId 从未被设置过(settings、credential、env 均无值),自动从 `~/.bailian/config.json` 采纳一次;`seededFields` 字段(settings 文档内,面板不可编辑)记账已消费/已由用户管理的字段,用户主动清空的值永不会被重新填回。
降级:远程浏览器(非 loopback,settings RPC 不可达)或未组合 settings 服务时,ID 字段退回旧的 write-only credential 控件,页面顶部显示提示。
@@ -73,18 +76,18 @@ Config 同时注册为 `bailian-kb` settings namespace(`installSettingsSection
| `kb_search` | `query`、`agent_id`(**必填**;程序化省略时回退 defaultRetrieveAgentId)、`top_k?`(默认 5,**客户端截断**——服务端无此参数)、`images?` | chunks(text/score/来源)+ total |
| `kb_chat` | `message`、`agent_id`(**必填**;程序化省略时回退 defaultChatAgentId) | 完整答案(内部消费 SSE 流缓冲返回)+ request_id |
服务发现(`kb_service_list` 已移除):通过 `kscli service list` CLI 命令查询可用检索/对话服务及其 agent_id。
服务发现(`kb_service_list` 已移除):通过 `bl knowledge service list` CLI 命令查询可用检索/对话服务及其 agent_id。
## 错误语义
- HTTP 错误:原始错误透传,模型可通过 `kscli service list` 发现可用服务以纠正无效 `agent_id`;
- HTTP 错误:原始错误透传,模型可通过 `bl knowledge service list` 发现可用服务以纠正无效 `agent_id`;
- 凭证缺失:指向 `~/.dsh/.env` / `.credentials.yaml` 配置方式与控制台取 key 页面;
- chat 超时:说明服务端多轮检索特性,建议重试或改用 `kb_search`;
- 服务端错误体截断至 500 字符进入错误信息(优先 `code: message`)。
## 管理面 skill
`skills/bailian-kb-management/SKILL.md` 随包分发,插件通过 `ctx.inject(['skills'])` 在 skills 服务可用时以 `source: 'bundled'` 运行时注册;无 skills 服务的组合(headless 最小装配)不受影响。内容:kscli 安装/鉴权/workspace 解析、建库→上传→部署工作流、agent_id 固定最佳实践。
`skills/bailian-kb-management/SKILL.md` 随包分发,插件通过 `ctx.inject(['skills'])` 在 skills 服务可用时以 `source: 'bundled'` 运行时注册;无 skills 服务的组合(headless 最小装配)不受影响。内容:bl CLI 安装/鉴权/workspace 解析、建库→上传→部署工作流、agent_id 固定最佳实践。
## Known Limitations
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@ali/bailian-kb-dsh",
"version": "0.1.6",
"description": "Bailian knowledge-base tools for DeepSeek Harness: kb_search and kb_chat over the DashScope RAG API, plus the kscli management skill.",
"version": "0.1.7",
"description": "Bailian knowledge-base tools for DeepSeek Harness: kb_search and kb_chat over the DashScope RAG API, plus the bl CLI management skill.",
"type": "module",
"main": "lib/index.js",
"types": "lib/index.d.ts",
@@ -1,66 +1,64 @@
---
name: bailian-kb-management
description: >-
管理阿里云百炼知识库(建库、上传文档、部署检索服务、Chunk 运维、数据中心文件管理),命令行工具为 kscli。
管理阿里云百炼知识库(建库、上传文档、部署检索服务、Chunk 运维、数据中心文件管理),命令行工具为 bl(bailian-cli)。
当用户要创建/更新/删除知识库、上传或导入文档(本地/OSS)、创建/部署/调参检索或问答服务、
增删改查 Chunk、管理数据中心类目/文件/集合时使用本 skill。
检索与问答不走本 skill——用原生工具 kb_search(取证据)/ kb_chat(成品问答);
kscli search / chat 仅用于部署后的验证调试(如 --agent-version beta 调试草稿版)。
bl knowledge search / chat 仅用于部署后的验证调试(如 --agent-version beta 调试草稿版)。
普通问答、编程、写作、翻译、泛搜索不触发本 skill。
---
# 百炼知识库管理(kscli)
# 百炼知识库管理(bl)
检索面与管理面的分工:**查知识用 `kb_search`(取证据)/ `kb_chat`(成品问答)原生工具;本 skill 只覆盖管理长尾**——知识库全生命周期、文档、检索服务、Chunk、数据中心。
## 前置检查
1. 安装校验:运行 `kscli kb list --help`。若报 `Unknown command` 或 kscli 未安装,执行
`npm install -g knowledge-studio-cli@knowledge`(需 Node.js ≥ 18.17)。
**管理命令(kb/doc/service/chunk/category/file/collection)只在 `knowledge` 发行通道;
`latest` 通道只有 search/chat/config,装错通道会导致所有管理命令不可用。**
1. 安装校验:运行 `bl knowledge list --help`。若报 `Unknown command` 或 bl 未安装,执行
`npm install -g bailian-cli`(需 Node.js ≥ 18.17);已安装但命令缺失时先 `bl update` 升级。
安装失败时把错误原样报告给用户,不要静默跳过。
2. 鉴权:需要 `DASHSCOPE_API_KEY`(环境变量,或 `kscli config set --key api_key --value sk-xxx`)。
3. workspace 解析优先级:`--workspace-id` 参数 > 环境变量 `BAILIAN_WORKSPACE_ID` > `kscli config set --key workspace_id --value ws-xxx`。
2. 鉴权:需要 `DASHSCOPE_API_KEY`(环境变量,或 `bl auth login --api-key sk-xxx`,或 `bl config set --key api_key --value sk-xxx`)。
3. workspace 解析优先级:`--workspace-id` 参数 > 环境变量 `BAILIAN_WORKSPACE_ID` > `bl config set --key workspace_id --value ws-xxx`。
## 何时用哪个命令
| 用户意图 | 命令 | 备注 |
| --- | --- | --- |
| 查知识 / 问答(日常检索) | 原生工具 `kb_search` / `kb_chat` | 不走 kscli |
| 建库 / 查看 / 改名 / 删库 / 监控 | `kscli kb create/list/info/update/delete/stats` | [reference/kb.md](reference/kb.md) |
| 上传本地文档、看解析状态、删文档、打标签 | `kscli doc upload/list/status/delete/tag` | [reference/doc.md](reference/doc.md) |
| 从 OSS 批量导入 | `kscli doc import-oss` | Bucket 需预先授权服务角色 |
| 创建 / 部署 / 调参检索(问答)服务 | `kscli service create/update/deploy/…` | [reference/service.md](reference/service.md) |
| 修正错误切片、屏蔽某段内容 | `kscli chunk add/list/update/delete` | [reference/chunk.md](reference/chunk.md) |
| 数据中心类目 / 文件 / 集合管理 | `kscli category/file/collection …` | [reference/datacenter.md](reference/datacenter.md) |
| CLI 配置、升级 | `kscli config show/set`、`kscli update` | [reference/config.md](reference/config.md) |
| 部署后验证、调试草稿版服务 | `kscli search/chat --agent-version beta` | [reference/query.md](reference/query.md) |
| 查知识 / 问答(日常检索) | 原生工具 `kb_search` / `kb_chat` | 不走 bl |
| 建库 / 查看 / 改名 / 删库 / 监控 | `bl knowledge create/list/info/update/delete/stats` | [reference/kb.md](reference/kb.md) |
| 上传本地文档、看解析状态、删文档、打标签 | `bl knowledge doc upload/list/status/delete/tag` | [reference/doc.md](reference/doc.md) |
| 从 OSS 批量导入 | `bl knowledge doc import-oss` | Bucket 需预先授权服务角色 |
| 创建 / 部署 / 调参检索(问答)服务 | `bl knowledge service create/update/deploy/…` | [reference/service.md](reference/service.md) |
| 修正错误切片、屏蔽某段内容 | `bl knowledge chunk add/list/update/delete` | [reference/chunk.md](reference/chunk.md) |
| 数据中心类目 / 文件 / 集合管理 | `bl knowledge category/file/collection …` | [reference/datacenter.md](reference/datacenter.md) |
| CLI 配置、升级 | `bl config show/set`、`bl update` | [reference/config.md](reference/config.md) |
| 部署后验证、调试草稿版服务 | `bl knowledge search/chat --agent-version beta` | [reference/query.md](reference/query.md) |
## 核心工作流:建库到可检索
```bash
kscli doc upload --file ./docs/ --workspace-id ws-xxx # 1. 上传本地文件/目录 → 得 fileId
kscli kb create --name my-kb --doc-id <fileId> --wait # 2. 建库并导入 → 得 index-id (pipelineId)
kscli service create --name my-search --scene search --index-id <index-id> # 3. 建检索服务 → 得 agent-id(draft)
kscli service deploy --agent-id <agent-id> --yes # 4. 发布服务(此后可被默认版本调用)
kscli service list --scene search --status deployed # 5. 确认服务可见
bl knowledge doc upload --file ./docs/ --workspace-id ws-xxx # 1. 上传本地文件/目录 → 得 fileId
bl knowledge create --name my-kb --doc-id <fileId> --wait # 2. 建库并导入 → 得 index-id (pipelineId)
bl knowledge service create --name my-search --scene search --index-id <index-id> # 3. 建检索服务 → 得 agent-id(draft)
bl knowledge service deploy --agent-id <agent-id> --yes # 4. 发布服务(此后可被默认版本调用)
bl knowledge service list --scene search --status deployed # 5. 确认服务可见
```
部署完成后用原生工具 `kb_search` 带该 `agent_id` 验证检索;若要在部署前调试草稿配置,用 `kscli search --agent-id <id> --agent-version beta`。
部署完成后用原生工具 `kb_search` 带该 `agent_id` 验证检索;若要在部署前调试草稿配置,用 `bl knowledge search --agent-id <id> --agent-version beta`。
已有文件再入库的简写:`kscli doc upload --file ./a.md --index-id <index-id> --wait`(上传+导入一步完成)。
已有文件再入库的简写:`bl knowledge doc upload --file ./a.md --index-id <index-id> --wait`(上传+导入一步完成)。
## ID 速查(极易混淆)
| ID | 来源 | 用在哪 |
| --- | --- | --- |
| `index-id` | `kb create` 返回的 pipelineId / `kb list` | 所有 kb/doc/chunk 命令的 `--index-id` |
| `fileId` | `doc upload` / `doc import-oss` 返回 | 数据中心命令(`file get/delete`、`kb create --doc-id`、`doc tag`) |
| `index-id` | `knowledge create` 返回的 pipelineId / `knowledge list` | 所有 knowledge/doc/chunk 命令的 `--index-id` |
| `fileId` | `doc upload` / `doc import-oss` 返回 | 数据中心命令(`file get/delete`、`knowledge create --doc-id`、`doc tag`) |
| `doc_id`(库内文档 ID) | `doc list` 输出 | `doc delete`、`chunk add/update` 的 `--doc-id`;**可能带 workspace 后缀,≠ fileId** |
| `job-id` | 导入命令返回的 ingestionId | `doc status`(必须同时给 `--index-id` 和 `--job-id`) |
| chunk id | `chunk list` 输出的 `metadata._id` | `chunk update/delete` 的 `--chunk-id` |
| `agent-id` | `service create/list` | `service *`、`kb_search`/`kb_chat`、`kscli search/chat` |
| `agent-id` | `service create/list` | `service *`、`kb_search`/`kb_chat`、`bl knowledge search/chat` |
## 命令参考(权威)
@@ -69,14 +67,14 @@ kscli service list --scene search --status deployed # 5. 确认
- [reference/index.md](reference/index.md) — 全命令速查表、全局 flag、鉴权说明
- reference/&lt;group&gt;.md — 按命令组分文件(kb / doc / service / chunk / datacenter / config / query)
执行不熟悉的命令前,先读对应 reference 或跑 `kscli <命令> --help`。**不要猜 flag。**
执行不熟悉的命令前,先读对应 reference 或跑 `bl <命令> --help`。**不要猜 flag。**
全部命令支持 `--output json`(结构化输出)、`--dry-run`(预览请求)、`--quiet`、`--verbose`。
## 危险与不可逆操作
执行以下操作前须向用户确认,脚本化时才用 `--yes` 跳过交互确认:
- `kb delete`:不可逆,库和全部索引内容永久删除(数据中心源文件保留)。
- `knowledge delete`:不可逆,库和全部索引内容永久删除(数据中心源文件保留)。
- `file delete`:不可逆,且引用该文件的知识库文档索引会失效;只想从单个库移除用 `doc delete`。
- `chunk delete`:不可逆。
- `service deploy`:发布影响线上调用方;`service delete` 后 agent_id 不可再用(软删、幂等)。
@@ -87,6 +85,6 @@ kscli service list --scene search --status deployed # 5. 确认
- 用户反复使用同一检索服务时,建议其把 agent_id 写入项目指令(如 AGENTS.md)或让 agent 记住,后续 kb_search / kb_chat 直接携带。
- 服务有 draft/deployed 两种状态:只有 deployed 可被默认版本调用;draft 调试用 `--agent-version beta`。改已发布版本的配置:先改 beta 草稿(`service update`),验证后 `service deploy` 发新版本。
- 导入类命令(`kb create`、`doc upload --index-id`、`doc status`)优先带 `--wait` 轮询到终态,避免手工轮询;文档解析失败(如 PARSE_FAILED)会以非零退出码透传错误。
- 导入类命令(`knowledge create`、`doc upload --index-id`、`doc status`)优先带 `--wait` 轮询到终态,避免手工轮询;文档解析失败(如 PARSE_FAILED)会以非零退出码透传错误。
- `chunk add` 有 10 QPS 限流,批量脚本注意节流;响应不带 chunk id,需要 `chunk list` 反查。
- `service list` 必须带 `--scene chat|search`,两个场景要分别查询。
@@ -1,14 +1,14 @@
# `kscli chunk` — Chunk 运维
# `bl knowledge chunk` — Chunk 运维
> 通用鉴权/全局 flag 见 [index.md](index.md)。以下 Flags 只列命令专属项。
> chunk id = `chunk list` 输出的 `metadata._id`;文档 id = `metadata.doc_id`。
## `kscli chunk add`
## `bl knowledge chunk add`
直接向库内添加 chunk。
```
Usage: kscli chunk add --index-id <id> (--content <text> | --field <k=v>) [flags]
Usage: bl knowledge chunk add --index-id <id> (--content <text> | --field <k=v>) [flags]
```
| Flag | 说明 |
@@ -29,16 +29,16 @@ Notes:
- 响应不带 chunk id;添加后用 `chunk list` 反查。
```bash
kscli chunk add --index-id idx-xxx --content "chunk text" --title intro --doc-id file-xxx
kscli chunk add --index-id idx-xxx --field 列A=v1 --field 列B=v2
bl knowledge chunk add --index-id idx-xxx --content "chunk text" --title intro --doc-id file-xxx
bl knowledge chunk add --index-id idx-xxx --field 列A=v1 --field 列B=v2
```
## `kscli chunk list`
## `bl knowledge chunk list`
列出 chunk 内容与状态。
```
Usage: kscli chunk list --index-id <id> [flags]
Usage: bl knowledge chunk list --index-id <id> [flags]
```
| Flag | 说明 |
@@ -51,15 +51,15 @@ Notes:
- 后续 update/delete 用输出中的 `metadata._id`(chunk id)与 `metadata.doc_id`(文档 id)。
```bash
kscli chunk list --index-id idx-xxx --doc-id file-xxx --page-size 50
bl knowledge chunk list --index-id idx-xxx --doc-id file-xxx --page-size 50
```
## `kscli chunk update`
## `bl knowledge chunk update`
改 chunk 内容或切换检索可见性。
```
Usage: kscli chunk update --index-id <id> --chunk-id <id> --doc-id <id> [flags]
Usage: bl knowledge chunk update --index-id <id> --chunk-id <id> --doc-id <id> [flags]
```
| Flag | 说明 |
@@ -78,16 +78,16 @@ Notes:
- 只切 `--exclude/--include` 不给新内容时,自动重提交现有内容。
```bash
kscli chunk update --index-id idx-xxx --chunk-id chunk-xxx --doc-id file-xxx --content "corrected text"
kscli chunk update --index-id idx-xxx --chunk-id chunk-xxx --doc-id file-xxx --exclude
bl knowledge chunk update --index-id idx-xxx --chunk-id chunk-xxx --doc-id file-xxx --content "corrected text"
bl knowledge chunk update --index-id idx-xxx --chunk-id chunk-xxx --doc-id file-xxx --exclude
```
## `kscli chunk delete`
## `bl knowledge chunk delete`
删除 chunk。**不可逆,执行前须向用户确认。**
```
Usage: kscli chunk delete --index-id <id> --chunk-id <id> [flags]
Usage: bl knowledge chunk delete --index-id <id> --chunk-id <id> [flags]
```
| Flag | 说明 |
@@ -96,5 +96,5 @@ Usage: kscli chunk delete --index-id <id> --chunk-id <id> [flags]
| `--yes` | 跳过交互确认 |
```bash
kscli chunk delete --index-id idx-xxx --chunk-id chunk-a --chunk-id chunk-b --yes
bl knowledge chunk delete --index-id idx-xxx --chunk-id chunk-a --chunk-id chunk-b --yes
```
@@ -1,55 +1,77 @@
# `kscli config` / `update` — 配置与升级
# `bl config` / `auth` / `update` — 配置、鉴权与升级
> 通用全局 flag 见 [index.md](index.md)。这两组命令无需鉴权。
> 通用全局 flag 见 [index.md](index.md)。这几组命令无需鉴权。
## `kscli config show`
## `bl config show`
显示当前配置。
```
Usage: kscli config show
Usage: bl config show
```
```bash
kscli config show
kscli config show --output json
bl config show
bl config show --output json
```
## `kscli config set`
## `bl config set`
设置配置项。
```
Usage: kscli config set --key <key> --value <value>
Usage: bl config set --key <key> --value <value>
```
可用 key:`base_url`、`output`、`output_dir`、`timeout`、`api_key`、`access_token`、
`access_key_id`、`access_key_secret`、`security_token`、`default_*_model`、`workspace_id`。
```bash
kscli config set --key workspace_id --value ws-xxx
kscli config set --key output --value json
kscli config set --key timeout --value 600
bl config set --key workspace_id --value ws-xxx
bl config set --key output --value json
bl config set --key timeout --value 600
```
## `kscli update`
## `bl config list` / `bl config use`
列出配置 profile 并显示当前激活项 / 切换激活 profile。任意命令可用全局 flag `--config <name>` 临时指定 profile。
```
Usage: bl config list
Usage: bl config use --name <name>
```
```bash
bl config list
bl config use --name default
```
## `bl auth login`
存储 API key(或 console 浏览器登录、OpenAPI AK/SK,多种凭据可共存)。知识库命令只需要 API key。
```
Usage: bl auth login --api-key <key> | --console | --open-api --access-key-id <id> --access-key-secret <secret>
```
```bash
bl auth login --api-key sk-xxxxx
bl auth status
```
## `bl update`
升级 CLI 到最新或指定版本。
```
Usage: kscli update [--to <version>]
Usage: bl update [--to <version>]
```
| Flag | 说明 |
| --- | --- |
| `--to <version>` | 安装该精确版本而非最新版 |
Notes:
- 管理命令在 `knowledge` 发行通道;若 `kscli update` 后管理命令消失(升到了 latest),用
`npm install -g knowledge-studio-cli@knowledge` 装回。
```bash
kscli update
kscli update --to 0.1.14
bl update
bl update --to 1.16.0
```
@@ -1,21 +1,21 @@
# `kscli category` / `file` / `collection` — 数据中心
# `bl knowledge category` / `file` / `collection` — 数据中心
> 通用鉴权/全局 flag 见 [index.md](index.md)。以下 Flags 只列命令专属项。
> 数据中心是文件的原始存储层:collection(集合)> category(类目)> file(文件)。知识库只是索引层,删库不影响这里的文件。
## `kscli category list`
## `bl knowledge category list`
列出数据中心类目。
```
Usage: kscli category list [flags]
Usage: bl knowledge category list [flags]
```
| Flag | 说明 |
| --- | --- |
| `--collection-id <id>` | 按集合 ID 精确过滤 |
| `--parent-id <id>` | 列出该父类目下的子类目 |
| `--name <text>` | 按名称过滤(**精确匹配**,与 kb list 的模糊匹配不同) |
| `--name <text>` | 按名称过滤(**精确匹配**,与 knowledge list 的模糊匹配不同) |
| `--next-token <token>` | 游标分页(取自上一页输出) |
| `--max-result <n>` | 每页条数(默认 20) |
@@ -24,16 +24,16 @@ Notes:
- 标 `[default]` 的类目是未指定类目时文件的默认落点。
```bash
kscli category list --workspace-id ws-xxx
kscli category list --name my-category
bl knowledge category list --workspace-id ws-xxx
bl knowledge category list --name my-category
```
## `kscli category add`
## `bl knowledge category add`
创建数据中心类目。
```
Usage: kscli category add --name <text> [flags]
Usage: bl knowledge category add --name <text> [flags]
```
| Flag | 说明 |
@@ -43,16 +43,16 @@ Usage: kscli category add --name <text> [flags]
| `--collection-id <id>` | 建在该集合下(默认平台集合) |
```bash
kscli category add --name product-docs --workspace-id ws-xxx
kscli category add --name sub --parent-id cate-xxx
bl knowledge category add --name product-docs --workspace-id ws-xxx
bl knowledge category add --name sub --parent-id cate-xxx
```
## `kscli category delete`
## `bl knowledge category delete`
删除数据中心类目。**执行前须向用户确认。**
```
Usage: kscli category delete --category-id <id> [flags]
Usage: bl knowledge category delete --category-id <id> [flags]
```
| Flag | 说明 |
@@ -64,15 +64,15 @@ Notes:
- 含文件或子类目时的行为由服务端决定——服务端错误原样透传。
```bash
kscli category delete --category-id cate-xxx --yes
bl knowledge category delete --category-id cate-xxx --yes
```
## `kscli file list`
## `bl knowledge file list`
列出类目下的文件。
```
Usage: kscli file list --category-id <id> [flags]
Usage: bl knowledge file list --category-id <id> [flags]
```
| Flag | 说明 |
@@ -83,28 +83,28 @@ Usage: kscli file list --category-id <id> [flags]
| `--next-token <token>` / `--max-result <n>` | 游标分页 |
```bash
kscli file list --category-id cate-xxx --workspace-id ws-xxx
kscli file list --category-id cate-xxx --name report
bl knowledge file list --category-id cate-xxx --workspace-id ws-xxx
bl knowledge file list --category-id cate-xxx --name report
```
## `kscli file get`
## `bl knowledge file get`
查看文件详情(大小、MD5、标签、时间戳)。
```
Usage: kscli file get --file-id <id> [flags]
Usage: bl knowledge file get --file-id <id> [flags]
```
```bash
kscli file get --file-id file-xxx --workspace-id ws-xxx
bl knowledge file get --file-id file-xxx --workspace-id ws-xxx
```
## `kscli file delete`
## `bl knowledge file delete`
永久删除数据中心文件。**不可逆,执行前须向用户确认。**
```
Usage: kscli file delete --file-id <id> [flags]
Usage: bl knowledge file delete --file-id <id> [flags]
```
| Flag | 说明 |
@@ -117,15 +117,15 @@ Notes:
- 只想从单个知识库移除文档时用 `doc delete`。
```bash
kscli file delete --file-id file-xxx --yes
bl knowledge file delete --file-id file-xxx --yes
```
## `kscli collection create`
## `bl knowledge collection create`
创建 FILE 数据集合。**没有删除 API——创建须慎重,执行前须向用户确认。**
```
Usage: kscli collection create --name <text> --description <text> [flags]
Usage: bl knowledge collection create --name <text> --description <text> [flags]
```
| Flag | 说明 |
@@ -140,19 +140,19 @@ Notes:
- 自有 bucket 必须带标签 `bailian-connector-access=ReadAndWrite`(百炼基于标签的访问控制);缺失时服务端会以有误导性的 “setBucketCORS failed” 报错拒绝创建。
```bash
kscli collection create --name my-collection --description 'team docs' --workspace-id ws-xxx
kscli collection create --name oss-coll --description 'own bucket' --store-type custom --oss-region cn-beijing --oss-bucket my-bucket
bl knowledge collection create --name my-collection --description 'team docs' --workspace-id ws-xxx
bl knowledge collection create --name oss-coll --description 'own bucket' --store-type custom --oss-region cn-beijing --oss-bucket my-bucket
```
## `kscli collection get`
## `bl knowledge collection get`
查看数据集合详情。
```
Usage: kscli collection get (--collection-id <id> | --name <text>) [flags]
Usage: bl knowledge collection get (--collection-id <id> | --name <text>) [flags]
```
```bash
kscli collection get --collection-id conn-xxx --workspace-id ws-xxx
kscli collection get --name my-collection
bl knowledge collection get --collection-id conn-xxx --workspace-id ws-xxx
bl knowledge collection get --name my-collection
```
@@ -1,13 +1,13 @@
# `kscli doc` — 文档上传与导入
# `bl knowledge doc` — 文档上传与导入
> 通用鉴权/全局 flag 见 [index.md](index.md)。以下 Flags 只列命令专属项。
## `kscli doc upload`
## `bl knowledge doc upload`
上传本地文件/目录到数据中心,可选同时导入知识库。
```
Usage: kscli doc upload --file <path> [flags]
Usage: bl knowledge doc upload --file <path> [flags]
```
| Flag | 说明 |
@@ -26,17 +26,17 @@ Notes:
- 多文件顺序处理;中途失败时,已注册的 fileId 会列在错误提示里。
```bash
kscli doc upload --file ./a.md --workspace-id ws-xxx
kscli doc upload --file ./a.md --file ./b.pdf --index-id idx-xxx --wait
kscli doc upload --file ./docs/ --dry-run --verbose
bl knowledge doc upload --file ./a.md --workspace-id ws-xxx
bl knowledge doc upload --file ./a.md --file ./b.pdf --index-id idx-xxx --wait
bl knowledge doc upload --file ./docs/ --dry-run --verbose
```
## `kscli doc list`
## `bl knowledge doc list`
列出库内文档及解析/索引状态。
```
Usage: kscli doc list --index-id <id> [flags]
Usage: bl knowledge doc list --index-id <id> [flags]
```
| Flag | 说明 |
@@ -50,16 +50,16 @@ Notes:
- 输出的 doc_id 才是 `doc delete` / `chunk add` 应使用的文档 ID。
```bash
kscli doc list --index-id idx-xxx --workspace-id ws-xxx
kscli doc list --index-id idx-xxx --page-size 100
bl knowledge doc list --index-id idx-xxx --workspace-id ws-xxx
bl knowledge doc list --index-id idx-xxx --page-size 100
```
## `kscli doc status`
## `bl knowledge doc status`
查看导入任务状态。
```
Usage: kscli doc status --index-id <id> --job-id <id> [flags]
Usage: bl knowledge doc status --index-id <id> --job-id <id> [flags]
```
| Flag | 说明 |
@@ -74,15 +74,15 @@ Notes:
- 任务整体状态:PENDING / RUNNING / COMPLETED;单文档失败(如 PARSE_FAILED)以非零退出码透传错误。
```bash
kscli doc status --index-id idx-xxx --job-id job-xxx --wait --poll-interval 10
bl knowledge doc status --index-id idx-xxx --job-id job-xxx --wait --poll-interval 10
```
## `kscli doc delete`
## `bl knowledge doc delete`
从库中删除文档及其 chunk。**执行前须向用户确认。**
```
Usage: kscli doc delete --index-id <id> --doc-id <id> [flags]
Usage: bl knowledge doc delete --index-id <id> --doc-id <id> [flags]
```
| Flag | 说明 |
@@ -93,19 +93,19 @@ Usage: kscli doc delete --index-id <id> --doc-id <id> [flags]
Notes:
- 只从知识库索引移除,数据中心源文件保留。
- **用 `doc list` 输出的 doc_id,不是 `doc upload` 返回的 fileId**:经 `kb create --doc-id` 入库的文档二者相等;经 `doc upload --index-id` 入库的 doc_id 可能带 workspace 后缀。
- **用 `doc list` 输出的 doc_id,不是 `doc upload` 返回的 fileId**:经 `knowledge create --doc-id` 入库的文档二者相等;经 `doc upload --index-id` 入库的 doc_id 可能带 workspace 后缀。
- 删除传播最多 ~30s,期间文档可能仍出现在 doc list 里。
```bash
kscli doc delete --index-id idx-xxx --doc-id file-a --doc-id file-b --yes
bl knowledge doc delete --index-id idx-xxx --doc-id file-a --doc-id file-b --yes
```
## `kscli doc tag`
## `bl knowledge doc tag`
批量更新数据中心文件标签。
```
Usage: kscli doc tag --doc-id <id> --tag <text> [flags]
Usage: bl knowledge doc tag --doc-id <id> --tag <text> [flags]
```
| Flag | 说明 |
@@ -120,16 +120,16 @@ Notes:
- 服务端限制:每文件 ≤100 个标签,标签总长 ≤700 字符。
```bash
kscli doc tag --doc-id file-xxx --tag project-a --tag draft --workspace-id ws-xxx
kscli doc tag --doc-id file-a --doc-id file-b --tag final --mode overwrite
bl knowledge doc tag --doc-id file-xxx --tag project-a --tag draft --workspace-id ws-xxx
bl knowledge doc tag --doc-id file-a --doc-id file-b --tag final --mode overwrite
```
## `kscli doc import-oss`
## `bl knowledge doc import-oss`
从已授权 OSS bucket 批量导入到数据中心。
```
Usage: kscli doc import-oss --bucket <name> --region <id> --oss-key <key> [flags]
Usage: bl knowledge doc import-oss --bucket <name> --region <id> --oss-key <key> [flags]
```
| Flag | 说明 |
@@ -146,6 +146,6 @@ Notes:
- `--overwrite` 会替换旧文件并签发**新的 fileId**(旧 fileId 失效)。
```bash
kscli doc import-oss --bucket my-bucket --region cn-beijing --oss-key docs/a.pdf --workspace-id ws-xxx
kscli doc import-oss --bucket my-bucket --region cn-beijing --oss-key docs/a.pdf --oss-key docs/b.docx --overwrite
bl knowledge doc import-oss --bucket my-bucket --region cn-beijing --oss-key docs/a.pdf --workspace-id ws-xxx
bl knowledge doc import-oss --bucket my-bucket --region cn-beijing --oss-key docs/a.pdf --oss-key docs/b.docx --overwrite
```
@@ -1,50 +1,52 @@
# `kscli` 命令参考索引
# `bl` 知识库命令参考索引
> 由 `knowledge-studio-cli@knowledge`(0.0.0-beta-4086da5-202608141600)各命令 `--help` 输出整理。
> 由 `bailian-cli`(1.16.0)各命令 `--help` 输出整理。
> 命令详情在同目录 `<group>.md`;本索引只放速查表、全局 flag 与鉴权说明。
> 版本更新后以 `kscli <命令> --help` 为准。
> 版本更新后以 `bl <命令> --help` 为准。
## 速查表
| 命令 | 鉴权 | 说明 | 详情 |
| --- | --- | --- | --- |
| `kscli kb list` | API Key | 列出 workspace 内知识库 | [kb.md](kb.md) |
| `kscli kb info` | API Key | 查看知识库配置详情 | [kb.md](kb.md) |
| `kscli kb create` | API Key | 建库并导入数据中心文件或类目 | [kb.md](kb.md) |
| `kscli kb update` | API Key | 改名、描述或 rerank 阈值 | [kb.md](kb.md) |
| `kscli kb delete` | API Key | 删库(含全部文档与 chunk,不可逆) | [kb.md](kb.md) |
| `kscli kb stats` | API Key | 存储量与 QPS 监控数据 | [kb.md](kb.md) |
| `kscli doc list` | API Key | 列出库内文档及解析/索引状态 | [doc.md](doc.md) |
| `kscli doc status` | API Key | 查看导入任务状态 | [doc.md](doc.md) |
| `kscli doc upload` | API Key | 上传本地文件/目录,可选同时入库 | [doc.md](doc.md) |
| `kscli doc delete` | API Key | 从库中删除文档及其 chunk | [doc.md](doc.md) |
| `kscli doc tag` | API Key | 批量更新数据中心文件标签 | [doc.md](doc.md) |
| `kscli doc import-oss` | API Key | 从已授权 OSS bucket 批量导入 | [doc.md](doc.md) |
| `kscli service list` | API Key | 列出检索/问答服务 | [service.md](service.md) |
| `kscli service get` | API Key | 查看服务各版本配置 | [service.md](service.md) |
| `kscli service create` | API Key | 创建服务(初始为 draft/beta) | [service.md](service.md) |
| `kscli service update` | API Key | 更新名称、描述或草稿配置 | [service.md](service.md) |
| `kscli service deploy` | API Key | 把 beta 草稿发布为新版本 | [service.md](service.md) |
| `kscli service delete` | API Key | 删除服务(软删、幂等) | [service.md](service.md) |
| `kscli service copy` | API Key | 复制服务为新草稿(名称加 copy\_ 前缀) | [service.md](service.md) |
| `kscli chunk add` | API Key | 直接向库内添加 chunk | [chunk.md](chunk.md) |
| `kscli chunk list` | API Key | 列出 chunk 内容与状态 | [chunk.md](chunk.md) |
| `kscli chunk update` | API Key | 改 chunk 内容或切换检索可见性 | [chunk.md](chunk.md) |
| `kscli chunk delete` | API Key | 删除 chunk(不可逆) | [chunk.md](chunk.md) |
| `kscli category list` | API Key | 列出数据中心类目 | [datacenter.md](datacenter.md) |
| `kscli category add` | API Key | 创建数据中心类目 | [datacenter.md](datacenter.md) |
| `kscli category delete` | API Key | 删除数据中心类目 | [datacenter.md](datacenter.md) |
| `kscli file list` | API Key | 列出类目下的文件 | [datacenter.md](datacenter.md) |
| `kscli file get` | API Key | 查看文件详情(大小/MD5/标签/时间) | [datacenter.md](datacenter.md) |
| `kscli file delete` | API Key | 永久删除数据中心文件 | [datacenter.md](datacenter.md) |
| `kscli collection create` | API Key | 创建 FILE 数据集合(无删除 API) | [datacenter.md](datacenter.md) |
| `kscli collection get` | API Key | 查看数据集合详情 | [datacenter.md](datacenter.md) |
| `kscli config show` | 无需 | 显示当前配置 | [config.md](config.md) |
| `kscli config set` | 无需 | 设置配置项 | [config.md](config.md) |
| `kscli update` | 无需 | 升级 CLI | [config.md](config.md) |
| `kscli search` | API Key | RAG 语义检索(部署验证用;日常检索走原生工具 kb_search) | [query.md](query.md) |
| `kscli chat` | API Key | RAG 问答,SSE 流式(部署验证用;日常问答走原生工具 kb_chat) | [query.md](query.md) |
| `kscli retrieve` | API Key | 已废弃,改用 `search` | [query.md](query.md) |
| `bl knowledge list` | API Key | 列出 workspace 内知识库 | [kb.md](kb.md) |
| `bl knowledge info` | API Key | 查看知识库配置详情 | [kb.md](kb.md) |
| `bl knowledge create` | API Key | 建库并导入数据中心文件或类目 | [kb.md](kb.md) |
| `bl knowledge update` | API Key | 改名、描述或 rerank 阈值 | [kb.md](kb.md) |
| `bl knowledge delete` | API Key | 删库(含全部文档与 chunk,不可逆) | [kb.md](kb.md) |
| `bl knowledge stats` | API Key | 存储量与 QPS 监控数据 | [kb.md](kb.md) |
| `bl knowledge doc list` | API Key | 列出库内文档及解析/索引状态 | [doc.md](doc.md) |
| `bl knowledge doc status` | API Key | 查看导入任务状态 | [doc.md](doc.md) |
| `bl knowledge doc upload` | API Key | 上传本地文件/目录,可选同时入库 | [doc.md](doc.md) |
| `bl knowledge doc delete` | API Key | 从库中删除文档及其 chunk | [doc.md](doc.md) |
| `bl knowledge doc tag` | API Key | 批量更新数据中心文件标签 | [doc.md](doc.md) |
| `bl knowledge doc import-oss` | API Key | 从已授权 OSS bucket 批量导入 | [doc.md](doc.md) |
| `bl knowledge service list` | API Key | 列出检索/问答服务 | [service.md](service.md) |
| `bl knowledge service get` | API Key | 查看服务各版本配置 | [service.md](service.md) |
| `bl knowledge service create` | API Key | 创建服务(初始为 draft/beta) | [service.md](service.md) |
| `bl knowledge service update` | API Key | 更新名称、描述或草稿配置 | [service.md](service.md) |
| `bl knowledge service deploy` | API Key | 把 beta 草稿发布为新版本 | [service.md](service.md) |
| `bl knowledge service delete` | API Key | 删除服务(软删、幂等) | [service.md](service.md) |
| `bl knowledge service copy` | API Key | 复制服务为新草稿(名称加 copy\_ 前缀) | [service.md](service.md) |
| `bl knowledge chunk add` | API Key | 直接向库内添加 chunk | [chunk.md](chunk.md) |
| `bl knowledge chunk list` | API Key | 列出 chunk 内容与状态 | [chunk.md](chunk.md) |
| `bl knowledge chunk update` | API Key | 改 chunk 内容或切换检索可见性 | [chunk.md](chunk.md) |
| `bl knowledge chunk delete` | API Key | 删除 chunk(不可逆) | [chunk.md](chunk.md) |
| `bl knowledge category list` | API Key | 列出数据中心类目 | [datacenter.md](datacenter.md) |
| `bl knowledge category add` | API Key | 创建数据中心类目 | [datacenter.md](datacenter.md) |
| `bl knowledge category delete` | API Key | 删除数据中心类目 | [datacenter.md](datacenter.md) |
| `bl knowledge file list` | API Key | 列出类目下的文件 | [datacenter.md](datacenter.md) |
| `bl knowledge file get` | API Key | 查看文件详情(大小/MD5/标签/时间) | [datacenter.md](datacenter.md) |
| `bl knowledge file delete` | API Key | 永久删除数据中心文件 | [datacenter.md](datacenter.md) |
| `bl knowledge collection create` | API Key | 创建 FILE 数据集合(无删除 API) | [datacenter.md](datacenter.md) |
| `bl knowledge collection get` | API Key | 查看数据集合详情 | [datacenter.md](datacenter.md) |
| `bl config show` | 无需 | 显示当前配置 | [config.md](config.md) |
| `bl config set` | 无需 | 设置配置项 | [config.md](config.md) |
| `bl config list` / `use` | 无需 | 列出 / 切换配置 profile | [config.md](config.md) |
| `bl auth login` | 无需 | 存储 API key 等凭据 | [config.md](config.md) |
| `bl update` | 无需 | 升级 CLI | [config.md](config.md) |
| `bl knowledge search` | API Key | RAG 语义检索(部署验证用;日常检索走原生工具 kb_search) | [query.md](query.md) |
| `bl knowledge chat` | API Key | RAG 问答,SSE 流式(部署验证用;日常问答走原生工具 kb_chat) | [query.md](query.md) |
| `bl knowledge retrieve` | API Key | 已废弃,改用 `search` | [query.md](query.md) |
## 全局 flag(所有命令可用)
@@ -68,6 +70,7 @@
## 说明
- 所有管理命令使用 DashScope API Key(Bearer token)鉴权,无 console 登录态。
- 所有知识库管理命令使用 DashScope API Key(Bearer token)鉴权,无需 console 登录态;API key 也可用 `bl auth login --api-key sk-xxx` 存储。
- 除知识库外,bl 还有模型调用/应用/用量等其他命令组,不在本 skill 范围,见 `bl --help`。
- 默认输出为 text;agent 解析结果时建议显式加 `--output json`。
- 分页有两种风格:kb/doc/service/chunk 用 `--page-number/--page-size`(page-size 上限 100);category/file 用游标 `--next-token/--max-result`。
- 分页有两种风格:knowledge/doc/service/chunk 用 `--page-number/--page-size`(page-size 上限 100);category/file 用游标 `--next-token/--max-result`。
@@ -1,13 +1,13 @@
# `kscli kb` — 知识库生命周期
# `bl knowledge` — 知识库生命周期
> 通用鉴权/全局 flag 见 [index.md](index.md)。以下 Flags 只列命令专属项。
## `kscli kb list`
## `bl knowledge list`
列出 workspace 内知识库。
```
Usage: kscli kb list [flags]
Usage: bl knowledge list [flags]
```
| Flag | 说明 |
@@ -21,16 +21,16 @@ Notes:
- 返回的 id 即后续 kb/doc/chunk 管理命令的 `--index-id`。
```bash
kscli kb list --workspace-id ws-xxx
kscli kb list --name demo --page-number 2 --page-size 50
bl knowledge list --workspace-id ws-xxx
bl knowledge list --name demo --page-number 2 --page-size 50
```
## `kscli kb info`
## `bl knowledge info`
查看知识库配置详情。
```
Usage: kscli kb info --index-id <id> [flags]
Usage: bl knowledge info --index-id <id> [flags]
```
Notes:
@@ -38,15 +38,15 @@ Notes:
- 索引配置不可变,改配置需重建知识库。
```bash
kscli kb info --index-id idx-xxx --workspace-id ws-xxx
bl knowledge info --index-id idx-xxx --workspace-id ws-xxx
```
## `kscli kb create`
## `bl knowledge create`
建库并导入数据中心文件或类目。
```
Usage: kscli kb create --name <text> (--doc-id <id> | --category-id <id>) [flags]
Usage: bl knowledge create --name <text> (--doc-id <id> | --category-id <id>) [flags]
```
| Flag | 说明 |
@@ -65,16 +65,16 @@ Notes:
- 返回知识库 id(pipelineId)与首次导入任务 id(ingestionId);用 `doc status`(或 `--wait`)跟踪导入。
```bash
kscli kb create --name demo --doc-id file-xxx --workspace-id ws-xxx
kscli kb create --name demo --category-id cate-xxx --wait
bl knowledge create --name demo --doc-id file-xxx --workspace-id ws-xxx
bl knowledge create --name demo --category-id cate-xxx --wait
```
## `kscli kb update`
## `bl knowledge update`
改名、描述或 rerank 阈值。
```
Usage: kscli kb update --index-id <id> [flags]
Usage: bl knowledge update --index-id <id> [flags]
```
| Flag | 说明 |
@@ -88,16 +88,16 @@ Notes:
- 索引配置(embedding 模型、chunk size 等)不可变——要改只能重建。
```bash
kscli kb update --index-id idx-xxx --description 'product docs v2' --workspace-id ws-xxx
kscli kb update --index-id idx-xxx --rerank-min-score 0.3
bl knowledge update --index-id idx-xxx --description 'product docs v2' --workspace-id ws-xxx
bl knowledge update --index-id idx-xxx --rerank-min-score 0.3
```
## `kscli kb delete`
## `bl knowledge delete`
删库(含全部文档与 chunk)。**不可逆,执行前须向用户确认。**
```
Usage: kscli kb delete --index-id <id> [flags]
Usage: bl knowledge delete --index-id <id> [flags]
```
| Flag | 说明 |
@@ -110,16 +110,16 @@ Notes:
- 数据中心内的源文件不受影响,只删索引。
```bash
kscli kb delete --index-id idx-xxx --workspace-id ws-xxx
kscli kb delete --index-id idx-xxx --yes
bl knowledge delete --index-id idx-xxx --workspace-id ws-xxx
bl knowledge delete --index-id idx-xxx --yes
```
## `kscli kb stats`
## `bl knowledge stats`
存储量与 QPS 监控数据。
```
Usage: kscli kb stats --index-id <id> [flags]
Usage: bl knowledge stats --index-id <id> [flags]
```
| Flag | 说明 |
@@ -132,6 +132,6 @@ Notes:
- 监控 API 只返回历史数据:`--start` 拒绝未来时间,`--end` 的未来值被截断到当前。
```bash
kscli kb stats --index-id idx-xxx --workspace-id ws-xxx
kscli kb stats --index-id idx-xxx --start 2026-07-30 --end 2026-07-31
bl knowledge stats --index-id idx-xxx --workspace-id ws-xxx
bl knowledge stats --index-id idx-xxx --start 2026-07-30 --end 2026-07-31
```
@@ -1,15 +1,15 @@
# `kscli search` / `chat` — 检索与问答(仅部署验证用)
# `bl knowledge search` / `chat` — 检索与问答(仅部署验证用)
> **日常检索/问答走原生工具 `kb_search` / `kb_chat`,不走 kscli。**
> **日常检索/问答走原生工具 `kb_search` / `kb_chat`,不走 bl。**
> 这两条命令只在两种场景下使用:(1) 部署前用 `--agent-version beta` 调试草稿配置;(2) 排查原生工具与 CLI 行为差异。
> 通用鉴权/全局 flag 见 [index.md](index.md)。
## `kscli search`
## `bl knowledge search`
RAG 语义检索。
```
Usage: kscli search --query <text> --agent-id <id> [flags]
Usage: bl knowledge search --query <text> --agent-id <id> [flags]
```
| Flag | 说明 |
@@ -24,16 +24,16 @@ Notes:
- 检索范围与策略(多库加权、路由、rerank 等)由 agent_id 的服务配置决定,只有 query 和 agent_id 必填。
```bash
kscli search --query "What is RAG?" --agent-id aid-xxx --workspace-id ws-xxx
kscli search --query "test" --agent-id aid-xxx --agent-version beta
bl knowledge search --query "What is RAG?" --agent-id aid-xxx --workspace-id ws-xxx
bl knowledge search --query "test" --agent-id aid-xxx --agent-version beta
```
## `kscli chat`
## `bl knowledge chat`
RAG 问答(SSE 流式)。
```
Usage: kscli chat --message <text> --agent-id <id> [flags]
Usage: bl knowledge chat --message <text> --agent-id <id> [flags]
```
| Flag | 说明 |
@@ -49,10 +49,10 @@ Notes:
- 多轮对话:用 `--message "user:..."` 和 `--message "assistant:..."` 传历史。
```bash
kscli chat --message "What is RAG?" --agent-id aid-xxx --workspace-id ws-xxx
kscli chat --message "user:What is RAG?" --message "assistant:RAG is..." --message "How does it work?" --agent-id aid-xxx
bl knowledge chat --message "What is RAG?" --agent-id aid-xxx --workspace-id ws-xxx
bl knowledge chat --message "user:What is RAG?" --message "assistant:RAG is..." --message "How does it work?" --agent-id aid-xxx
```
## `kscli retrieve`(已废弃)
## `bl knowledge retrieve`(已废弃)
改用 `kscli search`。
改用 `bl knowledge search`。
@@ -1,14 +1,14 @@
# `kscli service` — 检索 / 问答服务(agent)
# `bl knowledge service` — 检索 / 问答服务(agent)
> 通用鉴权/全局 flag 见 [index.md](index.md)。以下 Flags 只列命令专属项。
> 服务状态机:create → draft(beta 草稿,用 `--agent-version beta` 调试)→ deploy → deployed(版本号自增,可被默认版本调用)。
## `kscli service list`
## `bl knowledge service list`
列出检索/问答服务。
```
Usage: kscli service list --scene <chat|search> [flags]
Usage: bl knowledge service list --scene <chat|search> [flags]
```
| Flag | 说明 |
@@ -26,16 +26,16 @@ Notes:
- 返回的 agent_id 用于 search/chat 调用及 service 管理命令。
```bash
kscli service list --scene chat --workspace-id ws-xxx
kscli service list --scene search --status deployed
bl knowledge service list --scene chat --workspace-id ws-xxx
bl knowledge service list --scene search --status deployed
```
## `kscli service get`
## `bl knowledge service get`
查看服务各版本配置。
```
Usage: kscli service get --agent-id <id> [flags]
Usage: bl knowledge service get --agent-id <id> [flags]
```
| Flag | 说明 |
@@ -43,16 +43,16 @@ Usage: kscli service get --agent-id <id> [flags]
| `--agent-version <version>` | 只看指定版本(beta 或已发布版本号);缺省返回全部版本 |
```bash
kscli service get --agent-id aid-xxx --workspace-id ws-xxx
kscli service get --agent-id aid-xxx --agent-version beta
bl knowledge service get --agent-id aid-xxx --workspace-id ws-xxx
bl knowledge service get --agent-id aid-xxx --agent-version beta
```
## `kscli service create`
## `bl knowledge service create`
创建检索/问答服务(初始 status: draft,version: beta)。
```
Usage: kscli service create --name <text> --scene <chat|search> [flags]
Usage: bl knowledge service create --name <text> --scene <chat|search> [flags]
```
| Flag | 说明 |
@@ -68,16 +68,16 @@ Notes:
- 需要 workspace 的知识库创建权限。
```bash
kscli service create --name my-qa --scene chat --workspace-id ws-xxx
kscli service create --name my-search --scene search --index-id idx-xxx
bl knowledge service create --name my-qa --scene chat --workspace-id ws-xxx
bl knowledge service create --name my-search --scene search --index-id idx-xxx
```
## `kscli service update`
## `bl knowledge service update`
更新名称、描述或草稿配置。
```
Usage: kscli service update --agent-id <id> [flags]
Usage: bl knowledge service update --agent-id <id> [flags]
```
| Flag | 说明 |
@@ -100,17 +100,17 @@ Notes:
- 需要 workspace 的知识库修改权限。
```bash
kscli service update --agent-id aid-xxx --temperature 0.7 --workspace-id ws-xxx
kscli service update --agent-id aid-xxx --config-file ./agent-config.json
kscli service update --agent-id aid-xxx --agent-version 1 --version-desc 'first stable release'
bl knowledge service update --agent-id aid-xxx --temperature 0.7 --workspace-id ws-xxx
bl knowledge service update --agent-id aid-xxx --config-file ./agent-config.json
bl knowledge service update --agent-id aid-xxx --agent-version 1 --version-desc 'first stable release'
```
## `kscli service deploy`
## `bl knowledge service deploy`
把 beta 草稿发布为新版本。**发布影响线上调用方,执行前须向用户确认。**
```
Usage: kscli service deploy --agent-id <id> [flags]
Usage: bl knowledge service deploy --agent-id <id> [flags]
```
| Flag | 说明 |
@@ -123,15 +123,15 @@ Notes:
- 版本号自增;状态变为 deployed。需要 workspace 的知识库修改权限。
```bash
kscli service deploy --agent-id aid-xxx --version-desc 'tuned rerank params' --yes
bl knowledge service deploy --agent-id aid-xxx --version-desc 'tuned rerank params' --yes
```
## `kscli service delete`
## `bl knowledge service delete`
删除服务(软删、幂等)。**删除后 agent_id 不可再用于 search/chat,执行前须向用户确认。**
```
Usage: kscli service delete --agent-id <id> [flags]
Usage: bl knowledge service delete --agent-id <id> [flags]
```
| Flag | 说明 |
@@ -139,15 +139,15 @@ Usage: kscli service delete --agent-id <id> [flags]
| `--yes` | 跳过交互确认 |
```bash
kscli service delete --agent-id aid-xxx --yes
bl knowledge service delete --agent-id aid-xxx --yes
```
## `kscli service copy`
## `bl knowledge service copy`
复制服务为新草稿(名称加 copy\_ 前缀)。
```
Usage: kscli service copy --agent-id <id> [flags]
Usage: bl knowledge service copy --agent-id <id> [flags]
```
Notes:
@@ -155,5 +155,5 @@ Notes:
- 副本以 beta 草稿开始;用 `--agent-version beta` 测试后 deploy 发布。需要知识库创建权限。
```bash
kscli service copy --agent-id aid-xxx --workspace-id ws-xxx
bl knowledge service copy --agent-id aid-xxx --workspace-id ws-xxx
```
+1 -1
View File
@@ -1,4 +1,4 @@
/** Request/response fields of the DashScope search and chat endpoints, mirrored from the verified kscli types. */
/** Request/response fields of the DashScope search and chat endpoints, mirrored from the verified bl CLI types. */
export interface SearchRequest {
query: string
+78
View File
@@ -0,0 +1,78 @@
/**
* Host-side bridge to the locally installed `bl` CLI (bailian-cli). The CLI's
* credential file (`~/.bailian/config.json`) is its documented "output": the
* console browser login (`bl auth login --console`) validates the api key the
* console issues and persists it there in plain JSON — no CLI command ever
* echoes the value back (auth status / config show both mask), so reading the
* file is the only way to obtain it programmatically.
*/
import { spawn } from 'node:child_process'
import { readFileSync } from 'node:fs'
import { homedir } from 'node:os'
import { join } from 'node:path'
/** The two values this plugin can adopt from the bl CLI credential file. */
export interface BlCliConfig {
/** DashScope api key (`api_key`, top-level default profile). */
apiKey?: string
/** Bailian workspace id (`workspace_id`), present when the console login callback carried one. */
workspaceId?: string
}
/** Default location of the bl CLI credential file (default profile at top level). */
export function blCliConfigPath(): string {
return join(homedir(), '.bailian', 'config.json')
}
/**
* Read the api key and workspace id from the bl CLI credential file.
* Best-effort: a missing, unreadable, or malformed file reads as empty —
* callers treat that the same as "the CLI has not logged in yet".
* @param configPath - override for tests; defaults to `~/.bailian/config.json`.
* @returns the values found; fields are absent rather than blank.
*/
export function readBlCliConfig(configPath = blCliConfigPath()): BlCliConfig {
try {
const parsed = JSON.parse(readFileSync(configPath, 'utf8')) as unknown
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) return {}
const record = parsed as Record<string, unknown>
const apiKey = typeof record.api_key === 'string' && record.api_key.trim() !== '' ? record.api_key.trim() : undefined
const workspaceId = typeof record.workspace_id === 'string' && record.workspace_id.trim() !== '' ? record.workspace_id.trim() : undefined
return {
...(apiKey !== undefined ? { apiKey } : {}),
...(workspaceId !== undefined ? { workspaceId } : {}),
}
} catch (_unreadable) {
return {}
}
}
/** Outcome of asking the host to start a console browser login. */
export type ConsoleLoginStart = 'started' | 'already-running' | 'not-found' | 'failed'
/** The in-flight login child, if any: one browser flow at a time. */
let loginChild: ReturnType<typeof spawn> | undefined
/**
* Start `bl auth login --console` on the host: opens the Bailian console
* login page in the host's default browser; on completion the CLI persists
* the issued api key and workspace id to `~/.bailian/config.json` (the flow
* requests a key only when none is stored yet). Fire-and-forget: the child
* keeps running after this resolves — callers re-read the credential file
* on their next fill attempt.
* @returns whether the flow started, was already running, or the CLI is absent.
*/
export function startConsoleLogin(): Promise<ConsoleLoginStart> {
if (loginChild !== undefined) return Promise.resolve('already-running')
return new Promise((resolve) => {
const child = spawn('bl', ['auth', 'login', '--console'], { stdio: 'ignore' })
loginChild = child
child.once('spawn', () => { resolve('started') })
child.once('error', (err: NodeJS.ErrnoException) => {
loginChild = undefined
resolve(err.code === 'ENOENT' ? 'not-found' : 'failed')
})
child.once('exit', () => { loginChild = undefined })
})
}
+1 -1
View File
@@ -1,6 +1,6 @@
/** Protocol path constants and the workspace-subdomain URL builder (external API spec; not configurable). */
/** DashScope knowledge API paths for the two native tools (search, chat); service listing is handled by kscli. */
/** DashScope knowledge API paths for the two native tools (search, chat); service listing is handled by the bl CLI. */
export const KB_PATHS = {
search: '/api/v1/indices/knowledge/search',
chat: '/api/v2/apps/knowledge/chat',
+135 -3
View File
@@ -1,6 +1,6 @@
/**
* Bailian knowledge-base consumer plugin: registers kb_search and kb_chat over the DashScope RAG API,
* plus the kscli management skill.
* plus the bl management skill.
* @module dsh-tool-bailian-kb
*/
@@ -9,6 +9,7 @@ import type { IncomingMessage, ServerResponse } from 'node:http'
import z from '@deepseek-ai/schemastery'
import { credentialRef } from '@deepseek-ai/dsh-credentials'
import { settingsNamespace, SettingsProvider, type SettingsRegisterOptions, type SettingsScope } from '@deepseek-ai/dsh-settings'
import { readBlCliConfig, startConsoleLogin } from './bl-cli.js'
import { KbClient } from './client.js'
import { registerSkill } from './skill.js'
import { createKbTools } from './tools.js'
@@ -85,6 +86,58 @@ async function seedFromCredentials(ctx: Context, scope: SettingsScope<Config>):
}
}
/**
* One-time adoption of the bl CLI's stored login (`~/.bailian/config.json`):
* fields never set anywhere are filled from the CLI's credential file, so a
* `bl auth login --console` done before installing the plugin "just works".
* `seededFields` is the consumed-once ledger — a field is marked when it was
* seeded here, or when it already had a value (user-managed elsewhere) — so
* a value the user later clears deliberately is never resurrected.
* @param ctx - registrant context carrying credentials.
* @param scope - the registered `bailian-kb` scope the seed writes through.
*/
async function seedFromBlCli(ctx: Context, scope: SettingsScope<Config>): Promise<void> {
try {
const done = new Set(scope.get().seededFields ?? [])
if (done.has('apiKey') && done.has('workspaceId')) return
const bl = readBlCliConfig()
const marks: string[] = []
if (!done.has('apiKey')) {
const existing = await ctx.credentials.resolve(credentialRef('DASHSCOPE_API_KEY'))
if (existing) {
// Already configured (env or file): user-managed, never seed later.
marks.push('apiKey')
} else if (bl.apiKey !== undefined) {
try {
await ctx.credentials.set(credentialRef('DASHSCOPE_API_KEY'), bl.apiKey)
marks.push('apiKey')
} catch (_readOnlyShadow) {
// A read-only source refuses the write; leave unmarked so a later
// startup (once the shadow is gone) can still seed.
}
}
// Neither configured nor available from the CLI: leave unmarked so a
// later startup (after `bl auth login --console`) can seed.
}
if (!done.has('workspaceId')) {
const configured = scope.get().workspaceId
|| (await ctx.credentials.resolve(credentialRef('BAILIAN_WORKSPACE_ID'))) !== undefined
if (configured) {
marks.push('workspaceId')
} else if (bl.workspaceId !== undefined) {
await scope.update({ workspaceId: bl.workspaceId })
marks.push('workspaceId')
}
}
if (marks.length > 0) {
await scope.update({ seededFields: [...new Set([...(scope.get().seededFields ?? []), ...marks])] })
}
} catch (_seedFailure) {
// Best-effort: an unseeded field still resolves through the normal
// credential fallback chain, and the panel's autofill button remains.
}
}
/** Bailian knowledge-base plugin configuration. */
export interface Config {
/** Bailian workspace id; the API host is the workspace subdomain `https://<workspaceId>.<endpointHost>`. Optional here: an unset value falls back per call to the BAILIAN_WORKSPACE_ID credential (env/.env or ~/.dsh/.credentials.yaml). Editable with echo on the Settings → 百炼知识库 page (settings layer). */
@@ -99,6 +152,8 @@ export interface Config {
agentVersion?: string
/** kb_chat timeout in milliseconds; the server side is a minutes-scale agentic loop. */
chatTimeoutMs: number
/** Consumed-once ledger of {@link seedFromBlCli}: fields listed here are never auto-seeded again, so a deliberately cleared value stays cleared. Maintained by the host; not editable from the panel. */
seededFields?: string[]
}
/** Schemastery validation for {@link Config}; workspaceId and default agent ids are optional — both resolve per call with a credentials fallback. */
@@ -109,6 +164,7 @@ export const Config: z<Config> = z.object({
defaultChatAgentId: z.string(),
agentVersion: z.string(),
chatTimeoutMs: z.number().default(300_000),
seededFields: z.array(z.string()),
})
/**
@@ -132,6 +188,20 @@ export function apply(ctx: Context, config: Config): void {
let scope: SettingsScope<Config> | undefined
/** The settings provider, captured for `mutate` (path-level unset) access. */
let settings: SettingsProvider | undefined
/**
* Mark fields as consumed in the {@link seedFromBlCli} ledger — called on
* every user-driven write or clear, so a managed field is never re-seeded.
* Best-effort: a failed mark only risks one extra seed attempt.
*/
const markSeeded = async (fields: readonly string[]): Promise<void> => {
if (!scope) return
try {
const done = new Set(scope.get().seededFields ?? [])
const added = fields.filter(field => !done.has(field))
if (added.length === 0) return
await scope.update({ seededFields: [...done, ...added] })
} catch (_markFailure) { /* best-effort */ }
}
ctx.inject(['settings'], (sctx) => {
settings = sctx.settings
// `expose` is the wire opt-in the harness documents as deferred work; the
@@ -142,7 +212,13 @@ export function apply(ctx: Context, config: Config): void {
scope = sctx.settings.register(SETTINGS_NS, Config, options)
current = () => scope!.get()
sctx.effect(() => () => { current = () => config }, 'tool-bailian-kb: settings source fallback')
void seedFromCredentials(ctx, scope)
void seedFromCredentials(ctx, scope).then(() => seedFromBlCli(ctx, scope!))
// Any api-key write or clear — this panel, the Models page, an external
// file edit — means the user manages the credential: consume the seed so
// a deliberately cleared key is never resurrected at the next startup.
sctx.on('credentials/updated', (ref) => {
if (ref === 'DASHSCOPE_API_KEY') void markSeeded(['apiKey'])
})
})
const client = new KbClient({
@@ -194,7 +270,7 @@ export function apply(ctx: Context, config: Config): void {
registerSkill(ctx)
// Export the resolved workspace id as a shell environment variable so
// management CLI commands (`bl knowledge list`, `kscli kb list`, etc.)
// management CLI commands (`bl knowledge list`, `bl knowledge service list`, etc.)
// running in bash can see the value the settings service resolved.
// Without this, the settings.yaml value is invisible to child processes.
ctx.inject(['shellEnv'], (envCtx) => {
@@ -267,12 +343,68 @@ export function apply(ctx: Context, config: Config): void {
await settings.mutate(SETTINGS_NS, [{ op: 'unset', path: [key] }])
}
}
// A user-driven workspace write or clear consumes its bl-CLI seed:
// a deliberately cleared value must never be resurrected at startup.
if ('workspaceId' in patch || removals.has('workspaceId')) await markSeeded(['workspaceId'])
sendJson(res, 200, scope.get())
} catch (err) {
sendJson(res, 500, { error: err instanceof Error ? err.message : 'settings write failed' })
}
},
}), 'tool-bailian-kb: settings bridge route')
// Autofill bridge: adopt the bl CLI's stored login on demand (panel
// button). `fill` reads `~/.bailian/config.json` on the host and writes
// through the same layers the panel edits — the plain key never rides
// the wire to the browser; `login` starts the console browser flow that
// provisions the file for the next fill.
wctx.effect(() => wctx.webServer.register({
kind: 'exact',
path: '/bailian-kb/autofill',
handler: async (req: IncomingMessage, res: ServerResponse) => {
if (req.method !== 'POST') {
sendJson(res, 405, { error: 'use POST' })
return
}
let action = 'fill'
try {
const body = await readJsonBody(req)
if (typeof body === 'object' && body !== null && (body as { action?: unknown }).action === 'login') action = 'login'
} catch (_emptyOrMalformedBody) { /* default to fill */ }
if (action === 'login') {
sendJson(res, 200, { status: await startConsoleLogin() })
return
}
const bl = readBlCliConfig()
const filled: string[] = []
let apiKey: 'filled' | 'missing' | 'failed' = 'missing'
if (bl.apiKey !== undefined) {
try {
await ctx.credentials.set(credentialRef('DASHSCOPE_API_KEY'), bl.apiKey)
apiKey = 'filled'
filled.push('apiKey')
} catch (_readOnlyShadow) {
apiKey = 'failed'
}
}
let workspaceId: 'filled' | 'missing' | 'failed' = 'missing'
if (bl.workspaceId !== undefined) {
if (scope) {
try {
await scope.update({ workspaceId: bl.workspaceId })
workspaceId = 'filled'
filled.push('workspaceId')
} catch (_settingsWriteFailure) {
workspaceId = 'failed'
}
} else {
workspaceId = 'failed'
}
}
if (filled.length > 0) await markSeeded(filled)
sendJson(res, 200, { apiKey, workspaceId })
},
}), 'tool-bailian-kb: autofill bridge route')
})
}
+2 -2
View File
@@ -1,4 +1,4 @@
/** Runtime skill registration: the packaged kscli-management SKILL.md joins the catalog when a skills registry is composed. */
/** Runtime skill registration: the packaged bl-management SKILL.md joins the catalog when a skills registry is composed. */
import { readFileSync } from 'node:fs'
import { join } from 'node:path'
@@ -20,7 +20,7 @@ export function registerSkill(ctx: Context): void {
skillCtx.skills.register({
name: 'bailian-kb-management',
description:
'Manage Bailian knowledge bases with the kscli CLI: create/update KBs, upload documents, deploy '
'Manage Bailian knowledge bases with the bl CLI: create/update KBs, upload documents, deploy '
+ 'retrieval services, and maintain chunks. Retrieval itself uses the native kb_search/kb_chat tools. '
+ 'Credentials and workspace for kb_search/kb_chat resolve automatically from DSH config '
+ '(bailian-kb in ~/.dsh/settings.yaml, DASHSCOPE_API_KEY in ~/.dsh/.credentials.yaml).',
+4 -4
View File
@@ -28,7 +28,7 @@ export interface KbToolDeps {
/**
* Forward the original tool error unchanged; service discovery now lives
* in the kscli management skill (`kscli service list`), so the tool no
* in the bl management skill (`bl knowledge service list`), so the tool no
* longer makes a best-effort API round-trip to enrich the message.
*/
async function withServiceHint(_client: KbClient, err: unknown): Promise<never> {
@@ -49,7 +49,7 @@ export function createKbTools(deps: KbToolDeps) {
required: true as const,
description: 'Retrieval/Q&A service id. REQUIRED: the schema cannot know whether this deployment '
+ 'configures a default service, so always pass one. Find ids via '
+ '`kscli service list --scene search --workspace-id <workspaceId>` (workspaceId resolves '
+ '`bl knowledge service list --scene search --workspace-id <workspaceId>` (workspaceId resolves '
+ 'automatically from DSH settings: bailian-kb.workspaceId in ~/.dsh/settings.yaml).',
}
const resolveRetrieveAgentId = async (supplied: string | undefined): Promise<string> => {
@@ -58,7 +58,7 @@ export function createKbTools(deps: KbToolDeps) {
if (defaultId === undefined) {
throw new Error(
'agent_id is required: no default retrieval service is configured. Pass agent_id explicitly '
+ '(find ids: `kscli service list --scene search --workspace-id <workspaceId>`), or configure a '
+ '(find ids: `bl knowledge service list --scene search --workspace-id <workspaceId>`), or configure a '
+ 'default: bailian-kb.defaultRetrieveAgentId in ~/.dsh/settings.yaml or '
+ 'BAILIAN_DEFAULT_RETRIEVE_AGENT_ID in ~/.dsh/.credentials.yaml.',
)
@@ -71,7 +71,7 @@ export function createKbTools(deps: KbToolDeps) {
if (defaultId === undefined) {
throw new Error(
'agent_id is required: no default chat service is configured. Pass agent_id explicitly '
+ '(find ids: `kscli service list --scene chat --workspace-id <workspaceId>`), or configure a '
+ '(find ids: `bl knowledge service list --scene chat --workspace-id <workspaceId>`), or configure a '
+ 'default: bailian-kb.defaultChatAgentId in ~/.dsh/settings.yaml or '
+ 'BAILIAN_DEFAULT_CHAT_AGENT_ID in ~/.dsh/.credentials.yaml.',
)
@@ -41,6 +41,13 @@
background: var(--dsw-alias-bg-layer-3);
}
/* Autofill control between the intro and the form: button + one-line status. */
.autofillRow {
display: flex;
align-items: center;
gap: 10px;
}
/* Carried beside the title so a scrolled page still says it holds edits. */
.pending {
flex: none;
@@ -44,6 +44,14 @@ const FIELDS: readonly FieldView[] = [
{ key: 'BAILIAN_DEFAULT_CHAT_AGENT_ID', labelKey: 'chatAgentId', hintKey: 'chatAgentIdHint', fallbackHintKey: 'chatAgentIdHintFallback', setKey: 'chatAgentIdSet', unsetKey: 'chatAgentIdUnset', secret: false },
]
/** Result-notice locale key per settled autofill outcome. */
const AUTOFILL_NOTICES: Partial<Record<string, BailianKbLocaleKey>> = {
done: 'autofillDone',
loginStarted: 'autofillLoginStarted',
blMissing: 'autofillBlMissing',
failed: 'autofillFailed',
}
/**
* Render the Bailian section page.
* @param props - locale copy, the page snapshot, and its actions.
@@ -54,6 +62,7 @@ export function BailianCard(props: BailianCardProps) {
const state = props.useBailianCard(snapshot => snapshot)
const dirty = dirtyOf(state)
const busy = state.saving || state.clearing
const autofillNotice = AUTOFILL_NOTICES[state.autofill]
return (
<section className={css.section}>
<div className={css.headRow}>
@@ -61,6 +70,19 @@ export function BailianCard(props: BailianCardProps) {
{dirty ? <span className={css.pending}>{t('unsaved')}</span> : null}
</div>
<p className={css.intro}>{t('description')}</p>
<div className={css.autofillRow}>
<button
type="button"
className={css.discard}
disabled={busy || state.autofill === 'running'}
onClick={() => { void props.autofill() }}
>
{t(state.autofill === 'running' ? 'autofilling' : 'autofill')}
</button>
<span className={css.hint}>
{autofillNotice !== undefined ? t(autofillNotice) : t('autofillHint')}
</span>
</div>
<div className={css.form}>
{state.settings.status === 'unavailable'
? <p className={css.notice}>{t('settingsUnavailable')}</p>
@@ -61,6 +61,9 @@ export interface BailianSettingsView {
values: BailianKbSection
}
/** Where the autofill flow (adopt the bl CLI's stored login) currently stands. */
export type BailianAutofillStatus = 'idle' | 'running' | 'done' | 'loginStarted' | 'blMissing' | 'failed'
/** What the Bailian page renders. */
export interface BailianCardState {
/** Staged drafts; undefined = untouched (the control shows the echoed value). */
@@ -75,6 +78,8 @@ export interface BailianCardState {
clearing: boolean
/** Whether the last save or clear was refused; drafts are kept for correction. */
failed: boolean
/** The autofill flow's state; feeds the button label and its result notice. */
autofill: BailianAutofillStatus
}
/** The registration-side face the page's slot entry injects. */
@@ -91,6 +96,8 @@ export interface BailianCardFace {
discard: () => void
/** Remove the stored default service from every writable layer, then re-read. */
clearDefaultAgent: (key: 'BAILIAN_DEFAULT_RETRIEVE_AGENT_ID' | 'BAILIAN_DEFAULT_CHAT_AGENT_ID') => Promise<void>
/** Adopt the bl CLI's stored login (api key + workspace id) via the Host. */
autofill: () => Promise<void>
}
/** The text a field's control shows when its draft is untouched. */
@@ -144,6 +151,7 @@ export class BailianCardController {
saving: false,
clearing: false,
failed: false,
autofill: 'idle',
})
void this.fetchSettings()
void this.read()
@@ -250,6 +258,40 @@ export class BailianCardController {
})
}
/**
* Adopt the bl CLI's stored login through the Host autofill route. The
* Host reads `~/.bailian/config.json` itself and writes the api key into
* the credential store and the workspace id into the settings section —
* the plain key never rides the wire to this page. When the file has no
* key yet, ask the Host to start `bl auth login --console` (a browser
* flow on the host machine); the user finishes it and clicks again.
*/
async autofill(): Promise<void> {
if (this.store.getSnapshot().autofill === 'running') return
this.store.update(draft => { draft.autofill = 'running' })
let outcome: BailianAutofillStatus = 'failed'
try {
const fill = await this.postAutofill('fill') as { apiKey?: string, workspaceId?: string }
if (fill.apiKey === 'filled') {
outcome = 'done'
} else if (fill.apiKey === 'missing') {
// Nothing to adopt yet: start the console login that provisions the
// CLI's credential file, then have the user retry the button.
const login = await this.postAutofill('login') as { status?: string }
outcome = login.status === 'started' || login.status === 'already-running'
? 'loginStarted'
: login.status === 'not-found' ? 'blMissing' : 'failed'
}
// apiKey === 'failed' (a read-only source shadows the credential):
// fall through as 'failed' even when the workspace id was adopted.
} catch (_autofillFailure) {
outcome = 'failed'
}
this.store.update(draft => { draft.autofill = outcome })
await this.fetchSettings()
await this.read()
}
/**
* Remove the stored default service from every writable layer — the
* settings user layer AND the credential store, so the fallback chain does
@@ -312,9 +354,25 @@ export class BailianCardController {
save: () => this.save(),
discard: () => { this.discard() },
clearDefaultAgent: (key) => this.clearDefaultAgent(key),
autofill: () => this.autofill(),
}
}
/**
* Post one autofill action to the Host bridge route.
* @param action - `fill` adopts the CLI file; `login` starts the browser flow.
* @returns the route's JSON answer.
*/
private async postAutofill(action: 'fill' | 'login'): Promise<unknown> {
const resp = await fetch('/bailian-kb/autofill', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action }),
})
if (!resp.ok) throw new Error(`HTTP ${resp.status}`)
return resp.json()
}
/**
* Send a settings patch to the Host bridge route. `null`-valued keys are
* removals (the field falls back to the entry config and then the
+24 -8
View File
@@ -16,6 +16,8 @@ export type BailianKbLocaleKey =
| 'chatAgentId' | 'chatAgentIdHint' | 'chatAgentIdHintFallback' | 'chatAgentIdSet' | 'chatAgentIdUnset'
| 'fromEnv' | 'clear' | 'clearing'
| 'save' | 'saving' | 'discard' | 'unsaved' | 'saveFailed'
| 'autofill' | 'autofilling' | 'autofillHint'
| 'autofillDone' | 'autofillLoginStarted' | 'autofillBlMissing' | 'autofillFailed'
/** English copy. */
export const en: Record<BailianKbLocaleKey, string> = {
@@ -34,13 +36,13 @@ export const en: Record<BailianKbLocaleKey, string> = {
workspaceIdSet: 'A workspace is configured.',
workspaceIdUnset: 'No workspace is configured; knowledge tools fail until one is.',
retrieveAgentId: 'Default retrieval service id',
retrieveAgentIdHint: 'agent_id of the default retrieval service (kb_search); when unset, every call must name one (`kscli service list` discovers ids). Stored in the settings document.',
retrieveAgentIdHintFallback: 'agent_id of the default retrieval service (kb_search); when unset, every call must name one (`kscli service list` discovers ids). Leave blank to keep the current one.',
retrieveAgentIdHint: 'agent_id of the default retrieval service (kb_search); when unset, every call must name one (`bl knowledge service list` discovers ids). Stored in the settings document.',
retrieveAgentIdHintFallback: 'agent_id of the default retrieval service (kb_search); when unset, every call must name one (`bl knowledge service list` discovers ids). Leave blank to keep the current one.',
retrieveAgentIdSet: 'A default retrieval service is configured.',
retrieveAgentIdUnset: 'No default retrieval service; every kb_search call must name one.',
chatAgentId: 'Default chat service id',
chatAgentIdHint: 'agent_id of the default Q&A service (kb_chat); when unset, every call must name one (`kscli service list` discovers ids). Stored in the settings document.',
chatAgentIdHintFallback: 'agent_id of the default Q&A service (kb_chat); when unset, every call must name one (`kscli service list` discovers ids). Leave blank to keep the current one.',
chatAgentIdHint: 'agent_id of the default Q&A service (kb_chat); when unset, every call must name one (`bl knowledge service list` discovers ids). Stored in the settings document.',
chatAgentIdHintFallback: 'agent_id of the default Q&A service (kb_chat); when unset, every call must name one (`bl knowledge service list` discovers ids). Leave blank to keep the current one.',
chatAgentIdSet: 'A default chat service is configured.',
chatAgentIdUnset: 'No default chat service; every kb_chat call must name one.',
fromEnv: 'Set by the environment (read-only here)',
@@ -51,6 +53,13 @@ export const en: Record<BailianKbLocaleKey, string> = {
discard: 'Discard',
unsaved: 'Unsaved',
saveFailed: 'The Host did not accept these values; they were left for you to correct.',
autofill: 'Auto-fill from bl CLI',
autofilling: 'Fetching…',
autofillHint: 'Adopt the API key and workspace id stored by the bl CLI (~/.bailian/config.json on the host); starts a console browser login on the host when the CLI has none yet.',
autofillDone: 'Adopted the bl CLI login; the fields below reflect the new values.',
autofillLoginStarted: 'A Bailian console login was opened in a browser on the host machine — finish signing in there, then click again.',
autofillBlMissing: 'The bl CLI was not found on the host; install it with `npm install -g bailian-cli` and retry.',
autofillFailed: 'Auto-fill failed — the credential may be locked by an environment variable, or the Host refused the write.',
}
/** Simplified Chinese copy. */
@@ -70,13 +79,13 @@ export const zh: Record<BailianKbLocaleKey, string> = {
workspaceIdSet: '已配置工作空间。',
workspaceIdUnset: '未配置工作空间;配置前知识库工具不可用。',
retrieveAgentId: '默认检索服务 ID',
retrieveAgentIdHint: '默认检索服务(kb_search)的 agent_id;未设置时每次调用都需显式指定(可用 `kscli service list` 发现 id)。存入设置文档。',
retrieveAgentIdHintFallback: '默认检索服务(kb_search)的 agent_id;未设置时每次调用都需显式指定(可用 `kscli service list` 发现 id)。留空表示保持当前值。',
retrieveAgentIdHint: '默认检索服务(kb_search)的 agent_id;未设置时每次调用都需显式指定(可用 `bl knowledge service list` 发现 id)。存入设置文档。',
retrieveAgentIdHintFallback: '默认检索服务(kb_search)的 agent_id;未设置时每次调用都需显式指定(可用 `bl knowledge service list` 发现 id)。留空表示保持当前值。',
retrieveAgentIdSet: '已配置默认检索服务。',
retrieveAgentIdUnset: '未配置默认检索服务;每次 kb_search 调用需显式指定。',
chatAgentId: '默认对话服务 ID',
chatAgentIdHint: '默认对话服务(kb_chat)的 agent_id;未设置时每次调用都需显式指定(可用 `kscli service list` 发现 id)。存入设置文档。',
chatAgentIdHintFallback: '默认对话服务(kb_chat)的 agent_id;未设置时每次调用都需显式指定(可用 `kscli service list` 发现 id)。留空表示保持当前值。',
chatAgentIdHint: '默认对话服务(kb_chat)的 agent_id;未设置时每次调用都需显式指定(可用 `bl knowledge service list` 发现 id)。存入设置文档。',
chatAgentIdHintFallback: '默认对话服务(kb_chat)的 agent_id;未设置时每次调用都需显式指定(可用 `bl knowledge service list` 发现 id)。留空表示保持当前值。',
chatAgentIdSet: '已配置默认对话服务。',
chatAgentIdUnset: '未配置默认对话服务;每次 kb_chat 调用需显式指定。',
fromEnv: '来自环境变量(此处只读)',
@@ -87,4 +96,11 @@ export const zh: Record<BailianKbLocaleKey, string> = {
discard: '放弃',
unsaved: '未保存',
saveFailed: '宿主未接受这些值,已保留供你修改。',
autofill: '自动获取(bl CLI)',
autofilling: '获取中…',
autofillHint: '从宿主机 bl CLI 的登录态(~/.bailian/config.json)回填 API 密钥与工作空间 ID;CLI 尚未登录时会在宿主机拉起百炼控制台浏览器登录。',
autofillDone: '已回填 bl CLI 的登录信息,下方字段已更新。',
autofillLoginStarted: '已在宿主机浏览器打开百炼控制台登录页,完成登录后请再次点击。',
autofillBlMissing: '宿主机未安装 bl CLI;请先 `npm install -g bailian-cli` 再重试。',
autofillFailed: '自动获取失败——凭据可能被环境变量锁定,或宿主拒绝了写入。',
}
@@ -0,0 +1,41 @@
import { mkdtempSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { describe, expect, it } from 'vitest'
import { readBlCliConfig } from '../src/bl-cli.js'
const dir = mkdtempSync(join(tmpdir(), 'bl-cli-test-'))
function fileWith(name: string, content: string): string {
const path = join(dir, name)
writeFileSync(path, content)
return path
}
describe('readBlCliConfig', () => {
it('reads api_key and workspace_id from the default profile (top level)', () => {
const path = fileWith('full.json', JSON.stringify({
api_key: 'sk-abc',
workspace_id: 'ws-1',
output: 'text',
timeout: 600,
}))
expect(readBlCliConfig(path)).toEqual({ apiKey: 'sk-abc', workspaceId: 'ws-1' })
})
it('omits absent, blank, and non-string fields instead of returning empties', () => {
const path = fileWith('partial.json', JSON.stringify({
api_key: ' ',
workspace_id: 42,
}))
expect(readBlCliConfig(path)).toEqual({})
const keyOnly = fileWith('key-only.json', JSON.stringify({ api_key: 'sk-abc' }))
expect(readBlCliConfig(keyOnly)).toEqual({ apiKey: 'sk-abc' })
})
it('reads a missing, malformed, or non-object file as empty', () => {
expect(readBlCliConfig(join(dir, 'nope.json'))).toEqual({})
expect(readBlCliConfig(fileWith('broken.json', '{oops'))).toEqual({})
expect(readBlCliConfig(fileWith('array.json', '["sk-abc"]'))).toEqual({})
})
})
@@ -16,4 +16,9 @@ describe('Config', () => {
expect(resolved.workspaceId).toBeUndefined()
expect(resolved.endpointHost).toBe('cn-beijing.maas.aliyuncs.com')
})
it('carries the bl-CLI seed ledger through validation', () => {
const resolved = new Config({ seededFields: ['apiKey'] } as never)
expect(resolved.seededFields).toEqual(['apiKey'])
})
})