// SPEC: PJ2026-0104010803 Workbench唯一投影 draft-2026-06-20-p2-terminal-outbox-recovery; PJ2026-010403 API契约 draft-2026-06-20-p2-terminal-outbox-recovery; PJ2026-010205 HWLAB接入 draft-2026-06-25-p0-session-warm-runner-contract; PJ2026-0102 Agent编排 draft-2026-06-17-r0; PJ2026-01060505 Workbench Performance draft-2026-06-17-p0.
// Responsibility: Shared Code Agent HTTP lifecycle, billing, ownership, projection-read, and response helpers.

import { createHash, randomUUID } from "node:crypto";

import { M3_IO_CONTROL_ROUTE, M3_STATUS_ROUTE, describeM3StatusLive, handleM3IoControl } from "./m3-io-control.ts";
import {
  agentRunSessionEvidence,
  cancelAgentRunChatTurn,
  codeAgentAgentRunAdapterEnabled,
  initialAgentRunChatResult,
  loadPersistedAgentRunResult,
  steerAgentRunChatTurn,
  submitAgentRunChatTurn
} from "./code-agent-agentrun-adapter.ts";
import { createCodeAgentErrorPayload, handleCodeAgentChat } from "./code-agent-chat.ts";
import { defaultCodeAgentTraceStore } from "./code-agent-trace-store.ts";
import { codeAgentSessionLifecycleSummary } from "./code-agent-session-lifecycle.ts";
import { messageAuthorityTextValue } from "./code-agent-agentrun-prompt.ts";
import { recordWorkbenchSessionOwner } from "./workbench-projection-writer.ts";
import { createWorkbenchReadModel } from "./workbench-read-model.ts";
import { codeAgentOtelTraceFields, emitCodeAgentOtelSpan } from "./otel-trace.ts";
import {
  firstHeaderValue,
  getHeader,
  parsePositiveInteger,
  positiveInteger,
  readBody,
  safeConversationId,
  safeOpaqueId,
  safeSessionId,
  safeTraceId,
  sendJson,
  truthyFlag
} from "./server-http-utils.ts";

const DEFAULT_CODE_AGENT_RESULT_TRACE_EVENT_LIMIT = 120;
const DEFAULT_CODE_AGENT_TRACE_PAGE_LIMIT = 100;
const MAX_CODE_AGENT_TRACE_PAGE_LIMIT = 100;
const DEFAULT_CODE_AGENT_TURN_STATUS_REFRESH_TIMEOUT_MS = 2500;
const DEFAULT_CODE_AGENT_PROJECT_ID = "prj_hwpod_workbench";
const DEFAULT_CODE_AGENT_PROVIDER_PROFILE = "deepseek";
const CODE_AGENT_TERMINAL_STATUSES = new Set(["completed", "failed", "blocked", "timeout", "cancelled", "canceled"]);
const CODE_AGENT_PROVIDER_PROFILE_ALIASES = Object.freeze({ codex: "codex-api" });
const CODE_AGENT_PROVIDER_PROFILE_ID_PATTERN = /^[a-z0-9][a-z0-9.-]{0,63}$/u;
const CODE_AGENT_PROVIDER_PROFILE_LABELS = Object.freeze({
  "deepseek": "DeepSeek",
  "codex-api": "Codex API",
  "gpt.pika": "gpt.pika",
  "minimax-m3": "MiniMax-M3 via AgentRun",
  "runtime-default": "运行默认"
});
const DEFAULT_CODE_AGENT_CODEX_API_MODEL = "gpt-5.5";
const DEFAULT_CODE_AGENT_CODEX_API_BASE_URL = "http://127.0.0.1:49280/responses";
const DEFAULT_CODE_AGENT_DEEPSEEK_MODEL = "deepseek-chat";
const DEFAULT_CODE_AGENT_MINIMAX_M3_MODEL = "MiniMax-M3";


function normalizeCodeAgentProviderProfile(value) {
  const text = String(value ?? DEFAULT_CODE_AGENT_PROVIDER_PROFILE).trim().toLowerCase();
  if (!text) return DEFAULT_CODE_AGENT_PROVIDER_PROFILE;
  if (text === "runtime-default") return text;
  const normalized = CODE_AGENT_PROVIDER_PROFILE_ALIASES[text] ?? text;
  return CODE_AGENT_PROVIDER_PROFILE_ID_PATTERN.test(normalized) ? normalized : DEFAULT_CODE_AGENT_PROVIDER_PROFILE;
}

function firstNonEmptyValue(...values) {
  for (const value of values) {
    const text = String(value ?? "").trim();
    if (text) return text;
  }
  return null;
}

async function recordCodeAgentSessionInputFact({ params = {}, options = {}, traceId, delivery = "queue", status = "admitted", messageId = null, commandId = null, agentRun = null, error = null } = {}) {
  const runtimeStore = options.runtimeStore ?? null;
  if (typeof runtimeStore?.writeWorkbenchFacts !== "function") return null;
  const fact = buildCodeAgentSessionInputFact({ params, options, traceId, delivery, status, messageId, commandId, agentRun, error });
  if (!fact) return null;
  return runtimeStore.writeWorkbenchFacts({ facts: { inputs: [fact] } }, codeAgentSessionInputRequestMeta(fact, params, options));
}

function buildCodeAgentSessionInputFact({ params = {}, options = {}, traceId, delivery = "queue", status = "admitted", messageId = null, commandId = null, agentRun = null, error = null } = {}) {
  const resolvedTraceId = safeTraceId(traceId ?? params.traceId) || null;
  const lifecycle = codeAgentTurnLifecycleFields(resolvedTraceId, params);
  const sessionId = safeSessionId(params.sessionId ?? params.session?.sessionId) || null;
  if (!sessionId) return null;
  const resolvedMessageId = safeMessageId(messageId ?? params.messageId ?? lifecycle.userMessageId) || lifecycle.userMessageId;
  const resolvedCommandId = textValue(commandId ?? agentRun?.commandId ?? params.commandId ?? params.agentRun?.commandId) || null;
  const normalizedDelivery = codeAgentInputDelivery(delivery);
  const normalizedStatus = codeAgentInputStatus(status);
  const now = new Date().toISOString();
  const sourceEventId = `${sessionId}:${lifecycle.turnId}:${normalizedDelivery}:${resolvedTraceId ?? resolvedCommandId ?? resolvedMessageId}`;
  // Command allocation happens after the initial admitting write. Keep one stable
  // row across admitting -> blocked/failed/promoted transitions for the trace.
  const inputId = stableCodeAgentInputId({ sessionId, turnId: lifecycle.turnId, traceId: resolvedTraceId, messageId: resolvedMessageId, delivery: normalizedDelivery, sourceEventId });
  return {
    inputId,
    sessionId,
    turnId: lifecycle.turnId,
    traceId: resolvedTraceId,
    messageId: resolvedMessageId,
    commandId: resolvedCommandId,
    runId: textValue(agentRun?.runId ?? params.agentRun?.runId) || null,
    dispatchIntentId: textValue(agentRun?.dispatchIntentId ?? params.agentRun?.dispatchIntentId) || null,
    runnerJobId: textValue(agentRun?.runnerJobId ?? params.agentRun?.runnerJobId) || null,
    durableDispatch: agentRun?.durableDispatch === true || params.agentRun?.durableDispatch === true,
    delivery: normalizedDelivery,
    status: normalizedStatus,
    errorCode: textValue(error?.code ?? error?.error?.code) || null,
    sourceEventId,
    promptHash: params.message || params.prompt || params.text ? sha256Text(params.message ?? params.prompt ?? params.text).slice(0, 16) : null,
    textBytes: params.message || params.prompt || params.text ? Buffer.byteLength(String(params.message ?? params.prompt ?? params.text), "utf8") : 0,
    valuesRedacted: true,
    secretMaterialStored: false,
    createdAt: now,
    updatedAt: now
  };
}

function codeAgentSessionInputRequestMeta(fact, params = {}, options = {}) {
  return {
    sessionId: fact.sessionId,
    traceId: fact.traceId,
    turnId: fact.turnId,
    messageId: fact.messageId,
    ownerUserId: options.actor?.id ?? params.ownerUserId,
    projectId: params.projectId ?? DEFAULT_CODE_AGENT_PROJECT_ID,
    valuesPrinted: false
  };
}

function stableCodeAgentInputId(value) {
  const payload = Object.fromEntries(Object.entries(value ?? {}).filter(([, item]) => item !== undefined && item !== null && item !== "").sort(([left], [right]) => left.localeCompare(right)));
  return `wsi_${sha256Text(JSON.stringify(payload)).slice(0, 32)}`;
}

function codeAgentInputDelivery(value) {
  const text = textValue(value).toLowerCase();
  return ["queue", "steer", "cancel"].includes(text) ? text : "queue";
}

function codeAgentInputStatus(value) {
  const text = textValue(value).toLowerCase().replace(/-/gu, "_");
  return ["admitting", "admitted", "promoted", "blocked", "failed", "canceled", "completed"].includes(text) ? text : "admitted";
}

