Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ jobs:
- name: Test DSH package
run: make js-test

- name: Test built plugin in the real DSH runtime
run: make dsh-runtime-test

pi-package:
runs-on: ubuntu-latest
steps:
Expand Down
14 changes: 14 additions & 0 deletions .github/workflows/native-service.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,13 @@ jobs:
uv venv .native-venv
uv pip install --python .native-venv\Scripts\python.exe "powercontext[cli,server] @ $wheelUri" pytest

- name: Verify binary cursor persistence and restart compatibility
shell: pwsh
run: >-
.native-venv\Scripts\python.exe -m pytest -q
tests/test_cursor_secret.py
tests/test_server.py::test_server_reuses_file_backed_cursor_secret_across_restarts

- name: Exercise the real Task Scheduler lifecycle
shell: pwsh
run: >-
Expand All @@ -127,6 +134,13 @@ jobs:
if: failure()
shell: pwsh
run: |
Get-ChildItem -LiteralPath "$env:RUNNER_TEMP\powercontext-native-tests" -Recurse -File -ErrorAction SilentlyContinue |
Where-Object { $_.Name -in @('server.stdout.log', 'server.stderr.log') } |
ForEach-Object {
Write-Output "::group::$($_.FullName)"
Get-Content -LiteralPath $_.FullName -Tail 100
Write-Output "::endgroup::"
}
schtasks.exe /Query /TN "$env:POWERCONTEXT_NATIVE_SERVICE_IDENTIFIER" /XML /HRESULT
if ($LASTEXITCODE -ne 0) { exit 0 }
schtasks.exe /Query /TN "$env:POWERCONTEXT_NATIVE_SERVICE_IDENTIFIER" /FO LIST /V /HRESULT
Expand Down
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ js-test: ## Install, build, and test the DeepSeek Harness plugin.
@pnpm --dir integrations/dsh/plugins/powercontext test
@pnpm --dir integrations/dsh/plugins/powercontext test:e2e

.PHONY: dsh-runtime-test
dsh-runtime-test: ## Test the built plugin in the pinned real DSH runtime with a local model fixture.
@pnpm --dir integrations/dsh/plugins/powercontext/tests/runtime install --frozen-lockfile
@pnpm --dir integrations/dsh/plugins/powercontext test:e2e:runtime

.PHONY: openclaw-plugin-build
openclaw-plugin-build: ## Build the external OpenClaw memory plugin.
@pnpm --dir integrations/openclaw/plugins/memory-powercontext build
Expand Down
68 changes: 68 additions & 0 deletions docs/en/docs/how-to/configure-dsh.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,74 @@ workspace therefore uses the Server default instead of the Harness process direc

The plugin calls `POST /v1/context/prepare` once before the model analyzes the prompt. Explicit `remember_memory` calls do not require a model.

## Diagnose direct tool and command failures

Named tools and Scope-dependent `/pc` commands return a controlled failure if Scope resolution fails. They stop before
the requested operation, without creating a binding or retrying with another Scope. Cancellation and the existing
per-request timeout also apply to Scope resolution.

Inside DeepSeek Harness:

- `/pc doctor` checks liveness and readiness independently of Scope resolution and reports both results.
- `/pc capabilities` queries the Server capabilities without resolving a Scope.
- Unknown subcommands and missing arguments return local usage help without contacting the Server.
- Bare `/pc` shows the resolved Scope and Server origin. If resolution fails, it returns an error while still showing
`scope=unresolved`, a controlled error, and the `/pc doctor` recovery hint. Configured Scope IDs are not reported as
resolved. The displayed origin omits credentials, paths, query strings, and fragments.
- `search`, `remember`, `flush`, `review`, `skills scan`, and `stats` require a resolved Scope. `stats` queries that Scope.

| Result code | Meaning |
| --- | --- |
| `not_found` | A business 404. The optional `error_code` preserves a recognized public reason, such as `scope_not_found` or `memory_not_found`. |
| `version_mismatch` | A required endpoint returned 404 without a business code. Check the Server endpoint and plugin/Server compatibility; this does not establish a particular deployment cause. |
| `authentication_failed` | The Server returned 401. Check the configured Authorization header. |
| `unavailable` | Connection failure, timeout, cancellation, or HTTP 503. Native diagnostics use `server_unavailable`. |
| `unscoped` | The resolver completed without a Scope. |
| `invalid_response` | The client detected an invalid Server response. |

Existing conflict and validation codes, such as `revision_conflict` and `invalid_request`, retain their meaning. Failure
results preserve available HTTP status and request ID, but use fixed messages instead of Server-provided text. Unknown
error codes are omitted from `error_code` and diagnostics; their presence alone does not imply a version mismatch.

