Skip to main content

PocketFlow Adapter

The PocketFlow adapter integrates Kindling with PocketFlow workflow nodes. Each node run automatically gets its own capsule, and the full lifecycle (start, output, error, end) is captured as observations with intent inference and confidence tracking.

It is a TypeScript package that builds on @eddacraft/kindling:

npm install @eddacraft/kindling-adapter-pocketflow
# or: pnpm add @eddacraft/kindling-adapter-pocketflow
# or: yarn add @eddacraft/kindling-adapter-pocketflow
# or: bun add @eddacraft/kindling-adapter-pocketflow

KindlingNode

KindlingNode extends PocketFlow's Node with automatic observation capture. Each run:

  1. prep — Opens a capsule and records a node_start observation
  2. exec — Your logic runs as normal
  3. post — Records node_output and node_end, then closes the capsule
import {
KindlingNode,
KindlingFlow,
} from '@eddacraft/kindling-adapter-pocketflow';
import type { KindlingNodeContext } from '@eddacraft/kindling-adapter-pocketflow';

// Define a node
class RunTests extends KindlingNode {
constructor() {
super({ name: 'run-tests', intent: 'test' });
}

async exec(): Promise<unknown> {
// Your node logic
return { passed: 42, failed: 0 };
}
}

Error Handling

If exec throws after all retries, execFallback records a node_error observation with the error details and stack trace, then closes the capsule before re-throwing:

class RiskyNode extends KindlingNode {
constructor() {
// 3 retries with 1 second wait
super({ name: 'risky-operation' }, 3, 1);
}

async exec(): Promise<unknown> {
// If this fails 3 times, the error is captured
// with retryCount in provenance
return await riskyCall();
}
}

Observations Captured

KindWhenProvenance includes
node_startBefore exec runsNode name, intent, params
node_outputAfter exec succeedsNode name, output type, duration
node_errorAfter all retries exhaustedError type, message, stack, retryCount
node_endAlways (success or failure)Node name, duration, status

Output is automatically truncated to 2KB to avoid storing excessive data.

KindlingFlow

KindlingFlow wraps a graph of KindlingNodes. The flow itself gets a parent capsule, and each node creates its own child capsule during its run:

const runTests = new RunTests();
const deploy = new DeployNode();

// Wire the graph
runTests.next(deploy);

// Create the flow
const pipeline = new KindlingFlow(runTests, {
name: 'ci-pipeline',
intent: 'deploy',
});

// Run it
import { Kindling } from '@eddacraft/kindling';

const kindling = new Kindling({ projectRoot: process.cwd() });

const shared: KindlingNodeContext = {
kindling,
scopeIds: { repoId: 'my-app', sessionId: 'ci-run-1' },
};

await pipeline.run(shared);

Intent Inference

Node names are automatically mapped to semantic intents using pattern matching. This enables smarter retrieval and context organization.

import { inferIntent } from '@eddacraft/kindling-adapter-pocketflow';

inferIntent('run-tests'); // -> 'test'
inferIntent('buildApp'); // -> 'build'
inferIntent('deploy_production'); // -> 'deploy'
inferIntent('fixAuthBug'); // -> 'debug'
inferIntent('unknownNode'); // -> 'general'

The default patterns cover common development workflows:

IntentKeywords
testtest, spec, check, verify, validate, assert
buildbuild, compile, bundle, pack, transpile
deploydeploy, publish, release, ship
debugfix, debug, repair, patch, hotfix, troubleshoot
featureimplement, add, create, feature, develop
refactorrefactor, restructure, reorganize, cleanup
processprocess, transform, convert, parse, extract
analyzeanalyze, research, investigate, explore
generategenerate, scaffold, template, init, setup
storesave, store, persist, write, cache, backup
retrieveread, get, load, retrieve, query
cleanupclean, clear, remove, delete, prune
monitorlog, monitor, track, metric, observe, report

You can supply custom patterns:

inferIntent('myCustomNode', [
{ keywords: ['custom'], intent: 'my-intent' },
...DEFAULT_INTENT_PATTERNS,
]);

Confidence Tracking

The ConfidenceTracker maintains a reliability score (0.0 to 1.0) for each node based on its history. This score is included in observation provenance for explainability. Retrieval ranking itself is deterministic FTS + recency in kindling-provider — confidence metadata does not change search order.

import { ConfidenceTracker } from '@eddacraft/kindling-adapter-pocketflow';

const tracker = new ConfidenceTracker();

tracker.recordSuccess('run-tests');
tracker.recordSuccess('run-tests');
tracker.recordFailure('deploy-prod', 'Connection timeout');

tracker.getConfidence('run-tests'); // 0.7
tracker.getConfidence('deploy-prod'); // 0.35

// Embed in observation provenance
const provenance = tracker.getProvenanceMetadata('run-tests');
// { confidence: 0.7, successCount: 2, failureCount: 0, ... }

The confidence algorithm considers:

  • Overall success rate across all recorded runs
  • Recent trends weighted more heavily than older results (configurable, default 70%)
  • Consecutive failure penalty that depresses confidence during failure streaks
  • Configurable bounds with floor (0.1) and ceiling (0.95)
// Custom configuration
const tracker = new ConfidenceTracker({
historySize: 20, // Keep more history
baseConfidence: 0.6, // Higher starting confidence
successIncrement: 0.1,
failureDecrement: 0.15,
minConfidence: 0.1,
maxConfidence: 0.95,
recencyWeight: 0.7,
});

Next