function codeAgentResultTimingFields(...sources) {
  const records = sources.filter((source) => source && typeof source === "object");
  const timingSource = records.map((source) => source.timing).find((timing) => timing && typeof timing === "object") ?? {};
  const startedAt = firstTimestampIso(timingSource.startedAt, ...records.map((source) => source.startedAt), ...records.map((source) => source.createdAt));
  const lastEventAt = firstLatestTimestampIso(timingSource.lastEventAt, ...records.map((source) => source.lastEventAt), ...records.map((source) => source.updatedAt), ...records.map((source) => source.createdAt));
  const finishedAt = firstLatestTimestampIso(timingSource.finishedAt, ...records.map((source) => source.finishedAt), ...records.map((source) => source.completedAt));
  const durationMs = numberOrNull(timingSource.durationMs ?? records.map((source) => source.durationMs).find((value) => numberOrNull(value) !== null));
  const observedAt = timestampIsoOrNull(timingSource.observedAt);
  const lastEventAgeMs = numberOrNull(timingSource.lastEventAgeMs);
  if (!startedAt && !lastEventAt && !finishedAt && durationMs === null && lastEventAgeMs === null) return {};
  const timing = {
    ...(timingSource && typeof timingSource === "object" ? timingSource : {}),
    startedAt: startedAt ?? null,
    lastEventAt: lastEventAt ?? null,
    finishedAt: finishedAt ?? null,
    durationMs,
    observedAt: observedAt ?? null,
    lastEventAgeMs,
    valuesRedacted: timingSource.valuesRedacted !== false
  };
  return {
    timing,
    startedAt: timing.startedAt,
    lastEventAt: timing.lastEventAt,
    finishedAt: timing.finishedAt,
    durationMs: timing.durationMs
  };
}

function firstTimestampIso(...values) {
  for (const value of values) {
    const timestamp = timestampIsoOrNull(value);
    if (timestamp) return timestamp;
  }
  return null;
}

function firstLatestTimestampIso(...values) {
  let latest = null;
  let latestMs = Number.NEGATIVE_INFINITY;
  for (const value of values) {
    const timestamp = timestampIsoOrNull(value);
    if (!timestamp) continue;
    const ms = Date.parse(timestamp);
    if (!Number.isFinite(ms) || ms < latestMs) continue;
    latest = timestamp;
    latestMs = ms;
  }
  return latest;
}

function codeAgentChatShortConnectionRequested(request, params, options = {}) {
  const header = firstHeaderValue(request, "prefer");
  const explicit = firstHeaderValue(request, "x-hwlab-short-connection");
  const envValue = options.env?.HWLAB_CODE_AGENT_CHAT_SHORT_CONNECTION;
  return codeAgentAgentRunAdapterEnabled(options.env ?? process.env) ||
    /(?:^|,)\s*respond-async\s*(?:,|$)/iu.test(String(header ?? "")) ||
    truthyFlag(explicit) ||
    params?.shortConnection === true ||
    truthyFlag(envValue);
}

async function preflightCodeAgentBilling({ params = {}, options = {}, traceId, response, sendResponse = true } = {}) {
  const client = options.userBillingClient;
  if (!codeAgentBillingEnabled(options) || !client?.configured || !options.userBillingAuth?.active) return null;
  const estimatedCredits = parsePositiveInteger(options.env?.HWLAB_USER_BILLING_CODE_AGENT_ESTIMATED_CREDITS, 1);
  const body = {
    ...(options.actorApiKeySecret ? { apiKey: options.actorApiKeySecret } : { userId: options.actor?.id }),
    serviceId: "hwlab-code-agent",
    estimatedCredits,
    idempotencyKey: `code-agent:${traceId}:preflight`,
    metadata: codeAgentBillingMetadata(params, traceId, { stage: "preflight" })
  };
  const result = await client.billingPreflight(body);
  if (result.ok && result.body?.allowed !== false) return { reservation: sanitizeBillingReservation(result.body) };
  const status = [402, 403, 429].includes(Number(result.status)) ? Number(result.status) : 503;
  const payload = {
    ok: false,
    accepted: false,
    status: status === 402 ? "payment_required" : status === 403 ? "not_entitled" : status === 429 ? "rate_limited" : "billing_unavailable",
    traceId,
    error: {
      code: result.error?.code ?? (status === 402 ? "insufficient_credits" : "user_billing_preflight_failed"),
      layer: "billing",
      retryable: status === 429 || status === 503,
      message: result.error?.message ?? "Code Agent billing preflight failed",
      route: "/v1/agent/chat"
    },
    blocker: {
      code: result.error?.code ?? (status === 402 ? "insufficient_credits" : "user_billing_preflight_failed"),
      layer: "billing",
      retryable: status === 429 || status === 503,
      summary: result.error?.message ?? "Code Agent billing preflight failed"
    },
    valuesRedacted: true
  };
  if (sendResponse && response) sendJson(response, status, payload);
  return { blocked: true, statusCode: status, payload, error: payload.error, blocker: payload.blocker };
}

async function recordCodeAgentBillingUsage({ payload = {}, params = {}, options = {} } = {}) {
  const reservation = params.userBillingReservation ?? payload.userBillingReservation;
  const reservationId = typeof reservation?.reservationId === "string" ? reservation.reservationId : "";
  const client = options.userBillingClient;
  if (payload.billing?.recorded === true || payload.billing?.released === true || payload.status === "running") return payload.billing ?? null;
  if (!reservationId || !client?.configured) return null;
  const traceId = safeTraceId(payload.traceId ?? params.traceId);
  const usedTokens = codeAgentUsedTokens(payload);
  const usedCredits = parsePositiveInteger(options.env?.HWLAB_USER_BILLING_CODE_AGENT_USED_CREDITS, 1);
  const result = await client.billingRecord({
    reservationId,
    serviceId: "hwlab-code-agent",
    usedCredits,
    usedTokens,
    idempotencyKey: `code-agent:${traceId}:record`,
    metadata: codeAgentBillingMetadata(params, traceId, { stage: "record", status: payload.status ?? "unknown" })
  });
  const billing = result.ok ? sanitizeBillingRecord(result.body, reservation) : {
    recorded: false,
    reservationId,
    errorCode: result.error?.code ?? "user_billing_record_failed",
    valuesRedacted: true
  };
  payload.billing = billing;
  const traceStore = options.traceStore ?? defaultCodeAgentTraceStore;
  if (traceId) {
    traceStore.append(traceId, {
      type: "billing",
      status: result.ok ? "recorded" : "degraded",
      label: result.ok ? "billing:recorded" : "billing:record_failed",
      reservationId,
      recordId: result.ok ? result.body?.recordId ?? null : null,
      errorCode: result.ok ? null : billing.errorCode,
      valuesPrinted: false
    });
  }
  return billing;
}

async function finalizeCodeAgentBillingUsage({ payload = {}, params = {}, options = {} } = {}) {
  if (payload.billing?.recorded === true || payload.billing?.released === true) return payload.billing;
  if (payload.status === "running") return null;
  if (payload.status === "completed") {
    return recordCodeAgentBillingUsage({ payload, params, options });
  }
  return releaseCodeAgentBillingReservation({ payload, params, options });
}

async function releaseCodeAgentBillingReservation({ payload = {}, params = {}, options = {} } = {}) {
  const reservation = params.userBillingReservation ?? payload.userBillingReservation;
  const reservationId = typeof reservation?.reservationId === "string" ? reservation.reservationId : "";
  const client = options.userBillingClient;
  if (payload.billing?.recorded === true || payload.billing?.released === true || !reservationId || !client?.configured) return payload.billing ?? null;
  const traceId = safeTraceId(payload.traceId ?? params.traceId);
  const releaseReason = String(payload.status ?? "not_completed").trim() || "not_completed";
  const releaseBody = {
    reservationId,
    serviceId: "hwlab-code-agent",
    idempotencyKey: `code-agent:${traceId}:release`,
    reason: releaseReason,
    metadata: codeAgentBillingMetadata(params, traceId, {
      stage: "release",
      status: payload.status ?? "unknown",
      errorCode: payload.error?.code ?? payload.blocker?.code ?? null
    })
  };
  const result = typeof client.billingRelease === "function"
    ? await client.billingRelease(releaseBody)
    : { ok: false, error: { code: "user_billing_release_not_supported" } };
  const billing = result.ok ? sanitizeBillingRelease(result.body, reservation) : {
    released: false,
    reservationId,
    errorCode: result.error?.code ?? "user_billing_release_failed",
    valuesRedacted: true
  };
  payload.billing = billing;
  const traceStore = options.traceStore ?? defaultCodeAgentTraceStore;
  if (traceId) {
    traceStore.append(traceId, {
      type: "billing",
      status: result.ok ? "released" : "degraded",
      label: result.ok ? "billing:released" : "billing:release_failed",
      reservationId,
      reason: releaseReason,
      errorCode: result.ok ? null : billing.errorCode,
      valuesPrinted: false
    });
  }
  return billing;
}

function withCodeAgentBillingReservation(payload = {}, params = {}) {
  if (!payload || typeof payload !== "object" || payload.userBillingReservation) return payload;
  const reservation = params.userBillingReservation;
  return reservation ? { ...payload, userBillingReservation: reservation } : payload;
}

