Polyweave

@polyweave/sleuth (1.0.6)

Published 2026-07-11 15:32:37 +00:00 by Dvorak

Installation

@polyweave:registry=https://hub.kl1.tenere.ai/api/packages/Polyweave/npm/
npm install @polyweave/sleuth@1.0.6
"@polyweave/sleuth": "1.0.6"

About this package

@polyweave/sleuth

SLEUTH retrieval pipeline as a bt-harness tool.

Synopsis

import { createSleuthTool } from '@polyweave/sleuth';

const tool = createSleuthTool({
  apiKey: process.env.API_KEY,
  model: 'deepseek-v4-flash',
  dataset: [
    'What is the capital of France?',
    { query: 'Explain quantum computing' }
  ],
  retriever: myRetrieverAdapter,
  clueDiscovery: myClueAdapter,
  pageScreen: myScreenAdapter,
  difficultyAssess: myAssessAdapter,
  reasoner: myReasonerAdapter,
  topK: 5
});

tool.sink.write({ type: 'TOOL_CALL', content: {} });
tool.source.pipe(createFrameSink((frame) => {
  if (frame.type === 'TOOL_RESULT') console.log('Results:', frame.content.results);
  if (frame.type === 'ERROR') console.error(frame.content.message);
}));

Install

npm install @polyweave/sleuth

Why

SLEUTH is a 5-stage retrieval pipeline implemented as a bt-harness duplex tool. It processes batches of queries through sequential stages — retrieve, clue discovery, page screening, difficulty assessment, reasoning — each powered by pluggable adapters (duplex or callback). It supports optional feedback-descent answer refinement (LLM-driven iterative improvement), multi-state store integration for structured entity storage, and tick-driven advancement for stepwise execution. Use it for batched research QA, structured retrieval, and agent-driven search over document stores.

API

createSleuthTool(options)

Creates a SLEUTH retrieval pipeline tool.

createSleuthTool(options: object) → { source, sink, _toolName, getResults, close }

Parameters

Name Type Required Default Description
options.apiKey string Yes API key for LLM calls
options.model string No 'deepseek-v4-flash' Model name used for agent and evaluator
options.dataset string[] | { query, question }[] No [] Array of query items; strings are treated as query
options.retriever duplex | callback No Adapter for candidate page retrieval; receives { query, pages, topK }
options.clueDiscovery duplex | callback No Adapter for extracting clues from candidate pages; receives { query, page, index }
options.pageScreen duplex | callback No Adapter for screening/relevance filtering of pages; receives { query, page, index }
options.difficultyAssess duplex | callback No Adapter for assessing query difficulty and generating reasoning instructions; receives { query, context }
options.reasoner duplex | callback No Adapter for final reasoning and answer generation; receives { query, context, difficulty, instructions }
options.topK number No 5 Number of candidate pages to retrieve per query
options.state multi-state store | object No Multi-state store for structured entity storage (SleuthCandidate, SleuthEvidence, SleuthAnswer), or { docStore, textStore } for simple document storage
options.refineAnswer object No Feedback descent refinement config: { enabled: boolean, iterations: number, patience: number }
options.createAdapter function No Custom adapter factory forwarded to the inner bt-harness
options.adapterConfig object No Adapter factory configuration forwarded to the inner bt-harness
options.debug boolean No false Enable debug output on the inner bt-harness

Return Value

Returns an object:

Property Type Description
source push-stream source Subscribe with source.pipe(sink); emits TOOL_RESULT, ERROR, DESCRIPTION frames
sink push-stream sink Accepts TOOL_CALL, TICK, CANCEL, ABORT, DESCRIBE frames
_toolName string Always 'sleuth'
getResults() function → array Returns accumulated results array (parsed from doc store)
close() function Closes the internal document store

Frame Protocol

