agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
90 lines • 4.01 kB
JavaScript
;
/**
* time/wire — the time layer's JSON that crosses a transport (time
* design § 7.5): `ctx.time`, the window a call asks for, handed to the tool.
*
* Pattern: one versioned shape, the same object in process and on the wire.
* In process it is `ToolExecutionContext.time`; over MCP it travels
* in the `tools/call` request's `_meta.agentfootprint.time`
* (`mcp/mcpClient.ts` sends it, `mcp/mcpServe.ts` hands it
* to the served tool); a transport with no metadata slot sends
* nothing, and the tool declares its period from its own arguments.
* A tool's `period` declaration itself travels in the listing's
* `_meta.agentfootprint.period`, judged by `tools/declare.ts`.
* Role: L0 leaf (the time layer). Imports `instant.ts`, `range.ts` and
* `zone.ts` only.
* Emits: N/A.
*
* @example
* ```ts
* timeContextOf({ asked: { from: '2026-10-09T08:00:00-07:00', to: '2026-10-09T08:41:00-07:00' } },
* { now: '2026-10-09T15:40:00Z', zone: 'America/Los_Angeles' }, '2026-10-09T15:40:02.114Z');
* // { version: 1, asked: { from: …, to: …, edge: 'exclusive' }, zone: 'America/Los_Angeles',
* // now: '2026-10-09T15:40:00Z', dispatchedAt: '2026-10-09T15:40:02.114Z' }
* ```
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.readTimeContext = exports.timeContextOf = exports.TIME_CONTEXT_META_KEY = exports.TIME_CONTEXT_VERSION = void 0;
const instant_js_1 = require("./instant.js");
const range_js_1 = require("./range.js");
const zone_js_1 = require("./zone.js");
/** The shape's version — a reader refuses one it does not know. */
exports.TIME_CONTEXT_VERSION = 1;
/** The `_meta.agentfootprint` key the call's time travels under over MCP. */
exports.TIME_CONTEXT_META_KEY = 'time';
/** The context for one call, from its `call-window` row's `asked`, the turn's clock and the dispatch moment. */
function timeContextOf(window, clock, dispatchedAt) {
const asked = window?.asked;
return {
version: exports.TIME_CONTEXT_VERSION,
...(asked !== undefined && {
asked: { from: asked.from, to: asked.to, edge: 'exclusive' },
}),
zone: clock.zone,
...(clock.zoneSource === 'unknown' && { zoneUnknown: true }),
now: clock.now,
dispatchedAt,
};
}
exports.timeContextOf = timeContextOf;
/**
* A received context read — the version this runtime knows, every field well
* formed — or `undefined`. What a served tool is handed from the wire; never
* repaired.
*/
function readTimeContext(value) {
if (value === null || typeof value !== 'object' || Array.isArray(value))
return undefined;
const v = value;
const keys = Object.keys(v);
if (!keys.every((k) => ['version', 'asked', 'zone', 'zoneUnknown', 'now', 'dispatchedAt'].includes(k))) {
return undefined;
}
if (v.version !== exports.TIME_CONTEXT_VERSION || !(0, zone_js_1.isZoneName)(v.zone))
return undefined;
if (v.zoneUnknown !== undefined && v.zoneUnknown !== true)
return undefined;
if ((0, instant_js_1.instantOf)(v.now, 'strict') === undefined ||
(0, instant_js_1.instantOf)(v.dispatchedAt, 'strict') === undefined) {
return undefined;
}
let asked;
if (v.asked !== undefined) {
if (v.asked === null || typeof v.asked !== 'object' || Array.isArray(v.asked))
return undefined;
const { edge, ...range } = v.asked;
if (edge !== 'exclusive' || !(0, range_js_1.isTimeRange)(range))
return undefined;
asked = { from: range.from, to: range.to, edge };
}
return {
version: exports.TIME_CONTEXT_VERSION,
...(asked !== undefined && { asked }),
zone: v.zone,
...(v.zoneUnknown === true && { zoneUnknown: true }),
now: v.now,
dispatchedAt: v.dispatchedAt,
};
}
exports.readTimeContext = readTimeContext;
//# sourceMappingURL=wire.js.map