function codeAgentBillingEnabled(options = {}) {
  const env = options.env ?? process.env;
  if (String(env.HWLAB_USER_BILLING_CODE_AGENT_ENABLED ?? "").trim() === "0") return false;
  return Boolean(options.userBillingClient?.configured);
}

function codeAgentBillingMetadata(params = {}, traceId, extra = {}) {
  return {
    traceId,
    conversationId: safeConversationId(params.conversationId) || null,
    sessionId: safeSessionId(params.sessionId) || null,
    projectId: textValue(params.projectId) || null,
    route: "/v1/agent/chat",
    resource: "code-agent-turn",
    ...extra,
    valuesRedacted: true
  };
}

function sanitizeBillingReservation(value = {}) {
  return {
    allowed: value.allowed === true,
    reservationId: textValue(value.reservationId) || null,
    resourceType: textValue(value.resourceType) || null,
    planId: textValue(value.planId) || null,
    estimatedCredits: Number.isFinite(Number(value.estimatedCredits)) ? Number(value.estimatedCredits) : null,
    estimatedTokens: Number.isFinite(Number(value.estimatedTokens)) ? Number(value.estimatedTokens) : null,
    expiresAt: textValue(value.expiresAt) || null,
    valuesRedacted: true
  };
}

function sanitizeBillingRecord(value = {}, reservation = {}) {
  return {
    recorded: true,
    reservationId: textValue(reservation.reservationId) || null,
    recordId: textValue(value.recordId) || null,
    credits: Number.isFinite(Number(value.credits)) ? Number(value.credits) : null,
    balance: Number.isFinite(Number(value.balance)) ? Number(value.balance) : null,
    valuesRedacted: true
  };
}

function sanitizeBillingRelease(value = {}, reservation = {}) {
  return {
    released: true,
    reservationId: textValue(value.reservationId) || textValue(reservation.reservationId) || null,
    releasedCredits: Number.isFinite(Number(value.releasedCredits)) ? Number(value.releasedCredits) : null,
    status: textValue(value.status) || "cancelled",
    valuesRedacted: true
  };
}

function codeAgentUsedTokens(payload = {}) {
  const usage = payload.usage && typeof payload.usage === "object" ? payload.usage : null;
  const traceSummary = payload.traceSummary && typeof payload.traceSummary === "object" ? payload.traceSummary : null;
  const candidates = [
    usage?.totalTokens,
    usage?.total_tokens,
    usage?.tokens,
    Number(usage?.inputTokens ?? usage?.input_tokens ?? 0) + Number(usage?.outputTokens ?? usage?.output_tokens ?? 0),
    traceSummary?.tokenCount,
    traceSummary?.tokens
  ];
  for (const value of candidates) {
    const parsed = Number(value);
    if (Number.isFinite(parsed) && parsed > 0) return Math.ceil(parsed);
  }
  return 0;
}

function normalizeTurnStatus(...values) {
  for (const value of values) {
    const text = textValue(value).toLowerCase().replace(/_/gu, "-");
    if (!text) continue;
    if (["accepted", "pending", "processing", "running", "busy", "creating", "queued", "in-flight"].includes(text)) return "running";
    if (["completed", "done", "succeeded", "success"].includes(text)) return "completed";
    if (["failed", "failure", "error", "stale", "thread-resume-failed", "aborted", "interrupted", "expired"].includes(text)) return "failed";
    if (["cancelled", "canceled"].includes(text)) return "canceled";
    if (["blocked", "timeout"].includes(text)) return text;
  }
  return null;
}

function recordCodeAgentConversationFact(payload = {}, options = {}) {
  const registry = options.sessionRegistry;
  const conversationId = safeConversationId(payload.conversationId);
  if (!conversationId || typeof registry?.recordFact !== "function") return null;
  try {
    return registry.recordFact(conversationId, {
      kind: payload.status === "completed" ? "runner_turn" : "runner_turn_terminal",
      conversationId,
      sessionId: payload.sessionId,
      traceId: payload.traceId,
      provider: payload.provider,
      backend: payload.backend,
      workspace: payload.workspace,
      sandbox: payload.sandbox,
      session: payload.session,
      sessionMode: payload.sessionMode,
      sessionReuse: payload.sessionReuse,
      implementationType: payload.implementationType,
      runner: payload.runner,
      runnerTrace: payload.runnerTrace,
      partialContext: payload.partialContext ?? payload.runnerTrace?.partialContext,
      capabilityLevel: payload.capabilityLevel,
      toolCalls: payload.toolCalls,
      skills: payload.skills
    }, { now: options.now });
  } catch {
    return null;
  }
}

async function recordCodeAgentSessionOwner({ payload = {}, params = {}, options = {}, status = "active", preserveLastTraceId = false } = {}) {
  const ownerUserId = options.actor?.id ?? params.ownerUserId;
  if (!ownerUserId || !options.accessController?.recordAgentSessionOwner) return null;
  const traceId = safeTraceId(payload.traceId ?? params.traceId);
  const session = payload.session && typeof payload.session === "object" ? payload.session : null;
  const sessionReuse = payload.sessionReuse && typeof payload.sessionReuse === "object" ? payload.sessionReuse : null;
  const sessionId = safeSessionId(payload.sessionId ?? session?.sessionId ?? sessionReuse?.sessionId ?? params.sessionId) || null;
  const conversationId = safeConversationId(payload.conversationId ?? session?.conversationId ?? sessionReuse?.conversationId ?? params.conversationId) || null;
  const threadId = safeOpaqueId(session?.threadId ?? sessionReuse?.threadId ?? payload.threadId ?? params.threadId) || null;
  return recordWorkbenchSessionOwner({
    accessController: options.accessController,
    traceId,
    ownerUserId,
    ownerRole: options.actor?.role ?? params.ownerRole ?? null,
    sessionId,
    projectId: params.projectId ?? payload.projectId ?? null,
    conversationId,
    threadId,
    status,
    preserveLastTraceId,
    session: codeAgentSessionOwnerEvidence(payload, params)
  });
}

function codeAgentOwnerStatusForResult(result = {}) {
  const sessionStatus = textValue(result?.session?.status ?? result?.sessionSummary?.status ?? result?.sessionLifecycleStatus);
  if (sessionStatus === "thread-resume-failed") return "thread-resume-failed";
  if (codeAgentFreshContinuationFailure(result)) return "thread-resume-failed";
  if (codeAgentPayloadHasSealedFinalResponse(result)) return "completed";
  if (result?.status === "completed") return "completed";
  if (result?.status === "canceled" || result?.status === "cancelled") return "canceled";
  return result?.status ?? "active";
}

function textValue(value) {
  return String(value ?? "").trim();
}

function timestampIsoOrNow(value = null) {
  const parsed = Date.parse(String(value ?? ""));
  return Number.isFinite(parsed) ? new Date(parsed).toISOString() : new Date().toISOString();
}

function timestampIsoOrNull(value = null) {
  const parsed = Date.parse(String(value ?? ""));
  return Number.isFinite(parsed) ? new Date(parsed).toISOString() : null;
}

function codeAgentSessionOwnerEvidence(payload = {}, params = {}) {
  const traceId = payload.traceId ?? params.traceId ?? null;
  const finalResponse = codeAgentFinalResponseEvidence(payload, traceId);
  const traceSummary = codeAgentTraceSummaryEvidence(payload, traceId, finalResponse);
  const messages = codeAgentConversationMessagesEvidence(payload, params, traceId, finalResponse);
  const firstUserMessagePreview = messages.find((message) => message.role === "user")?.text?.slice(0, 240) ?? null;
  const promptEvidence = codeAgentPromptMetadata(payload, params, traceId);
  const traceResult = codeAgentTraceResultEvidence(payload, params, traceId, finalResponse, traceSummary);
  const providerProfile = codeAgentProviderProfileEvidence(payload, params);
  const continuation = codeAgentContinuationEvidence(payload, params);
  const sessionLifecycleStatus = continuation.requiresFreshSession ? "thread-resume-failed" : payload.sessionLifecycleStatus ?? null;
  return {
    ...(providerProfile ? { providerProfile, codeAgentProviderProfile: providerProfile } : {}),
    provider: payload.provider ?? null,
    model: payload.model ?? null,
    backend: payload.backend ?? null,
    status: payload.status ?? null,
    sessionMode: payload.sessionMode ?? payload.session?.sessionMode ?? null,
    sessionLifecycleStatus,
    continuation,
    runnerKind: payload.runner?.kind ?? payload.runnerTrace?.runnerKind ?? null,
    conversationId: payload.conversationId ?? params.conversationId ?? null,
    sessionId: payload.sessionId ?? payload.session?.sessionId ?? payload.sessionReuse?.sessionId ?? params.sessionId ?? null,
    threadId: payload.session?.threadId ?? payload.sessionReuse?.threadId ?? payload.threadId ?? params.threadId ?? null,
    traceId,
    projectId: payload.projectId ?? params.projectId ?? null,
    ...codeAgentPromptFields(promptEvidence),
    finalResponse,
    traceSummary,
    ...(traceResult ? { traceResults: { [traceResult.traceId]: traceResult } } : {}),
    ...(messages.length ? { messages, messageCount: messages.length } : {}),
    ...(firstUserMessagePreview ? { firstUserMessagePreview } : {}),
    ...agentRunSessionEvidence(payload),
    secretMaterialStored: false,
    valuesRedacted: true
  };
}

