Merge branch 'codex/simp-agent-entry-state' into codex/simp-unify-agent-session-id

# Conflicts:
#	docs/architecture.md
#	docs/config-catalog.md
#	docs/cordis-catalog/events.md
#	docs/cordis-catalog/services.md
#	docs/core-data-structures/core.md
#	docs/event-producer-consumer.md
#	docs/module-graph.md
#	examples/coding-agent/tests/code-mode.e2e.ts
#	examples/coding-agent/tests/coding-task.e2e.ts
#	examples/coding-agent/tests/compaction.e2e.ts
#	examples/coding-agent/tests/full-loop.e2e.ts
#	examples/coding-agent/tests/todo-write.e2e.ts
#	examples/cordis-agent/tests/cordis-tools.e2e.ts
#	packages/bash/tool-bash/tests/integration.spec.ts
#	packages/bash/tool-bash/tests/tools.spec.ts
#	packages/compact/compact-basic/tests/compact-loop-repro.spec.ts
#	packages/context/time-context/tests/time-context.spec.ts
#	packages/cordis/tool-cordis/src/api-catalog.ts
#	packages/cordis/tool-cordis/tests/integration.spec.ts
#	packages/core/agent-loop/README.md
#	packages/core/agent-loop/src/agent.ts
#	packages/core/agent-loop/src/index.ts
#	packages/core/agent-loop/tests/agent.spec.ts
#	packages/core/agent-loop/tests/cancel.spec.ts
#	packages/core/agent-loop/tests/config-session-id.spec.ts
#	packages/core/agent-loop/tests/contract-regressions.spec.ts
#	packages/core/agent-loop/tests/coverage-edges.spec.ts
#	packages/core/agent-loop/tests/interception.spec.ts
#	packages/core/agent-loop/tests/loop.spec.ts
#	packages/core/agent-loop/tests/properties.spec.ts
#	packages/core/agent-loop/tests/request-cache.e2e.ts
#	packages/core/agent-loop/tests/request-reconstruction.spec.ts
#	packages/core/agent-loop/tests/resume.spec.ts
#	packages/core/agent-loop/tests/scope-lifecycle.spec.ts
#	packages/core/agent-loop/tests/tool-order.spec.ts
#	packages/core/agent-loop/tests/turn-stop.spec.ts
#	packages/core/agent/src/types.ts
#	packages/examples/agent-spine-demo/README.md
#	packages/examples/agent-spine-demo/tests/agent-core.spec.ts
#	packages/examples/stdio-demo/README.md
#	packages/examples/stdio-demo/src/index.ts
#	packages/examples/stdio-demo/tests/stdio-agent.spec.ts
#	packages/fs/tool-fs/tests/fs-tools.e2e.ts
#	packages/guard/repeat-tool-guard/tests/repeat-tool-guard.spec.ts
#	packages/hooks/hooks-claude/tests/bridge.spec.ts
#	packages/hooks/hooks-claude/tests/coverage.spec.ts
#	packages/hooks/hooks-codex/tests/bridge.spec.ts
#	packages/hooks/hooks-codex/tests/coverage.spec.ts
#	packages/subagent/subagent-fork/tests/multi-subagent.spec.ts
#	packages/subagent/subagent-fork/tests/subagent-fork.spec.ts
#	packages/subagent/subagent-inprocess/tests/structured.spec.ts
#	packages/subagent/subagent-inprocess/tests/subagent-inprocess.spec.ts
#	packages/subagent/subagent-spawn/tests/spawn.e2e.ts
#	packages/subagent/subagent-spawn/tests/subagent-spawn.spec.ts
#	packages/todo/tool-todo/tests/integration.spec.ts
#	packages/ui/acp/tests/dispose.spec.ts
#	packages/ui/acp/tests/edges.spec.ts
#	packages/workflow/workflow-workerthread/tests/integration.spec.ts
This commit is contained in:
Tianyi Cui
2026-07-18 12:21:15 +08:00
657 changed files with 36658 additions and 7514 deletions
+130
View File
@@ -0,0 +1,130 @@
<!-- Generated by scripts/gen-website-api.ts — do not edit by hand. Run `pnpm run gen-website-api` to regenerate. -->
# ctx.agents
`AgentRegistry` — provided by `@deepseek-ai/dsh-agent`.
Agent registry (`ctx.agents`): tracks live agents so UI, hook, and orchestrator plugins can find them without depending on the concrete loop package. Agent *creation* is provided by whichever plugin implements the AgentFactory (`@deepseek-ai/dsh-agent-loop`), registered via setFactory.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L201)
### ctx.agents.setFactory(factory)
```ts website-api
setFactory(factory: AgentFactory): () => void
```
Register the agent-creation factory (the loop calls this on construction, effect-scoped). A traced Cordis service is canonicalized to its concrete target; each create/resume call is then traced through that caller's context so ownership follows the caller without stacking proxy layers. Throws if a factory is already registered. Returns the disposer; on dispose the factory slot is cleared.
- `factory` — the loop-owned factory `create`/`resume` delegate to.
**Returns** the disposer that clears the factory slot. The exact Cordis effect disposer (single-shot): composite (generator) effects may yield it directly — exact identity nests the teardown in order.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L228)
### ctx.agents.create(options)
```ts website-api
async create(options: CreateAgentOptions): Promise<AgentHandle>
```
Create and publish a new agent through the registered factory. Distinct from register (which records an already-constructed agent): this constructs the agent and its session. Rejects if no factory is registered or creation/setup fails. The resolved AgentHandle lets the owner tear down exactly this agent.
- `options` — shared identity, session seed/metadata, and agent options.
**Returns** the handle after setup, rollback-covered publication, and loop start complete.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L261)
### ctx.agents.resume(options)
```ts website-api
async resume(options: ResumeAgentOptions): Promise<AgentHandle>
```
Load a persisted session and resume an agent on it through the registered factory. Rejects if no factory is registered; the factory rejects if session persistence is not configured or persistence/setup fails.
- `options` — persisted identity, configuration, and optional setup.
**Returns** the handle after setup, rollback-covered publication, and loop start complete.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L280)
### ctx.agents.register(agent)
```ts website-api
register(agent: Agent): () => void
```
Register a live agent. Throws if an agent with the same id is already registered. Emits `agent/created` on registration and `agent/disposed` when the calling fiber is disposed — both with the agent's scope carrier (`scopeTarget(agent, agent)`): the subject is the agent in hand, so the emits are scope-filtered regardless of which context invoked `register` (calling through `agent.ctx` scopes EFFECTS; dispatch scoping always requires passing the carrier). Returns the disposer.
- `agent` — the already-constructed agent to record in the store.
**Returns** the EXACT Cordis effect disposer (single-shot; a repeat call returns undefined without awaiting an in-flight teardown). Exact identity is load-bearing: a composite (generator) effect that owns a teardown ORDER — the agent factory's lifecycle chain — must yield THIS function so Cordis nests the unregistration at that yield position; yielding a wrapper would leave it disposing as a concurrent sibling on owner unload, unregistering the agent (and emitting `agent/disposed`) while its final turn is still draining.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L306)
### ctx.agents.enter(agent, owner)
```ts website-api
enter(agent: Agent, owner: Agent | undefined): () => void
```
Insert an already-constructed agent without announcing it. This is the advanced ordered-lifecycle primitive used by the async agent factory: it first completes setup while the agent is unpublished, then assigns the returned detach closure into its pre-installed composite teardown before calling announce. Ordinary callers use register.
- `agent` — the prepared, unpublished agent.
- `owner` — live agent whose scoped context created this agent, or undefined for a top-level runtime root. This is runtime ownership, not the resumed session's durable parent lineage.
**Returns** an idempotent closure that removes this exact entry and emits `agent/disposed` with listener failures contained. When called from a synchronous `agent/created` listener, removal and disposal wait until that creation dispatch unwinds.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L330)
### ctx.agents.announce(agent)
```ts website-api
announce(agent: Agent): void
```
Announce an agent previously inserted with enter.
- `agent` — the live inserted agent to announce.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L405)
### ctx.agents.get(id)
```ts website-api
get(id: SessionId): Agent | undefined
```
Look up a live agent.
- `id` — the shared agent/session id to look up.
**Returns** the agent, or undefined when no live agent has that id.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L439)
### ctx.agents.list()
```ts website-api
list(): Agent[]
```
All live agents, in registration order.
**Returns** a fresh array; mutating it does not affect the registry.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L447)
### ctx.agents.roots()
```ts website-api
roots(): Agent[]
```
All live top-level agents in registration order. A top-level agent was created without an owning agent context; durable session lineage does not affect this runtime relation, so a resumed fork may still be a root.
**Returns** a fresh array; mutating it does not affect the registry.
[Source](https://github.com/deepseek-harness/deepseek-harness/blob/master/packages/core/agent/src/index.ts#L457)