Skip to content

fix(dsh-plugin): pass recallExcludeUris so subtrees can be excluded from recall - #5312

Merged
ZaynJarvis merged 1 commit into
volcengine:mainfrom
ydflow:fix/dsh-plugin-exclude-uris
Sep 23, 2026
Merged

ZaynJarvis merged 1 commit into
volcengine:mainfrom
ydflow:fix/dsh-plugin-exclude-uris

Conversation

@ydflow

@ydflow ydflow commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Description

recall-core.mjs reads options.excludeUris and forwards it as the search request's exclude_uris, but the DSH runtime built its recall options without that key, so nothing a user configured could stop a subtree from being recalled.

The generated per-directory context files (viking://user/<space>/skills, viking://user/<space>/resources, viking://agent/skills) are returned as ordinary hits and carry only boilerplate text. On a vague prompt, 3 of 7 returned entries were these directory files. The only current remedy is deleting the data.

Before: excludeUris appears 0 times in examples/dsh-memory-plugin/runtime.mjs; the search request body never carries exclude_uris.
After: a recallExcludeUris list knob reaches the request as exclude_uris, and the field is omitted entirely when the knob is unset.

Human Involvement

  • A human participated in the implementation or review loop
  • This PR was generated entirely by AI agents without human participation in the loop

Related Issue

Addresses the first of the three defects in #5206 (excludeUris is implemented but never passed by the DSH plugin). The other two defects in that issue — recallLimit below the category count widening the search, and recallTokenBudget / recallMaxContentChars only affecting the fallback path — are separate changes and are deliberately left out so this stays one coherent fix.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (bug fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (no functional changes)
  • Performance improvement
  • Test update

Changes Made

  • examples/memory-plugin-shared/lib/config-schema.mjs: add recallExcludeUris (type: "list", default [], OPENVIKING_RECALL_EXCLUDE_URIS, capability: "recall"), following the existing recallQueryFilters precedent for list-valued recall knobs.
  • examples/dsh-memory-plugin/runtime.mjs: pass excludeUris: state.config.recallExcludeUris in the options object built for buildRecallBlock. This is the single place that builds those options.
  • The two vendored shared/config-schema.mjs copies under examples/claude-code-memory-plugin and examples/codex-memory-plugin are regenerated by examples/memory-plugin-shared/sync.mjs. Both targets are declared committed: true there because a host installs those plugins from a directory in this repository, so their copies belong in git; examples/dsh-memory-plugin/shared/ is committed: false and gitignored, so it is not part of the diff.

No server, SDK, persisted-data, or public API change. recall-core.mjs already caps the forwarded list at 200 entries and omits exclude_uris when the list is empty, so the default request body is byte-identical to before.

Testing

Validation run on Windows / Node.js v24.18.0, from examples/dsh-memory-plugin after node ../memory-plugin-shared/sync.mjs and npm install:

  • node --test *.test.mjs: 77 tests, 76 passed, 0 failed, 1 skipped. Baseline before this change was 75 tests / 74 passed / 1 skipped, so the two new cases are the only delta.
  • The new recallExcludeUris reaches the search request failed before the source change with exclude_uris reported as undefined in the captured request body, and passes after it. The companion case asserts no exclude_uris field is sent when the knob is unset, so the default path is pinned as well.
  • node --check passes on runtime.mjs, runtime.test.mjs, and config-schema.mjs.

Pre-existing failures, verified not to be caused by this change: examples/claude-code-memory-plugin fails 6 tests in scripts/auto-capture.test.mjs on this machine. Those tests spawn a real subprocess that talks to a mock server on 127.0.0.1. They fail identically with this change stashed and against a pristine checkout, so they are environmental (Windows subprocess/loopback) rather than related to this diff, which only adds a schema entry that those tests do not read.

No live server, live model, or packaged-plugin (npm pack) run was performed; the recall path was exercised against the plugin's own mock transport.

Checklist

  • My code follows the project's coding style
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-under-from-a-diff areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

Additional Notes

Documentation is unchanged: recallExcludeUris is a new optional knob with a safe empty default, and the DSH README does not currently enumerate recall knobs individually, so there is no existing statement to correct. If maintainers would like the knob documented alongside the other recall* settings, say so and I will add it in both languages.

One design note for review: I scoped this to the DSH plugin only, matching the issue's report. excludeUris is read by shared recall-core.mjs, so the same gap exists for any other host that builds recall options without the key — but no other plugin in this repository currently reads a recallExcludeUris config value, so wiring only DSH keeps the change minimal rather than speculative.

…rom recall

`recall-core.mjs` reads `options.excludeUris` and forwards it as the search
request's `exclude_uris`, but the DSH runtime built its recall options without
that key, so no configuration could stop a subtree from being recalled. The
generated per-directory context files (`viking://user/<space>/skills`,
`viking://user/<space>/resources`, `viking://agent/skills`) came back as ordinary
hits and carry only boilerplate text — on a vague prompt, 3 of 7 returned entries
were these files. The only remedy was deleting the data.

Add a `recallExcludeUris` list knob to the shared config schema and pass
`cfg.recallExcludeUris` through as `excludeUris` from the DSH recall call, which
is the single place that builds those options. The schema entry lands in
`memory-plugin-shared/lib` and is propagated to the claude-code and codex copies
by `sync.mjs`; those two plugins are marked `committed: true` there because a
host installs them from a directory in this repository, so their vendored copies
belong in git. `recall-core.mjs` already caps the forwarded list at 200 entries
and omits the field entirely when the list is empty, so the default behaviour and
the request body are unchanged.

Validation, from `examples/dsh-memory-plugin` after
`node ../memory-plugin-shared/sync.mjs` and `npm install`:
`node --test *.test.mjs` 77 tests, 76 passed, 0 failed, 1 skipped. The new
`recallExcludeUris reaches the search request` failed before the change with
`exclude_uris` undefined in the request body and passes after it; the companion
case asserts no `exclude_uris` field is sent when the knob is unset.
`node --check` passes on all three changed source files.

`examples/claude-code-memory-plugin` fails 6 tests in
`scripts/auto-capture.test.mjs` on this Windows machine. Those tests spawn a real
subprocess that talks to a mock server on 127.0.0.1; they fail identically with
this change stashed and with a pristine checkout, so they are pre-existing and
environmental rather than caused by this change.
@ZaynJarvis ZaynJarvis added the agent-plugins Agent harness and plugin integrations label Sep 23, 2026
@ZaynJarvis
ZaynJarvis merged commit de1c5c4 into volcengine:main Sep 23, 2026
@github-project-automation github-project-automation Bot moved this from Backlog to Done in OpenViking project Sep 23, 2026
qin-ctx pushed a commit that referenced this pull request Sep 28, 2026
* fix(pi): honor recallExcludeUris and recallQueryFilters

Both knobs are declared in the shared config schema, and the Claude Code,
Codex and DSH plugins apply them, but the pi extension's RecallManager never
read either one:

- `recallExcludeUris` was not passed as `excludeUris`, so `exclude_uris`
  never reached the context search and no configuration could keep a URI
  out of pi's recall (the DSH half of this was fixed in #5312).
- `recallQueryFilters` was never compiled or applied, so pi searched with
  the raw prompt even when the operator configured rules to drop or strip
  it (acknowledgements, option picks, prefixes).

Apply the filters before the length gate, as auto-recall.mjs does, and
forward the exclude list to buildRecallBlock. Document both knobs in the
pi README.

* chore(pi): bump version to 0.4.6
chaucerj added a commit to chaucerj/OpenViking that referenced this pull request Sep 29, 2026
The recallExcludeUris wiring changes entry scripts in both plugins;
the plugin-versions gate requires changed plugins to move their
version string (same as the DSH volcengine#5312 and pi volcengine#5368 precedents).

Co-Authored-By: Claude Code <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent-plugins Agent harness and plugin integrations

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants