mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
refactor(credentials,llm): remove speculative mutation and route lifecycle
This commit is contained in:
@@ -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 docs/core-data-structures/core.md
|
||||
core.md: 09b437a8483134230d4b941c20940c5655bc53f0
|
||||
core.zh.md: 2025707db397203dbaec52c59172f83367f2033e
|
||||
core.md: fa313fee4f29c79ae0713b156ed248cca7285e21
|
||||
core.zh.md: be604b24474f2308ddb31d50ae88b73e6aaa4084
|
||||
|
||||
@@ -25,7 +25,7 @@ Everything else is documented on a **sub-page**, not here. The rule that draws t
|
||||
| [session.md](session.md) | the full `SessionEventMap` variant catalog, `TurnTrigger`/`TurnEndReason`, `deriveMessages()`, execution enclosure, and standalone events |
|
||||
| [persistence.md](persistence.md) | the durability seam: `SessionPersistence`, JSONL + SQLite backends, `session/flush`, crash recovery, `SessionHeader` |
|
||||
| [settings.md](settings.md) | the user-settings seam: `SettingsNamespace` registration, layered resolution (defaults → composition `base` → user document), owner scopes, hot commits |
|
||||
| [credentials.md](credentials.md) | the credential seam: `CredentialRef` references (never values) in configuration, per-operation resolution, UI-safe `CredentialInfo`, provider source layers |
|
||||
| [credentials.md](credentials.md) | the read-only credential seam: `CredentialRef` references and per-operation value resolution |
|
||||
| [session-query.md](session-query.md) | logical records, bounded exact-event reads, relationship traces, semantic filters/documents, and full-text result pages |
|
||||
| [session-title.md](session-title.md) | durable title snapshots, source provenance, and the asynchronous provider contract |
|
||||
| [system-prompt.md](system-prompt.md) | per-assembly context, tool-provider results, prompt sections, and cooperative assembly |
|
||||
@@ -183,33 +183,7 @@ Source: [`packages/llm/llm/src/types.ts`](../../packages/llm/llm/src/types.ts)
|
||||
|
||||
Provider and model discovery uses small provider-neutral descriptors. A model catalog is advisory: routing still keys on a registered provider, and an adapter may accept unlisted model ids.
|
||||
|
||||
Registering an adapter returns a handle: the disposer, plus the atomic route replacement a plugin whose route set is user-configurable needs.
|
||||
|
||||
```ts type-equiv
|
||||
/**
|
||||
* What {@link LlmService.registerAdapter} returns: the disposer, plus an
|
||||
* atomic route replacement for the same adapter instance.
|
||||
*/
|
||||
interface AdapterRegistrationHandle {
|
||||
/** Release every route this registration currently holds. */
|
||||
(): void
|
||||
/**
|
||||
* Replace this registration's routes with `providers`, keeping the same
|
||||
* adapter instance. The candidate set is validated in full first — a
|
||||
* conflict with another adapter, an invalid name, or bad provider metadata
|
||||
* throws and leaves the current routes untouched — and the swap itself is
|
||||
* one synchronous section, so no request can observe a gap. An empty array
|
||||
* is legal here (a settings section that emptied holds zero routes while
|
||||
* staying registered), unlike an empty initial registration.
|
||||
*
|
||||
* Throws `LlmError` with code `REGISTRATION_DISPOSED` once the registration
|
||||
* has been released: its routes are gone and its disposer has already run,
|
||||
* so anything registered afterwards would have no owner left to release it.
|
||||
* @param providers - the complete next route set for this registration.
|
||||
*/
|
||||
replace(providers: string[]): void
|
||||
}
|
||||
```
|
||||
Registering an adapter binds one non-empty provider-route set to the calling fiber and returns its disposer. Routes are composition-owned rather than mutable user settings.
|
||||
|
||||
```ts type-equiv
|
||||
/** Display metadata for one registered provider route. */
|
||||
|
||||
@@ -25,7 +25,7 @@ harness 是一个微内核:一个极小的核心加上众多插件。大多数
|
||||
| [session.md](session.md) | 完整的 `SessionEventMap` 变体目录、`TurnTrigger`/`TurnEndReason`、`deriveMessages()`、执行封闭与独立事件 |
|
||||
| [persistence.md](persistence.md) | 持久性 seam:`SessionPersistence`、JSONL + SQLite 后端、`session/flush`、崩溃恢复、`SessionHeader` |
|
||||
| [settings.md](settings.md) | 用户设置 seam:`SettingsNamespace` 注册、分层解析(默认值 → 组合 `base` → 用户文档)、owner scope、热提交 |
|
||||
| [credentials.md](credentials.md) | 凭据 seam:配置中的 `CredentialRef` 引用(绝不含值)、按操作解析、对 UI 安全的 `CredentialInfo`、provider 来源层 |
|
||||
| [credentials.md](credentials.md) | 只读凭据 seam:`CredentialRef` 引用与按操作解析值 |
|
||||
| [session-query.md](session-query.md) | 逻辑记录、有界精确事件读取、关系追踪、语义筛选器/文档与全文检索结果页 |
|
||||
| [session-title.md](session-title.md) | 持久标题快照、来源 provenance 与异步提供方契约 |
|
||||
| [system-prompt.md](system-prompt.md) | 逐次组装的上下文、工具提供方结果、提示词段落与协作式组装 |
|
||||
@@ -189,33 +189,7 @@ interface MessageSourceMap {
|
||||
|
||||
提供方与模型发现使用小型、提供方无关的描述符。模型目录仅供参考:路由仍以已注册提供方为键,适配器也可以接受未列出的模型 id。
|
||||
|
||||
注册适配器会返回一个句柄:既是释放器,也带有原子的路由替换——路由集合由用户配置决定的插件正需要它。
|
||||
|
||||
```ts type-equiv
|
||||
/**
|
||||
* What {@link LlmService.registerAdapter} returns: the disposer, plus an
|
||||
* atomic route replacement for the same adapter instance.
|
||||
*/
|
||||
interface AdapterRegistrationHandle {
|
||||
/** Release every route this registration currently holds. */
|
||||
(): void
|
||||
/**
|
||||
* Replace this registration's routes with `providers`, keeping the same
|
||||
* adapter instance. The candidate set is validated in full first — a
|
||||
* conflict with another adapter, an invalid name, or bad provider metadata
|
||||
* throws and leaves the current routes untouched — and the swap itself is
|
||||
* one synchronous section, so no request can observe a gap. An empty array
|
||||
* is legal here (a settings section that emptied holds zero routes while
|
||||
* staying registered), unlike an empty initial registration.
|
||||
*
|
||||
* Throws `LlmError` with code `REGISTRATION_DISPOSED` once the registration
|
||||
* has been released: its routes are gone and its disposer has already run,
|
||||
* so anything registered afterwards would have no owner left to release it.
|
||||
* @param providers - the complete next route set for this registration.
|
||||
*/
|
||||
replace(providers: string[]): void
|
||||
}
|
||||
```
|
||||
注册适配器会把一组非空提供方路由绑定到调用方 fiber,并返回相应的释放器。路由归组合所有,不属于可变的用户设置。
|
||||
|
||||
```ts type-equiv
|
||||
/** Display metadata for one registered provider route. */
|
||||
|
||||
@@ -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 docs/core-data-structures/credentials.md
|
||||
credentials.md: 3f6fcd127d01e2c49e17c70c002bebe9f363e951
|
||||
credentials.zh.md: b5d2d9e164a85ce090790635c438b768cae4c9ca
|
||||
credentials.md: 90e39a013f6b557ca5d4f07facebda390b908305
|
||||
credentials.zh.md: 92986f484bcc271538d02169038bbe71ebd5e4a6
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
English | [中文](credentials.zh.md)
|
||||
|
||||
The credential seam of [dsh-credentials](../../packages/credentials/credentials) keeps secrets out of configuration: settings sections and `cordis.yml` entries carry *references* (environment-variable names), providers such as [dsh-credentials-local](../../packages/credentials/credentials-local) own the values, and consumers resolve a reference once per operation — the LLM adapters resolve once per model request, so a rotated credential reaches the very next request without any restart. One seam-wide rule binds every provider: an empty stored value is absent everywhere.
|
||||
The [dsh-credentials](../../packages/credentials/credentials) seam lets configuration name secrets by reference rather than carry their values. Providers such as [dsh-credentials-local](../../packages/credentials/credentials-local) resolve the current non-empty value, and consumers resolve once per operation so an external rotation reaches the next operation without a restart.
|
||||
|
||||
Source: [`packages/credentials/credentials/src/index.ts`](../../packages/credentials/credentials/src/index.ts)
|
||||
|
||||
@@ -17,34 +17,4 @@ type CredentialRef = Branded<'CredentialRef'>
|
||||
|
||||
## Resolution
|
||||
|
||||
`resolve(ref)` returns the value with the provider-defined source layer that supplied it, or `undefined` while unconfigured. Consumers re-resolve at each operation and never cache across operations — that per-operation read is the hot-update mechanism.
|
||||
|
||||
```ts type-equiv
|
||||
/** One resolved credential value and the source layer that supplied it. */
|
||||
interface ResolvedCredential {
|
||||
/** The non-empty secret value. */
|
||||
value: string
|
||||
/** Provider-defined source layer id (the local provider uses `env` and `file`). */
|
||||
source: string
|
||||
}
|
||||
```
|
||||
|
||||
## Description
|
||||
|
||||
`describe(ref)` answers configuration surfaces without ever exposing a value: whether the reference resolves, from which layer, and whether `set` would currently succeed. The local provider reports a reference supplied by the live process environment as `writable: false` — a write would appear to succeed while resolution kept returning the shadowing value, so the seam rejects it and the UI can render the reference read-only up front.
|
||||
|
||||
```ts type-equiv
|
||||
/** Source and writability facts for one reference, safe for configuration UIs — never the value. */
|
||||
interface CredentialInfo {
|
||||
/** Whether {@link Credentials.resolve} would currently return a value. */
|
||||
configured: boolean
|
||||
/** Source layer currently supplying the value; absent while unconfigured. */
|
||||
source?: string
|
||||
/** Whether {@link Credentials.set} would currently succeed for this reference. */
|
||||
writable: boolean
|
||||
}
|
||||
```
|
||||
|
||||
## Change commits
|
||||
|
||||
`credentials/updated (ref)` fires after a committed change to a provider-managed source — a `set`, an `unset`, or an external edit observed in storage. Ambient process-environment changes are not observable and never emit. Consumers do not need the event (they re-resolve per operation); it exists for configuration surfaces refreshing a "configured" badge.
|
||||
`ctx.credentials.resolve(ref)` returns the provider's current non-empty secret string, or `undefined` while unconfigured. Consumers do not cache across operations. The seam deliberately exposes no mutation, source-description, enumeration, or change-event contract; the generated [service catalog](../cordis-catalog/services.md) owns the method signature.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[English](credentials.md) | 中文
|
||||
|
||||
[dsh-credentials](../../packages/credentials/credentials) 的凭据 seam 把机密挡在配置之外:settings 分节与 `cordis.yml` 条目携带的是*引用*(环境变量名),值归 [dsh-credentials-local](../../packages/credentials/credentials-local) 这类 provider 所有,消费方每个操作解析一次引用——LLM 适配器每次模型请求解析一次,因此轮换后的凭据无需任何重启即可作用于紧随其后的下一次请求。一条 seam 级规则约束每个 provider:空的存储值在任何地方都视为不存在。
|
||||
[dsh-credentials](../../packages/credentials/credentials) seam 允许配置以引用点名机密,而非携带机密值。[dsh-credentials-local](../../packages/credentials/credentials-local) 这类提供方解析当前非空值,消费方每个操作解析一次,因此从外部轮换的值无需重启即可作用于下一次操作。
|
||||
|
||||
Source: [`packages/credentials/credentials/src/index.ts`](../../packages/credentials/credentials/src/index.ts)
|
||||
|
||||
@@ -17,34 +17,4 @@ type CredentialRef = Branded<'CredentialRef'>
|
||||
|
||||
## 解析
|
||||
|
||||
`resolve(ref)` 返回值,连同供出该值、由 provider 定义的来源层;未配置期间返回 `undefined`。消费方在每个操作中重新解析,绝不跨操作缓存——这次按操作进行的读取正是热更新机制。
|
||||
|
||||
```ts type-equiv
|
||||
/** One resolved credential value and the source layer that supplied it. */
|
||||
interface ResolvedCredential {
|
||||
/** The non-empty secret value. */
|
||||
value: string
|
||||
/** Provider-defined source layer id (the local provider uses `env` and `file`). */
|
||||
source: string
|
||||
}
|
||||
```
|
||||
|
||||
## 描述
|
||||
|
||||
`describe(ref)` 在绝不暴露值的前提下回应配置界面:引用当前是否可解析、来自哪一层、`set` 当前能否成功。本地 provider 把由活跃进程环境供值的引用报告为 `writable: false`——那样的写入会表面成功而解析持续返回遮蔽值,因此 seam 直接拒绝,界面也得以提前把该引用渲染为只读。
|
||||
|
||||
```ts type-equiv
|
||||
/** Source and writability facts for one reference, safe for configuration UIs — never the value. */
|
||||
interface CredentialInfo {
|
||||
/** Whether {@link Credentials.resolve} would currently return a value. */
|
||||
configured: boolean
|
||||
/** Source layer currently supplying the value; absent while unconfigured. */
|
||||
source?: string
|
||||
/** Whether {@link Credentials.set} would currently succeed for this reference. */
|
||||
writable: boolean
|
||||
}
|
||||
```
|
||||
|
||||
## 变更提交
|
||||
|
||||
`credentials/updated (ref)` 在 provider 管理的来源发生已提交变更后触发——`set`、`unset` 或在存储中观察到的外部编辑。进程环境自身的变化不可观测,永不发出事件。消费方不需要该事件(它们按操作重新解析);它服务于配置界面刷新「已配置」徽标。
|
||||
`ctx.credentials.resolve(ref)` 返回提供方当前的非空机密字符串,未配置时返回 `undefined`。消费方不跨操作缓存。该 seam 刻意不暴露变更、来源描述、枚举或变更事件契约;方法签名由生成的[服务目录](../cordis-catalog/services.md)负责。
|
||||
|
||||
Reference in New Issue
Block a user