import { and, eq } from "drizzle-orm";
import { agents, heartbeatRuns, issues, projects, } from "@rudderhq/db";
import { updateExecutionObservation, updateExecutionTraceIO, updateExecutionTraceName, updateExecutionTraceSession, withExecutionObservation, } from "../../langfuse.js";
import { emitExecutionTranscriptTree } from "../../langfuse-transcript.js";
import { logger } from "../../middleware/logger.js";
import { publishLiveEvent } from "../live-events.js";
import { findServerAdapter, getServerAdapter } from "../../agent-runtimes/index.js";
import { createLocalAgentJwt } from "../../agent-auth-jwt.js";
import { parseObject } from "../../agent-runtimes/utils.js";
import { resolveDefaultAgentWorkspaceDir, } from "../../home-paths.js";
import { summarizeHeartbeatRunResultJson } from "../heartbeat-run-summary.js";
import { publishAutomationRunOutputToChat } from "../automation-chat-output.js";
import { buildWorkspaceReadyComment, cleanupExecutionWorkspaceArtifacts, ensureRuntimeServicesForRun, persistAdapterManagedRuntimeServices, realizeExecutionWorkspace, releaseRuntimeServicesForRun, } from "../workspace-runtime.js";
import { isManagedWorkspaceConfigurationError, isWorkspacePermissionPreflightError, preflightManagedAgentWorkspace, } from "../managed-workspace-preflight.js";
import { buildExecutionWorkspaceAdapterConfig, issueExecutionWorkspaceModeForPersistedWorkspace, parseIssueExecutionWorkspaceSettings, parseProjectExecutionWorkspacePolicy, resolveExecutionWorkspaceMode, } from "../execution-workspace-policy.js";
import { redactCurrentUserText } from "../../log-redaction.js";
import { buildIssueDocumentsPrompt } from "@rudderhq/agent-runtime-utils/server-utils";
import { executeAdapterWithModelFallbacks } from "./model-fallback.js";
export { prioritizeProjectWorkspaceCandidatesForRun } from "../agent-run-context.js";
import * as heartbeatCore from "./heartbeat.core.js";
import * as heartbeatSessions from "./heartbeat.sessions.js";
const { MAX_LIVE_LOG_CHUNK_BYTES, HEARTBEAT_MAX_CONCURRENT_RUNS_DEFAULT, HEARTBEAT_MAX_CONCURRENT_RUNS_MIN, HEARTBEAT_MAX_CONCURRENT_RUNS_MAX, DEFERRED_WAKE_CONTEXT_KEY, DETACHED_PROCESS_ERROR_CODE, ORPHANED_PROCESS_TERMINATION_GRACE_MS, ORPHANED_PROCESS_KILL_WAIT_MS, ORPHANED_PROCESS_POLL_INTERVAL_MS, startLocksByAgent, MAX_RECOVERY_CHAIN_DEPTH, ISSUE_PASSIVE_FOLLOWUP_REASON, ISSUE_PASSIVE_FOLLOWUP_WAKE_SOURCE, ISSUE_PASSIVE_FOLLOWUP_FAILURE_REASON, ISSUE_PASSIVE_FOLLOWUP_MAX_ATTEMPTS, ISSUE_REVIEW_CLOSEOUT_REASON, ISSUE_REVIEW_CLOSEOUT_FAILURE_REASON, ISSUE_REVIEW_CLOSEOUT_MAX_ATTEMPTS, ISSUE_PASSIVE_FOLLOWUP_COOLDOWN_MS_BY_ATTEMPT, ISSUE_PASSIVE_FOLLOWUP_TIMER_CONTINUITY_MAX_WINDOW_MS, SESSIONED_LOCAL_ADAPTERS, heartbeatRunListColumns, appendExcerpt, appendTranscriptEntriesFromChunk, normalizeMaxConcurrentRuns, withAgentStartLock, readNonEmptyString, resolveHeartbeatObservabilitySurface, buildHeartbeatObservationName, compactTraceText, buildIssueRunTraceName, buildHeartbeatRuntimeTraceMetadata, buildHeartbeatAdapterInvokePayload, buildRecentDateKeys, buildDateKeysBetween, fallbackSkillLabel, normalizeLoadedSkill, normalizeLoadedSkillForPayload, emptySkillEvidenceCounts, incrementSkillEvidenceCount, strongestSkillEvidence, resolveSkillEvidence, readSkillEvidenceFromPayload, extractSkillSlugFromPath, collectSkillPathsFromText, collectStringValues, normalizeSkillUseFromPath, dedupeSkillUses, collectSkillUsesFromText, readToolCommandInput, isCommandTranscriptTool, isReadTranscriptTool, inferUsedSkillsFromTranscript, normalizeSkillCandidate, addSkillCandidate, readSkillReferenceSlug, collectSkillReferences, inferUsedSkillsFromPrompt, normalizeLedgerBillingType, resolveLedgerBiller, normalizeBilledCostCents, resolveLedgerScopeForRun } = heartbeatCore;
const { buildExplicitResumeSessionOverride, normalizeUsageTotals, readRawUsageTotals, deriveNormalizedUsageDelta, formatCount, parseSessionCompactionPolicy, resolveRuntimeSessionParamsForWorkspace, parseIssueAssigneeAgentRuntimeOverrides, deriveTaskKey, shouldResetTaskSessionForWake, formatRuntimeWorkspaceWarningLog, describeSessionResetReason, deriveCommentId, enrichWakeContextSnapshot, mergeCoalescedContextSnapshot, issueCommentAuthorKind, issueCommentAuthorLabel, buildDeferredWakePayload, readDeferredWakeContext, readDeferredWakePayload, deriveDeferredWakeTaskKey, hydrateWakeContextSnapshot, firstNonEmptyLine, deriveRecoveryFailureKind, deriveRecoveryFailureSummary, mergeMissingRecoveryContextFields, hydrateRecoveryBaseContextSnapshot, buildRecoveryContextSnapshot, normalizePassiveFollowupContext, normalizeReviewCloseoutContext, passiveFollowupCooldownMs, issueHasReviewer, isAgentEligibleForTimerContinuation, hasCredibleTimerContinuation, buildPassiveFollowupContextSnapshot, runTaskKey, isSameTaskScope, isTrackedLocalChildProcessAdapter, isProcessAlive, waitForProcessExit, terminateOrphanedProcess, truncateDisplayId, normalizeAgentNameKey, defaultSessionCodec, getAgentRuntimeSessionCodec, normalizeSessionParams, resolveNextSessionState } = heartbeatSessions;
export function createHeartbeatExecuteHandlers(context) {
    const { db, instanceSettings, getCurrentUserRedactionOptions, runLogStore, runContextSvc, issuesSvc, documentsSvc, executionWorkspacesSvc, workspaceOperationsSvc, activeRunExecutions, budgetHooks, budgets, getAgent, getRun, getRuntimeState, getTaskSession, getLatestRunForSession, getOldestRunForSession, resolveNormalizedUsageForSession, evaluateSessionCompaction, resolveSessionBeforeForWakeup, resolveExplicitResumeSessionOverride, upsertTaskSession, clearTaskSessions, ensureRuntimeState, buildHeartbeatObservabilityContext, emitHeartbeatObservationEvent, emitHeartbeatLiveEval, setRunStatus, setWakeupStatus, updateWakeupRequestRecord, insertWakeupRequestRecord, appendRunEvent, nextRunEventSeq, persistRunProcessMetadata, clearDetachedRunWarning, enqueueRecoveryRun, enqueueProcessLossRetry, parseHeartbeatPolicy, markAgentHeartbeatChecked, evaluateTimerPreflight, runHasIssueClosureComment, runHasIssueReviewDecision, issueHasDeferredWake, passiveFollowupAlreadyRecorded, reviewerCloseoutAlreadyRecorded, issueHasConfirmedBlockedReviewerHandoff, evaluatePassiveIssueClosureForLockedIssue, countRunningRunsForAgent, claimQueuedRun, finalizeAgentStatus, reapOrphanedRuns, resumeQueuedRuns, updateRuntimeState, startNextQueuedRunForAgent, releaseIssueExecutionAndPromote, enqueueWakeup, resumeDeferredWakeupsForAgent, listProjectScopedRunIds, listProjectScopedWakeupIds, cancelPendingWakeupsForBudgetScope, cancelRunInternal, cancelActiveForAgentInternal, cancelBudgetScopeWork, retryRunInternal, buildSkillAnalytics } = context;
    async function executeRun(runId) {
        let run = await getRun(runId);
        if (!run)
            return;
        if (run.status !== "queued" && run.status !== "running")
            return;
        if (run.status === "queued") {
            const claimed = await claimQueuedRun(run);
            if (!claimed) {
                // Another worker has already claimed or finalized this run.
                return;
            }
            run = claimed;
        }
        activeRunExecutions.add(run.id);
        try {
            const agent = await getAgent(run.agentId);
            if (!agent) {
                await setRunStatus(runId, "failed", {
                    error: "Agent not found",
                    errorCode: "agent_not_found",
                    finishedAt: new Date(),
                });
                await setWakeupStatus(run.wakeupRequestId, "failed", {
                    finishedAt: new Date(),
                    error: "Agent not found",
                });
                const failedRun = await getRun(runId);
                if (failedRun)
                    await releaseIssueExecutionAndPromote(failedRun);
                return;
            }
            const heartbeatObservationContext = buildHeartbeatObservabilityContext(run, {
                runtime: agent.agentRuntimeType,
                metadata: {
                    agentName: agent.name,
                    invocationSource: run.invocationSource,
                    triggerDetail: run.triggerDetail,
                },
            });
            await withExecutionObservation(heartbeatObservationContext, {
                name: buildHeartbeatObservationName(run, agent.name),
                asType: "agent",
                input: {
                    agentId: agent.id,
                    agentName: agent.name,
                    invocationSource: run.invocationSource,
                    triggerDetail: run.triggerDetail,
                    issueId: readNonEmptyString(parseObject(run.contextSnapshot).issueId),
                },
            }, async (observation) => {
                const executionTranscript = [];
                let stdoutTranscriptBuffer = "";
                let stderrTranscriptBuffer = "";
                let stdoutTranscriptParser = null;
                let transcriptFallbackResult = null;
                let modelTurnInput;
                let finalObservationOutput = null;
                let finalObservationStatus = run.status;
                let finalObservationSessionId = heartbeatObservationContext.sessionKey ?? null;
                const runtime = await ensureRuntimeState(agent);
                const context = parseObject(run.contextSnapshot);
                delete context.rudderGitIdentity;
                const taskKey = deriveTaskKey(context, null);
                const sessionCodec = getAgentRuntimeSessionCodec(agent.agentRuntimeType);
                const issueId = readNonEmptyString(context.issueId);
                const issueContext = issueId
                    ? await db
                        .select({
                        id: issues.id,
                        identifier: issues.identifier,
                        title: issues.title,
                        description: issues.description,
                        projectId: issues.projectId,
                        projectWorkspaceId: issues.projectWorkspaceId,
                        executionWorkspaceId: issues.executionWorkspaceId,
                        executionWorkspacePreference: issues.executionWorkspacePreference,
                        assigneeAgentId: issues.assigneeAgentId,
                        assigneeAgentRuntimeOverrides: issues.assigneeAgentRuntimeOverrides,
                        executionWorkspaceSettings: issues.executionWorkspaceSettings,
                    })
                        .from(issues)
                        .where(and(eq(issues.id, issueId), eq(issues.orgId, agent.orgId)))
                        .then((rows) => rows[0] ?? null)
                    : null;
                const issueAssigneeOverrides = issueContext && issueContext.assigneeAgentId === agent.id
                    ? parseIssueAssigneeAgentRuntimeOverrides(issueContext.assigneeAgentRuntimeOverrides)
                    : null;
                const issueExecutionWorkspaceSettings = parseIssueExecutionWorkspaceSettings(issueContext?.executionWorkspaceSettings);
                const contextProjectId = readNonEmptyString(context.projectId);
                const executionProjectId = issueContext?.projectId ?? contextProjectId;
                const projectExecutionWorkspacePolicy = executionProjectId
                    ? await db
                        .select({ executionWorkspacePolicy: projects.executionWorkspacePolicy })
                        .from(projects)
                        .where(and(eq(projects.id, executionProjectId), eq(projects.orgId, agent.orgId)))
                        .then((rows) => parseProjectExecutionWorkspacePolicy(rows[0]?.executionWorkspacePolicy))
                    : null;
                const taskSession = taskKey
                    ? await getTaskSession(agent.orgId, agent.id, agent.agentRuntimeType, taskKey)
                    : null;
                const resetTaskSession = shouldResetTaskSessionForWake(context);
                const sessionResetReason = describeSessionResetReason(context);
                const taskSessionForRun = resetTaskSession ? null : taskSession;
                const explicitResumeSessionParams = normalizeSessionParams(sessionCodec.deserialize(parseObject(context.resumeSessionParams)));
                const explicitResumeSessionDisplayId = truncateDisplayId(readNonEmptyString(context.resumeSessionDisplayId) ??
                    (sessionCodec.getDisplayId ? sessionCodec.getDisplayId(explicitResumeSessionParams) : null) ??
                    readNonEmptyString(explicitResumeSessionParams?.sessionId));
                const previousSessionParams = explicitResumeSessionParams ??
                    (explicitResumeSessionDisplayId ? { sessionId: explicitResumeSessionDisplayId } : null) ??
                    normalizeSessionParams(sessionCodec.deserialize(taskSessionForRun?.sessionParamsJson ?? null));
                const config = parseObject(agent.agentRuntimeConfig);
                const executionWorkspaceMode = resolveExecutionWorkspaceMode({
                    projectPolicy: projectExecutionWorkspacePolicy,
                    issueSettings: issueExecutionWorkspaceSettings,
                    legacyUseProjectWorkspace: issueAssigneeOverrides?.useProjectWorkspace ?? null,
                });
                const resolvedWorkspace = await runContextSvc.resolveWorkspaceForRun(agent, context, previousSessionParams, { useProjectWorkspace: executionWorkspaceMode !== "agent_default" });
                const workspaceManagedConfig = buildExecutionWorkspaceAdapterConfig({
                    agentConfig: config,
                    projectPolicy: projectExecutionWorkspacePolicy,
                    issueSettings: issueExecutionWorkspaceSettings,
                    mode: executionWorkspaceMode,
                    legacyUseProjectWorkspace: issueAssigneeOverrides?.useProjectWorkspace ?? null,
                });
                const mergedConfig = issueAssigneeOverrides?.agentRuntimeConfig
                    ? { ...workspaceManagedConfig, ...issueAssigneeOverrides.agentRuntimeConfig }
                    : workspaceManagedConfig;
                const { resolvedConfig, runtimeConfig, runtimeSkillEntries, secretKeys } = await runContextSvc.prepareRuntimeConfig({
                    scene: "heartbeat",
                    agent,
                    baseConfig: mergedConfig,
                });
                heartbeatObservationContext.metadata = {
                    ...(heartbeatObservationContext.metadata ?? {}),
                    ...buildHeartbeatRuntimeTraceMetadata({
                        runtimeConfig,
                        runtimeSkills: runtimeSkillEntries,
                    }),
                };
                const issueRef = issueContext
                    ? {
                        id: issueContext.id,
                        identifier: issueContext.identifier,
                        title: issueContext.title,
                        projectId: issueContext.projectId,
                        projectWorkspaceId: issueContext.projectWorkspaceId,
                        executionWorkspaceId: issueContext.executionWorkspaceId,
                        executionWorkspacePreference: issueContext.executionWorkspacePreference,
                    }
                    : null;
                const rootObservationInput = {
                    agentId: agent.id,
                    agentName: agent.name,
                    invocationSource: run.invocationSource,
                    triggerDetail: run.triggerDetail,
                    issue: issueRef
                        ? {
                            id: issueRef.id,
                            identifier: issueRef.identifier ?? null,
                            title: issueRef.title ?? null,
                        }
                        : null,
                };
                updateExecutionObservation(observation, heartbeatObservationContext, {
                    input: rootObservationInput,
                });
                updateExecutionTraceIO(observation, { input: rootObservationInput });
                if (issueRef) {
                    updateExecutionTraceName(observation, buildIssueRunTraceName({
                        issueTitle: issueRef.title,
                        issueId: issueRef.id,
                    }));
                }
                const existingExecutionWorkspace = issueRef?.executionWorkspaceId ? await executionWorkspacesSvc.getById(issueRef.executionWorkspaceId) : null;
                const workspaceOperationRecorder = workspaceOperationsSvc.createRecorder({
                    orgId: agent.orgId,
                    heartbeatRunId: run.id,
                    executionWorkspaceId: existingExecutionWorkspace?.id ?? null,
                });
                const executionWorkspace = await realizeExecutionWorkspace({
                    base: {
                        baseCwd: resolvedWorkspace.cwd,
                        source: resolvedWorkspace.source,
                        projectId: resolvedWorkspace.projectId,
                        workspaceId: resolvedWorkspace.workspaceId,
                        repoUrl: resolvedWorkspace.repoUrl,
                        repoRef: resolvedWorkspace.repoRef,
                    },
                    config: runtimeConfig,
                    issue: issueRef,
                    agent: {
                        id: agent.id,
                        name: agent.name,
                        orgId: agent.orgId,
                    },
                    recorder: workspaceOperationRecorder,
                });
                const resolvedProjectId = executionWorkspace.projectId ?? issueRef?.projectId ?? executionProjectId ?? null;
                const resolvedProjectWorkspaceId = issueRef?.projectWorkspaceId ?? resolvedWorkspace.workspaceId ?? null;
                const shouldReuseExisting = issueRef?.executionWorkspacePreference === "reuse_existing" &&
                    existingExecutionWorkspace &&
                    existingExecutionWorkspace.status !== "archived";
                let persistedExecutionWorkspace = null;
                try {
                    persistedExecutionWorkspace = shouldReuseExisting && existingExecutionWorkspace
                        ? await executionWorkspacesSvc.update(existingExecutionWorkspace.id, {
                            cwd: executionWorkspace.cwd,
                            repoUrl: executionWorkspace.repoUrl,
                            baseRef: executionWorkspace.repoRef,
                            branchName: executionWorkspace.branchName,
                            providerType: executionWorkspace.strategy === "git_worktree" ? "git_worktree" : "local_fs",
                            providerRef: executionWorkspace.worktreePath,
                            status: "active",
                            lastUsedAt: new Date(),
                            metadata: {
                                ...(existingExecutionWorkspace.metadata ?? {}),
                                source: executionWorkspace.source,
                                createdByRuntime: executionWorkspace.created,
                            },
                        })
                        : resolvedProjectId
                            ? await executionWorkspacesSvc.create({
                                orgId: agent.orgId,
                                projectId: resolvedProjectId,
                                projectWorkspaceId: resolvedProjectWorkspaceId,
                                sourceIssueId: issueRef?.id ?? null,
                                mode: executionWorkspaceMode === "isolated_workspace"
                                    ? "isolated_workspace"
                                    : executionWorkspaceMode === "operator_branch"
                                        ? "operator_branch"
                                        : executionWorkspaceMode === "agent_default"
                                            ? "adapter_managed"
                                            : "shared_workspace",
                                strategyType: executionWorkspace.strategy === "git_worktree" ? "git_worktree" : "project_primary",
                                name: executionWorkspace.branchName ?? issueRef?.identifier ?? `workspace-${agent.id.slice(0, 8)}`,
                                status: "active",
                                cwd: executionWorkspace.cwd,
                                repoUrl: executionWorkspace.repoUrl,
                                baseRef: executionWorkspace.repoRef,
                                branchName: executionWorkspace.branchName,
                                providerType: executionWorkspace.strategy === "git_worktree" ? "git_worktree" : "local_fs",
                                providerRef: executionWorkspace.worktreePath,
                                lastUsedAt: new Date(),
                                openedAt: new Date(),
                                metadata: {
                                    source: executionWorkspace.source,
                                    createdByRuntime: executionWorkspace.created,
                                },
                            })
                            : null;
                }
                catch (error) {
                    if (executionWorkspace.created) {
                        try {
                            await cleanupExecutionWorkspaceArtifacts({
                                workspace: {
                                    id: existingExecutionWorkspace?.id ?? `transient-${run.id}`,
                                    cwd: executionWorkspace.cwd,
                                    providerType: executionWorkspace.strategy === "git_worktree" ? "git_worktree" : "local_fs",
                                    providerRef: executionWorkspace.worktreePath,
                                    branchName: executionWorkspace.branchName,
                                    repoUrl: executionWorkspace.repoUrl,
                                    baseRef: executionWorkspace.repoRef,
                                    projectId: resolvedProjectId,
                                    projectWorkspaceId: resolvedProjectWorkspaceId,
                                    sourceIssueId: issueRef?.id ?? null,
                                    metadata: {
                                        createdByRuntime: true,
                                        source: executionWorkspace.source,
                                    },
                                },
                                projectWorkspace: {
                                    cwd: resolvedWorkspace.cwd,
                                    cleanupCommand: null,
                                },
                                teardownCommand: projectExecutionWorkspacePolicy?.workspaceStrategy?.teardownCommand ?? null,
                                recorder: workspaceOperationRecorder,
                            });
                        }
                        catch (cleanupError) {
                            logger.warn({
                                runId: run.id,
                                issueId,
                                executionWorkspaceCwd: executionWorkspace.cwd,
                                cleanupError: cleanupError instanceof Error ? cleanupError.message : String(cleanupError),
                            }, "Failed to cleanup realized execution workspace after persistence failure");
                        }
                    }
                    throw error;
                }
                await workspaceOperationRecorder.attachExecutionWorkspaceId(persistedExecutionWorkspace?.id ?? null);
                if (existingExecutionWorkspace &&
                    persistedExecutionWorkspace &&
                    existingExecutionWorkspace.id !== persistedExecutionWorkspace.id &&
                    existingExecutionWorkspace.status === "active") {
                    await executionWorkspacesSvc.update(existingExecutionWorkspace.id, {
                        status: "idle",
                        cleanupReason: null,
                    });
                }
                if (issueId && persistedExecutionWorkspace) {
                    const nextIssueWorkspaceMode = issueExecutionWorkspaceModeForPersistedWorkspace(persistedExecutionWorkspace.mode);
                    const shouldSwitchIssueToExistingWorkspace = issueRef?.executionWorkspacePreference === "reuse_existing" ||
                        executionWorkspaceMode === "isolated_workspace" ||
                        executionWorkspaceMode === "operator_branch";
                    const nextIssuePatch = {};
                    if (issueRef?.executionWorkspaceId !== persistedExecutionWorkspace.id) {
                        nextIssuePatch.executionWorkspaceId = persistedExecutionWorkspace.id;
                    }
                    if (resolvedProjectWorkspaceId && issueRef?.projectWorkspaceId !== resolvedProjectWorkspaceId) {
                        nextIssuePatch.projectWorkspaceId = resolvedProjectWorkspaceId;
                    }
                    if (shouldSwitchIssueToExistingWorkspace) {
                        nextIssuePatch.executionWorkspacePreference = "reuse_existing";
                        nextIssuePatch.executionWorkspaceSettings = {
                            ...(issueExecutionWorkspaceSettings ?? {}),
                            mode: nextIssueWorkspaceMode,
                        };
                    }
                    if (Object.keys(nextIssuePatch).length > 0) {
                        await issuesSvc.update(issueId, nextIssuePatch);
                    }
                }
                if (persistedExecutionWorkspace) {
                    context.executionWorkspaceId = persistedExecutionWorkspace.id;
                    await db
                        .update(heartbeatRuns)
                        .set({
                        contextSnapshot: context,
                        updatedAt: new Date(),
                    })
                        .where(eq(heartbeatRuns.id, run.id));
                }
                const runtimeSessionResolution = resolveRuntimeSessionParamsForWorkspace({
                    orgId: agent.orgId,
                    agent,
                    previousSessionParams,
                    resolvedWorkspace: {
                        ...resolvedWorkspace,
                        cwd: resolveDefaultAgentWorkspaceDir(agent.orgId, agent),
                        source: "agent_home",
                    },
                });
                const runtimeSessionParams = runtimeSessionResolution.sessionParams;
                const runtimeWorkspaceWarnings = [
                    ...resolvedWorkspace.warnings,
                    ...executionWorkspace.warnings,
                    ...(runtimeSessionResolution.warning ? [runtimeSessionResolution.warning] : []),
                    ...(resetTaskSession && sessionResetReason
                        ? [
                            taskKey
                                ? `Skipping saved session resume for task "${taskKey}" because ${sessionResetReason}.`
                                : `Skipping saved session resume because ${sessionResetReason}.`,
                        ]
                        : []),
                ];
                const runtimeSceneContext = await runContextSvc.buildSceneContext({
                    scene: "heartbeat",
                    agent,
                    resolvedWorkspace,
                    runtimeConfig,
                    executionWorkspaceMode,
                    executionWorkspace: {
                        cwd: executionWorkspace.cwd,
                        source: executionWorkspace.source,
                        strategy: executionWorkspace.strategy,
                        projectId: executionWorkspace.projectId,
                        workspaceId: executionWorkspace.workspaceId,
                        repoUrl: executionWorkspace.repoUrl,
                        repoRef: executionWorkspace.repoRef,
                        branchName: executionWorkspace.branchName,
                        worktreePath: executionWorkspace.worktreePath,
                    },
                });
                context.rudderScene = runtimeSceneContext.rudderScene;
                context.rudderWorkspace = runtimeSceneContext.rudderWorkspace;
                context.rudderWorkspaces = runtimeSceneContext.rudderWorkspaces;
                if (runtimeSceneContext.rudderRuntimeServiceIntents) {
                    context.rudderRuntimeServiceIntents = runtimeSceneContext.rudderRuntimeServiceIntents;
                }
                else {
                    delete context.rudderRuntimeServiceIntents;
                }
                if (executionWorkspace.projectId && !readNonEmptyString(context.projectId)) {
                    context.projectId = executionWorkspace.projectId;
                }
                if (issueContext) {
                    const issueDocumentPayload = await documentsSvc.getIssueDocumentPayload({
                        id: issueContext.id,
                        description: issueContext.description,
                    });
                    const issueDocumentsPrompt = buildIssueDocumentsPrompt(issueDocumentPayload);
                    if (issueDocumentsPrompt) {
                        context.issueDocumentsPrompt = issueDocumentsPrompt;
                    }
                    else {
                        delete context.issueDocumentsPrompt;
                    }
                }
                const runtimeSessionFallback = taskKey || resetTaskSession ? null : runtime.sessionId;
                let previousSessionDisplayId = truncateDisplayId(explicitResumeSessionDisplayId ??
                    taskSessionForRun?.sessionDisplayId ??
                    (sessionCodec.getDisplayId ? sessionCodec.getDisplayId(runtimeSessionParams) : null) ??
                    readNonEmptyString(runtimeSessionParams?.sessionId) ??
                    runtimeSessionFallback);
                let runtimeSessionIdForAdapter = readNonEmptyString(runtimeSessionParams?.sessionId) ?? runtimeSessionFallback;
                let runtimeSessionParamsForAdapter = runtimeSessionParams;
                const sessionCompaction = await evaluateSessionCompaction({
                    agent,
                    sessionId: previousSessionDisplayId ?? runtimeSessionIdForAdapter,
                    issueId,
                });
                if (sessionCompaction.rotate) {
                    context.rudderSessionHandoffMarkdown = sessionCompaction.handoffMarkdown;
                    context.rudderSessionRotationReason = sessionCompaction.reason;
                    context.rudderPreviousSessionId = previousSessionDisplayId ?? runtimeSessionIdForAdapter;
                    runtimeSessionIdForAdapter = null;
                    runtimeSessionParamsForAdapter = null;
                    previousSessionDisplayId = null;
                    if (sessionCompaction.reason) {
                        runtimeWorkspaceWarnings.push(`Starting a fresh session because ${sessionCompaction.reason}.`);
                    }
                }
                else {
                    delete context.rudderSessionHandoffMarkdown;
                    delete context.rudderSessionRotationReason;
                    delete context.rudderPreviousSessionId;
                }
                const runtimeForAdapter = {
                    sessionId: runtimeSessionIdForAdapter,
                    sessionParams: runtimeSessionParamsForAdapter,
                    sessionDisplayId: previousSessionDisplayId,
                    taskKey,
                };
                let seq = 1;
                let handle = null;
                let stdoutExcerpt = "";
                let stderrExcerpt = "";
                try {
                    await preflightManagedAgentWorkspace({
                        agentHome: readNonEmptyString(runtimeSceneContext.rudderWorkspace.agentHome) ?? "",
                        instructionsDir: readNonEmptyString(runtimeSceneContext.rudderWorkspace.instructionsDir) ?? "",
                        memoryDir: readNonEmptyString(runtimeSceneContext.rudderWorkspace.memoryDir) ?? "",
                        lifeDir: readNonEmptyString(runtimeSceneContext.rudderWorkspace.lifeDir) ?? "",
                        skillsDir: readNonEmptyString(runtimeSceneContext.rudderWorkspace.agentSkillsDir) ?? "",
                    });
                    const startedAt = run.startedAt ?? new Date();
                    const runningWithSession = await db
                        .update(heartbeatRuns)
                        .set({
                        startedAt,
                        sessionIdBefore: runtimeForAdapter.sessionDisplayId ?? runtimeForAdapter.sessionId,
                        contextSnapshot: context,
                        updatedAt: new Date(),
                    })
                        .where(eq(heartbeatRuns.id, run.id))
                        .returning()
                        .then((rows) => rows[0] ?? null);
                    if (runningWithSession)
                        run = runningWithSession;
                    const runningAgent = await db
                        .update(agents)
                        .set({ status: "running", updatedAt: new Date() })
                        .where(eq(agents.id, agent.id))
                        .returning()
                        .then((rows) => rows[0] ?? null);
                    if (runningAgent) {
                        publishLiveEvent({
                            orgId: runningAgent.orgId,
                            type: "agent.status",
                            payload: {
                                agentId: runningAgent.id,
                                status: runningAgent.status,
                                outcome: "running",
                            },
                        });
                    }
                    const currentRun = run;
                    await appendRunEvent(currentRun, seq++, {
                        eventType: "lifecycle",
                        stream: "system",
                        level: "info",
                        message: "run started",
                    });
                    handle = await runLogStore.begin({
                        orgId: run.orgId,
                        agentId: run.agentId,
                        runId,
                    });
                    await db
                        .update(heartbeatRuns)
                        .set({
                        logStore: handle.store,
                        logRef: handle.logRef,
                        updatedAt: new Date(),
                    })
                        .where(eq(heartbeatRuns.id, runId));
                    const adapter = getServerAdapter(agent.agentRuntimeType);
                    stdoutTranscriptParser = adapter.parseStdoutLine ?? null;
                    const currentUserRedactionOptions = await getCurrentUserRedactionOptions();
                    const onLog = async (stream, chunk) => {
                        const sanitizedChunk = redactCurrentUserText(chunk, currentUserRedactionOptions);
                        if (stream === "stdout")
                            stdoutExcerpt = appendExcerpt(stdoutExcerpt, sanitizedChunk);
                        if (stream === "stderr")
                            stderrExcerpt = appendExcerpt(stderrExcerpt, sanitizedChunk);
                        const ts = new Date().toISOString();
                        if (handle) {
                            await runLogStore.append(handle, {
                                stream,
                                chunk: sanitizedChunk,
                                ts,
                            });
                        }
                        const payloadChunk = sanitizedChunk.length > MAX_LIVE_LOG_CHUNK_BYTES
                            ? sanitizedChunk.slice(sanitizedChunk.length - MAX_LIVE_LOG_CHUNK_BYTES)
                            : sanitizedChunk;
                        publishLiveEvent({
                            orgId: run.orgId,
                            type: "heartbeat.run.log",
                            payload: {
                                runId: run.id,
                                agentId: run.agentId,
                                ts,
                                stream,
                                chunk: payloadChunk,
                                truncated: payloadChunk.length !== sanitizedChunk.length,
                            },
                        });
                        if (stream === "stdout") {
                            stdoutTranscriptBuffer = appendTranscriptEntriesFromChunk({
                                buffer: stdoutTranscriptBuffer,
                                chunk: sanitizedChunk,
                                transcript: executionTranscript,
                                parser: stdoutTranscriptParser,
                                kind: "stdout",
                            });
                            return;
                        }
                        stderrTranscriptBuffer = appendTranscriptEntriesFromChunk({
                            buffer: stderrTranscriptBuffer,
                            chunk: sanitizedChunk,
                            transcript: executionTranscript,
                            kind: "stderr",
                        });
                    };
                    for (const warning of runtimeWorkspaceWarnings) {
                        const logEntry = formatRuntimeWorkspaceWarningLog(warning);
                        await onLog(logEntry.stream, logEntry.chunk);
                    }
                    const adapterEnv = Object.fromEntries(Object.entries(parseObject(resolvedConfig.env)).filter((entry) => typeof entry[0] === "string" && typeof entry[1] === "string"));
                    const runtimeServices = await ensureRuntimeServicesForRun({
                        db,
                        runId: run.id,
                        agent: {
                            id: agent.id,
                            name: agent.name,
                            orgId: agent.orgId,
                        },
                        issue: issueRef,
                        workspace: executionWorkspace,
                        executionWorkspaceId: persistedExecutionWorkspace?.id ?? issueRef?.executionWorkspaceId ?? null,
                        config: resolvedConfig,
                        adapterEnv,
                        onLog,
                    });
                    if (runtimeServices.length > 0) {
                        context.rudderRuntimeServices = runtimeServices;
                        context.rudderRuntimePrimaryUrl =
                            runtimeServices.find((service) => readNonEmptyString(service.url))?.url ?? null;
                        await db
                            .update(heartbeatRuns)
                            .set({
                            contextSnapshot: context,
                            updatedAt: new Date(),
                        })
                            .where(eq(heartbeatRuns.id, run.id));
                    }
                    if (issueId && (executionWorkspace.created || runtimeServices.some((service) => !service.reused))) {
                        try {
                            await issuesSvc.addComment(issueId, buildWorkspaceReadyComment({
                                workspace: executionWorkspace,
                                runtimeServices,
                            }), { agentId: agent.id });
                        }
                        catch (err) {
                            await onLog("stderr", `[rudder] Failed to post workspace-ready comment: ${err instanceof Error ? err.message : String(err)}\n`);
                        }
                    }
                    const onAdapterMeta = async (meta) => {
                        if (meta.env && secretKeys.size > 0) {
                            for (const key of secretKeys) {
                                if (key in meta.env)
                                    meta.env[key] = "***REDACTED***";
                            }
                        }
                        modelTurnInput = meta.prompt;
                        heartbeatObservationContext.metadata = {
                            ...(heartbeatObservationContext.metadata ?? {}),
                            ...buildHeartbeatRuntimeTraceMetadata({
                                runtimeConfig,
                                runtimeSkills: runtimeSkillEntries,
                                adapterMeta: meta,
                            }),
                        };
                        updateExecutionObservation(observation, heartbeatObservationContext, {
                            input: rootObservationInput,
                        });
                        await appendRunEvent(currentRun, seq++, {
                            eventType: "adapter.invoke",
                            stream: "system",
                            level: "info",
                            message: "adapter invocation",
                            payload: buildHeartbeatAdapterInvokePayload({
                                meta,
                                runtimeSkills: runtimeSkillEntries,
                            }),
                        });
                    };
                    const authToken = adapter.supportsLocalAgentJwt
                        ? createLocalAgentJwt(agent.id, agent.orgId, agent.agentRuntimeType, run.id)
                        : null;
                    if (adapter.supportsLocalAgentJwt && !authToken) {
                        logger.warn({
                            orgId: agent.orgId,
                            agentId: agent.id,
                            runId: run.id,
                            agentRuntimeType: agent.agentRuntimeType,
                        }, "local agent jwt secret missing or invalid; running without injected RUDDER_API_KEY");
                    }
                    const adapterResult = await executeAdapterWithModelFallbacks(adapter, {
                        runId: run.id,
                        agent,
                        runtime: runtimeForAdapter,
                        config: runtimeConfig,
                        context,
                        onLog,
                        onMeta: onAdapterMeta,
                        onSpawn: async (meta) => {
                            await persistRunProcessMetadata(run.id, meta);
                        },
                        authToken: authToken ?? undefined,
                    }, {
                        resolveAdapter: findServerAdapter,
                        createAuthToken: (agentRuntimeType) => createLocalAgentJwt(agent.id, agent.orgId, agentRuntimeType, run.id) ?? undefined,
                        onAttemptStart: (_attempt, attemptAdapter) => {
                            stdoutTranscriptParser = attemptAdapter.parseStdoutLine ?? null;
                        },
                    });
                    const adapterManagedRuntimeServices = adapterResult.runtimeServices
                        ? await persistAdapterManagedRuntimeServices({
                            db,
                            agentRuntimeType: agent.agentRuntimeType,
                            runId: run.id,
                            agent: {
                                id: agent.id,
                                name: agent.name,
                                orgId: agent.orgId,
                            },
                            issue: issueRef,
                            workspace: executionWorkspace,
                            reports: adapterResult.runtimeServices,
                        })
                        : [];
                    if (adapterManagedRuntimeServices.length > 0) {
                        const combinedRuntimeServices = [
                            ...runtimeServices,
                            ...adapterManagedRuntimeServices,
                        ];
                        context.rudderRuntimeServices = combinedRuntimeServices;
                        context.rudderRuntimePrimaryUrl =
                            combinedRuntimeServices.find((service) => readNonEmptyString(service.url))?.url ?? null;
                        await db
                            .update(heartbeatRuns)
                            .set({
                            contextSnapshot: context,
                            updatedAt: new Date(),
                        })
                            .where(eq(heartbeatRuns.id, run.id));
                        if (issueId) {
                            try {
                                await issuesSvc.addComment(issueId, buildWorkspaceReadyComment({
                                    workspace: executionWorkspace,
                                    runtimeServices: adapterManagedRuntimeServices,
                                }), { agentId: agent.id });
                            }
                            catch (err) {
                                await onLog("stderr", `[rudder] Failed to post adapter-managed runtime comment: ${err instanceof Error ? err.message : String(err)}\n`);
                            }
                        }
                    }
                    const nextSessionState = resolveNextSessionState({
                        codec: sessionCodec,
                        adapterResult,
                        previousParams: previousSessionParams,
                        previousDisplayId: runtimeForAdapter.sessionDisplayId,
                        previousLegacySessionId: runtimeForAdapter.sessionId,
                    });
                    const rawUsage = normalizeUsageTotals(adapterResult.usage);
                    const sessionUsageResolution = await resolveNormalizedUsageForSession({
                        agentId: agent.id,
                        runId: run.id,
                        sessionId: nextSessionState.displayId ?? nextSessionState.legacySessionId,
                        rawUsage,
                    });
                    const normalizedUsage = sessionUsageResolution.normalizedUsage;
                    let outcome;
                    const latestRun = await getRun(run.id);
                    if (latestRun?.status === "cancelled") {
                        outcome = "cancelled";
                    }
                    else if (adapterResult.timedOut) {
                        outcome = "timed_out";
                    }
                    else if ((adapterResult.exitCode ?? 0) === 0 && !adapterResult.errorMessage) {
                        outcome = "succeeded";
                    }
                    else {
                        outcome = "failed";
                    }
                    let logSummary = null;
                    if (handle) {
                        logSummary = await runLogStore.finalize(handle);
                    }
                    const status = outcome === "succeeded"
                        ? "succeeded"
                        : outcome === "cancelled"
                            ? "cancelled"
                            : outcome === "timed_out"
                                ? "timed_out"
                                : "failed";
                    heartbeatObservationContext.status = status;
                    finalObservationStatus = status;
                    finalObservationSessionId = nextSessionState.displayId ?? nextSessionState.legacySessionId ?? finalObservationSessionId;
                    const adapterResultSummary = summarizeHeartbeatRunResultJson(adapterResult.resultJson);
                    transcriptFallbackResult = {
                        ts: new Date().toISOString(),
                        model: readNonEmptyString(adapterResult.model),
                        output: readNonEmptyString(adapterResult.summary)
                            ?? readNonEmptyString(adapterResultSummary?.result)
                            ?? readNonEmptyString(adapterResultSummary?.summary)
                            ?? readNonEmptyString(adapterResultSummary?.message)
                            ?? null,
                        usage: adapterResult.usage ?? null,
                        costUsd: typeof adapterResult.costUsd === "number" ? adapterResult.costUsd : null,
                        subtype: status,
                        isError: outcome !== "succeeded",
                        errors: adapterResult.errorMessage ? [adapterResult.errorMessage] : [],
                    };
                    const usageJson = normalizedUsage || adapterResult.costUsd != null
                        ? {
                            ...(normalizedUsage ?? {}),
                            ...(rawUsage ? {
                                rawInputTokens: rawUsage.inputTokens,
                                rawCachedInputTokens: rawUsage.cachedInputTokens,
                                rawOutputTokens: rawUsage.outputTokens,
                            } : {}),
                            ...(sessionUsageResolution.derivedFromSessionTotals ? { usageSource: "session_delta" } : {}),
                            ...((nextSessionState.displayId ?? nextSessionState.legacySessionId)
                                ? { persistedSessionId: nextSessionState.displayId ?? nextSessionState.legacySessionId }
                                : {}),
                            sessionReused: runtimeForAdapter.sessionId != null || runtimeForAdapter.sessionDisplayId != null,
                            taskSessionReused: taskSessionForRun != null,
                            freshSession: runtimeForAdapter.sessionId == null && runtimeForAdapter.sessionDisplayId == null,
                            sessionRotated: sessionCompaction.rotate,
                            sessionRotationReason: sessionCompaction.reason,
                            provider: readNonEmptyString(adapterResult.provider) ?? "unknown",
                            biller: resolveLedgerBiller(adapterResult),
                            model: readNonEmptyString(adapterResult.model) ?? "unknown",
                            ...(adapterResult.costUsd != null ? { costUsd: adapterResult.costUsd } : {}),
                            billingType: normalizeLedgerBillingType(adapterResult.billingType),
                        }
                        : null;
                    await setRunStatus(run.id, status, {
                        finishedAt: new Date(),
                        error: outcome === "succeeded"
                            ? null
                            : redactCurrentUserText(adapterResult.errorMessage ?? (outcome === "timed_out" ? "Timed out" : "Adapter failed"), currentUserRedactionOptions),
                        errorCode: outcome === "timed_out"
                            ? "timeout"
                            : outcome === "cancelled"
                                ? "cancelled"
                                : outcome === "failed"
                                    ? (adapterResult.errorCode ?? "adapter_failed")
                                    : null,
                        exitCode: adapterResult.exitCode,
                        signal: adapterResult.signal,
                        usageJson,
                        resultJson: adapterResult.resultJson ?? null,
                        sessionIdAfter: nextSessionState.displayId ?? nextSessionState.legacySessionId,
                        stdoutExcerpt,
                        stderrExcerpt,
                        logBytes: logSummary?.bytes,
                        logSha256: logSummary?.sha256,
                        logCompressed: logSummary?.compressed ?? false,
                    });
                    await setWakeupStatus(run.wakeupRequestId, outcome === "succeeded" ? "completed" : status, {
                        finishedAt: new Date(),
                        error: adapterResult.errorMessage ?? null,
                    });
                    const finalizedRun = await getRun(run.id);
                    if (finalizedRun) {
                        const transcriptUsedSkills = inferUsedSkillsFromTranscript(executionTranscript);
                        if (transcriptUsedSkills.length > 0) {
                            await appendRunEvent(finalizedRun, seq++, {
                                eventType: "adapter.skill_usage",
                                stream: "system",
                                level: "info",
                                message: "skill usage inferred from transcript",
                                payload: {
                                    source: "transcript.skill_file_read",
                                    usedSkillCount: transcriptUsedSkills.length,
                                    usedSkillKeys: transcriptUsedSkills.map((entry) => entry.key),
                                    usedSkills: transcriptUsedSkills,
                                    skillEvidenceType: "used",
                                    skillEvidenceCount: transcriptUsedSkills.length,
                                    skillEvidenceKeys: transcriptUsedSkills.map((entry) => entry.key),
                                    skillEvidenceSkills: transcriptUsedSkills,
                                },
                            });
                        }
                        await appendRunEvent(finalizedRun, seq++, {
                            eventType: "lifecycle",
                            stream: "system",
                            level: outcome === "succeeded" ? "info" : "error",
                            message: `run ${outcome}`,
                            payload: {
                                status,
                                exitCode: adapterResult.exitCode,
                            },
                        });
                        await releaseIssueExecutionAndPromote(finalizedRun);
                    }
                    if (finalizedRun) {
                        await updateRuntimeState(agent, finalizedRun, adapterResult, {
                            legacySessionId: nextSessionState.legacySessionId,
                        }, normalizedUsage);
                        if (taskKey) {
                            if (adapterResult.clearSession || (!nextSessionState.params && !nextSessionState.displayId)) {
                                await clearTaskSessions(agent.orgId, agent.id, {
                                    taskKey,
                                    agentRuntimeType: agent.agentRuntimeType,
                                });
                            }
                            else {
                                await upsertTaskSession({
                                    orgId: agent.orgId,
                                    agentId: agent.id,
                                    agentRuntimeType: agent.agentRuntimeType,
                                    taskKey,
                                    sessionParamsJson: nextSessionState.params,
                                    sessionDisplayId: nextSessionState.displayId,
                                    lastRunId: finalizedRun.id,
                                    lastError: outcome === "succeeded" ? null : (adapterResult.errorMessage ?? "run_failed"),
                                });
                            }
                        }
                        await emitHeartbeatLiveEval(finalizedRun.id);
                    }
                    await finalizeAgentStatus(agent.id, outcome);
                }
                catch (err) {
                    const isWorkspacePreflightFailure = isWorkspacePermissionPreflightError(err) ||
                        isManagedWorkspaceConfigurationError(err);
                    const message = redactCurrentUserText(err instanceof Error ? err.message : "Unknown adapter failure", await getCurrentUserRedactionOptions());
                    heartbeatObservationContext.status = "failed";
                    finalObservationStatus = "failed";
                    transcriptFallbackResult = {
                        ts: new Date().toISOString(),
                        output: message,
                        subtype: "failed",
                        isError: true,
                        errors: [message],
                    };
                    logger.error({ err, runId }, "heartbeat execution failed");
                    let logSummary = null;
                    if (handle) {
                        try {
                            logSummary = await runLogStore.finalize(handle);
                        }
                        catch (finalizeErr) {
                            logger.warn({ err: finalizeErr, runId }, "failed to finalize run log after error");
                        }
                    }
                    const failedRun = await setRunStatus(run.id, "failed", {
                        error: message,
                        errorCode: isWorkspacePreflightFailure ? err.errorCode : "adapter_failed",
                        finishedAt: new Date(),
                        stdoutExcerpt,
                        stderrExcerpt,
                        logBytes: logSummary?.bytes,
                        logSha256: logSummary?.sha256,
                        logCompressed: logSummary?.compressed ?? false,
                    });
                    await setWakeupStatus(run.wakeupRequestId, "failed", {
                        finishedAt: new Date(),
                        error: message,
                    });
                    if (failedRun) {
                        await appendRunEvent(failedRun, seq++, {
                            eventType: isWorkspacePreflightFailure ? "runtime.workspace_preflight_failed" : "error",
                            stream: "system",
                            level: "error",
                            message,
                            ...(isWorkspacePreflightFailure
                                ? {
                                    payload: {
                                        errorCode: err.errorCode,
                                        failure: err.failure,
                                    },
                                }
                                : {}),
                        });
                        await releaseIssueExecutionAndPromote(failedRun);
                        if (!isWorkspacePreflightFailure) {
                            await updateRuntimeState(agent, failedRun, {
                                exitCode: null,
                                signal: null,
                                timedOut: false,
                                errorMessage: message,
                            }, {
                                legacySessionId: runtimeForAdapter.sessionId,
                            });
                            if (taskKey && (previousSessionParams || previousSessionDisplayId || taskSession)) {
                                await upsertTaskSession({
                                    orgId: agent.orgId,
                                    agentId: agent.id,
                                    agentRuntimeType: agent.agentRuntimeType,
                                    taskKey,
                                    sessionParamsJson: previousSessionParams,
                                    sessionDisplayId: previousSessionDisplayId,
                                    lastRunId: failedRun.id,
                                    lastError: message,
                                });
                            }
                        }
                        await emitHeartbeatLiveEval(failedRun.id);
                    }
                    await finalizeAgentStatus(agent.id, "failed");
                }
                finally {
                    stdoutTranscriptBuffer = appendTranscriptEntriesFromChunk({
                        buffer: stdoutTranscriptBuffer,
                        chunk: "",
                        transcript: executionTranscript,
                        parser: stdoutTranscriptParser,
                        finalize: true,
                        kind: "stdout",
                    });
                    stderrTranscriptBuffer = appendTranscriptEntriesFromChunk({
                        buffer: stderrTranscriptBuffer,
                        chunk: "",
                        transcript: executionTranscript,
                        finalize: true,
                        kind: "stderr",
                    });
                    try {
                        const transcriptStats = emitExecutionTranscriptTree({
                            context: heartbeatObservationContext,
                            parentObservation: observation,
                            transcript: executionTranscript,
                            initialTurnInput: modelTurnInput,
                            fallbackResult: transcriptFallbackResult,
                        });
                        finalObservationOutput = transcriptStats.finalOutput ?? transcriptFallbackResult?.output ?? null;
                        finalObservationSessionId = transcriptStats.finalSessionId ?? finalObservationSessionId;
                    }
                    catch (error) {
                        logger.warn({
                            runId: run.id,
                            err: error instanceof Error ? error.message : String(error),
                        }, "Failed to export heartbeat transcript tree to Langfuse");
                    }
                    await publishAutomationRunOutputToChat(db, {
                        issueId,
                        output: finalObservationOutput,
                        status: finalObservationStatus,
                        transcript: executionTranscript,
                    }).catch((error) => {
                        logger.warn({
                            runId: run.id,
                            issueId,
                            err: error instanceof Error ? error.message : String(error),
                        }, "Failed to publish automation run output to chat");
                    });
                    updateExecutionObservation(observation, heartbeatObservationContext, {
                        input: rootObservationInput,
                        output: finalObservationOutput,
                        level: finalObservationStatus === "failed" || finalObservationStatus === "timed_out" ? "ERROR" : "DEFAULT",
                        statusMessage: finalObservationStatus ?? undefined,
                    });
                    updateExecutionTraceIO(observation, {
                        input: rootObservationInput,
                        output: finalObservationOutput,
                    });
                    updateExecutionTraceSession(observation, finalObservationSessionId);
                }
            });
        }
        catch (outerErr) {
            // Setup code before adapter.execute threw (e.g. ensureRuntimeState, resolveWorkspaceForRun).
            // The inner catch did not fire, so we must record the failure here.
            const message = outerErr instanceof Error ? outerErr.message : "Unknown setup failure";
            logger.error({ err: outerErr, runId }, "heartbeat execution setup failed");
            await setRunStatus(runId, "failed", {
                error: message,
                errorCode: "adapter_failed",
                finishedAt: new Date(),
            }).catch(() => undefined);
            await setWakeupStatus(run.wakeupRequestId, "failed", {
                finishedAt: new Date(),
                error: message,
            }).catch(() => undefined);
            const failedRun = await getRun(runId).catch(() => null);
            if (failedRun) {
                // Emit a run-log event so the failure is visible in the run timeline,
                // consistent with what the inner catch block does for adapter failures.
                await appendRunEvent(failedRun, 1, {
                    eventType: "error",
                    stream: "system",
                    level: "error",
                    message,
                }).catch(() => undefined);
                await emitHeartbeatLiveEval(failedRun.id).catch(() => undefined);
                await releaseIssueExecutionAndPromote(failedRun).catch(() => undefined);
            }
            // Ensure the agent is not left stuck in "running" if the inner catch handler's
            // DB calls threw (e.g. a transient DB error in finalizeAgentStatus).
            await finalizeAgentStatus(run.agentId, "failed").catch(() => undefined);
        }
        finally {
            await releaseRuntimeServicesForRun(run.id).catch(() => undefined);
            activeRunExecutions.delete(run.id);
            await startNextQueuedRunForAgent(run.agentId);
        }
    }
    return { executeRun };
}
//# sourceMappingURL=heartbeat.execute.js.map