function codeAgentContinuationEvidence(payload = {}, params = {}) {
  const failure = codeAgentFreshContinuationFailure(payload);
  const providerProfile = codeAgentProviderProfileEvidence(payload, params);
  const traceId = safeTraceId(payload.traceId ?? params.traceId) || null;
  if (!failure) {
    return {
      requiresFreshSession: false,
      providerProfile,
      traceId,
      valuesRedacted: true
    };
  }
  return {
    requiresFreshSession: true,
    reasonCode: failure.code,
    reason: failure.message,
    staleThreadId: safeOpaqueId(payload.session?.threadId ?? payload.sessionReuse?.threadId ?? payload.threadId ?? params.threadId ?? payload.agentRun?.threadId) || null,
    providerProfile,
    traceId,
    valuesRedacted: true
  };
}

function codeAgentFreshContinuationFailure(payload = {}) {
  if (!payload || typeof payload !== "object") return null;
  const sessionStatus = String(payload.session?.status ?? payload.sessionLifecycleStatus ?? payload.sessionReuse?.status ?? "").trim().toLowerCase().replace(/_/gu, "-");
  if (sessionStatus === "thread-resume-failed") return { code: "thread-resume-failed", message: "previous AgentRun thread/session resume failed", valuesRedacted: true };
  const status = normalizeTurnStatus(payload.status, payload.agentRun?.terminalStatus, payload.agentRun?.commandState, payload.agentRun?.status, payload.session?.status, payload.sessionReuse?.status);
  if (!status || !["failed", "blocked", "timeout"].includes(status)) return null;
  const code = normalizeCodeAgentFailureKind(firstNonEmptyValue(
    payload.error?.code,
    payload.blocker?.code,
    payload.providerTrace?.failureKind,
    payload.providerTrace?.errorCode,
    payload.agentRun?.failureKind,
    payload.agentRun?.errorCode,
    payload.transient?.failureKind,
    payload.transient?.errorCode
  ));
  const message = firstNonEmptyValue(
    payload.error?.message,
    payload.error?.userMessage,
    payload.blocker?.summary,
    payload.blocker?.message,
    payload.providerTrace?.failureMessage,
    payload.providerTrace?.summary,
    payload.agentRun?.failureMessage,
    payload.agentRun?.message
  ) ?? "";
  if (!codeAgentFailureRequiresFreshContinuation(code, message)) return null;
  return { code: code ?? "stale-continuation", message: message || code || "stale continuation", valuesRedacted: true };
}

function normalizeCodeAgentFailureKind(value) {
  const normalized = String(value ?? "").trim().toLowerCase().replace(/_/gu, "-");
  return normalized || null;
}

function codeAgentFailureRequiresFreshContinuation(code, message = "") {
  const failureKind = normalizeCodeAgentFailureKind(code);
  if (["thread-resume-failed", "session-store-evicted", "provider-stream-disconnected"].includes(failureKind)) return true;
  return /session stor(?:e|age).*evicted|pvc-backed session|no rollout found for thread id|no rollout found|thread\/resume failed|provider stream disconnected/iu.test(String(message ?? ""));
}

function codeAgentProviderProfileEvidence(payload = {}, params = {}) {
  const raw = firstNonEmptyValue(
    params.providerProfile,
    params.codeAgentProviderProfile,
    payload.providerProfile,
    payload.codeAgentProviderProfile,
    payload.agentRun?.backendProfile,
    payload.providerTrace?.backendProfile,
    payload.backendProfile
  );
  if (!raw) return null;
  const normalized = normalizeCodeAgentProviderProfile(raw);
  return normalized === "runtime-default" ? null : normalized;
}

function codeAgentTraceResultEvidence(payload = {}, params = {}, traceId = null, finalResponse = null, traceSummary = null) {
  const resolvedTraceId = safeTraceId(traceId);
  if (!resolvedTraceId) return null;
  const agentRun = agentRunSessionEvidence(payload).agentRun ?? null;
  const userBillingReservation = codeAgentBillingReservationEvidence(payload.userBillingReservation ?? params.userBillingReservation);
  const resultSession = payload.session && typeof payload.session === "object" ? payload.session : null;
  const sessionReuse = payload.sessionReuse && typeof payload.sessionReuse === "object" ? payload.sessionReuse : null;
  const conversationId = safeConversationId(payload.conversationId ?? agentRun?.conversationId ?? resultSession?.conversationId ?? sessionReuse?.conversationId ?? params.conversationId) || null;
  const sessionId = safeSessionId(payload.sessionId ?? resultSession?.sessionId ?? sessionReuse?.sessionId ?? params.sessionId) || null;
  const threadId = safeOpaqueId(payload.threadId ?? resultSession?.threadId ?? sessionReuse?.threadId ?? params.threadId ?? agentRun?.threadId) || null;
  const promptEvidence = codeAgentPromptMetadata(payload, params, resolvedTraceId);
  if (!agentRun && !finalResponse && !traceSummary) return null;
  return {
    traceId: resolvedTraceId,
    status: codeAgentPayloadHasSealedFinalResponse(payload) ? "completed" : payload.status ?? agentRun?.terminalStatus ?? agentRun?.commandState ?? null,
    conversationId,
    sessionId,
    threadId,
    ...codeAgentPromptFields(promptEvidence),
    messageId: finalResponse?.messageId ?? payload.messageId ?? null,
    createdAt: payload.createdAt ?? finalResponse?.createdAt ?? null,
    updatedAt: payload.updatedAt ?? finalResponse?.updatedAt ?? null,
    finalResponse,
    traceSummary,
    agentRun,
    ...(userBillingReservation ? { userBillingReservation } : {}),
    valuesRedacted: true,
    secretMaterialStored: false
  };
}

function codeAgentPromptMetadata(payload = {}, params = {}, traceId = null) {
  const prompt = payload?.prompt && typeof payload.prompt === "object" ? payload.prompt : null;
  const rawPrompt = firstNonEmptyValue(
    params.message,
    params.prompt,
    params.text,
    payload.userMessage,
    typeof payload.prompt === "string" ? payload.prompt : null
  );
  const fromText = codeAgentPromptMetadataFromText(rawPrompt, traceId, "code-agent-request", { fullText: Boolean(rawPrompt) });
  return codeAgentPromptMetadataFromParts({
    traceId,
    source: prompt?.source ?? payload.promptSource ?? fromText?.prompt?.source ?? "code-agent-request",
    promptId: firstNonEmptyValue(payload.promptId, prompt?.id, fromText?.promptId),
    promptSha256: firstNonEmptyValue(payload.promptSha256, prompt?.sha256, fromText?.promptSha256),
    promptSummary: firstNonEmptyValue(payload.promptSummary, prompt?.summary, fromText?.promptSummary),
    promptPreview: firstNonEmptyValue(payload.promptPreview, prompt?.preview, fromText?.promptPreview),
    textChars: Number.isInteger(prompt?.textChars) ? prompt.textChars : fromText?.prompt?.textChars
  });
}

function codeAgentPromptMetadataFromText(value, traceId = null, source = "code-agent-request", options = {}) {
  const promptText = String(value ?? "").trim();
  if (!promptText) return null;
  return codeAgentPromptMetadataFromParts({
    traceId,
    source,
    promptSha256: options.fullText === true ? sha256Text(promptText) : undefined,
    promptSummary: promptText,
    promptPreview: promptText,
    textChars: options.fullText === true ? promptText.length : undefined
  });
}

function codeAgentPromptMetadataFromParts({ traceId = null, source = "code-agent-request", promptId = null, promptSha256 = null, promptSummary = null, promptPreview = null, textChars = undefined } = {}) {
  const digest = firstNonEmptyValue(promptSha256);
  const summary = clippedPromptText(firstNonEmptyValue(promptSummary, promptPreview), 240);
  const preview = clippedPromptText(firstNonEmptyValue(promptPreview, promptSummary), 500);
  const explicitId = firstNonEmptyValue(promptId);
  if (!explicitId && !digest && !summary && !preview) return null;
  const id = explicitId || codeAgentPromptId(traceId, digest);
  const prompt = compactCodeAgentObject({
    id,
    sha256: digest || undefined,
    summary,
    preview,
    textChars: Number.isInteger(textChars) ? textChars : undefined,
    source,
    valuesPrinted: false
  });
  return compactCodeAgentObject({
    promptId: id,
    promptSha256: digest || undefined,
    promptSummary: summary,
    promptPreview: preview,
    prompt,
    valuesPrinted: false
  }) ?? null;
}

function codeAgentPromptFields(metadata = null) {
  if (!metadata) return {};
  return compactCodeAgentObject({
    promptId: metadata.promptId,
    promptSha256: metadata.promptSha256,
    promptSummary: metadata.promptSummary,
    promptPreview: metadata.promptPreview,
    prompt: metadata.prompt
  }) ?? {};
}

