Merge latest origin/master into compact-post-step-overflow-recovery

# Conflicts:
#	docs/agent-lifecycle.md
#	docs/architecture.md
#	docs/cookbook/extension-cookbook.i18n.yaml
#	docs/cordis-catalog/events.md
#	docs/cordis-catalog/services.md
#	docs/event-producer-consumer.md
#	docs/rfc/INDEX.md
#	docs/rfc/implemented/architecture/2026-07-05-reconstructable-requests.md
#	docs/rfc/implemented/architecture/2026-07-15-replay-token-meter-service.i18n.yaml
#	docs/rfc/implemented/architecture/2026-07-15-replay-token-meter-service.md
#	docs/rfc/implemented/architecture/2026-07-15-replay-token-meter-service.zh.md
#	docs/rfc/implemented/feature/2026-06-18-compaction-capability-seam.md
#	docs/rfc/implemented/feature/2026-07-07-session-prefix.md
#	packages/compact/compact-basic/README.md
#	packages/compact/compact-basic/src/config.ts
#	packages/compact/compact-basic/src/index.ts
#	packages/compact/compact-basic/src/summarizer.ts
#	packages/compact/compact-basic/tests/compact-basic.spec.ts
#	packages/compact/compact-basic/tests/compact-loop-repro.spec.ts
#	packages/compact/compact/README.md
#	packages/cordis/tool-cordis/src/api-catalog.ts
#	packages/core/agent-loop/src/loop.ts
#	packages/core/agent-loop/tests/cancel.spec.ts
#	packages/llm/llm-deepseek/src/adapter.ts
#	packages/llm/llm-pi-ai/README.md
#	packages/llm/llm-pi-ai/src/stream.ts
#	packages/llm/llm-pi-ai/tests/convert.spec.ts
#	packages/llm/llm/README.md
#	packages/llm/llm/src/index.ts
#	packages/llm/llm/tests/service.spec.ts
#	scripts/gen-doc-graphs.ts
This commit is contained in:
Tianyi Cui
2026-07-19 12:06:23 +08:00
814 changed files with 42348 additions and 10067 deletions

View File

