dsh-plugin-dev-kb 1.0.8 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/README.en.md +6 -6
- package/README.md +6 -6
- package/kb/INDEX.md +21 -5
- package/kb/README.md +11 -10
- package/kb/extra/AGENTS.md +4 -4
- package/kb/extra/cookbook/adding-a-remote-api.md +197 -0
- package/kb/extra/cookbook/adding-a-remote-api.zh.md +197 -0
- package/kb/extra/cookbook/adding-a-vendored-package.md +2 -2
- package/kb/extra/cookbook/adding-a-vendored-package.zh.md +2 -2
- package/kb/extra/deepseek-llm-api-wire-extensions.md +163 -0
- package/kb/extra/deepseek-llm-api-wire-extensions.zh.md +163 -0
- package/kb/extra/development.md +8 -14
- package/kb/extra/development.zh.md +8 -14
- package/kb/extra/event-producer-consumer.md +55 -48
- package/kb/extra/event-producer-consumer.zh.md +58 -51
- package/kb/extra/glossary.md +1 -1
- package/kb/extra/glossary.zh.md +1 -1
- package/kb/extra/graph-atlas.md +0 -2
- package/kb/extra/graph-atlas.zh.md +0 -2
- package/kb/extra/i18n/README.md +4 -4
- package/kb/extra/i18n/README.zh.md +4 -4
- package/kb/extra/i18n/style-samples.md +2 -2
- package/kb/extra/module-graph.md +646 -926
- package/kb/extra/module-graph.zh.md +648 -928
- package/kb/extra/postmortem/0001-acp-default-export-drops-inject.md +2 -2
- package/kb/extra/postmortem/0001-acp-default-export-drops-inject.zh.md +2 -2
- package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.md +2 -2
- package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md +2 -2
- package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.md +2 -2
- package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.zh.md +2 -2
- package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.md +1 -1
- package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.zh.md +1 -1
- package/kb/extra/rescope.md +2 -2
- package/kb/extra/rescope.zh.md +2 -2
- package/kb/extra/subsystems/agent-team.md +28 -4
- package/kb/extra/subsystems/agent-team.zh.md +28 -4
- package/kb/extra/subsystems/attachment.md +168 -7
- package/kb/extra/subsystems/attachment.zh.md +168 -7
- package/kb/extra/subsystems/extensions.md +18 -0
- package/kb/extra/subsystems/extensions.zh.md +18 -0
- package/kb/extra/subsystems/feedback.md +4 -4
- package/kb/extra/subsystems/feedback.zh.md +4 -4
- package/kb/extra/subsystems/todo.md +32 -0
- package/kb/extra/subsystems/todo.zh.md +32 -0
- package/kb/extra/subsystems/webhook.md +70 -0
- package/kb/extra/subsystems/webhook.zh.md +70 -0
- package/kb/extra/testing.md +15 -10
- package/kb/extra/testing.zh.md +13 -8
- package/kb/extra/web-styling.md +4 -0
- package/kb/extra/web-styling.zh.md +4 -0
- package/kb/meta/search-index.json +309 -177
- package/kb/meta/site-pages.txt +183 -167
- package/kb/meta/source.json +5 -5
- package/kb/meta/topics.md +14 -6
- package/kb/site/develop/basic/publish.md +2 -2
- package/kb/site/develop/basic/tool.md +1 -1
- package/kb/site/develop/cordis-tutorial/07-into-the-harness.md +5 -4
- package/kb/site/develop/framework/events.md +1 -1
- package/kb/site/develop/practice/dynamic-cordis.md +17 -0
- package/kb/site/develop/practice/llm-adapter.md +4 -3
- package/kb/site/en/develop/basic/publish.md +2 -2
- package/kb/site/en/develop/basic/tool.md +1 -1
- package/kb/site/en/develop/cordis-tutorial/07-into-the-harness.md +5 -4
- package/kb/site/en/develop/framework/events.md +1 -1
- package/kb/site/en/develop/practice/dynamic-cordis.md +17 -0
- package/kb/site/en/develop/practice/llm-adapter.md +4 -3
- package/kb/site/en/guide/github-review.md +104 -0
- package/kb/site/en/guide/mcp-memory.md +103 -0
- package/kb/site/en/guide/network-proxy.md +87 -0
- package/kb/site/en/guide/providers.md +70 -17
- package/kb/site/en/guide/python-sdk.md +80 -34
- package/kb/site/en/guide/schedule.md +23 -0
- package/kb/site/en/reference/agent-lifecycle.md +6 -4
- package/kb/{extra → site/en/reference}/api-gateway.md +12 -10
- package/kb/site/en/reference/capability-seams.md +128 -73
- package/kb/site/en/reference/config-catalog.md +481 -360
- package/kb/site/en/reference/cookbook/adding-a-package.md +3 -4
- package/kb/site/en/reference/cookbook/adding-a-settings-card.md +12 -10
- package/kb/site/en/reference/cookbook/adding-a-tool.md +11 -4
- package/kb/site/en/reference/cookbook/adding-an-llm-adapter.md +1 -1
- package/kb/site/en/reference/cookbook/extension-cookbook.md +20 -17
- package/kb/site/en/reference/cordis-api/inherited.md +1 -1
- package/kb/site/en/reference/cordis-primer.md +2 -1
- package/kb/site/en/reference/index.md +30 -11
- package/kb/site/en/reference/persistence-catalog.md +148 -80
- package/kb/site/en/reference/subsystems/approval.md +10 -10
- package/kb/site/en/reference/subsystems/client-modules.md +58 -16
- package/kb/site/en/reference/subsystems/code-runtime.md +10 -6
- package/kb/site/en/reference/subsystems/commands.md +25 -16
- package/kb/site/en/reference/subsystems/compaction.md +11 -11
- package/kb/site/en/reference/{cookbook/adding-a-conversation-node.md → subsystems/conversation.md} +50 -24
- package/kb/site/en/reference/subsystems/core.md +156 -17
- package/kb/site/en/reference/subsystems/credentials.md +44 -3
- package/kb/site/en/reference/subsystems/filesystem.md +12 -2
- package/kb/site/en/reference/subsystems/goal.md +1 -1
- package/kb/site/en/reference/subsystems/index.md +7 -2
- package/kb/site/en/reference/subsystems/jobs.md +1 -1
- package/kb/site/en/reference/subsystems/llm-streaming.md +154 -12
- package/kb/site/en/reference/subsystems/permission-presets.md +6 -6
- package/kb/site/en/reference/subsystems/persistence.md +185 -175
- package/kb/site/en/reference/subsystems/plan.md +2 -2
- package/kb/site/en/reference/subsystems/sandbox.md +2 -0
- package/kb/site/en/reference/subsystems/schedule.md +9 -3
- package/kb/site/en/reference/subsystems/session-projection.md +115 -48
- package/kb/site/en/reference/subsystems/session-query.md +28 -14
- package/kb/site/en/reference/subsystems/session-reference.md +53 -8
- package/kb/site/en/reference/subsystems/session-telemetry.md +8 -8
- package/kb/site/en/reference/subsystems/session-title.md +6 -6
- package/kb/site/en/reference/subsystems/session.md +401 -99
- package/kb/site/en/reference/subsystems/settings.md +101 -6
- package/kb/site/en/reference/subsystems/skills.md +23 -0
- package/kb/site/en/reference/subsystems/slots.md +178 -0
- package/kb/site/en/reference/subsystems/spill.md +2 -2
- package/kb/site/en/reference/subsystems/storage.md +34 -3
- package/kb/site/en/reference/subsystems/subagent.md +122 -109
- package/kb/site/en/reference/subsystems/system-prompt.md +17 -4
- package/kb/site/en/reference/subsystems/token-meter.md +27 -12
- package/kb/site/en/reference/subsystems/tools.md +39 -39
- package/kb/site/en/reference/subsystems/typert.md +62 -55
- package/kb/site/en/reference/subsystems/user-questions.md +33 -33
- package/kb/site/en/reference/subsystems/web-client.md +98 -0
- package/kb/site/en/reference/subsystems/web-server.md +11 -5
- package/kb/site/en/reference/subsystems/web.md +7 -1
- package/kb/site/en/reference/subsystems/workspace.md +102 -9
- package/kb/site/en/reference/tool-catalog.md +86 -82
- package/kb/site/en/reference/tool-execution-pipeline.md +1 -1
- package/kb/site/guide/github-review.md +104 -0
- package/kb/site/guide/mcp-memory.md +103 -0
- package/kb/site/guide/network-proxy.md +87 -0
- package/kb/site/guide/providers.md +70 -17
- package/kb/site/guide/python-sdk.md +87 -41
- package/kb/site/guide/schedule.md +23 -0
- package/kb/site/reference/agent-lifecycle.md +6 -4
- package/kb/{extra/api-gateway.zh.md → site/reference/api-gateway.md} +12 -10
- package/kb/site/reference/capability-seams.md +128 -73
- package/kb/site/reference/config-catalog.md +481 -360
- package/kb/site/reference/cookbook/adding-a-package.md +3 -4
- package/kb/site/reference/cookbook/adding-a-settings-card.md +12 -10
- package/kb/site/reference/cookbook/adding-a-tool.md +11 -4
- package/kb/site/reference/cookbook/adding-an-llm-adapter.md +1 -1
- package/kb/site/reference/cookbook/extension-cookbook.md +20 -17
- package/kb/site/reference/cordis-api/inherited.md +1 -1
- package/kb/site/reference/cordis-primer.md +2 -1
- package/kb/site/reference/index.md +30 -11
- package/kb/site/reference/persistence-catalog.md +148 -80
- package/kb/site/reference/subsystems/approval.md +10 -10
- package/kb/site/reference/subsystems/client-modules.md +58 -16
- package/kb/site/reference/subsystems/code-runtime.md +10 -6
- package/kb/site/reference/subsystems/commands.md +25 -16
- package/kb/site/reference/subsystems/compaction.md +11 -11
- package/kb/site/reference/{cookbook/adding-a-conversation-node.md → subsystems/conversation.md} +50 -24
- package/kb/site/reference/subsystems/core.md +156 -17
- package/kb/site/reference/subsystems/credentials.md +44 -3
- package/kb/site/reference/subsystems/filesystem.md +12 -2
- package/kb/site/reference/subsystems/goal.md +1 -1
- package/kb/site/reference/subsystems/index.md +7 -2
- package/kb/site/reference/subsystems/jobs.md +1 -1
- package/kb/site/reference/subsystems/llm-streaming.md +154 -12
- package/kb/site/reference/subsystems/permission-presets.md +5 -5
- package/kb/site/reference/subsystems/persistence.md +184 -174
- package/kb/site/reference/subsystems/plan.md +2 -2
- package/kb/site/reference/subsystems/schedule.md +9 -3
- package/kb/site/reference/subsystems/session-projection.md +115 -48
- package/kb/site/reference/subsystems/session-query.md +28 -14
- package/kb/site/reference/subsystems/session-reference.md +53 -8
- package/kb/site/reference/subsystems/session-telemetry.md +8 -8
- package/kb/site/reference/subsystems/session-title.md +6 -6
- package/kb/site/reference/subsystems/session.md +401 -99
- package/kb/site/reference/subsystems/settings.md +101 -6
- package/kb/site/reference/subsystems/skills.md +23 -0
- package/kb/site/reference/subsystems/slots.md +178 -0
- package/kb/site/reference/subsystems/spill.md +2 -2
- package/kb/site/reference/subsystems/storage.md +34 -3
- package/kb/site/reference/subsystems/subagent.md +122 -109
- package/kb/site/reference/subsystems/system-prompt.md +17 -4
- package/kb/site/reference/subsystems/token-meter.md +27 -12
- package/kb/site/reference/subsystems/tools.md +39 -39
- package/kb/site/reference/subsystems/typert.md +62 -55
- package/kb/site/reference/subsystems/user-questions.md +33 -33
- package/kb/site/reference/subsystems/web-client.md +98 -0
- package/kb/site/reference/subsystems/web-server.md +11 -5
- package/kb/site/reference/subsystems/web.md +7 -1
- package/kb/site/reference/subsystems/workspace.md +102 -9
- package/kb/site/reference/tool-catalog.md +85 -81
- package/kb/site/reference/tool-execution-pipeline.md +1 -1
- package/package.json +2 -2
- package/skills/dsh-plugin-dev-kb.md +8 -6
|
@@ -20,7 +20,7 @@ A turn flows through the six packages in one loop: the driver in [`agent-loop`](
|
|
|
20
20
|
| `agent-loop/` | The concrete driver implementing the public `Agent` contract (`ctx.agentLoop`) | this page |
|
|
21
21
|
| `scope/` | The scoped-registration primitive the registries and loop build per-agent scoping on | [scope.md](./scope.md) |
|
|
22
22
|
|
|
23
|
-
`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.
|
|
23
|
+
`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. [`dsh-base`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/bundle/base/README.md) is the default product composition, while [`dsh-sdk-minimal`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/bundle/sdk-minimal/README.md) declares a smaller standalone tree.
|
|
24
24
|
|
|
25
25
|
## Creation and ownership
|
|
26
26
|
|
|
@@ -49,7 +49,7 @@ interface AgentHandle {
|
|
|
49
49
|
}
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
`CreateAgentOptions` carries the shared identity and everything a fresh agent needs before publication: session metadata (`meta` — validated `cwd`, fork lineage,
|
|
52
|
+
`CreateAgentOptions` carries the shared identity and everything a fresh agent needs before publication: session metadata (`meta` — validated `cwd`, fork lineage, the `isSeeded` marker, origin classification, delegation depth, and `agentPreset`), the exact fork cut in sibling field `inheritedEventCount`, an optional `seed` replay prefix, 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.
|
|
53
53
|
|
|
54
54
|
`AgentFactory` is the creation interface behind the registry: the loop registers its factory via `ctx.agents.setFactory()`, so consumers use `ctx.agents` without depending on the concrete loop package. The exact `create`/`resume` signatures and rollback contracts are in the [generated section](#ctxagents--agentregistry) below.
|
|
55
55
|
|
|
@@ -60,9 +60,9 @@ interface AgentHandle {
|
|
|
60
60
|
Source: [`packages/core/agent/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/types.ts)
|
|
61
61
|
|
|
62
62
|
```ts type-equiv
|
|
63
|
-
/** Public live-agent handle. */
|
|
63
|
+
/** Public live-agent handle; the runtime face augments its live capabilities. */
|
|
64
64
|
interface Agent {
|
|
65
|
-
/**
|
|
65
|
+
/** Session-backed Agent identity. */
|
|
66
66
|
readonly id: SessionId
|
|
67
67
|
/** The provider route and model this agent's requests use. */
|
|
68
68
|
readonly options: AgentOptions
|
|
@@ -155,6 +155,44 @@ interface Agent {
|
|
|
155
155
|
type AgentStatus = 'idle' | 'running'
|
|
156
156
|
```
|
|
157
157
|
|
|
158
|
+
```ts type-equiv
|
|
159
|
+
/** One process-local live assistant streaming publication. */
|
|
160
|
+
type AssistantStreamFrame =
|
|
161
|
+
| {
|
|
162
|
+
readonly type: 'start'
|
|
163
|
+
readonly attemptId: LlmAttemptId
|
|
164
|
+
/** Monotone within one attached Agent lifecycle; replacement restarts at 1. */
|
|
165
|
+
readonly revision: number
|
|
166
|
+
readonly turn: number
|
|
167
|
+
readonly step: number
|
|
168
|
+
}
|
|
169
|
+
| {
|
|
170
|
+
readonly type: 'chunk'
|
|
171
|
+
readonly attemptId: LlmAttemptId
|
|
172
|
+
readonly revision: number
|
|
173
|
+
/** Dense zero-based position within the attempt. */
|
|
174
|
+
readonly index: number
|
|
175
|
+
/** Safe-integer timestamp reused by the durable embedded stream. */
|
|
176
|
+
readonly time: number
|
|
177
|
+
readonly chunk: StreamChunk
|
|
178
|
+
}
|
|
179
|
+
| {
|
|
180
|
+
readonly type: 'end'
|
|
181
|
+
readonly attemptId: LlmAttemptId
|
|
182
|
+
readonly revision: number
|
|
183
|
+
/** Number of chunk frames emitted by this attempt. */
|
|
184
|
+
readonly index: number
|
|
185
|
+
/** Durable settlement committed before this notification, or live abandonment without one. */
|
|
186
|
+
readonly outcome:
|
|
187
|
+
| {
|
|
188
|
+
readonly kind: 'committed'
|
|
189
|
+
readonly eventType: 'assistant/message' | 'assistant/attempt'
|
|
190
|
+
readonly seq: SessionSeq
|
|
191
|
+
}
|
|
192
|
+
| { readonly kind: 'abandoned' }
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
158
196
|
`running` describes the driver-wide drain interval and may span consecutive queued turns; it does not prove a turn is still open. Disposal removes the agent from the registry and emits `agent/disposed`; it is not a terminal status value. `followup()` returns no handle: its `MessageId` identifies durable inbox insertion, claim, and discard facts, not a later assistant output or turn ending. `whenIdle()` observes the whole agent, so callers may call a receipt-to-idle interval a run only when they explicitly own that interval ([decision](https://github.com/deepseek-ai/deepseek-harness/blob/master/.agents/notes/implemented/architecture/2026-07-30-followup-enqueue-and-owned-runs.md)).
|
|
159
197
|
|
|
160
198
|
```ts type-equiv
|
|
@@ -164,12 +202,14 @@ interface AgentOptions {
|
|
|
164
202
|
provider?: string
|
|
165
203
|
/** Model id interpreted by the selected provider adapter. */
|
|
166
204
|
model?: string
|
|
205
|
+
/** Adapter-owned reasoning effort for the selected provider/model route. */
|
|
206
|
+
reasoningEffort?: ReasoningEffortId
|
|
167
207
|
/** Maximum output tokens for each conversation-model request. */
|
|
168
208
|
maxTokens?: number
|
|
169
209
|
}
|
|
170
210
|
```
|
|
171
211
|
|
|
172
|
-
Dispatch requires `provider` and `model` after `agent/request`. When present, `maxTokens` must be a positive safe integer and caps every conversation-model request; omission allows the exact-model adapter default to materialize before the request header, or otherwise leaves provider behavior unchanged. An agent-scoped `deployment:persona` prompt section may shadow the global default persona.
|
|
212
|
+
Dispatch requires `provider` and `model` after `agent/request`. An explicit `reasoningEffort` seeds the first request on that route; exact-model resolution validates it, while omission allows the adapter default to materialize. When present, `maxTokens` must be a positive safe integer and caps every conversation-model request; omission allows the exact-model adapter default to materialize before the request header, or otherwise leaves provider behavior unchanged. An agent-scoped `deployment:persona` prompt section may shadow the global default persona.
|
|
173
213
|
|
|
174
214
|
The inbox is the delivery vocabulary — two ordered pending-message lists the agent owns as a durable projection:
|
|
175
215
|
|
|
@@ -203,7 +243,7 @@ type AgentCancelCause =
|
|
|
203
243
|
| { readonly kind: 'disposed' }
|
|
204
244
|
```
|
|
205
245
|
|
|
206
|
-
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`
|
|
246
|
+
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` records the outcome as `{ kind: 'aborted', reason: TurnEndCancelCause }`, so the cancel cause lands in the terminal result.
|
|
207
247
|
|
|
208
248
|
The [event taxonomy](../index.md#events) owns the `agent/*` lifecycle, checkpoint, and waterfall contracts. Turn and step boundaries are durable session events rather than agent emits.
|
|
209
249
|
|
|
@@ -225,7 +265,12 @@ It returns a `PreStepDecision`. Reject opens no step. Enter supplies the complet
|
|
|
225
265
|
/** Whether and with which messages the loop enters a proposed step. */
|
|
226
266
|
type PreStepDecision =
|
|
227
267
|
| { kind: 'reject' }
|
|
228
|
-
| {
|
|
268
|
+
| {
|
|
269
|
+
kind: 'enter'
|
|
270
|
+
messages: UserMessage[]
|
|
271
|
+
/** Start a distinct model-message series before this step's admitted messages. */
|
|
272
|
+
startsRequestSeries?: true
|
|
273
|
+
}
|
|
229
274
|
```
|
|
230
275
|
|
|
231
276
|
`agent/request-error` runs after a failed model step closes and before its turn closes. Listeners can repair durable state or await policy work while the failed turn's signal is still live. A handling listener returns `{ kind: 'retry' }` without calling `next()`; the default `undefined` leaves the failure terminal.
|
|
@@ -235,7 +280,7 @@ type PreStepDecision =
|
|
|
235
280
|
type RequestErrorAction = { kind: 'retry' } | undefined
|
|
236
281
|
```
|
|
237
282
|
|
|
238
|
-
`agent/pre-step` is the only
|
|
283
|
+
`agent/pre-step` is the only waterfall listener chain before request derivation. `agent/turn-stopping` runs when a turn has no tool or steering continuation, before one final steering drain.
|
|
239
284
|
|
|
240
285
|
`agent/session-start` carries a `SessionStartSource` (why the session lifecycle began; a bridge keys its SessionStart matcher on it):
|
|
241
286
|
|
|
@@ -248,7 +293,7 @@ type SessionStartSource = 'startup' | 'resume' | 'clear' | 'compact'
|
|
|
248
293
|
|
|
249
294
|
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`.
|
|
250
295
|
|
|
251
|
-
The `SessionEvent` envelope's exact conditional fields, the twelve event variants (`turn/start`, `turn/end`, `step/start`, `step/end`, `user/message`, `assistant/
|
|
296
|
+
The `SessionEvent` envelope's exact conditional fields, the twelve core event variants (`turn/start`, `turn/end`, `step/start`, `step/end`, `user/message`, `assistant/message`, `assistant/attempt`, `tool/call`, `tool/result`, `request/header`, `request/context`, `session/end-seed`), the `deriveMessages()` projection rules, the `TurnEndReason` reasons, and the execution-enclosure and standalone-event rules are on **[session.md](./session.md)**. How the log is made durable — the `SessionPersistence` interface, JSONL provider, `session/flush` checkpoint, crash recovery, and `SessionHeader` — is on **[persistence.md](./persistence.md)**.
|
|
252
297
|
|
|
253
298
|
## `ToolDefinition`
|
|
254
299
|
|
|
@@ -283,14 +328,13 @@ declare module '@deepseek-ai/dsh-llm' {
|
|
|
283
328
|
}
|
|
284
329
|
```
|
|
285
330
|
|
|
286
|
-
|
|
331
|
+
Five canonical maps use this pattern; a plugin author extends these:
|
|
287
332
|
|
|
288
333
|
| Map | Package | Derives | Catalog |
|
|
289
334
|
|---|---|---|---|
|
|
290
335
|
| `ContentBlockMap` | dsh-llm | `ContentBlock` | [llm-streaming.md](./llm-streaming.md#content-blocks-and-messages) |
|
|
291
336
|
| `MessageSourceMap` | dsh-llm | `MessageSource` | [llm-streaming.md](./llm-streaming.md#content-blocks-and-messages) |
|
|
292
337
|
| `FinishReasonMap` | dsh-llm | `FinishReason` | [llm-streaming.md](./llm-streaming.md#the-model-request-and-result) |
|
|
293
|
-
| `TurnTriggerMap` | dsh-session | `TurnTrigger` | [session.md](./session.md) |
|
|
294
338
|
| `TurnEndReasonMap` | dsh-session | `TurnEndReason` | [session.md](./session.md) |
|
|
295
339
|
| `SessionEventMap` | dsh-session | `SessionEvent` | [session.md](./session.md) |
|
|
296
340
|
|
|
@@ -298,9 +342,9 @@ Two large discriminated unions are the ones consumers `switch` over most: **`Str
|
|
|
298
342
|
|
|
299
343
|
### Branded IDs
|
|
300
344
|
|
|
301
|
-
IDs passed between packages are **branded** — structurally strings, but non-interchangeable at the type level (a `SessionId` cannot be passed where a `
|
|
345
|
+
IDs passed between packages are **branded** — structurally strings, but non-interchangeable at the type level (a `SessionId` cannot be passed where a `ToolCallId` is expected). Construction uses the shared `brandString<T>()` helper or an owner-defined validating factory; comparison, logging, and JSON behave as ordinary strings.
|
|
302
346
|
|
|
303
|
-
The `Branded<B>` primitive
|
|
347
|
+
The `Branded<B>` primitive and stateless constructor live in [dsh-brand](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/util/brand), which has no harness capability dependency. `brandString<T>()` applies a compile-time-only string brand.
|
|
304
348
|
|
|
305
349
|
Source: [`packages/util/brand/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/util/brand/src/index.ts)
|
|
306
350
|
|
|
@@ -309,7 +353,7 @@ Source: [`packages/util/brand/src/index.ts`](https://github.com/deepseek-ai/deep
|
|
|
309
353
|
type Branded<B extends string> = string & { readonly [BRAND]: B }
|
|
310
354
|
```
|
|
311
355
|
|
|
312
|
-
The two core IDs are `
|
|
356
|
+
The two core IDs are `ToolCallId` (correlates a tool call with its result; dsh-llm) and `SessionId` (the shared live agent and durable session identity; dsh-session). Capability packages brand their own ids too, such as `JobId` in [jobs.md](./jobs.md).
|
|
313
357
|
|
|
314
358
|
<!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
|
|
315
359
|
|
|
@@ -353,13 +397,14 @@ Concrete agent factory and driver service.
|
|
|
353
397
|
/**
|
|
354
398
|
* Create an agent and session under one caller-supplied identity, owned by
|
|
355
399
|
* the accessing fiber. Constructor-driven config calls mint a fresh combined
|
|
356
|
-
* id before entering this boundary.
|
|
400
|
+
* id before entering this boundary. When a persistence backend is mounted,
|
|
401
|
+
* the session's durable identity and any seed are stored before publication.
|
|
357
402
|
* @param id - shared agent/session identity.
|
|
358
403
|
* @param options - concrete loop options.
|
|
359
404
|
* @param meta - optional fresh-session workspace metadata.
|
|
360
405
|
* @returns the published running agent.
|
|
361
406
|
*/
|
|
362
|
-
create(id: SessionId, options: AgentOptions = {}, meta: Pick<SessionHeader, 'cwd'> = {}): Agent
|
|
407
|
+
async create(id: SessionId, options: AgentOptions = {}, meta: Pick<SessionHeader, 'cwd'> = {}): Promise<Agent>
|
|
363
408
|
|
|
364
409
|
/**
|
|
365
410
|
* Create an owned agent on a caller-supplied session id.
|
|
@@ -397,6 +442,35 @@ Discovery is unmemoized: `list()` and `resolve()` re-read the roots on every cal
|
|
|
397
442
|
*/
|
|
398
443
|
async list(): Promise<AgentPreset[]>
|
|
399
444
|
|
|
445
|
+
/**
|
|
446
|
+
* The roster off the Host: {@link list} projected to path-free rows, with
|
|
447
|
+
* the default marked and this deployment's authoring capability beside it.
|
|
448
|
+
*
|
|
449
|
+
* Whether a client can open a preset's directory is the Host's own opener
|
|
450
|
+
* capability, not a roster property — a caller needing both joins them.
|
|
451
|
+
* @returns the rows and the authoring capability.
|
|
452
|
+
*/
|
|
453
|
+
@Remote('list') async remoteExportList(): Promise<AgentPresetRoster>
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Every preset's composition as flattened plugin rows, for plugin-listing
|
|
457
|
+
* surfaces beside the roster's own picker.
|
|
458
|
+
*
|
|
459
|
+
* A preset with a live standing mount answers from its newest generation's
|
|
460
|
+
* Loader entries — the composition new sessions join — even when the file
|
|
461
|
+
* behind it has since been edited into an unreadable state: the mount is
|
|
462
|
+
* what sessions actually run, so the broken verdict only applies to a
|
|
463
|
+
* preset nothing composed. One never composed since boot answers from its
|
|
464
|
+
* file, with `!!js` disabled gates evaluated against the Loader context so
|
|
465
|
+
* both answers reflect the same host. Reading never mounts: an unmounted
|
|
466
|
+
* preset is parsed, not composed, so listing a preset's plugins cannot
|
|
467
|
+
* activate them early. A composition that stopped reading between
|
|
468
|
+
* discovery's health verdict and this read is reported broken with the
|
|
469
|
+
* raced reason rather than dropped.
|
|
470
|
+
* @returns one composition per roster preset, in roster order.
|
|
471
|
+
*/
|
|
472
|
+
async compositionInventory(): Promise<AgentPresetComposition[]>
|
|
473
|
+
|
|
400
474
|
/**
|
|
401
475
|
* Resolve one preset by id.
|
|
402
476
|
*
|
|
@@ -471,6 +545,15 @@ composedPreset(agentCtx: Context): string | undefined
|
|
|
471
545
|
*/
|
|
472
546
|
async read(id: string): Promise<string>
|
|
473
547
|
|
|
548
|
+
/**
|
|
549
|
+
* One preset's composition text with the roster row it belongs to.
|
|
550
|
+
* @param agentPreset - the preset id.
|
|
551
|
+
* @returns the composition beside its trust and published metadata.
|
|
552
|
+
* @throws {RemoteError} `gateway/bad-request` for an empty id, or
|
|
553
|
+
* `agent-preset/not-found` when no configured root supplies it.
|
|
554
|
+
*/
|
|
555
|
+
@Remote('read') async readDocument(agentPreset: string): Promise<AgentPresetDocument>
|
|
556
|
+
|
|
474
557
|
/**
|
|
475
558
|
* Create a locally authored preset by copying an existing one whole.
|
|
476
559
|
*
|
|
@@ -488,13 +571,34 @@ async read(id: string): Promise<string>
|
|
|
488
571
|
*/
|
|
489
572
|
async copy(from: string, id: string, name?: string): Promise<void>
|
|
490
573
|
|
|
574
|
+
/**
|
|
575
|
+
* Copy one preset through the Remote API.
|
|
576
|
+
* @param from - the source preset id.
|
|
577
|
+
* @param id - the new preset id.
|
|
578
|
+
* @param name - the copy's optional display name.
|
|
579
|
+
* @returns once the copy is stored.
|
|
580
|
+
* @throws {RemoteError} with the corresponding stable preset code and
|
|
581
|
+
* details when the copy is refused.
|
|
582
|
+
*/
|
|
583
|
+
@Remote('copy') async remoteExportCopy(from: string, id: string, name?: string): Promise<void>
|
|
584
|
+
|
|
491
585
|
/**
|
|
492
586
|
* Delete a locally authored preset.
|
|
587
|
+
*
|
|
493
588
|
* @param id - the preset id.
|
|
494
589
|
* @throws when the preset is unknown or ships with the deployment.
|
|
495
590
|
*/
|
|
496
591
|
async remove(id: string): Promise<void>
|
|
497
592
|
|
|
593
|
+
/**
|
|
594
|
+
* Delete one preset through the Remote API.
|
|
595
|
+
* @param id - the preset id.
|
|
596
|
+
* @returns once the preset is deleted.
|
|
597
|
+
* @throws {RemoteError} with the corresponding stable preset code and
|
|
598
|
+
* details when deletion is refused.
|
|
599
|
+
*/
|
|
600
|
+
@Remote('deletePreset') async remoteExportDelete(id: string): Promise<void>
|
|
601
|
+
|
|
498
602
|
/**
|
|
499
603
|
* One agent's instance of a service its preset mounted.
|
|
500
604
|
*
|
|
@@ -527,7 +631,9 @@ serviceFor<K extends string & keyof Context>(agent: { ctx: Context }, name: K):
|
|
|
527
631
|
* state to restore. The re-link runs through the binding this roster kept
|
|
528
632
|
* from the agent's mount — dsh-scope's only re-link authority. An agent
|
|
529
633
|
* that never composed one has nothing to re-link: the switch is then the
|
|
530
|
-
* agent's first bind, exactly a mount.
|
|
634
|
+
* agent's first bind, exactly a mount. A committed re-link emits
|
|
635
|
+
* `tools/change` because changing the parent scope changes the Agent's
|
|
636
|
+
* resolved tool set without adding or removing registry entries.
|
|
531
637
|
* @param agentCtx - the agent's scope context.
|
|
532
638
|
* @param id - the preset to compose the agent from instead.
|
|
533
639
|
* @returns the preset now installed.
|
|
@@ -535,6 +641,16 @@ serviceFor<K extends string & keyof Context>(agent: { ctx: Context }, name: K):
|
|
|
535
641
|
*/
|
|
536
642
|
async recompose(agentCtx: Context, id: string): Promise<AgentPreset>
|
|
537
643
|
|
|
644
|
+
/**
|
|
645
|
+
* Compose a blank session's agent from a different preset and record it.
|
|
646
|
+
* @param agent - the session's live agent, resolved from the wire identity.
|
|
647
|
+
* @param agentPreset - the preset to compose the agent from instead.
|
|
648
|
+
* @returns the preset id that was recorded.
|
|
649
|
+
* @throws {RemoteError} with `gateway/bad-request`, `agent-preset/locked`,
|
|
650
|
+
* `agent-preset/not-found`, or `agent-preset/invalid` when refused.
|
|
651
|
+
*/
|
|
652
|
+
@Remote('select') async select(agent: Agent, agentPreset: string): Promise<string>
|
|
653
|
+
|
|
538
654
|
/**
|
|
539
655
|
* The standing scope key of one preset, for a host reader with no agent.
|
|
540
656
|
*
|
|
@@ -729,6 +845,29 @@ Source: [`packages/core/agent/src/index.ts`](https://github.com/deepseek-ai/deep
|
|
|
729
845
|
|
|
730
846
|
### `agent/*` events
|
|
731
847
|
|
|
848
|
+
<a id="agentassistant-stream--emit"></a>
|
|
849
|
+
|
|
850
|
+
#### `agent/assistant-stream` — emit
|
|
851
|
+
|
|
852
|
+
Process-local assistant-stream publication. Chunk frames are transient; the loop appends one final v2 `assistant/message` or `assistant/attempt` with the same stream before a committed end frame.
|
|
853
|
+
|
|
854
|
+
```ts cordis-catalog
|
|
855
|
+
/**
|
|
856
|
+
* Process-local assistant-stream publication. Chunk frames are transient;
|
|
857
|
+
* the loop appends one final v2 `assistant/message` or `assistant/attempt`
|
|
858
|
+
* with the same stream before a committed end frame.
|
|
859
|
+
* @param payload.agent - the agent whose attempt produced the frame.
|
|
860
|
+
* @param payload.frame - one ordered start, chunk, or end publication.
|
|
861
|
+
* Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.
|
|
862
|
+
* @mode emit
|
|
863
|
+
*/
|
|
864
|
+
'agent/assistant-stream'(this: Scoped<Agent>, payload: { agent: Agent; frame: AssistantStreamFrame }): void
|
|
865
|
+
```
|
|
866
|
+
|
|
867
|
+
Types: [Scoped](./scope.md)
|
|
868
|
+
|
|
869
|
+
Source: [`packages/core/agent/src/runtime-types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
|
|
870
|
+
|
|
732
871
|
<a id="agentcreated--emit"></a>
|
|
733
872
|
|
|
734
873
|
#### `agent/created` — emit
|
|
@@ -37,13 +37,17 @@ interface ResolvedCredential {
|
|
|
37
37
|
`describe(ref)` answers configuration surfaces without ever exposing a value: whether the reference resolves, from which layer, and whether `set` would currently succeed. The local provider reports a reference supplied by the live process environment as `writable: false` — a write would appear to succeed while resolution kept returning the shadowing value, so the seam rejects it and the UI can render the reference read-only up front.
|
|
38
38
|
|
|
39
39
|
```ts type-equiv
|
|
40
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* Source and writability facts for one reference, safe for configuration UIs —
|
|
42
|
+
* never the value. The view has no slot a value could ride in, which is what
|
|
43
|
+
* lets the whole read half cross the Remote wire.
|
|
44
|
+
*/
|
|
41
45
|
interface CredentialInfo {
|
|
42
|
-
/** Whether
|
|
46
|
+
/** Whether resolving the reference would currently return a value. */
|
|
43
47
|
configured: boolean
|
|
44
48
|
/** Source layer currently supplying the value; absent while unconfigured. */
|
|
45
49
|
source?: string
|
|
46
|
-
/** Whether
|
|
50
|
+
/** Whether the active provider can write this reference. */
|
|
47
51
|
writable: boolean
|
|
48
52
|
}
|
|
49
53
|
```
|
|
@@ -215,6 +219,43 @@ abstract deleteRecord(key: CredentialKey): Promise<void>
|
|
|
215
219
|
|
|
216
220
|
Source: [`packages/credentials/credentials/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/credentials/credentials/src/index.ts)
|
|
217
221
|
|
|
222
|
+
<a id="ctxcredentialscontroller--credentialscontroller"></a>
|
|
223
|
+
|
|
224
|
+
### `ctx.credentialsController` — `CredentialsController`
|
|
225
|
+
|
|
226
|
+
Host service backing the generated `ctx.remote.credentials` namespace. It carries every wire obligation the credential seam itself does not: the batch fan-out bound, the field-by-field view projection, the reference-grammar guard, and the refusal mapping. Secret values cross in one direction only — no method here returns one.
|
|
227
|
+
|
|
228
|
+
```ts cordis-catalog
|
|
229
|
+
/**
|
|
230
|
+
* Describe several references for one configuration surface. Batched because
|
|
231
|
+
* a settings page describes every reference its rows name at once, and one
|
|
232
|
+
* round trip keeps those rows from settling separately.
|
|
233
|
+
* @param refs - reference names, at most {@link MAX_DESCRIBE_REFS}; a name outside the grammar
|
|
234
|
+
* rejects the whole call as `gateway/bad-request`.
|
|
235
|
+
* @returns one view per requested name, keyed by that name.
|
|
236
|
+
* @throws RemoteError when the request is invalid or no credential provider is mounted.
|
|
237
|
+
*/
|
|
238
|
+
@Remote async describe(refs: string[]): Promise<Record<string, CredentialInfo>>
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Store one value from a configuration surface. The value crosses the wire in
|
|
242
|
+
* this direction only: no read path returns it.
|
|
243
|
+
* @param ref - reference name to store under.
|
|
244
|
+
* @param value - the non-empty secret value.
|
|
245
|
+
* @throws RemoteError when the request is invalid, no provider is mounted, or the provider refuses the write.
|
|
246
|
+
*/
|
|
247
|
+
@Remote async set(ref: string, value: string): Promise<void>
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Remove one reference from a configuration surface.
|
|
251
|
+
* @param ref - reference name to remove.
|
|
252
|
+
* @throws RemoteError when the request is invalid, no provider is mounted, or the provider refuses the write.
|
|
253
|
+
*/
|
|
254
|
+
@Remote async unset(ref: string): Promise<void>
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Source: [`packages/api/settings-controller/src/credentials.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/api/settings-controller/src/credentials.ts)
|
|
258
|
+
|
|
218
259
|
<a id="authorization-events"></a>
|
|
219
260
|
|
|
220
261
|
### `authorization/*` events
|
|
@@ -15,7 +15,7 @@ Provider source: [`packages/fs/fs/src/types.ts`](https://github.com/deepseek-ai/
|
|
|
15
15
|
|
|
16
16
|
Every operation resolves a user-supplied path to an opaque backend target first. Consumers may display `displayPath`, but must not parse `targetKey` (a branded opaque id) or assume it is a local absolute path.
|
|
17
17
|
|
|
18
|
-
Consumers that share the filesystem's execution world obtain cross-capability coordinates through the provider instead of interpreting that identity: `processPath(target)` returns the canonical absolute path a subprocess can open, `fileUrl(target)` returns its provider-platform `file:` URI, and `contains(parent, child)` tests canonical identity or descendant containment.
|
|
18
|
+
Consumers that share the filesystem's execution world obtain cross-capability coordinates through the provider instead of interpreting that identity: `processPath(target)` returns the canonical absolute path a subprocess can open, `processPathFromHostPath(hostPath)` maps an absolute harness-host file only when that execution world shares it, `fileUrl(target)` returns its provider-platform `file:` URI, and `contains(parent, child)` tests canonical identity or descendant containment.
|
|
19
19
|
|
|
20
20
|
```ts type-equiv
|
|
21
21
|
/**
|
|
@@ -278,7 +278,7 @@ type FsErrorCode =
|
|
|
278
278
|
|
|
279
279
|
## The service and the plugin
|
|
280
280
|
|
|
281
|
-
`FileSystem` (`ctx.fs`, abstract) owns the provider primitives: `resolve`, `processPath`, `fileUrl`, `contains`, `stat`, `lstat`, `readText`, `streamText`, `readBytes`, `listDir`, `writeText`, and `editText`. `dsh-fs-observation-policy` registers **no service** — it is a plugin that adds policy through the `fs/*` event gate: it decides the write/edit intent waterfalls from unseen/absent/present state and records `FsObservation` values. The executor is `dsh-tool-fs`: it reads/writes/edits through `ctx.fs`, dispatches the waterfalls, and emits the recording event. The generated [`ctx.fs` section](#ctxfs--filesystem-abstract-seam) below shows the exact signatures.
|
|
281
|
+
`FileSystem` (`ctx.fs`, abstract) owns the provider primitives: `resolve`, `processPath`, `processPathFromHostPath`, `fileUrl`, `contains`, `stat`, `lstat`, `readText`, `streamText`, `readBytes`, `listDir`, `writeText`, and `editText`. `dsh-fs-observation-policy` registers **no service** — it is a plugin that adds policy through the `fs/*` event gate: it decides the write/edit intent waterfalls from unseen/absent/present state and records `FsObservation` values. The executor is `dsh-tool-fs`: it reads/writes/edits through `ctx.fs`, dispatches the waterfalls, and emits the recording event. The generated [`ctx.fs` section](#ctxfs--filesystem-abstract-seam) below shows the exact signatures.
|
|
282
282
|
|
|
283
283
|
<!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
|
|
284
284
|
|
|
@@ -316,6 +316,16 @@ abstract resolve(path: string, opts?: { cwd?: string; signal?: AbortSignal }): P
|
|
|
316
316
|
*/
|
|
317
317
|
abstract processPath(target: FsTarget): string
|
|
318
318
|
|
|
319
|
+
/**
|
|
320
|
+
* Map an absolute path from the harness host into this filesystem's
|
|
321
|
+
* execution world when both paths identify the same file. The base provider
|
|
322
|
+
* exposes no mapping; host-backed or explicitly shared backends override it.
|
|
323
|
+
* @param hostPath - absolute path in the harness host filesystem.
|
|
324
|
+
* @returns the process path for the same file, or undefined when this
|
|
325
|
+
* execution world cannot read that host file.
|
|
326
|
+
*/
|
|
327
|
+
processPathFromHostPath(hostPath: string): string | undefined
|
|
328
|
+
|
|
319
329
|
/**
|
|
320
330
|
* Return the canonical `file:` URI for a target in this filesystem's
|
|
321
331
|
* execution world. Backends own URI encoding because the host platform may
|
|
@@ -145,7 +145,7 @@ interface GoalChanged {
|
|
|
145
145
|
|
|
146
146
|
## Service behavior
|
|
147
147
|
|
|
148
|
-
[`GoalService`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/goal/goal/src/index.ts) resolves creation defaults,
|
|
148
|
+
[`GoalService`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/goal/goal/src/index.ts) resolves creation defaults, reads strict replay from the optionally registered `goal` projection, enforces exact-live-agent identity and compare-and-set mutations, and emits contained `goal/changed` notifications. Its first dependent access fails if the projection registry or key is absent. The package [README](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/goal/goal/README.md) defines the callable API and model-visible contract.
|
|
149
149
|
|
|
150
150
|
<!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
|
|
151
151
|
|
|
@@ -16,9 +16,10 @@ One page per subsystem of the DeepSeek Harness: what it is, the data structures
|
|
|
16
16
|
| [typert.md](./typert.md) | Remote invocation descriptors, lookup/Context declarations, Typert registries, and the Host Gateway/Client API boundaries |
|
|
17
17
|
| [goal.md](./goal.md) | persisted goal identity, lifecycle snapshots, activation, change records, and round attribution |
|
|
18
18
|
| [schedule.md](./schedule.md) | Session-local reminder records, durable transitions, active views, and ordinary-conversation delivery |
|
|
19
|
+
| [todo.md](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/subsystems/todo.md) | the todo package's whole-list item type, durable event ownership, projection, and open-turn invariant |
|
|
19
20
|
| [commands.md](./commands.md) | the human-command registry service: definitions, adapter discovery, direct invocation, results, and parsing views |
|
|
20
|
-
| [session.md](./session.md) | the full `SessionEventMap` variant catalog, `
|
|
21
|
-
| [persistence.md](./persistence.md) | the durability seam: `SessionPersistence`, JSONL
|
|
21
|
+
| [session.md](./session.md) | the full `SessionEventMap` variant catalog, `TurnEndReason`, `deriveMessages()`, execution enclosure, and standalone events |
|
|
22
|
+
| [persistence.md](./persistence.md) | the durability seam: `SessionPersistence`, the JSONL provider, `session/flush`, crash recovery, `SessionHeader` |
|
|
22
23
|
| [settings.md](./settings.md) | the user-settings seam: `SettingsNamespace` registration, layered resolution (defaults → composition `base` → user document), owner scopes, hot commits |
|
|
23
24
|
| [credentials.md](./credentials.md) | the credential seam: `CredentialRef` references (never values) in configuration, per-operation resolution, UI-safe `CredentialInfo`, provider source layers |
|
|
24
25
|
| [session-query.md](./session-query.md) | logical records, bounded exact-event reads, relationship traces, semantic filters/documents, and full-text result pages |
|
|
@@ -50,9 +51,13 @@ One page per subsystem of the DeepSeek Harness: what it is, the data structures
|
|
|
50
51
|
| [plan.md](./plan.md) | plan mode: the log-only `plan/mode` state, pending-selection flush, `PlanModeConfig`, the `exit_plan_mode` review arc |
|
|
51
52
|
| [invariants.md](./invariants.md) | the runtime-invariant registry: selection `Config`, `InvariantInstaller`/`InvariantFailure`, the empty-companion contract |
|
|
52
53
|
| [web-server.md](./web-server.md) | the HTTP carrier: `WebRouteKind`/`WebRoute`, match order, the claimable fallback seat, index taps |
|
|
54
|
+
| [webhook.md](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/subsystems/webhook.md) | authenticated provider deliveries, arbitrary programmatic rules, and fire-and-forget Workspace Session creation |
|
|
53
55
|
| [storage.md](./storage.md) | the storage subsystem: the backend contract (`StorageBackend`), `StorageForms`, `DomainSpec`/`Domain`, `domain/changed` |
|
|
54
56
|
| [workspace.md](./workspace.md) | the workspace registry: `Workspace`/`WorkspaceId`, registration and resolution, the session `cwd` relationship |
|
|
57
|
+
| [web-client.md](./web-client.md) | the browser architecture: boot, Remote communication, paired Client models, UI adapters, Conversation assembly, Slots, and reconnect semantics |
|
|
55
58
|
| [client-modules.md](./client-modules.md) | the web plugin table: `dsh.client` declarations, `WebBootGraph` wire composition, the bundle route and index tap |
|
|
59
|
+
| [slots.md](./slots.md) | typed Web UI composition: declaration ownership, cardinality and scope, framework and feature injection, props derivation, and the shipped hierarchy |
|
|
60
|
+
| [conversation.md](./conversation.md) | target-neutral Session-event assembly: Context identity, Location data, replay paths, view builders, and target-owned render nodes |
|
|
56
61
|
| [session-projection.md](./session-projection.md) | the projection seam: `SessionProjectionMap`, the pure `ProjectionDefinition` unit, `ProjectionSnapshot`'s consistent cut, the change feed |
|
|
57
62
|
| [session-telemetry.md](./session-telemetry.md) | the outbound session-reporting capability seam: `SessionTelemetryRecord`/`SessionTelemetrySeverity`, the `SessionTelemetrySink` contract, and the `session-telemetry/record` redact waterfall |
|
|
58
63
|
|
|
@@ -157,7 +157,7 @@ interface JobRead {
|
|
|
157
157
|
|
|
158
158
|
## Service behavior
|
|
159
159
|
|
|
160
|
-
The abstract [`JobRegistry`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs/src/index.ts) Service Definition specifies atomic `start`, caller-scoped `get` and `list`, `read`, `kill`, bounded `wait`, failure-isolated `onJobDone` and `onJobsChanged` listeners, and
|
|
160
|
+
The abstract [`JobRegistry`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs/src/index.ts) Service Definition specifies atomic `start`, caller-scoped `get` and `list`, `read`, `kill`, bounded `wait`, failure-isolated `onJobDone` and `onJobsChanged` listeners, and `attachController`; [`LocalJobRegistry`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs-local/src/index.ts) is the process-local Service Provider. Authorization compares owner sessions; owner cleanup and admission use the exact registered `Agent` instance. The local provider's positive-safe-integer `maxConcurrentJobsPerOwner` config defaults to `10` and counts `running` plus `stopping` records per exact owner, with one shared bucket for unowned jobs; terminal producer settlement releases capacity. See [`dsh-jobs`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs/README.md) for the Service Definition contract, [`dsh-jobs-local`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/jobs-local/README.md) for the registry lifecycle and admission policy, and [`dsh-tool-jobs`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/jobs/tool-jobs/README.md) for the model-facing Consumer.
|
|
161
161
|
|
|
162
162
|
<!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
|
|
163
163
|
|