function codeAgentPromptId(traceId = null, digest = null) {
  const traceSuffix = safeTraceId(traceId)?.slice(4).replace(/[^A-Za-z0-9_.:-]/gu, "_");
  const digestSuffix = firstNonEmptyValue(digest)?.slice(0, 16);
  const suffix = firstNonEmptyValue(traceSuffix, digestSuffix);
  return suffix ? `prm_${suffix}` : undefined;
}

function clippedPromptText(value, limit) {
  const promptText = String(value ?? "").trim();
  if (!promptText) return undefined;
  return promptText.length > limit ? `${promptText.slice(0, limit)}...` : promptText;
}

function sha256Text(value) {
  return createHash("sha256").update(String(value)).digest("hex");
}

function compactCodeAgentObject(value) {
  const result = {};
  for (const [key, item] of Object.entries(value ?? {})) {
    if (item === undefined || item === null) continue;
    if (Array.isArray(item) && item.length === 0) continue;
    if (typeof item === "object" && !Array.isArray(item) && Object.keys(item).length === 0) continue;
    result[key] = item;
  }
  return Object.keys(result).length > 0 ? result : undefined;
}

function codeAgentBillingReservationEvidence(value = null) {
  if (!value || typeof value !== "object") return null;
  const reservationId = textValue(value.reservationId);
  if (!reservationId) return null;
  return {
    reservationId,
    resourceType: textValue(value.resourceType) || null,
    planId: textValue(value.planId) || null,
    estimatedCredits: numberOrNull(value.estimatedCredits),
    estimatedTokens: numberOrNull(value.estimatedTokens),
    expiresAt: textValue(value.expiresAt) || null,
    valuesRedacted: true,
    secretMaterialStored: false
  };
}

function codeAgentConversationMessagesEvidence(payload = {}, params = {}, traceId = null, finalResponse = null) {
  const userText = boundedConversationMessageText(params.message ?? params.prompt ?? payload.userMessage ?? payload.prompt);
  if (!userText) return [];
  const resolvedTraceId = safeTraceId(traceId) || null;
  const lifecycle = codeAgentTurnLifecycleFields(resolvedTraceId, payload);
  const session = payload.session && typeof payload.session === "object" ? payload.session : null;
  const sessionReuse = payload.sessionReuse && typeof payload.sessionReuse === "object" ? payload.sessionReuse : null;
  const conversationId = safeConversationId(payload.conversationId ?? session?.conversationId ?? sessionReuse?.conversationId ?? params.conversationId) || null;
  const sessionId = safeSessionId(payload.sessionId ?? session?.sessionId ?? sessionReuse?.sessionId ?? params.sessionId) || null;
  const threadId = safeOpaqueId(session?.threadId ?? sessionReuse?.threadId ?? payload.threadId ?? params.threadId) || null;
  const createdAt = payload.createdAt ?? payload.reply?.createdAt ?? new Date().toISOString();
  const updatedAt = payload.updatedAt ?? createdAt;
  const userMessage = {
    id: lifecycle.userMessageId,
    messageId: lifecycle.userMessageId,
    role: "user",
    title: "用户",
    text: userText,
    status: "sent",
    traceId: resolvedTraceId,
    turnId: lifecycle.turnId,
    conversationId,
    sessionId,
    threadId,
    createdAt,
    updatedAt,
    source: "code-agent-submit",
    secretMaterialStored: false,
    valuesRedacted: true
  };
  const agentText = boundedConversationMessageText(
    finalResponse?.text
      ?? payload.reply?.content
      ?? payload.message?.content
      ?? payload.assistantText
      ?? payload.error?.userMessage
      ?? payload.error?.message
      ?? payload.blocker?.userMessage
      ?? payload.blocker?.message
      ?? payload.blocker?.summary
  );
  const agentStatus = codeAgentConversationAgentMessageStatus(payload);
  const agentMessage = {
    id: lifecycle.assistantMessageId,
    messageId: lifecycle.assistantMessageId,
    role: "agent",
    title: agentStatus === "failed" ? "Code Agent 返回阻塞" : agentStatus === "running" ? "Code Agent 处理中" : "Code Agent 回复",
    text: agentText || (agentStatus === "running" ? "" : "Code Agent 请求已结束，请查看 Trace 详情。"),
    status: agentStatus,
    traceId: resolvedTraceId,
    turnId: lifecycle.turnId,
    conversationId,
    sessionId,
    threadId,
    createdAt: payload.reply?.createdAt ?? updatedAt,
    updatedAt,
    source: "code-agent-result",
    ...(payload.runnerTrace && typeof payload.runnerTrace === "object" ? { runnerTrace: codeAgentConversationRunnerTraceEvidence(payload.runnerTrace, resolvedTraceId) } : {}),
    secretMaterialStored: false,
    valuesRedacted: true
  };
  return [userMessage, agentMessage];
}

function boundedConversationMessageText(value, limit = 12000) {
  const text = conversationText(value);
  if (!text) return "";
  return text.length > limit ? text.slice(0, limit) : text;
}

function conversationText(value) {
  const extracted = conversationTextRaw(value).replace(/\r\n?/gu, "\n");
  if (!extracted.trim() || extracted.trim() === "[object Object]") return "";
  return extracted;
}

function conversationTextRaw(value) {
  if (value === undefined || value === null) return "";
  if (typeof value === "string") return value;
  if (typeof value === "number" || typeof value === "boolean") return String(value);
  if (Array.isArray(value)) return value.map(conversationTextRaw).filter(Boolean).join("\n");
  if (typeof value === "object") {
    for (const key of ["text", "content", "message", "prompt", "value", "summary", "preview", "title"]) {
      const text = conversationTextRaw(value[key]);
      if (text) return text;
    }
  }
  return "";
}

function codeAgentMessageTraceSuffix(traceId) {
  const text = safeTraceId(traceId) || `local_${Date.now().toString(36)}`;
  return text.replace(/^trc_/u, "").replace(/[^A-Za-z0-9_.:-]/gu, "_").slice(0, 48) || "trace";
}

function codeAgentTurnLifecycleFields(traceId, source = {}) {
  const resolvedTraceId = safeTraceId(source?.traceId ?? traceId) || safeTraceId(traceId) || null;
  const turnId = safeTurnId(source?.turnId) || resolvedTraceId;
  const traceSuffix = codeAgentMessageTraceSuffix(resolvedTraceId);
  return {
    turnId,
    userMessageId: safeMessageId(source?.userMessageId ?? source?.userMessage?.messageId) || codeAgentLifecycleMessageId(traceSuffix, "user"),
    assistantMessageId: safeMessageId(source?.assistantMessageId ?? source?.assistantMessage?.messageId) || codeAgentLifecycleMessageId(traceSuffix, "agent")
  };
}

function codeAgentLifecycleMessageId(traceSuffix, role) {
  return `msg_${traceSuffix}_${role}`;
}

function safeTurnId(value) {
  const text = textValue(value);
  return /^turn_[A-Za-z0-9_.:-]+$/u.test(text) ? text : null;
}

function safeMessageId(value) {
  const text = textValue(value);
  return /^msg_[A-Za-z0-9_.:-]+$/u.test(text) ? text : null;
}

function codeAgentConversationAgentMessageStatus(payload = {}) {
  const status = textValue(payload.status ?? payload.agentRun?.terminalStatus ?? payload.commandState ?? payload.runStatus).toLowerCase();
  if (codeAgentPayloadHasSealedFinalResponse(payload)) return "completed";
  if (["completed", "done", "success"].includes(status)) return "completed";
  if (["failed", "blocked", "error", "timeout", "canceled", "cancelled"].includes(status)) return "failed";
  if (payload.error || payload.blocker) return "failed";
  return "running";
}

function codeAgentPayloadHasSealedFinalResponse(payload = {}) {
  if (!payload || typeof payload !== "object") return false;
  if (payload.error || payload.blocker) return false;
  if (!codeAgentFinalResponseText(payload)) return false;
  const agentRun = payload.agentRun && typeof payload.agentRun === "object" ? payload.agentRun : {};
  return isTraceCommandTerminalStatus(payload.status) ||
    isTraceCommandTerminalStatus(agentRun.status) ||
    isTraceCommandTerminalStatus(agentRun.runStatus) ||
    isTraceCommandTerminalStatus(agentRun.commandState) ||
    isTraceCommandTerminalStatus(agentRun.terminalStatus);
}

function codeAgentConversationRunnerTraceEvidence(runnerTrace = {}, traceId = null) {
  const events = Array.isArray(runnerTrace.events) ? runnerTrace.events : [];
  const lastEvent = runnerTrace.lastEvent && typeof runnerTrace.lastEvent === "object" ? runnerTrace.lastEvent : events.at(-1) ?? null;
  const eventCount = Number.isFinite(Number(runnerTrace.eventCount)) ? Number(runnerTrace.eventCount) : events.length;
  return {
    traceId: safeTraceId(runnerTrace.traceId ?? traceId) || traceId || null,
    status: runnerTrace.status ?? lastEvent?.status ?? null,
    sessionId: runnerTrace.sessionId ?? null,
    threadId: runnerTrace.threadId ?? null,
    runId: runnerTrace.runId ?? lastEvent?.runId ?? null,
    commandId: runnerTrace.commandId ?? lastEvent?.commandId ?? null,
    eventCount,
    lastEvent: lastEvent ? {
      label: lastEvent.label ?? null,
      status: lastEvent.status ?? null,
      terminal: lastEvent.terminal === true,
      createdAt: lastEvent.createdAt ?? null,
      message: boundedConversationMessageText(lastEvent.message ?? lastEvent.text, 1000),
      valuesPrinted: false
    } : null,
    eventsCompacted: true,
    fullTraceLoaded: false,
    valuesPrinted: false
  };
}

