UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

148 lines (147 loc) • 8.84 kB
import { defaultPromptProvider, formatLocalDate, isValidTimeZone } from "../../prompts/default.js"; import { isIsolated } from "../remote-env.js"; import { readDateAnchor } from "./announce-once-ledger.js"; import { probeGitStatusLane } from "./git-status-frame.js"; import { fenceMcpServerInstructions } from "./turn-attachments.js"; const ULTRA_REASONING_TIERS = new Set(["xhigh", "max"]); import { compactionEnabled } from "../context-settings.js"; export async function preparePromptInputs(input) { const { spec, deps, failClosedReason, lockedPreflight, selfOrchestrationActive, executionEnv, reminderMark, resolvedReadFace, resolvedWriteFace, toolFaceSnapshot, promptProfile, fableMitigations, internals, thinking, ownedEnv, delegation, resolvedRole, mcp, model, externalContentTargetActive, resume, handsEnabled, taskRootFinal, additionalRootsCanonical, additionalReadRootsCanonical, sessionId, session, advertisedWritableDirs } = input; const provider = spec.promptProvider ?? deps.promptProvider ?? defaultPromptProvider; const promptPolicyEnabled = Boolean(lockedPreflight.toolPolicy); const promptHooks = spec.hooks ?? deps.hooks; const promptHooksEnabled = Boolean(promptHooks?.preToolUse || promptHooks?.postToolUse); if (failClosedReason) { deps.onError?.(new Error(failClosedReason), { phase: "config", sessionId }); } const featureFlags = { policyEnabled: promptPolicyEnabled, hooksEnabled: promptHooksEnabled, isolationEnabled: isIsolated(executionEnv), reminderMark, readFaceOpen: resolvedReadFace === "open", writeFaceOpen: resolvedWriteFace === "open", orchestrationEnabled: selfOrchestrationActive, orchestrationDeferred: selfOrchestrationActive && (toolFaceSnapshot.defer?.includes("Workflow") ?? false), promptProfile, fableMitigations, goalEnabled: internals?.goalMode === true, awarenessEnabled: thinking !== undefined && ULTRA_REASONING_TIERS.has(thinking), worktreeIsolated: internals?.isolation === "worktree" && ownedEnv !== undefined, withinTaskCompactionEnabled: compactionEnabled(spec.compaction?.enabled, input.contextOverlay) && (spec.compaction?.withinTask ?? true), isSubagent: delegation.isNonForkChild, }; const userSystemPrompt = spec.systemPrompt ?? resolvedRole.systemPrompt ?? internals?.defaultSystemPrompt; const userAppendSystemPrompt = spec.appendSystemPrompt; const mcpInstructionsBlock = mcp.serverInstructions.length ? `# MCP Server Instructions\n${mcp.serverInstructions.map((s) => fenceMcpServerInstructions(s.server, s.text)).join("\n\n")}` : undefined; const userTz = spec.clientContext?.timeZone; const tzValid = userTz !== undefined && isValidTimeZone(userTz); const dateAnchor = await readDateAnchor(session); const envFacts = { date: dateAnchor?.current?.prefixDate ?? formatLocalDate(new Date(), tzValid ? userTz : undefined), modelId: model.id }; if (tzValid) envFacts.timeZone = userTz; if (spec.clientContext?.userEmail) envFacts.userEmail = spec.clientContext.userEmail; const declaredCutoff = deps.modelKnowledgeCutoffs?.[model.id]; if (declaredCutoff) envFacts.knowledgeCutoff = declaredCutoff; if (spec.envFacts?.profile) envFacts.sandboxProfile = spec.envFacts.profile; if (spec.envFacts?.capabilities && spec.envFacts.capabilities.length > 0) envFacts.sandboxCapabilities = [...spec.envFacts.capabilities]; if (spec.envFacts?.pkgSource) envFacts.sandboxPkgSource = spec.envFacts.pkgSource; if (spec.envFacts?.egress === "none" || spec.envFacts?.egress === "allowlist" || spec.envFacts?.egress === "full") envFacts.sandboxEgress = spec.envFacts.egress; if (spec.envFacts?.scratchpadDir && advertisedWritableDirs?.verdictOf("scratchpad") !== "skipped") envFacts.scratchpadDir = spec.envFacts.scratchpadDir; if (externalContentTargetActive) envFacts.externalContentTarget = true; if (resume !== undefined && spec.envFacts?.resumeFacts) { const rf = spec.envFacts.resumeFacts; const copy = {}; if (rf.processes === "preserved" || rf.processes === "lost") copy.processes = rf.processes; if (rf.scratch === "preserved" || rf.scratch === "lost") copy.scratch = rf.scratch; if (typeof rf.note === "string" && rf.note.length > 0) copy.note = rf.note; if (Object.keys(copy).length > 0) envFacts.resumeFacts = copy; } if (handsEnabled) { envFacts.cwd = taskRootFinal; if (additionalRootsCanonical.length > 0) { envFacts.additionalDirectories = [...additionalRootsCanonical]; } if (resolvedReadFace !== undefined) envFacts.readFace = resolvedReadFace; if (resolvedWriteFace !== undefined) envFacts.writeFace = resolvedWriteFace; if (additionalReadRootsCanonical.length > 0) { envFacts.additionalReadDirectories = [...additionalReadRootsCanonical]; } try { const probe = await executionEnv.exec('uname -s; uname -r; (git rev-parse --is-inside-work-tree 2>/dev/null || echo false); (git symbolic-ref --short -q HEAD 2>/dev/null || echo "HEAD (detached)"); (git rev-parse --show-toplevel 2>/dev/null || echo); (test -n "$(git status --porcelain 2>/dev/null | head -1)" && echo dirty || echo clean); (s=$(ps -p $$ -o comm= 2>/dev/null); s=${s##*/}; echo "${s#-}"); (test "$(git rev-parse --git-dir 2>/dev/null)" != "$(git rev-parse --git-common-dir 2>/dev/null)" && echo linked || echo main); (pwd -P 2>/dev/null || pwd)', { cwd: envFacts.cwd, timeout: 10 }); if (probe.ok && probe.value.exitCode === 0) { const lines = probe.value.stdout.split("\n"); if (lines.length >= 6) { const [osName, osVer, git, branch, worktreeRoot, dirty] = lines; if (osName?.trim()) envFacts.platform = osName.trim(); if (osVer?.trim()) envFacts.osVersion = osVer.trim(); envFacts.isGitRepo = (git ?? "").trim() === "true"; if (envFacts.isGitRepo) { const b = (branch ?? "").trim(); if (b) envFacts.gitBranch = b; const root = (worktreeRoot ?? "").trim(); if (root) envFacts.gitWorktreeRoot = root; const d = (dirty ?? "").trim(); if (d === "dirty" || d === "clean") envFacts.gitDirty = d === "dirty"; } const sh = (lines[6] ?? "").trim(); if (sh) envFacts.shell = sh; if (envFacts.isGitRepo && (lines[7] ?? "").trim() === "linked") envFacts.isLinkedWorktree = true; const probedPwd = (lines[8] ?? "").trim(); if (probedPwd && envFacts.cwd && probedPwd !== envFacts.cwd) { const canonOf = async (p) => { try { const c = await executionEnv.canonicalPath(p); return c.ok ? c.value : p; } catch { return p; } }; const canonicalProbed = await canonOf(probedPwd); if (canonicalProbed !== (await canonOf(envFacts.cwd))) { try { deps.onError?.(new Error(`execution-env cwd misalignment: task root is "${envFacts.cwd}" but the env's shell reports pwd "${canonicalProbed}" — per-exec cwd injection may be ignored on this lane (execs/artifacts can land outside the workspace root)`), { phase: "config", sessionId }); } catch { } } } } } } catch { } } const gitStatusRef = await probeGitStatusLane({ executionEnv, envFacts, handsEnabled, taskRoot: taskRootFinal, onDegrade: (reason) => deps.onError?.(new Error(`env git snapshot degraded — ${reason}`), { phase: "degraded", sessionId, classification: "env-git-snapshot" }), }); return { provider, featureFlags, userSystemPrompt, userAppendSystemPrompt, mcpInstructionsBlock, envFacts, tzValid, userTz, dateAnchor, gitStatusRef }; }