## Diagnose automatic recall and capture

Ordinary messages also trigger Scope resolution, context preparation, prompt capture, and optional flush. A failure
in these automatic stages leaves the Harness conversation running. Scope resolution failures stop all subsequent
PowerContext operations for that step; they never select a different Scope or create a binding.

The `powercontext.dsh` logger identifies the stage as `scope_resolve`, `context_prepare`,
`capture_content_source`, `flush_memory`, or `context_inject`. It reports fixed diagnostic outcomes and recognized
public error codes, without Server messages, prompt content, credentials, or request paths. Repeated identical
warnings are suppressed for 60 seconds. Logger failures cannot discard prepared context or interrupt the conversation.

Log visibility depends on the DSH profile's native exporters. The tested DSH 0.1.2-rc.1 Web profile does not export
these warnings to the terminal by default. A profile using Cordis's console exporter
(`@deepseek-ai/cordis-plugin-logger-console`) needs `config.levels.default: 2` to include warnings, or `3` for debug
events as well. Read the terminal running `dsh web` for `powercontext.dsh` records. This uses the host logger and adds
no model message or separate log panel.

A missing required route produces `version_mismatch` only when its 404 has no business code. A Scope business 404
instead records `invalid_response` with `error_code: scope_not_found`. A resolver that completes without a Scope
records `skipped` with `reason: scope_unresolved`. A valid empty recall is normal and logged at debug level.
Use `/pc doctor` and `/pc capabilities` to check the Server even when Scope resolution fails.

Preparation and capture are independent: a prepare failure can still allow capture, and a capture or flush failure
does not discard already prepared context. An accepted Source does not mean Memory has been generated; that requires
successful Server processing. Cancellation stops subsequent operations, while an individual request timeout retains
the existing per-request behavior.

## Inspect recalled context

A non-empty PreparedContext is appended once as a plugin message with `source.form=snapshot` and a `PowerContext`
section. In DSH 0.1.2-rc.1 Web, expand a completed turn's process details, then its **Context injection — powercontext-dsh**
row. Other host versions may expose this in a context browser. The section
contains the same text sent to the model and saved in the session log, including the untrusted-history label and
request-specific replacement wording. Reopening session history retains this metadata.

Empty responses and automatic failures do not create a snapshot or a model-visible error notice. Presentation uses
the host's existing snapshot support; it does not add a separate PowerContext panel or claim receipt/source details
that the Server has not returned.

## Control prompt capture

Prompt capture is enabled by default. Disable it before starting DeepSeek Harness when the current work must not be recorded:
Expand Down
61 changes: 61 additions & 0 deletions docs/zh/docs/how-to/configure-dsh.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,67 @@ Server 管理的 Scope。workspace 路径只会哈希为外部 binding key。缺

插件在模型分析提示词前只调用一次 `POST /v1/context/prepare`。显式 `remember_memory` 不需要模型。

## 排查工具和命令的直接调用失败

Scope 解析失败时,具名工具和依赖 Scope 的 `/pc` 命令会返回受控失败,并在执行请求的操作前停止。
插件不会因此创建 binding 或换用其他 Scope 重试。取消信号和现有的单请求超时也适用于 Scope 解析。

在 DeepSeek Harness 内:

- `/pc doctor` 不依赖 Scope 解析,继续检查 liveness 和 readiness,并保留两个检查结果。
- `/pc capabilities` 直接查询 Server 能力,无需解析 Scope。
- 未知子命令或缺少参数时,在本地返回用法说明,不访问 Server。
- 裸 `/pc` 显示已解析的 Scope 和 Server origin。解析失败时返回错误,但仍显示 `scope=unresolved`、受控错误信息
和 `/pc doctor` 恢复提示。配置中的 Scope ID 不会被当作已解析成功;显示的 origin 不包含凭据、路径、查询参数和 fragment。
- `search`、`remember`、`flush`、`review`、`skills scan` 和 `stats` 必须成功解析 Scope;`stats` 仅查询当前 Scope。

| 结果 code | 含义 |
| --- | --- |
| `not_found` | 业务 404。可选的 `error_code` 保留已识别的公开原因,例如 `scope_not_found` 或 `memory_not_found`。 |
| `version_mismatch` | 必需端点返回了没有业务码的 404。应检查 Server 端点和插件、Server 的兼容性;该结果不能证明具体的部署原因。 |
| `authentication_failed` | Server 返回 401,应检查 Authorization 配置。 |
| `unavailable` | 连接失败、超时、取消或 HTTP 503。原生诊断使用 `server_unavailable`。 |
| `unscoped` | resolver 执行完成,但没有返回 Scope。 |
| `invalid_response` | 客户端识别到无效的 Server 响应。 |

