agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
73 lines • 4.97 kB
JavaScript
;
/**
* agentfootprint/time — the conversion the time layer itself asks, for an app
* that needs the same answer OUTSIDE a run.
*
* Under `.time()` the library writes the person's window into a tool's own
* arguments (the fill, the time ask's choices, the served line). An app that
* previews what a tool would read, or builds a call itself, asks the SAME
* question the run asks — and gets the library's answer, not a copy that
* drifts:
*
* - `convertForTool` — THE answer: can this tool read this window, and how.
* The tool's facts first (a fact it breaks → `{ refused }`), then the
* first form that holds the window exactly, then the first that holds it
* by reading MORE within the tool's `maxRange`, then `multi-day` for a
* `day`-only tool, else `no-form-holds`; a window partly older than
* `retention` converts, marked `partlyBeyondRetention`. The time ask and
* the bind ask this function (`convert.ts` · `convertForTool`).
* - the tool's own declaration, read the run's way: `sugarForms(period)` is
* the forms a `period` declares (its `forms`, else the `argument` +
* `spelling`/`accepts` sugar); `granularityMsOf(period)` is the clock's
* `granularityMs` (its `granularity`, else one minute); `widestMsOf(period)`
* is its `maxRange` in milliseconds. A tool's `period` IS its facts — pass
* it whole.
* - the parts, for a caller that needs one step alone: `convertExact`,
* `convertWidened` (asked only AFTER `convertExact` finds nothing — it does
* not look for an exact form first), `periodFactProblem`.
* - time for a PERSON, as the run writes it: `presentRange(range, { zone,
* locale? }, grain?)` — the label the time ask and the served line use (a
* half-open range with its end as said, the zone always named), so an
* app's panel shows the run's own words; and `isZoneName(value)` — the
* run's zone check (an IANA name; `PST` and a bare offset are refused,
* although `Intl` takes them), for a session zone before it is passed as
* `time.zone`.
*
* Pure functions over a clock the caller passes: no run, no record, no
* `.time()`. A door of its own because the conversions are the time layer's
* RUN-TIME half, which a plain agent never loads (`src/time/README.md` ·
* "What a plain agent carries"; pinned by
* `test/trace-toolpack/browserGraph.test.ts`): on the main barrel they
* would put that half on every consumer's default graph. The shapes they take
* (`PeriodForm`, `PeriodFacts`, `TimeRange`, `ToolPeriod`) are on the main
* barrel.
*
* @example
* ```ts
* import { convertForTool, granularityMsOf, sugarForms } from 'agentfootprint/time';
*
* // The tool's own declaration — `defineTool({ …, period })`.
* const period = { argument: 'window', spelling: 'lookback', direction: 'past', maxRange: '24h' } as const;
* const clock = { now: '2026-10-09T15:40:00Z', zone: 'America/Los_Angeles', granularityMs: granularityMsOf(period) };
* const yesterday = { from: '2026-10-08T00:00:00-07:00', to: '2026-10-09T00:00:00-07:00' };
*
* convertForTool({ range: yesterday }, sugarForms(period), period, clock);
* // { refused: 'no-form-holds' } — reaching 8 Oct from now takes a look-back wider than 24h
* ```
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.isZoneName = exports.presentRange = exports.sugarForms = exports.periodFactProblem = exports.widestMsOf = exports.granularityMsOf = exports.convertWidened = exports.convertForTool = exports.convertExact = void 0;
var convert_js_1 = require("../time/convert.js");
Object.defineProperty(exports, "convertExact", { enumerable: true, get: function () { return convert_js_1.convertExact; } });
Object.defineProperty(exports, "convertForTool", { enumerable: true, get: function () { return convert_js_1.convertForTool; } });
Object.defineProperty(exports, "convertWidened", { enumerable: true, get: function () { return convert_js_1.convertWidened; } });
Object.defineProperty(exports, "granularityMsOf", { enumerable: true, get: function () { return convert_js_1.granularityMsOf; } });
Object.defineProperty(exports, "widestMsOf", { enumerable: true, get: function () { return convert_js_1.widestMsOf; } });
var periodForm_js_1 = require("../time/periodForm.js");
Object.defineProperty(exports, "periodFactProblem", { enumerable: true, get: function () { return periodForm_js_1.periodFactProblem; } });
Object.defineProperty(exports, "sugarForms", { enumerable: true, get: function () { return periodForm_js_1.sugarForms; } });
var present_js_1 = require("../time/present.js");
Object.defineProperty(exports, "presentRange", { enumerable: true, get: function () { return present_js_1.presentRange; } });
var zone_js_1 = require("../time/zone.js");
Object.defineProperty(exports, "isZoneName", { enumerable: true, get: function () { return zone_js_1.isZoneName; } });
//# sourceMappingURL=time.js.map