function codeAgentFinalResponseEvidence(payload = {}, traceId = null) {
  const text = codeAgentFinalResponseText(payload);
  if (!text) return null;
  return {
    text,
    textChars: text.length,
    messageId: payload.finalResponse?.messageId ?? payload.reply?.messageId ?? payload.messageId ?? null,
    role: payload.reply?.role ?? payload.message?.role ?? "assistant",
    status: codeAgentPayloadHasSealedFinalResponse(payload) ? "completed" : payload.finalResponse?.status ?? payload.status ?? null,
    traceId,
    createdAt: payload.finalResponse?.createdAt ?? payload.reply?.createdAt ?? payload.createdAt ?? null,
    updatedAt: payload.finalResponse?.updatedAt ?? payload.updatedAt ?? null,
    source: payload.finalResponse?.source ?? "code-agent-result",
    valuesPrinted: false
  };
}

function codeAgentFinalResponseText(payload = {}) {
  for (const value of [
    payload?.finalResponse?.text,
    payload?.finalResponse?.content,
    payload?.finalResponse,
    payload?.reply?.content,
    payload?.reply,
    payload?.message?.content,
    payload?.message,
    payload?.assistantText,
    payload?.finalText,
    payload?.text,
    payload?.content
  ]) {
    const text = conversationText(value);
    if (text) return text;
  }
  return "";
}

function codeAgentTraceSummaryEvidence(payload = {}, traceId = null, finalResponse = null) {
  const runnerTrace = payload.runnerTrace && typeof payload.runnerTrace === "object" ? payload.runnerTrace : null;
  const events = Array.isArray(runnerTrace?.events) ? runnerTrace.events : [];
  const terminalEvent = [...events].reverse().find((event) => event?.terminal === true) ?? runnerTrace?.lastEvent ?? null;
  return {
    traceId,
    source: "code-agent-derived-session-evidence",
    sourceEventCount: Number.isFinite(Number(runnerTrace?.eventCount)) ? Number(runnerTrace.eventCount) : events.length,
    terminalStatus: payload.agentRun?.terminalStatus ?? payload.status ?? terminalEvent?.status ?? null,
    lastEventLabel: terminalEvent?.label ?? null,
    finalAssistantRow: finalResponse ? {
      role: finalResponse.role,
      status: finalResponse.status,
      textChars: finalResponse.textChars,
      textPreview: finalResponse.text.slice(0, 240),
      messageId: finalResponse.messageId,
      valuesPrinted: false
    } : null,
    agentRun: payload.agentRun ? {
      runId: payload.agentRun.runId ?? null,
      commandId: payload.agentRun.commandId ?? null,
      attemptId: payload.agentRun.attemptId ?? null,
      runnerId: payload.agentRun.runnerId ?? null,
      jobName: payload.agentRun.jobName ?? null,
      namespace: payload.agentRun.namespace ?? null,
      lastSeq: payload.agentRun.lastSeq ?? null,
      valuesPrinted: false
    } : null,
    updatedAt: payload.updatedAt ?? null,
    valuesPrinted: false
  };
}

function annotateOwner(payload, params = {}) {
  if (!params.ownerUserId) return payload;
  return {
    ...payload,
    ownerUserId: params.ownerUserId,
    ownerRole: params.ownerRole ?? null
  };
}

function canAccessOwnedResult(result, actor) {
  if (!result?.ownerUserId || !actor) return true;
  return actor.role === "admin" || actor.id === result.ownerUserId;
}

function isCodeAgentResultCanceled(result) {
  return result?.status === "canceled" || result?.canceled === true || result?.error?.code === "codex_stdio_canceled";
}

function codeAgentCancelScopeMismatch(params = {}, result = {}) {
  return cancelScopeFieldMismatch("conversationId", safeConversationId(params.conversationId), cancelExpectedValues(safeConversationId,
    result.conversationId,
    result.agentRun?.conversationId,
    result.session?.conversationId,
    result.sessionReuse?.conversationId,
    result.runnerTrace?.conversationId
  )) ?? cancelScopeFieldMismatch("sessionId", safeSessionId(params.sessionId), cancelExpectedValues(safeSessionId,
    result.sessionId,
    result.session?.sessionId,
    result.sessionReuse?.sessionId,
    result.agentRun?.hwlabSessionId
  )) ?? cancelScopeFieldMismatch("threadId", safeOpaqueId(params.threadId), cancelExpectedValues(safeOpaqueId,
    result.threadId,
    result.agentRun?.threadId,
    result.session?.threadId,
    result.sessionReuse?.threadId,
    result.runnerTrace?.threadId
  ));
}

function cancelExpectedValues(normalize, ...values) {
  return [...new Set(values.map((value) => normalize(value)).filter(Boolean))];
}

function cancelScopeFieldMismatch(field, requested, expectedValues) {
  if (!requested || expectedValues.length === 0 || expectedValues.includes(requested)) return null;
  return { field, requested, expected: expectedValues[0] };
}

function cancelBlockedPayload({
  code,
  message,
  traceId,
  conversationId = null,
  sessionId = null,
  session = null,
  runnerTrace = null,
  status = "failed",
  unsupported = false,
  degraded = false
}) {
  const sessionSummary = codeAgentSessionLifecycleSummary({
    session,
    runnerTrace,
    status,
    unsupported,
    degraded,
    error: { code, userMessage: message, message }
  });
  return {
    accepted: false,
    canceled: false,
    status,
    conversationId,
    sessionId,
    traceId,
    session,
    sessionLifecycleStatus: sessionSummary.status,
    sessionLifecycle: sessionSummary,
    sessionSummary,
    unsupported,
    degraded,
    runnerTrace,
    lastTraceEvent: runnerTrace?.lastEvent ?? null,
    error: {
      code,
      layer: "session",
      category: "cancel_blocked",
      retryable: true,
      userMessage: message,
      message,
      traceId,
      route: "/v1/agent/chat/cancel",
      toolName: "codex-stdio.cancel"
    },
    blocker: {
      code,
      layer: "session",
      category: "cancel_blocked",
      retryable: true,
      summary: message,
      userMessage: message,
      traceId,
      route: "/v1/agent/chat/cancel",
      toolName: "codex-stdio.cancel"
    }
  };
}

function isTraceCommandTerminalStatus(status) {
  return CODE_AGENT_TERMINAL_STATUSES.has(String(status ?? "").trim().toLowerCase().replace(/_/gu, "-"));
}

function traceSnapshotWithTerminalEvidence(snapshot, result, traceId, refreshError = null) {
  const evidence = agentRunTerminalTraceEvidence(result, traceId);
  if (snapshot && snapshot.status !== "missing") return traceSnapshotWithAttachedTerminalEvidence(snapshot, evidence, refreshError);
  if (!evidence) return {
    ...snapshot,
    ok: false,
    traceStatus: "missing",
    retention: traceRetentionSummary("missing")
  };
  return {
    ...snapshot,
    ok: true,
    status: "expired",
    traceStatus: "expired",
    projectionStatus: "projecting",
    projectionHealth: "degraded",
    persisted: true,
    retention: traceRetentionSummary("expired"),
    conversationId: evidence.conversationId,
    sessionId: evidence.sessionId,
    threadId: evidence.threadId,
    ...codeAgentPromptFields(evidence),
    agentRun: evidence.agentRun,
    finalResponse: evidence.finalResponse,
    traceSummary: evidence.traceSummary,
    terminalEvidence: {
      available: true,
      source: evidence.source,
      refresh: refreshError ? {
        attempted: true,
        ok: false,
        code: refreshError?.code ?? "agentrun_trace_refresh_failed",
        message: refreshError?.message ?? "AgentRun trace events could not be refreshed; command result remains authoritative for final response.",
        valuesPrinted: false
      } : { attempted: false, ok: null },
      conversationId: evidence.conversationId,
      sessionId: evidence.sessionId,
      threadId: evidence.threadId,
      ...codeAgentPromptFields(evidence),
      agentRun: evidence.agentRun,
      traceSummary: evidence.traceSummary,
      finalResponse: evidence.finalResponse,
      valuesPrinted: false
    }
  };
}

