@sema-agent/core
Version:
Stateless, task-oriented AI agent core
144 lines (143 loc) • 10.7 kB
TypeScript
/**
* 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>;