dsh-plugin-dev-kb 1.0.8 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/README.en.md +6 -6
- package/README.md +6 -6
- package/kb/INDEX.md +21 -5
- package/kb/README.md +11 -10
- package/kb/extra/AGENTS.md +4 -4
- package/kb/extra/cookbook/adding-a-remote-api.md +197 -0
- package/kb/extra/cookbook/adding-a-remote-api.zh.md +197 -0
- package/kb/extra/cookbook/adding-a-vendored-package.md +2 -2
- package/kb/extra/cookbook/adding-a-vendored-package.zh.md +2 -2
- package/kb/extra/deepseek-llm-api-wire-extensions.md +163 -0
- package/kb/extra/deepseek-llm-api-wire-extensions.zh.md +163 -0
- package/kb/extra/development.md +8 -14
- package/kb/extra/development.zh.md +8 -14
- package/kb/extra/event-producer-consumer.md +55 -48
- package/kb/extra/event-producer-consumer.zh.md +58 -51
- package/kb/extra/glossary.md +1 -1
- package/kb/extra/glossary.zh.md +1 -1
- package/kb/extra/graph-atlas.md +0 -2
- package/kb/extra/graph-atlas.zh.md +0 -2
- package/kb/extra/i18n/README.md +4 -4
- package/kb/extra/i18n/README.zh.md +4 -4
- package/kb/extra/i18n/style-samples.md +2 -2
- package/kb/extra/module-graph.md +646 -926
- package/kb/extra/module-graph.zh.md +648 -928
- package/kb/extra/postmortem/0001-acp-default-export-drops-inject.md +2 -2
- package/kb/extra/postmortem/0001-acp-default-export-drops-inject.zh.md +2 -2
- package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.md +2 -2
- package/kb/extra/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md +2 -2
- package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.md +2 -2
- package/kb/extra/postmortem/0003-web-agent-gui-feedback-loop.zh.md +2 -2
- package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.md +1 -1
- package/kb/extra/postmortem/0004-landlock-partial-notice-misclassified-child-failures.zh.md +1 -1
- package/kb/extra/rescope.md +2 -2
- package/kb/extra/rescope.zh.md +2 -2
- package/kb/extra/subsystems/agent-team.md +28 -4
- package/kb/extra/subsystems/agent-team.zh.md +28 -4
- package/kb/extra/subsystems/attachment.md +168 -7
- package/kb/extra/subsystems/attachment.zh.md +168 -7
- package/kb/extra/subsystems/extensions.md +18 -0
- package/kb/extra/subsystems/extensions.zh.md +18 -0
- package/kb/extra/subsystems/feedback.md +4 -4
- package/kb/extra/subsystems/feedback.zh.md +4 -4
- package/kb/extra/subsystems/todo.md +32 -0
- package/kb/extra/subsystems/todo.zh.md +32 -0
- package/kb/extra/subsystems/webhook.md +70 -0
- package/kb/extra/subsystems/webhook.zh.md +70 -0
- package/kb/extra/testing.md +15 -10
- package/kb/extra/testing.zh.md +13 -8
- package/kb/extra/web-styling.md +4 -0
- package/kb/extra/web-styling.zh.md +4 -0
- package/kb/meta/search-index.json +309 -177
- package/kb/meta/site-pages.txt +183 -167
- package/kb/meta/source.json +5 -5
- package/kb/meta/topics.md +14 -6
- package/kb/site/develop/basic/publish.md +2 -2
- package/kb/site/develop/basic/tool.md +1 -1
- package/kb/site/develop/cordis-tutorial/07-into-the-harness.md +5 -4
- package/kb/site/develop/framework/events.md +1 -1
- package/kb/site/develop/practice/dynamic-cordis.md +17 -0
- package/kb/site/develop/practice/llm-adapter.md +4 -3
- package/kb/site/en/develop/basic/publish.md +2 -2
- package/kb/site/en/develop/basic/tool.md +1 -1
- package/kb/site/en/develop/cordis-tutorial/07-into-the-harness.md +5 -4
- package/kb/site/en/develop/framework/events.md +1 -1
- package/kb/site/en/develop/practice/dynamic-cordis.md +17 -0
- package/kb/site/en/develop/practice/llm-adapter.md +4 -3
- package/kb/site/en/guide/github-review.md +104 -0
- package/kb/site/en/guide/mcp-memory.md +103 -0
- package/kb/site/en/guide/network-proxy.md +87 -0
- package/kb/site/en/guide/providers.md +70 -17
- package/kb/site/en/guide/python-sdk.md +80 -34
- package/kb/site/en/guide/schedule.md +23 -0
- package/kb/site/en/reference/agent-lifecycle.md +6 -4
- package/kb/{extra → site/en/reference}/api-gateway.md +12 -10
- package/kb/site/en/reference/capability-seams.md +128 -73
- package/kb/site/en/reference/config-catalog.md +481 -360
- package/kb/site/en/reference/cookbook/adding-a-package.md +3 -4
- package/kb/site/en/reference/cookbook/adding-a-settings-card.md +12 -10
- package/kb/site/en/reference/cookbook/adding-a-tool.md +11 -4
- package/kb/site/en/reference/cookbook/adding-an-llm-adapter.md +1 -1
- package/kb/site/en/reference/cookbook/extension-cookbook.md +20 -17
- package/kb/site/en/reference/cordis-api/inherited.md +1 -1
- package/kb/site/en/reference/cordis-primer.md +2 -1
- package/kb/site/en/reference/index.md +30 -11
- package/kb/site/en/reference/persistence-catalog.md +148 -80
- package/kb/site/en/reference/subsystems/approval.md +10 -10
- package/kb/site/en/reference/subsystems/client-modules.md +58 -16
- package/kb/site/en/reference/subsystems/code-runtime.md +10 -6
- package/kb/site/en/reference/subsystems/commands.md +25 -16
- package/kb/site/en/reference/subsystems/compaction.md +11 -11
- package/kb/site/en/reference/{cookbook/adding-a-conversation-node.md → subsystems/conversation.md} +50 -24
- package/kb/site/en/reference/subsystems/core.md +156 -17
- package/kb/site/en/reference/subsystems/credentials.md +44 -3
- package/kb/site/en/reference/subsystems/filesystem.md +12 -2
- package/kb/site/en/reference/subsystems/goal.md +1 -1
- package/kb/site/en/reference/subsystems/index.md +7 -2
- package/kb/site/en/reference/subsystems/jobs.md +1 -1
- package/kb/site/en/reference/subsystems/llm-streaming.md +154 -12
- package/kb/site/en/reference/subsystems/permission-presets.md +6 -6
- package/kb/site/en/reference/subsystems/persistence.md +185 -175
- package/kb/site/en/reference/subsystems/plan.md +2 -2
- package/kb/site/en/reference/subsystems/sandbox.md +2 -0
- package/kb/site/en/reference/subsystems/schedule.md +9 -3
- package/kb/site/en/reference/subsystems/session-projection.md +115 -48
- package/kb/site/en/reference/subsystems/session-query.md +28 -14
- package/kb/site/en/reference/subsystems/session-reference.md +53 -8
- package/kb/site/en/reference/subsystems/session-telemetry.md +8 -8
- package/kb/site/en/reference/subsystems/session-title.md +6 -6
- package/kb/site/en/reference/subsystems/session.md +401 -99
- package/kb/site/en/reference/subsystems/settings.md +101 -6
- package/kb/site/en/reference/subsystems/skills.md +23 -0
- package/kb/site/en/reference/subsystems/slots.md +178 -0
- package/kb/site/en/reference/subsystems/spill.md +2 -2
- package/kb/site/en/reference/subsystems/storage.md +34 -3
- package/kb/site/en/reference/subsystems/subagent.md +122 -109
- package/kb/site/en/reference/subsystems/system-prompt.md +17 -4
- package/kb/site/en/reference/subsystems/token-meter.md +27 -12
- package/kb/site/en/reference/subsystems/tools.md +39 -39
- package/kb/site/en/reference/subsystems/typert.md +62 -55
- package/kb/site/en/reference/subsystems/user-questions.md +33 -33
- package/kb/site/en/reference/subsystems/web-client.md +98 -0
- package/kb/site/en/reference/subsystems/web-server.md +11 -5
- package/kb/site/en/reference/subsystems/web.md +7 -1
- package/kb/site/en/reference/subsystems/workspace.md +102 -9
- package/kb/site/en/reference/tool-catalog.md +86 -82
- package/kb/site/en/reference/tool-execution-pipeline.md +1 -1
- package/kb/site/guide/github-review.md +104 -0
- package/kb/site/guide/mcp-memory.md +103 -0
- package/kb/site/guide/network-proxy.md +87 -0
- package/kb/site/guide/providers.md +70 -17
- package/kb/site/guide/python-sdk.md +87 -41
- package/kb/site/guide/schedule.md +23 -0
- package/kb/site/reference/agent-lifecycle.md +6 -4
- package/kb/{extra/api-gateway.zh.md → site/reference/api-gateway.md} +12 -10
- package/kb/site/reference/capability-seams.md +128 -73
- package/kb/site/reference/config-catalog.md +481 -360
- package/kb/site/reference/cookbook/adding-a-package.md +3 -4
- package/kb/site/reference/cookbook/adding-a-settings-card.md +12 -10
- package/kb/site/reference/cookbook/adding-a-tool.md +11 -4
- package/kb/site/reference/cookbook/adding-an-llm-adapter.md +1 -1
- package/kb/site/reference/cookbook/extension-cookbook.md +20 -17
- package/kb/site/reference/cordis-api/inherited.md +1 -1
- package/kb/site/reference/cordis-primer.md +2 -1
- package/kb/site/reference/index.md +30 -11
- package/kb/site/reference/persistence-catalog.md +148 -80
- package/kb/site/reference/subsystems/approval.md +10 -10
- package/kb/site/reference/subsystems/client-modules.md +58 -16
- package/kb/site/reference/subsystems/code-runtime.md +10 -6
- package/kb/site/reference/subsystems/commands.md +25 -16
- package/kb/site/reference/subsystems/compaction.md +11 -11
- package/kb/site/reference/{cookbook/adding-a-conversation-node.md → subsystems/conversation.md} +50 -24
- package/kb/site/reference/subsystems/core.md +156 -17
- package/kb/site/reference/subsystems/credentials.md +44 -3
- package/kb/site/reference/subsystems/filesystem.md +12 -2
- package/kb/site/reference/subsystems/goal.md +1 -1
- package/kb/site/reference/subsystems/index.md +7 -2
- package/kb/site/reference/subsystems/jobs.md +1 -1
- package/kb/site/reference/subsystems/llm-streaming.md +154 -12
- package/kb/site/reference/subsystems/permission-presets.md +5 -5
- package/kb/site/reference/subsystems/persistence.md +184 -174
- package/kb/site/reference/subsystems/plan.md +2 -2
- package/kb/site/reference/subsystems/schedule.md +9 -3
- package/kb/site/reference/subsystems/session-projection.md +115 -48
- package/kb/site/reference/subsystems/session-query.md +28 -14
- package/kb/site/reference/subsystems/session-reference.md +53 -8
- package/kb/site/reference/subsystems/session-telemetry.md +8 -8
- package/kb/site/reference/subsystems/session-title.md +6 -6
- package/kb/site/reference/subsystems/session.md +401 -99
- package/kb/site/reference/subsystems/settings.md +101 -6
- package/kb/site/reference/subsystems/skills.md +23 -0
- package/kb/site/reference/subsystems/slots.md +178 -0
- package/kb/site/reference/subsystems/spill.md +2 -2
- package/kb/site/reference/subsystems/storage.md +34 -3
- package/kb/site/reference/subsystems/subagent.md +122 -109
- package/kb/site/reference/subsystems/system-prompt.md +17 -4
- package/kb/site/reference/subsystems/token-meter.md +27 -12
- package/kb/site/reference/subsystems/tools.md +39 -39
- package/kb/site/reference/subsystems/typert.md +62 -55
- package/kb/site/reference/subsystems/user-questions.md +33 -33
- package/kb/site/reference/subsystems/web-client.md +98 -0
- package/kb/site/reference/subsystems/web-server.md +11 -5
- package/kb/site/reference/subsystems/web.md +7 -1
- package/kb/site/reference/subsystems/workspace.md +102 -9
- package/kb/site/reference/tool-catalog.md +85 -81
- package/kb/site/reference/tool-execution-pipeline.md +1 -1
- package/package.json +2 -2
- package/skills/dsh-plugin-dev-kb.md +8 -6
|
@@ -56,7 +56,8 @@ export function apply(ctx: Context, config: Config) {
|
|
|
56
56
|
`stream()` yields chunks using this protocol:
|
|
57
57
|
|
|
58
58
|
```ts
|
|
59
|
-
import {
|
|
59
|
+
import { brandString } from '@deepseek-ai/dsh-brand'
|
|
60
|
+
import type { StreamChunk, ToolCallId } from '@deepseek-ai/dsh-llm'
|
|
60
61
|
|
|
61
62
|
async function* exampleChunks(): AsyncIterable<StreamChunk> {
|
|
62
63
|
// 1. Start each content block with block-start.
|
|
@@ -78,7 +79,7 @@ async function* exampleChunks(): AsyncIterable<StreamChunk> {
|
|
|
78
79
|
yield {
|
|
79
80
|
type: 'tool-call-delta',
|
|
80
81
|
index: 1,
|
|
81
|
-
id:
|
|
82
|
+
id: brandString<ToolCallId>('call-123'),
|
|
82
83
|
name: 'bash',
|
|
83
84
|
argumentsDelta: '{"command":"ls"}',
|
|
84
85
|
}
|
|
@@ -87,7 +88,7 @@ async function* exampleChunks(): AsyncIterable<StreamChunk> {
|
|
|
87
88
|
index: 1,
|
|
88
89
|
block: {
|
|
89
90
|
type: 'tool-call',
|
|
90
|
-
id:
|
|
91
|
+
id: brandString<ToolCallId>('call-123'),
|
|
91
92
|
name: 'bash',
|
|
92
93
|
arguments: '{"command":"ls"}',
|
|
93
94
|
},
|
|
@@ -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.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
editSource: "docs/user/guide/network-proxy.md"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Run DSH behind a network proxy
|
|
6
|
+
|
|
7
|
+
DSH routes its outbound requests — model calls, web search, page fetches, and MCP servers over HTTP — through the proxy named by the standard proxy environment variables. It reads them at launch; nothing else needs configuring. A few paths stay direct by design or by runtime limit, listed under "What stays direct" below.
|
|
8
|
+
|
|
9
|
+
## Export the variables
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
export HTTPS_PROXY=http://127.0.0.1:7890
|
|
13
|
+
export HTTP_PROXY=http://127.0.0.1:7890
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Put both lines in your shell profile so every `dsh` invocation inherits them, or in `$DSH_HOME/.env` (`~/.dsh/.env` by default) next to your API key; an exported variable always wins over that file. A project's own `.env` cannot set them: it arrives with `git clone`, and DSH refuses to start rather than let a repository decide where your traffic goes.
|
|
17
|
+
|
|
18
|
+
A proxy that needs credentials takes them in the URL: `http://user:password@proxy.example:8080`. DSH never prints the URL back: a diagnostic names the variable it rejected, so neither the username nor the password appears anywhere.
|
|
19
|
+
|
|
20
|
+
## Why your browser is proxied but your terminal is not
|
|
21
|
+
|
|
22
|
+
This is the most common surprise, and it is not specific to DSH. There is no single "system proxy" that all software obeys — there are three unrelated mechanisms:
|
|
23
|
+
|
|
24
|
+
| Mechanism | Who follows it |
|
|
25
|
+
|---|---|
|
|
26
|
+
| The operating system's proxy settings | Safari, most native macOS apps, Chrome and Edge |
|
|
27
|
+
| The `HTTP_PROXY` / `HTTPS_PROXY` environment variables | `curl`, `git`, `npm`, `pip`, and DSH |
|
|
28
|
+
| TUN mode (a virtual network interface) | Everything, transparently |
|
|
29
|
+
|
|
30
|
+
The "system proxy" switch in a proxy application such as Clash writes only the first one. Browsers pick it up; command-line tools never see it. That is why exporting the variables is a separate step, and why turning on TUN mode makes both work without any variables at all.
|
|
31
|
+
|
|
32
|
+
DSH does not read the operating system's proxy settings. Export the variables, or use TUN mode.
|
|
33
|
+
|
|
34
|
+
## Choose what stays direct
|
|
35
|
+
|
|
36
|
+
`NO_PROXY` lists hosts to reach directly:
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
export NO_PROXY=internal.example.com,.corp.example.com,registry.local
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
An entry names a host and matches it together with every subdomain under it: `NO_PROXY=example.com` also sends `api.example.com` direct. A leading `.` or `*.` is accepted and means the same thing. An entry may carry a `:port`, and `*` bypasses everything.
|
|
43
|
+
|
|
44
|
+
**CIDR ranges do not work.** An operating system bypass list often contains entries like `10.0.0.0/8` or `192.168.0.0/16`; copying those into `NO_PROXY` has no effect. Use host names or domain suffixes instead.
|
|
45
|
+
|
|
46
|
+
You do not need to list `localhost` or `127.0.0.1`. DSH always bypasses loopback, because its own Web UI and local servers would otherwise route through the proxy and loop.
|
|
47
|
+
|
|
48
|
+
## Limits worth knowing
|
|
49
|
+
|
|
50
|
+
**SOCKS proxies are not supported.** A `socks5://` value is reported at startup and skipped, and DSH connects directly for the scheme that named it — setting `HTTPS_PROXY=socks5://…` alongside a usable `HTTP_PROXY` leaves `https:` direct rather than borrowing the HTTP proxy. Point the variables at your proxy application's HTTP port instead — most expose both, and the HTTP one is usually a neighbouring port number.
|
|
51
|
+
|
|
52
|
+
**`ALL_PROXY` alone is enough.** DSH falls back to it for both schemes, even though Node and curl differ on this. Setting `HTTPS_PROXY` explicitly is still clearer.
|
|
53
|
+
|
|
54
|
+
**A TLS-intercepting corporate proxy needs its certificate.** If requests fail with a certificate error once the proxy is reachable, point Node at your organisation's CA bundle before launching:
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
export NODE_EXTRA_CA_CERTS=/path/to/corporate-ca.pem
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Node reads that variable only at process start, so export it before running `dsh`.
|
|
61
|
+
|
|
62
|
+
**Tools DSH runs for you follow the same proxy.** Commands in the bash tool, `git`, `gh`, and MCP servers started as child processes all inherit these variables. A child that is itself a Node program honors them only on Node 22.21 or later; an older Node connects directly. If one of your proxy variables holds a value DSH rejected — a SOCKS URL, say — Node-based tools also connect directly rather than fail to start, while `curl` and `git` still read that value.
|
|
63
|
+
|
|
64
|
+
**A password in the proxy URL reaches those tools too.** `HTTPS_PROXY=http://alice:s3cret@proxy.example:8080` is a normal environment variable, so every command DSH runs — including the ones the model writes — can read it, and a command that prints its environment puts the password in output that is kept. This is how the variable already behaves for everything else in your shell. If that matters, give the proxy a credential-free entry point, or authenticate it some other way than in the URL.
|
|
65
|
+
|
|
66
|
+
## What stays direct
|
|
67
|
+
|
|
68
|
+
Not every request DSH makes goes through the proxy:
|
|
69
|
+
|
|
70
|
+
- **Anything on this machine.** Loopback is always direct: `localhost`, the whole `127.0.0.0/8` range, `::1`, and `0.0.0.0`. A proxy cannot usefully reach a service that only listens locally.
|
|
71
|
+
- **Code the model writes.** The workflow and code-runtime workers never receive the proxy settings, so a script the model authors cannot read a proxy URL that may carry a password. Such a script reaches the network only if it configures that itself.
|
|
72
|
+
- **Usage telemetry.** The OTLP exporter uses Node's own HTTP client rather than the one a proxy configures, so telemetry connects directly and simply fails where direct egress is blocked. Nothing you do in DSH depends on it. Set `DSH_TELEMETRY_MODE=DISABLED` to turn it off entirely.
|
|
73
|
+
- **`web_fetch` to a literal private address.** A URL naming an address like `http://10.0.0.5/` is refused rather than handed to the proxy, the same refusal it gets with no proxy configured.
|
|
74
|
+
|
|
75
|
+
## Check that it worked
|
|
76
|
+
|
|
77
|
+
Ask the agent to fetch a page and watch your proxy application's connection log:
|
|
78
|
+
|
|
79
|
+
```sh
|
|
80
|
+
dsh --profile headless "fetch https://example.com and tell me the page title"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
If the request does not appear there, confirm the variables survive into DSH's own environment:
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
env | grep -i proxy
|
|
87
|
+
```
|
|
@@ -14,21 +14,39 @@ Open **Settings → Models**. The DeepSeek card exposes one API-key field; enter
|
|
|
14
14
|
|
|
15
15
|
Keys are write-only. The page receives a redacted descriptor after saving, never the literal secret. The key is stored in `$DSH_HOME/.credentials.yaml`, while settings retain only its credential reference.
|
|
16
16
|
|
|
17
|
-
## Add a
|
|
17
|
+
## Add a built-in provider
|
|
18
18
|
|
|
19
|
-
Choose **Add provider
|
|
19
|
+
Choose **Add provider** and pick a provider dsh ships with; the list shows provider ids such as `anthropic`, `openai`, `moonshotai` for Kimi, or `zai` for GLM. Enter its API key and save. The installed catalog supplies the endpoint, protocol, and model list.
|
|
20
20
|
|
|
21
|
-
Providers
|
|
21
|
+
Providers that sign in with OAuth, such as Codex, are not supported here yet.
|
|
22
22
|
|
|
23
23
|
## Add a custom provider
|
|
24
24
|
|
|
25
|
-
Choose **Add a custom provider** for a company gateway, self-hosted server, or provider absent from the installed catalog. Supply a lowercase Provider ID, base URL, API protocol, credential, and at least one model.
|
|
25
|
+
Choose **Add a custom provider** for a company gateway, self-hosted server, or provider absent from the installed catalog. Supply a lowercase Provider ID, base URL, API protocol, credential, and at least one model. The **API protocol** must be the one your gateway speaks, and the form offers three: `openai-completions` for OpenAI Chat Completions, `openai-responses` for the OpenAI Responses API, and `anthropic-messages` for the Anthropic Messages API. A provider speaks one protocol, so a gateway that serves two needs two providers.
|
|
26
26
|
|
|
27
27
|

|
|
28
28
|
|
|
29
29
|
The Provider ID is permanent because requests, saved sessions, model defaults, and credential references use it. To rename a provider, add a new provider and delete the old one. The display name, base URL, protocol, credential, and models remain editable.
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
### Discover models
|
|
32
|
+
|
|
33
|
+
Under **Model catalog**, choose **Fetch available models** to ask the endpoint which models it serves. The request uses the base URL, protocol, and key currently in the form, or a saved provider's stored key, and the reply opens a searchable picker: search, tick the models you want, and choose **Add selected**. Nothing is stored until you save or create the provider.
|
|
34
|
+
|
|
35
|
+
Discovery reads the listing formats common gateways publish, but not every endpoint answers in one of them, so treat it as a convenience rather than a guarantee: when it fails or lists nothing, add the model ids by hand and they work just the same. A built-in provider is always answered from the installed catalog, even when its base URL points at a gateway, so fetch through a custom provider to see what the gateway really serves.
|
|
36
|
+
|
|
37
|
+
## Select a model
|
|
38
|
+
|
|
39
|
+
Configured providers appear in the model picker. Selecting a model also makes it the default for new sessions. A session that has already sent a request retains the model recorded in its own log.
|
|
40
|
+
|
|
41
|
+
If a saved default names a provider that was deleted, the composer displays **Select model** and blocks input until another model is selected.
|
|
42
|
+
|
|
43
|
+
## Advanced configuration
|
|
44
|
+
|
|
45
|
+
The generated [plugin configuration catalog](../reference/config-catalog.md) lists every supported field and default for every plugin; [`dsh-llm-pi-ai`](../reference/config-catalog.md#deepseek-aidsh-llm-pi-ai) is the provider section this page configures. The [`dsh-llm-pi-ai`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/llm/llm-pi-ai/README.md) and [`dsh-llm-deepseek`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/llm/llm-deepseek/README.md) references own direct `settings.yaml` configuration, catalog resolution, reasoning controls, credentials, and adapter errors.
|
|
46
|
+
|
|
47
|
+
::: tip The form is deliberately small
|
|
48
|
+
The Models page exposes only what a route needs to exist: the API key, display name, base URL, API protocol, and for each model its id, display name, context window, and max output tokens. Every other field — reasoning effort levels, image input, request-compatibility switches, headers, timeouts, retry policy — is set in `$DSH_HOME/settings.yaml`, the same document the page writes. Edit it directly, or, when the browser runs on the same machine as the server, open it with **Open configuration file** in the Settings header; the adapters re-read it on the next request, so nothing needs a restart. The subsections below cover the fields most gateways need.
|
|
49
|
+
:::
|
|
32
50
|
|
|
33
51
|
### Image input
|
|
34
52
|
|
|
@@ -66,7 +84,7 @@ llm-pi-ai:
|
|
|
66
84
|
- id: second-model
|
|
67
85
|
```
|
|
68
86
|
|
|
69
|
-
`defaultInput` is a fallback, not an override, and defaults to `[text]`: on a
|
|
87
|
+
`defaultInput` is a fallback, not an override, and defaults to `[text]`: on a built-in provider it answers only for models its catalog does not describe, so it never removes images from a catalog model that has them. Narrow one of those with that model's own `input`. A built-in provider has no `models` list to put it in, so write it under `modelOverrides`, keyed by model id:
|
|
70
88
|
|
|
71
89
|
```yaml
|
|
72
90
|
llm-pi-ai:
|
|
@@ -81,6 +99,48 @@ Every list must name at least one modality except a model's own, where an empty
|
|
|
81
99
|
|
|
82
100
|
Both fields state a claim about your endpoint rather than checking it. A model that declares images its endpoint does not serve is not caught here; the provider rejects the request instead.
|
|
83
101
|
|
|
102
|
+
### Reasoning effort
|
|
103
|
+
|
|
104
|
+
The model picker offers an **Effort** menu for a model that declares reasoning levels. A built-in provider's models inherit their levels from the installed catalog. A model you enter by hand declares none, so the Effort entry does not appear in the menu and the endpoint's own default decides whether the model thinks. Declare the levels with `reasoningEfforts` in `$DSH_HOME/settings.yaml`:
|
|
105
|
+
|
|
106
|
+
```yaml
|
|
107
|
+
llm-pi-ai:
|
|
108
|
+
providers:
|
|
109
|
+
my-gateway:
|
|
110
|
+
apiKeyEnv: GATEWAY_API_KEY
|
|
111
|
+
api: openai-completions
|
|
112
|
+
baseURL: https://gateway.example/v1
|
|
113
|
+
reasoning: high
|
|
114
|
+
models:
|
|
115
|
+
- id: my-reasoner
|
|
116
|
+
reasoningEfforts:
|
|
117
|
+
off:
|
|
118
|
+
high: high
|
|
119
|
+
max: max
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Each key is a level the menu offers, and its value is the spelling sent on the wire as `reasoning_effort`, so `max: xhigh` renames a level for a gateway with its own vocabulary. Only `off` may stay empty, because for most endpoints not thinking is the parameter's absence. The route's `reasoning` is the level used while a session has picked none; choosing an effort in the picker saves it, with the model, as the default for new sessions.
|
|
123
|
+
|
|
124
|
+
An `off` left empty sends nothing, which only stops a model that thinks on request; an `off` given a value sends that value as `reasoning_effort` instead. A model that thinks unless told not to — DeepSeek V4 behind an OpenAI-compatible gateway, for example — needs `compat.thinkingFormat: deepseek`, which makes `off` send `thinking: {type: disabled}` and every other level send `thinking: {type: enabled}` beside the effort:
|
|
125
|
+
|
|
126
|
+
```yaml
|
|
127
|
+
models:
|
|
128
|
+
- id: deepseek-v4-pro
|
|
129
|
+
compat:
|
|
130
|
+
thinkingFormat: deepseek
|
|
131
|
+
reasoningEfforts:
|
|
132
|
+
off:
|
|
133
|
+
high: high
|
|
134
|
+
max: max
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
A built-in provider's model whose gateway does not reason loses its levels with `reasoningEfforts: false` under `modelOverrides`; selecting an effort for it is then refused as `UNSUPPORTED_REASONING_EFFORT`. DeepSeek's own route needs none of this: its models already offer `off`, `low`, `high`, and `max`, and `llm-deepseek.reasoningEffort` sets the default the picker starts from:
|
|
138
|
+
|
|
139
|
+
```yaml
|
|
140
|
+
llm-deepseek:
|
|
141
|
+
reasoningEffort: max
|
|
142
|
+
```
|
|
143
|
+
|
|
84
144
|
### Request compatibility
|
|
85
145
|
|
|
86
146
|
A gateway can hold a working key at a reachable address and still refuse every request. pi-ai decides the shape of a request — which role carries the system prompt, which field caps the output, how a thinking level travels — from the endpoint's URL, and an address it does not recognize is addressed as though it were OpenAI itself. Most OpenAI-compatible gateways refuse at least one thing OpenAI accepts.
|
|
@@ -117,23 +177,16 @@ Each switch belongs to the protocols that declare it, so a switch valid on one `
|
|
|
117
177
|
|
|
118
178
|
Every switch, its accepted values, and the protocols that take it are listed under `PiAiCompatProfile` in the [generated `dsh-llm-pi-ai` configuration reference](../reference/config-catalog.md#deepseek-aidsh-llm-pi-ai) — which is derived from the source, so it cannot fall behind what the adapter accepts.
|
|
119
179
|
|
|
120
|
-
## Select a model
|
|
121
|
-
|
|
122
|
-
Configured providers appear in the model picker. Selecting a model also makes it the default for new sessions. A session that has already sent a request retains the model recorded in its own log.
|
|
123
|
-
|
|
124
|
-
If a saved default names a provider that was deleted, the composer displays **Select model** and blocks input until another model is selected.
|
|
125
|
-
|
|
126
180
|
## Troubleshooting
|
|
127
181
|
|
|
128
182
|
- **`MISSING_CREDENTIAL`** — Store the provider key through the Models page or supply the referenced environment variable.
|
|
129
183
|
- **`UNKNOWN_MODEL`** — Select a configured model or add the missing model to the custom provider.
|
|
130
184
|
- **Fetching available models returns 401** — Check the key. Model discovery calls the OpenAI-compatible `GET /models` endpoint; enter models manually for endpoints that do not provide it.
|
|
185
|
+
- **Fetching available models reports neither a `data` array nor a `models` object** — The endpoint's listing is in a format discovery does not read. Enter the models by hand.
|
|
131
186
|
- **The gateway refuses every request although the key and URL are right** — Its request shape differs from OpenAI's. Start with `compat.supportsDeveloperRole: false` and `compat.maxTokensField: max_tokens` on the route.
|
|
132
187
|
- **Only reasoning models fail** — pi-ai sends their system prompt as the `developer` role, which the gateway rejects. Set `compat.supportsDeveloperRole: false`.
|
|
188
|
+
- **The Effort menu does not appear for a model you entered by hand** — It declares no levels. Add `reasoningEfforts` to the model in `settings.yaml`.
|
|
189
|
+
- **`off` does not stop a DeepSeek model from thinking** — An empty `off` sends no reasoning field at all, and an endpoint that thinks by default keeps thinking. Set `compat.thinkingFormat: deepseek` on the model or the route.
|
|
133
190
|
- **A compat switch is refused as having no value** — A key written with nothing after the colon. Give it a value, or remove the key to keep the installed catalog's.
|
|
134
|
-
- **An image is refused before sending** — The model declares no image modality. Give a custom provider's model `input: [text, image]`; DeepSeek's own
|
|
191
|
+
- **An image is refused before sending** — The model declares no image modality. Give a custom provider's model `input: [text, image]`; on DeepSeek's own route, select `deepseek-v4-flash-vision-exp`, the model that declares images.
|
|
135
192
|
- **The provider rejects a request carrying an image** — The model declares images its endpoint does not actually serve. Remove `image` from whichever list granted it — the model's `input`, or the route's `defaultInput` — then start a new session: the attached image stays in the session log, so the same request repeats until the session moves off it.
|
|
136
|
-
|
|
137
|
-
## Advanced configuration
|
|
138
|
-
|
|
139
|
-
The generated [plugin configuration catalog](../reference/config-catalog.md) lists every supported field and default for every plugin; [`dsh-llm-pi-ai`](../reference/config-catalog.md#deepseek-aidsh-llm-pi-ai) is the provider section this page configures. The [`dsh-llm-pi-ai`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/llm/llm-pi-ai/README.md) and [`dsh-llm-deepseek`](https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/llm/llm-deepseek/README.md) references own direct `settings.yaml` configuration, catalog resolution, reasoning controls, credentials, and adapter errors.
|