Skip to content

feat(dsh): 新增 bailian-cli-dsh 插件包,并修复 bl memory 与 v2 API 的偏差 - #159

Open
lishengzxc wants to merge 3 commits into
mainfrom
feat/bailian-cli-dsh
Open

feat(dsh): 新增 bailian-cli-dsh 插件包,并修复 bl memory 与 v2 API 的偏差#159
lishengzxc wants to merge 3 commits into
mainfrom
feat/bailian-cli-dsh

Conversation

@lishengzxc

Copy link
Copy Markdown
Contributor

背景

DeepSeek Harness(dsh)是「万物皆插件」的 Cordis 架构 agent harness,暴露了若干真正可插拔的 service seam。本 PR 把百炼的能力接到这些 seam 上,并顺带修掉 bl memory 与长期记忆 v2 API 之间的偏差。

新增 packages/dshbailian-cli-dsh

单包 + 6 个 subpath 入口 + 一个 dsh.bundle patch。默认启用前三项,后三项需要部署方特有的资源 ID 或按次计费,故默认停用。

row 能力 默认
llm-pi-ai(覆盖) TokenPlan 注册为 LLM provider 启用
bailian-tool-vision bailian_vision_describe(图片/视频) 启用
bailian-tool-image bailian_image_generate 启用
bailian-web-search-rag 知识库检索接入 web_search 停用
bailian-memory 跨会话长期记忆 停用
bailian-subagent-managed-agent 子 agent 跑百炼托管运行时 停用

调用方式是混合的:managed-agent 与 image/vision 走 bl 子进程(复用它的轮询、下载、SSE、agents.yaml 解析),memory 与 RAG 直连 HTTP(v2 API 有一批 CLI 没暴露的参数)。

用法见 packages/dsh/README.md

实测得到的三个非显然结论

1. 不能挂第二个 pi-ai 实例。 最初的做法是新起一个 row id 再挂一个 dsh-llm-pi-ai,理由是 registerAdapter 只在重复 route 时报错。实际启动直接失败:

LlmError: configurable provider "amazon-bedrock" is already declared

pi-ai 每次 apply 都会把自己内建的整个 provider 目录注册到 ctx.llm.registerConfigurableProviders,而那个目录是全局的。只有 adapter route 是按实例隔离的。所以改成覆盖 base bundle 已有的 llm-pi-ai 行——它在 base 里是空配置挂载的,整体替换不丢东西。

2. 模型清单和视觉能力是逐个探出来的,不是照文档抄的。 TokenPlan 网关 GET /models 返回 11 个模型,文档里提到的 qwen3-vl-plus 并不存在。用一张纯色 PNG 逐个问颜色:

模型 读图
qwen3.8-max / qwen3.7-plus / qwen3.6-flash / glm-5.2
qwen3.7-max 否,传图直接 400
deepseek-v4-pro / deepseek-v4-flash-0731 否,不报错但答 "None"

DeepSeek 那两个是静默失明。所以它们故意不声明 input: [text, image]——声明了会把「明确拒绝」退化成「静默错答」,更难排查。这也正是 bailian_vision_describe 存在的理由:它返回文字,绕过 dsh 的模态门禁(api-proxy 粘图预检和 read_image 都在 agent/pre-step 之前拦截,纯文本路由下图片根本进不了对话)。

3. plan_version 是失效的,计费差 50 倍。

请求 实际 billing_plan
plan_version: "lite" pro
enable_rerank: false lite
什么都不传 pro

文档说 plan_version 优先级高于 enable_rerank,实际单独传 lite 会被忽略。CLI flag 和 memory 插件现在都下发真正生效的那个参数。

修复 bl memory(均已线上验证)

两处偏差都是 CLI 的 bug,不是文档过时:

  • profile get 是坏的:走 /profiles 返回 HTTP 500 InternalError,正确路径是 /user_profile
  • add 的返回字段读错:读 response.memory_ids,服务端实际返回 memory_nodes,导致文本模式恒打印 Memory added. IDs: none
  • 附带两个类型错误:MemoryNode.created_at/updated_at 是秒级数字不是字符串;UserProfileResponse.profile 的字段名与实际报文完全对不上

补齐 v2 API 缺失的面:

  • 参数:--meta-data --project-id --project-ids --min-score --enable-rerank --plan-version --enable-judge --enable-rewrite --timestamp
  • 命令:memory profile list|detail|update|delete(v2 的四个 profile-schema 操作原先全缺)

memory profile detail 会打印 attribute_id,那是 profile update 定位属性的必需键。

工程改动

pnpm-workspace.yaml 关闭 autoInstallPeers@deepseek-ai/dsh-* 的 rc 依赖图 peer 了三个从未发布到 npm 的包(dsh-type-meta / dsh-environment / dsh-tasks),开着的话整个 workspace 装不上。已验证既有包构建不受影响。

依赖统一钉 ^0.1.0-rc.6 —— npm 的 latest tag 指向残缺的 0.0.1-rc.1 线,而 0.1.0-rc.6 才是与 @deepseek-ai/dsh@0.1.0-rc.6 配套的版本。

验证情况

已真实调用验证

  • bl vision describe:本地 PNG → content: "Blue",插件的 readContent() 取的正是该字段
  • memory 全链路:profile create/list/detail/get/update/delete + add/search/delete,逐个跑通并清理干净
  • --enable-rerank false → 响应 billing_plan: "lite"
  • 全仓 vp check 0 error(3 个 warning 是既有代码的)
  • 6 个入口构建 + pnpm pack 产物结构正确

