Polyweave

@polyweave/nursery (1.0.6)

Published 2026-07-11 15:28:22 +00:00 by Dvorak

Installation

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

About this package

@polyweave/nursery

Reliability-economic protocol grower for Polyweave harnesses — scores, evolves, and selects behavior tree (BT) specifications against calibration instances from domain definitions.

Synopsis

import { createNurseryTool, growProtocol, scoreProtocolCandidate, createDomainFromSpec } from '@polyweave/nursery';

// Synchronous protocol scoring
const domain = createDomainFromSpec(myDomainSpec);
const instances = domain.generateInstances(50, 42);

const result = growProtocol({
  domain: myDomainSpec,
  seeds: [{ id: 'test', name: 'Test protocol', spec: '─── SYMBOLS ───\n@done : boolean = false\n\n─── ACTIONS ───\nsolve (action):\n  task "Solve"\n  on success: @done = true\n\n─── TREE ───\nroot = sequence { action solve }', metrics: { p0: 0.7, c: 0.2, gamma: 0.02 } }],
  scoringProfile: { objectiveWeights: { validRate: 5.0, costEfficiency: 4.0 } }
});

// Frame-duplex tool
const tool = createNurseryTool({ executionGraph: myGraph });
tool.sink.write({ type: 'TOOL_CALL', content: { requirement: 'Build a microstep verifier protocol' } });

// Grow loop tool
const growTool = createNurseryGrowTool({
  apiKey: process.env.OPENAI_API_KEY,
  model: 'gpt-4o',
  domain: myDomain,
  initialSpec: baseSpec,
  maxImprovements: 10,
  patience: 3
});
growTool.sink.write({ type: 'TOOL_CALL', content: {} });

Install

npm install @polyweave/nursery

Why

Polyweave harnesses need protocols that maximize reliability per token — but writing BT specs by hand is brittle. The nursery automates protocol growth using multi-objective optimization: it evaluates candidates against domain calibration instances, scores them on reliability gain, validity rate, quorum convergence, temperature diversity, correction/corruption efficiency, and cost, then selects the best. This removes human trial-and-error from protocol design while providing audit trails through execution graph traces.

API

createNurseryTool(options)

Creates a frame-duplex tool for synchronous protocol growing.

Parameters:

Name Type Required Default Description
options.executionGraph object No New execution graph Execution graph for tracking protocol runs
options.executionGraphOptions object No {} Options passed to createExecutionGraph
options.scoringProfile object No DEFAULT_SCORING_PROFILE Custom scoring weight profile
options.name string No null Node name
options.* any No All options forwarded to growProtocol

TOOL_CALL args: { requirement, initialSpec, candidates, baselineAccuracy, packageInventory }

Return value: IFrameDuplex with .source, .sink, .graph (execution graph), .name, ._toolName = 'nursery'.

Handles DESCRIBE frames (returns tool description) and TOOL_CALL frames (runs growProtocol, responds with TOOL_RESULT + END). Errors are caught and returned as TOOL_RESULT with { success: false, error }.

createNurseryGrowTool(options)

Creates a bt-harness-driven nursery grow loop tool. Supports two modes:

  • Static mode (no agentAdapter/agentFactory/createAdapter): Uses sampler variants + internal scoring
  • BT harness mode (with agent adapters): Uses NURSERY_GROW_SPEC BT spec with real LLM calls

Parameters:

Name Type Required Default Description
options.apiKey string Yes API key for LLM calls
options.model string No 'deepseek-v4-pro' Model name for agent/evaluator
options.domainSpec object No Domain specification
options.initialSpec string No '' Starting BT spec
options.scoringProfile object No DEFAULT_SCORING_PROFILE Scoring weights
options.packageInventory array No DEFAULT_PACKAGE_ROLES Polyweave package roles
options.executionGraph object No New graph Execution graph
options.maxIterations number No 8 Maximum refinement iterations
options.patience number No 3 Stagnation patience
options.debug boolean No false Debug console output
options.agentAdapter object No Agent adapter (triggers BT harness mode)
options.evaluatorAdapter object No Evaluator adapter
options.agentFactory function No Agent factory
options.evaluatorFactory function No Evaluator factory
options.createAdapter function No Adapter creation function
options.adapterConfig object No Adapter configuration
options.quorumAdapter object No Custom quorum adapter (injected into tools)
options.redflagAdapter object No Custom redflag adapter (injected into tools)
options.name string No null Node name

Return value: IFrameDuplex with methods getBestSpec(), getBestScore(), getHistory(), .graph, .name, ._toolName = 'nursery'.

