dsh-plugin-dev-kb 1.0.7 → 1.0.9

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.
Files changed (169) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.en.md +144 -0
  3. package/README.md +21 -7
  4. package/kb/INDEX.md +19 -5
  5. package/kb/README.md +11 -10
  6. package/kb/extra/AGENTS.md +4 -4
  7. package/kb/extra/cookbook/adding-a-vendored-package.md +2 -2
  8. package/kb/extra/cookbook/adding-a-vendored-package.zh.md +2 -2
  9. package/kb/extra/deepseek-llm-api-wire-extensions.md +159 -0
  10. package/kb/extra/deepseek-llm-api-wire-extensions.zh.md +159 -0
  11. package/kb/extra/development.md +8 -14
  12. package/kb/extra/development.zh.md +8 -14
  13. package/kb/extra/event-producer-consumer.md +47 -41
  14. package/kb/extra/event-producer-consumer.zh.md +47 -41
  15. package/kb/extra/glossary.md +1 -1
  16. package/kb/extra/glossary.zh.md +1 -1
  17. package/kb/extra/graph-atlas.md +0 -2
  18. package/kb/extra/graph-atlas.zh.md +0 -2
  19. package/kb/extra/i18n/README.md +4 -4
  20. package/kb/extra/i18n/README.zh.md +4 -4
  21. package/kb/extra/module-graph.md +680 -413
  22. package/kb/extra/module-graph.zh.md +681 -414
  23. package/kb/extra/postmortem/0001-acp-default-export-drops-inject.md +2 -2
  24. package/kb/extra/postmortem/0001-acp-default-export-drops-inject.zh.md +2 -2
  25. package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.md +2 -2
  26. package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md +2 -2
  27. package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.md +2 -2
  28. package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.zh.md +2 -2
  29. package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.md +1 -1
  30. package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.zh.md +1 -1
  31. package/kb/extra/rescope.md +2 -2
  32. package/kb/extra/rescope.zh.md +2 -2
  33. package/kb/extra/subsystems/agent-team.md +24 -1
  34. package/kb/extra/subsystems/agent-team.zh.md +24 -1
  35. package/kb/extra/subsystems/attachment.md +12 -4
  36. package/kb/extra/subsystems/attachment.zh.md +12 -4
  37. package/kb/extra/subsystems/extensions.md +18 -0
  38. package/kb/extra/subsystems/extensions.zh.md +18 -0
  39. package/kb/extra/subsystems/feedback.md +2 -2
  40. package/kb/extra/subsystems/feedback.zh.md +2 -2
  41. package/kb/extra/subsystems/todo.md +32 -0
  42. package/kb/extra/subsystems/todo.zh.md +32 -0
  43. package/kb/extra/subsystems/webhook.md +70 -0
  44. package/kb/extra/subsystems/webhook.zh.md +70 -0
  45. package/kb/extra/testing.md +11 -10
  46. package/kb/extra/testing.zh.md +8 -7
  47. package/kb/meta/search-index.json +269 -161
  48. package/kb/meta/site-pages.txt +182 -168
  49. package/kb/meta/source.json +5 -5
  50. package/kb/meta/topics.md +14 -6
  51. package/kb/site/develop/basic/publish.md +2 -2
  52. package/kb/site/develop/basic/tool.md +1 -1
  53. package/kb/site/develop/cordis-tutorial/07-into-the-harness.md +4 -4
  54. package/kb/site/develop/framework/events.md +1 -1
  55. package/kb/site/develop/practice/dynamic-cordis.md +17 -0
  56. package/kb/site/develop/practice/llm-adapter.md +3 -3
  57. package/kb/site/en/develop/basic/publish.md +2 -2
  58. package/kb/site/en/develop/basic/tool.md +1 -1
  59. package/kb/site/en/develop/cordis-tutorial/07-into-the-harness.md +4 -4
  60. package/kb/site/en/develop/framework/events.md +1 -1
  61. package/kb/site/en/develop/practice/dynamic-cordis.md +17 -0
  62. package/kb/site/en/develop/practice/llm-adapter.md +3 -3
  63. package/kb/site/en/guide/github-review.md +104 -0
  64. package/kb/site/en/guide/mcp-memory.md +103 -0
  65. package/kb/site/en/guide/python-sdk.md +80 -34
  66. package/kb/site/en/guide/schedule.md +21 -0
  67. package/kb/site/en/reference/agent-lifecycle.md +1 -1
  68. package/kb/{extra → site/en/reference}/api-gateway.md +11 -9
  69. package/kb/site/en/reference/capability-seams.md +115 -67
  70. package/kb/site/en/reference/config-catalog.md +358 -164
  71. package/kb/site/en/reference/cookbook/adding-a-package.md +2 -2
  72. package/kb/site/en/reference/cookbook/adding-a-settings-card.md +2 -2
  73. package/kb/site/en/reference/cookbook/adding-a-tool.md +11 -4
  74. package/kb/site/en/reference/cookbook/adding-an-llm-adapter.md +1 -1
  75. package/kb/site/en/reference/cookbook/extension-cookbook.md +6 -6
  76. package/kb/site/en/reference/cordis-api/inherited.md +1 -1
  77. package/kb/site/en/reference/cordis-primer.md +2 -1
  78. package/kb/site/en/reference/index.md +19 -7
  79. package/kb/site/en/reference/persistence-catalog.md +91 -44
  80. package/kb/site/en/reference/subsystems/approval.md +10 -10
  81. package/kb/site/en/reference/subsystems/client-modules.md +58 -16
  82. package/kb/site/en/reference/subsystems/code-runtime.md +3 -3
  83. package/kb/site/en/reference/subsystems/compaction.md +2 -2
  84. package/kb/site/en/reference/{cookbook/adding-a-conversation-node.md → subsystems/conversation.md} +43 -24
  85. package/kb/site/en/reference/subsystems/core.md +70 -12
  86. package/kb/site/en/reference/subsystems/credentials.md +43 -3
  87. package/kb/site/en/reference/subsystems/filesystem.md +12 -2
  88. package/kb/site/en/reference/subsystems/index.md +6 -1
  89. package/kb/site/en/reference/subsystems/jobs.md +1 -1
  90. package/kb/site/en/reference/subsystems/llm-streaming.md +132 -11
  91. package/kb/site/en/reference/subsystems/permission-presets.md +1 -1
  92. package/kb/site/en/reference/subsystems/persistence.md +22 -3
  93. package/kb/site/en/reference/subsystems/plan.md +1 -1
  94. package/kb/site/en/reference/subsystems/session-projection.md +74 -33
  95. package/kb/site/en/reference/subsystems/session-query.md +9 -1
  96. package/kb/site/en/reference/subsystems/session-reference.md +28 -7
  97. package/kb/site/en/reference/subsystems/session-telemetry.md +2 -3
  98. package/kb/site/en/reference/subsystems/session.md +260 -41
  99. package/kb/site/en/reference/subsystems/settings.md +78 -1
  100. package/kb/site/en/reference/subsystems/skills.md +23 -0
  101. package/kb/site/en/reference/subsystems/slots.md +177 -0
  102. package/kb/site/en/reference/subsystems/spill.md +2 -2
  103. package/kb/site/en/reference/subsystems/storage.md +9 -1
  104. package/kb/site/en/reference/subsystems/subagent.md +90 -23
  105. package/kb/site/en/reference/subsystems/system-prompt.md +4 -4
  106. package/kb/site/en/reference/subsystems/token-meter.md +25 -10
  107. package/kb/site/en/reference/subsystems/tools.md +39 -39
  108. package/kb/site/en/reference/subsystems/typert.md +44 -37
  109. package/kb/site/en/reference/subsystems/user-questions.md +33 -33
  110. package/kb/site/en/reference/subsystems/web-client.md +98 -0
  111. package/kb/site/en/reference/subsystems/web-server.md +11 -5
  112. package/kb/site/en/reference/subsystems/web.md +7 -1
  113. package/kb/site/en/reference/subsystems/workspace.md +95 -2
  114. package/kb/site/en/reference/tool-catalog.md +76 -18
  115. package/kb/site/en/reference/tool-execution-pipeline.md +1 -1
  116. package/kb/site/guide/github-review.md +104 -0
  117. package/kb/site/guide/mcp-memory.md +103 -0
  118. package/kb/site/guide/python-sdk.md +87 -41
  119. package/kb/site/guide/schedule.md +21 -0
  120. package/kb/site/reference/agent-lifecycle.md +1 -1
  121. package/kb/{extra/api-gateway.zh.md → site/reference/api-gateway.md} +11 -9
  122. package/kb/site/reference/capability-seams.md +115 -67
  123. package/kb/site/reference/config-catalog.md +357 -163
  124. package/kb/site/reference/cookbook/adding-a-package.md +2 -2
  125. package/kb/site/reference/cookbook/adding-a-settings-card.md +2 -2
  126. package/kb/site/reference/cookbook/adding-a-tool.md +11 -4
  127. package/kb/site/reference/cookbook/adding-an-llm-adapter.md +1 -1
  128. package/kb/site/reference/cookbook/extension-cookbook.md +6 -6
  129. package/kb/site/reference/cordis-api/inherited.md +1 -1
  130. package/kb/site/reference/cordis-primer.md +2 -1
  131. package/kb/site/reference/index.md +19 -7
  132. package/kb/site/reference/persistence-catalog.md +87 -40
  133. package/kb/site/reference/subsystems/approval.md +10 -10
  134. package/kb/site/reference/subsystems/client-modules.md +58 -16
  135. package/kb/site/reference/subsystems/code-runtime.md +3 -3
  136. package/kb/site/reference/subsystems/compaction.md +2 -2
  137. package/kb/site/reference/{cookbook/adding-a-conversation-node.md → subsystems/conversation.md} +43 -24
  138. package/kb/site/reference/subsystems/core.md +70 -12
  139. package/kb/site/reference/subsystems/credentials.md +43 -3
  140. package/kb/site/reference/subsystems/filesystem.md +12 -2
  141. package/kb/site/reference/subsystems/index.md +6 -1
  142. package/kb/site/reference/subsystems/jobs.md +1 -1
  143. package/kb/site/reference/subsystems/llm-streaming.md +132 -11
  144. package/kb/site/reference/subsystems/persistence.md +22 -3
  145. package/kb/site/reference/subsystems/plan.md +1 -1
  146. package/kb/site/reference/subsystems/session-projection.md +74 -33
  147. package/kb/site/reference/subsystems/session-query.md +9 -1
  148. package/kb/site/reference/subsystems/session-reference.md +28 -7
  149. package/kb/site/reference/subsystems/session-telemetry.md +2 -3
  150. package/kb/site/reference/subsystems/session.md +260 -41
  151. package/kb/site/reference/subsystems/settings.md +78 -1
  152. package/kb/site/reference/subsystems/skills.md +23 -0
  153. package/kb/site/reference/subsystems/slots.md +177 -0
  154. package/kb/site/reference/subsystems/spill.md +2 -2
  155. package/kb/site/reference/subsystems/storage.md +9 -1
  156. package/kb/site/reference/subsystems/subagent.md +90 -23
  157. package/kb/site/reference/subsystems/system-prompt.md +4 -4
  158. package/kb/site/reference/subsystems/token-meter.md +25 -10
  159. package/kb/site/reference/subsystems/tools.md +39 -39
  160. package/kb/site/reference/subsystems/typert.md +44 -37
  161. package/kb/site/reference/subsystems/user-questions.md +33 -33
  162. package/kb/site/reference/subsystems/web-client.md +98 -0
  163. package/kb/site/reference/subsystems/web-server.md +11 -5
  164. package/kb/site/reference/subsystems/web.md +7 -1
  165. package/kb/site/reference/subsystems/workspace.md +95 -2
  166. package/kb/site/reference/tool-catalog.md +76 -18
  167. package/kb/site/reference/tool-execution-pipeline.md +1 -1
  168. package/package.json +11 -3
  169. package/skills/dsh-plugin-dev-kb.md +8 -6