未验证

  • RAG provider 与 managed-agent subagent:本机没有可用知识库和 agents.yaml,只做了类型与打包验证
  • memory.e2e.test.ts 有 1 个 live 测试失败,原因是它硬编码了别属账号的记忆库 ID(memoryLibraryId does not exist),与本次改动无关;可用 BAILIAN_E2E_MEMORY_LIBRARY_ID 覆盖

待确认

packages/dsh 尚未纳入 tools/release/lib/packages.mjs 的发布清单,目前只能本地 pnpm pack 安装。是否要纳入发版流程请评审时定。

🤖 Generated with Claude Code

lishengzxc and others added 3 commits August 15, 2026 01:47
Expose Bailian capabilities to dsh through its service seams as one
package with six subpath plugin entries and a `dsh.bundle` patch:

- TokenPlan as an LLM provider
- bailian_vision_describe / bailian_image_generate tools over `bl`
- knowledge-base retrieval as a WebSearchProvider (`bailian-kb`)
- cross-session memory: tools, pre-step recall, turn-close persist
- managed-agent as a SubagentProvider

TokenPlan configures the base bundle's existing pi-ai row rather than
mounting a second `dsh-llm-pi-ai` instance. A second instance cannot
work: pi-ai re-declares its entire built-in provider catalog to
`registerConfigurableProviders`, and that directory is global, so boot
fails with a duplicate on `amazon-bedrock`.

Routes and vision support were probed against the live gateway.
qwen3.8-max, qwen3.7-plus, qwen3.6-flash and glm-5.2 read images;
qwen3.7-max rejects them with HTTP 400; the DeepSeek routes accept image
content without erroring yet stay blind. The DeepSeek entries therefore
do not declare image input — claiming it would turn a clean refusal into
a silently wrong answer — and `bailian_vision_describe` serves them by
returning text instead.

Also fix `bl memory` against the v2 API, each verified live:

- `profile get` used /profiles, which returns HTTP 500. The documented
  and working endpoint is /user_profile.
- `add` read `response.memory_ids`, which the service never returns. It
  returns `memory_nodes`, so text output always printed "IDs: none".
- `MemoryNode.created_at`/`updated_at` are unix seconds, not strings, and
  `UserProfileResponse.profile` did not match the wire shape.
- Add the missing request parameters: --meta-data, --project-id,
  --project-ids, --min-score, --enable-rerank, --plan-version,
  --enable-judge, --enable-rewrite, --timestamp.
- Add `memory profile list|detail|update|delete`, covering the four v2
  profile-schema operations the CLI was missing.

`plan_version: lite` is ignored by the service and still bills pro;
`enable_rerank: false` is what actually selects lite, which is ~50x
cheaper per search. The CLI flag and the memory plugin both send the
parameter that works.

Disable pnpm's autoInstallPeers: the @deepseek-ai/dsh-* rc line peers on
three packages that were never published to npm, which 404s the whole
workspace install. Verified the existing packages still build.

Co-Authored-By: Claude <noreply@anthropic.com>
Rework the managed-agent integration so a dsh user can, in plain
language, have a Bailian cloud agent created and run a task — no
hand-written agents.yaml, no prior apply.

New `bl managed-agent run --prompt <task> [--instructions] [--model]
[--agent]`: one step that idempotently materializes a cloud agent + its
environment, then opens a session and streams the result. It mirrors the
OpenAgentPack webui backend's ensure+run recipe (resolveProjectConfigFrom
Object → syncAgentResourcesWithStateBackend → readProjectRuntime +
startSessionRun) from an in-memory config, reusing the existing
credential spine in _engine/credentials.ts. State persists under the bl
config dir (~/.bailian/managed-agent/<agent>/), never the user's cwd, so
repeat runs with the same --agent reuse the materialized agent. Unlike
apply it provisions without --yes, since running is the intent.

dsh side: replace the SubagentProvider with a plain tool
`bailian_run_remote_task` (packages/dsh/src/tool-managed-agent). The
subagent seam did not fit: in the web profile every tool-subagent row is
disabled in the host plane (delegation lives in agent presets), a
provider fixes one agent identity in config, and the default numeric
maxDepth would fail-mount a no-depthLimit provider. As a tool the model
calls it directly and fills `instructions` from the user's intent, so the
remote agent's role is defined per task. Enabled by default — it creates
nothing at load, only on invocation.

LLM row: configure the base bundle's existing llm-pi-ai row instead of
mounting a second pi-ai instance (a second instance re-declares pi-ai's
global configurable-provider catalog and fails boot on a duplicate
amazon-bedrock). TokenPlan reads a dedicated BAILIAN_TOKENPLAN_API_KEY,
not DASHSCOPE_API_KEY: TokenPlan (sk-sp-) and pay-as-you-go (sk-ws-) keys
401 each other's endpoints, so sharing one var would silently break
whichever plugin lost.

Note: the ensure+run happy path could not be verified end-to-end on the
available account — agentstudio returns 404 there, and the existing
`managed-agent apply` 404s identically against the same endpoint/key, so
the failure is account/service provisioning, not this change. Command
wiring, dry-run, config assembly, credential injection and URL
construction were all verified.

Co-Authored-By: Claude <noreply@anthropic.com>
- Updated README.md to clarify API key usage and access restrictions for TokenPlan and pay-as-you-go keys.
- Introduced shared credential validation logic to prevent TokenPlan keys from being used in incompatible contexts.
- Enhanced error messaging for credential resolution failures in managed-agent and memory plugins.
- Added tests for credential classification and workspace endpoint composition.
- Updated documentation to reflect changes in credential handling and workspace-scoped agentstudio endpoint requirements.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant