UNPKG

agentfootprint

Version:

The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.

63 lines • 3.43 kB
"use strict"; /** * buildCacheSubflow — the per-turn prompt-cache decision, as ONE subflow. * * Collapses the cache machinery into a single `sf-cache` boundary so the * agent chart reads cleanly (one "Cache" box you can drill into) while the * execution tree stays honest: * * decideCacheMarkers → CacheGate (decider) → ApplyMarkers / SkipCaching * * Layering (see src/cache/types.ts): * - This subflow is the provider-AGNOSTIC DECISION layer — it only computes * and gates provider-neutral `CacheMarker[]`. It knows nothing about any * provider. * - The provider-SPECIFIC MECHANISM (Anthropic `cache_control`, OpenAI * automatic, …) is the attached provider's `CacheStrategy`, selected by * the provider's declared `promptCaching` (`cacheStrategyFor`), applied * later when the request is built. * * Why `UpdateSkillHistory` is NOT in here: the `skillHistory` rolling window * must persist across loop iterations. Keeping `UpdateSkillHistory` in the * main loop (just before this subflow) lets `skillHistory` live in the parent * scope without round-tripping through this subflow's in/out mappers — the * subflow stays pure (reads the turn's state, writes only `cacheMarkers`). * * Deps-free: every input (`activeInjections`, `iteration`, `skillHistory`, * `recentHitRate`, `systemPromptCachePolicy`, …) is supplied by the PARENT's * `inputMapper` at the mount site; the output is just `cacheMarkers`. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.buildCacheSubflow = void 0; const footprintjs_1 = require("footprintjs"); const CacheDecisionSubflow_js_1 = require("../../cache/CacheDecisionSubflow.js"); const CacheGateDecider_js_1 = require("../../cache/CacheGateDecider.js"); const conventions_js_1 = require("../../lib/conventions.js"); /** * Build the `sf-cache` subflow chart. Called by `buildAgentChart` and * `buildDynamicAgentChart` and mounted via `addSubFlowChartNext( * SUBFLOW_IDS.CACHE, buildCacheSubflow(), 'Cache', { inputMapper, * outputMapper, arrayMerge: Replace })`. */ function buildCacheSubflow(options = {}) { return (0, footprintjs_1.flowChart)('CacheDecision', // Root stage = the cache-decision function (a chart cannot start with a // nested subflow). Exported from CacheDecisionSubflow.ts and reused here — // the cache decision is the root of sf-cache, no logic duplication. (0, CacheDecisionSubflow_js_1.cacheDecisionStage)(options), 'decide-cache-markers', { description: 'CacheDecision: walk activeInjections, evaluate cache directives, emit CacheMarker[]', }) .addDeciderFunction('CacheGate', CacheGateDecider_js_1.cacheGateDecide, conventions_js_1.STAGE_IDS.CACHE_GATE, 'Gate cache-marker application: kill switch / hit-rate / skill-churn') .addFunctionBranch(conventions_js_1.STAGE_IDS.APPLY_MARKERS, 'ApplyMarkers', // Pass-through — markers stay in scope; the request build reads them. () => undefined, 'Proceed with cache markers from CacheDecision') .addFunctionBranch(conventions_js_1.STAGE_IDS.SKIP_CACHING, 'SkipCaching', // Clear markers so the request is built unmodified this iteration. (scope) => { scope.cacheMarkers = []; }, 'Skip caching this iteration') .end() .build(); } exports.buildCacheSubflow = buildCacheSubflow; //# sourceMappingURL=buildCacheSubflow.js.map