已有冲突和校验错误码(如 `revision_conflict`、`invalid_request`)保持原有含义。失败结果保留可用的 HTTP status 和
request ID,提示文字使用固定内容,不透传 Server message。未知错误码不会出现在 `error_code` 或诊断中,
也不会仅因无法识别就被判为版本不匹配。

## 排查自动召回和采集

普通消息也会触发 Scope 解析、上下文准备、提示词采集和可选 flush。这些自动阶段失败时,Harness 对话继续。
Scope 解析失败会停止本轮后续的 PowerContext 操作,不会换用其他 Scope 或创建 binding。

`powercontext.dsh` 日志通过 `scope_resolve`、`context_prepare`、`capture_content_source`、`flush_memory`
或 `context_inject` 标识失败阶段。诊断使用固定结果和已识别的公开错误码,不包含 Server message、
提示词内容、凭据或请求路径。同类重复警告在 60 秒内降噪。logger 自身失败也不会丢弃已准备的上下文或打断对话。

能否看到日志取决于 DSH profile 的原生 exporter 配置。本次测试的 DSH 0.1.2-rc.1 Web profile 默认不向终端
导出这些警告。如果 profile 使用 Cordis 的 console exporter(`@deepseek-ai/cordis-plugin-logger-console`),
需要将其 `config.levels.default` 设为 `2` 以包含警告;设为 `3` 可同时查看 debug 事件。
在启动 `dsh web` 的终端中查看 `powercontext.dsh` 记录。这里使用宿主 logger,不增加模型消息或独立日志面板。

必需路由的 404 只有在没有业务错误码时才记录为 `version_mismatch`。Scope 的业务 404 则记录
`invalid_response` 和 `error_code: scope_not_found`。resolver 正常结束但未返回 Scope 时记录
`skipped` 和 `reason: scope_unresolved`。有效的空召回属于正常结果,只写 debug 日志。
Scope 解析失败时,仍可使用 `/pc doctor` 和 `/pc capabilities` 检查 Server。

上下文准备和采集相互独立:prepare 失败后仍可采集输入;capture 或 flush 失败不会丢弃已经准备好的上下文。
Source 被接收不代表已经生成 Memory,后者需要 Server 成功处理。取消会停止后续操作;单个请求超时仍沿用
现有的单请求行为。

## 查看召回的上下文

非空 PreparedContext 只追加一次,消息带有 `source.form=snapshot` 和名为 `PowerContext` 的 section。
在 DSH 0.1.2-rc.1 Web 中,展开已完成轮次的“已思考”过程内容,再展开“上下文注入 — powercontext-dsh”。
其他宿主版本也可能将它展示在上下文浏览器中。section 与发给模型、
保存到会话日志的文字一致,包含不可信历史证据的提示,以及当前请求替换此前快照的说明。
重新打开会话历史时,这些元数据仍然保留。

空结果和自动失败不会生成 snapshot,也不会向模型注入错误通知。展示使用宿主已有的 snapshot 能力,
不新增 PowerContext 面板,也不声称存在 Server 尚未返回的 receipt 或来源信息。

## 控制提示词采集

默认开启提示词采集。如果当前工作不应被记录,请在启动 DeepSeek Harness 前关闭:
Expand Down
11 changes: 11 additions & 0 deletions integrations/dsh/plugins/powercontext/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,14 @@ The plugin resolves an explicit Scope, a durable workspace binding, or the Serve
the `POWERCONTEXT_DSH_` prefix for `BASE_URL`, `AUTHORIZATION`, `SCOPE_ID`, `CAPTURE_PROMPTS`, and `FLUSH_ON_CAPTURE`.
`timeoutMs`, `requestTimeoutMs`, `maxBytes`, and `flushMaxCalls` are plugin patch settings. Context returned by recall
is labelled as untrusted history. An unavailable Server never blocks normal Harness work.

Automatic failures are reported through the native `powercontext.dsh` logger with a stage, a safe outcome, and an
optional public error code. They do not become model messages. Scope failure stops that step's PowerContext work;
prepare and capture otherwise fail independently. Cancellation prevents subsequent operations, and logger failures
cannot discard a successful recall. Accepted Source evidence still needs Server processing before it becomes Memory.

Non-empty recall uses a persisted plugin `snapshot` with a `PowerContext` section for the host context browser.
Its displayed text is the same untrusted, request-specific context sent to the model. Empty recall creates no snapshot.

See [runtime acceptance tests](tests/runtime/README.md) for the pinned real DSH host, deterministic CI scenarios,
and the separate real-model and Web acceptance procedure.
Loading
Loading