@@ -56,7 +56,7 @@ export function apply(ctx: Context, config: Config) {
56
56
  `stream()` yields chunks using this protocol:
57
57
 
58
58
  ```ts
59
- import { CallId, type StreamChunk } from '@deepseek-ai/dsh-llm'
59
+ import { ToolCallId, type StreamChunk } from '@deepseek-ai/dsh-llm'
60
60
 
61
61
  async function* exampleChunks(): AsyncIterable<StreamChunk> {
62
62
  // 1. Start each content block with block-start.
@@ -78,7 +78,7 @@ async function* exampleChunks(): AsyncIterable<StreamChunk> {
78
78
  yield {
79
79
  type: 'tool-call-delta',
80
80
  index: 1,
81
- id: CallId('call-123'),
81
+ id: ToolCallId('call-123'),
82
82
  name: 'bash',
83
83
  argumentsDelta: '{"command":"ls"}',
84
84
  }
@@ -87,7 +87,7 @@ async function* exampleChunks(): AsyncIterable<StreamChunk> {
87
87
  index: 1,
88
88
  block: {
89
89
  type: 'tool-call',
90
- id: CallId('call-123'),
90
+ id: ToolCallId('call-123'),
91
91
  name: 'bash',
92
92
  arguments: '{"command":"ls"}',
93
93
  },
@@ -0,0 +1,104 @@
1
+ ---
2
+ editSource: "docs/user/guide/github-review.md"
3
+ ---
4
+
5
+ # Create review Sessions from GitHub webhooks
6
+
7
+ This opt-in overlay adds a signed GitHub endpoint to `dsh web`. When a pull request in the configured repository changes from draft to ready for review, the rule creates a titled root Session under the repository's Web Workspace and starts a read-only review prompt.
8
+
9
+ ## Prerequisites
10
+
11
+ - A local checkout that DSH may register as a Web Workspace.
12
+ - A high-entropy GitHub webhook secret available through the `DSH_GITHUB_WEBHOOK_SECRET` credential reference.
13
+ - A TLS reverse proxy or tunnel that can forward one public URL to the loopback listener.
14
+ - GitHub webhook subscription to the Pull requests event with content type `application/json`.
15
+
16
+ The overlay defaults the Workspace to the launch directory and the listener to `127.0.0.1:3081`. Override them with `DSH_GITHUB_REVIEW_WORKSPACE` and `DSH_GITHUB_WEBHOOK_PORT`.
17
+
18
+ ## Start DSH
19
+
20
+ Generate a secret and retain the same value across restarts:
21
+
22
+ ```sh
23
+ export DSH_GITHUB_WEBHOOK_SECRET="$(openssl rand -hex 32)"
24
+ printf '%s\n' "$DSH_GITHUB_WEBHOOK_SECRET"
25
+ ```
26
+
27
+ From a development checkout:
28
+
29
+ ```sh
30
+ export DSH_GITHUB_REVIEW_WORKSPACE=/path/to/deepseek-harness
31
+ pnpm dsh web --patch apps/cli/config/examples/github-review/cordis.yml
32
+ ```
33
+
34
+ An installed DSH uses the same overlay through an absolute path:
35
+
36
+ ```sh
37
+ dsh web --patch /absolute/path/to/github-review/cordis.yml
38
+ ```
39
+
40
+ For a permanent profile, place `github-ready-review-rule.mjs` beside `$DSH_HOME/profiles/web/cordis.patch.yml`, append the rows from `cordis.yml` to that patch, and start with `dsh web`. The shipped CLI already contains both webhook packages; the overlay alone activates them.
41
+
42
+ ## Expose the dedicated endpoint
43
+
44
+ The main Web UI and `/api` remain on port 3080. The overlay mounts a second WebServer in an isolated realm; only `POST /github` is registered there, and every other path returns `404`.
45
+
46
+ A Caddy configuration can expose only that listener:
47
+
48
+ ```caddyfile
49
+ hooks.example.com {
50
+ route {
51
+ @github path /github
52
+ reverse_proxy @github 127.0.0.1:3081
53
+ respond 404
54
+ }
55
+ }
56
+ ```
57
+
58
+ Configure GitHub with:
59
+
60
+ ```text
61
+ Payload URL: https://hooks.example.com/github
62
+ Content type: application/json
63
+ Secret: DSH_GITHUB_WEBHOOK_SECRET value
64
+ Events: Pull requests
65
+ Active: yes
66
+ ```
67
+
68
+ ## Rule behavior
69
+
70
+ The rule accepts only source `primary-github`, repository `deepseek-harness/deepseek-harness`, event `pull_request`, and action `ready_for_review`. It passes the exact head SHA plus selected PR fields to the review prompt, labeling the JSON as untrusted metadata and forbidding file, branch, PR, or GitHub mutation.
71
+
72
+ The Session request selects the `standard` agent preset and `read-only` permission preset. `workspacePath` is canonicalized through `WorkspaceRegistry.create()`, so the first matching delivery creates the Web Workspace when absent and later deliveries reuse it.
73
+
74
+ The HTTP response is intentionally weaker than the Agent outcome: `202` means the signature and JSON were accepted and rule calls were scheduled in memory. It does not mean this rule matched or that a Session was created.
75
+
76
+ ## Programmatic extensions
77
+
78
+ `run()` is ordinary trusted JavaScript. A deployment can query an internal policy service before returning a Session request:
79
+
80
+ ```js
81
+ const response = await fetch('https://policy.internal/pr-review', {
82
+ method: 'POST',
83
+ headers: { 'content-type': 'application/json' },
84
+ body: JSON.stringify({ repository: payload.repository.full_name }),
85
+ signal,
86
+ })
87
+ if (!response.ok || (await response.json()).automaticReview !== true) return null
88
+ ```
89
+
90
+ It can also map repositories to different local paths:
91
+
92
+ ```js
93
+ const workspacePath = {
94
+ 'deepseek-harness/deepseek-harness': '/path/to/deepseek-harness',
95
+ 'deepseek-harness/dsh-sdk': '/path/to/dsh-sdk',
96
+ }[payload.repository.full_name]
97
+ if (workspacePath === undefined) return null
98
+ ```
99
+
100
+ ## Delivery semantics
101
+
102
+ The webhook runtime stores no delivery or execution state. Repeated delivery runs the rule and may create another Session. A crash loses rule calls that have not admitted their prompt. After prompt admission, the ordinary Session log, persistence, Workspace, and Agent lifecycle own the work.
103
+
104
+ The webhook secret authenticates inbound GitHub data only. It grants neither rule code nor the created Agent outbound GitHub access; configure that authority separately when a rule or Agent needs it.
@@ -0,0 +1,103 @@
1
+ ---
2
+ editSource: "docs/user/guide/mcp-memory.md"
3
+ ---
4
+
5
+ # Connect a third-party memory MCP server
6
+
7
+ These three **default-off reference configurations** connect one memory system to DSH through [`@deepseek-ai/dsh-mcp-client`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/mcp/mcp-client/README.md). Pick one, or copy the same generic MCP row for another server.
8
+
9
+ These third-party configurations are provided as interoperability examples only. Their inclusion does not imply endorsement, recommendation, partnership, or ongoing support by DeepSeek.
10
+
11
+ ## What DSH does
12
+
13
+ DSH parses the selected Cordis overlay, starts a configured stdio command or connects to a configured Streamable HTTP URL, discovers MCP tools, and exposes them as `mcp__<serverName>__<tool>`. DSH does **not** download the server, initialize its database, choose its model or embedding provider, create a cloud account, migrate vendor data, or supervise a separate HTTP service. For stdio, the generic client launches and stops the child with the DSH plugin lifecycle; for HTTP, the upstream service must already be running.
14
+
15
+ The stdio bridge deliberately removes ambient variables whose names usually identify credentials and all `DSH_*` variables before launching a child; other ambient variables remain inherited. Each example adds only the baseline override it needs. If an optional upstream feature needs another secret, add that variable to the row's `config.env` instead of putting the secret directly in YAML.
16
+
17
+ ## Choose one
18
+
19
+ | System | Tested pin | Transport | Upstream prerequisite |
20
+ |---|---:|---|---|
21
+ | [Memorix](https://github.com/AVIDS2/memorix) | `memorix@1.3.0` (`500792cad3144142293bfbb20acb4841c9f7fcfa`) | stdio | Node 22.18+ and `npm install --global memorix@1.3.0` |
22
+ | [MCP Reference Memory](https://github.com/modelcontextprotocol/servers/tree/main/src/memory) | `@modelcontextprotocol/server-memory@2026.7.4` (`6dd0a683e198783e30feabf7abaf42f925bd18b1`) | stdio | `npm install --global @modelcontextprotocol/server-memory@2026.7.4` |
23
+ | [Engram](https://github.com/Gentleman-Programming/engram) | `v1.20.0` (`ba9e46ced152c37a7cb9e576153c41995873e2fc`) | stdio | Go 1.25.10+ and `go install github.com/Gentleman-Programming/engram/cmd/engram@v1.20.0`, or the matching release binary |
24
+
25
+ ## Enable one
26
+
27
+ Pass one overlay to DSH:
28
+
29
+ ```sh
30
+ dsh web --patch "$PWD/apps/cli/config/examples/mcp-memory/memorix.cordis.yml"
31
+ ```
32
+
33
+ Replace the filename with `mcp-reference-memory.cordis.yml` or `engram.cordis.yml`. The path may point to a copied file anywhere on disk. No memory server is present in the shipped composition, so omitting `--patch` keeps all three disabled.
34
+
35
+ To keep the selection across runs, merge the chosen file's single `insert` patch into a user patch layer — `$DSH_HOME/profiles/<name>/cordis.patch.yml` for one profile, or `$DSH_HOME/cordis.patch.yml` for every profile on the machine. Do not copy over an existing file: it may already contain unrelated user patches.
36
+
37
+ ## Provider setup
38
+
39
+ ### Memorix
40
+
41
+ ```sh
42
+ npm install --global memorix@1.3.0
43
+ dsh web --patch "$PWD/apps/cli/config/examples/mcp-memory/memorix.cordis.yml"
44
+ ```
45
+
46
+ Memorix works in local heuristic mode without an LLM or embedding service. Configure optional providers in Memorix's own `~/.memorix/config.toml` or project `memorix.toml`. The example keeps Memorix's Git-project identity from the DSH working directory and uses Memorix's own `~/.memorix/data` default. Set `MEMORIX_DATA_DIR` before starting DSH to override it.
47
+
48
+ ### MCP Reference Memory
49
+
50
+ ```sh
51
+ npm install --global @modelcontextprotocol/server-memory@2026.7.4
52
+ dsh web --patch "$PWD/apps/cli/config/examples/mcp-memory/mcp-reference-memory.cordis.yml"
53
+ ```
54
+
55
+ This reference server stores a local knowledge graph and exposes entity, relation, observation, read, search, and open tools. It needs no model or embedding service. The example stores its JSONL at `$HOME/.dsh-mcp-reference-memory.jsonl` instead of the installed npm package directory. Set `MEMORY_FILE_PATH` before starting DSH to override it.
56
+
57
+ Search is case-insensitive substring matching over entity names, types, and observations, not semantic retrieval. The server does not add embeddings, automatic summarization, conflict resolution, or a forgetting policy.
58
+
59
+ ### Engram
60
+
61
+ ```sh
62
+ go install github.com/Gentleman-Programming/engram/cmd/engram@v1.20.0
63
+ dsh web --patch "$PWD/apps/cli/config/examples/mcp-memory/engram.cordis.yml"
64
+ ```
65
+
66
+ Engram owns storage and project selection: it uses `~/.engram` by default, detects the Git project from the DSH working directory, and accepts `ENGRAM_DATA_DIR` or `ENGRAM_PROJECT` as ambient overrides.
67
+
68
+ ## Optional shared model instruction
69
+
70
+ Add this short, vendor-neutral instruction to your existing model instructions if the server's tool descriptions do not trigger memory use reliably:
71
+
72
+ > When the user asks you to remember something, call a memory write tool. When historical information may be relevant, search memory and use relevant results.
73
+
74
+ This is additive guidance only. The examples do not replace DSH's system-prompt persona.
75
+
76
+ ## Verify write, fresh-session recall, and use
77
+
78
+ Use one unique value and keep the provider's storage scope unchanged throughout:
79
+
80
+ 1. In DSH session A, ask: `Remember that my validation drink is lapsang-<unique suffix>.` Confirm the model called the provider's write tool and the tool returned success.
81
+ 2. Create DSH session B in the same running Host. Do not copy session A's conversation. Ask: `What is my validation drink? Check memory.` Confirm the model called the provider's search or recall tool and returned the value.
82
+ 3. Still in session B, ask: `Use that preference to suggest one drink for the meeting.` Confirm the answer uses the recalled value.
83
+
84
+ A new DSH session is required; a Host restart is not. A crashed MCP child triggers automatic reconnection with backoff and a tool re-sync; tools stay listed and calls fail only during the outage, and after the reconnect budget is exhausted the tools are unregistered and reconnection stops until a reload or restart. Initial discovery is asynchronous, so wait for the provider's `mcp__...` tools before sending the first validation prompt.
85
+
86
+ ## Bring another MCP server
87
+
88
+ Copy the same entry fields and use a unique `id` and `serverName`:
89
+
90
+ ```yaml
91
+ - insert:
92
+ - id: memory-my-server
93
+ name: '@deepseek-ai/dsh-mcp-client'
94
+ config:
95
+ serverName: my-memory
96
+ transport: stdio
97
+ command: my-memory-mcp
98
+ args: []
99
+ env: {}
100
+ cwd: !!js process.cwd()
101
+ ```
102
+
103
+ For a remote server, use `transport: streamable-http`, `url`, and `headers` instead. Provider-specific installation, identity, authentication, models, embeddings, persistence, and licensing remain the provider's responsibility.
@@ -4,19 +4,19 @@ editSource: "docs/user/guide/python-sdk.md"
4
4
 
5
5
  # Get started with the Python SDK
6
6
 
7
- This tutorial is the programmatic alternative to the Web UI. It installs the published Python SDK, runs a checked-in agent composition, and shows how to call the same API from your own program.
7
+ This tutorial installs the published Python SDK, runs the shipped standalone minimal profile, and shows how to customize the same `dsh` profile from your own program.
8
8
 
9
9
  ## Prerequisites
10
10
 
11
11
  - Python 3.10 or newer
12
12
  - Git
13
- - Linux x64, Linux arm64, or macOS 14 or newer on arm64
13
+ - Linux x64, Linux arm64, macOS 14 or newer on arm64, or Windows x64
14
14
  - A DeepSeek-compatible API endpoint and credential
15
- - An isolated workspace that the agent may modify
15
+ - An isolated workspace and an isolated Harness home
16
16
 
17
17
  ## Install the SDK
18
18
 
19
- Clone the repository for its runnable example, create a virtual environment, and install the SDK with its same-version bundled runtime:
19
+ ### Linux and macOS
20
20
 
21
21
  ```sh
22
22
  git clone https://github.com/deepseek-ai/deepseek-harness.git
@@ -26,51 +26,76 @@ python -m venv .venv
26
26
  python -m pip install deepseek-harness-sdk
27
27
  ```
28
28
 
29
- The installed runtime needs no system Node.js. Repository contributors who need to build the runtime or wheels from source should use the [Python contributor workflows](https://github.com/deepseek-ai/deepseek-harness/blob/master/python/development.md).
29
+ ### Windows PowerShell
30
+
31
+ ```powershell
32
+ git clone https://github.com/deepseek-ai/deepseek-harness.git
33
+ Set-Location deepseek-harness
34
+ py -3.10 -m venv .venv
35
+ .venv\Scripts\Activate.ps1
36
+ python -m pip install deepseek-harness-sdk
37
+ ```
38
+
39
+ The installation includes a matching native runtime wheel and the `dsh` command. Normal SDK execution needs no system Node.js. Repository contributors who build the artifacts should use the [Python contributor workflow](https://github.com/deepseek-ai/deepseek-harness/blob/master/python/development.md).
30
40
 
31
41
  ## Run the checked-in example
32
42
 
33
- Set the credential in the environment. Set `DEEPSEEK_BASE_URL` as well when the model is served by an OpenAI-compatible proxy rather than the default DeepSeek endpoint.
43
+ Export the credential and, when needed, a compatible proxy endpoint:
44
+
45
+ ### Linux and macOS
34
46
 
35
47
  ```sh
36
48
  export DEEPSEEK_API_KEY=sk-your-key-here
37
49
  # export DEEPSEEK_BASE_URL=http://127.0.0.1:8000/v1
38
- # export DSH_MODEL=deepseek-v4-flash
39
- # export DSH_SYSTEM_PROMPT='You are a helpful software engineer assistant.'
40
50
  ```
41
51
 
42
- Run one task against an isolated workspace and session directory:
52
+ ### Windows PowerShell
53
+
54
+ ```powershell
55
+ $env:DEEPSEEK_API_KEY = "sk-your-key-here"
56
+ # $env:DEEPSEEK_BASE_URL = "http://127.0.0.1:8000/v1"
57
+ ```
58
+
59
+ Run one task with explicit workspace and home paths:
60
+
61
+ ### Linux and macOS
43
62
 
44
63
  ```sh
45
- python examples/jsonrpc-agent/minimal.py \
46
- --workspace /absolute/path/to/workspace \
47
- --session-root /absolute/path/to/sessions \
64
+ python python/sdk/examples/minimal.py \
65
+ --workspace /absolute/path/to/disposable-workspace \
66
+ --dsh-home /absolute/path/to/example-dsh-home \
48
67
  --session-id example-001 \
49
68
  "Inspect the repository and fix the failing tests."
50
69
  ```
51
70
 
52
- The script prints the final assistant response. The session directory receives a JSONL log containing the assembled model requests and tool calls.
71
+ ### Windows PowerShell
72
+
73
+ ```powershell
74
+ python python/sdk/examples/minimal.py `
75
+ --workspace C:\work\disposable-workspace `
76
+ --dsh-home C:\work\example-dsh-home `
77
+ --session-id example-001 `
78
+ "Inspect the repository and fix the failing tests."
79
+ ```
53
80
 
54
- ## Use the SDK in your own program
81
+ The script prints the final assistant response. The selected home receives the generated `sdk-minimal` profile, installed plugins, and uncompressed JSONL session logs under `sessions/`. The example and SDK never silently read `~/.dsh`.
55
82
 
56
- The checked-in example is a thin wrapper around this SDK call:
83
+ ## Use the SDK in your program
57
84
 
58
85
  ```python
59
86
  from pathlib import Path
60
87
 
61
88
  from deepseek_harness import DeepSeekHarness
62
89
 
63
- config = Path("examples/jsonrpc-agent/minimal.cordis.yml").resolve()
64
- workspace = Path("/absolute/path/to/workspace").resolve()
65
- sessions = Path("/absolute/path/to/sessions").resolve()
66
-
90
+ workspace = Path("/absolute/path/to/disposable-workspace").resolve()
91
+ dsh_home = Path("/absolute/path/to/example-dsh-home").resolve()
67
92
  with DeepSeekHarness(
68
93
  provider="deepseek-official",
69
94
  model="deepseek-v4-flash",
70
95
  max_tokens=49_152,
71
96
  cwd=str(workspace),
72
- session_root=str(sessions),
73
- cordis=str(config),
97
+ dsh_home=str(dsh_home),
98
+ profile="sdk-minimal",
74
99
  ) as harness:
75
100
  result = harness.run(
76
101
  "Inspect the repository and fix the failing tests.",
@@ -80,27 +105,48 @@ with DeepSeekHarness(
80
105
  print(result.final_response)
81
106
  ```
82
107
 
83
- `DeepSeekHarness` starts the bundled runtime lazily and reuses it until the context manager exits. Reusing the same harness and session id preserves the session-owned Bash process, including its working directory, exported variables, and shell functions. Use a fresh session id for an independent task; reuse an id only when the next call should continue the same durable conversation.
108
+ The SDK starts the bundled `dsh --profile sdk-minimal` process lazily and reuses it until context-manager exit. The profile, its persistent patch, the home patch, and any ordered `patches` tuple form the application configuration. There is no separate Python runtime bin or complete-config option.
109
+
110
+ ## Install or define plugins
111
+
112
+ Use `dsh plugin` for dependencies and bundle layers that should persist in this home:
113
+
114
+ ### Linux and macOS
115
+
116
+ ```sh
117
+ export DSH_HOME=/absolute/path/to/example-dsh-home
118
+ dsh --profile sdk-minimal --dump-default-config >/dev/null
119
+ dsh plugin --profile sdk-minimal add file:/absolute/path/to/my-plugin-bundle
120
+ ```
84
121
 
85
- ## Understand the example composition
122
+ ### Windows PowerShell
123
+
124
+ ```powershell
125
+ $env:DSH_HOME = "C:\work\example-dsh-home"
126
+ dsh --profile sdk-minimal --dump-default-config | Out-Null
127
+ dsh plugin --profile sdk-minimal add file:C:/work/my-plugin-bundle
128
+ ```
129
+
130
+ The first command initializes the shipped standalone profile. The second forwards package management to `pnpm`, then records any installed package that exports a `dsh.bundle` layer. Install `pnpm` only for this management command; launching the installed SDK does not need it. Edit `$DSH_HOME/profiles/sdk-minimal/cordis.patch.yml` for persistent row changes, or pass patch files from Python for per-launch changes.
131
+
132
+ Another `profile` is valid when it includes `@deepseek-ai/dsh-sdk-app` or another JSON-RPC server row. Missing server rows, unresolved plugins, and invalid patches fail during startup instead of falling back to another composition.
133
+
134
+ ## Understand the minimal profile
86
135
 
87
136
  | Property | Value |
88
137
  |---|---|
89
138
  | System prompt | `DSH_SYSTEM_PROMPT`, falling back to `You are a helpful software engineer assistant.` |
90
139
  | Model in `minimal.py` | `--model`, then `DSH_MODEL`, then `deepseek-v4-flash` |
91
- | Model-facing tools | Persistent `bash` and `str_replace_editor` only |
92
- | Bash timeout | 300 seconds |
140
+ | Model-facing tools | Persistent `bash` on Linux/macOS or `pwsh` on Windows, plus `str_replace_editor` |
141
+ | Shell timeout | 300 seconds |
93
142
  | Editor output limit | 16,000 characters |
94
- | Context compaction | Disabled |
95
- | Filesystem | Bare local backend; absolute editor paths may address any path visible to the runtime process |
96
- | Session persistence | Uncompressed JSONL under `DSH_SESSION_ROOT` |
97
-
98
- The composition omits harness identity, workspace prompt text, skills, one-shot Bash, task tools, compaction, and every other model-facing plugin. Sandbox-policy facts are logged as runtime user context rather than appended to the system prompt.
143
+ | Runtime context and compaction | Absent |
144
+ | Session persistence | Uncompressed JSONL under `<dsh_home>/sessions` |
99
145
 
100
- ## Choose workspace and session IDs
146
+ The profile's sole bundle inserts the complete tree over an empty root and does not include `dsh-base`; later base-profile tools therefore cannot appear implicitly. It contains the SDK protocol, one environment-configured DeepSeek adapter, local execution, and persistence, while settings, managed credentials, telemetry, Web tools, subagents, local instruction discovery, and compaction are absent. It pins `danger-full-access`, so the platform-selected persistent shell and editor can modify any path visible to the runtime; use a disposable checkout or container.
101
147
 
102
- `cwd` selects the workspace available to the agent, while `session_root` stores session logs and state. Use a fresh session id for an independent task; reuse an id only when the next call should continue the same conversation and persistent shell state.
148
+ The installed wheel still packages the full `web` profile and frontend assets. Run `dsh web` against an explicit `DSH_HOME` when a Python SDK deployment also needs the browser application; `web` is a separate CLI application and cannot serve a Python SDK client.
103
149
 
104
- The composition uses `danger-full-access`. Run it only inside a disposable checkout or container: Bash and the editor can modify any path allowed to the runtime process. The persistent PTY backend requires a POSIX terminal substrate, so this composition does not support Windows agents.
150
+ Use a fresh home when profiles, plugins, credentials, settings, and sessions must be isolated. Use a fresh session id for independent work; reuse a harness, home, and id only to continue the same durable conversation and session-owned resources.
105
151
 
106
- The [`jsonrpc-agent` example reference](https://github.com/deepseek-ai/deepseek-harness/blob/master/examples/jsonrpc-agent/README.md) owns the exact composition. The [Python SDK reference](https://github.com/deepseek-ai/deepseek-harness/blob/master/python/sdk/README.md) covers lifecycle, results, notifications, runtime selection, and configuration; the [Cordis primer](../reference/cordis-primer.md) covers composition syntax.
152
+ The [bundle reference](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/bundle/sdk-minimal/README.md) owns the exact tree, and the [example reference](https://github.com/deepseek-ai/deepseek-harness/blob/master/python/sdk/examples/README.md) owns the runnable program. The [Python SDK reference](https://github.com/deepseek-ai/deepseek-harness/blob/master/python/sdk/README.md) covers lifecycle, results, notifications, and low-level behavior; the [dsh CLI reference](https://github.com/deepseek-ai/deepseek-harness/blob/master/apps/cli/reference/README.md) covers profile layering.
@@ -0,0 +1,21 @@
1
+ ---
2
+ editSource: "docs/user/guide/schedule.md"
3
+ ---
4
+
5
+ # Schedule session-local reminders
6
+
7
+ This overlay opts one `dsh web` process into Schedule reminders without changing the shipped default Web composition:
8
+
9
+ ```sh
10
+ dsh web --patch apps/cli/config/examples/schedule/cordis.yml
11
+ ```
12
+
13
+ The current overlay supports reminders created with a positive whole-number `after_seconds`, an absolute `at` target, or a fixed-rate `every_seconds` interval of at least 300 seconds. The model manages them through `schedule_create`, `schedule_list`, and `schedule_delete`; every result identifies delivery as `session-local`.
14
+
15
+ The browser attaches its IANA zone to each prompt. Time-context tells the model to interpret otherwise-unqualified dates and times in that request's browser zone. This assumption belongs to natural-language interpretation only: `schedule_create.at` must be either a strict RFC 3339 date-time with `Z` or a numeric offset, or `{ date, time, time_zone }` with an explicit `UTC` or IANA Area/Location zone. Schedule does not retain or infer a Session default zone. Daylight-saving gaps are rejected, overlaps choose the first instant, and successful records keep only the resulting UTC target.
16
+
17
+ The original Session log owns each reminder. A live root Agent waits until it is fully idle, then queues a normal follow-up turn in that conversation. It never steers current work and adds no separate receipt or reminder card. Closing the process or leaving the Session cold stops its in-memory timer without deleting the record; reopening that same Session restores the wait and delivers an overdue reminder. Reading cold history never activates it, and a fork does not inherit its parent's reminders.
18
+
19
+ Every reminders stay aligned to their creation time. If one is overdue, only its latest due occurrence is presented and the next target remains on the original fixed-rate sequence. All distinct Every records overdue at the same idle decision are combined into one follow-up with one occurrence each; missed intervals do not create a backlog. Due one-shots run before that batch. Calendar and Cron expressions are not supported.
20
+
21
+ Create and actual delete operations acknowledge success only after Session persistence confirms their event prefix. Schedule does not provide browser, operating-system, email, SMS, or other external notification. A durable dispatch records that the follow-up was queued; it does not acknowledge model success or user receipt.
@@ -79,7 +79,7 @@ The `assistant/message` event records every successful provider call, including
79
79
 
80
80
  `dsh-compaction-basic` uses `agent/pre-step` for pressure before request derivation and `agent/request-error` only for canonical context overflow. Once either trigger qualifies, optional tool-result pruning runs before summary selection. Recovery works between the closed failed step and failed turn close, and opens a fresh retry turn only when pruning or summarization advances the surface replacement generation; otherwise the original request error remains authoritative.
81
81
 
82
- The returned `agent/pre-step` decision is authoritative; listeners wrapping `next()` preserve downstream messages unless replacement is intentional. Steering and injected context pass through the same waterfall after a later claim operation takes their next-step batch.
82
+ The returned `agent/pre-step` decision is authoritative; listeners wrapping `next()` preserve downstream messages and `startsRequestSeries` unless replacement is intentional. Steering and injected context pass through the same waterfall after a later claim operation takes their next-step batch.
83
83
 
84
84
  SDK users that need replayable transcript data should consume `session/event`; `agent/*` is the live coordination API for queue/status, prompt interception, request construction, steering, continuation, and errors.
85
85
 
@@ -1,6 +1,8 @@
1
- # API Gateway
1
+ ---
2
+ editSource: "docs/api-gateway.md"
3
+ ---
2
4
 
3
- English | [中文](api-gateway.zh.md)
5
+ # API Gateway
4
6
 
5
7
  This is the current-state reference for the Typert API Gateway. It describes how business services declare unary Remote methods, how the build generates Host and Client contracts, and how calls reuse the Connection RPC and `/api` route. Session events, incremental data, and other streaming protocols are outside this document's scope; they may use the same Connection but do not use Remote method descriptors.
6
8
 
@@ -59,7 +61,7 @@ The Client uses concrete functions on ordinary objects, not a JavaScript Proxy.
59
61
 
60
62
  ```ts ignore-check
61
63
  import type { SessionId } from '@deepseek-ai/dsh-session/types'
62
- import type { AgentContext } from '@deepseek-ai/dsh-client-runtime/client'
64
+ import type { AgentContext } from '@deepseek-ai/dsh-api-session-controller/client'
63
65
  import type { Context } from '@deepseek-ai/cordis'
64
66
  import type {} from '@deepseek-ai/dsh-api-remotes/client'
65
67
 
@@ -84,7 +86,7 @@ The `api-remotes` assembly and the `ctx.remote` contract are React-independent;
84
86
  | Shared | `@deepseek-ai/dsh-typert-protocol` | Declares decorators, Gateway bindings, merge-extensible protocol maps, invocation descriptors, and provider types; starts no TypeScript analysis and registers no Cordis services |
85
87
  | Build | `@deepseek-ai/dsh-typert-generator` | Strictly analyzes Remote signatures, the type graph, lookups, Contexts, and source locations from the Host `ts.Program`, then generates Host and Host-for-Client artifacts |
86
88
  | Host | `@deepseek-ai/dsh-typert-registry` and Loader | Places generated Host descriptors, schemas, and business-package registrations in `ctx.typert`, and holds lookup and Context providers |
87
- | Host | `@deepseek-ai/dsh-api-remotes` | Owns the application Agent/Session identity policy and configures the corresponding Typert lookups |
89
+ | Host | `@deepseek-ai/dsh-api-session-controller` | Owns the application Agent/Session identity policy and configures the corresponding Typert lookups |
88
90
  | Host | `@deepseek-ai/dsh-api-gateway` | Provides `ctx.typertGateway`, claims Remote endpoints, resolves objects or Contexts, invokes live Cordis services, and validates request and return values |
89
91
  | Client | `@deepseek-ai/dsh-api-gateway/client` | Provides `ctx.remote` and `remote.<namespace>` child Services, mounts generated descriptors as concrete methods, and initiates, validates, and cancels calls through the Connection |
90
92
  | Client | `@deepseek-ai/dsh-api-remotes/client` | Explicitly selects and mounts the `/remote` contributions allowed by the application and brings the corresponding declaration merges into business code |
@@ -98,7 +100,7 @@ The root build runs `build:lib:host`, `build:lib:client`, and `build:web` in ord
98
100
 
99
101
  Both tsdown passes receive the complete workspace and bundle only JavaScript emitted to `lib/types` by the corresponding tsc phase. The root config does not scan Client artifacts, classify package names, or pass a maintained filter to tsdown; package-local configs return entries for the current phase based on `DSH_BUILD_FACE`. An ordinary Client plugin produces both its Node loader entry and browser bundle during the Client phase.
100
102
 
101
- `api-remotes` is the only package with split TypeScript faces. Its Host project owns the Agent/Session lookup policy, while its Client project depends on `/remote` declarations generated for business packages during Host tsdown; root aggregates and direct consumers must reference `api/remotes/tsconfig.host.json` or `api/remotes/tsconfig.client.json` respectively. The package's `clientBundle(..., { hostPhase: true })` produces its Host entry during Host tsdown and leaves only the browser entry for Client tsdown. Every other package remains registered in one aggregate.
103
+ `api/remotes`, `api/gateway`, `api/session-controller`, and `api/workspace-controller` (plus `client/connection`) split TypeScript faces. `api/remotes`' Client project depends on `/remote` declarations generated for business packages during Host tsdown; root aggregates and direct consumers must reference each split package's `tsconfig.host.json` or `tsconfig.client.json` respectively. `api-remotes`' `clientBundle(..., { hostPhase: true })` produces its Host entry during Host tsdown and leaves only the browser entry for Client tsdown. The Agent/Session lookup policy lives in `@deepseek-ai/dsh-api-session-controller`, not in `api-remotes`.
102
104
 
103
105
  Each contributing business package writes generated files to its own `lib/` directory, not to its source directory:
104
106
 
@@ -118,13 +120,13 @@ Strict analysis requires a Remote to be a public, non-static instance method wit
118
120
 
119
121
  ## Runtime invocation
120
122
 
121
- Remote and API Proxy share the Connection's `/api` route. The Client Remote calls `connection.rpc.call('/api', '<namespace>/<method>', { args }, signal)`; the HTTP carrier maps this to `POST /api/<namespace>/<method>`, with a payload containing only a named `args` object.
123
+ Remote calls use the Connection's `/api` route. The Client Remote calls `connection.rpc.call('/api', '<namespace>/<method>', { args }, signal)`; the HTTP carrier maps this to `POST /api/<namespace>/<method>`, with a payload containing only a named `args` object.
122
124
 
123
- The Connection performs the unified trust check for `/api` before the HTTP bridge, then dispatches inside the shared FetchHandler in interceptor order. The Typert Gateway claims only two-segment endpoints that have a strict descriptor or active SRC marker; unclaimed requests fall back to the existing API Proxy. The Connection owns transport, RPC ids, response envelopes, and request cancellation, while the Gateway owns only the Remote data protocol and business dispatch. Replacing the Connection carrier in the future does not require changes to Remote descriptors or the Client programming interface.
125
+ The Connection performs the unified trust check for `/api` before the HTTP bridge, then dispatches inside the shared FetchHandler. The Typert Gateway claims only two-segment endpoints that have a strict descriptor or active SRC marker; feature-owned exact Fetch routes handle non-JSON responses, and other requests return 404. The Connection owns transport, RPC ids, response envelopes, and request cancellation, while the Gateway owns only the Remote data protocol and business dispatch. Replacing the Connection carrier does not require changes to Remote descriptors or the Client programming interface.
124
126
 
125
127
  For every call, the Gateway resolves the descriptor and live service from the current registries instead of caching business objects. It requires the fields in `args` to match the descriptor exactly, validates wire values with codecs, resolves objects or receivers through registered lookup or Context providers, invokes the service method targeted by the binding, and validates the return value. A missing provider, unknown identity, binding mismatch, missing or extra argument, schema failure, or missing method fails before entering or after leaving business code.
126
128
 
127
- The lookup provider's `register()` supplies both the stable declaration and the default resolver; `configure()` supplies a resolver owned by Host composition that may execute asynchronously and is scoped to an effect lifetime. Configuration may precede provider mounting; without a provider, invocation still fails with `lookup-unavailable`, and unloading the configuration restores the provider's default policy. API Remotes owns the standard `agentFor()` semantics for `agent` and `session`: it reuses a live Agent, automatically resumes ordinary cold sessions, deduplicates concurrent resumes, and rejects identities owned by subagent routing; the `session` lookup returns that Agent's Session. The Web API Proxy supplies its Agent defaults and scope setup, then consumes the same resolver for legacy methods. Resume failures and ownership fences pass through unchanged as existing RPC errors rather than being collapsed into the Gateway's `internal` error.
129
+ The lookup provider's `register()` supplies both the stable declaration and the default resolver; `configure()` supplies a resolver owned by Host composition that may execute asynchronously and is scoped to an effect lifetime. Configuration may precede provider mounting; without a provider, invocation still fails with `lookup-unavailable`, and unloading the configuration restores the provider's default policy. The Session Controller owns the standard `agentFor()` semantics for `agent` and `session`: it reuses a live Agent, automatically resumes ordinary cold sessions, deduplicates concurrent resumes, and rejects identities owned by subagent routing; the `session` lookup returns that Agent's Session. Resume failures and ownership fences pass through unchanged as existing RPC errors rather than being collapsed into the Gateway's `internal` error.
128
130
 
129
131
  Unloading a Client contribution removes its descriptors and concrete methods together, aborts its in-flight calls, and makes stale method handles retained by external code reject further calls. A strict endpoint withdrawn on the Host also does not degrade to SRC inference, preventing a hot unload from silently weakening validation.
130
132
 
@@ -159,6 +161,6 @@ The running Client watcher consumes these generated files when it rebundles. If
159
161
 
160
162
  Remote handles only unary method calls with one request and one result. Session event streams, pagination, incremental reduce, projection, and entity substreams require a separate data protocol and registration model; even when they reuse the Connection, they must not masquerade as Remote methods or enter invocation descriptors.
161
163
 
162
- The API layers are organized as `remotes → gateway → connection → webserver`. The BFF and Typert RPC layers live under `packages/api`; Connection and WebServer live at `packages/client/connection` and `packages/host/webserver`. The API Proxy at `packages/host/apiproxy` handles endpoints without Remote descriptors.
164
+ The API layers are organized as `remotes → gateway → connection → webserver`. The BFF and Typert RPC layers live under `packages/api`; Connection and WebServer live at `packages/client/connection` and `packages/host/webserver`. A feature that needs a streamed or browser-native response registers an exact Connection Fetch route instead of defining a Remote method.
163
165
 
164
166
  Lookup policy is configured per key, so all `agent` or `session` parameters share the cold-resume behavior. Accepting live objects only would require an explicit per-parameter or per-endpoint policy, which does not exist; the business method must not guess whether the object came from restoration.