Input frames (write to sink)
Frame Type Content Description
TOOL_CALL { dataset } Start pipeline execution; dataset overrides options.dataset
TICK Advance one step in the current bt-harness (for tick-driven execution)
CANCEL Cancel the current harness and the active refine harness
ABORT Abort the current harness
DESCRIBE { streamId } Request a description frame
Output frames (read from source)
Frame Type Content Description
TOOL_RESULT { results, itemCount, itemsProcessed, failed } Pipeline completed; results is an array of { answer, result } per item
ERROR { message } Pipeline error or harness validation failure
DESCRIPTION { name, description, capabilities, schema } Response to DESCRIBE

Internal Tools (available to agents during pipeline execution)

Tool Name Args Description
sleuth_read { sectionId } Read any document section from the internal doc store
sleuth_retrieve { query, pages } Retrieve candidate pages using the retriever adapter
sleuth_clue { query, page, index } Extract clues from a candidate page using the clueDiscovery adapter
sleuth_screen { query, page, index } Screen a page for relevance using the pageScreen adapter
sleuth_assess { query } Assess difficulty using the difficultyAssess adapter
sleuth_reason { query, answer } Reason and produce an answer; pass answer to store directly without invoking reasoner
sleuth_search { query, limit } Full-text search across indexed documents (only available when textStore is configured)
sleuth_query { query | dsl } or query DSL Structured query against multi-state store (only available with state multi-state store)
sleuth_multi_search { query, limit } Unified multi-store search (only available with state multi-state store)

Error Conditions

  • TOOL_CALL while already running: emits ERROR frame with message: 'Already running'
  • Invalid harness (parse failure, missing tools): emits ERROR frame with harness error messages
  • Adapter callback error: returns { error } in tool result with the error message string
  • reasoner not provided during sleuth_reason: returns { error: 'No reasoner provided' }
  • Multi-state store not configured during sleuth_query: returns { results: [], note: 'Multi-state store not configured...' }
  • Multi-state store not configured during sleuth_multi_search: returns { results: [], note: '...' }
  • Refinement harness invalid: silently falls back to base answer

Pipeline Stages (5-stage sequential BT)

The behavior tree spec defines sequential execution:

  1. retrieve — Read current item, call sleuth_retrieve(query)
  2. clue_discovery — For each candidate, call sleuth_clue
  3. page_screen — Screen each page via sleuth_screen(label), retain pages marked R or CR
  4. difficulty_assess — Assess difficulty, generate instructions via sleuth_assess
  5. reason — Produce final answer via sleuth_reason(answer), increment @itemIndex

The pipeline processes all items sequentially. When @itemIndex reaches itemCount, the harness sets @complete = true and emits TOOL_RESULT.

Feedback Descent Refinement

When options.refineAnswer.enabled is true, after the reasoner produces a base answer, a nested bt-harness runs an iterative refinement loop:

  • propose — agent reads best answer + evidence, generates improved candidate
  • evaluate — evaluator compares candidate vs best against evidence, sets @preferred
  • promote_best — if preferred, the candidate becomes the new best
  • increment_stagnant — if not preferred, increment stagnation counter

The loop stops when @iteration >= iterations or @stagnant >= patience. The best answer is returned.

Tests

npm test

Covers: tool creation with all adapter combinations, 5-stage pipeline execution, candidate retrieval and evidence collection, page screening with label filtering, difficulty assessment, reasoning with and without answer refinement, multi-state entity storage and querying, tick-driven advancement, CANCEL/ABORT handling.

Requirements

  • Node.js 22+
  • ESM only

Dependencies: @polyweave/core, @polyweave/bt-harness, @polyweave/state, @polyweave/tools, @polyweave/loop-utils

Dependencies

Dependencies

ID Version
@polyweave/bt-harness *
@polyweave/core *
@polyweave/loop-utils *

Development Dependencies

ID Version
@rigor/core *

Keywords

polyweave sleuth retrieval behavior-tree
Details
npm
2026-07-11 15:32:37 +00:00
16
John Dvorak
SEE LICENSE IN LICENSE
latest
10 KiB
Assets (1)
Versions (4) View all
1.0.6 2026-07-11
1.0.3 2026-07-11
1.0.2 2026-07-10
1.0.1 2026-07-10