function traceSnapshotWithAttachedTerminalEvidence(snapshot, evidence, refreshError = null) {
  if (!evidence) return snapshot;
  return {
    ...snapshot,
    conversationId: snapshot.conversationId ?? evidence.conversationId,
    sessionId: snapshot.sessionId ?? evidence.sessionId,
    threadId: snapshot.threadId ?? evidence.threadId,
    ...codeAgentPromptFields(evidence),
    agentRun: snapshot.agentRun ?? evidence.agentRun,
    finalResponse: snapshot.finalResponse ?? evidence.finalResponse,
    traceSummary: snapshot.traceSummary ?? evidence.traceSummary,
    terminalEvidence: snapshot.terminalEvidence ?? (refreshError ? {
      available: true,
      source: evidence.source,
      refresh: {
        attempted: true,
        ok: false,
        code: refreshError?.code ?? "agentrun_trace_refresh_failed",
        message: refreshError?.message ?? "AgentRun trace events could not be refreshed; live events may be partial.",
        valuesPrinted: false
      },
      valuesPrinted: false
    } : undefined)
  };
}

function agentRunTerminalTraceEvidence(result, traceId) {
  if (!result || typeof result !== "object") return null;
  const storedSummary = result.traceSummary && typeof result.traceSummary === "object" && result.traceSummary.source === "agentrun-command-result" ? result.traceSummary : null;
  const finalResponse = agentRunTerminalFinalResponse(result, traceId);
  const promptEvidence = codeAgentPromptMetadata(result, {}, traceId);
  const agentRun = result.agentRun && typeof result.agentRun === "object" ? {
    adapter: result.agentRun.adapter ?? null,
    runId: result.agentRun.runId ?? null,
    commandId: result.agentRun.commandId ?? null,
    attemptId: result.agentRun.attemptId ?? null,
    runnerId: result.agentRun.runnerId ?? null,
    jobName: result.agentRun.jobName ?? null,
    namespace: result.agentRun.namespace ?? null,
    terminalStatus: result.agentRun.terminalStatus ?? null,
    lastSeq: result.agentRun.lastSeq ?? null,
    valuesPrinted: false
  } : null;
  const terminalStatus = normalizeTurnStatus(result.agentRun?.terminalStatus, result.agentRun?.commandState, result.agentRun?.status, result.agentRun?.runStatus);
  if (!isTraceCommandTerminalStatus(terminalStatus)) return null;
  if (!agentRun?.runId || !agentRun?.commandId || (!storedSummary && !finalResponse)) return null;
  const traceSummary = {
    traceId,
    source: "agentrun-command-result",
    sourceEventCount: numberOrNull(storedSummary?.sourceEventCount ?? storedSummary?.eventCount ?? result.runnerTrace?.eventCount),
    renderedRowSummary: storedSummary?.renderedRowSummary ?? null,
    noiseEventCount: numberOrNull(storedSummary?.noiseEventCount),
    omittedNoiseCount: numberOrNull(storedSummary?.omittedNoiseCount),
    terminalStatus: storedSummary?.terminalStatus ?? terminalStatus,
    updatedAt: storedSummary?.updatedAt ?? result.updatedAt ?? null,
    valuesPrinted: false
  };
  return {
    source: "agentrun-command-result",
    conversationId: safeConversationId(result.conversationId) || null,
    sessionId: safeSessionId(result.sessionId) || null,
    threadId: safeOpaqueId(result.threadId) || null,
    ...codeAgentPromptFields(promptEvidence),
    agentRun,
    finalResponse,
    traceSummary
  };
}

function agentRunTerminalFinalResponse(result, traceId) {
  const stored = result.finalResponse && typeof result.finalResponse === "object" ? result.finalResponse : null;
  const text = textValue(stored?.text ?? result.reply?.content ?? result.message?.content ?? result.assistantText);
  if (!text) return null;
  const storedTraceId = safeTraceId(stored?.traceId ?? result.traceId) || null;
  if (storedTraceId && storedTraceId !== traceId) return null;
  return {
    text,
    textChars: text.length,
    messageId: stored?.messageId ?? result.reply?.messageId ?? result.messageId ?? null,
    role: stored?.role ?? result.reply?.role ?? "assistant",
    status: stored?.status ?? result.status ?? null,
    traceId: traceId,
    createdAt: stored?.createdAt ?? result.reply?.createdAt ?? result.createdAt ?? null,
    updatedAt: stored?.updatedAt ?? result.updatedAt ?? null,
    source: "agentrun-command-result",
    valuesPrinted: false
  };
}

function traceRetentionSummary(status) {
  return {
    traceStatus: status,
    liveTraceStore: status === "missing" ? "missing" : "expired-or-evicted",
    policy: "live trace events are short-term storage; terminal final response and summary are resolved from AgentRun command result by traceId and commandId",
    replacementEvidence: status === "missing" ? "resolve the trace through AgentRun command registry/result or report the trace as missing" : "use terminalEvidence.finalResponse, terminalEvidence.traceSummary, conversationId, sessionId, threadId, and agentRun ids",
    valuesPrinted: false
  };
}

function numberOrNull(value) {
  const parsed = Number(value);
  return Number.isFinite(parsed) ? parsed : null;
}

function createCodeAgentChatResultStore({ maxResults = 256 } = {}) {
  const limit = positiveInteger(maxResults, 256);
  const results = new Map();
  function set(traceId, payload) {
    const id = safeTraceId(traceId);
    if (!id) return;
    results.set(id, {
      ...payload,
      traceId: id,
      cachedAt: new Date().toISOString()
    });
    while (results.size > limit) {
      const oldest = results.keys().next().value;
      if (!oldest) break;
      results.delete(oldest);
    }
  }
  return {
    set,
    get: (traceId) => results.get(safeTraceId(traceId)) ?? null,
    clear: () => results.clear()
  };
}

function compactCodeAgentChatResultPayload(payload, options = {}) {
  if (!payload || typeof payload !== "object") return payload;
  const limit = resultTraceEventLimit(options);
  const terminalEvidence = agentRunTerminalTraceEvidence(payload, payload.traceId);
  const { userBillingReservation, ...publicPayload } = payload;
  return {
    ...publicPayload,
    ...codeAgentTurnLifecycleFields(publicPayload.traceId, publicPayload),
    ...(terminalEvidence ? { terminalEvidence: terminalEvidencePayload(terminalEvidence) } : {}),
    ...(publicPayload.runnerTrace && typeof publicPayload.runnerTrace === "object"
      ? { runnerTrace: compactRunnerTraceForResult(publicPayload.runnerTrace, limit) }
      : {})
  };
}

function terminalEvidencePayload(evidence) {
  return {
    available: true,
    source: evidence.source,
    conversationId: evidence.conversationId,
    sessionId: evidence.sessionId,
    threadId: evidence.threadId,
    ...codeAgentPromptFields(evidence),
    agentRun: evidence.agentRun,
    traceSummary: evidence.traceSummary,
    finalResponse: evidence.finalResponse,
    valuesPrinted: false
  };
}

function compactRunnerTraceForResult(runnerTrace, limit = DEFAULT_CODE_AGENT_RESULT_TRACE_EVENT_LIMIT) {
  if (!runnerTrace || typeof runnerTrace !== "object") return runnerTrace;
  const events = Array.isArray(runnerTrace.events) ? runnerTrace.events : [];
  const total = Number.isInteger(runnerTrace.eventCount) ? runnerTrace.eventCount : events.length;
  const effectiveLimit = Math.max(8, positiveInteger(limit, DEFAULT_CODE_AGENT_RESULT_TRACE_EVENT_LIMIT));
  if (events.length <= effectiveLimit) {
    return {
      ...runnerTrace,
      eventCount: total,
      eventsCompacted: false
    };
  }
  const headCount = Math.min(24, Math.max(1, Math.floor(effectiveLimit / 4)));
  const tailCount = Math.max(1, effectiveLimit - headCount - 1);
  const omitted = Math.max(0, events.length - headCount - tailCount);
  const head = events.slice(0, headCount);
  const tail = events.slice(events.length - tailCount);
  const marker = {
    traceId: runnerTrace.traceId ?? head[0]?.traceId ?? tail[0]?.traceId ?? null,
    type: "trace",
    stage: "trace",
    status: "truncated",
    label: "trace:compacted",
    createdAt: tail[0]?.createdAt ?? runnerTrace.updatedAt ?? new Date().toISOString(),
    message: `Compatibility result response compacted ${omitted} trace events; fetch /v1/agent/traces/${encodeURIComponent(runnerTrace.traceId ?? "")} for the full trace.`,
    omittedEventCount: omitted,
    retainedEventCount: head.length + tail.length,
    totalEventCount: total,
    valuesPrinted: false
  };
  const compactEvents = [...head, marker, ...tail];
  return {
    ...runnerTrace,
    eventCount: total,
    events: compactEvents,
    eventLabels: compactEvents.map(traceEventLabel).filter(Boolean),
    eventsCompacted: true,
    eventWindow: {
      mode: "head-tail",
      retained: compactEvents.length,
      omitted,
      total
    }
  };
}

function traceEventLabel(event) {
  return typeof event === "string" ? event : event?.label;
}

function resultTraceEventLimit(options = {}) {
  return positiveInteger(
    options.env?.HWLAB_CODE_AGENT_RESULT_TRACE_EVENT_LIMIT,
    DEFAULT_CODE_AGENT_RESULT_TRACE_EVENT_LIMIT
  );
}

