dsh-plugin-dev-kb 1.0.9 → 1.3.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 +26 -0
- package/README.en.md +14 -8
- package/README.md +14 -8
- package/docs/banner.svg +25 -0
- package/kb/INDEX.md +8 -2
- package/kb/README.md +4 -4
- package/kb/extra/AGENTS.md +3 -3
- 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-session-format-version.md +109 -0
- package/kb/extra/cookbook/adding-a-session-format-version.zh.md +109 -0
- package/kb/extra/cookbook/adding-a-vendored-package.md +1 -1
- package/kb/extra/cookbook/adding-a-vendored-package.zh.md +1 -1
- package/kb/extra/cookbook/responding-to-pr-review-on-a-stack.md +1 -1
- package/kb/extra/cookbook/responding-to-pr-review-on-a-stack.zh.md +1 -1
- package/kb/extra/deepseek-llm-api-wire-extensions.md +19 -15
- package/kb/extra/deepseek-llm-api-wire-extensions.zh.md +19 -15
- package/kb/extra/development.md +13 -3
- package/kb/extra/development.zh.md +13 -3
- package/kb/extra/event-producer-consumer.md +49 -46
- package/kb/extra/event-producer-consumer.zh.md +52 -49
- package/kb/extra/i18n/README.md +2 -1
- package/kb/extra/i18n/README.zh.md +3 -2
- package/kb/extra/i18n/style-samples.md +2 -2
- package/kb/extra/i18n/translation-prompt.md +1 -1
- package/kb/extra/module-graph.md +493 -1002
- package/kb/extra/module-graph.zh.md +495 -1004
- package/kb/extra/rescope.md +1 -1
- package/kb/extra/rescope.zh.md +1 -1
- package/kb/extra/session-format-status.md +47 -0
- package/kb/extra/session-format-status.zh.md +47 -0
- package/kb/extra/subsystems/agent-team.md +3 -2
- package/kb/extra/subsystems/agent-team.zh.md +3 -2
- package/kb/extra/subsystems/attachment.md +157 -4
- package/kb/extra/subsystems/attachment.zh.md +157 -4
- package/kb/extra/subsystems/feedback.md +164 -30
- package/kb/extra/subsystems/feedback.zh.md +164 -30
- package/kb/extra/testing.md +9 -4
- package/kb/extra/testing.zh.md +9 -4
- package/kb/extra/web-styling.md +5 -0
- package/kb/extra/web-styling.zh.md +5 -0
- package/kb/meta/search-index.json +223 -151
- package/kb/meta/site-pages.txt +187 -181
- package/kb/meta/source.json +5 -5
- package/kb/meta/topics.md +5 -5
- package/kb/site/develop/basic/publish.md +1 -1
- package/kb/site/develop/cordis-tutorial/07-into-the-harness.md +3 -2
- package/kb/site/develop/practice/llm-adapter.md +4 -3
- package/kb/site/en/develop/basic/publish.md +1 -1
- package/kb/site/en/develop/cordis-tutorial/07-into-the-harness.md +3 -2
- package/kb/site/en/develop/practice/llm-adapter.md +4 -3
- 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 +19 -3
- package/kb/site/en/guide/schedule.md +2 -0
- package/kb/site/en/reference/agent-lifecycle.md +17 -8
- package/kb/site/en/reference/api-gateway.md +2 -2
- package/kb/site/en/reference/capability-seams.md +24 -10
- package/kb/site/en/reference/config-catalog.md +322 -264
- package/kb/site/en/reference/cookbook/adding-a-package.md +1 -2
- package/kb/site/en/reference/cookbook/adding-a-settings-card.md +10 -8
- package/kb/site/en/reference/cookbook/adding-a-tool.md +1 -1
- package/kb/site/en/reference/cookbook/extension-cookbook.md +16 -13
- package/kb/site/en/reference/index.md +26 -9
- package/kb/site/en/reference/persistence-catalog.md +189 -95
- package/kb/site/en/reference/subsystems/approval.md +1 -1
- package/kb/site/en/reference/subsystems/client-modules.md +9 -0
- package/kb/site/en/reference/subsystems/client-resources.md +94 -0
- package/kb/site/en/reference/subsystems/code-runtime.md +7 -3
- package/kb/site/en/reference/subsystems/commands.md +25 -16
- package/kb/site/en/reference/subsystems/compaction.md +10 -10
- package/kb/site/en/reference/subsystems/conversation.md +11 -4
- package/kb/site/en/reference/subsystems/core.md +173 -29
- package/kb/site/en/reference/subsystems/credentials.md +5 -4
- package/kb/site/en/reference/subsystems/filesystem.md +15 -0
- package/kb/site/en/reference/subsystems/goal.md +38 -2
- package/kb/site/en/reference/subsystems/index.md +3 -1
- package/kb/site/en/reference/subsystems/invariants.md +1 -1
- package/kb/site/en/reference/subsystems/llm-streaming.md +43 -12
- package/kb/site/en/reference/subsystems/lsp.md +1 -1
- package/kb/site/en/reference/subsystems/permission-presets.md +5 -5
- package/kb/site/en/reference/subsystems/persistence.md +211 -199
- package/kb/site/en/reference/subsystems/plan.md +3 -3
- 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/scope.md +1 -1
- package/kb/site/en/reference/subsystems/session-projection.md +50 -24
- package/kb/site/en/reference/subsystems/session-query.md +19 -13
- package/kb/site/en/reference/subsystems/session-reference.md +29 -1
- package/kb/site/en/reference/subsystems/session-telemetry.md +27 -10
- package/kb/site/en/reference/subsystems/session-title.md +6 -6
- package/kb/site/en/reference/subsystems/session.md +208 -103
- package/kb/site/en/reference/subsystems/settings.md +30 -12
- package/kb/site/en/reference/subsystems/shell.md +9 -6
- package/kb/site/en/reference/subsystems/sidebar-right.md +151 -0
- package/kb/site/en/reference/subsystems/skills.md +1 -1
- package/kb/site/en/reference/subsystems/slots.md +41 -32
- package/kb/site/en/reference/subsystems/spill.md +13 -6
- package/kb/site/en/reference/subsystems/storage.md +28 -5
- package/kb/site/en/reference/subsystems/subagent.md +58 -105
- package/kb/site/en/reference/subsystems/subprocess.md +25 -26
- package/kb/site/en/reference/subsystems/system-prompt.md +18 -3
- package/kb/site/en/reference/subsystems/token-meter.md +4 -3
- package/kb/site/en/reference/subsystems/tools.md +5 -5
- package/kb/site/en/reference/subsystems/typert.md +18 -18
- package/kb/site/en/reference/subsystems/web-client.md +1 -1
- package/kb/site/en/reference/subsystems/workspace.md +88 -9
- package/kb/site/en/reference/tool-catalog.md +56 -66
- package/kb/site/en/reference/tool-execution-pipeline.md +2 -2
- package/kb/site/guide/network-proxy.md +87 -0
- package/kb/site/guide/providers.md +70 -17
- package/kb/site/guide/python-sdk.md +19 -3
- package/kb/site/guide/schedule.md +2 -0
- package/kb/site/reference/agent-lifecycle.md +17 -8
- package/kb/site/reference/api-gateway.md +2 -2
- package/kb/site/reference/capability-seams.md +24 -10
- package/kb/site/reference/config-catalog.md +321 -263
- package/kb/site/reference/cookbook/adding-a-package.md +1 -2
- package/kb/site/reference/cookbook/adding-a-settings-card.md +10 -8
- package/kb/site/reference/cookbook/adding-a-tool.md +1 -1
- package/kb/site/reference/cookbook/extension-cookbook.md +16 -13
- package/kb/site/reference/index.md +26 -9
- package/kb/site/reference/persistence-catalog.md +190 -96
- package/kb/site/reference/subsystems/approval.md +1 -1
- package/kb/site/reference/subsystems/client-modules.md +9 -0
- package/kb/site/reference/subsystems/client-resources.md +94 -0
- package/kb/site/reference/subsystems/code-runtime.md +7 -3
- package/kb/site/reference/subsystems/commands.md +25 -16
- package/kb/site/reference/subsystems/compaction.md +10 -10
- package/kb/site/reference/subsystems/conversation.md +11 -4
- package/kb/site/reference/subsystems/core.md +173 -29
- package/kb/site/reference/subsystems/credentials.md +5 -4
- package/kb/site/reference/subsystems/filesystem.md +15 -0
- package/kb/site/reference/subsystems/goal.md +38 -2
- package/kb/site/reference/subsystems/index.md +14 -12
- package/kb/site/reference/subsystems/invariants.md +1 -1
- package/kb/site/reference/subsystems/llm-streaming.md +43 -12
- package/kb/site/reference/subsystems/lsp.md +1 -1
- package/kb/site/reference/subsystems/permission-presets.md +5 -5
- package/kb/site/reference/subsystems/persistence.md +210 -198
- package/kb/site/reference/subsystems/plan.md +3 -3
- package/kb/site/reference/subsystems/schedule.md +9 -3
- package/kb/site/reference/subsystems/scope.md +1 -1
- package/kb/site/reference/subsystems/session-projection.md +50 -24
- package/kb/site/reference/subsystems/session-query.md +19 -13
- package/kb/site/reference/subsystems/session-reference.md +29 -1
- package/kb/site/reference/subsystems/session-telemetry.md +27 -10
- package/kb/site/reference/subsystems/session-title.md +6 -6
- package/kb/site/reference/subsystems/session.md +208 -103
- package/kb/site/reference/subsystems/settings.md +30 -12
- package/kb/site/reference/subsystems/shell.md +9 -6
- package/kb/site/reference/subsystems/sidebar-right.md +151 -0
- package/kb/site/reference/subsystems/skills.md +1 -1
- package/kb/site/reference/subsystems/slots.md +41 -32
- package/kb/site/reference/subsystems/spill.md +13 -6
- package/kb/site/reference/subsystems/storage.md +28 -5
- package/kb/site/reference/subsystems/subagent.md +58 -105
- package/kb/site/reference/subsystems/subprocess.md +25 -26
- package/kb/site/reference/subsystems/system-prompt.md +18 -3
- package/kb/site/reference/subsystems/token-meter.md +4 -3
- package/kb/site/reference/subsystems/tools.md +5 -5
- package/kb/site/reference/subsystems/typert.md +18 -18
- package/kb/site/reference/subsystems/web-client.md +1 -1
- package/kb/site/reference/subsystems/workspace.md +88 -9
- package/kb/site/reference/tool-catalog.md +55 -65
- package/kb/site/reference/tool-execution-pipeline.md +2 -2
- package/lib/index.js +25 -44
- package/package.json +3 -2
- package/skills/dsh-plugin-dev-kb.md +4 -4
|
@@ -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,9 +49,9 @@ 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: an optional live `parentAgent`, 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`, `parentAgent`, `agentOptions`, `signal`, and `setup`. The `setup` callback (`AgentSetup`) receives `(agentCtx, agent)` while both ids are still unpublished: the context owns scoped registrations, while the explicit Agent supplies the exact child Session without a reverse property on the Context. Everything registered through `agentCtx` exists before `agent/created` and the first prompt assembly. Setup 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
|
-
`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.
|
|
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. A runtime child creator sets `options.parentAgent`; the registry passes the options and caller Context to the factory without deriving one from the other. The exact `create`/`resume` signatures and rollback contracts are in the [generated section](#ctxagents--agentregistry) below.
|
|
55
55
|
|
|
56
56
|
## The agent handle
|
|
57
57
|
|
|
@@ -68,7 +68,7 @@ interface Agent {
|
|
|
68
68
|
readonly options: AgentOptions
|
|
69
69
|
/** The live session this agent drives; its log is the durable source of truth. */
|
|
70
70
|
readonly session: Session
|
|
71
|
-
/**
|
|
71
|
+
/** Agent-owned access to durable pending work. */
|
|
72
72
|
readonly inbox: Inbox
|
|
73
73
|
/** The current lifecycle state, mirrored on every `agent/status` transition. */
|
|
74
74
|
readonly status: AgentStatus
|
|
@@ -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
|
|
@@ -171,16 +209,73 @@ interface AgentOptions {
|
|
|
171
209
|
}
|
|
172
210
|
```
|
|
173
211
|
|
|
174
|
-
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.
|
|
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-prefix` prompt section may shadow the global default persona.
|
|
175
213
|
|
|
176
214
|
The inbox is the delivery vocabulary — two ordered pending-message lists the agent owns as a durable projection:
|
|
177
215
|
|
|
216
|
+
```ts type-equiv
|
|
217
|
+
/** Agent-owned access to pending work; concrete storage belongs to the driver. */
|
|
218
|
+
interface Inbox {
|
|
219
|
+
/** Prompts awaiting individual turns. */
|
|
220
|
+
readonly nextTurn: readonly UserMessage[]
|
|
221
|
+
/** Input awaiting the next step boundary. */
|
|
222
|
+
readonly nextStep: readonly UserMessage[]
|
|
223
|
+
|
|
224
|
+
/** Durably cancel all pending input, clearing next-step before next-turn. */
|
|
225
|
+
clear(): void
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Append one message to a pending list.
|
|
229
|
+
* @param target - pending list to extend.
|
|
230
|
+
* @param message - message to append.
|
|
231
|
+
*/
|
|
232
|
+
append(target: InboxTarget, message: UserMessage): void
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Prepend one message to a pending list.
|
|
236
|
+
* @param target - pending list to extend.
|
|
237
|
+
* @param message - message to prepend.
|
|
238
|
+
*/
|
|
239
|
+
prepend(target: InboxTarget, message: UserMessage): void
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Replace one pending message in place.
|
|
243
|
+
* @param messageId - identity of the pending message to replace.
|
|
244
|
+
* @param newMessage - replacement message.
|
|
245
|
+
* @returns whether the message was still pending.
|
|
246
|
+
*/
|
|
247
|
+
replace(messageId: MessageId, newMessage: UserMessage): boolean
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Remove one pending message.
|
|
251
|
+
* @param messageId - identity of the pending message to remove.
|
|
252
|
+
* @returns whether the message was still pending.
|
|
253
|
+
*/
|
|
254
|
+
remove(messageId: MessageId): boolean
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Apply standard splice semantics and durably record the normalized result.
|
|
258
|
+
* @param target - pending list to mutate.
|
|
259
|
+
* @param start - splice position.
|
|
260
|
+
* @param deleteCount - maximum number of messages to remove.
|
|
261
|
+
* @param inserted - messages to insert at the resolved position.
|
|
262
|
+
* @returns messages removed by the splice.
|
|
263
|
+
*/
|
|
264
|
+
splice(
|
|
265
|
+
target: InboxTarget,
|
|
266
|
+
start: number,
|
|
267
|
+
deleteCount: number,
|
|
268
|
+
inserted: UserMessage[],
|
|
269
|
+
): UserMessage[]
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
178
273
|
```ts type-equiv
|
|
179
274
|
/** One of the two ordered pending-message lists owned by an agent. */
|
|
180
275
|
type InboxTarget = 'next-turn' | 'next-step'
|
|
181
276
|
```
|
|
182
277
|
|
|
183
|
-
Every pending occurrence is its `UserMessage`; `MessageId` is the sole identity.
|
|
278
|
+
Every pending occurrence is its `UserMessage`; `MessageId` is the sole identity. The structural `Inbox` methods record normalized durable `agent/inbox/spliced` mutations and reject duplicate pending ids. `replace(messageId, newMessage)` and `remove(messageId)` locate the pending message across both lists; replacement may change identity and emits the old message as discarded followed by the new message as inserted. Ordinary removals and `clear()` are cancellations. At a step boundary, dsh-agent-loop's package-internal `ReactLoopInbox` removes the proposed batch — all `next-step` input plus, at a turn boundary, one `next-turn` message — through pure deletion splices without discarded notifications, then emits per-message claimed notifications. Loop-only pending detection and claiming are not part of `Agent.inbox`. Each `ReactLoopInbox` constructor contributes the standard `inbox` projection from its agent scope; the registry shares that definition across agents by reference count, and its cell is the sole live state while the same fold serves cold consumers. The fold rejects unsafe or out-of-range splice coordinates and duplicate identities across both lists, identifying malformed durable history by event seq. Consumers following one message use the exact `agent/inbox/inserted`, `claimed`, and `discarded` notifications.
|
|
184
279
|
|
|
185
280
|
Cancellation:
|
|
186
281
|
|
|
@@ -255,7 +350,7 @@ type SessionStartSource = 'startup' | 'resume' | 'clear' | 'compact'
|
|
|
255
350
|
|
|
256
351
|
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`.
|
|
257
352
|
|
|
258
|
-
The `SessionEvent` envelope's exact conditional fields, the
|
|
353
|
+
The `SessionEvent` envelope's exact conditional fields, the thirteen core event variants (`turn/start`, `turn/end`, `step/start`, `step/end`, `user/message`, `system/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)**.
|
|
259
354
|
|
|
260
355
|
## `ToolDefinition`
|
|
261
356
|
|
|
@@ -304,9 +399,9 @@ Two large discriminated unions are the ones consumers `switch` over most: **`Str
|
|
|
304
399
|
|
|
305
400
|
### Branded IDs
|
|
306
401
|
|
|
307
|
-
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
|
|
402
|
+
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.
|
|
308
403
|
|
|
309
|
-
The `Branded<B>` primitive
|
|
404
|
+
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.
|
|
310
405
|
|
|
311
406
|
Source: [`packages/util/brand/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/util/brand/src/index.ts)
|
|
312
407
|
|
|
@@ -359,18 +454,19 @@ Concrete agent factory and driver service.
|
|
|
359
454
|
/**
|
|
360
455
|
* Create an agent and session under one caller-supplied identity, owned by
|
|
361
456
|
* the accessing fiber. Constructor-driven config calls mint a fresh combined
|
|
362
|
-
* id before entering this boundary.
|
|
457
|
+
* id before entering this boundary. When a persistence backend is mounted,
|
|
458
|
+
* the session's durable identity and any seed are stored before publication.
|
|
363
459
|
* @param id - shared agent/session identity.
|
|
364
460
|
* @param options - concrete loop options.
|
|
365
461
|
* @param meta - optional fresh-session workspace metadata.
|
|
366
462
|
* @returns the published running agent.
|
|
367
463
|
*/
|
|
368
|
-
create(id: SessionId, options: AgentOptions = {}, meta: Pick<SessionHeader, 'cwd'> = {}): Agent
|
|
464
|
+
async create(id: SessionId, options: AgentOptions = {}, meta: Pick<SessionHeader, 'cwd'> = {}): Promise<Agent>
|
|
369
465
|
|
|
370
466
|
/**
|
|
371
467
|
* Create an owned agent on a caller-supplied session id.
|
|
372
468
|
* @param ownerCtx - caller context that structurally owns the lifecycle.
|
|
373
|
-
* @param options - identities, session seed/metadata, loop options, setup, and cancellation.
|
|
469
|
+
* @param options - identities, optional live parent, session seed/metadata, loop options, setup, and cancellation.
|
|
374
470
|
* @returns the published handle.
|
|
375
471
|
*/
|
|
376
472
|
async createAgent(ownerCtx: Context, options: CreateAgentOptions): Promise<AgentHandle>
|
|
@@ -378,7 +474,7 @@ async createAgent(ownerCtx: Context, options: CreateAgentOptions): Promise<Agent
|
|
|
378
474
|
/**
|
|
379
475
|
* Resume an owned agent from the configured persistence service.
|
|
380
476
|
* @param ownerCtx - caller context that owns load, setup, and the live lifecycle.
|
|
381
|
-
* @param options - persisted identity, loop options, setup, and cancellation.
|
|
477
|
+
* @param options - persisted identity, optional live parent, loop options, setup, and cancellation.
|
|
382
478
|
* @returns the published handle.
|
|
383
479
|
*/
|
|
384
480
|
async resume(ownerCtx: Context, options: ResumeAgentOptions): Promise<AgentHandle>
|
|
@@ -413,6 +509,25 @@ async list(): Promise<AgentPreset[]>
|
|
|
413
509
|
*/
|
|
414
510
|
@Remote('list') async remoteExportList(): Promise<AgentPresetRoster>
|
|
415
511
|
|
|
512
|
+
/**
|
|
513
|
+
* Every preset's composition as flattened plugin rows, for plugin-listing
|
|
514
|
+
* surfaces beside the roster's own picker.
|
|
515
|
+
*
|
|
516
|
+
* A preset with a live standing mount answers from its newest generation's
|
|
517
|
+
* Loader entries — the composition new sessions join — even when the file
|
|
518
|
+
* behind it has since been edited into an unreadable state: the mount is
|
|
519
|
+
* what sessions actually run, so the broken verdict only applies to a
|
|
520
|
+
* preset nothing composed. One never composed since boot answers from its
|
|
521
|
+
* file, with `!!js` disabled gates evaluated against the Loader context so
|
|
522
|
+
* both answers reflect the same host. Reading never mounts: an unmounted
|
|
523
|
+
* preset is parsed, not composed, so listing a preset's plugins cannot
|
|
524
|
+
* activate them early. A composition that stopped reading between
|
|
525
|
+
* discovery's health verdict and this read is reported broken with the
|
|
526
|
+
* raced reason rather than dropped.
|
|
527
|
+
* @returns one composition per roster preset, in roster order.
|
|
528
|
+
*/
|
|
529
|
+
async compositionInventory(): Promise<AgentPresetComposition[]>
|
|
530
|
+
|
|
416
531
|
/**
|
|
417
532
|
* Resolve one preset by id.
|
|
418
533
|
*
|
|
@@ -491,8 +606,8 @@ async read(id: string): Promise<string>
|
|
|
491
606
|
* One preset's composition text with the roster row it belongs to.
|
|
492
607
|
* @param agentPreset - the preset id.
|
|
493
608
|
* @returns the composition beside its trust and published metadata.
|
|
494
|
-
* @throws {
|
|
495
|
-
* `agent-preset
|
|
609
|
+
* @throws {RemoteError} `gateway/bad-request` for an empty id, or
|
|
610
|
+
* `agent-preset/not-found` when no configured root supplies it.
|
|
496
611
|
*/
|
|
497
612
|
@Remote('read') async readDocument(agentPreset: string): Promise<AgentPresetDocument>
|
|
498
613
|
|
|
@@ -519,8 +634,8 @@ async copy(from: string, id: string, name?: string): Promise<void>
|
|
|
519
634
|
* @param id - the new preset id.
|
|
520
635
|
* @param name - the copy's optional display name.
|
|
521
636
|
* @returns once the copy is stored.
|
|
522
|
-
* @throws {
|
|
523
|
-
*
|
|
637
|
+
* @throws {RemoteError} with the corresponding stable preset code and
|
|
638
|
+
* details when the copy is refused.
|
|
524
639
|
*/
|
|
525
640
|
@Remote('copy') async remoteExportCopy(from: string, id: string, name?: string): Promise<void>
|
|
526
641
|
|
|
@@ -536,8 +651,8 @@ async remove(id: string): Promise<void>
|
|
|
536
651
|
* Delete one preset through the Remote API.
|
|
537
652
|
* @param id - the preset id.
|
|
538
653
|
* @returns once the preset is deleted.
|
|
539
|
-
* @throws {
|
|
540
|
-
*
|
|
654
|
+
* @throws {RemoteError} with the corresponding stable preset code and
|
|
655
|
+
* details when deletion is refused.
|
|
541
656
|
*/
|
|
542
657
|
@Remote('deletePreset') async remoteExportDelete(id: string): Promise<void>
|
|
543
658
|
|
|
@@ -588,8 +703,8 @@ async recompose(agentCtx: Context, id: string): Promise<AgentPreset>
|
|
|
588
703
|
* @param agent - the session's live agent, resolved from the wire identity.
|
|
589
704
|
* @param agentPreset - the preset to compose the agent from instead.
|
|
590
705
|
* @returns the preset id that was recorded.
|
|
591
|
-
* @throws {
|
|
592
|
-
* `agent-preset
|
|
706
|
+
* @throws {RemoteError} with `gateway/bad-request`, `agent-preset/locked`,
|
|
707
|
+
* `agent-preset/not-found`, or `agent-preset/invalid` when refused.
|
|
593
708
|
*/
|
|
594
709
|
@Remote('select') async select(agent: Agent, agentPreset: string): Promise<string>
|
|
595
710
|
|
|
@@ -624,7 +739,8 @@ Initiator methods provide same-process causal attribution only. Ambient presence
|
|
|
624
739
|
* Read the Agent that initiated the inherited asynchronous driver chain.
|
|
625
740
|
* Use this optional form for logging, tracing, metrics, or host attribution
|
|
626
741
|
* that also supports agentless calls. When a parent creates a child, setup
|
|
627
|
-
* reports the causal parent while
|
|
742
|
+
* reports the causal parent while the setup callback's Agent parameter
|
|
743
|
+
* identifies the child.
|
|
628
744
|
* @returns the inherited Agent, or `undefined` outside an initiator boundary
|
|
629
745
|
* and inside an explicit clearing boundary.
|
|
630
746
|
* @throws when this service instance has been disposed.
|
|
@@ -689,7 +805,7 @@ setFactory(factory: AgentFactory): () => void
|
|
|
689
805
|
* agent): this constructs the agent and its session. Rejects if no factory is
|
|
690
806
|
* registered or creation/setup fails. The resolved {@link AgentHandle} lets
|
|
691
807
|
* the owner tear down exactly this agent.
|
|
692
|
-
* @param options - shared identity, session seed/metadata, and agent options.
|
|
808
|
+
* @param options - shared identity, optional live parent, session seed/metadata, and agent options.
|
|
693
809
|
* @returns the handle after setup, rollback-covered publication, and loop start complete.
|
|
694
810
|
*/
|
|
695
811
|
async create(options: CreateAgentOptions): Promise<AgentHandle>
|
|
@@ -698,7 +814,7 @@ async create(options: CreateAgentOptions): Promise<AgentHandle>
|
|
|
698
814
|
* Load a persisted session and resume an agent on it through the registered
|
|
699
815
|
* factory. Rejects if no factory is registered; the factory rejects if
|
|
700
816
|
* session persistence is not configured or persistence/setup fails.
|
|
701
|
-
* @param options - persisted identity, configuration, and
|
|
817
|
+
* @param options - persisted identity, optional live parent, configuration, and setup.
|
|
702
818
|
* @returns the handle after setup, rollback-covered publication, and loop start complete.
|
|
703
819
|
*/
|
|
704
820
|
async resume(options: ResumeAgentOptions): Promise<AgentHandle>
|
|
@@ -710,7 +826,8 @@ async resume(options: ResumeAgentOptions): Promise<AgentHandle>
|
|
|
710
826
|
* (`scopeTarget(agent, agent)`): the subject is the agent in hand, so the
|
|
711
827
|
* emits are scope-filtered regardless of which context invoked `register`
|
|
712
828
|
* (calling through `agent.ctx` scopes EFFECTS; dispatch scoping always
|
|
713
|
-
* requires passing the carrier).
|
|
829
|
+
* requires passing the carrier). The entry is a runtime root; factory-backed
|
|
830
|
+
* creation uses `options.parentAgent` for child ownership. Returns the disposer.
|
|
714
831
|
* @param agent - the already-constructed agent to record in the store.
|
|
715
832
|
* @returns the EXACT Cordis effect disposer (single-shot; a repeat call
|
|
716
833
|
* returns undefined without awaiting an in-flight teardown). Exact
|
|
@@ -730,7 +847,7 @@ register(agent: Agent): () => void
|
|
|
730
847
|
* returned detach closure into its pre-installed composite teardown before
|
|
731
848
|
* calling {@link announce}. Ordinary callers use {@link register}.
|
|
732
849
|
* @param agent - the prepared, unpublished agent.
|
|
733
|
-
* @param owner -
|
|
850
|
+
* @param owner - explicitly supplied live runtime owner, or
|
|
734
851
|
* undefined for a top-level runtime root. This is runtime ownership, not
|
|
735
852
|
* the resumed session's durable parent lineage.
|
|
736
853
|
* @returns an idempotent closure that removes this exact entry and emits
|
|
@@ -787,6 +904,29 @@ Source: [`packages/core/agent/src/index.ts`](https://github.com/deepseek-ai/deep
|
|
|
787
904
|
|
|
788
905
|
### `agent/*` events
|
|
789
906
|
|
|
907
|
+
<a id="agentassistant-stream--emit"></a>
|
|
908
|
+
|
|
909
|
+
#### `agent/assistant-stream` — emit
|
|
910
|
+
|
|
911
|
+
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.
|
|
912
|
+
|
|
913
|
+
```ts cordis-catalog
|
|
914
|
+
/**
|
|
915
|
+
* Process-local assistant-stream publication. Chunk frames are transient;
|
|
916
|
+
* the loop appends one final v2 `assistant/message` or `assistant/attempt`
|
|
917
|
+
* with the same stream before a committed end frame.
|
|
918
|
+
* @param payload.agent - the agent whose attempt produced the frame.
|
|
919
|
+
* @param payload.frame - one ordered start, chunk, or end publication.
|
|
920
|
+
* Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.
|
|
921
|
+
* @mode emit
|
|
922
|
+
*/
|
|
923
|
+
'agent/assistant-stream'(this: Scoped<Agent>, payload: { agent: Agent; frame: AssistantStreamFrame }): void
|
|
924
|
+
```
|
|
925
|
+
|
|
926
|
+
Types: [Scoped](./scope.md)
|
|
927
|
+
|
|
928
|
+
Source: [`packages/core/agent/src/runtime-types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/core/agent/src/runtime-types.ts)
|
|
929
|
+
|
|
790
930
|
<a id="agentcreated--emit"></a>
|
|
791
931
|
|
|
792
932
|
#### `agent/created` — emit
|
|
@@ -952,14 +1092,18 @@ Source: [`packages/core/agent/src/runtime-types.ts`](https://github.com/deepseek
|
|
|
952
1092
|
|
|
953
1093
|
#### `agent/request` — waterfall
|
|
954
1094
|
|
|
955
|
-
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.
|
|
1095
|
+
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. On step admission, this runs after assembly and `step/start`, before the system prompt and accepted user batch are committed. Cancellation here or during subsequent `prepareCall()` resolution commits neither. The prepared call capability governs prompt admission. Model-visible content must use logged channels; this waterfall cannot mutate messages.
|
|
956
1096
|
|
|
957
1097
|
```ts cordis-catalog
|
|
958
1098
|
/**
|
|
959
1099
|
* Replace the frozen call configuration. `await next()` yields the config
|
|
960
1100
|
* the machine would use (agent options on the first request, the logged
|
|
961
|
-
* header afterwards); return a replacement to switch.
|
|
962
|
-
*
|
|
1101
|
+
* header afterwards); return a replacement to switch. On step admission,
|
|
1102
|
+
* this runs after assembly and `step/start`, before the system prompt and
|
|
1103
|
+
* accepted user batch are committed. Cancellation here or during subsequent
|
|
1104
|
+
* `prepareCall()` resolution commits neither. The prepared call capability
|
|
1105
|
+
* governs prompt admission. Model-visible content must use logged channels;
|
|
1106
|
+
* this waterfall cannot mutate messages.
|
|
963
1107
|
* @param payload.agent - the agent making the model call.
|
|
964
1108
|
* @param payload.turn - the open turn number.
|
|
965
1109
|
* @param payload.step - the step whose request this is.
|
|
@@ -230,9 +230,10 @@ Host service backing the generated `ctx.remote.credentials` namespace. It carrie
|
|
|
230
230
|
* Describe several references for one configuration surface. Batched because
|
|
231
231
|
* a settings page describes every reference its rows name at once, and one
|
|
232
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
|
|
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`.
|
|
234
235
|
* @returns one view per requested name, keyed by that name.
|
|
235
|
-
* @throws
|
|
236
|
+
* @throws RemoteError when the request is invalid or no credential provider is mounted.
|
|
236
237
|
*/
|
|
237
238
|
@Remote async describe(refs: string[]): Promise<Record<string, CredentialInfo>>
|
|
238
239
|
|
|
@@ -241,14 +242,14 @@ Host service backing the generated `ctx.remote.credentials` namespace. It carrie
|
|
|
241
242
|
* this direction only: no read path returns it.
|
|
242
243
|
* @param ref - reference name to store under.
|
|
243
244
|
* @param value - the non-empty secret value.
|
|
244
|
-
* @throws
|
|
245
|
+
* @throws RemoteError when the request is invalid, no provider is mounted, or the provider refuses the write.
|
|
245
246
|
*/
|
|
246
247
|
@Remote async set(ref: string, value: string): Promise<void>
|
|
247
248
|
|
|
248
249
|
/**
|
|
249
250
|
* Remove one reference from a configuration surface.
|
|
250
251
|
* @param ref - reference name to remove.
|
|
251
|
-
* @throws
|
|
252
|
+
* @throws RemoteError when the request is invalid, no provider is mounted, or the provider refuses the write.
|
|
252
253
|
*/
|
|
253
254
|
@Remote async unset(ref: string): Promise<void>
|
|
254
255
|
```
|
|
@@ -399,6 +399,21 @@ abstract streamText(target: FsTarget, signal?: AbortSignal): Promise<AsyncIterab
|
|
|
399
399
|
*/
|
|
400
400
|
abstract readBytes(target: FsTarget, signal: AbortSignal | undefined, maxBytes: number): Promise<Uint8Array>
|
|
401
401
|
|
|
402
|
+
/**
|
|
403
|
+
* Read one byte window of the regular file as raw bytes with no decoding or
|
|
404
|
+
* binary rejection: the bytes at `[offset, offset + length)`, shorter when
|
|
405
|
+
* the file ends inside the window and empty when `offset` lies at or past
|
|
406
|
+
* its end. The window is the bound here, not the file: a backend transfers
|
|
407
|
+
* at most `length` bytes of content beyond the prefix it skips to reach
|
|
408
|
+
* `offset` and never buffers the whole file, so the caller's cap on `length`
|
|
409
|
+
* is the guard against unbounded buffering.
|
|
410
|
+
* @param target - the resolved target to read.
|
|
411
|
+
* @param range - `offset`, the 0-based first byte, and `length`, the largest byte count; both non-negative integers.
|
|
412
|
+
* @param signal - aborts the read.
|
|
413
|
+
* @returns the window's bytes, at most `length` long.
|
|
414
|
+
*/
|
|
415
|
+
abstract readByteRange(target: FsTarget, range: { offset: number; length: number }, signal?: AbortSignal): Promise<Uint8Array>
|
|
416
|
+
|
|
402
417
|
/**
|
|
403
418
|
* List direct children of a directory in stable name order. Returns resolved
|
|
404
419
|
* child targets plus cheap metadata only; never reads file contents.
|
|
@@ -72,6 +72,25 @@ interface GoalView extends GoalSnapshot {
|
|
|
72
72
|
}
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
+
The service also publishes process-local activation edges without changing durable state; clients consume this event for live status.
|
|
76
|
+
|
|
77
|
+
```ts type-equiv
|
|
78
|
+
/** Live process-local activation update forwarded to UI clients. */
|
|
79
|
+
interface GoalActivationChanged {
|
|
80
|
+
/** Session whose live goal activation changed. */
|
|
81
|
+
readonly sessionId: SessionId
|
|
82
|
+
/** Current exact activation, absent when no goal is current. */
|
|
83
|
+
readonly goal?: {
|
|
84
|
+
/** Exact current goal identity. */
|
|
85
|
+
readonly id: GoalId
|
|
86
|
+
/** Exact current goal revision. */
|
|
87
|
+
readonly revision: number
|
|
88
|
+
/** Current process-local continuation state. */
|
|
89
|
+
readonly activation: GoalActivation
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
75
94
|
## Durable changes
|
|
76
95
|
|
|
77
96
|
Every mutation is a durable `goal/change` session event whose payload is either a complete post-mutation snapshot or a clear tombstone. The strict fold and persisted projection derive lifecycle state only from these events; inbox mutations do not affect goal state.
|
|
@@ -145,7 +164,7 @@ interface GoalChanged {
|
|
|
145
164
|
|
|
146
165
|
## Service behavior
|
|
147
166
|
|
|
148
|
-
[`GoalService`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/goal/goal/src/index.ts) resolves creation defaults,
|
|
167
|
+
[`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
168
|
|
|
150
169
|
<!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
|
|
151
170
|
|
|
@@ -168,7 +187,7 @@ Goal service (`ctx.goals`) backed exclusively by the owning session log.
|
|
|
168
187
|
* @returns a fresh view or `undefined` when no goal is current.
|
|
169
188
|
* @throws {@link GoalError} when the agent is not the registry's live instance.
|
|
170
189
|
*/
|
|
171
|
-
get(agent: Agent): GoalView | undefined
|
|
190
|
+
@Remote('get') get(agent: Agent): GoalView | undefined
|
|
172
191
|
|
|
173
192
|
/**
|
|
174
193
|
* Remove process-local continuation authority without changing durable goal
|
|
@@ -256,6 +275,23 @@ Source: [`packages/goal/goal/src/index.ts`](https://github.com/deepseek-ai/deeps
|
|
|
256
275
|
|
|
257
276
|
### `goal/*` events
|
|
258
277
|
|
|
278
|
+
<a id="goalactivation-changed--emit"></a>
|
|
279
|
+
|
|
280
|
+
#### `goal/activation-changed` — emit
|
|
281
|
+
|
|
282
|
+
Process-local goal activation changed for one session.
|
|
283
|
+
|
|
284
|
+
```ts cordis-catalog
|
|
285
|
+
/**
|
|
286
|
+
* Process-local goal activation changed for one session.
|
|
287
|
+
* @mode emit
|
|
288
|
+
* @param payload - session id and the exact current goal activation, or no goal after a clear.
|
|
289
|
+
*/
|
|
290
|
+
'goal/activation-changed'(payload: GoalActivationChanged): void
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Source: [`packages/goal/goal/src/types.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/goal/goal/src/types.ts)
|
|
294
|
+
|
|
259
295
|
<a id="goalchanged--emit"></a>
|
|
260
296
|
|
|
261
297
|
#### `goal/changed` — emit
|
|
@@ -19,7 +19,7 @@ One page per subsystem of the DeepSeek Harness: what it is, the data structures
|
|
|
19
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 |
|
|
20
20
|
| [commands.md](./commands.md) | the human-command registry service: definitions, adapter discovery, direct invocation, results, and parsing views |
|
|
21
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`, JSONL
|
|
22
|
+
| [persistence.md](./persistence.md) | the durability seam: `SessionPersistence`, the JSONL provider, `session/flush`, crash recovery, `SessionHeader` |
|
|
23
23
|
| [settings.md](./settings.md) | the user-settings seam: `SettingsNamespace` registration, layered resolution (defaults → composition `base` → user document), owner scopes, hot commits |
|
|
24
24
|
| [credentials.md](./credentials.md) | the credential seam: `CredentialRef` references (never values) in configuration, per-operation resolution, UI-safe `CredentialInfo`, provider source layers |
|
|
25
25
|
| [session-query.md](./session-query.md) | logical records, bounded exact-event reads, relationship traces, semantic filters/documents, and full-text result pages |
|
|
@@ -57,6 +57,8 @@ One page per subsystem of the DeepSeek Harness: what it is, the data structures
|
|
|
57
57
|
| [web-client.md](./web-client.md) | the browser architecture: boot, Remote communication, paired Client models, UI adapters, Conversation assembly, Slots, and reconnect semantics |
|
|
58
58
|
| [client-modules.md](./client-modules.md) | the web plugin table: `dsh.client` declarations, `WebBootGraph` wire composition, the bundle route and index tap |
|
|
59
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
|
+
| [client-resources.md](./client-resources.md) | the client resource model: `dsh-resource://<type>/…` addresses, protocol providers and `ResourceProtocolMap`, the `useResource` global hook and its states, pins and release |
|
|
61
|
+
| [sidebar-right.md](./sidebar-right.md) | the right Sidebar: resource and navigation addresses, tab-type registration and routing, the `ctx.sidebarRight` navigation service, the pane-tab slots and owner props, the resource model, and the Workspace Files service |
|
|
60
62
|
| [conversation.md](./conversation.md) | target-neutral Session-event assembly: Context identity, Location data, replay paths, view builders, and target-owned render nodes |
|
|
61
63
|
| [session-projection.md](./session-projection.md) | the projection seam: `SessionProjectionMap`, the pure `ProjectionDefinition` unit, `ProjectionSnapshot`'s consistent cut, the change feed |
|
|
62
64
|
| [session-telemetry.md](./session-telemetry.md) | the outbound session-reporting capability seam: `SessionTelemetryRecord`/`SessionTelemetrySeverity`, the `SessionTelemetrySink` contract, and the `session-telemetry/record` redact waterfall |
|
|
@@ -5,7 +5,7 @@ outline: [2,3]
|
|
|
5
5
|
|
|
6
6
|
# Runtime Invariants
|
|
7
7
|
|
|
8
|
-
[dsh-invariants](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/runtime-diagnostics/invariants) is the configurable registry service (`ctx.invariants`) for package-owned runtime invariant checks. It is one support-group package, not a three-package capability seam, and not part of the agent-loop spine: the registry owns selection, name reservation, child-fiber lifecycle, and package-attributed failure, while every workspace package publishes a `./invariant` companion plugin that registers checks under its exact npm package name. What a check may assert — authoritative event streams or mutable data, never service or method presence — is the runtime-invariants convention in [AGENTS.md](https://github.com/deepseek-ai/deepseek-harness/blob/master/AGENTS.md#conventions)
|
|
8
|
+
[dsh-invariants](https://github.com/deepseek-ai/deepseek-harness/tree/master/packages/runtime-diagnostics/invariants) is the configurable registry service (`ctx.invariants`) for package-owned runtime invariant checks. It is one support-group package, not a three-package capability seam, and not part of the agent-loop spine: the registry owns selection, name reservation, child-fiber lifecycle, and package-attributed failure, while every workspace package publishes a `./invariant` companion plugin that registers checks under its exact npm package name. What a check may assert — authoritative event streams or mutable data, never service or method presence — is the runtime-invariants convention in [AGENTS.md](https://github.com/deepseek-ai/deepseek-harness/blob/master/AGENTS.md#conventions).
|
|
9
9
|
|
|
10
10
|
Source: [`packages/runtime-diagnostics/invariants/src/index.ts`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/runtime-diagnostics/invariants/src/index.ts)
|
|
11
11
|
|