Files
deepseek-harness/docs/cordis-catalog/services.md
T
2026-07-12 03:36:43 +08:00

17 KiB

Cordis Services Catalog

Every ctx.<key> service a plugin can call: the exact public interface plus the class JSDoc. This is one axis of the wiring reference a plugin author works against — the events a plugin listens to are the sibling events catalog, and core-data-structures/ catalogs the data structures these signatures move around. An abstract seam (e.g. ctx.bash) is implemented by a separate package; the interface is what consumers code against.

This file is GENERATED from source (scripts/gen-cordis-catalog.ts) and verified fresh by pnpm run verify-cordis-catalog (part of doc-sync) — do not edit it by hand. Signature blocks use a ts cordis-catalog fence (skipped by doc-typecheck, since a bare signature is not standalone-compilable). Type names in a signature link to the page that documents them.

The harness tier below (the @deepseek-ai/dsh-* packages) is the vocabulary this repo owns. The inherited tier at the end is the cordis-core + loader/hmr/timer ctx surface a plugin also sees — pinned vendor source, summarized tersely.

ctx.agentLoopAgentLoop

The agent-loop plugin (ctx.agentLoop): creates ReactLoopAgents, runs their loops, and registers them in ctx.agents. Also implements the AgentFactory seam, so plugins create/resume agents through ctx.agents (the interface) without depending on this concrete package.

The loop itself is deliberately thin — every behavior beyond "call the model, run the tools, repeat" belongs to plugins listening on the event taxonomy declared in @deepseek-ai/dsh-agent.

create(id: AgentId, options: AgentOptions = {}, meta: Pick<SessionHeader, 'cwd'> = {}): ReactLoopAgent
async createAgent(options: CreateAgentOptions): Promise<AgentHandle>
async resume(options: ResumeAgentOptions): Promise<AgentHandle>

Source: packages/core/agent-loop/src/index.ts:62

ctx.agentsAgentRegistry

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.

setFactory(factory: AgentFactory): () => Promise<void> | void
async create(options: CreateAgentOptions): Promise<AgentHandle>
async resume(options: ResumeAgentOptions): Promise<AgentHandle>
register(agent: Agent): () => Promise<void> | void
enter(agent: Agent): () => void
announce(agent: Agent): void
get(id: AgentId): Agent | undefined
list(): Agent[]

Types: Agent

Source: packages/core/agent/src/index.ts:141

ctx.approvalApprovalService

The ctx.approval service: dispatches ApprovalRequests to the approval/request waterfall and audits every ask/outcome pair to the requesting agent's session log. Stateless between requests — grants are returned to the caller, never stored here.

async request(req: ApprovalRequest): Promise<ApprovalOutcome>

Types: ApprovalOutcome · ApprovalRequest

Source: packages/ui/user-approval/src/index.ts:244

ctx.bashBashExecutor (abstract seam)

