agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
58 lines • 3.03 kB
TypeScript
/**
* identityKey — the conversation a pooled client belongs to, as one key.
*
* Pattern: the library's one identity encoding, never a second.
* Role: The client key is `identityNamespace` of the identity the CALLER
* named — each field through `encodeIdentityField`, the encoding the
* memory layer calls the tenant boundary. It is injective: tenant
* `acme/hr` with principal `alice` and tenant `acme` with principal
* `hr/alice` are two keys, and an absent field and a field named `_`
* are two keys. A pool is one server, so the key needs no server
* segment, and two pools never share a client.
*
* Two doors only: the run's caller identity (`ToolDispatchContext.callerIdentity`,
* `ToolExecutionContext.identity`) and the identity app code passes to `acquire`
* and `terminate`. Never tool arguments, model output, a message, a request
* body, or a `sessionId` alone. No identity value is ever written to an error,
* an event or a report: the wire carries `keyHash`, the tool-session digest.
*/
import type { McpPoolIdentity } from './options.js';
/** One conversation's key, and the coarser keys its budgets count by. */
export interface PoolKey {
/** `identityNamespace` of the identity — the client key. */
readonly key: string;
/** The tenant and principal segments — what `maxClientsPerPrincipal` counts by. */
readonly principal: string;
/** The tenant segment — always part of a shared definitions context. */
readonly tenant: string;
/** The digest the record carries in the key's place. */
readonly keyHash: string;
/** The identity itself, as a frozen copy — what the transport factory and `share` are asked with. */
readonly identity: McpPoolIdentity;
}
/** What an identity must carry. */
export interface IdentityRules {
readonly requirePrincipal: boolean;
readonly requireTenant: boolean;
}
/**
* The key for `identity`, or why there is none: `'no-identity'` when nothing was
* named (a derived identity counts as none), `'incomplete-identity'` when it
* lacks a `conversationId`, a required `principal` or a required `tenant`, or a
* field is not a string.
*/
export declare function poolKeyOf(identity: unknown, rules: IdentityRules): PoolKey | 'no-identity' | 'incomplete-identity';
/**
* Which keys a scope names. The tenant is matched exactly, always — an absent
* tenant is the absent segment, never a wildcard, because the tenant is the
* boundary. A scope that names a `conversationId` names exactly that one
* conversation (an absent principal is then the absent segment, as in the key).
* A scope without one names every conversation of its principal, and a scope
* without a principal either names every conversation of its tenant.
*/
export declare function scopeMatcher(scope: {
readonly tenant?: string;
readonly principal?: string;
readonly conversationId?: string;
}): (key: PoolKey) => boolean;
//# sourceMappingURL=identityKey.d.ts.map