UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

115 lines (114 loc) • 8.48 kB
import type { ResolvedSkillListingBudget } from "../skill-listing-budget.js"; import { type StoredSession } from "../session.js"; import type { RunnerDeps, TaskSpec, ToolSpec } from "../types.js"; import { type SkillGrantTable, type SkillSeatReader } from "../skill-grant.js"; import { type AllowEntryTable } from "../allow-entry.js"; import type { AnnounceOnceSink, Prepared, PrepareResume, RunInternals, ToolFaceSnapshot } from "./contracts.js"; import { normalizeSkills } from "./synthetic-tools.js"; import { RosterBuilder } from "../tool-roster.js"; export interface PrepareProjectContextInput { /** borrowed-readonly — the deployment seams this phase reads: `loadProjectMemory` (the snapshot), * `onError` (the operator lane for a throwing seam / seeding / oversize skill), `sharedMemoryStores` * (the shared-memory pair's switch: wired ⇒ mount). Receiver preserved (`deps.onError?.(…)`). */ deps: Pick<RunnerDeps, "loadProjectMemory" | "onError" | "sharedMemoryStores" | "onNotice" | "allowedTools">; /** borrowed-readonly — the REBOUND spec (`spec′`). Read: `sessionId` (phase derivation + the * continuation projections), `skills` (the roster), `userInvokedSkills` (the person's invoked skills — their * rows are written here), `principal` (the shared-memory tools' trusted identity). Never mutated. */ spec: Pick<TaskSpec, "sessionId" | "skills" | "userInvokedSkills" | "principal">; /** borrowed-readonly — trusted internals: `agentName` (seam ctx), `inheritedSkillGrants` (the parent's captured * skill grant rows, seeded as `inherited`), `inheritedAllowedTools` (the parent's request entries, seeded as this leg's * own). `undefined` on a standalone prepare. */ internals: Pick<RunInternals, "agentName" | "inheritedSkillGrants" | "inheritedAllowedTools"> | undefined; /** borrowed-readonly — the request's `allowedTools`, screened and snapshotted at the config door (before the first await). */ allowedTools: readonly string[] | undefined; /** borrowed-mutable — the request's and the deployment's allow-entry tables (identity is the contract: the gate's lanes and * the delegation capture alias these objects). Seeded here, once; nothing writes them after this phase. */ allowedToolTables: { readonly request: AllowEntryTable; readonly deployment: AllowEntryTable; }; /** borrowed-readonly — the acquired session; only `getBranch()` is read (phase derivation walk). * The read is best-effort: a throw keeps the provisional phase. */ session: Pick<StoredSession, "getBranch">; /** borrowed-readonly — the acquired session's id (seam ctx cache key; operator-line context). */ sessionId: string; /** borrowed-readonly — `spec.taskId ?? sessionId`: the shared-memory tools' trusted task identity. */ hostTaskId: string; /** borrowed-readonly — the FINAL task root (post-restore): the seam's `cwd`. */ taskRootFinal: string; /** borrowed-readonly — whether a real execution env is mounted (seam ctx flag). */ handsEnabled: boolean; /** borrowed-readonly — the leg's effective-delegation facts; only `isNonForkChild` is read (the * seam's `isSubagent` — one derivation shared with the prompt fact, never re-derived here). */ delegation: { readonly isNonForkChild: boolean; }; /** borrowed-readonly — the hands phase's read-state seeding closure (CREATED there, CALLED here for * the snapshot's declared `seededFiles`); `undefined` on a hands-less task = nothing to seed. */ seedContextFiles: ((files: ReadonlyArray<{ path: string; content: string; }>) => Promise<void>) | undefined; /** borrowed-readonly — the memory phase's composed block, as returned (recall discipline + engine * files). This phase APPENDS the project layer and hands the result back as * {@link PrepareProjectContextResult.memoryBlock}; the input value itself is never mutated. */ memoryBlockFromEngine: string | undefined; /** borrowed-mutable — the run's skill grant table (identity is the contract: the `skill` tool, the gate's lane and the * ctx capture alias this exact object). Mutated here: the parent's captured rows (`inherited`) and the person's invoked * skills (`user`); after this phase only the `skill` tool writes (on activation). */ skillGrants: SkillGrantTable; /** borrowed-mutable — the run's roster builder (later refs alias its read face; in-place contract). Mutated * here: `mount` of the `skill` tool, the shared-memory pair and the engine-memory pair. Occupancy * is judged on the ALREADY-MOUNTED read face (names + aliases). */ roster: RosterBuilder; /** borrowed-readonly — the frozen task-start tool face; only `exclude` is read (pair yield ①). */ toolFaceSnapshot: Pick<ToolFaceSnapshot, "exclude">; /** borrowed-readonly — the once-per-session announcement ledger; only its deduplicated `onError` * sink is invoked (a pair's mount shape is a session-level fact, announced once). */ onceLedger: AnnounceOnceSink; /** borrowed-readonly — the memory phase's engine-pair ToolSpecs (present iff the pair may mount). */ memoryTools: ToolSpec[] | undefined; /** borrowed-readonly — the memory phase's session seat; only `!== undefined` is read (the * blocked-mount disclosure fires only when a session mounted). */ memoryEngineSession: Prepared["memoryEngineSession"]; /** borrowed-readonly — the engine pair's early conjuncts (computed before the memory phase). */ memorySearchToolsPlanned: boolean; /** borrowed-readonly — the engine-pair name the exclusion valve removed, if any (disclosure text). */ memoryPairExcludedName: string | undefined; /** borrowed-readonly — the engine-pair name a declared tool already occupies, if any (disclosure text). */ memoryPairOccupiedName: string | undefined; /** borrowed-readonly — the durable-resume carrier; read for `!== undefined` (seedAnnounced), * `seed.announcedListings.skills` (the removal-to-zero projection's gate) and `seed.skillGrants` (the frozen grant rows). */ resume: Pick<PrepareResume, "seed"> | undefined; /** borrowed-readonly — the lowered listing-budget seats from the config door. The listing projection * carries it to the boundary renderer, and the over-budget disclosure below is priced against it. */ skillListingBudget: ResolvedSkillListingBudget; } export interface PrepareProjectContextResult { /** owned — the memory block with the project layer appended at the tail (unchanged when the seam is * unwired or returns null/blank). The driver binds it under a NEW name; the defer-classification * stretch may still strip the recall-discipline segment from it. */ memoryBlock: string | undefined; /** owned — the snapshot's declared instruction sources (non-empty only), for the run loop's * instructions_change lane (`Prepared.instructionSources`). */ instructionSources: ReadonlyArray<{ path: string; contentHash: string | null; }> | undefined; /** owned — the RAW snapshot text (pre-compose) for the compaction lanes' instruction-file seat * (`Prepared.projectInstructionContent`). */ projectInstructionContent: string | undefined; /** owned — the normalized, load-gated skills (first-wins dedupe, name-sorted). Consumed inside this * phase (tool + listing); exposed as the phase's own product. */ skillSpecs: ReturnType<typeof normalizeSkills>; /** owned — the `Skill` tool's per-call seat over the loaded skills (`Execute skill: <name>`); `undefined` with no skill. */ skillSeatOf: SkillSeatReader | undefined; /** owned — the skills-listing projection the run loop's announce lane consumes (`Prepared.skillsListing`). */ skillsListing: Prepared["skillsListing"]; /** owned — whether the shared-memory pair mounted here (the support-name pre-check reads it). */ sharedMemoryPairMounted: boolean; /** owned — whether the engine-memory pair mounted here (the support-name pre-check reads it). */ memoryEnginePairMounted: boolean; } /** The M9 phase body — prepareTask's project-context stretch, verbatim (see the module header). */ export declare function prepareProjectContext(input: PrepareProjectContextInput): Promise<PrepareProjectContextResult>;