agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
45 lines • 1.94 kB
JavaScript
const DEFAULT_DIMENSIONS = 32;
/**
* Declared input ceiling (9.1.0). Not a model limit — there is no model. This
* embedder reads every character it is given, so the number is a practical
* bound (a megabyte of text) rather than a cliff.
*/
const MOCK_MAX_INPUT_CHARS = 1_000_000;
function charFrequency(text, dims) {
const vec = new Array(dims).fill(0);
for (let i = 0; i < text.length; i++) {
vec[text.charCodeAt(i) % dims] += 1;
}
return vec;
}
/**
* Build a deterministic mock embedder. Same text always yields the
* same vector; texts sharing characters share cosine similarity.
*/
export function mockEmbedder(options = {}) {
const dimensions = options.dimensions ?? DEFAULT_DIMENSIONS;
if (!Number.isInteger(dimensions) || dimensions <= 0) {
throw new Error(`mockEmbedder: dimensions must be a positive integer (got ${dimensions})`);
}
return {
dimensions,
// Named like the others so a store can refuse the swap between a mock
// index and a real one — which is a swap worth refusing, since a corpus
// indexed by letter frequency and queried by meaning scores nothing.
id: 'mock',
// Deliberately generous: this counts characters in a loop, so there is no
// window to fall off and nothing is ever clipped. It is declared anyway
// (rather than left absent) so a mock-first run does not report truncation
// that only the DEFAULT ceiling believes in — a warning about a limit the
// embedder does not have teaches the wrong lesson before the real embedder
// is swapped in.
maxInputChars: MOCK_MAX_INPUT_CHARS,
async embed({ text }) {
return charFrequency(text, dimensions);
},
async embedBatch({ texts }) {
return texts.map((text) => charFrequency(text, dimensions));
},
};
}
//# sourceMappingURL=mockEmbedder.js.map