The code stays small. Every symbol in H = (S, N, E, T, Σ, R, V, F) maps to a
primitive, and most of them are thin layers over modelgraph rather than
reimplementations.
| Symbol | Primitive | File |
|---|---|---|
S source |
the input you pass to path.run(input) |
— |
N nodes |
FlowNode (alias of a modelgraph Transform), createFlowNode |
src/flow.ts |
E edges |
FlowEdge, EdgeFlowSignal |
src/edge.ts |
T trace |
FlowRun.trace (lifted from a modelgraph GraphRun) |
src/flow.ts |
Σ signals |
FlowSignal, SignalExtractor, aggregateSignals, latencySignal, fromOutputField, staticSignal |
src/signals.ts |
R relations |
RelationCheck, runRelationChecks, TraceRelation, firstRelationBreak |
src/relations.ts |
V verifier |
Sink predicate or a modelgraph Evaluator on the path |
src/flow.ts |
F feedback |
runWithFeedback, FeedbackLoopConfig, FeedbackLoopResult |
src/feedback.ts |
Φ score |
usefulFlowScore, combineCost, combineQuality, scorePath |
src/theory.ts, src/path.ts |
Cross-cutting primitives:
src/theory.ts— the formal types (Harness,UsefulFlowScore,CostTerms,QualityTerms) and the scoring functions. This is the layer that makes paths comparable.src/path.ts— path-scoped helpers:pathCost,scorePath(Φ = Q/C),pathSignature.src/compare.ts—comparePathsandbestPathrank candidate runs by acceptance, cost, signal deltas, and divergence.src/bottleneck.ts—findBottleneckreturns aBottleneckResult: the boundary limiting useful flow (a heuristic, not a proven min-cut).src/diagram.ts—printFlowGraphrenders a harness graph as inspectable terminal ASCII (static topology, or a run overlaid with signals + a bottleneck readout).fromFlowPath/overlayRunadapt a liveFlowPath/FlowRun;printLinearPath/printFeedbackLoop/printParallelPathsdraw the canonical patterns. Renders any labelled graph — no AI-specific node kinds.src/modelgraph-adapter.ts— the single place that imports modelgraph. Everything else imports from here, so intelligence-flow stays a layer above modelgraph instead of entangled with it.
- Node kinds are not hardcoded. A node is defined by the boundary it
exposes. There is no
model | tool | memory | evaluatorenum. - The core attaches no meaning to a signal
key. Domains decide whatcost,relevance, orerrormean; the primitives only move and aggregate numbers. - Do not duplicate modelgraph. Transform execution, traces, evaluators, and graph runs live in modelgraph. intelligence-flow adds edges, paths, signals, bottlenecks, feedback, and useful-flow scoring on top.
type UsefulFlowScore = {
quality: number;
cost: number;
score: number; // quality / cost
};
type EdgeFlowSignal = {
edgeId: string;
capacity?: number;
cost?: number;
loss?: number;
error?: number;
confidence?: number;
};
type BottleneckResult = {
targetId: string;
scope: "node" | "edge" | "path";
reason: string;
limitingSignal: string;
value: number;
};