agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
71 lines (70 loc) • 3.58 kB
TypeScript
/**
* skillGraphDeclared — the AUTHOR'S skill map, projected for the record.
*
* Pattern: Pure projection over the structural graph `.skillGraph()` accepts.
* Role: Turn what the builder was HANDED into what
* `agentfootprint.skill.graph_declared` SAYS — the declared nodes and
* edges as DATA, so a consumer drawing the graph from a recording
* (the lens's `declaredSource: 'recording'` branch) never has to
* reconstruct the topology from per-hop `routing[]` provenance, which
* names an edge only once it FIRES and is therefore a lower bound.
* Emits: N/A — the Agent dispatches what this returns, once per run, right
* after the run-configuration manifest.
*
* ## The rule this file exists to keep
*
* The map carries EXACTLY what the author declared — the built graph's own
* `nodes` and `edges` — and nothing inferred. Two consequences, both refusals
* to guess:
*
* - a structurally-typed graph that carries no `nodes` yields `undefined`
* (no event), because a map this file would have to invent is not the
* author's map — the same forward-compat posture as `explainNextSkill`
* ("a graph built before it existed still routes, it just cannot narrate");
* - an edge row that does not state its own `from` (the `.skillGraph()`
* structural type required only `to` until 9.50.0) is SKIPPED, never
* completed: `from: null` means the synthetic START and only the graph may
* say so.
*
* Descriptions are the skills' catalog descriptions, verbatim — the text the
* model reads — looked up by node id; absent when a skill declares none.
* Titles (`defineSkill({ title })`) are looked up the same way and absent the
* same way; a title is for a person reading a report and is never drawn in
* place of `label`.
*/
import type { Injection } from '../../injection-engine/types.js';
import type { SkillGraphDeclaredPayload } from '../../events/payloads.js';
/** The structural slice of a graph this projection reads. Matches (a widened
* version of) what `AgentBuilder.skillGraph()` accepts — every field optional,
* because a consumer may hand the builder a structurally-typed graph. */
export interface DeclarableGraph {
readonly nodes?: ReadonlyArray<{
readonly kind: string;
readonly id?: string;
readonly label?: string;
}>;
readonly edges?: ReadonlyArray<{
readonly to: string;
readonly from?: string | null;
readonly kind?: string;
readonly label?: string;
/** The edge's declared DATA guard (9.51.0) — carried verbatim when it has
* the compiled shape; anything else is SKIPPED, never completed (the
* same refusal-to-guess as `from`). */
readonly guard?: {
readonly conditions?: unknown;
};
}>;
}
/** The captured map — the exact payload `skill.graph_declared` will carry.
* A named alias so Agent/AgentBuilder speak about the capture without
* importing an event payload for a field type. */
export type SkillGraphDeclaredMap = SkillGraphDeclaredPayload;
/**
* Project the declared map, or `undefined` when the graph cannot state one.
*
* `skills` supplies the catalog descriptions (the graph's compiled
* injections); only `flavor: 'skill'` rows are consulted, and a node with no
* matching skill (a predicate diamond) simply carries no description.
*/
export declare function buildSkillGraphDeclared(graph: DeclarableGraph, skills: readonly Injection[]): SkillGraphDeclaredMap | undefined;