dsh-context-aware-search
Context-aware web search plugin for DeepSeek Harness (dsh): rewrites queries with session context, reranks + credibility-tags results, one-click source summarization across multiple backends. Fully decoupled from @deepseek-ai private packages for public CI.
- Stars
- 0
- Language
- TypeScript
- Created
- Aug 19, 2026
- Updated
- Aug 23, 2026
Introduction
dsh-context-aware-search: Web Search That Actually Understands What You're Working On
A DeepSeek Harness (dsh) plugin that turns the web_search seam from a
dumb keyword blast into a context-aware research assistant. It reads your
current session, rewrites the raw query with what you're actually doing,
reranksthe results by relevance to that context, tags every source with a
credibility level, and can boil the top hits down into a one-click Markdown
brief.
Same raw query, completely different — and far more useful — results when the plugin knows you're writing Rust instead of Go.
Why this exists
Generic web-search plugins return the global most-popular page for a keyword.
But when you search error handling while writing Rust, you don't want the
Wikipedia overview — you want doc.rust-lang.org and thiserror patterns.
dsh-context-aware-search closes that gap with four capabilities that ordinary
search plugins simply don't have:
- Context-aware query rewriting — the plugin reads your session's last N
messages and expands the raw query with the technologies, languages, and
libraries you're working with (e.g.
await 报错→Python asyncio await 常见错误 解决方案). - Result reranking — results are scored by TF-IDF similarity to the (rewritten) query plus your session context, so the most relevant source lands on top instead of whichever SEO won today.
- One-click source summarization — the model-callable
web_summarizetool fetches a URL (or the top-N search hits) and returns a structured Markdown brief: key points, key data, and source links. - Source credibility tags — every result is labeled
high/medium/lowby domain rules (.edu/.gov/ official docs = high, known media / registries = medium, personal blogs = low), so you can triage at a glance.
It works zero-config out of the box (DuckDuckGo HTML needs no API key) and fans out across up to three backends with automatic fallback.
Comparison
| Capability | dsh-context-aware-search | built-in web_search (dsh-web-tools) | dsh-web-search-deepseek | dsh-free-search¹ |
|---|---|---|---|---|
| Context-aware query rewriting | ✅ | ❌ | ❌ | ❌ |
| Result reranking by context | ✅ (TF-IDF) | ❌ | ❌ | ❌ |
| Source credibility tags | ✅ high/med/low | ❌ | ❌ | ❌ |
One-click web_summarize tool | ✅ | ❌ | ❌ | ❌ |
| Multiple backends + auto-fallback | ✅ DDG / Bing / SearXNG | provider-dependent | single (DeepSeek) | single |
| Zero-config (no API key) | ✅ (DuckDuckGo) | depends on provider | ❌ needs DEEPSEEK_API_KEY | ✅ |
| Settings Card (live config) | ✅ | n/a | ✅ | varies |
| DSH version pinned | ✅ 0.1.0-rc.6 | same runtime | same runtime | varies |
¹ dsh-free-search is a community no-key search plugin. The "❌" cells mark
capabilities that are, by definition, not part of a generic keyword search;
verify the upstream feature set before relying on this comparison.
Install
⚠️ Do NOT install
@latest. This plugin is built and type-checked against DeepSeek Harness0.1.0-rc.6. Thectx.webseam contract can change between releases; an unpinned or mismatched version can break search and fetch for your whole harness. Always pin the plugin version:dsh-context-aware-search@0.1.1
Method 1 — GitHub Release tarball (recommended, no build step)
- Download
dsh-context-aware-search-0.1.1.tgzfrom the Releases page. - Extract it into your dsh profile's plugin folder:
mkdir -p ~/.dsh/profiles/node_modules/dsh-context-aware-search tar -xzf dsh-context-aware-search-0.1.1.tgz -C ~/.dsh/profiles/node_modules/ --strip-components=1 - Add
dsh-context-aware-searchto your profile'sdsh.profile.bundlesarray. Its bundledcordis.patch.ymlre-pins thewebseam to the context-aware providers as the active backends. - Restart dsh.
Method 2 — From the DeepSeek npm registry (needs registry access)
The @deepseek-ai/* runtime packages live on the DeepSeek registry, not
public npmjs.com, so a plain npm install will not resolve the peer
dependencies. With registry access:
npm install dsh-context-aware-search@0.1.1 --registry <your-deepseek-registry>
then enable it in your dsh bundle as in Method 1, step 3–4.
Configuration
All settings are optional — the schema supplies the defaults below, and they can
be changed live from the Settings Card (ctx → settings).
| Key | Type | Default | Meaning |
|---|---|---|---|
rerank | boolean | true | Rerank results by TF-IDF similarity to query + context. |
credibility | boolean | true | Tag each result with a high/medium/low credibility badge. |
rewriteEnabled | boolean | true | Rewrite the raw query using session context. |
contextWindow | number | 8 | How many recent session messages to read for context. |
backendOrder | string[] | ['duckduckgo','bing','searxng'] | Backend priority for fallback. |
duckduckgoEnabled / bingEnabled / searxngEnabled | boolean | true | Per-backend on/off. |
searxngInstance | string | '' | Base URL of a SearXNG instance (empty = disabled). |
bingApiKey | string | '' | Optional Bing key (empty = keyless scrape fallback). |
maxResults | number | 10 | Max results returned per search. |
summarizeTopN | number | 5 | Links the web_summarize tool pulls when given a query. |
userAgent | string | dsh-context-aware-search/0.1.1 | UA sent on fetch. |
Usage
Just search as usual — the plugin does the rest.
Session:
User: I'm writing a Rust CLI; my main() returns Result<(), Box<dyn Error>>.
User: search error handling
What the plugin does:
- Reads the last
contextWindowmessages → detects Rust, cargo, Result. - Rewrites
error handling→Rust error handling Result Option unwrap ? best practices. - Runs the rewritten query across the backends (DuckDuckGo → Bing → SearXNG).
- Reranks by context similarity and tags credibility.
- Returns a banner + sources, e.g.:
🔎 Context-aware rewrite: Rust error handling Result Option unwrap ? best practices
| # | credibility | title | url |
|---|----|----|----|
| 1 | 🟢 high | Error Handling in Rust - The Rust Book | https://doc.rust-lang.org/book/ch09-00-error-handling.html |
| 2 | 🟢 high | Recoverable vs Unrecoverable Errors | https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html |
| 3 | 🟡 medium | thiserror / anyhow patterns | https://crates.io/crates/thiserror |
One-click brief — ask the model to summarize:
User: web_summarize query="Rust error handling best practices" topN=3
Returns a Markdown brief with key points, key data, and source links.
You can also summarize a specific page:
User: web_summarize url="https://doc.rust-lang.org/book/ch09-00-error-handling.html"
How it works
web_search(query)
│
├─ context.ts read last N session messages → plain-text context
├─ rewrite.ts expand query with context terms (TF-IDF keyword extraction)
├─ backends/* fan out to DuckDuckGo / Bing / SearXNG (priority + fallback)
├─ rerank.ts TF-IDF score of each result vs (query + context) → reorder
├─ credibility.ts domain rules → high / medium / low badge
└─ search-provider.ts assembles banner + pristine sources
web_summarize(url | query)
├─ fetch via ctx.web.fetch (context-aware-fetch provider)
├─ htmlextract.ts pure-TS extractor → title / headings / paragraphs / lists
└─ returns structured Markdown brief
No heavy NLP models, no external embedding service, no ctx.llm dependency —
just TypeScript and the platform fetch. Lightweight by design.
Known limitations
- No embedding model. Reranking uses TF-IDF over the query + context, not semantic vectors. It's fast and dependency-free but weaker on paraphrase / intent mismatch than an embedding model would be.
- Context text extraction is heuristic. It only reads
textcontent blocks from recent messages; images, tool outputs, and non-text blocks are ignored. - Search-result scraping is brittle. DuckDuckGo / Bing HTML parsing can
break if those sites change their markup; SearXNG JSON is more stable when
you point
searxngInstanceat a reliable instance. - Summaries are extractive, not abstractive.
web_summarizepulls and structures the page's own text; it does not generate a free-form prose summary (no LLM call by design). - Credibility is rule-based. It keys off domain suffixes / fragments; a high-value personal blog can be under-rated and a slick low-quality site over-rated. Treat badges as triage hints, not verdicts.
License
MIT © dsh-context-aware-search contributors.
Topics: dsh-plugin · deepseek-harness