function createCodeAgentM3HwlabApiRequestJson(options = {}) {
  return async (targetUrl, request = {}) => {
    const url = new URL(targetUrl);
    const route = url.pathname;
    if (route === M3_IO_CONTROL_ROUTE && request.method === "POST") {
      return {
        ok: true,
        status: 200,
        body: await handleM3IoControl(request.body ?? {}, {
          runtimeStore: options.runtimeStore,
          now: options.now,
          env: options.env,
          requestJson: options.m3IoRequestJson
        })
      };
    }
    if (route === M3_STATUS_ROUTE && request.method === "GET") {
      return {
        ok: true,
        status: 200,
        body: await describeM3StatusLive(options)
      };
    }
    return {
      ok: false,
      status: 404,
      body: {
        error: {
          code: "not_found",
          message: `Unsupported Code Agent M3 HWLAB API route ${route}`
        }
      },
      error: `Unsupported Code Agent M3 HWLAB API route ${route}`
    };
  };
}
function recordCodeAgentProjectionMetrics(options = {}, { result = null, trace = null, projection = null, refreshError = null } = {}) {
  const performanceStore = options.backendPerformanceStore ?? options.backendPerformance;
  if (!performanceStore?.recordWorkbenchProjection || !projection) return;
  const sourceLatestSeq = sourceLatestSeqFromResult(result);
  const lastProjectedSeq = Number(projection.lastProjectedSeq ?? 0);
  if (!Number.isFinite(sourceLatestSeq) && !Number.isFinite(lastProjectedSeq)) return;
  performanceStore.recordWorkbenchProjection({
    sourceLatestSeq: Number.isFinite(sourceLatestSeq) ? sourceLatestSeq : lastProjectedSeq,
    lastProjectedSeq: Number.isFinite(lastProjectedSeq) ? lastProjectedSeq : 0,
    sourceLatestEventAt: sourceLatestAtFromResult(result, trace),
    projectedLatestEventAt: projection.updatedAt ?? trace?.updatedAt ?? result?.updatedAt ?? null,
    terminalSourceAt: terminalSourceAtFromResult(result),
    terminalProjectedAt: projection.projectionStatus === "caught-up" ? projection.updatedAt ?? trace?.updatedAt ?? result?.updatedAt ?? null : null,
    status: projection?.status ?? "unknown",
    reason: projectionReason(projection, refreshError),
    projectionStatus: projection.projectionStatus ?? "unknown",
    source: "workbench_read_model"
  });
}

function recordCodeAgentTurnReadMetric(options = {}, url, statusCode, body = {}, startedAt = nowMs()) {
  const performanceStore = options.backendPerformanceStore ?? options.backendPerformance;
  if (!performanceStore?.recordWorkbenchTurnRead) return;
  performanceStore.recordWorkbenchTurnRead({
    route: url?.pathname ?? "/v1/agent/turns/:id",
    status: body?.status ?? statusClassLabel(statusCode),
    degradedReason: turnReadDegradedReason(body),
    durationMs: nowMs() - startedAt,
    responseBytes: responseBodyBytes(body),
    timedOut: statusCode === 504 || body?.error?.code === "timeout" || body?.refreshError?.code === "agentrun_timeout"
  });
}

function turnReadDegradedReason(body = {}) {
  if (body?.refreshError?.code) return body.refreshError.code;
  if (body?.projection?.blocker?.code) return body.projection.blocker.code;
  if (body?.blocker?.code) return body.blocker.code;
  if (body?.error?.code) return body.error.code;
  if (body?.projectionStatus === "projecting") return "projecting";
  if (body?.projectionStatus === "blocked") return "projection_blocked";
  return "none";
}

function responseBodyBytes(body = {}) {
  try { return Buffer.byteLength(JSON.stringify(body)); } catch { return 0; }
}

function statusClassLabel(value) {
  const status = Number(value);
  if (!Number.isFinite(status) || status <= 0) return "unknown";
  return `${Math.floor(status / 100)}xx`;
}

function sourceLatestSeqFromResult(result = null) {
  const candidates = [
    result?.agentRun?.lastSeq,
    result?.traceSummary?.agentRun?.lastSeq,
    result?.traceSummary?.lastSeq,
    result?.providerTrace?.lastSeq,
    result?.runnerTrace?.lastEvent?.sourceSeq,
    result?.runnerTrace?.lastEvent?.seq,
    result?.runnerTrace?.eventCount
  ];
  for (const value of candidates) {
    const seq = Number(value);
    if (Number.isFinite(seq) && seq >= 0) return Math.floor(seq);
  }
  return NaN;
}

function sourceLatestAtFromResult(result = null, trace = null) {
  return result?.traceSummary?.updatedAt
    ?? result?.agentRun?.updatedAt
    ?? result?.providerTrace?.updatedAt
    ?? result?.runnerTrace?.updatedAt
    ?? trace?.updatedAt
    ?? result?.updatedAt
    ?? null;
}

function terminalSourceAtFromResult(result = null) {
  if (!result) return null;
  const terminalStatus = result?.agentRun?.terminalStatus ?? result?.traceSummary?.terminalStatus ?? result?.status;
  if (!isTraceCommandTerminalStatus(terminalStatus)) return null;
  return result?.traceSummary?.updatedAt ?? result?.agentRun?.updatedAt ?? result?.updatedAt ?? null;
}

function projectionReason(projection = null, refreshError = null) {
  if (refreshError) return refreshError.code ?? "refresh_error";
  if (projection?.blocker) return projection.blocker.code ?? "projection_blocked";
  if (projection?.projectionStatus === "projecting") return "projecting";
  if (projection?.projectionStatus === "caught-up") return "none";
  return projection?.projectionStatus ?? "unknown";
}

function nowMs() {
  if (typeof performance !== "undefined" && typeof performance.now === "function") return performance.now();
  return Date.now();
}

function uniqueStrings(values) {
  return [...new Set(values.map((value) => String(value ?? "").trim()).filter(Boolean))];
}

export {
  normalizeCodeAgentProviderProfile,
  firstNonEmptyValue,
  recordCodeAgentSessionInputFact,
  buildCodeAgentSessionInputFact,
  stableCodeAgentInputId,
  codeAgentInputDelivery,
  codeAgentInputStatus,
  codeAgentResultTimingFields,
  firstTimestampIso,
  firstLatestTimestampIso,
  codeAgentChatShortConnectionRequested,
  preflightCodeAgentBilling,
  recordCodeAgentBillingUsage,
  finalizeCodeAgentBillingUsage,
  releaseCodeAgentBillingReservation,
  withCodeAgentBillingReservation,
  codeAgentBillingEnabled,
  codeAgentBillingMetadata,
  sanitizeBillingReservation,
  sanitizeBillingRecord,
  sanitizeBillingRelease,
  codeAgentUsedTokens,
  normalizeTurnStatus,
  recordCodeAgentConversationFact,
  recordCodeAgentSessionOwner,
  codeAgentOwnerStatusForResult,
  textValue,
  timestampIsoOrNow,
  timestampIsoOrNull,
  codeAgentSessionOwnerEvidence,
  codeAgentContinuationEvidence,
  codeAgentFreshContinuationFailure,
  normalizeCodeAgentFailureKind,
  codeAgentFailureRequiresFreshContinuation,
  codeAgentProviderProfileEvidence,
  codeAgentTraceResultEvidence,
  codeAgentPromptMetadata,
  codeAgentPromptMetadataFromText,
  codeAgentPromptMetadataFromParts,
  codeAgentPromptFields,
  codeAgentPromptId,
  clippedPromptText,
  sha256Text,
  compactCodeAgentObject,
  codeAgentBillingReservationEvidence,
  codeAgentConversationMessagesEvidence,
  boundedConversationMessageText,
  conversationText,
  conversationTextRaw,
  codeAgentMessageTraceSuffix,
  codeAgentTurnLifecycleFields,
  codeAgentLifecycleMessageId,
  safeTurnId,
  safeMessageId,
  codeAgentConversationAgentMessageStatus,
  codeAgentPayloadHasSealedFinalResponse,
  codeAgentConversationRunnerTraceEvidence,
  codeAgentFinalResponseEvidence,
  codeAgentFinalResponseText,
  codeAgentTraceSummaryEvidence,
  annotateOwner,
  canAccessOwnedResult,
  isCodeAgentResultCanceled,
  codeAgentCancelScopeMismatch,
  cancelExpectedValues,
  cancelScopeFieldMismatch,
  cancelBlockedPayload,
  isTraceCommandTerminalStatus,
  traceSnapshotWithTerminalEvidence,
  traceSnapshotWithAttachedTerminalEvidence,
  agentRunTerminalTraceEvidence,
  agentRunTerminalFinalResponse,
  traceRetentionSummary,
  numberOrNull,
  createCodeAgentChatResultStore,
  compactCodeAgentChatResultPayload,
  terminalEvidencePayload,
  compactRunnerTraceForResult,
  traceEventLabel,
  resultTraceEventLimit,
  createCodeAgentM3HwlabApiRequestJson,
  recordCodeAgentProjectionMetrics,
  recordCodeAgentTurnReadMetric,
  turnReadDegradedReason,
  responseBodyBytes,
  statusClassLabel,
  sourceLatestSeqFromResult,
  sourceLatestAtFromResult,
  terminalSourceAtFromResult,
  projectionReason,
  nowMs,
  uniqueStrings
};