@@ -11,15 +11,17 @@ The **harness tier** below (the `@deepseek-ai/dsh-*` packages) is the vocabulary
## `ctx.agentLoop` — `AgentLoop`
Concrete ReactLoopAgent factory and driver service.
Concrete agent factory and driver service.
```ts cordis-catalog
create(id: AgentId, options: AgentOptions = {}, meta: Pick<SessionHeader, 'cwd'> = {}): ReactLoopAgent
create(id: SessionId, options: AgentOptions = {}, meta: Pick<SessionHeader, 'cwd'> = {}): Agent
async createAgent(ownerCtx: Context, options: CreateAgentOptions): Promise<AgentHandle>
async resume(ownerCtx: Context, options: ResumeAgentOptions): Promise<AgentHandle>
```
Source: [`packages/core/agent-loop/src/index.ts:335`](../../packages/core/agent-loop/src/index.ts)
Types: [Agent](../core-data-structures/core.md)
Source: [`packages/core/agent-loop/src/index.ts:407`](../../packages/core/agent-loop/src/index.ts)
## `ctx.agents` — `AgentRegistry`
@@ -30,15 +32,17 @@ setFactory(factory: AgentFactory): () => void
async create(options: CreateAgentOptions): Promise<AgentHandle>
async resume(options: ResumeAgentOptions): Promise<AgentHandle>
register(agent: Agent): () => void
enter(agent: Agent): () => void
enter(agent: Agent, owner: Agent | undefined): () => void
announce(agent: Agent): void
get(id: AgentId): Agent | undefined
get(id: SessionId): Agent | undefined
isOwnedBy(id: SessionId, owner: Agent): boolean
list(): Agent[]
roots(): Agent[]
```
Types: [Agent](../core-data-structures/core.md)
Source: [`packages/core/agent/src/index.ts:133`](../../packages/core/agent/src/index.ts)
Source: [`packages/core/agent/src/index.ts:201`](../../packages/core/agent/src/index.ts)
## `ctx.approval` — `ApprovalService`
@@ -71,7 +75,21 @@ abstract start(spec: BashExecSpec): BashProcess
Types: [BashExecRequest](../core-data-structures/bash.md) · [BashExecSpec](../core-data-structures/bash.md) · [BashRunResult](../core-data-structures/bash.md)
Source: [`packages/bash/bash/src/index.ts:46`](../../packages/bash/bash/src/index.ts)
Source: [`packages/bash/bash/src/index.ts:49`](../../packages/bash/bash/src/index.ts)
## `ctx.bashEnv` — `BashEnvRegistry`
Registry (`ctx.bashEnv`) for trusted, per-execution `DSH_*` variables. The namespace is rebuilt for every model bash call: ambient `DSH_*` values are discarded by the executor, then the registry's current snapshot is injected. Built-in shell facts remain owned by the registry itself while plugins can register additional, enumerable facts with effect-scoped disposal.
```ts cordis-catalog
register(contributor: BashEnvContributor): () => void
collect(execution: ToolExecution): DshEnvironment
list(): BashEnvVariableInfo[]
```
Types: [ToolExecution](../core-data-structures/tools.md)
Source: [`packages/bash/tool-bash/src/index.ts:102`](../../packages/bash/tool-bash/src/index.ts)
## `ctx.codeRuntime` — `CodeRuntime` (abstract seam)
@@ -91,7 +109,7 @@ Abstract compaction service. Implementations own trigger policy, retention, and
```ts cordis-catalog
abstract compactIfNeeded( agent: CompactAgentContext, trigger: CompactionTrigger, signal: AbortSignal, ): Promise<CompactionResult | null>
abstract compactRegion( session: Session, start: number, end: number, agent: CompactAgentContext, signal?: AbortSignal, ): Promise<CompactionResult>
abstract compactRegion( start: number, end: number, agent: CompactAgentContext, signal?: AbortSignal, ): Promise<CompactionResult>
```
Source: [`packages/compact/compact/src/index.ts:40`](../../packages/compact/compact/src/index.ts)
@@ -101,8 +119,9 @@ Source: [`packages/compact/compact/src/index.ts:40`](../../packages/compact/comp
Abstract filesystem provider. Targets must preserve identity across aliases; reads expose regular UTF-8 text or typed errors, listings are stable and content-free, and mutations are atomic. Optional guards add stale protection without changing the unguarded provider contract.
```ts cordis-catalog
abstract resolve(path: string, opts?: { cwd?: string }): Promise<FsTarget>
abstract resolve(path: string, opts?: { cwd?: string; signal?: AbortSignal }): Promise<FsTarget>
abstract stat(target: FsTarget, signal?: AbortSignal): Promise<FsInfo | undefined>
abstract lstat(path: string, opts?: { cwd?: string }, signal?: AbortSignal): Promise<FsPathInfo | undefined>
abstract readText(target: FsTarget, signal?: AbortSignal): Promise<string>
abstract streamText(target: FsTarget, signal?: AbortSignal): Promise<AsyncIterable<string>>
abstract listDir(target: FsTarget, signal?: AbortSignal): Promise<FsDirEntry[]>
@@ -112,21 +131,22 @@ abstract editText(target: FsTarget, edit: FsEditRequest, expected?: { version: F
Types: [FsEditOutcome](../core-data-structures/filesystem.md) · [FsEditRequest](../core-data-structures/filesystem.md) · [FsInfo](../core-data-structures/filesystem.md) · [FsTarget](../core-data-structures/filesystem.md) · [FsVersion](../core-data-structures/filesystem.md) · [FsWriteIntent](../core-data-structures/filesystem.md) · [FsWriteOutcome](../core-data-structures/filesystem.md)
Source: [`packages/fs/fs/src/index.ts:78`](../../packages/fs/fs/src/index.ts)
Source: [`packages/fs/fs/src/index.ts:80`](../../packages/fs/fs/src/index.ts)
## `ctx.llm` — `LlmService`
The abstract `llm` service: an adapter registry plus a streaming model-call surface, interceptable via the `llm/stream` waterfall.
```ts cordis-catalog
registerAdapter(models: string[], adapter: LlmAdapter): () => void
models(): string[]
registerAdapter(providers: string[], adapter: LlmAdapter): () => void
listProviders(): LlmProviderInfo[]
async listModels(provider: string): Promise<LlmModelInfo[]>
stream(options: GenerateOptions): AsyncIterable<StreamChunk>
```
Types: [GenerateOptions](../core-data-structures/core.md) · [StreamChunk](../core-data-structures/llm-streaming.md)
Source: [`packages/llm/llm/src/index.ts:77`](../../packages/llm/llm/src/index.ts)
Source: [`packages/llm/llm/src/index.ts:96`](../../packages/llm/llm/src/index.ts)
## `ctx.permission` — `PermissionService`
@@ -160,6 +180,7 @@ Source: [`packages/sandbox/sandbox/src/index.ts:111`](../../packages/sandbox/san
Durable append-only session storage. Implementations preserve contiguous, losslessly JSON-serializable events; append resolves only after durability, and load balances a complete interrupted tail without rewriting committed events.
```ts cordis-catalog
abstract locate(meta: SessionHeader): SessionLocation | undefined
abstract create(meta: SessionHeader): Promise<void>
abstract append(id: SessionId, events: readonly SessionEvent[]): Promise<void>
abstract load(id: SessionId): Promise<{ meta: SessionHeader; events: SessionEvent[] }>
@@ -168,19 +189,21 @@ abstract list(): Promise<SessionHeader[]>
Types: [SessionEvent](../core-data-structures/core.md)
Source: [`packages/session-persistence/session-persistence/src/index.ts:30`](../../packages/session-persistence/session-persistence/src/index.ts)
Source: [`packages/session-persistence/session-persistence/src/index.ts:42`](../../packages/session-persistence/session-persistence/src/index.ts)
## `ctx.sessionQuery` — `SessionQueryService`
Live-preferred logical-corpus and exact-event read service.
Live-preferred logical-corpus exact-read and relationship-tracing service.
```ts cordis-catalog
listSessions(): Promise<SessionRecord[]>
async listEvents(sessionId: SessionId): Promise<SessionEventRecord[]>
async traceSession(sessionId: SessionId): Promise<SessionLineageTrace>
async traceEvent(request: SessionEventTraceRequest): Promise<SessionEventTrace>
async readEvent(request: SessionEventReadRequest): Promise<SessionEventWindow>
```
Source: [`packages/session-query/session-query/src/index.ts:35`](../../packages/session-query/session-query/src/index.ts)
Source: [`packages/session-query/session-query/src/index.ts:38`](../../packages/session-query/session-query/src/index.ts)
## `ctx.sessions` — `SessionStore`
@@ -199,7 +222,7 @@ list(): Session[]
fork(source: SessionForkSource, boundary?: number, childSessionId?: SessionId): Session
```
Source: [`packages/core/session/src/index.ts:563`](../../packages/core/session/src/index.ts)
Source: [`packages/core/session/src/index.ts:585`](../../packages/core/session/src/index.ts)
## `ctx.skills` — `SkillService`
@@ -214,6 +237,22 @@ async get(name: string, options: SkillLookupOptions = {}): Promise<SkillDefiniti
Source: [`packages/skill/skill/src/index.ts:141`](../../packages/skill/skill/src/index.ts)
## `ctx.spillStore` — `SpillStore` (abstract seam)
Abstract spill storage service. Subclass, implement saveText, and load the subclass as a plugin — it registers as `ctx.spillStore` (one implementation per context; loading a second throws, cordis' standard duplicate-service behavior).
Semantics every implementation must honor:
- saveText persists the FULL `content` verbatim and returns an opaque locator, exact byte length, and model-facing retrieval guidance.
- Storage is scoped by the request's SaveTextSpill.owner session; the backend chooses a private (not world-readable) location and a collision-free name derived from — never equal to — the caller's `suggestedName`.
- `saveText` REJECTS on a real storage failure (permissions, ENOSPC, backend unavailable); the caller decides how to degrade (the spill policy treats a rejection as best-effort and keeps the inline result).
```ts cordis-catalog
abstract saveText(input: SaveTextSpill): Promise<SpillRef>
```
Source: [`packages/spill/spill/src/index.ts:45`](../../packages/spill/spill/src/index.ts)
## `ctx.subagents` — `SubagentService`
Named provider registry and capability-checked start surface.
@@ -225,7 +264,7 @@ list(): string[]
async start(name: string, request: SubagentStartRequest): Promise<SubagentRun>
```
Source: [`packages/subagent/subagent/src/index.ts:141`](../../packages/subagent/subagent/src/index.ts)
Source: [`packages/subagent/subagent/src/index.ts:153`](../../packages/subagent/subagent/src/index.ts)
## `ctx.systemPrompt` — `SystemPrompt`
@@ -282,12 +321,13 @@ restrict(filter: ToolRestriction): () => void
guard(guard: ToolGuard): () => void
get(name: string, scope?: ScopeKey): ToolDefinition | undefined
schemas(scope?: ScopeKey): ToolSchema[]
executionMode(exec: ToolExecutionInput): ToolExecutionMode
async execute(exec: ToolExecutionInput): Promise<ToolExecutionResult>
```
Types: [ToolDefinition](../core-data-structures/tools.md) · [ToolExecutionInput](../core-data-structures/tools.md) · [ToolExecutionResult](../core-data-structures/tools.md)
Types: [ToolDefinition](../core-data-structures/tools.md) · [ToolExecutionInput](../core-data-structures/tools.md) · [ToolExecutionMode](../core-data-structures/tools.md) · [ToolExecutionResult](../core-data-structures/tools.md)
Source: [`packages/core/tools/src/index.ts:363`](../../packages/core/tools/src/index.ts)
Source: [`packages/core/tools/src/index.ts:438`](../../packages/core/tools/src/index.ts)
## `ctx.userInteraction` — `UserInteractionService`
@@ -336,12 +376,12 @@ Source: [`packages/workflow/workflow/src/index.ts:159`](../../packages/workflow/
The framework `ctx` surface every plugin also sees, beyond the harness services above. This is pinned vendor source ([vendoring policy](../../vendor/README.md)); it is summarized here so the page is a complete picture of what `ctx` offers, without elevating framework internals to the harness tier's prominence.
- `ctx.on / ctx.once` — Register an event listener (disposable). ([`vendor/cordis/src/events.ts:29`](../../vendor/cordis/src/events.ts))
- `ctx.emit / ctx.parallel / ctx.serial / ctx.bail / ctx.waterfall` — Dispatch an event (sync / awaited / first-bail / veto-chain). ([`vendor/cordis/src/events.ts:29`](../../vendor/cordis/src/events.ts))
- `ctx.plugin / ctx.inject` — Load a plugin / declare required services. ([`vendor/cordis/src/registry.ts:144`](../../vendor/cordis/src/registry.ts))
- `ctx.on / ctx.once` — Register an event listener (disposable). ([`vendor/cordis/src/events.ts:34`](../../vendor/cordis/src/events.ts))
- `ctx.emit / ctx.parallel / ctx.serial / ctx.bail / ctx.waterfall` — Dispatch an event (sync / awaited / first-bail / veto-chain). ([`vendor/cordis/src/events.ts:34`](../../vendor/cordis/src/events.ts))
- `ctx.plugin / ctx.inject` — Load a plugin / declare required services. ([`vendor/cordis/src/registry.ts:164`](../../vendor/cordis/src/registry.ts))
- `ctx.effect` — Register a disposable side effect tied to the fiber. ([`vendor/cordis/src/fiber.ts:9`](../../vendor/cordis/src/fiber.ts))
- `ctx.get / ctx.set / ctx.provide / ctx.accessor / ctx.mixin` — Low-level service-store access and binding. ([`vendor/cordis/src/reflect.ts:7`](../../vendor/cordis/src/reflect.ts))
- `ctx.extend / ctx.isolate / ctx.intercept` — Derive a child context (scoped services / isolation / interception). ([`vendor/cordis/src/context.ts:35`](../../vendor/cordis/src/context.ts))
- `ctx.extend / ctx.isolate / ctx.intercept` — Derive a child context (scoped services / isolation / interception). ([`vendor/cordis/src/context.ts:42`](../../vendor/cordis/src/context.ts))
- `ctx.root / ctx.scope / ctx.fiber / ctx.registry / ctx.reflect / ctx.events / ctx.logger` — Ambient handles onto the running context graph. ([`vendor/cordis/src/context.ts:16`](../../vendor/cordis/src/context.ts))
- `ctx.timer (+ interval / timeout / throttle / debounce / setTimeout / setInterval)` — Disposable timer helpers. The `timer` key is provided at runtime; the six helpers are mixed onto ctx directly (declared via Pick). ([`vendor/timer/src/index.ts:4`](../../vendor/timer/src/index.ts))
- `ctx.loader` — The config Loader that booted the app (present under the loader). ([`vendor/loader/src/index.ts:30`](../../vendor/loader/src/index.ts))