docs(website): align LLM references with provider routing

This commit is contained in:
Tianyi Cui
2026-07-17 22:02:54 +08:00
parent 35e45af081
commit cfa5d60ccb
5 changed files with 61 additions and 44 deletions

View File

@@ -22,7 +22,7 @@ Create an agent on a fresh per-run session, owned by the accessing fiber. Constr
**Returns** the published running agent.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent-loop/src/index.ts#L389)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent-loop/src/index.ts#L391)
### ctx.agentLoop.createAgent(ownerCtx, options)
@@ -37,7 +37,7 @@ Create an owned agent on a caller-supplied session id.
**Returns** the published handle.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent-loop/src/index.ts#L412)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent-loop/src/index.ts#L414)
### ctx.agentLoop.resume(ownerCtx, options)
@@ -52,4 +52,4 @@ Resume an owned agent from the configured persistence service.
**Returns** the published handle.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent-loop/src/index.ts#L443)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent-loop/src/index.ts#L445)

View File

@@ -18,7 +18,7 @@ A fully configured agent and live session were published. Setup is composition-o
- `agent` — the newly registered agent with its live session and completed setup. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L151)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L153)
### agent/disposed
@@ -32,7 +32,7 @@ An agent left the registry; AgentLoop emits this after driver quiescence but bef
- `agent` — the exact agent removed from the registry. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L160)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L162)
### agent/error
@@ -49,7 +49,7 @@ A step or turn errored. The loop reports a failure here (plus the logger) even w
- `step` — the step at which the failure surfaced.
- `error` — the failure, verbatim. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L295)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L297)
### agent/pre-step
@@ -68,7 +68,7 @@ Awaited serial checkpoint for session-surface mutation after prompt assembly and
- `sessionPrefix` — the frozen request prefix.
- `signal` — the turn abort signal.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L214)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L216)
### agent/prompt-submit
@@ -84,7 +84,7 @@ Allow, rewrite, or block one drained prompt before it becomes a user message. Ca
- `content` — the drained message's blocks, as queued.
- `source` — the message's resolved source. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L224)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L226)
### agent/queued
@@ -100,7 +100,7 @@ Detached, frozen content entered the agent's inbox. Source defaults have already
- `content` — the accepted content blocks retained by the inbox.
- `info` — the accepted source plus whether it entered as steering. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L179)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L181)
### agent/request
@@ -117,7 +117,7 @@ Replace the frozen call configuration. Model-visible content must use logged cha
- `step` — the step whose request this is.
- `config` — the config the loop would use (frozen); return a replacement to switch. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L236)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L238)
### agent/session-prefix
@@ -133,7 +133,7 @@ Compose request-only messages placed before derived history. The frozen result i
- `prefix` — the frozen seed; return an extended replacement.
- `signal` — aborts composition when the step is torn down.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L251)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L253)
### agent/session-start
@@ -148,7 +148,7 @@ The session lifecycle began, once before the first turn. Use `agent.inject()` to
- `agent` — the agent whose session lifecycle began.
- `source` — why the session started (fresh startup, resume, …). Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L192)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L194)
### agent/status
@@ -163,7 +163,7 @@ Agent status changed (`idle` ⇄ `running`, or → `disposed`). `send()` does no
- `agent` — the agent whose status flipped.
- `status` — the status just entered (the transition's destination). Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L169)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L171)
### agent/step-result
@@ -180,7 +180,7 @@ Waterfall: post-process the assembled assistant Message before tool dispatch (va
- `step` — the step that produced the message.
- `message` — the assistant message as assembled from the stream. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L262)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L264)
### agent/turn-continuation
@@ -196,7 +196,7 @@ Override whether the turn continues. The default continues after tool calls or s
- `turn` — the turn being continued or stopped.
- `defaultDecision` — what the loop would do absent an override. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L272)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L274)
### agent/turn-stop
@@ -211,7 +211,7 @@ Monotonic terminal-stop checkpoint after continuation and steering are folded; a
- `agent` — the agent whose composed continuation outcome may be stopped.
- `turn` — the turn at its terminal-stop checkpoint. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L282)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/types.ts#L284)
## approval/*
@@ -291,7 +291,7 @@ Waterfall around every streaming model call (retry, replay, routing). Bound to t
- `options` — the full request. A LOOP-built request arrives deep-frozen (mutation throws): its content is a pure function of the session log (the reconstructability RFC), so listeners read it, never rewrite it. A hand-built one-shot (compaction summarize) is the caller's own object and stays mutable here.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/llm/llm/src/index.ts#L39)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/llm/llm/src/index.ts#L40)
## session/*

View File

