Skip to content

feat(recall): recallMulti() for multi-query recall + pluggable taskQueryBuilder - #101

Open
evilh2019 wants to merge 1 commit into
adoresever:mainfrom
evilh2019:feat/recall-multi-query
Open

feat(recall): recallMulti() for multi-query recall + pluggable taskQueryBuilder#101
evilh2019 wants to merge 1 commit into
adoresever:mainfrom
evilh2019:feat/recall-multi-query

Conversation

@evilh2019

Copy link
Copy Markdown

Summary

Adds two new capabilities to improve recall quality:

1. recallMulti(queries, options) — multi-query recall

The Recaller class now supports running multiple independent queries in parallel and merging the results. This is a natural generalization of the existing single-query recall() — each query runs its own precise + generalized path internally, and results are merged with dedup via the new mergeMany() static method.

API added:

  • recaller.recallMulti(queries: string[], options?) — parallel multi-query recall
  • Recaller.merge(a, b) — merge two results (static, was previously private mergeResults)
  • Recaller.mergeMany(results[]) — merge any number of results

2. Pluggable taskQueryBuilder — configurable query construction

The DSH integration now captures skill-catalog events (user/message with source.kind === "skill-catalog") and passes them to a configurable taskQueryBuilder that can produce additional recall queries from skill descriptions relevant to the current user message.

Default builder: bigramRelevanceFilter

  • Only includes skills whose name or description has a 2-char overlap with the user message
  • Excludes lark-* infrastructure skills
  • Caps at 500 characters total
  • Returns undefined when no skills match (no additional queries)

Config:

taskQueryBuilder?: (
  userQuery: string,
  skills: Array<{ name: string; description: string }>,
) => string[] | undefined;

Custom builders can use embedding similarity, keyword expansion, or LLM-based skill selection — the interface is intentionally minimal and host-agnostic.

Motivation

Single-query recall only searches the user message ("what is the user talking about"), which misses procedural knowledge ("how to do the task"). For example, when a user says "send a task to mama1", the user query finds workflow nodes like dispatch-task-to-mama1-correctly but misses mama1-executor-json-command-send (JSON format requirement that previously caused rejected tasks). The task-oriented query from relevant skill descriptions fills this gap.

Testing

  • 148 existing tests pass (1 pre-existing failure in pro-dsh.test.ts due to missing @deepseek-ai/dsh-typert-protocol dependency, unrelated)
  • Verified in production with 5 scenarios: KB quality review, A2A dispatch, web restart, plugin development, and code review — dual-recall finds complementary nodes in all cases

Files changed

File Change
src/recaller/recall.ts +recallMulti(), +static merge(), +static mergeMany(), extract mergeResultsImpl
dsh.ts +skillEntries capture, +taskQueryBuilder config, +bigramRelevanceFilter default, dual-recall in system-prompt/assemble
dist/ Compiled JS output

… query builder

- Recaller: add recallMulti(queries, options) that runs each query in
  parallel and merges results via mergeMany().  Extract static merge()
  from private mergeResults() so callers can merge externally.

- dsh.ts: capture skill-catalog events and build task-oriented recall
  queries from skills relevant to the current user message.  The query
  builder is configurable via taskQueryBuilder; the default is a
  bigram-overlap relevance filter that excludes lark-* infrastructure
  skills and caps at 500 characters.

Multi-query recall lets the host augment the primary user-message
query with task-domain queries (e.g. skill descriptions), improving
recall of procedural knowledge that the user message alone would miss.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants