import type { RegisteredSkill, ResolvedSkillBody, SkillResourceRef, SkillSummary, SkillWarn } from "./types.js"; /** * Tier 2 — resolving the bodies of the skills a run has loaded. * * The bodies land in the **system prompt**, not the conversation tail, which is * the decision the rest of this module follows from. It makes them immune to * compaction (an agent cannot forget an instruction it was given the way it * forgets a message), and it puts them inside the provider's cacheable prefix — * so their order and their bytes have to be a pure function of the run's state, * or every turn pays for a cache miss on everything below them. */ /** * Resolve the bodies of the host's own skills — the ones the registry does not * hold. Batched rather than per-ref because the natural implementation is a * query, and a per-ref port turns one query into N. * * `pinnedShas` is a subset of the caller's pin map covering only these refs. A * source that can reproduce a historical body should return it; one that cannot * should return its current body and leave the drift for the caller to notice * (the resolver records what it actually resolved, never what was asked for). * Refs the source omits are dropped from the result, which is the right answer * for a skill that was deleted mid-session. */ export type ExternalSkillSource = (refs: string[], pinnedShas: Record | undefined) => Promise>; export interface ResolveActiveSkillsParams { /** The run's active refs, in whatever order the host stored them. */ activeRefs: readonly string[]; /** This run's Tier-1 catalog. A ref absent from it resolves to nothing. */ available: readonly SkillSummary[]; /** Where code refs (`platform:`) resolve from. */ registry: { get(name: string): RegisteredSkill | undefined; }; /** Where every other ref resolves from. Omit for a code-only deployment. */ externalSource?: ExternalSkillSource; /** * Ref → `contentSha` recorded by a completed run. Present = **pinned mode**: * reproduce what that run saw, for a replay, an eval, or an optimizer. * Absent = live head, which is what an ordinary turn wants — a skill edited * mid-session should take effect on the next turn. */ pinnedShas?: Record; /** * Skills resolvable by name that are **not** in the registry, consulted * before it. * * This is the isolation seam. A host may want an always-on instruction module * — an onboarding persona, a per-agent operating manual — that flows through * this one resolver alongside the standard library but must never appear in * any catalog and must never be loadable by name from a model's tool call. * Registering it globally would do both. Passing it here does neither. */ extraSkills?: ReadonlyMap; onWarn?: SkillWarn; } export interface ResolvedSkillInstructions { /** One wrapped body per resolved ref, in catalog order. */ instructions: string[]; /** Ref → the `contentSha` actually resolved. The run's pin. */ shas: Record; } /** * Wrap a resolved body for in-prompt identification. * * The wrapper is not decoration: several bodies are concatenated into one * section, and without a delimiter a model attributes an instruction from one * skill to another — or to the host's own system prompt, which is worse, * because it then applies workspace-authored text with the authority of the * platform. The attributes are what let it cite which skill it is following, * and the resource block is what tells it a Tier-3 read is available at all. */ export declare function wrapSkillContent(params: { name: string; ownerPlugin: string | null; version: number | null; body: string; resources: readonly SkillResourceRef[]; }): string; /** * Resolve the active set into instruction bodies plus the per-skill hash pin. * * Rendering order is the **catalog's** total order, never the caller's * `activeRefs` order. That argument is set/insertion order, which differs * between a fresh run that loaded A then B and a resumed run whose session * persisted `[B, A]`; since these bodies sit high in the system prompt, an * unstable order byte-shifts the prefix and busts the provider's cache for * every turn after a resume. */ export declare function resolveActiveSkillInstructions(params: ResolveActiveSkillsParams): Promise;