Internal tools registered: nrs_read, nrs_propose, nrs_validate, nrs_benchmark, nrs_score — each exposed as a frame-duplex tool adapter with TOOL_CALL handling.

Frame handling:

  • TOOL_CALL → starts a run (static or BT harness depending on adapter presence)
  • TICK → forwards tick to running BT harness
  • CANCEL → cancels current harness run
  • ABORT → aborts current harness run
  • DESCRIBE → returns tool description

The static mode (startStaticRun) generates diversified spec proposals via createSampleVariants, validates them, benchmarks against domain calibration instances, scores them, and promotes the best. Rounds are bounded by maxIterations with stagnation-based early stopping.

The BT harness mode (startBtHarnessRun) creates a bt-harness running NURSERY_GROW_SPEC, piping its output frames for progress tracking and bt:tree_complete / bt:tree_failed / bt:error event handling.

growProtocol(options)

Synchronous protocol growing function. Scores candidates and returns the best.

Parameters:

Name Type Required Default Description
options.domain object No Domain specification
options.requirement string No '' Task requirement description
options.initialSpec string No Starting BT spec
options.initialMetrics object No Metrics for initial spec
options.initialTokenEconomics object No Token economics for initial spec
options.candidates array No [] Additional candidate protocol objects
options.includeDefaultSeeds boolean No false Include built-in seed protocols when no candidates provided
options.scoringProfile object No DEFAULT_SCORING_PROFILE Scoring weights
options.executionGraph object No New graph Execution graph for recording runs, steps, candidates, verifications, selections, commits
options.packageInventory array No DEFAULT_PACKAGE_ROLES Package inventory
options.runId string No Auto-generated Run identifier
options.baselineAccuracy number No Baseline accuracy for score normalization

Return value:

{
  success: true,
  best: { id, name, spec, valid, errors, score, tScore, econScore,
          objectiveLabels, objectiveValues, objectiveWeights,
          economics: { p0, predictedP1, expectedGain, c, gamma, validRate, avgVotes,
                       tokenCostUsd, tokens, uncertainty, consistency, confidence,
                       learnedGain, diversity, judgeAgreement, exampleQuality,
                       temperatureDiversity, cpEfficiency, redflagQuality, oracleHeadroom,
                       breakEvenScale },
          structure: { actionCount, conditionCount, checkCount, parallelCount, selectorCount },
          rationale },
  candidates: [/* all scored candidates sorted by score descending */],
  packageInventory,
  objective: 'maximize verified reliability per token while increasing decomposition, parallelism, and traceability'
}

scoreProtocolCandidate(candidate, context)

Scores a single BT specification against calibration instances.

Parameters:

Name Type Required Default Description
candidate.spec string Yes BT spec string
candidate.id / candidate.name string No Auto-generated Candidate identifier
candidate.metrics object No {} { p0, p1, c, gamma, validRate, avgVotes, counts }
candidate.tokenEconomics object No {} { inputTokens, outputTokens, inputCostPer1M, outputCostPer1M, costUsd }
candidate.uncertainty object No {} { consistency, uncertainty, confidence, samples }
candidate.selfImproving object No {} { learnedGain, diversity, judgeAgreement, exampleQuality }
candidate.temperature object No {} { useTemperatureVariation, firstVoteTemperature, subsequentTemperature }
candidate.redflag object No {} { hasTokenLimit, maxTokens, hasSpikeThreshold, tokenSpikeThreshold, detectSelfContradiction, trackCollisions }
candidate.oracle object No {} { pOracle, pSelected }
candidate.decomposition object No {} { modes, parallelism }
candidate.usesExecutionGraph boolean No false Adds traceability bonus
context.scoringProfile object No DEFAULT_SCORING_PROFILE Scoring weight profile
context.baselineAccuracy number No 0.5 Baseline p0 fallback
context.baselineEmbedding array No Baseline embedding for diversity calculation

Return value — see single candidate structure in growProtocol return above.

Scoring algorithm: The nursery computes a multi-objective score in two parts:

  1. Economics score (weighted product): econScore = gain × econMods × validRateMod × invGammaMod, where:

    • gain = clamp01(p1Pred - p0 + 0.005)
    • econMods = econBase + econCostEff × costEfficiency + econTemperature × tempDiversity + econRedflag × redflagQuality + econCpEff × cpEfficiency
    • invGamma = clamp01(1 - gamma × breakEvenScale × 0.5)
    • breakEvenScale = p0 / (1-p0)
  2. Tchebycheff score: Measures worst-case weighted gap across 13 objectives (reliabilityGain, invGamma, validRate, quorumConv, temperatureDiversity, cpEfficiency, redflagQuality, consistency, learnedGain, oracleHeadroom, costEfficiency, decomposition, traceability).