Abstract bash execution service. Subclass, implement the abstract methods, and load the subclass as a plugin — it registers as ctx.bash (one implementation per context; loading a second throws, which is cordis' standard duplicate-service behavior).

abstract resolve(request: BashExecRequest): BashExecSpec
abstract run(spec: BashExecSpec): Promise<BashRunResult>
abstract start(spec: BashExecSpec): BashTask
abstract get(id: BashTaskId): BashTask | undefined
abstract ownerOf(id: BashTaskId): OwnerToken | undefined
abstract list(): BashTask[]
abstract readOutput(id: BashTaskId): BashTaskRead
abstract kill(id: BashTaskId): boolean
onTaskDone(listener: BashTaskListener): () => void

Types: BashExecRequest · BashExecSpec · BashRunResult · BashTask · BashTaskRead

Source: packages/bash/bash/src/index.ts:36

ctx.codeRuntimeCodeRuntime (abstract seam)

Abstract code-execution service. Subclass, implement run and the two descriptors, and load the subclass as a plugin — it registers as ctx.codeRuntime (one implementation per context; loading a second throws, cordis' standard duplicate-service behavior).

abstract run(request: CodeRunRequest): Promise<CodeRunResult>

Types: CodeRunRequest · CodeRunResult

Source: packages/code-runtime/code-runtime/src/index.ts:29

ctx.compactCompactService (abstract seam)

Abstract compaction service. Subclass implement the two abstract methods, and load the subclass as a plugin — it registers as ctx.compact (one implementation per context; loading a second throws, which is cordis' standard duplicate-service behavior).

abstract compactIfNeeded( agent: CompactAgentContext, fullSystemPrompt: string, sessionPrefix: readonly Message[], signal: AbortSignal, ): Promise<CompactionResult | null>
abstract compactRegion( session: Session, start: number, end: number, agent: CompactAgentContext, signal?: AbortSignal, ): Promise<CompactionResult>

Types: Message

Source: packages/compact/compact/src/index.ts:33

ctx.fsFileSystem (abstract seam)

Abstract filesystem provider service. Subclass, implement the seven storage primitives, and load the subclass as a plugin — it registers as ctx.fs (one implementation per context; loading a second throws, cordis' standard duplicate-service behavior).

abstract resolve(path: string, opts?: { cwd?: string }): Promise<FsTarget>
abstract stat(target: FsTarget, signal?: AbortSignal): Promise<FsInfo | 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[]>
abstract writeText(target: FsTarget, content: string, expected?: FsWriteIntent, signal?: AbortSignal): Promise<FsWriteOutcome>
abstract editText(target: FsTarget, edit: FsEditRequest, expected?: { version: FsVersion }, signal?: AbortSignal): Promise<FsEditOutcome>

Types: FsEditOutcome · FsEditRequest · FsInfo · FsTarget · FsVersion · FsWriteIntent · FsWriteOutcome

Source: packages/fs/fs/src/index.ts:78

ctx.llmLlmService

The abstract llm service: an adapter registry plus a streaming model-call surface, interceptable via the llm/stream waterfall.

registerAdapter(models: string[], adapter: LlmAdapter): () => void
models(): string[]
stream(options: GenerateOptions): AsyncIterable<StreamChunk>

Types: GenerateOptions · StreamChunk

Source: packages/llm/llm/src/index.ts:72

ctx.sandboxSandboxProvider (abstract seam)

Abstract process-sandbox service. Subclass, implement confine, and load the subclass as a plugin — it registers as ctx.sandbox (one implementation per context; loading a second throws, cordis' standard duplicate-service behavior).

abstract confine(argv: readonly string[], policy: SandboxPolicy): ConfinedArgv

Types: ConfinedArgv · SandboxPolicy

Source: packages/sandbox/sandbox/src/index.ts:109

ctx.sessionPersistenceSessionPersistence (abstract seam)

Abstract durable session-persistence service. Subclass, implement the abstract methods, and load the subclass as a plugin — it registers as ctx.sessionPersistence (one implementation per context; loading a second throws, cordis' standard duplicate-service behavior).

abstract create(meta: SessionHeader): Promise<void>
abstract append(id: SessionId, events: readonly SessionEvent[]): Promise<void>
abstract load(id: SessionId): Promise<{ meta: SessionHeader; events: SessionEvent[] }>
abstract list(): Promise<SessionHeader[]>

Types: SessionEvent

Source: packages/session-persistence/session-persistence/src/index.ts:61

ctx.sessionsSessionStore

In-memory session store (ctx.sessions).

Persistence is intentionally not implemented here — persistence plugins subscribe to session/event and flush on session/flush / dispose.

create(id?: SessionId, options?: CreateSessionOptions): Session
prepare(id?: SessionId, options?: CreateSessionOptions): Session
enter(session: Session): () => void
announce(session: Session): void
async flush(session: Session): Promise<void>
get(id: SessionId): Session | undefined
list(): Session[]
fork(source: SessionForkSource, boundary?: number, childSessionId?: SessionId): Session

Source: packages/core/session/src/index.ts:333

ctx.skillsSkillService

Registry of skill providers. It merges provider catalogs with stable first-wins duplicate handling, exposes sorted model-visible summaries, and loads full skill bodies on demand.

registerProvider(provider: SkillProvider): () => Promise<void> | void
register(skill: SkillRegistration): () => Promise<void> | void
async list(options: SkillLookupOptions = {}): Promise<SkillSummary[]>
async get(name: string, options: SkillLookupOptions = {}): Promise<SkillDefinition | undefined>

Source: packages/skill/skill/src/index.ts:157

ctx.subagentsSubagentService

The subagents service: a registry of named SubagentProviders and a capability-checked start surface.

registerProvider(provider: SubagentProvider): () => Promise<void> | void
getProvider(name: string): SubagentProvider | undefined
list(): string[]
start(name: string, request: SubagentStartRequest): SubagentRun

Source: packages/subagent/subagent/src/index.ts:126

ctx.systemPromptSystemPrompt

Registry service (ctx.systemPrompt): plugins contribute ordered text sections, tool-schema providers, named prompt variables, and authoritative contribution protections; the agent loop calls assemble(context) once per step. Registers the harness-owned harness:identity and deployment:persona sections itself (see Config.persona).

section(section: PromptSection): () => Promise<void> | void
tools(provider: (context: AssembleContext) => ToolProviderResult): () => Promise<void> | void
variable(name: string, provider: (context: AssembleContext) => string | undefined): () => Promise<void> | void
protect(protection: PromptProtection): () => Promise<void> | void
async assemble(context: AssembleContext = {}): Promise<PromptAssembly>

Source: packages/core/system-prompt/src/index.ts:291

ctx.toolsToolRegistry

Tool registry (ctx.tools): tool plugins register definitions; the agent loop executes calls through the tools/pre-execute → guards → tools/executetools/post-executetools/result pipeline.

register(definition: ToolDefinition): () => Promise<void> | void
restrict(filter: ToolRestriction): () => Promise<void> | void
guard(guard: ToolGuard): () => Promise<void> | void
visible(scope?: ScopeKey): ToolDefinition[]
get(name: string, scope?: ScopeKey): ToolDefinition | undefined
schemas(scope?: ScopeKey): ToolSchema[]
knownNames(scope?: ScopeKey): string[]
async execute(exec: ToolExecutionInput): Promise<ToolExecutionResult>

Types: ToolDefinition · ToolExecutionInput · ToolExecutionResult

Source: packages/core/tools/src/index.ts:374

ctx.userInteractionUserInteractionService

ctx.userInteraction: one active UI provider plus an ask() surface.

registerProvider(provider: UserInteractionProvider): () => void
async ask(request: AskUserQuestionRequest): Promise<AskUserQuestionAnswer>

Source: packages/ui/user-interaction/src/index.ts:82

ctx.webWebService

The web access service. Registered as ctx.web (one instance per context).

Selection semantics (resolved at execution time, never order-dependent):

  • A configured id that is registered and status().available → that provider.
  • A configured id not registered → WEB_PROVIDER_CONFIGURED_MISSING.
  • A configured id registered but unavailable → WEB_PROVIDER_CONFIGURED_UNAVAILABLE.
  • No id configured, exactly one registered usable provider → that provider.
  • No id configured, multiple usable providers → WEB_PROVIDER_AMBIGUOUS.
  • No id configured, no usable provider → WEB_PROVIDER_UNAVAILABLE.
registerSearchProvider(provider: WebSearchProvider): () => void
registerFetchProvider(provider: WebFetchProvider): () => void
async search(request: WebSearchRequest, exec?: WebExecContext): Promise<WebSearchResult>
async fetch(request: WebFetchRequest, exec?: WebExecContext): Promise<WebFetchResult>

Source: packages/web/web/src/index.ts:79

ctx.workflowsWorkflowService (abstract seam)

Abstract workflow execution service. Subclass, implement start, and load the subclass as a plugin — it registers as ctx.workflows (one implementation per context; loading a second throws, cordis' standard duplicate-service behavior).

abstract start(request: WorkflowStartRequest): WorkflowRun

Source: packages/workflow/workflow/src/index.ts:157

Inherited ctx members (cordis core + loader/hmr/timer)

The framework ctx surface every plugin also sees, beyond the harness services above. This is pinned vendor source (vendoring policy); 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.