Clicking a welcome card used to POST /bailian/console and render the raw
feature result inline — a dead end: the user saw a summary with no way to
follow up, and the agent never learned the question was asked.
Now each feature declares a `query` (natural-language phrasing) and the
card drops it into the conversation input, then submits. The agent routes
it to the matching tool itself, can AskUserQuestion for missing params,
and the whole exchange stays in the transcript where the user can ask
follow-ups. This removes the inline result panel and its loading state.
Drop the `apikey` feature: it only echoed a masked key, which the settings
page already shows. `bl token-plan personal-key` stays as a CLI command.
Co-Authored-By: Claude <noreply@anthropic.com>
Add a feature catalog (`packages/dsh/src/features.ts`) that drives two entry
points from one declaration: a model tool per feature (natural-language
entry) and a card-click webServer route (UI entry). Each feature declares
its `bl` argv, optional parameter flags, and a `summarize` projection, so
adding a capability means adding one catalog entry rather than wiring a
tool and a route separately.
New CLI commands backing the TokenPlan usage panel:
- `bl token-plan personal-usage` — 5h/1w usage percentage, subscription
state, and addon credits, unwrapping the console gateway's nested
`data.DataV2.data.data` envelope.
- `bl token-plan personal-key` — the masked personal-edition API key.
Both are `auth: "console"` and registered per the command checklist
(library export, `bl` product map, e2e topic routes, generated reference).
Two type fixes in the tool registration path:
- The parameter map was typed `Record<string, { type: string; ... }>`,
which widens `FeatureParam["type"]` to `string` and is then unassignable
to `ParameterSchemaSpec` (it needs the literal union). Keep the literal.
- `invokeFeature` returned `Promise<unknown>`, so the tool's `{ summary,
data }` value failed `Record<string, JsonValue>`. It parses
`bl --output json` output, so its return type is `JsonValue` — narrowing
the signature is more honest than casting at the call site.
Co-Authored-By: Claude <noreply@anthropic.com>
- Updated build process to include a new script for building the client bundle in ModuleLoader format.
- Introduced `build-client.mjs` to handle client-side bundling with esbuild.
- Added `client.ts` to implement the DSH web UI, including settings and usage pages.
- Registered new settings section for managing credentials and token usage.
- Refactored API routes to remove `/api` prefix for consistency.
- Cleaned up Vite configuration by removing unused client entry.
- Deleted the `tool-image`, `tool-managed-agent`, `tool-vision`, and `web-search-rag` modules from the codebase.
- Updated the Vite configuration to remove entries for the deleted tools and added a new entry for `tokenplan-usage`.
- Adjusted tests to reflect the removal of TokenPlan key handling logic from the now-deleted tools.
- 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.
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>
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>