Final score: score = round((econScore × (1 - tchebycheffWeight) + tchebycheffNormalized × tchebycheffWeight) × econScale)

DEFAULT_SCORING_PROFILE

Default weight configuration (frozen):

{
  objectiveWeights: {
    reliabilityGain: 8.0, invGamma: 4.0, validRate: 2.0,
    quorumConv: 1.0, temperatureDiversity: 2.0, cpEfficiency: 2.0,
    redflagQuality: 1.5, consistency: 1.0, learnedGain: 0.5,
    oracleHeadroom: 1.0, costEfficiency: 3.0, decomposition: 1.0,
    traceability: 0.5
  },
  econBase: 0.7, econCostEff: 0.15, econTemperature: 0.05,
  econRedflag: 0.05, econCpEff: 0.05,
  validRateWeight: 0.2, invGammaWeight: 0.5,
  econScale: 1000, tchebycheffWeight: 0.3
}

defaultProtocolSeeds(options)

Returns an array of two default seed BT spec candidates:

  • quorum-redflag-verifier — 5-action VRFQ pipeline with p0: 0.7, c: 0.25, gamma: 0.02
  • maximal-decomposition — 3-action decomposer with p0: 0.65, c: 0.2, gamma: 0.015

Each seed includes metrics, uncertainty, self-improving, tokenEconomics, and decomposition data.

DEFAULT_PACKAGE_ROLES

Frozen array of 22 Polyweave packages with their roles (e.g. { name: '@polyweave/bt-harness', role: 'behavior-tree control plane and evaluator-gated decomposition' }).

summarizePackageInventory(packages)

Normalizes a package inventory to { name, role } format. Accepts string arrays or object arrays.

createDomainFromSpec(spec, options)

Creates a domain object from a declarative domain specification with a composable verifier compiler.

Parameters:

Name Type Required Default Description
spec.name string No 'unnamed' Domain name
spec.description string No '' Domain description
spec.type string No 'batch' Domain type
spec.capabilityRequirements array No [] Required capabilities
spec.taskTemplate string No '{{task}}' Mustache-style prompt template
spec.instanceGenerator object/function No Simple seed generator { type, name, parameters } or JS function
spec.verifier object/function No { type, rules[] } (composite) or JS function
spec.critic object/function No { onFailure: { code: message } } or JS function
spec.slices object/function No { all: 'true' } Slice predicate map { name: expr }
options.jsEscapeHatch object No {} Map of named JS functions for custom rules

Return value: { name, description, capabilityRequirements, type, generateInstance(seed), generateInstances(count, startSeed), renderPrompt(instance), verify(output, instance), getSlice(instance), getCritique(verdict, instance), rawSpec }

Verifier rule types (compiled by createVerifierCompiler):

  • json_parse / is_object — output must be a JSON object
  • is_array — output must be a JSON array
  • is_string — output must be a string
  • required_fields{ fields: ['field', 'nested.field'] } — field presence check
  • integer_range{ field, min, max } — integer in range
  • predicate{ predicate: 'expr', code, message } — boolean expression
  • equals{ field, value, fieldRef? } — equality check
  • array_entry{ rules: [...] } — each array entry checked
  • function{ name } — delegates to jsEscapeHatch[name]
  • code_exec{ codeField, tests: [{ input, expected }] } — runs code through tests

Domain presets (from src/domain-presets.js): createHanoiSpec(), createJsonPatchSpec(), createBtSpecRepairSpec(), createFactGraphQuerySpec(), createHumanEvalSpec(). Accessible via DOMAIN_DEFAULTS map.

createDomainJsEscapeHatches()

Returns an object with JS functions for domain instance generation and verification:

  • generateHanoiInstance(seed, param) — generates Tower of Hanoi instances
  • verifyHanoiMove(output, instance) — verifies Hanoi move validity
  • generateJsonPatchInstance(seed) — generates JSON patch instances
  • verifyJsonPatch(output, instance) — verifies patch correctness
  • generateBtSpecRepairInstance(seed) — generates BT spec repair instances
  • verifyBtSpecStructure(output, instance) — verifies repaired spec structure
  • generateFactGraphQueryInstance(seed) — generates fact graph query instances
  • generateHumanEvalInstance(seed) — generates HumanEval-like instances

NURSERY_GROW_SPEC