@@ -6,34 +6,48 @@
The abstract `llm` service: an adapter registry plus a streaming model-call surface, interceptable via the `llm/stream` waterfall.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/llm/llm/src/index.ts#L75)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/llm/llm/src/index.ts#L96)
### ctx.llm.registerAdapter(models, adapter)
### ctx.llm.registerAdapter(providers, adapter)
```ts website-api
registerAdapter(models: string[], adapter: LlmAdapter): () => void
registerAdapter(providers: string[], adapter: LlmAdapter): () => void
```
Register an adapter for the given model names. Throws `LlmError` with code `DUPLICATE_ADAPTER` if any model already has an adapter (all-or-nothing). Disposed with the fiber.
Register an adapter for the given provider routes. Throws `LlmError` with code `DUPLICATE_ADAPTER` if any provider already has an adapter (all-or-nothing). Disposed with the fiber.
- `models` — every model name this adapter should serve.
- `adapter` — the adapter that streams calls for those models.
- `providers` — every provider route this adapter should serve.
- `adapter` — the adapter that streams calls for those providers.
**Returns** the disposer that unregisters all of them.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/llm/llm/src/index.ts#L90)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/llm/llm/src/index.ts#L111)
### ctx.llm.models()
### ctx.llm.listProviders()
```ts website-api
models(): string[]
listProviders(): LlmProviderInfo[]
```
Model names with a registered adapter.
Describe provider routes with a registered adapter.
**Returns** the registered names, in registration order.
**Returns** detached provider metadata in registration order.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/llm/llm/src/index.ts#L111)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/llm/llm/src/index.ts#L142)
### ctx.llm.listModels(provider)
```ts website-api
async listModels(provider: string): Promise<LlmModelInfo[]>
```
Discover models advertised by one registered provider. Catalog membership is advisory and never changes routing or request validation.
- `provider` — registered provider route to inspect.
**Returns** detached model metadata in adapter-preferred order.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/llm/llm/src/index.ts#L152)
### ctx.llm.stream(options)
@@ -41,10 +55,10 @@ Model names with a registered adapter.
stream(options: GenerateOptions): AsyncIterable<StreamChunk>
```
Stream one model call as raw chunks (token-level deltas). Throws `LlmError` with code `NO_ADAPTER` if no adapter is registered for `options.model`. Dispatches through the `llm/stream` waterfall.
Stream one model call as raw chunks (token-level deltas). Throws `LlmError` with code `NO_ADAPTER` if no adapter is registered for `options.provider`. Replay state is retained only when the same adapter instance owns its historical provider and the target provider. Dispatches through the `llm/stream` waterfall.
- `options` — the full request; `options.model` selects the adapter.
- `options` — the full request; `options.provider` selects the adapter.
**Returns** the chunk stream, possibly wrapped by `llm/stream` listeners.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/llm/llm/src/index.ts#L128)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/llm/llm/src/index.ts#L210)

View File

@@ -7,7 +7,7 @@
In-memory session store (`ctx.sessions`).
Persistence is intentionally not implemented here — persistence plugins subscribe to `session/event` and flush on `session/flush` / dispose.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/session/src/index.ts#L540)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/session/src/index.ts#L567)
### ctx.sessions.create(id?, options?)
@@ -23,7 +23,7 @@ For an agent whose session must be torn down IN ORDER with its loop (so the loop
**Returns** the live session, already entered and announced.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/session/src/index.ts#L569)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/session/src/index.ts#L596)
### ctx.sessions.prepare(id?, options?)
@@ -38,7 +38,7 @@ Build a session WITHOUT entering it into the store — validate the id/cwd and c
**Returns** the constructed session, NOT yet in the store.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/session/src/index.ts#L598)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/session/src/index.ts#L625)
### ctx.sessions.enter(session)
@@ -53,7 +53,7 @@ Re-checks the id for a duplicate: `prepare` and `enter` are public cross-package
**Returns** the detach disposer (publication hooks + store removal). When called from a synchronous `session/created` listener, removal and disposal wait until that creation dispatch unwinds.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/session/src/index.ts#L642)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/session/src/index.ts#L669)
### ctx.sessions.announce(session)
@@ -65,7 +65,7 @@ Emit `session/created` exactly once for an entered session (with the carrier ent
- `session` — the entered session to announce to listeners.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/session/src/index.ts#L697)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/session/src/index.ts#L724)
### ctx.sessions.flush(session)
@@ -79,7 +79,7 @@ Dispatch the awaited `session/flush` durability checkpoint for `session`, with t
**Returns** resolves when every flush listener has settled; after all settle, rejects with the first registered listener failure if any listener failed.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/session/src/index.ts#L749)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/session/src/index.ts#L776)
### ctx.sessions.get(id)
@@ -93,7 +93,7 @@ Look up a live session.
**Returns** the session, or undefined when no live session has that id.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/session/src/index.ts#L781)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/session/src/index.ts#L808)
### ctx.sessions.list()
@@ -105,7 +105,7 @@ All live sessions, in creation order.
**Returns** a fresh array; mutating it does not affect the store.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/session/src/index.ts#L789)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/session/src/index.ts#L816)
### ctx.sessions.fork(source, boundary?, childSessionId?)
@@ -121,4 +121,4 @@ Create a live child session from a turn-enclosed prefix of a live source. `bound
**Returns** The created live child session.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/session/src/index.ts#L806)
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/session/src/index.ts#L833)

View File

@@ -83,23 +83,26 @@ export interface Config {
### 配置错误要响亮
如果配置引用了不存在的东西(比如一个不存在的模型名),应该尽早报错,而不是静默跳过:
如果配置引用了不存在的东西(比如一个未注册的 LLM 提供方路由),应该尽早报错,而不是静默跳过:
```ts
import type { Context } from 'cordis'
import type {} from '@deepseek-ai/dsh-llm'
export interface Config {
provider: string
model: string
}
export function apply(ctx: Context, config: Config) {
if (!ctx.llm.models().includes(config.model)) {
throw new Error(`Model "${config.model}" is not registered by any LLM adapter`)
if (!ctx.llm.listProviders().some(provider => provider.id === config.provider)) {
throw new Error(`LLM provider "${config.provider}" is not registered`)
}
}
```
模型目录只用于发现;适配器可能接受目录之外的模型 ID因此不能把 `listModels()` 当作请求白名单。
## 配合 HMR
配置变更会触发插件热替换:修改 `cordis.yml` 中某个插件的 `config`,框架会卸载旧实例、加载新实例。由于注册都是效果(自动清理),这个过程是安全的。