docs: bilingual config-plane documentation, regenerated catalogs, and the web-config-plane Agent Note
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
README.md: 80228a180faba0c556ff720e999b29b5bb1635b6
|
||||
README.zh.md: f4b857886bfafa891ceb1bd6b79b27e1fb725819
|
||||
# pnpm run verify-translation-pairing --write packages/client/connection/README.md
|
||||
README.md: 3c3aad6e74b567fdf57f8dbf425024d99f4a3467
|
||||
README.zh.md: 4a2a38a975960a81056ef672901b44367c485e19
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
Wire consumer layer: the client plugin's apply mounts `ctx.connection` (shared api client + single-consumer stream-loop starter); the export face carries the wire contract types, the `AbstractApiClient` seam, and the loop's sink/config types. The platform subclasses (WebApiClient/FixtureApiClient), the ConnectionController loop, and the fixture data source are package-internal — apply selects and drives them; tests reach them via src. Contract: api-contracts v3 §3.
|
||||
Wire consumer layer: the client plugin's apply mounts `ctx.connection` (shared api client + single-consumer stream-loop starter); the export face carries the wire contract types, the `AbstractApiClient` seam, and the loop's sink/config types. The node half's `/api` route guards the privileged method set (`host.pickDirectory`, `host.openPath`, `settings.update`, `settings.replace`, `credentials.set`, `credentials.unset`) behind the loopback same-origin check — under `--host 0.0.0.0` reads stay reachable, writes stay browser-local until a real authentication layer exists. The platform subclasses (WebApiClient/FixtureApiClient), the ConnectionController loop, and the fixture data source are package-internal — apply selects and drives them; tests reach them via src. Contract: api-contracts v3 §3.
|
||||
|
||||
## Keyless fixture
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
协议消费层:客户端插件的 apply 会挂载 `ctx.connection`(共享 API 客户端 + 单消费方流循环启动器);导出表层携带协议契约类型、`AbstractApiClient` seam,以及循环的 sink/配置类型。平台子类(WebApiClient/FixtureApiClient)、ConnectionController 循环和 fixture 数据源都属于包内部:apply 负责选择并驱动它们,测试则通过 src 访问。契约:api-contracts v3 §3。
|
||||
协议消费层:客户端插件的 apply 会挂载 `ctx.connection`(共享 API 客户端 + 单消费方流循环启动器);导出表层携带协议契约类型、`AbstractApiClient` seam,以及循环的 sink/配置类型。node 半侧的 `/api` 路由把特权方法集(`host.pickDirectory`、`host.openPath`、`settings.update`、`settings.replace`、`credentials.set`、`credentials.unset`)挡在回环同源检查之后——在 `--host 0.0.0.0` 下读取仍然可达,写入在真正的认证层出现之前仍只限本机浏览器。平台子类(WebApiClient/FixtureApiClient)、ConnectionController 循环和 fixture 数据源都属于包内部:apply 负责选择并驱动它们,测试则通过 src 访问。契约:api-contracts v3 §3。
|
||||
|
||||
## 无密钥 fixture
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/client/runtime/README.md
|
||||
README.md: 25eb60e2c95059ae918669c9f5169b6b8e9c6816
|
||||
README.zh.md: e3085f91750503aeaffda41d86c40c62943b4ba9
|
||||
README.md: 3f1efa14d19ded0a8fd3d27b28836cdeb6798f31
|
||||
README.zh.md: 4ba7433973d98848503a9d08766d3ecfac0840e4
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
Client cordis boot and React-free object services: SlotsService wraps SlotCore and supplies renderer data sources; SessionsService owns Session objects, list/scope/history state; WorkspacesService depends on SessionsService and owns Workspace objects, list/actions, default-target derivation, and the New Session blank-reuse entry (`connectWorkspace`). The runtime fans the shared Host stream into both managers. Client sessions are always Host-born (Session+Agent+cwd in one `session.create`); the client holds no pre-entity session state — a session's Agent scope (the client mirror of host dsh-scope, keyed by the shared agent/session id) is born when its row enters the list mirror and dies with the prune. Contract: api-contracts v3 §4. Each `Session` holds a generic `ProjectionValueStore` seeded from the history-tail `projections` block and updated by `session/projection` frames under higher-seq-wins; domain keys (including `todos`) are read via `projections.faceOf` / `useProjection`, not via `ConversationSnapshot`.
|
||||
Client cordis boot and React-free object services: SlotsService wraps SlotCore and supplies renderer data sources; SessionsService owns Session objects, list/scope/history state; WorkspacesService depends on SessionsService and owns Workspace objects, list/actions, default-target derivation, and the New Session blank-reuse entry (`connectWorkspace`). The runtime fans the shared Host stream into both managers, and bridges the registry-invalidation frames to typed ctx events (`commands/changed`, `settings/changed`, `credentials/changed`, `models/changed`) so surface caches refetch without touching the stream. Client sessions are always Host-born (Session+Agent+cwd in one `session.create`); the client holds no pre-entity session state — a session's Agent scope (the client mirror of host dsh-scope, keyed by the shared agent/session id) is born when its row enters the list mirror and dies with the prune. Contract: api-contracts v3 §4. Each `Session` holds a generic `ProjectionValueStore` seeded from the history-tail `projections` block and updated by `session/projection` frames under higher-seq-wins; domain keys (including `todos`) are read via `projections.faceOf` / `useProjection`, not via `ConversationSnapshot`.
|
||||
|
||||
## Workspace and Session lists
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
客户端 cordis 启动与不依赖 React 的对象服务:SlotsService 包装 SlotCore 并提供 renderer 数据源;SessionsService 拥有 Session 对象、列表/scope/history 状态;WorkspacesService 依赖 SessionsService,拥有 Workspace 对象、列表/操作、默认目标派生,以及 New Session 空会话复用入口(`connectWorkspace`)。运行时把共享 Host 流分发给两个 manager。客户端 Session 一律由 Host 出生(一次 `session.create` 同瞬产出 Session+Agent+cwd);客户端不持有任何实体化之前的会话状态——Agent scope(host dsh-scope 的客户端镜像,以 agent/session 共用 id 为键)在会话行进入列表镜像时出生,随 prune 死亡。契约:api-contracts v3 §4。每个 `Session` 持有一个通用的 `ProjectionValueStore`,由历史尾页的 `projections` 块播种,并经 `session/projection` 帧按 seq 高者胜更新;领域键(含 `todos`)经 `projections.faceOf`/`useProjection` 读取,不经 `ConversationSnapshot`。
|
||||
客户端 cordis 启动与不依赖 React 的对象服务:SlotsService 包装 SlotCore 并提供 renderer 数据源;SessionsService 拥有 Session 对象、列表/scope/history 状态;WorkspacesService 依赖 SessionsService,拥有 Workspace 对象、列表/操作、默认目标派生,以及 New Session 空会话复用入口(`connectWorkspace`)。运行时把共享 Host 流分发给两个 manager,并把注册表失效帧桥接为类型化 ctx 事件(`commands/changed`、`settings/changed`、`credentials/changed`、`models/changed`),使各表面缓存无需触碰流即可重拉。客户端 Session 一律由 Host 出生(一次 `session.create` 同瞬产出 Session+Agent+cwd);客户端不持有任何实体化之前的会话状态——Agent scope(host dsh-scope 的客户端镜像,以 agent/session 共用 id 为键)在会话行进入列表镜像时出生,随 prune 死亡。契约:api-contracts v3 §4。每个 `Session` 持有一个通用的 `ProjectionValueStore`,由历史尾页的 `projections` 块播种,并经 `session/projection` 帧按 seq 高者胜更新;领域键(含 `todos`)经 `projections.faceOf`/`useProjection` 读取,不经 `ConversationSnapshot`。
|
||||
|
||||
## Workspace 与 Session 列表
|
||||
|
||||
|
||||
6
packages/client/schema-form/README.i18n.yaml
Normal file
6
packages/client/schema-form/README.i18n.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/client/schema-form/README.md
|
||||
README.md: d6819ccf29cf58667d518c43c43b875eb20e02e9
|
||||
README.zh.md: 2f2e07d41db2af5f0afc3352072e7d49129ce6f2
|
||||
30
packages/client/schema-form/README.zh.md
Normal file
30
packages/client/schema-form/README.zh.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# @deepseek-ai/dsh-client-schema-form
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
面向 settings 分节的 schema 驱动 React 表单渲染器。wire 侧的 `settings.describe` 携带每个 namespace 的序列化 schemastery schema(`schema.toJSON()` 的 ref 信封);`SchemaForm` 用 `new Schema(json)` 将其还原(rehydrate),并把每个已声明的字段渲染为可编辑控件——在宿主上校验分节的那份 schema 对象,就是在浏览器里校验并驱动表单的那份对象,因此不存在第二份会漂移的表单定义。
|
||||
|
||||
## 契约
|
||||
|
||||
`SchemaForm` 是围绕**用户分节草稿**的受控组件:`draft` 是正在编辑的对象(绝不被原地修改;每次编辑都以新的根对象调用 `onChange`),`fallback` 则是用于展示继承值的解析值(schema 默认值 → 组合 base → 用户层)。字段只要出现在草稿中就被标记为**已覆盖**,并显示一个删除该键、回退到继承层的逐字段 Reset——判定采用存在性语义而非值比较,与 settings seam 的分层方式严格对应。
|
||||
|
||||
控件按 schema 节点分派:`object` → 带标签的字段组(渲染 JSDoc `description`,`required` 字段加星标);`string`/`number`/`boolean` → 以继承值为占位符的输入框;字面量 `union` → 下拉框,空选项表示「继承」;`array` → 按位置排列、可增删的行(数组在写入时整体替换);`dict` → 按键排列的行,其中联合类型的 `sKey` 成为「新增」下拉框的词汇。`role('secret')` 渲染为**只写**的密码输入框:已存储的值永远不会送达(wire 会剥除它),占位状态由 `secrets` 槽位列表(`{path, set}`)提供。渲染器无法忠实编辑的节点(非字面量联合、转换(transform)节点)渲染为带提示的只读 JSON 视图,而不是直接消失——schema 字段绝不会被静默丢弃。
|
||||
|
||||
`renderField(context)` 是感知角色的覆盖钩子:返回一个节点,即可替换单个叶子字段的默认控件。Models 设置页用它挂载与 `credentials.*` 通信的凭据引用控件(`role('credential-ref')`)——该包(package)自身始终不接触 wire,也没有副作用。
|
||||
|
||||
`validateDraft(schema, draft)` 运行还原出的校验器并返回其失败消息,页面因此可以先校验再写入;路径辅助函数(`getPath`/`hasPath`/`setPath`/`deletePath`)对外暴露的不可变草稿编辑,与控件内部使用的是同一套。
|
||||
|
||||
## Model Experience
|
||||
|
||||
无。该包渲染的是浏览器配置表单;这里没有任何内容进入模型请求。
|
||||
|
||||
#### KV Cache effect
|
||||
|
||||
无;该包既不组装也不发送提供方请求。
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **校验是表单级的,而非逐字段**——`validateDraft` 报告 schemastery 的第一条失败消息(其中会点名 `$.path`);逐字段的内联报错展示延后到出现需要它的第二个消费方再做。
|
||||
- **字符串内置为英文**——`labels` prop 可以覆盖每一条用户可见字符串,但包内没有接入语言环境词典的接线;本地化归嵌入它的页面所有。
|
||||
- **非字面量联合与转换节点只读渲染**——忠实编辑这些形状需要逐形状的控件;目前它们回退为带提示的 JSON 视图。
|
||||
- **数组编辑整体替换**——settings seam 同样不存在元素级合并;表单如实呈现该契约,而不是把它藏起来。
|
||||
@@ -1,6 +1,6 @@
|
||||
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
README.md: 13f51d5338affd65d0705cec6a3b4ef78a534f0f
|
||||
README.zh.md: 466505beb27c729246afe04e6378235b91d072cf
|
||||
# pnpm run verify-translation-pairing --write packages/client/ui-models/README.md
|
||||
README.md: 5bcfdcdbfe31ada89f787cd4d193e9763dba94d3
|
||||
README.zh.md: 84b4b2187851506697de635d56691ca7e988ea00
|
||||
|
||||
@@ -2,11 +2,15 @@
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
Models settings section plugin: registers the `models` nav entry into `settings.section` with an intentionally empty content column — model management lands in a later phase.
|
||||
Models settings section plugin: the provider configuration page. It joins three wire domains into one surface — `llm.providers` (the configurable-provider directory with each route's live/dormant state), `settings.describe` (serialized schemas, layered redacted values, secret slots), and `credentials.describe` (value-free configured/source/writable badges) — and renders provider rows with one editor card at a time.
|
||||
|
||||
Rows are the *configured* providers (their profile resolves in the owning namespace); the add select's vocabulary is every dormant directory entry, so a bare-mounted `llm-pi-ai` offers its whole installed catalog before any route exists. The editor renders the provider's profile subtree through [`@deepseek-ai/dsh-client-schema-form`](../schema-form); the `credential-ref` role mounts the credential control, which shows the reference's live state and stores key values **write-only** through `credentials.set` — no value ever renders back. A row is deletable only when the user layer alone carries it (removal restores the composition base).
|
||||
|
||||
Apply semantics mirror the settings seam: an edit without removals lands as a minimal `settings.update` merge patch (stored secrets outside the patch survive), while a field reset or row deletion lands through `settings.replace` of the whole user section so removals actually take effect. The page refetches on the pushed invalidations (`settings/changed`, `credentials/changed`, `models/changed`, and `connection/reset`) once it has loaded, so an external `settings.yaml` edit, a second tab, or a settings-born route converges without polling.
|
||||
|
||||
## Model Experience
|
||||
|
||||
None, as the section renders an empty browser UI column; nothing here reaches a model request.
|
||||
None, as the section renders a browser configuration UI; nothing here reaches a model request.
|
||||
|
||||
#### KV Cache effect
|
||||
|
||||
@@ -14,4 +18,6 @@ None; this package neither assembles nor sends a provider request.
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
- **Content column is empty by design** — provider list, editing form, and activation flow are deferred until the model-management service exists.
|
||||
- **A reset can drop a stored literal secret in the same subtree** — a replace-carried removal cannot re-supply secrets the wire never returned; store keys behind `credentials.*` references (the product default) and the case cannot arise.
|
||||
- **No per-provider model listing on the page** — the picker surfaces models; this page shows route state only. A models preview per row is deferred until a consumer needs it.
|
||||
- **Undeclared live routes render nowhere** — a route registered without a configurable-provider declaration has no settings address; it stays visible in pickers but not on this page's rows.
|
||||
|
||||
@@ -2,11 +2,15 @@
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
模型设置分区插件:注册 `models` 导航项,使其进入 `settings.section`;内容栏有意留空,模型管理将在后续阶段实现。
|
||||
模型设置分区插件:提供方配置页。它把三个协议领域汇聚为一个界面——`llm.providers`(可配置提供方目录,含每条路由的存活/休眠状态)、`settings.describe`(序列化 schema、分层脱敏值、secret 槽位)与 `credentials.describe`(不含值的 configured/source/writable 徽标)——并渲染提供方行,一次只展开一张编辑卡片。
|
||||
|
||||
行是*已配置*的提供方(其 profile 在所属 namespace 中解析得出);新增选择框的词汇是全部休眠目录条目,因此裸挂载的 `llm-pi-ai` 在任何路由存在之前就能提供其完整的已安装 catalog。编辑器经 [`@deepseek-ai/dsh-client-schema-form`](../schema-form) 渲染该提供方的 profile 子树;`credential-ref` 角色会挂载凭据控件,它展示该引用的实时状态,并经 `credentials.set` 以**只写**方式存入密钥值——任何值都绝不回显。只有当某行仅由用户层承载时它才可删除(删除会还原组合 base)。
|
||||
|
||||
「应用」语义与 settings seam 呈镜像:不含删除的编辑以最小的 `settings.update` 合并 patch 落地(patch 之外已存储的 secret 得以保留),字段重置或整行删除则经对整个用户分节的 `settings.replace` 落地,使删除真正生效。页面加载完成后会在推送的失效事件(`settings/changed`、`credentials/changed`、`models/changed` 与 `connection/reset`)上重拉,因此外部的 `settings.yaml` 编辑、第二个标签页或 settings 新生的路由都无需轮询即可收敛。
|
||||
|
||||
## 模型体验
|
||||
|
||||
无。该分区渲染空白的浏览器 UI 内容栏;这里没有任何内容进入模型请求。
|
||||
无。该分区渲染浏览器配置 UI;这里没有任何内容进入模型请求。
|
||||
|
||||
#### KV Cache 影响
|
||||
|
||||
@@ -14,4 +18,6 @@
|
||||
|
||||
## 已知限制与暂缓事项
|
||||
|
||||
- **内容栏按设计留空**:提供方列表、编辑表单和激活流程均暂缓,待模型管理服务就绪后实现。
|
||||
- **重置可能丢弃同一子树中已存储的字面 secret**:经 replace 承载的删除无法重新提供协议从未返回过的 secret;把密钥放在 `credentials.*` 引用背后(产品默认做法),该情形便不会出现。
|
||||
- **页面上没有逐提供方的模型列表**:模型由选择器呈现;本页只展示路由状态。逐行的模型预览暂缓,待有消费方需要时再实现。
|
||||
- **未声明的存活路由无处渲染**:未附带可配置提供方声明即注册的路由没有 settings 地址;它在各选择器中仍然可见,但不会出现在本页的行里。
|
||||
|
||||
Reference in New Issue
Block a user