A complete BT spec string used as the default spec for createNurseryGrowTool BT harness mode. Defines the grow loop: propose_protocols → validate_protocols → benchmark_protocols → score_protocols → promote_best (if improved) / record_stagnation (if not). Uses parametric maxIterations and patience, symbols for iteration/stagnation tracking, and selector-based branching for promote vs. stagnate.

Prompt Builders

  • buildBtHarnessSystemPrompt(options) — builds the system prompt for bt-harness protocol generation with domain context, pattern catalog, tool reference, scoring explanation, and 3-5 diverse spec generation instructions
  • buildBtHarnessFeedbackPrompt(history, bestScore, bestSpec, domainContext, packageInventory) — builds feedback from prior rounds with per-candidate scores, c/gamma trace, improvement directions
  • buildDomainContextForPrompt(domainSpec) — builds domain-aware context from a domain spec with name, task template (rendered), output schema, verifier checks, example instances, and slice definitions

Error Conditions

Condition Where Handling
Candidate spec has no text nrs_propose Returns { stored: false, error: 'Missing spec text' }
No valid candidate for benchmark nrs_benchmark Returns { benchmarked: false, error: 'No valid candidate' }
No candidate to score nrs_score Returns { scored: false, error: 'No candidate to score' }
Already running startBtHarnessRun Returns ERROR frame with 'nursery already running'
Invalid BT harness spec startBtHarnessRun Returns ERROR frame with joined errors
Domain spec parsing failure initDomainContext (grow loop) Swallows error, sets domainObj = null, empty instances
createDomainFromSpec missing JS function domain-spec rule compilation Returns { passed: false, code: 'MISSING_FUNCTION' }
code_exec compile/runtime error domain-spec verifier Returns { passed: false, code: 'TEST_ERROR' }
growProtocol exception createNurseryTool Caught, returned as TOOL_RESULT with { success: false, error }

Tests

npm test

Runs node --test test/*.test.js. Covers:

  • scoreProtocolCandidate scoring invariants (score range, valid vs invalid, economics consistency)
  • growProtocol best candidate selection, execution graph recording
  • DEFAULT_SCORING_PROFILE immutability
  • defaultProtocolSeeds structure
  • summarizePackageInventory normalization
  • createNurseryTool tool creation and DESCRIBE response
  • createNurseryGrowTool construction, quorum/redflag adapter injection
  • createDomainFromSpec with composite verifier rules
  • createDomainJsEscapeHatches Hanoi move generation and verification
  • buildBtHarnessSystemPrompt output structure
  • NURSERY_GROW_SPEC parseability

Requirements

  • Node.js >= 22.0.0
  • ESM only ("type": "module")
  • Dependencies: @polyweave/bt-harness, @polyweave/core, @polyweave/creativity, @polyweave/execution-graph, @polyweave/protocol-metrics, @polyweave/quorum, @polyweave/redflag, @polyweave/sampler, @polyweave/self-improving, @polyweave/state, @polyweave/uncertainty
  • Peer dependencies: @polyweave/agent-loop, @polyweave/feedback-descent, @polyweave/flex, @polyweave/grpo, @polyweave/harness-base, @polyweave/meta-bt-harness, @polyweave/pool, @polyweave/prompt-manager, @polyweave/routing, @polyweave/smart-templates, @polyweave/state-search, @polyweave/tool-adapter, @polyweave/tools

Dependencies

Dependencies

ID Version
@polyweave/bt-harness *
@polyweave/core *
@polyweave/creativity *
@polyweave/execution-graph *
@polyweave/protocol-metrics *
@polyweave/quorum *
@polyweave/redflag *
@polyweave/sampler *
@polyweave/self-improving *
@polyweave/state *
@polyweave/uncertainty *

Development Dependencies

ID Version
@rigor/core *

Peer Dependencies

ID Version
@polyweave/agent-loop *
@polyweave/feedback-descent *
@polyweave/flex *
@polyweave/grpo *
@polyweave/harness-base *
@polyweave/meta-bt-harness *
@polyweave/pool *
@polyweave/prompt-manager *
@polyweave/routing *
@polyweave/smart-templates *
@polyweave/state-search *
@polyweave/tool-adapter *
@polyweave/tools *

Keywords

polyweave nursery protocol optimization
Details
npm
2026-07-11 15:28:22 +00:00
43
John Dvorak
SEE LICENSE IN LICENSE
latest
33 KiB
Assets (1)
Versions (3) View all
1.0.6 2026-07-11
1.0.3 2026-07-11
1.0.2 2026-07-10