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.
- package/CHANGELOG.md +16 -0
- package/README.en.md +144 -0
- package/README.md +21 -7
- package/kb/INDEX.md +19 -5
- package/kb/README.md +11 -10
- package/kb/extra/AGENTS.md +4 -4
- package/kb/extra/cookbook/adding-a-vendored-package.md +2 -2
- package/kb/extra/cookbook/adding-a-vendored-package.zh.md +2 -2
- package/kb/extra/deepseek-llm-api-wire-extensions.md +159 -0
- package/kb/extra/deepseek-llm-api-wire-extensions.zh.md +159 -0
- package/kb/extra/development.md +8 -14
- package/kb/extra/development.zh.md +8 -14
- package/kb/extra/event-producer-consumer.md +47 -41
- package/kb/extra/event-producer-consumer.zh.md +47 -41
- package/kb/extra/glossary.md +1 -1
- package/kb/extra/glossary.zh.md +1 -1
- package/kb/extra/graph-atlas.md +0 -2
- package/kb/extra/graph-atlas.zh.md +0 -2
- package/kb/extra/i18n/README.md +4 -4
- package/kb/extra/i18n/README.zh.md +4 -4
- package/kb/extra/module-graph.md +680 -413
- package/kb/extra/module-graph.zh.md +681 -414
- package/kb/extra/postmortem/0001-acp-default-export-drops-inject.md +2 -2
- package/kb/extra/postmortem/0001-acp-default-export-drops-inject.zh.md +2 -2
- package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.md +2 -2
- package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md +2 -2
- package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.md +2 -2
- package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.zh.md +2 -2
- package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.md +1 -1
- package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.zh.md +1 -1
- package/kb/extra/rescope.md +2 -2
- package/kb/extra/rescope.zh.md +2 -2
- package/kb/extra/subsystems/agent-team.md +24 -1
- package/kb/extra/subsystems/agent-team.zh.md +24 -1
- package/kb/extra/subsystems/attachment.md +12 -4
- package/kb/extra/subsystems/attachment.zh.md +12 -4
- package/kb/extra/subsystems/extensions.md +18 -0
- package/kb/extra/subsystems/extensions.zh.md +18 -0
- package/kb/extra/subsystems/feedback.md +2 -2
- package/kb/extra/subsystems/feedback.zh.md +2 -2
- package/kb/extra/subsystems/todo.md +32 -0
- package/kb/extra/subsystems/todo.zh.md +32 -0
- package/kb/extra/subsystems/webhook.md +70 -0
- package/kb/extra/subsystems/webhook.zh.md +70 -0
- package/kb/extra/testing.md +11 -10
- package/kb/extra/testing.zh.md +8 -7
- package/kb/meta/search-index.json +269 -161
- package/kb/meta/site-pages.txt +182 -168
- package/kb/meta/source.json +5 -5
- package/kb/meta/topics.md +14 -6
- package/kb/site/develop/basic/publish.md +2 -2
- package/kb/site/develop/basic/tool.md +1 -1
- package/kb/site/develop/cordis-tutorial/07-into-the-harness.md +4 -4
- package/kb/site/develop/framework/events.md +1 -1
- package/kb/site/develop/practice/dynamic-cordis.md +17 -0
- package/kb/site/develop/practice/llm-adapter.md +3 -3
- package/kb/site/en/develop/basic/publish.md +2 -2
- package/kb/site/en/develop/basic/tool.md +1 -1
- package/kb/site/en/develop/cordis-tutorial/07-into-the-harness.md +4 -4
- package/kb/site/en/develop/framework/events.md +1 -1
- package/kb/site/en/develop/practice/dynamic-cordis.md +17 -0
- package/kb/site/en/develop/practice/llm-adapter.md +3 -3
- package/kb/site/en/guide/github-review.md +104 -0
- package/kb/site/en/guide/mcp-memory.md +103 -0
- package/kb/site/en/guide/python-sdk.md +80 -34
- package/kb/site/en/guide/schedule.md +21 -0
- package/kb/site/en/reference/agent-lifecycle.md +1 -1
- package/kb/{extra → site/en/reference}/api-gateway.md +11 -9
- package/kb/site/en/reference/capability-seams.md +115 -67
- package/kb/site/en/reference/config-catalog.md +358 -164
- package/kb/site/en/reference/cookbook/adding-a-package.md +2 -2
- package/kb/site/en/reference/cookbook/adding-a-settings-card.md +2 -2
- package/kb/site/en/reference/cookbook/adding-a-tool.md +11 -4
- package/kb/site/en/reference/cookbook/adding-an-llm-adapter.md +1 -1
- package/kb/site/en/reference/cookbook/extension-cookbook.md +6 -6
- package/kb/site/en/reference/cordis-api/inherited.md +1 -1
- package/kb/site/en/reference/cordis-primer.md +2 -1
- package/kb/site/en/reference/index.md +19 -7
- package/kb/site/en/reference/persistence-catalog.md +91 -44
- package/kb/site/en/reference/subsystems/approval.md +10 -10
- package/kb/site/en/reference/subsystems/client-modules.md +58 -16
- package/kb/site/en/reference/subsystems/code-runtime.md +3 -3
- package/kb/site/en/reference/subsystems/compaction.md +2 -2
- package/kb/site/en/reference/{cookbook/adding-a-conversation-node.md → subsystems/conversation.md} +43 -24
- package/kb/site/en/reference/subsystems/core.md +70 -12
- package/kb/site/en/reference/subsystems/credentials.md +43 -3
- package/kb/site/en/reference/subsystems/filesystem.md +12 -2
- package/kb/site/en/reference/subsystems/index.md +6 -1
- package/kb/site/en/reference/subsystems/jobs.md +1 -1
- package/kb/site/en/reference/subsystems/llm-streaming.md +132 -11
- package/kb/site/en/reference/subsystems/permission-presets.md +1 -1
- package/kb/site/en/reference/subsystems/persistence.md +22 -3
- package/kb/site/en/reference/subsystems/plan.md +1 -1
- package/kb/site/en/reference/subsystems/session-projection.md +74 -33
- package/kb/site/en/reference/subsystems/session-query.md +9 -1
- package/kb/site/en/reference/subsystems/session-reference.md +28 -7
- package/kb/site/en/reference/subsystems/session-telemetry.md +2 -3
- package/kb/site/en/reference/subsystems/session.md +260 -41
- package/kb/site/en/reference/subsystems/settings.md +78 -1
- package/kb/site/en/reference/subsystems/skills.md +23 -0
- package/kb/site/en/reference/subsystems/slots.md +177 -0
- package/kb/site/en/reference/subsystems/spill.md +2 -2
- package/kb/site/en/reference/subsystems/storage.md +9 -1
- package/kb/site/en/reference/subsystems/subagent.md +90 -23
- package/kb/site/en/reference/subsystems/system-prompt.md +4 -4
- package/kb/site/en/reference/subsystems/token-meter.md +25 -10
- package/kb/site/en/reference/subsystems/tools.md +39 -39
- package/kb/site/en/reference/subsystems/typert.md +44 -37
- package/kb/site/en/reference/subsystems/user-questions.md +33 -33
- package/kb/site/en/reference/subsystems/web-client.md +98 -0
- package/kb/site/en/reference/subsystems/web-server.md +11 -5
- package/kb/site/en/reference/subsystems/web.md +7 -1
- package/kb/site/en/reference/subsystems/workspace.md +95 -2
- package/kb/site/en/reference/tool-catalog.md +76 -18
- package/kb/site/en/reference/tool-execution-pipeline.md +1 -1
- package/kb/site/guide/github-review.md +104 -0
- package/kb/site/guide/mcp-memory.md +103 -0
- package/kb/site/guide/python-sdk.md +87 -41
- package/kb/site/guide/schedule.md +21 -0
- package/kb/site/reference/agent-lifecycle.md +1 -1
- package/kb/{extra/api-gateway.zh.md → site/reference/api-gateway.md} +11 -9
- package/kb/site/reference/capability-seams.md +115 -67
- package/kb/site/reference/config-catalog.md +357 -163
- package/kb/site/reference/cookbook/adding-a-package.md +2 -2
- package/kb/site/reference/cookbook/adding-a-settings-card.md +2 -2
- package/kb/site/reference/cookbook/adding-a-tool.md +11 -4
- package/kb/site/reference/cookbook/adding-an-llm-adapter.md +1 -1
- package/kb/site/reference/cookbook/extension-cookbook.md +6 -6
- package/kb/site/reference/cordis-api/inherited.md +1 -1
- package/kb/site/reference/cordis-primer.md +2 -1
- package/kb/site/reference/index.md +19 -7
- package/kb/site/reference/persistence-catalog.md +87 -40
- package/kb/site/reference/subsystems/approval.md +10 -10
- package/kb/site/reference/subsystems/client-modules.md +58 -16
- package/kb/site/reference/subsystems/code-runtime.md +3 -3
- package/kb/site/reference/subsystems/compaction.md +2 -2
- package/kb/site/reference/{cookbook/adding-a-conversation-node.md → subsystems/conversation.md} +43 -24
- package/kb/site/reference/subsystems/core.md +70 -12
- package/kb/site/reference/subsystems/credentials.md +43 -3
- package/kb/site/reference/subsystems/filesystem.md +12 -2
- package/kb/site/reference/subsystems/index.md +6 -1
- package/kb/site/reference/subsystems/jobs.md +1 -1
- package/kb/site/reference/subsystems/llm-streaming.md +132 -11
- package/kb/site/reference/subsystems/persistence.md +22 -3
- package/kb/site/reference/subsystems/plan.md +1 -1
- package/kb/site/reference/subsystems/session-projection.md +74 -33
- package/kb/site/reference/subsystems/session-query.md +9 -1
- package/kb/site/reference/subsystems/session-reference.md +28 -7
- package/kb/site/reference/subsystems/session-telemetry.md +2 -3
- package/kb/site/reference/subsystems/session.md +260 -41
- package/kb/site/reference/subsystems/settings.md +78 -1
- package/kb/site/reference/subsystems/skills.md +23 -0
- package/kb/site/reference/subsystems/slots.md +177 -0
- package/kb/site/reference/subsystems/spill.md +2 -2
- package/kb/site/reference/subsystems/storage.md +9 -1
- package/kb/site/reference/subsystems/subagent.md +90 -23
- package/kb/site/reference/subsystems/system-prompt.md +4 -4
- package/kb/site/reference/subsystems/token-meter.md +25 -10
- package/kb/site/reference/subsystems/tools.md +39 -39
- package/kb/site/reference/subsystems/typert.md +44 -37
- package/kb/site/reference/subsystems/user-questions.md +33 -33
- package/kb/site/reference/subsystems/web-client.md +98 -0
- package/kb/site/reference/subsystems/web-server.md +11 -5
- package/kb/site/reference/subsystems/web.md +7 -1
- package/kb/site/reference/subsystems/workspace.md +95 -2
- package/kb/site/reference/tool-catalog.md +76 -18
- package/kb/site/reference/tool-execution-pipeline.md +1 -1
- package/package.json +11 -3
- 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 {
|
|
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:
|
|
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:
|
|
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
|
|
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,
|
|
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
|
|
15
|
+
- An isolated workspace and an isolated Harness home
|
|
16
16
|
|
|
17
17
|
## Install the SDK
|
|
18
18
|
|
|
19
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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/
|
|
46
|
-
--workspace /absolute/path/to/workspace \
|
|
47
|
-
--
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
64
|
-
|
|
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
|
-
|
|
73
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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`
|
|
92
|
-
|
|
|
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
|
-
|
|
|
95
|
-
|
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 [
|
|
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
|
-
|
|
1
|
+
---
|
|
2
|
+
editSource: "docs/api-gateway.md"
|
|
3
|
+
---
|
|
2
4
|
|
|
3
|
-
|
|
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-
|
|
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-
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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`.
|
|
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.
|