@polyweave/patterns (1.0.7)
Installation
@polyweave:registry=https://hub.kl1.tenere.ai/api/packages/Polyweave/npm/npm install @polyweave/patterns@1.0.7"@polyweave/patterns": "1.0.7"About this package
@polyweave/patterns
Reusable prompting patterns and LLM-backed tools for agent workflows. Provides ranking, pairwise comparison, confidence elicitation, and prompt repetition as dependency-injected frame-duplex tools that plug into any Polyweave harness.
Synopsis
import {
createRankingPattern,
createPairwisePattern,
createConfidenceProbePattern,
createRepeatTwiceTemplateNode
} from '@polyweave/patterns';
const ranker = createRankingPattern(llmAdapter, {
criterion: 'Which implementation is more correct?',
idStrategy: 'numeric'
});
ranker.sink.write({ type: 'TOOL_CALL', content: {
name: 'patterns.rank',
arguments: {
items: [
{ id: 'a1', text: 'function add(a,b){return a+b}' },
{ id: 'b2', text: 'const add = (a, b) => a + b' }
],
criterion: 'Code quality and readability'
}
}});
ranker.source.pipe(someSink);
Install
npm install @polyweave/patterns
Why
LLM-based agent workflows repeatedly need the same judgment patterns: ranking N items, comparing two items pairwise, estimating confidence in generated answers, and repeating prompt content for reliability. The patterns package provides these as composable, dependency-injected tools — each takes an LLM adapter (any { source, sink } duplex) and returns a frame-protocol-conformant tool that plugs into any harness. Pattern tools accumulate responses via the adapter's source stream and emit TOOL_RESULT frames with structured parsed output.
API
createRankingPattern(adapter [, options])
Creates a ranking judge frame-duplex tool. Sends a prompt listing items with generated IDs, parses the ordered-ID response, and returns ranked items with positions.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
adapter |
IFrameDuplex |
Yes | — | LLM adapter with source and sink |
options.toolName |
string |
No | 'patterns.rank' |
Tool name matched in TOOL_CALL |
options.idStrategy |
string |
No | 'numeric' |
ID generation strategy: 'numeric' | 'alphabetic' | 'chinese' |
options.itemTemplate |
string |
No | 'ID ${id}: ${text}' |
Template for formatting each item |
options.promptTemplate |
string |
No | Ranking prompt template | Full prompt template with ${criteriaBlock}, ${contextBlock}, ${itemsText} |
options.outputTemplate |
string |
No | Output instruction template | Format instructions appended to prompt |
options.repeatTwice |
boolean |
No | false |
If true, wraps prompt in repeat-twice template node |
options.repeatCount |
number |
No | 2 |
Repetition count when repeatTwice is enabled |
options.separator |
string |
No | '\n\n' |
Separator between repetition blocks |
options.includeDisclaimer |
boolean |
No | true |
Whether to include disclaimer text in repeats |
options.disclaimerTemplate |
string |
No | default disclaimer | Disclaimer text override |
options.idPool |
string[] |
No | [] |
Required for 'chinese' strategy — pool of ID strings |
TOOL_CALL args: { items: [{ id?, text }], criterion?, context? }
TOOL_RESULT content: { rankedItems: [{ id, index, rank, item }], orderedIds: string[], idMap: [{ id, index }] }
ID strategies and parsing:
'numeric': IDs are"1","2","3"… Parsed by extracting all\d+matches from LLM response, mapping back to integers.'alphabetic': IDs are"A","B","C"…"AA","AB"… Parsed by extracting uppercase\b[A-Z]{1,3}\bboundaries.'chinese': Requiresoptions.idPoolwith enough entries. Parsed by splitting response on whitespace/commas/semicolons/pipes/slashes.
Error conditions:
adaptermissingsinkorsource→ throwsError('createRankingPattern requires an adapter duplex.')- TOOL_CALL name mismatch → responds with
{ error: 'Tool "<name>" not handled by ranking pattern' } - Empty items array → responds with
{ error: 'Ranking pattern requires items array' } idPooltoo small for'chinese'strategy → responds with{ error: 'Chinese idStrategy requires idPool with enough entries.' }- Unknown
idStrategy→ responds with error message - LLM emits ERROR frame → responds with error from frame message
- Parse failure on LLM response → responds with
{ error: 'Failed to parse ranking' }
createPairwisePattern(adapter [, options])
Creates a pairwise comparison frame-duplex tool. Presents LEFT vs RIGHT to the LLM, parses XML decision output.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
adapter |
IFrameDuplex |
Yes | — | LLM adapter with source and sink |
options.toolName |
string |
No | 'patterns.pairwise' |
Tool name matched in TOOL_CALL |
options.promptTemplate |
string |
No | Pairwise prompt template | Full prompt template with ${criterionBlock}, ${contextBlock}, ${left}, ${right} |
options.outputTemplate |
string |
No | Output XML template | XML output instructions appended to prompt |
options.repeatTwice |
boolean |
No | false |
If true, wraps prompt in repeat-twice template node |
options.repeatCount |
number |
No | 2 |
Repetition count |
options.separator |
string |
No | '\n\n' |
Separator between repetition blocks |
options.includeDisclaimer |
boolean |
No | true |
Whether to include disclaimer text |
options.disclaimerTemplate |
string |
No | default disclaimer | Disclaimer text override |
TOOL_CALL args: { left: string, right: string, criterion?: string, context?: string }
TOOL_RESULT content: { winner: 'left' | 'right' | 'tie', intensity: number (1–9), rationale: string }
XML parsing: Expects <winner>LEFT|RIGHT|TIE</winner>, <intensity>1-9</intensity>, <rationale>text</rationale>. Winner is lowercased. Intensity defaults to 1 if not a finite positive number.
Error conditions:
adaptermissingsinkorsource→ throwsError('createPairwisePattern requires an adapter duplex.')- Missing
leftorright→ responds with{ error: 'Pairwise pattern requires left and right inputs' } - LLM emits ERROR frame → responds with error from frame message
- Parse failure → responds with
{ error: 'Failed to parse pairwise response' }
createConfidenceProbePattern(adapter [, options])
Creates a confidence elicitation frame-duplex tool. Supports three modes: p_true (probability the answer is correct given a forced-answer setup), p_sufficient (probability the given information is sufficient), and verbal (verbal confidence mapping to numeric).
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
adapter |
IFrameDuplex |
Yes | — | LLM adapter with source and sink |
options.toolName |
string |
No | 'patterns.confidence' |
Tool name matched in TOOL_CALL |
options.mode |
string |
No | 'ptrue' |
Default mode: 'ptrue' | 'psufficient' | 'verbal' |
options.ptrueTemplate |
string |
No | @polyweave/uncertainty default |
Template override for p_true prompt |
options.psufficientTemplate |
string |
No | @polyweave/uncertainty default |
Template override for p_sufficient prompt |
options.verbalTemplate |
string |
No | @polyweave/uncertainty default |
Template override for verbal confidence prompt |
TOOL_CALL args: { question: string (required), answer: string (required), mode?: 'ptrue'|'psufficient'|'verbal', context?: string, promptText?: string (overrides auto-generated prompt), ptrueTemplate?, psufficientTemplate?, verbalTemplate?, choice?: string, other?: string }
TOOL_RESULT content: { mode: string, confidence: number | null, choice: 'A' | 'B' | null, text: string }
Mode behavior:
'ptrue'/'psufficient': Uses@polyweave/uncertaintyto build a binary-choice prompt. Confidence is extracted from logprobs (extractBinaryChoiceConfidence) or falls back to text parsing.choiceis parsed from A/B in response text.'verbal': Builds a verbal confidence prompt. Confidence is normalized vianormalizeVerbalConfidencefrom the first number in the response text.
Error conditions:
adaptermissingsinkorsource→ throwsError('createConfidenceProbePattern requires an adapter duplex.')- Missing
questionoranswer→ responds with{ error: 'Confidence pattern requires question and answer' } - LLM emits ERROR frame → responds with error from frame message
createConfidenceToolRouter(adapter [, options])
Creates an async tool router wrapping the confidence tool. Uses createAsyncToolRouter from @polyweave/tools for integration with tool-routing harnesses. Same options as createConfidenceProbePattern, plus options.tools for extending with additional tool handlers.
Return value: An async tool router duplex from createAsyncToolRouter.
createRepeatTwiceTemplateNode(options)
Creates a @polyweave/smart-templates composite template node that repeats core content N times.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
options.coreTemplate |
TemplateNode|string |
Yes | — | The template to repeat (passed to createTemplateNode if string) |
options.endTemplate |
TemplateNode|string |
Yes | — | Template appended after repetitions (passed to createTemplateNode if string) |
options.repeatCount |
number |
No | 2 |
Number of repetitions (clamped to >= 1) |
options.separator |
string |
No | '\n\n' |
Separator between template nodes |
options.includeDisclaimer |
boolean |
No | true |
Whether to prepend disclaimer text |
options.disclaimerTemplate |
string |
No | 'I will repeat the instructions and content twice for clarity. Follow the output format exactly.' |
Disclaimer text (used as template if includeDisclaimer is true) |
Return value: A composite TemplateNode from composeTemplateNodes.
Structure: [disclaimer? (1 node), coreTemplate (repeatCount nodes), endTemplate (1 node)], composed with separator.
Error conditions:
coreTemplatemissing → throwsError('createRepeatTwiceTemplateNode requires coreTemplate.')endTemplatemissing → throwsError('createRepeatTwiceTemplateNode requires endTemplate.')
Tests
npm test
Tests cover: ranking tool creation and execution with numeric/alphabetic/chinese ID strategies, pairwise judgment with winner/intensity/rationale XML parsing, p_true/p_sufficient/verbal confidence modes with logprob extraction, repeat template node generation with variable repeat counts, error handling for missing/invalid arguments, and js-rigor property tests for pattern output structure.
Requirements
- Node.js >= 22.0.0
- ESM (
"type": "module") @polyweave/core(dependency)@polyweave/smart-templates(dependency)@polyweave/uncertainty(dependency)@polyweave/tools(dependency)
Dependencies
Dependencies
| ID | Version |
|---|---|
| @polyweave/core | * |
| @polyweave/smart-templates | * |
| @polyweave/tools | * |
| @polyweave/uncertainty | * |
Development Dependencies
| ID | Version |
|---|---|
| @rigor/core | * |