Polyweave

@polyweave/harness-base (1.0.5)

Published 2026-07-17 15:30:10 +00:00 by Dvorak

Installation

@polyweave:registry=https://hub.kl1.tenere.ai/api/packages/Polyweave/npm/
npm install @polyweave/harness-base@1.0.5
"@polyweave/harness-base": "1.0.5"

About this package

@polyweave/harness-base

Shared primitives for LLM execution harnesses — bounded pushable output source, lifecycle wrapper with iteration tracking, and standardized harness error frame factories.

Synopsis

import { createBoundedPushable, createLifecycleWrapper, createHarnessErrorFrame } from '@polyweave/harness-base';

const output = createBoundedPushable({ maxBufferedFrames: 64, overflowStrategy: 'drop-oldest' });
output.pipe(mySink);
output.write({ type: 'TEXT', content: { text: 'Hello' } });

const lifecycle = createLifecycleWrapper(adapterDuplex, { maxIterations: 5 });
lifecycle.startRun();

const errorFrame = createHarnessErrorFrame(new Error('failed'), 'my-component');

Install

npm install @polyweave/harness-base

Why

Multiple harness implementations (bt-harness, meta-bt-harness, agent-loop, gatto-agent-harness) need the same primitives: a writable push-stream source that can buffer frames safely, a lifecycle tracker that gates iteration count and CANCEL/ABORT signals, and a canonical error frame shape. Rather than duplicate these across every harness, this package provides the single-source-of-truth implementations used by all harnesses.

API

createBoundedPushable(options)

Creates a writable push-stream source with configurable bounded buffering.

Signature: createBoundedPushable(options?: Object): BoundedPushable

Name Type Required Default Description
options Object No {} Configuration object
options.maxBufferedFrames number|null No 100 Maximum frames to buffer before triggering overflow strategy. null disables the limit.
options.overflowStrategy string No 'drop-oldest' One of 'drop-oldest', 'drop-newest', or 'error'
options.onBufferOverflow Function No undefined Callback invoked when buffer exceeds maxBufferedFrames. Receives { bufferedLength, maxBufferedFrames, strategy }.

Returns: BoundedPushable — a writable source with these methods and properties:

Member Type Description
pipe(sink) Function Connects this pushable to a downstream sink. Returns the sink.
write(frame) Function Writes a frame. If downstream sink is paused, buffers the frame. If buffer overflow, applies overflowStrategy.
end(err?) Function Flushes buffer then ends downstream. Ignores subsequent write() calls.
abort(err?) Function Immediately discards buffer and aborts downstream.
resume() Function Resumes drained frames from buffer. Called automatically on pipe().
paused boolean Reports downstream sink paused state.
ended boolean Reports whether end() or abort() was called.
getBufferedFrameCount() Function Returns current number of pending frames in the buffer.

Overflow strategies:

  • 'drop-oldest' (default): Shifts the oldest buffered frame and pushes the new one.
  • 'drop-newest': Drops the incoming frame silently.
  • 'error': Calls end(new Error('Buffer overflow: max N frames')), shutting down the pushable.

Throws: Does not throw. Errors from 'error' overflow strategy are delivered via end() to the downstream sink.


createLifecycleWrapper(innerDuplex, options)

Wraps a duplex stream with lifecycle state tracking — iteration count, running/aborted/completed flags, and CANCEL/ABORT signal interception.

Signature: createLifecycleWrapper(innerDuplex: IFrameDuplex, options?: Object): LifecycleWrapper

Name Type Required Default Description
innerDuplex IFrameDuplex Yes The duplex to wrap (e.g., an LLM adapter).
options Object No {} Configuration object
options.maxIterations number No 10 Maximum iteration count before onMaxIterations fires. Overridable at runtime via PARAM frame with key 'maxIterations'.
options.onMaxIterations Function No undefined Callback invoked when iteration >= maxIterations. Receives a state snapshot object.
options.onAbort Function No undefined Callback invoked on CANCEL or ABORT. Receives the abort reason string.
options.name string No null Name forwarded to createBidirectionalWrapper.

Returns: LifecycleWrapper object with:

Member Type Description
source IFrameSource The wrapped duplex source, interleaved with observable state frames.
sink IFrameSink The wrapped duplex sink.
getState() Function Returns a state snapshot: { iteration, running, aborted, completed, maxIterations }.
startRun() Function Resets running=true, aborted=false, completed=false, iteration=0.
incrementIteration() Function Increments iteration. Fires onMaxIterations if iteration >= maxIterations.
abort(reason?) Function Triggers abort sequence: sets aborted/running flags, calls onAbort, writes an ABORT frame downstream, then ends.
isMaxIterations() Function Returns true if iteration >= maxIterations.
isAborted() Function Returns true if abort has been triggered.
isRunning() Function Returns true if the lifecycle is in running state.

Frame protocol:

Direction Frame Type Behavior
Input PARAM { key: 'maxIterations', value } Updates maxIterations in state.
Input CANCEL Triggers abort with message 'aborted via CANCEL'.
Input ABORT Triggers abort with message 'aborted via ABORT'.
Output (response) END Sets running=false.
Output (response) ERROR Sets running=false, completed=true.

Throws: Does not throw. Errors propagate as ABORT frames to the downstream sink.


createHarnessErrorFrame(error, source)

Produces a standardized ERROR frame for harness error reporting.

Signature: createHarnessErrorFrame(error: Error, source?: string): IFrame

Name Type Required Default Description
error Error Yes The error to encode in the frame.
source string No 'harness' Identifier for the error source component.

Returns: IFrame{ type: FrameType.ERROR, content: { message: error.message, source } }

Throws: Does not throw.

Tests

npm test

Covers: bounded pushable overflow strategies (drop-oldest, drop-newest, error), buffer counting, end/abort semantics, lifecycle wrapper state transitions (start, iteration increment, max iterations callback, cancel/abort interception), and harness error frame shape.

Requirements

  • Node.js 22+
  • ESM only
  • Peer: @polyweave/core

Dependencies

Development Dependencies

ID Version
@rigor/core *

Peer Dependencies

ID Version
@polyweave/core *

Keywords

polyweave harness execution-loop push-stream
Details
npm
2026-07-17 15:30:10 +00:00
278
John Dvorak
SEE LICENSE IN LICENSE
latest
5.3 KiB
Assets (1)
Versions (5) View all
1.0.5 2026-07-17
1.0.6 2026-07-11
1.0.3 2026-07-11
1.0.2 2026-07-10
1.0.1 2026-07-10