UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

104 lines (103 loc) • 4.44 kB
import { GIT_STATUS_ECHO_PREVIEW } from "./git-status-frame.js"; import { wrapGitFrame } from "./git-leg-delivery.js"; import { thrownText } from "../thrown-value.js"; export function runGitLane(input) { const { prepared, queue, rs, ident, onMessageUpdate, onMessageEnd, onToolStart, onToolEnd, onTurnEnd, onTurnBoundary, runner } = input; prepared.gitStatusRef.reassert = async () => { const ref = prepared.gitStatusRef; const frame = ref.frame; if (frame === undefined) return; delete ref.mirrorOwed; const use = ref.overBudgetShrunk && frame.shrunk !== undefined ? { kind: "degraded", body: frame.shrunk.body, hash: frame.shrunk.hash } : { kind: frame.kind, body: frame.body, hash: frame.hash }; const wrapped = wrapGitFrame(use.body, prepared.reminderMark); try { const entryId = await prepared.session.appendMessage({ role: "user", content: [{ type: "text", text: wrapped }], timestamp: Date.now(), engineMinted: true, }); ref.announced = { kind: use.kind, hash: use.hash, entryId }; ref.protectedText = wrapped; if (use.kind === "full" && frame.shrunk !== undefined) { ref.wrappedShrink = { find: wrapped, replace: wrapGitFrame(frame.shrunk.body, prepared.reminderMark) }; } else { delete ref.wrappedShrink; } queue.push({ type: "steering_injected", source: "git_status", preview: GIT_STATUS_ECHO_PREVIEW[use.kind], ...ident() }); rs.attach.attachmentsInjected += 1; try { await prepared.session.appendGitAnnouncement?.({ kind: use.kind, hash: use.hash, entryId }); } catch (mirrorErr) { try { runner.deps.onError?.(new Error(`git announcement mirror write failed (frame delivered; next leg re-announces): ${thrownText(mirrorErr)}`), { phase: "degraded", sessionId: prepared.sessionId }); } catch { } } } catch (err) { ref.announced = { kind: use.kind, hash: use.hash, pending: true }; try { runner.deps.onError?.(new Error(`git status frame re-assert append failed (pending; retried at the next boundary): ${thrownText(err)}`), { phase: "degraded", sessionId: prepared.sessionId }); } catch { } } }; const flushGitMirror = async () => { const owed = prepared.gitStatusRef.mirrorOwed; if (owed === undefined) return; if (prepared.gitStatusRef.overBudgetShrunk && owed.kind === "full") { delete prepared.gitStatusRef.mirrorOwed; return; } delete prepared.gitStatusRef.mirrorOwed; try { await prepared.session.appendGitAnnouncement?.(owed); } catch (mirrorErr) { prepared.gitStatusRef.mirrorOwed = owed; try { runner.deps.onError?.(new Error(`git announcement mirror write failed (frame delivered; retried at the next serialization point): ${thrownText(mirrorErr)}`), { phase: "degraded", sessionId: prepared.sessionId }); } catch { } } }; const unsubGitRetry = prepared.harness.on("turn_boundary", async () => { await flushGitMirror(); if (prepared.gitStatusRef.announced?.pending === true) await prepared.gitStatusRef.reassert?.(); return undefined; }); const unsubBoundary = prepared.harness.on("turn_boundary", onTurnBoundary); const unsub = prepared.harness.subscribe((event) => { switch (event.type) { case "message_update": onMessageUpdate(event); break; case "message_end": onMessageEnd(event); break; case "tool_execution_start": onToolStart(event); break; case "tool_execution_end": onToolEnd(event); break; case "turn_end": onTurnEnd(); break; default: break; } }); return { flushGitMirror, unsubGitRetry, unsubBoundary, unsub }; }