mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
Merge remote-tracking branch 'origin/stack/agent-profiles-1-seam' into stack/agent-profiles-3-wire
# Conflicts: # docs/module-graph.md # packages/host/apiproxy/src/api-proxy.ts # packages/host/apiproxy/tsconfig.json
This commit is contained in:
@@ -17,7 +17,7 @@ A turn flows through the six packages in one loop: the driver in [`agent-loop`](
|
||||
| `agent-loop/` | The concrete driver implementing the public `Agent` contract (`ctx.agentLoop`) | this page |
|
||||
| `scope/` | The scoped-registration primitive the registries and loop build per-agent scoping on | [scope.md](scope.md) |
|
||||
|
||||
`scope/` is the one non-service package: a dependency-free library (`createScope`/`scopeOf`/`scopeTarget`) that sits below `session/` and `system-prompt/` in the module graph precisely so they can consume it without a cycle. `agent-loop` is the one concrete implementation of the `agent` seam and lives here because it is the harness's default product loop; it runs each driver inside `ctx.agents.withInitiator()`. Extension plugins depend on `agent` — including when they need the initiating Agent — and never on `agent-loop` directly, so the loop stays swappable. The default composition that wires this spine into a runnable agent is [`examples/agent-spine-demo`](../../packages/examples/agent-spine-demo/README.md).
|
||||
`scope/` is the one non-service package: a dependency-free library (`createScope`/`scopeOf`/`scopeTarget`) that sits below `session/` and `system-prompt/` in the module graph precisely so they can consume it without a cycle. `agent-loop` is the one concrete implementation of the public `Agent` contract and lives here because it is the harness's default product loop; it runs each driver inside `ctx.agents.withInitiator()`. Extension plugins depend on `agent` — including when they need the initiating Agent — and never on `agent-loop` directly, so the loop stays swappable. The default composition that wires this spine into a runnable agent is [`examples/agent-spine-demo`](../../packages/examples/agent-spine-demo/README.md).
|
||||
|
||||
## Creation and ownership
|
||||
|
||||
@@ -48,7 +48,7 @@ interface AgentHandle {
|
||||
|
||||
`CreateAgentOptions` carries the shared identity and everything a fresh agent needs before publication: session metadata (`meta` — validated `cwd`, fork lineage, seed boundary, origin classification, delegation depth), an optional `seed` replay prefix for forks, per-agent `AgentOptions`, a creation-only cancellation `signal`, and `setup`. `ResumeAgentOptions` is the persisted-identity counterpart: `resumeSessionId`, `agentOptions`, `signal`, and `setup`. The `setup` callback (`AgentSetup`) composes the agent's scoped world while both ids are still unpublished — everything registered through `agentCtx` exists before `agent/created` and the first prompt assembly — and may return a synchronous commit invoked immediately before publication; a setup rejection, commit throw, or owner disposal rolls the transaction back without publishing either id.
|
||||
|
||||
`AgentFactory` is the creation seam behind the registry: the loop registers its factory via `ctx.agents.setFactory()`, so consumers program against `ctx.agents` without depending on the concrete loop package. The exact `create`/`resume` signatures and their rollback contracts are in the [generated section](#ctxagents--agentregistry) below.
|
||||
`AgentFactory` is the creation contract behind the registry: the loop registers its factory via `ctx.agents.setFactory()`, so consumers program against `ctx.agents` without depending on the concrete loop package. The exact `create`/`resume` signatures and their rollback contracts are in the [generated section](#ctxagents--agentregistry) below.
|
||||
|
||||
## The agent handle
|
||||
|
||||
@@ -107,7 +107,7 @@ interface Agent {
|
||||
* cancel leaves it parked. A wake submitted while already idle always opens
|
||||
* its turn boundary, even when its message is cleared before the driver
|
||||
* claims ([cancel-convergence wake latch](../../../../.agents/notes/implemented/bug-fix/2026-08-07-cancel-convergence-wake-latch.md)).
|
||||
* @param message - identified content and its producer provenance.
|
||||
* @param message - identified content and the source that supplied it.
|
||||
* @param target - the preferred next-turn or next-step inbox boundary.
|
||||
* @param wakeup - whether delivery may wake the driver.
|
||||
*/
|
||||
@@ -116,7 +116,7 @@ interface Agent {
|
||||
/**
|
||||
* Queue an ordinary follow-up turn and wake the driver. The item becomes the
|
||||
* sole ordinary message of its own turn.
|
||||
* @param message - identified prompt content and its producer provenance.
|
||||
* @param message - identified prompt content and the source that supplied it.
|
||||
*/
|
||||
followup(message: UserMessage): void
|
||||
|
||||
@@ -125,7 +125,7 @@ interface Agent {
|
||||
* a running driver consumes it at its next step boundary.
|
||||
* A rejected step leaves steering parked in the inbox until the next
|
||||
* wake; cancellation or disposal may discard pending steering.
|
||||
* @param message - identified steering content and its producer provenance.
|
||||
* @param message - identified steering content and the source that supplied it.
|
||||
*/
|
||||
steer(message: UserMessage): void
|
||||
|
||||
@@ -135,7 +135,7 @@ interface Agent {
|
||||
* idle drivers leave it pending until follow-up or steering
|
||||
* wakes them. It may miss a request whose pre-step already claimed its
|
||||
* batch. Cancellation or disposal may discard pending context.
|
||||
* @param message - identified injected context and its producer provenance.
|
||||
* @param message - identified injected context and the source that supplied it.
|
||||
*/
|
||||
inject(message: UserMessage): void
|
||||
}
|
||||
@@ -200,7 +200,7 @@ type AgentCancelCause =
|
||||
| { readonly kind: 'disposed' }
|
||||
```
|
||||
|
||||
The cause is a TypeScript-enforced same-process input. An active cancellation holder copies it into the runtime-only `AbortSignal.reason`; a signal grants cooperating listeners no classification authority. Durable `turn/end` retains the coarse `{ kind: 'aborted' }` outcome; request provenance would require a separate durable event rather than overloading the terminal result.
|
||||
The cause is a TypeScript-enforced same-process input. An active cancellation holder copies it into the runtime-only `AbortSignal.reason`; a signal grants cooperating listeners no classification authority. Durable `turn/end` retains the coarse `{ kind: 'aborted' }` outcome; recording who requested cancellation would require a separate durable event rather than overloading the terminal result.
|
||||
|
||||
The [event taxonomy](../architecture.md#event) owns the `agent/*` lifecycle, checkpoint, and waterfall contracts. Turn and step boundaries are durable session events rather than agent emits.
|
||||
|
||||
@@ -210,7 +210,7 @@ The process-local initiator carried by `ctx.agents` is the exact `Agent` above,
|
||||
|
||||
## Interception decisions
|
||||
|
||||
Pre-step decisions use the same identified `UserMessage` shape as durable user-role input. The entered batch is authoritative and preserves every message's identity and provenance. Hook bridges map their native decision fields onto this typed result.
|
||||
Pre-step decisions use the same identified `UserMessage` shape as durable user-role input. The entered batch is authoritative and preserves every message's id and source. Hook bridges map their native decision fields onto this typed result.
|
||||
|
||||
Source: [`packages/core/agent/src/types.ts`](../../packages/core/agent/src/types.ts)
|
||||
|
||||
@@ -243,7 +243,7 @@ type SessionStartSource = 'startup' | 'resume' | 'clear' | 'compact'
|
||||
|
||||
## Sessions
|
||||
|
||||
A `Session` is an **append-only log** of typed `SessionEvent`s — the single source of truth. The LLM message history is *derived* from the log (`deriveMessages()`), not stored separately. Every entry carries a monotonic `seq`, a `time`, and a `type`-discriminated `data` payload; surface variants additionally carry `sourceEventSeqs` provenance and a `surfaceOp`.
|
||||
A `Session` is an **append-only log** of typed `SessionEvent`s — the single source of truth. The LLM message history is *derived* from the log (`deriveMessages()`), not stored separately. Every entry carries a monotonic `seq`, a `time`, and a `type`-discriminated `data` payload; surface variants may also list cited earlier events in `sourceEventSeqs` and carry a `surfaceOp`.
|
||||
|
||||
The `SessionEvent` envelope's exact conditional shape, the twelve event variants (`turn/start`, `turn/end`, `step/start`, `step/end`, `user/message`, `assistant/chunk`, `assistant/message`, `tool/call`, `tool/result`, `steering/message`, `todo/write`, `request/header`), the `deriveMessages()` projection rules, the `TurnTrigger`/`TurnEndReason` reasons, and the execution-enclosure and standalone-event rules are on **[session.md](session.md)**. How the log is made durable — the `SessionPersistence` seam, JSONL/SQLite backends, the `session/flush` checkpoint, crash recovery, and `SessionHeader` — is on **[persistence.md](persistence.md)**.
|
||||
|
||||
@@ -314,6 +314,30 @@ The two core IDs are `CallId` (correlates a tool call with its result; dsh-llm)
|
||||
|
||||
Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnpm run verify-cordis-catalog` in doc-sync; regenerate with `pnpm run gen-cordis-catalog`) — this section is byte-identical in both language sides of the page. Signature blocks use a `ts cordis-catalog` fence and keep the original source JSDoc; dispatch modes are defined in the [primer](../cordis-primer.md#dispatch-modes), and the framework-inherited `ctx` surface lives in [cordis-api/inherited.md](../cordis-api/inherited.md).
|
||||
|
||||
<a id="ctxagentdefaultmodel--agentdefaultmodelservice"></a>
|
||||
|
||||
### `ctx.agentDefaultModel` — `AgentDefaultModelService`
|
||||
|
||||
Owns the default model selection independently of any Host or transport. The composition entry remains usable without a settings provider; when one is mounted, its user layer is read live.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
* Read the current default model selection.
|
||||
* @returns a detached provider, model, and optional reasoning selection.
|
||||
*/
|
||||
currentSelection(): ModelSelection
|
||||
|
||||
/**
|
||||
* Save the complete default model selection. A deployment without a settings
|
||||
* provider keeps its composition entry.
|
||||
* @param next - resolved selection accepted by a front door.
|
||||
* @returns fulfillment after the optional settings write settles.
|
||||
*/
|
||||
async saveSelection(next: ModelSelection): Promise<void>
|
||||
```
|
||||
|
||||
Source: [`packages/core/agent-default-model/src/index.ts:64`](../../packages/core/agent-default-model/src/index.ts)
|
||||
|
||||
<a id="ctxagentloop--agentloop"></a>
|
||||
|
||||
### `ctx.agentLoop` — `AgentLoop`
|
||||
@@ -450,7 +474,7 @@ currentInitiator(): Agent | undefined
|
||||
* Read the initiating Agent and fail when no initiator boundary is active.
|
||||
* Use this for private helpers contractually below a driver, or for a
|
||||
* deployment-owned outbound request whose contract forbids agentless calls.
|
||||
* Generic or direct-call seams use optional lookup or explicit request fields.
|
||||
* Generic or direct-call paths use optional lookup or explicit request fields.
|
||||
* @returns the inherited Agent.
|
||||
* @throws when no initiator is active or this service instance has been disposed.
|
||||
*/
|
||||
@@ -606,12 +630,12 @@ Source: [`packages/core/agent/src/index.ts:254`](../../packages/core/agent/src/i
|
||||
|
||||
#### `agent/created` — emit
|
||||
|
||||
A fully configured agent and live session were published. Setup is composition-only; `agent/session-start` is the first startup-driving seam. Synchronous listener failure vetoes publication, while returned-promise rejection is reported. Detach requested during dispatch waits until every creation listener has observed the stable entry.
|
||||
A fully configured agent and live session were published. Setup is composition-only; `agent/session-start` is the first startup-driving extension point. Synchronous listener failure vetoes publication, while returned-promise rejection is reported. Detach requested during dispatch waits until every creation listener has observed the stable entry.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
* A fully configured agent and live session were published. Setup is
|
||||
* composition-only; `agent/session-start` is the first startup-driving seam.
|
||||
* composition-only; `agent/session-start` is the first startup-driving extension point.
|
||||
* Synchronous listener failure vetoes publication, while returned-promise
|
||||
* rejection is reported. Detach requested during dispatch waits until every
|
||||
* creation listener has observed the stable entry.
|
||||
@@ -767,14 +791,14 @@ Source: [`packages/core/agent/src/types.ts:230`](../../packages/core/agent/src/t
|
||||
|
||||
#### `agent/request` — waterfall
|
||||
|
||||
Replace the frozen call configuration. `await next()` yields the config the machine would use (agent options on the first request, the logged header afterwards); return a replacement to switch. Model-visible content must use logged channels; this seam cannot mutate messages.
|
||||
Replace the frozen call configuration. `await next()` yields the config the machine would use (agent options on the first request, the logged header afterwards); return a replacement to switch. Model-visible content must use logged channels; this waterfall cannot mutate messages.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
* Replace the frozen call configuration. `await next()` yields the config
|
||||
* the machine would use (agent options on the first request, the logged
|
||||
* header afterwards); return a replacement to switch. Model-visible
|
||||
* content must use logged channels; this seam cannot mutate messages.
|
||||
* content must use logged channels; this waterfall cannot mutate messages.
|
||||
* @param payload.agent - the agent making the model call.
|
||||
* @param payload.turn - the open turn number.
|
||||
* @param payload.step - the step whose request this is.
|
||||
|
||||
Reference in New Issue
Block a user