UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

144 lines (143 loc) • 10.7 kB
/** * PrepareTask's PROMPT-INPUTS phase: the runtime feature flags the harness-context block gates on (so it never * claims a mechanism the task lacks), the request-body sugar's overlays (the task's role text and appended block), * the fenced MCP server-instructions * block, the environment facts (client zone + date basis, knowledge cutoff, the deployment's sandbox * axes, resume-continuity facts on a durable-resume leg only, the hands facts + the one batched env * probe with its cwd/pwd alignment guard) and the git-status lane probe. The body is moved verbatim * from the driver's own stretch; its interface is the dependency list that stretch had implicitly. * * ASYNC BY CONTENT: the stretch awaits the env probe (hands) and the git-status lane probe (always). * It sits past prepareTask's first await, so the driver's `await` adds no window a caller could reach. * * The one input computed by the DRIVER rather than read here: `failClosedReason` — the * self-orchestration fail-closed advisory's text. Its helper takes the whole `TaskSpec`/`RunnerDeps` * (it audits several deployment seats), which this phase's narrow `spec`/`deps` seats cannot satisfy * The driver evaluates the helper in the Input literal and this phase only announces * the result on the operator lane, exactly where the stretch always did. * * Nothing here throws on its own: the env probe and the alignment guard are best-effort (a stub/odd env * just omits the shell-derived facts), and the git lane degrades through `onDegrade` → `deps.onError`. */ import type { LegModBus } from "../mods/stations.js"; import type { ExecutionEnv, ThinkingLevel } from "../../internal/harness.js"; import type { Model } from "../../internal/llm.js"; import { type EnvironmentFacts } from "../../prompts/default.js"; import type { SourcedOverlay } from "../../prompt-assembly/overlay.js"; import type { ContainmentFace } from "../../tools/fs/index.js"; import type { LockedPreflight } from "../locked-config.js"; import type { MaterializedMcp } from "../mcp.js"; import type { RosterBuilder } from "../tool-roster.js"; import type { ResolvedRole } from "../roles.js"; import type { RunnerDeps, TaskSpec } from "../types.js"; import type { SessionTreeEntry } from "../../internal/harness-types.js"; import type { DateAnchorRead, PrepareResume, PromptFeatureFlags, RunInternals, ToolFaceSnapshot } from "./contracts.js"; import type { AdvertisedWritableDirs } from "./advertised-writable-dirs.js"; import { type GitStatusLaneRef } from "./git-status-frame.js"; import { type ContextWindowOverlay } from "../context-settings.js"; export interface PreparePromptInputsInput { /** borrowed-readonly — the REBOUND spec (`spec′`). Read: `systemPrompt` / `appendSystemPrompt` (handed whole to the * request-body sugar), `clientContext` (zone, email), `envFacts` (the deployment's sandbox + resume facts), * `compaction` (the within-task flag), `excludeAllTools` (the valve's whole-face switch). Never mutated. */ spec: Pick<TaskSpec, "systemPrompt" | "appendSystemPrompt" | "clientContext" | "envFacts" | "compaction" | "excludeAllTools">; /** borrowed-readonly — deployment deps: `onError` (the operator lane: fail-closed advisory, cwd misalignment, * git-lane degrade), `modelKnowledgeCutoffs`. Receiver preserved (`deps.onError?.(…)`). */ deps: Pick<RunnerDeps, "onError" | "modelKnowledgeCutoffs">; /** borrowed-readonly — the leg's mods bus (the harness-context block's "hooks may intercept" claim reads it). */ modBus: LegModBus; /** borrowed-readonly — the self-orchestration fail-closed advisory (null = nothing to announce), * evaluated by the DRIVER against the whole spec/deps (see the module header). */ failClosedReason: string | null; /** borrowed-readonly — the locked preflight; only `toolPolicy` presence is read (the policy flag). */ lockedPreflight: Pick<LockedPreflight, "toolPolicy">; /** borrowed-readonly — whether self-orchestration is ACTIVE (the same gate that mounted the * workflow tool): drives the orchestration prompt flags. */ selfOrchestrationActive: boolean; /** borrowed-readonly — the task's execution env: `isIsolated` for the isolation flag, `exec` for the * one batched probe, `canonicalPath` for the alignment guard. Never re-bound, never destroyed here. */ executionEnv: ExecutionEnv; /** borrowed-readonly — the session's reminder mark (rides the prompt facts for the declaration). */ reminderMark: string; /** borrowed-readonly — the resolved read face (the open-reads flag + the structured env fact). */ resolvedReadFace: ContainmentFace | undefined; /** borrowed-readonly — the resolved write face (the open-writes flag + the structured env fact). */ resolvedWriteFace: ContainmentFace | undefined; /** borrowed-readonly — the frozen tool face; `defer` (the Workflow short-pointer flag) and `selector` (with the spec's whole-face * switch, the valve's reading that decides which servers' instructions are taught). */ toolFaceSnapshot: Pick<ToolFaceSnapshot, "defer" | "selector">; /** borrowed-readonly — the resolved prompt profile (rides the flags to the legacy ctx). */ promptProfile: "simple" | "classic"; /** borrowed-readonly — the fable-mitigations profile axis (rides the flags with the profile). */ fableMitigations: boolean; /** borrowed-readonly — trusted internals: `goalMode` (goal flag), `isolation` (worktree flag), * `defaultSystemPrompt` (the sugar's third source). `undefined` on a standalone prepare. */ internals: Pick<RunInternals, "goalMode" | "isolation" | "defaultSystemPrompt"> | undefined; /** borrowed-readonly — the resolved, role-folded reasoning tier (the awareness flag's input). */ thinking: ThinkingLevel | undefined; /** borrowed-readonly — the factory-minted isolated env, read for PRESENCE only (the worktree flag's * belt over the fail-closed isolation guard). */ ownedEnv: ExecutionEnv | undefined; /** borrowed-readonly — the leg's effective-delegation facts; only `isNonForkChild` is read. */ delegation: { readonly isNonForkChild: boolean; }; /** borrowed-readonly — the resolved role; only its `systemPrompt` preset is read (second source). */ resolvedRole: Pick<ResolvedRole, "systemPrompt">; /** borrowed-mutable — the materialized MCP roster; `serverInstructions` (the disposed entries) and `tools` (each server's listing: did it list * any tool) are read, and the instructions lane's ledger is stated: the block is what the model is told at the run's start. */ mcp: Pick<MaterializedMcp, "serverInstructions" | "tools" | "instructionsDelta">; /** borrowed-readonly — the run's roster as the protocol-tools phase mounted it (the deployment's overlay applied, the valve not yet): * the tools the teaching answer reads, with the valve's predicate. */ roster: Pick<RosterBuilder, "tools">; /** borrowed-readonly — the resolved model (id for the env line + the cutoff lookup). */ model: Model; /** borrowed-readonly — the run's external-content-target fold (the single-source disclosure fact). */ externalContentTargetActive: boolean; /** borrowed-readonly — the durable-resume carrier, read for PRESENCE only (resume facts copy on a * resume leg and never on a fresh one). */ resume: PrepareResume | undefined; /** borrowed-readonly — whether a real execution env is mounted (the hands facts + both probes). */ handsEnabled: boolean; /** borrowed-readonly — the FINAL task root: the env `cwd` fact and the git lane's root. */ taskRootFinal: string; /** borrowed-readonly — the canonical extra working roots (copied into the env facts). */ additionalRootsCanonical: readonly string[]; /** borrowed-readonly — the canonical extra read-only roots (copied into the env facts). */ additionalReadRootsCanonical: readonly string[]; /** borrowed-readonly — the advertised-writable-directory seat (hands only). The scratchpad section is * rendered only when the seat did not SKIP the scratchpad — a directory the fence refused is not advertised. */ advertisedWritableDirs?: AdvertisedWritableDirs; /** borrowed-readonly — the acquired session's id (operator-line context). */ sessionId: string; /** borrowed-readonly — the acquired session; only `getBranch` is read (the date anchor). */ session: { getBranch(): Promise<ReadonlyArray<SessionTreeEntry>>; }; /** borrowed-readonly — the deployment's window overlay for this leg, as it reads at PREPARE. The prompt's * context-management sentence must not claim mid-task summarization a deployment has turned off for this * model; the seat is live, so a later swap's effect on the SENTENCE lands at the next prepare while its * effect on the BEHAVIOR lands at the next boundary — stated, not sworn away. */ contextOverlay?: ContextWindowOverlay; } export interface PreparePromptInputsResult { /** owned — the runtime feature flags (see {@link PromptFeatureFlags}). */ featureFlags: PromptFeatureFlags; /** owned — the request-body sugar's overlays (the task class's first contributions), in application order. */ sugar: readonly SourcedOverlay[]; /** owned — the fenced MCP server-instructions block, or undefined when no server declared any. */ mcpInstructionsBlock: string | undefined; /** owned — the environment facts the env tail renders from. Filled here; no later phase writes it * (the run loop re-renders only the date through `renderWithDate`). */ envFacts: EnvironmentFacts; /** owned — whether the client zone validated (the date-change seam re-renders in the same zone). */ tzValid: boolean; /** owned — the client's declared zone as given (paired with `tzValid`; unvalidated on its own). */ userTz: string | undefined; /** owned — the session's date anchor as read here; `envFacts.date` is its prefix date when present. */ dateAnchor: DateAnchorRead | undefined; /** owned — the git-status lane's run-local state (empty on a hands-less leg); the run loop and the checkpoint * serializer mutate its fields from here on (`announced`, `mirrorOwed`, …; the frame's receipt rides the leg's shared `Prepared.frameReceipts`). */ gitStatusRef: GitStatusLaneRef; } /** The M10 phase body — prepareTask's prompt-inputs stretch, verbatim (see the module header). */ export declare function preparePromptInputs(input: PreparePromptInputsInput): Promise<PreparePromptInputsResult>;