// SPEC: PJ2026-010401080313 Workbench实时权威 draft-2026-07-14-p0-pure-kafka-authority; 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: Code Agent HTTP session and turn admission.

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 { classifyCodeAgentDispatchFailure } from "./code-agent-dispatch-failure.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 { promoteWorkbenchTurnAdmission as persistWorkbenchTurnAdmissionPromotion, writeWorkbenchSessionAdmissionFact } from "./workbench-projection-writer.ts";
import { createWorkbenchReadModel } from "./workbench-read-model.ts";
import { workbenchRealtimeCapabilities } from "./workbench-realtime-capabilities.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";

import {
  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
} from "./server-code-agent-http-support.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";

export async function handleCodeAgentChatHttp(request, response, options) {
  const perf = options.backendPerformance;
  const body = perf ? await perf.measure("body_read", () => readBody(request, options.bodyLimitBytes)) : await readBody(request, options.bodyLimitBytes);
  let params = {};

  try {
    params = body ? JSON.parse(body) : {};
  } catch (error) {
    sendJson(response, 400, {
      ...createCodeAgentErrorPayload({
        code: "parse_error",
        message: "Invalid JSON body",
        reason: error.message,
        traceId: getHeader(request, "x-trace-id") || "trc_unassigned",
        model: options.env?.HWLAB_CODE_AGENT_MODEL || options.env?.OPENAI_MODEL || process.env.HWLAB_CODE_AGENT_MODEL || process.env.OPENAI_MODEL || "unknown",
        layer: "api",
        retryable: true
      })
    });
    return;
  }

  if (!params || typeof params !== "object" || Array.isArray(params)) {
    sendJson(response, 400, {
      ...createCodeAgentErrorPayload({
        code: "invalid_params",
        message: "Code Agent chat body must be a JSON object",
        traceId: getHeader(request, "x-trace-id") || "trc_unassigned",
        model: options.env?.HWLAB_CODE_AGENT_MODEL || options.env?.OPENAI_MODEL || process.env.HWLAB_CODE_AGENT_MODEL || process.env.OPENAI_MODEL || "unknown",
        layer: "api",
        retryable: true
      })
    });
    return;
  }
  params = withMdtodoExecutionPrompt(params);

  const traceId = safeTraceId(getHeader(request, "x-trace-id") || params.traceId) || `trc_${randomUUID()}`;
  const lifecycle = codeAgentTurnLifecycleFields(traceId, params);
  const chatParams = {
    ...params,
    traceId,
    ...lifecycle,
    ownerUserId: options.actor?.id ?? params.ownerUserId,
    ownerRole: options.actor?.role ?? params.ownerRole
  };
  const manualSession = perf ? await perf.measure("manual_session", () => prepareManualCodeAgentSession({ params: chatParams, options, traceId, response })) : await prepareManualCodeAgentSession({ params: chatParams, options, traceId, response });
  if (manualSession?.blocked) return;
  const nativeSessionChatParams = stripSyntheticConversationContext(chatParams, traceId, options);

  if (codeAgentChatShortConnectionRequested(request, params, options)) {
    if (perf) perf.recordPhase({ phase: "short_connection_accept", durationMs: 0, outcome: "ok" });
    let submitted = null;
    try {
      submitted = await submitCodeAgentChatTurn({
        params: nativeSessionChatParams,
        options,
        traceId
      });
    } catch (error) {
      if (isCodeAgentSubmissionUnavailableError(error)) {
        sendJson(response, error.statusCode ?? 503, error.payload);
        return;
      }
      throw error;
    }
    const traceUrl = `/v1/agent/traces/${encodeURIComponent(traceId)}`;
    const turnUrl = `/v1/agent/turns/${encodeURIComponent(traceId)}`;
    const workbenchEventsUrl = `/v1/workbench/events?sessionId=${encodeURIComponent(safeSessionId(nativeSessionChatParams.sessionId) || "")}&traceId=${encodeURIComponent(traceId)}`;
    const statusCode = 202;
    const admittedTiming = codeAgentAdmissionTimingFields(submitted?.createdAt ?? submitted?.updatedAt);
    void emitCodeAgentOtelSpan("POST /v1/agent/chat", traceId, options.env ?? process.env, {
      kind: 2,
      attributes: { "http.method": "POST", "http.route": "/v1/agent/chat", "http.status_code": statusCode, sessionId: safeSessionId(nativeSessionChatParams.sessionId) || null, turnId: lifecycle.turnId, ...agentChatOtelAttributes(nativeSessionChatParams) }
    });
    sendJson(response, 202, {
      accepted: true,
      status: "running",
      shortConnection: true,
      controlSemantics: "submit-and-project-sse",
      traceId,
      ...codeAgentOtelTraceFields(traceId, options.env ?? process.env),
      ...lifecycle,
      sessionId: safeSessionId(nativeSessionChatParams.sessionId) || null,
      createdAt: submitted?.createdAt ?? admittedTiming.createdAt,
      updatedAt: submitted?.updatedAt ?? admittedTiming.updatedAt,
      timing: submitted?.timing ?? admittedTiming.timing,
      startedAt: submitted?.startedAt ?? admittedTiming.startedAt,
      lastEventAt: submitted?.lastEventAt ?? admittedTiming.lastEventAt,
      finishedAt: submitted?.finishedAt ?? admittedTiming.finishedAt,
      durationMs: submitted?.durationMs ?? admittedTiming.durationMs,
      admission: submitted?.agentRun ? {
        state: submitted.admissionState ?? "promoted",
        runId: submitted.agentRun.runId ?? null,
        commandId: submitted.agentRun.commandId ?? null,
        dispatchIntentId: submitted.agentRun.dispatchIntentId ?? null,
        runnerJobId: submitted.agentRun.runnerJobId ?? null,
        durableDispatch: submitted.agentRun.durableDispatch === true,
        valuesRedacted: true
      } : null,
      traceUrl,
      turnUrl,
      workbenchEventsUrl,
      cancelUrl: "/v1/agent/chat/cancel",
      runnerTrace: (options.traceStore ?? defaultCodeAgentTraceStore).snapshot(traceId)
    });
    return;
  }

  const admittedBase = codeAgentAdmittedFailureBasePayload({ params: nativeSessionChatParams, options, traceId });
  try {
    await recordCodeAgentTurnAdmission({ payload: admittedBase, params: nativeSessionChatParams, options, traceId });
  } catch (error) {
    if (isCodeAgentAdmissionUnavailableError(error)) {
      sendJson(response, error.statusCode ?? 503, error.payload);
      return;
    }
    throw error;
  }
  const billingPreflight = perf ? await perf.measure("billing_preflight", () => preflightCodeAgentBilling({ params: nativeSessionChatParams, options, traceId, response: null, sendResponse: false })) : await preflightCodeAgentBilling({ params: nativeSessionChatParams, options, traceId, response: null, sendResponse: false });
  if (billingPreflight?.blocked) {
    const failed = await settleAdmittedCodeAgentFailure({
      base: admittedBase,
      params: nativeSessionChatParams,
      options,
      traceId,
      results: options.codeAgentChatResults,
      failure: billingPreflight,
      traceLabel: "billing:preflight:failed"
    });
    sendJson(response, billingPreflight.statusCode ?? 503, failed);
    return;
  }
  const nativeSessionChatParamsWithBilling = { ...nativeSessionChatParams, userBillingReservation: billingPreflight?.reservation ?? null };
  const payload = perf ? await perf.measure("code_agent_run", () => runCodeAgentChat(nativeSessionChatParamsWithBilling, options)) : await runCodeAgentChat(nativeSessionChatParamsWithBilling, options);
  await (perf ? perf.measure("billing_finalize", () => finalizeCodeAgentBillingUsage({ payload, params: nativeSessionChatParamsWithBilling, options })) : finalizeCodeAgentBillingUsage({ payload, params: nativeSessionChatParamsWithBilling, options }));
  await (perf ? perf.measure("session_owner_record", () => recordCodeAgentSessionOwner({ payload, params: nativeSessionChatParamsWithBilling, options, status: codeAgentOwnerStatusForResult(payload) })) : recordCodeAgentSessionOwner({ payload, params: nativeSessionChatParamsWithBilling, options, status: codeAgentOwnerStatusForResult(payload) }));
  const responsePayload = annotateOwner(payload, nativeSessionChatParamsWithBilling);

  sendJson(response, responsePayload.status === "failed" && responsePayload.error?.code === "invalid_params" ? 400 : 200, responsePayload);
}

export async function handleWorkbenchTurnAdmissionHttp(request, response, options) {
  const body = await readJsonObjectBody(request, options.bodyLimitBytes);
  if (!body.ok) {
    sendJson(response, 400, manualSessionErrorPayload({ code: body.code, message: body.message, reason: body.reason }));
    return;
  }
  const rawParams = withMdtodoExecutionPrompt(body.value);
  const traceId = safeTraceId(rawParams.traceId) || `trc_${randomUUID()}`;
  const lifecycle = codeAgentTurnLifecycleFields(traceId, rawParams);
  const params = {
    ...rawParams,
    traceId,
    ...lifecycle,
    ownerUserId: options.actor?.id,
    ownerRole: options.actor?.role
  };
  const manualSession = await prepareManualCodeAgentSession({ params, options, traceId, response });
  if (manualSession?.blocked) return;
  const admittedParams = stripSyntheticConversationContext(params, traceId, options);
  const payload = codeAgentAdmittedFailureBasePayload({ params: admittedParams, options, traceId });
  try {
    await recordCodeAgentTurnAdmission({ payload, params: admittedParams, options, traceId });
  } catch (error) {
    if (isCodeAgentAdmissionUnavailableError(error)) {
      sendJson(response, error.statusCode ?? 503, error.payload);
      return;
    }
    throw error;
  }
  sendJson(response, 202, {
    ok: true,
    accepted: true,
    status: "admitted",
    admissionState: "durable",
    traceId,
    sessionId: safeSessionId(admittedParams.sessionId),
    conversationId: safeConversationId(admittedParams.conversationId),
    ...lifecycle,
    terminalAuthority: "hwlab.event.v1",
    resultSynthesized: false,
    valuesRedacted: true,
    secretMaterialStored: false
  });
}

export async function handleCodeAgentSessionsHttp(request, response, url, options) {
  const match = url.pathname.match(/^\/v1\/agent\/sessions(?:\/([^/]+)(?:\/(select))?)?$/u);
  const sessionId = safeSessionId(match?.[1] ? decodeURIComponent(match[1]) : "");
  const action = match?.[2] ?? null;
  if (!match) {
    sendJson(response, 404, manualSessionErrorPayload({ code: "session_route_not_found", message: "Code Agent session route is not implemented." }));
    return;
  }
  if (request.method === "GET" && !sessionId) {
    await listManualCodeAgentSessions(request, response, url, options);
    return;
  }
  if (request.method === "POST" && !sessionId) {
    await createManualCodeAgentSession(request, response, options);
    return;
  }
  if (request.method === "GET" && sessionId && !action) {
    await getManualCodeAgentSession(response, options, sessionId);
    return;
  }
  if (request.method === "DELETE" && sessionId && !action) {
    await archiveManualCodeAgentSession(response, options, sessionId);
    return;
  }
  if (request.method === "POST" && sessionId && action === "select") {
    await selectManualCodeAgentSession(request, response, options, sessionId);
    return;
  }
  sendJson(response, 405, manualSessionErrorPayload({ code: "session_method_not_allowed", message: "Unsupported Code Agent session method." }));
}

async function listManualCodeAgentSessions(request, response, url, options) {
  const projectId = textValue(url.searchParams.get("projectId")) || DEFAULT_CODE_AGENT_PROJECT_ID;
  const limit = parsePositiveInteger(url.searchParams.get("limit"), 20);
  const sessions = await options.accessController?.store?.listAgentSessionsForUser?.({
    ownerUserId: options.actor?.id,
    actorRole: options.actor?.role,
    ownerScoped: true,
    projectId,
    limit
  }) ?? [];
  sendJson(response, 200, {
    ok: true,
    status: "succeeded",
    contractVersion: "code-agent-manual-session-v1",
    projectId,
    sessions: sessions.map(publicManualAgentSession),
    count: sessions.length,
    valuesRedacted: true,
    secretMaterialStored: false
  });
}

async function createManualCodeAgentSession(request, response, options) {
  const body = await readJsonObjectBody(request, options.bodyLimitBytes);
  if (!body.ok) {
    sendJson(response, 400, manualSessionErrorPayload({ code: body.code, message: body.message, reason: body.reason }));
    return;
  }
  const params = body.value;
  const projectId = textValue(params.projectId) || DEFAULT_CODE_AGENT_PROJECT_ID;
  const conversationId = safeConversationId(params.conversationId) || `cnv_${randomUUID()}`;
  const sessionId = safeSessionId(params.sessionId) || `ses_${randomUUID()}`;
  const providerProfile = normalizeCodeAgentProviderProfile(params.providerProfile ?? params.codeAgentProviderProfile);
  const now = new Date().toISOString();
  const session = await options.accessController.recordAgentSessionOwner({
    ownerUserId: options.actor?.id,
    ownerRole: options.actor?.role,
    sessionId,
    projectId,
    agentId: "hwlab-code-agent",
    status: "idle",
    conversationId,
    threadId: null,
    traceId: null,
    session: {
      source: "manual-session-create",
      providerProfile,
      sessionStatus: "idle",
      createdAt: now,
      valuesRedacted: true,
      secretMaterialStored: false
    }
  });
  await writeWorkbenchSessionAdmissionFact({
    runtimeStore: options.runtimeStore,
    session,
    ownerUserId: options.actor?.id,
    ownerRole: options.actor?.role,
    projectId,
    conversationId,
    threadId: null,
    status: "idle",
    now
  });
  sendJson(response, 201, {
    ok: true,
    status: "created",
    contractVersion: "code-agent-manual-session-v1",
    session: publicManualAgentSession(session),
    nextCommands: manualSessionNextCommands(session),
    valuesRedacted: true,
    secretMaterialStored: false
  });
}

async function getManualCodeAgentSession(response, options, sessionId) {
  const session = await getVisibleManualAgentSession(options, sessionId);
  if (!session) {
    sendJson(response, 404, manualSessionErrorPayload({ code: "session_not_found", message: "Code Agent session is not visible to the current actor.", sessionId }));
    return;
  }
  sendJson(response, 200, {
    ok: true,
    status: "found",
    contractVersion: "code-agent-manual-session-v1",
    session: publicManualAgentSession(session),
    valuesRedacted: true,
    secretMaterialStored: false
  });
}

async function archiveManualCodeAgentSession(response, options, sessionId) {
  const session = await getVisibleManualAgentSession(options, sessionId);
  if (!session) {
    sendJson(response, 404, manualSessionErrorPayload({ code: "session_not_found", message: "Code Agent session is not visible to the current actor.", sessionId }));
    return;
  }
  const result = await options.accessController?.store?.archiveAgentConversation?.({
    ownerUserId: options.actor?.id,
    actorRole: options.actor?.role,
    ownerScoped: true,
    sessionId,
    conversationId: session.conversationId,
    projectId: session.projectId
  }) ?? { count: 0 };
  sendJson(response, 200, {
    ok: true,
    status: "archived",
    contractVersion: "code-agent-manual-session-v1",
    archivedCount: result.count ?? 0,
    session: publicManualAgentSession({ ...session, status: "archived", endedAt: session.endedAt ?? new Date().toISOString(), updatedAt: new Date().toISOString() }),
    valuesRedacted: true,
    secretMaterialStored: false
  });
}

async function selectManualCodeAgentSession(request, response, options, sessionId) {
  const body = await readJsonObjectBody(request, options.bodyLimitBytes);
  if (!body.ok) {
    sendJson(response, 400, manualSessionErrorPayload({ code: body.code, message: body.message, reason: body.reason, sessionId }));
    return;
  }
  const session = await getVisibleManualAgentSession(options, sessionId);
  if (!session) {
    sendJson(response, 404, manualSessionErrorPayload({ code: "session_not_found", message: "Code Agent session is not visible to the current actor.", sessionId }));
    return;
  }
  if (!manualSessionUsable(session.status)) {
    sendJson(response, 409, manualSessionErrorPayload({ code: "session_not_usable", message: `Code Agent session ${sessionId} is ${session.status}; create a new session before continuing.`, sessionId, session }));
    return;
  }
  sendJson(response, 200, {
    ok: true,
    status: "selected",
    contractVersion: "code-agent-manual-session-v1",
    session: publicManualAgentSession(session),
    nextCommands: manualSessionNextCommands(session),
    valuesRedacted: true,
    secretMaterialStored: false
  });
}

async function prepareManualCodeAgentSession({ params, options, traceId, response }) {
  if (!options.actor?.id) {
    sendJson(response, 401, manualSessionErrorPayload({
      code: "auth_required",
      message: "Authentication is required before using an explicit HWLAB Code Agent session.",
      traceId,
      retryable: true
    }));
    return { blocked: true };
  }
  const sessionId = safeSessionId(params.sessionId);
  if (!sessionId) {
    sendJson(response, 409, manualSessionErrorPayload({
      code: "session_required",
      message: "Code Agent session is explicit in HWLAB v0.2; create/select a session before sending a turn.",
      traceId,
      retryable: true,
      nextCommands: ["hwlab-cli client agent session create --provider-profile PROFILE", "hwlab-cli client agent send --session-id <SESSION_ID> --message TEXT"]
    }));
    return { blocked: true };
  }
  const session = await getVisibleManualAgentSession(options, sessionId);
  if (!session) {
    sendJson(response, 404, manualSessionErrorPayload({ code: "session_not_found", message: "Code Agent session is not visible to the current actor.", traceId, sessionId }));
    return { blocked: true };
  }
  const freshContinuation = manualSessionFreshContinuationRequired(session);
  if (!manualSessionUsable(session.status) && !freshContinuation) {
    sendJson(response, 409, manualSessionErrorPayload({ code: "session_not_usable", message: `Code Agent session ${sessionId} is ${session.status}; create a new session before continuing.`, traceId, sessionId, session }));
    return { blocked: true };
  }
  const requestedProjectId = textValue(params.projectId);
  const sessionProjectId = textValue(session.projectId);
  if (requestedProjectId && sessionProjectId && requestedProjectId !== sessionProjectId) {
    sendJson(response, 409, manualSessionErrorPayload({ code: "session_project_mismatch", message: `sessionId ${sessionId} belongs to ${sessionProjectId}; requested ${requestedProjectId}.`, traceId, sessionId, session }));
    return { blocked: true };
  }
  const storedConversationId = safeConversationId(session.conversationId);
  const requestedConversationId = safeConversationId(params.conversationId);
  if (requestedConversationId && storedConversationId && requestedConversationId !== storedConversationId) {
    sendJson(response, 409, manualSessionErrorPayload({ code: "session_conversation_mismatch", message: `sessionId ${sessionId} is bound to ${storedConversationId}; requested ${requestedConversationId}.`, traceId, sessionId, session }));
    return { blocked: true };
  }
  const conversationId = requestedConversationId || storedConversationId;
  if (!conversationId) {
    sendJson(response, 409, manualSessionErrorPayload({ code: "session_conversation_required", message: "Code Agent session has no bound conversationId; create a new session before continuing.", traceId, sessionId, session }));
    return { blocked: true };
  }
  params.conversationId = conversationId;
  params.sessionId = sessionId;
  params.projectId = requestedProjectId || sessionProjectId || DEFAULT_CODE_AGENT_PROJECT_ID;
  applyManualSessionProviderProfile(params, session);
  if (freshContinuation) {
    params.threadId = undefined;
    params.forceFreshAgentRunSession = true;
    params.forceFreshAgentRunSessionReason = manualSessionFreshContinuationReason(session);
  } else {
    params.threadId = safeOpaqueId(params.threadId) || manualSessionContinuationThreadId(session) || undefined;
  }
  return { session };
}

function applyManualSessionProviderProfile(params = {}, session = null) {
  const requested = firstNonEmptyValue(params.providerProfile, params.codeAgentProviderProfile);
  if (requested) {
    const normalized = normalizeCodeAgentProviderProfile(requested);
    params.providerProfile = normalized;
    params.codeAgentProviderProfile = normalized;
    params.providerProfileSource = "request";
    return normalized;
  }
  const stored = manualSessionStoredProviderProfile(session);
  if (!stored) return null;
  params.providerProfile = stored;
  params.codeAgentProviderProfile = stored;
  params.providerProfileSource = "session";
  return stored;
}

function manualSessionStoredProviderProfile(session = null) {
  const evidence = session?.session && typeof session.session === "object" ? session.session : {};
  const traceProfile = latestCompletedTraceResultProviderProfile(evidence.traceResults);
  const raw = firstNonEmptyValue(
    traceProfile,
    evidence.agentRun?.backendProfile,
    evidence.providerProfile,
    evidence.codeAgentProviderProfile,
    evidence.backendProfile
  );
  if (!raw) return null;
  const normalized = normalizeCodeAgentProviderProfile(raw);
  return normalized === "runtime-default" ? null : normalized;
}

function latestCompletedTraceResultProviderProfile(traceResults = null) {
  if (!traceResults || typeof traceResults !== "object") return null;
  const entries = Object.values(traceResults).filter((value) => value && typeof value === "object");
  for (const result of entries.reverse()) {
    const agentRun = result.agentRun && typeof result.agentRun === "object" ? result.agentRun : null;
    if (!agentRun) continue;
    const status = normalizeTurnStatus(result.status ?? agentRun.terminalStatus ?? agentRun.commandState ?? agentRun.status);
    if (status && status !== "completed") continue;
    const profile = firstNonEmptyValue(agentRun.backendProfile, result.providerProfile, result.codeAgentProviderProfile);
    if (profile) return profile;
  }
  return null;
}

function manualSessionFreshContinuationRequired(session = null) {
  const status = String(session?.status ?? "").trim().toLowerCase().replace(/_/gu, "-");
  if (status === "thread-resume-failed") return true;
  const continuation = session?.session?.continuation && typeof session.session.continuation === "object" ? session.session.continuation : null;
  return continuation?.requiresFreshSession === true;
}

function manualSessionFreshContinuationReason(session = null) {
  const continuation = session?.session?.continuation && typeof session.session.continuation === "object" ? session.session.continuation : null;
  return firstNonEmptyValue(continuation?.reasonCode, continuation?.reason, session?.status, "stale-continuation") ?? "stale-continuation";
}

function manualSessionContinuationThreadId(session = null) {
  if (manualSessionFreshContinuationRequired(session)) return null;
  const evidence = session?.session && typeof session.session === "object" ? session.session : {};
  return safeOpaqueId(evidence.threadId) || safeOpaqueId(evidence.agentRun?.threadId) || safeOpaqueId(session?.threadId) || null;
}

async function getVisibleManualAgentSession(options, sessionId) {
  if (!safeSessionId(sessionId) || !options.actor?.id || !options.accessController?.getAgentSession) return null;
  const session = await options.accessController.getAgentSession(sessionId);
  if (!session) return null;
  if (session.ownerUserId === options.actor.id) return session;
  return null;
}

function publicManualAgentSession(session) {
  if (!session || typeof session !== "object") return null;
  return {
    sessionId: session.id,
    agentId: session.agentId ?? "hwlab-code-agent",
    status: session.status ?? null,
    usable: manualSessionUsable(session.status),
    threadId: safeOpaqueId(session.threadId) || null,
    lastTraceId: safeTraceId(session.lastTraceId) || null,
    providerProfile: textValue(session.session?.providerProfile) || null,
    createdAt: session.startedAt ?? null,
    updatedAt: session.updatedAt ?? null,
    valuesRedacted: true,
    secretMaterialStored: false
  };
}

function manualSessionUsable(status) {
  const value = String(status ?? "").trim().toLowerCase().replace(/_/gu, "-");
  return !["blocked", "expired", "stale"].includes(value);
}

function manualSessionErrorPayload({ code, message, reason = null, traceId = null, sessionId = null, session = null, retryable = true, nextCommands = undefined } = {}) {
  return {
    ok: false,
    accepted: false,
    status: "blocked",
    traceId: safeTraceId(traceId) || null,
    sessionId: safeSessionId(sessionId) || safeSessionId(session?.id) || null,
    session: session ? publicManualAgentSession(session) : null,
    error: {
      code,
      layer: "api",
      category: "session_blocked",
      retryable,
      message,
      reason,
      userMessage: message,
      route: "/v1/agent/chat"
    },
    blocker: {
      code,
      layer: "api",
      retryable,
      summary: message
    },
    nextCommands,
    valuesRedacted: true,
    secretMaterialStored: false
  };
}

function manualSessionNextCommands(session) {
  const sessionId = session?.id ?? "<SESSION_ID>";
  return [
    `hwlab-cli client agent send --session-id ${sessionId} --message TEXT`,
    `hwlab-cli client agent session status ${sessionId}`
  ];
}

async function readJsonObjectBody(request, bodyLimitBytes) {
  const body = await readBody(request, bodyLimitBytes);
  try {
    const value = body ? JSON.parse(body) : {};
    if (!value || typeof value !== "object" || Array.isArray(value)) return { ok: false, code: "invalid_params", message: "body must be a JSON object" };
    return { ok: true, value };
  } catch (error) {
    return { ok: false, code: "parse_error", message: "Invalid JSON body", reason: error.message };
  }
}

async function runCodeAgentChat(params, options) {
  return handleCodeAgentChat(params, await codeAgentChatExecutionOptions(options, params));
}

function stripSyntheticConversationContext(params = {}, traceId, options = {}) {
  if (Array.isArray(params.conversationContext?.messages) || Array.isArray(params.messages)) {
    (options.traceStore ?? defaultCodeAgentTraceStore).append(traceId, {
      type: "synthetic-context",
      status: "ignored",
      label: "synthetic-context:ignored",
      message: "Synthetic conversation context was stripped; Code Agent continuation uses only Codex stdio native thread/resume and turn/start.",
      valuesPrinted: false
    });
  }
  const { conversationContext, conversationContextTruncated, contextSource, messages, ...nativeParams } = params;
  return nativeParams;
}

async function codeAgentChatExecutionOptions(options = {}, params = {}) {
  const env = codeAgentProviderProfileEnv(options.env ?? process.env, params);
  Object.assign(env, await codeAgentAuthEnv(options, env, params));
  return {
    callProvider: options.callCodeAgentProvider,
    timeoutMs: options.codeAgentTimeoutMs,
    hardTimeoutMs: options.codeAgentHardTimeoutMs,
    env,
    workspace: options.workspace,
    skillsDirs: options.skillsDirs,
    skillsDirsExact: options.skillsDirsExact,
    skillsDiscoveryDelayMs: options.skillsDiscoveryDelayMs,
    sessionRegistry: options.sessionRegistry,
    m3IoSkillRequestJson: options.m3IoSkillRequestJson ?? createCodeAgentM3HwlabApiRequestJson(options),
    codexStdioManager: options.codexStdioManager,
    traceStore: options.traceStore,
    gatewayRegistry: options.gatewayRegistry
  };
}

async function codeAgentAuthEnv(options = {}, env = process.env, params = {}) {
  const ownerUserId = textValue(params.ownerUserId ?? options.actor?.id ?? "");
  const store = options.accessController?.store;
  const key = ownerUserId && store?.findActiveDefaultApiKeyForUser
    ? await store.findActiveDefaultApiKeyForUser(ownerUserId)
    : null;
  const envRuntimeLane = runtimeLaneForEnv(env);
  const runtimeNamespace = runtimeNamespaceForEnv(env);
  const namespaceRuntimeLane = runtimeLaneForNamespace(runtimeNamespace);
  const runtimeLane = resolveRuntimeLaneAuthority({ envRuntimeLane, runtimeNamespace, namespaceRuntimeLane });
  const inClusterApiUrl = internalCodeAgentApiUrl(env, runtimeNamespace);
  const inClusterWebUrl = internalCodeAgentWebUrl(env, runtimeNamespace);
  const apiUrl = firstNonEmptyValue(
    codeAgentAgentRunAdapterEnabled(env) ? inClusterApiUrl : null,
    env.HWLAB_RUNTIME_API_URL,
    sameRuntimeEndpoint(env.HWLAB_CLOUD_API_URL, runtimeNamespace, runtimeLane),
    env.HWLAB_PUBLIC_ENDPOINT,
    localCloudApiUrl(env)
  );
  return {
    HWLAB_CLOUD_API_URL: apiUrl,
    HWLAB_RUNTIME_API_URL: apiUrl,
    HWLAB_RUNTIME_WEB_URL: firstNonEmptyValue(codeAgentAgentRunAdapterEnabled(env) ? inClusterWebUrl : null, env.HWLAB_RUNTIME_WEB_URL, apiUrl),
    HWLAB_RUNTIME_NAMESPACE: runtimeNamespace,
    HWLAB_RUNTIME_LANE: runtimeLane,
    HWLAB_RUNTIME_ENDPOINT_SOURCE: codeAgentAgentRunAdapterEnabled(env) ? "runtime-namespace" : "runtime-env",
    HWLAB_RUNTIME_ENDPOINT_LOCKED: "1",
    HWLAB_CODE_AGENT_ASSEMBLED_RUNTIME: "1",
    ...(options.actorApiKeySecret ? { HWLAB_API_KEY: options.actorApiKeySecret } : key?.displaySecret ? { HWLAB_API_KEY: key.displaySecret } : {})
  };
}

function internalCodeAgentApiUrl(env = process.env, namespace = runtimeNamespaceForEnv(env)) {
  const serviceName = firstNonEmptyValue(env.HWLAB_CODE_AGENT_INTERNAL_API_SERVICE_NAME, env.HWLAB_CLOUD_API_SERVICE_NAME, "hwlab-cloud-api");
  const port = parsePositiveInteger(firstNonEmptyValue(env.HWLAB_CODE_AGENT_INTERNAL_API_PORT, env.HWLAB_CLOUD_API_PORT), 6667);
  return `http://${serviceName}.${namespace}.svc.cluster.local:${port}`;
}

function internalCodeAgentWebUrl(env = process.env, namespace = runtimeNamespaceForEnv(env)) {
  const serviceName = firstNonEmptyValue(env.HWLAB_CODE_AGENT_INTERNAL_WEB_SERVICE_NAME, env.HWLAB_CLOUD_WEB_SERVICE_NAME, "hwlab-cloud-web");
  const port = parsePositiveInteger(firstNonEmptyValue(env.HWLAB_CODE_AGENT_INTERNAL_WEB_PORT, env.HWLAB_CLOUD_WEB_PORT), 8080);
  return `http://${serviceName}.${namespace}.svc.cluster.local:${port}`;
}

function runtimeNamespaceForEnv(env = process.env) {
  return firstNonEmptyValue(
    env.HWLAB_RUNTIME_NAMESPACE,
    env.POD_NAMESPACE,
    env.HWLAB_NAMESPACE,
    defaultRuntimeNamespace(env)
  );
}

function runtimeLaneForEnv(env = process.env) {
  const raw = firstNonEmptyValue(env.HWLAB_RUNTIME_LANE, env.HWLAB_GITOPS_LANE, env.HWLAB_GITOPS_PROFILE, env.HWLAB_ENVIRONMENT, env.HWLAB_BOOT_REF);
  if (!raw) return null;
  const lane = normalizeRuntimeLane(raw);
  if (!lane) {
    throw runtimeAuthorityError("unsupported_runtime_lane", `unsupported HWLAB runtime lane: ${String(raw).trim()}`);
  }
  return lane;
}

function runtimeLaneForNamespace(namespace) {
  const value = String(namespace ?? "").trim().toLowerCase();
  if (value === "hwlab-prod") return "prod";
  if (value === "hwlab-dev") return "dev";
  const versionMatch = value.match(/^hwlab-v(\d+)$/u);
  if (versionMatch) return versionRuntimeLane(versionMatch[1]);
  return null;
}

function sameRuntimeEndpoint(value, namespace, lane) {
  const text = firstNonEmptyValue(value);
  if (!text) return null;
  const endpointLane = runtimeLaneForEndpoint(text);
  const endpointNamespace = runtimeNamespaceForEndpoint(text);
  if (namespace && endpointNamespace && endpointNamespace !== namespace) return null;
  if (lane && endpointLane && endpointLane !== lane) return null;
  return text;
}

function runtimeNamespaceForEndpoint(value) {
  const match = String(value ?? "").match(/\.((?:hwlab-[a-z0-9-]+))\.svc\.cluster\.local(?::|\/|$)/iu);
  return match?.[1] ?? null;
}

function runtimeLaneForEndpoint(value) {
  const text = String(value ?? "").toLowerCase();
  const namespaceLane = runtimeLaneForNamespace(runtimeNamespaceForEndpoint(text));
  if (namespaceLane) return namespaceLane;
  if (/hwlab-prod|:18666(?:\/|$)|:18667(?:\/|$)/u.test(text)) return "prod";
  if (/hwlab-dev|:17666(?:\/|$)|:17667(?:\/|$)|:16666(?:\/|$)|:16667(?:\/|$)/u.test(text)) return "dev";
  return null;
}

function normalizeRuntimeLane(value) {
  const profile = String(value ?? "").trim().toLowerCase();
  if (!profile) return null;
  if (profile === "prod" || profile === "production") return "prod";
  if (profile === "dev" || profile === "development" || profile === "local") return "dev";
  const dotted = profile.match(/^v?0+\.(\d+)$/u);
  if (dotted) return versionRuntimeLane(dotted[1]);
  const compact = profile.match(/^v?0*(\d+)$/u);
  if (compact) return versionRuntimeLane(compact[1]);
  return null;
}

function versionRuntimeLane(value) {
  const version = Number.parseInt(value, 10);
  if (!Number.isFinite(version) || version <= 0) return null;
  return `v${String(version).padStart(2, "0")}`;
}

function resolveRuntimeLaneAuthority({ envRuntimeLane, runtimeNamespace, namespaceRuntimeLane }) {
  if (!namespaceRuntimeLane) {
    throw runtimeAuthorityError("unsupported_runtime_namespace", `unsupported HWLAB runtime namespace: ${runtimeNamespace}`);
  }
  if (envRuntimeLane && envRuntimeLane !== namespaceRuntimeLane) {
    throw runtimeAuthorityError(
      "runtime_authority_mismatch",
      `HWLAB runtime lane ${envRuntimeLane} does not match namespace ${runtimeNamespace} (${namespaceRuntimeLane})`
    );
  }
  return namespaceRuntimeLane;
}

function runtimeAuthorityError(code, message) {
  return Object.assign(new Error(message), {
    code,
    statusCode: 500,
    valuesPrinted: false
  });
}

function defaultRuntimeNamespace(env = process.env) {
  const profile = runtimeLaneForEnv(env) ?? "dev";
  if (profile === "prod") return "hwlab-prod";
  if (profile === "dev") return "hwlab-dev";
  return `hwlab-${profile}`;
}

function localCloudApiUrl(env = process.env) {
  const port = parsePositiveInteger(env.HWLAB_CLOUD_API_PORT, 6667);
  return `http://127.0.0.1:${port}`;
}

function codeAgentProviderProfileEnv(env = process.env, params = {}) {
  const profile = normalizeCodeAgentProviderProfile(params.providerProfile ?? params.codeAgentProviderProfile ?? params.provider ?? env.HWLAB_CODE_AGENT_DEFAULT_PROVIDER_PROFILE);
  if (profile === "runtime-default") return env;
  const overlay = { ...env };
  overlay.HWLAB_CODE_AGENT_SELECTED_PROVIDER_PROFILE = profile;
  overlay.HWLAB_CODE_AGENT_PROVIDER_PROFILE_LABEL = CODE_AGENT_PROVIDER_PROFILE_LABELS[profile] ?? profile;
  overlay.HWLAB_CODE_AGENT_PROVIDER = "codex-stdio";
  if (profile === "codex-api") {
    overlay.HWLAB_CODE_AGENT_MODEL = firstNonEmptyValue(env.HWLAB_CODE_AGENT_CODEX_API_MODEL, env.HWLAB_CODE_AGENT_LEGACY_CODEX_MODEL, DEFAULT_CODE_AGENT_CODEX_API_MODEL);
    overlay.HWLAB_CODE_AGENT_OPENAI_BASE_URL = firstNonEmptyValue(env.HWLAB_CODE_AGENT_CODEX_API_BASE_URL, env.HWLAB_CODE_AGENT_LEGACY_OPENAI_BASE_URL, DEFAULT_CODE_AGENT_CODEX_API_BASE_URL);
  } else if (profile === "minimax-m3") {
    overlay.HWLAB_CODE_AGENT_MODEL = firstNonEmptyValue(env.HWLAB_CODE_AGENT_MINIMAX_M3_MODEL, DEFAULT_CODE_AGENT_MINIMAX_M3_MODEL);
  } else {
    const dynamicProfile = profile !== "deepseek";
    overlay.HWLAB_CODE_AGENT_MODEL = dynamicProfile
      ? firstNonEmptyValue(env[`HWLAB_CODE_AGENT_${providerProfileEnvKey(profile)}_MODEL`], profile)
      : firstNonEmptyValue(env.HWLAB_CODE_AGENT_DEEPSEEK_MODEL, DEFAULT_CODE_AGENT_DEEPSEEK_MODEL);
    if (!dynamicProfile || !codeAgentAgentRunAdapterEnabled(env)) {
      overlay.HWLAB_CODE_AGENT_OPENAI_BASE_URL = firstNonEmptyValue(env.HWLAB_CODE_AGENT_DEEPSEEK_BASE_URL, defaultDeepSeekBaseUrlForEnv(env));
    }
  }
  overlay.NO_PROXY = mergeNoProxyEntries(env.NO_PROXY, codeAgentClusterNoProxyEntries(env));
  overlay.no_proxy = mergeNoProxyEntries(env.no_proxy ?? env.NO_PROXY, codeAgentClusterNoProxyEntries(env));
  return overlay;
}

function providerProfileEnvKey(profile) {
  return String(profile ?? "")
    .trim()
    .toUpperCase()
    .replace(/[^A-Z0-9]+/gu, "_")
    .replace(/^_+|_+$/gu, "") || "PROFILE";
}

function defaultDeepSeekBaseUrlForEnv(env = process.env) {
  const namespace = env.HWLAB_GITOPS_PROFILE === "prod" || env.HWLAB_ENVIRONMENT === "prod" ? "hwlab-prod" : "hwlab-dev";
  return `http://hwlab-deepseek-proxy.${namespace}.svc.cluster.local:4000/v1/responses`;
}

function codeAgentClusterNoProxyEntries(env = process.env) {
  const namespace = env.HWLAB_GITOPS_PROFILE === "prod" || env.HWLAB_ENVIRONMENT === "prod" ? "hwlab-prod" : "hwlab-dev";
  return [
    `${namespace}.svc.cluster.local`,
    ".svc",
    ".cluster.local",
    "127.0.0.1",
    "localhost",
    "::1",
    "10.0.0.0/8",
    "10.42.0.0/16",
    "10.43.0.0/16",
    "hyueapi.com",
    ".hyueapi.com",
    "hyui.com",
    ".hyui.com",
    "api.minimaxi.com",
    ".minimaxi.com"
  ];
}

function mergeNoProxyEntries(current, additions = []) {
  return uniqueStrings([...String(current ?? "").split(","), ...additions]).join(",");
}

function safeOtelConfigText(value) {
  const text = firstNonEmptyValue(value);
  return text === null ? null : text.slice(0, 120);
}

function safeOtelUrlHost(value) {
  const text = firstNonEmptyValue(value);
  if (text === null) return null;
  try {
    return new URL(text).host.slice(0, 120);
  } catch {
    return null;
  }
}

function withMdtodoExecutionPrompt(params = {}) {
  const execution = mdtodoExecutionContextFromParams(params);
  if (!execution?.hwpodId || !execution?.hwpodWorkspaceArgs) return params;
  const message = firstNonEmptyValue(params.message, params.prompt, params.text);
  if (!message || /hwpodWorkspaceArgs\s*:/u.test(message)) return params;
  const taskRef = firstNonEmptyValue(params.taskRef, execution.taskRef) ?? "-";
  const mdtodoRootRef = execution.mdtodoRootRef ?? "docs/MDTODO";
  const prefix = [
    "# MDTODO HWPOD 执行上下文",
    `TaskRef: ${taskRef}`,
    `sourceId: ${execution.sourceId ?? "-"}`,
    `hwpodId: ${execution.hwpodId}`,
    `nodeId: ${execution.nodeId ?? "-"}`,
    `mdtodoRootRef: ${mdtodoRootRef}`,
    `hwpodWorkspaceArgs: ${execution.hwpodWorkspaceArgs}`,
    "所有 hwpod/hwpod-ctl 命令都必须携带上述 hwpodWorkspaceArgs。读取 MDTODO、报告和工程文件必须通过 HWPOD workspace/node-ops 入口，不得猜测或访问普通容器本地路径，也不得创建本地 .hwlab/hwpod-spec.yaml fallback。"
  ].join("\n");
  const nextMessage = `${prefix}\n\n${message}`;
  return {
    ...params,
    message: nextMessage,
    prompt: nextMessage,
    launchContext: {
      ...(params.launchContext && typeof params.launchContext === "object" ? params.launchContext : {}),
      hwpodId: execution.hwpodId,
      nodeId: execution.nodeId,
      mdtodoRootRef: execution.mdtodoRootRef,
      hwpodWorkspaceArgs: execution.hwpodWorkspaceArgs,
      contextFingerprint: execution.contextFingerprint,
      executionContext: execution,
      valuesRedacted: true
    }
  };
}

function mdtodoExecutionContextFromParams(params = {}) {
  const launchContext = params.launchContext && typeof params.launchContext === "object" && !Array.isArray(params.launchContext) ? params.launchContext : null;
  const execution = launchContext?.executionContext && typeof launchContext.executionContext === "object" && !Array.isArray(launchContext.executionContext) ? launchContext.executionContext : launchContext;
  if (!execution || typeof execution !== "object") return null;
  return {
    sourceId: safeOtelConfigText(execution.sourceId ?? launchContext?.sourceId),
    sourceKind: safeOtelConfigText(execution.sourceKind ?? launchContext?.sourceKind),
    projectId: safeOtelConfigText(execution.projectId ?? launchContext?.projectId ?? params.projectId),
    taskRef: safeOtelText(execution.taskRef ?? launchContext?.taskRef ?? params.taskRef),
    fileRef: safeOtelConfigText(execution.fileRef ?? launchContext?.fileRef),
    relativePath: safeOtelText(execution.relativePath ?? launchContext?.relativePath),
    taskId: safeOtelConfigText(execution.taskId ?? launchContext?.taskId),
    hwpodId: safeOtelText(execution.hwpodId ?? launchContext?.hwpodId),
    nodeId: safeOtelText(execution.nodeId ?? launchContext?.nodeId),
    mdtodoRootRef: safeOtelText(execution.mdtodoRootRef ?? launchContext?.mdtodoRootRef),
    workspaceRootHash: safeOtelText(execution.workspaceRootHash ?? launchContext?.workspaceRootHash),
    hwpodWorkspaceArgs: safeOtelText(execution.hwpodWorkspaceArgs ?? launchContext?.hwpodWorkspaceArgs, 500),
    contextFingerprint: safeOtelText(execution.contextFingerprint ?? launchContext?.contextFingerprint),
    valuesRedacted: true
  };
}

function agentChatOtelAttributes(params = {}) {
  const execution = mdtodoExecutionContextFromParams(params);
  return {
    "agent.chat.session_id": safeSessionId(params.sessionId) || null,
    "agent.chat.provider_profile": safeOtelConfigText(params.providerProfile ?? params.codeAgentProviderProfile),
    "agent.chat.provider_profile_source": safeOtelConfigText(params.providerProfileSource),
    "agent.chat.task_ref": safeOtelText(params.taskRef ?? execution?.taskRef),
    "agent.chat.source_id": safeOtelConfigText(execution?.sourceId ?? params.sourceId),
    "agent.chat.hwpod_id": safeOtelText(execution?.hwpodId),
    "agent.chat.workspace_root_hash": safeOtelText(execution?.workspaceRootHash),
    "agent.chat.context_fingerprint": safeOtelText(execution?.contextFingerprint)
  };
}

function safeOtelText(value, max = 360) {
  const text = firstNonEmptyValue(value);
  return text === null ? null : text.slice(0, max);
}

async function submitCodeAgentChatTurn({ params, options, traceId }) {
  const traceStore = options.traceStore ?? defaultCodeAgentTraceStore;
  const results = options.codeAgentChatResults ?? createCodeAgentChatResultStore();
  const timestamp = new Date().toISOString();
  const runtimeEnv = options.env ?? process.env;
  const adapterEnabled = codeAgentAgentRunAdapterEnabled(runtimeEnv);
  const acceptedPayload = {
    accepted: true,
    status: "running",
    traceId,
    ...codeAgentOtelTraceFields(traceId, process.env),
    ...codeAgentTurnLifecycleFields(traceId, params),
    conversationId: safeConversationId(params.conversationId) || null,
    sessionId: safeSessionId(params.sessionId) || null,
    threadId: safeOpaqueId(params.threadId) || null,
    projectId: params.projectId ?? null,
    ...codeAgentAdmissionTimingFields(timestamp)
  };
  void emitCodeAgentOtelSpan("provider_decision", traceId, runtimeEnv, {
    attributes: {
      ...agentChatOtelAttributes(params),
      adapterEnabled,
      adapter: safeOtelConfigText(runtimeEnv.HWLAB_CODE_AGENT_ADAPTER ?? runtimeEnv.HWLAB_CODE_AGENT_PROVIDER),
      provider: safeOtelConfigText(runtimeEnv.HWLAB_CODE_AGENT_PROVIDER),
      defaultProviderProfile: safeOtelConfigText(runtimeEnv.HWLAB_CODE_AGENT_DEFAULT_PROVIDER_PROFILE),
      agentRunManagerHost: safeOtelUrlHost(runtimeEnv.AGENTRUN_MGR_URL ?? runtimeEnv.HWLAB_CODE_AGENT_AGENTRUN_MGR_URL),
      agentRunRunnerNamespace: safeOtelConfigText(runtimeEnv.HWLAB_CODE_AGENT_AGENTRUN_RUNNER_NAMESPACE ?? runtimeEnv.AGENTRUN_RUNTIME_NAMESPACE),
      agentRunSourceCommitPresent: Boolean(firstNonEmptyValue(runtimeEnv.HWLAB_CODE_AGENT_AGENTRUN_SOURCE_COMMIT))
    }
  });
  if (adapterEnabled) {
    const realtimeCapabilities = workbenchRealtimeCapabilities(runtimeEnv);
    const transactionalAdmission = realtimeCapabilities.transactionalProjector;
    const pendingPromotion = results.get(traceId);
    if (pendingPromotion?.admissionState === "promotion-pending" && pendingPromotion?.agentRun?.durableDispatch === true) {
      const retryParams = { ...params, userBillingReservation: pendingPromotion.userBillingReservation ?? null };
      try {
        await promoteCodeAgentTurnAdmission({ payload: pendingPromotion, params: retryParams, options, traceId });
      } catch (error) {
        throw codeAgentPromotionUnavailableError(error, { payload: pendingPromotion, params: retryParams, options, traceId });
      }
      const promoted = annotateOwner({ ...pendingPromotion, accepted: true, status: "running", admissionState: "promoted" }, retryParams);
      results.set(traceId, promoted);
      return promoted;
    }

    const lifecycle = codeAgentTurnLifecycleFields(traceId, params);
    if (transactionalAdmission) {
      await persistCodeAgentAdmissionInputState({
        params,
        options,
        traceId,
        status: "admitting",
        messageId: lifecycle.userMessageId
      });
    }

    traceStore.append(traceId, {
      type: "request",
      status: "admitting",
      label: "turn:admitting",
      message: "Code Agent turn is validating billing and durable AgentRun dispatch before UI admission.",
      terminal: false,
      waitingFor: "billing-and-durable-dispatch",
      valuesPrinted: false
    });
    const initial = initialAgentRunChatResult({ params, options, traceId });
    const billingStartedAt = Date.now();
    const billingPreflight = await preflightCodeAgentBilling({ params, options, traceId, sendResponse: false });
    void emitCodeAgentOtelSpan("billing_preflight", traceId, options.env ?? process.env, {
      startTimeMs: billingStartedAt,
      attributes: { sessionId: safeSessionId(params.sessionId) || null, turnId: codeAgentTurnLifecycleFields(traceId, params).turnId, blocked: Boolean(billingPreflight?.blocked) },
      status: billingPreflight?.blocked ? "error" : "ok",
      error: billingPreflight?.blocked ? billingPreflight?.payload?.error?.message ?? billingPreflight?.blocker?.summary ?? "billing preflight blocked" : null
    });
    if (billingPreflight?.blocked) {
      if (transactionalAdmission) {
        await persistCodeAgentAdmissionInputState({
          params,
          options,
          traceId,
          status: "blocked",
          messageId: lifecycle.userMessageId,
          error: billingPreflight.payload?.error ?? billingPreflight.blocker ?? { code: "billing_preflight_blocked" }
        });
      }
      traceStore.append(traceId, {
        type: "billing",
        status: "blocked",
        label: "billing:preflight:blocked-before-admission",
        errorCode: billingPreflight.payload?.error?.code ?? billingPreflight.blocker?.code ?? "billing_preflight_blocked",
        terminal: false,
        valuesPrinted: false
      });
      throw codeAgentSubmissionUnavailableError(billingPreflight, { params, options, traceId });
    }

    const dispatchParams = {
      ...params,
      ...lifecycle,
      userBillingReservation: billingPreflight?.reservation ?? null
    };
    const executionOptions = { ...options, ...(await codeAgentChatExecutionOptions(options, dispatchParams)) };
    const dispatchStartedAt = Date.now();
    let payload;
    try {
      payload = await submitAgentRunChatTurn({ params: dispatchParams, options: executionOptions, traceId, traceStore, results });
    } catch (error) {
      const failure = codeAgentDispatchFailure(error);
      const rejected = codeAgentSubmissionUnavailablePayload(failure, { params: dispatchParams, options: executionOptions, traceId });
      await finalizeCodeAgentBillingUsage({ payload: rejected, params: dispatchParams, options: executionOptions });
      if (transactionalAdmission) {
        await persistCodeAgentAdmissionInputState({
          params: dispatchParams,
          options: executionOptions,
          traceId,
          status: "failed",
          messageId: lifecycle.userMessageId,
          error: failure.payload?.error ?? error
        });
      }
      void emitCodeAgentOtelSpan("agentrun_dispatch", traceId, executionOptions.env ?? process.env, {
        startTimeMs: dispatchStartedAt,
        status: "error",
        error,
        attributes: { sessionId: safeSessionId(dispatchParams.sessionId) || null, turnId: codeAgentTurnLifecycleFields(traceId, dispatchParams).turnId, ...codeAgentDispatchErrorOtelAttributes(error) }
      });
      throw codeAgentSubmissionUnavailableError(failure, { params: dispatchParams, options: executionOptions, traceId });
    }
    void emitCodeAgentOtelSpan("agentrun_dispatch", traceId, executionOptions.env ?? process.env, {
      startTimeMs: dispatchStartedAt,
      attributes: { sessionId: safeSessionId(dispatchParams.sessionId) || null, turnId: codeAgentTurnLifecycleFields(traceId, dispatchParams).turnId, runId: payload?.agentRun?.runId ?? null, commandId: payload?.agentRun?.commandId ?? null, providerProfile: dispatchParams.providerProfile ?? null }
    });
    const pending = annotateOwner({
      ...withCodeAgentBillingReservation(payload, dispatchParams),
      accepted: false,
      status: "admitting",
      admissionState: "promotion-pending"
    }, dispatchParams);
    results.set(traceId, pending);
    try {
      if (transactionalAdmission) {
        await persistCodeAgentAdmissionInputState({
          params: dispatchParams,
          options: executionOptions,
          traceId,
          status: "admitting",
          messageId: lifecycle.userMessageId,
          commandId: payload.agentRun?.commandId ?? null,
          agentRun: payload.agentRun ?? null
        });
      }
      await promoteCodeAgentTurnAdmission({ payload: pending, params: dispatchParams, options: executionOptions, traceId });
    } catch (error) {
      throw codeAgentPromotionUnavailableError(error, { payload: pending, params: dispatchParams, options: executionOptions, traceId });
    }
    const promoted = annotateOwner({ ...pending, accepted: true, status: "running", admissionState: "promoted" }, dispatchParams);
    results.set(traceId, promoted);
    return promoted;
  }
  await recordCodeAgentTurnAdmission({ payload: acceptedPayload, params, options, traceId });
  results.set(traceId, annotateOwner(acceptedPayload, params));
  traceStore.ensure(traceId, {
    runnerKind: "codex-app-server-stdio-runner",
    workspace: options.workspace ?? options.env?.HWLAB_CODE_AGENT_CODEX_WORKSPACE ?? options.env?.HWLAB_CODE_AGENT_WORKSPACE ?? null,
    sandbox: options.env?.HWLAB_CODE_AGENT_CODEX_SANDBOX ?? null,
    sessionMode: "codex-app-server-stdio-long-lived",
    implementationType: "repo-owned-codex-app-server-stdio-session"
  });
  traceStore.append(traceId, {
    type: "request",
    status: "accepted",
    label: "request:accepted-short-connection",
    message: "Code Agent request accepted; committed progress is delivered through the Workbench projection event stream.",
    waitingFor: "codex-stdio"
  });

  const run = async () => {
    try {
      const billingStartedAt = Date.now();
      const billingPreflight = await preflightCodeAgentBilling({ params, options, traceId, sendResponse: false });
      void emitCodeAgentOtelSpan("billing_preflight", traceId, options.env ?? process.env, {
        startTimeMs: billingStartedAt,
        attributes: { sessionId: safeSessionId(params.sessionId) || null, turnId: codeAgentTurnLifecycleFields(traceId, params).turnId, blocked: Boolean(billingPreflight?.blocked) },
        status: billingPreflight?.blocked ? "error" : "ok",
        error: billingPreflight?.blocked ? billingPreflight?.payload?.error?.message ?? billingPreflight?.blocker?.summary ?? "billing preflight blocked" : null
      });
      if (billingPreflight?.blocked) {
        await settleAdmittedCodeAgentFailure({
          base: codeAgentAdmittedFailureBasePayload({ params, options, traceId }),
          params,
          options,
          traceId,
          results,
          failure: billingPreflight,
          traceLabel: "billing:preflight:failed"
        });
        return;
      }
      const dispatchParams = { ...params, userBillingReservation: billingPreflight?.reservation ?? null };
      const payload = await runCodeAgentChat(dispatchParams, options);
      if (isCodeAgentResultCanceled(results.get(traceId))) return;
      await finalizeCodeAgentBillingUsage({ payload, params: dispatchParams, options });
      await recordCodeAgentSessionOwner({ payload, params: dispatchParams, options, status: codeAgentOwnerStatusForResult(payload) });
      results.set(traceId, annotateOwner(payload, dispatchParams));
      traceStore.append(traceId, {
        type: "result",
        status: payload.status === "completed" ? "completed" : "failed",
        label: `result:${payload.status}`,
        message: payload.status === "completed"
          ? "Code Agent result is committed to the Workbench projection event stream."
          : payload.error?.message ?? "Code Agent completed without a successful reply.",
        sessionId: payload.sessionId ?? payload.session?.sessionId,
        sessionStatus: payload.session?.status,
        terminal: true
      });
    } catch (error) {
      if (isCodeAgentResultCanceled(results.get(traceId))) return;
      const payload = {
        status: "failed",
        traceId,
        conversationId: safeConversationId(params.conversationId) || null,
        sessionId: safeSessionId(params.sessionId) || null,
        error: {
          code: "code_agent_background_failed",
          layer: "api",
          retryable: true,
          message: error?.message ?? "Code Agent background turn failed",
          userMessage: "Code Agent 后台任务失败；错误已提交到 Workbench 实时投影。"
        },
        updatedAt: new Date().toISOString()
      };
      await finalizeCodeAgentBillingUsage({ payload, params, options });
      results.set(traceId, payload);
      traceStore.append(traceId, {
        type: "result",
        status: "failed",
        label: "result:failed",
        errorCode: payload.error.code,
        message: payload.error.message,
        terminal: true
      });
    }
  };
  setImmediate(() => {
    run();
  });
  return annotateOwner(acceptedPayload, params);
}

async function recordCodeAgentTurnAdmission({ payload = {}, params = {}, options = {}, traceId } = {}) {
  const traceStore = options.traceStore ?? defaultCodeAgentTraceStore;
  let ownerRecord = null;
  try {
    ownerRecord = await recordCodeAgentSessionOwner({ payload, params, options, status: "running" });
    if (!ownerRecord) {
      const error = new Error("Code Agent turn admission did not durably persist Workbench session ownership.");
      error.code = "workbench_admission_owner_not_persisted";
      error.valuesRedacted = true;
      throw error;
    }
    await writeWorkbenchSessionAdmissionFact({
      runtimeStore: options.runtimeStore,
      session: ownerRecord,
      ownerUserId: options.actor?.id ?? params.ownerUserId,
      ownerRole: options.actor?.role ?? params.ownerRole,
      projectId: params.projectId ?? ownerRecord.projectId ?? null,
      conversationId: params.conversationId ?? ownerRecord.conversationId ?? null,
      threadId: params.threadId ?? ownerRecord.threadId ?? null,
      status: "running"
    });
    await recordCodeAgentSessionInputFact({
      params,
      options,
      traceId,
      delivery: "queue",
      status: "admitted",
      messageId: codeAgentTurnLifecycleFields(traceId, params).userMessageId,
      commandId: payload.agentRun?.commandId ?? null
    });
  } catch (error) {
    throw codeAgentAdmissionUnavailableError(error, { params, options, traceId });
  }
  traceStore.append(traceId, {
    type: "request",
    status: "admitted",
    label: "turn:admitted",
    message: "Code Agent turn was durably admitted before billing or dispatch preflight.",
    sessionId: safeSessionId(params.sessionId) || null,
    threadId: safeOpaqueId(params.threadId) || null,
    ...codeAgentOtelTraceFields(traceId, options.env ?? process.env),
    waitingFor: "billing-or-dispatch",
    valuesPrinted: false
  });
  void emitCodeAgentOtelSpan("durable_admission", traceId, options.env ?? process.env, {
    attributes: { sessionId: safeSessionId(params.sessionId) || null, threadId: safeOpaqueId(params.threadId) || null, turnId: codeAgentTurnLifecycleFields(traceId, params).turnId }
  });
  return ownerRecord;
}

async function promoteCodeAgentTurnAdmission({ payload = {}, params = {}, options = {}, traceId } = {}) {
  const traceStore = options.traceStore ?? defaultCodeAgentTraceStore;
  const ownerRecord = await recordCodeAgentSessionOwner({ payload, params, options, status: "admitting" });
  if (!ownerRecord) {
    const error = new Error("Code Agent turn promotion did not durably persist the admitting owner record.");
    error.code = "workbench_admission_owner_not_persisted";
    throw error;
  }
  const lifecycle = codeAgentTurnLifecycleFields(traceId, params);
  const realtimeCapabilities = workbenchRealtimeCapabilities(options.env ?? process.env);
  if (!realtimeCapabilities.transactionalProjector) {
    const runningOwner = await recordCodeAgentSessionOwner({ payload: { ...payload, status: "running" }, params, options, status: "running" });
    if (!runningOwner) {
      const error = new Error("Code Agent live turn did not durably promote the session owner to running.");
      error.code = "workbench_admission_owner_not_promoted";
      error.valuesRedacted = true;
      throw error;
    }
    traceStore.append(traceId, {
      type: "request",
      status: "admitted",
      label: "turn:admitted-live-kafka",
      message: "Code Agent turn is live after AgentRun durable dispatch; lifecycle visibility is owned by hwlab.event.v1 without transactional outbox promotion.",
      sessionId: safeSessionId(params.sessionId) || null,
      runId: payload.agentRun?.runId ?? null,
      commandId: payload.agentRun?.commandId ?? null,
      dispatchIntentId: payload.agentRun?.dispatchIntentId ?? null,
      waitingFor: "hwlab-live-kafka-sse",
      terminal: false,
      valuesPrinted: false
    });
    return { written: false, promoted: true, outboxCommitted: false, realtimeCapabilities, liveOnly: realtimeCapabilities.liveKafkaSse, valuesPrinted: false };
  }
  const inputFact = buildCodeAgentSessionInputFact({
    params,
    options,
    traceId,
    delivery: "queue",
    status: "promoted",
    messageId: lifecycle.userMessageId,
    commandId: payload.agentRun?.commandId ?? null,
    agentRun: payload.agentRun ?? null
  });
  const promotion = await persistWorkbenchTurnAdmissionPromotion({
    runtimeStore: options.runtimeStore,
    session: ownerRecord,
    inputFact,
    payload,
    params,
    ownerUserId: options.actor?.id ?? params.ownerUserId,
    ownerRole: options.actor?.role ?? params.ownerRole,
    projectId: params.projectId ?? ownerRecord.projectId ?? null,
    conversationId: params.conversationId ?? ownerRecord.conversationId ?? null,
    threadId: payload.agentRun?.threadId ?? params.threadId ?? ownerRecord.threadId ?? null
  });
  const runningOwner = await recordCodeAgentSessionOwner({ payload: { ...payload, status: "running" }, params, options, status: "running" });
  if (!runningOwner) {
    const error = new Error("Code Agent turn promotion did not durably promote the session owner to running.");
    error.code = "workbench_admission_owner_not_promoted";
    error.valuesRedacted = true;
    throw error;
  }
  traceStore.append(traceId, {
    type: "request",
    status: "admitted",
    label: "turn:admitted",
    message: "Code Agent turn was promoted only after billing and durable AgentRun dispatch admission committed.",
    sessionId: safeSessionId(params.sessionId) || null,
    threadId: safeOpaqueId(payload.agentRun?.threadId ?? params.threadId) || null,
    runId: payload.agentRun?.runId ?? null,
    commandId: payload.agentRun?.commandId ?? null,
    dispatchIntentId: payload.agentRun?.dispatchIntentId ?? null,
    runnerJobId: payload.agentRun?.runnerJobId ?? null,
    waitingFor: "agentrun-kafka-projection",
    terminal: false,
    valuesPrinted: false
  });
  void emitCodeAgentOtelSpan("durable_admission", traceId, options.env ?? process.env, {
    attributes: {
      sessionId: safeSessionId(params.sessionId) || null,
      threadId: safeOpaqueId(payload.agentRun?.threadId ?? params.threadId) || null,
      turnId: lifecycle.turnId,
      runId: payload.agentRun?.runId ?? null,
      commandId: payload.agentRun?.commandId ?? null,
      dispatchIntentId: payload.agentRun?.dispatchIntentId ?? null,
      outboxCommitted: promotion?.outboxCommitted === true
    }
  });
  return promotion;
}

async function persistCodeAgentAdmissionInputState({ params = {}, options = {}, traceId, status, messageId = null, commandId = null, agentRun = null, error = null } = {}) {
  try {
    const written = await recordCodeAgentSessionInputFact({
      params,
      options,
      traceId,
      delivery: "queue",
      status,
      messageId,
      commandId,
      agentRun,
      error
    });
    if (written?.written !== true) {
      const unavailable = new Error("Code Agent admission input state was not durably persisted.");
      unavailable.code = "workbench_admission_input_not_persisted";
      unavailable.valuesRedacted = true;
      throw unavailable;
    }
    return written;
  } catch (cause) {
    throw codeAgentAdmissionUnavailableError(cause, { params, options, traceId });
  }
}

function codeAgentAdmissionUnavailableError(error, { params = {}, options = {}, traceId } = {}) {
  const payload = codeAgentAdmissionUnavailablePayload({ error, params, options, traceId });
  return Object.assign(new Error(payload.error.message), {
    code: "admission_unavailable",
    statusCode: 503,
    payload,
    alreadyClassified: true
  });
}

function isCodeAgentAdmissionUnavailableError(error) {
  return error?.code === "admission_unavailable" && error?.payload;
}

function isCodeAgentSubmissionUnavailableError(error) {
  return Boolean(error?.payload && Number.isInteger(error?.statusCode) && (
    isCodeAgentAdmissionUnavailableError(error)
    || error.code === "submission_unavailable"
    || error.code === "admission_promotion_unavailable"
  ));
}

function codeAgentSubmissionUnavailableError(failure = {}, context = {}) {
  const payload = codeAgentSubmissionUnavailablePayload(failure, context);
  return Object.assign(new Error(payload.error.message), {
    code: "submission_unavailable",
    statusCode: failure.statusCode ?? 503,
    payload,
    alreadyClassified: true
  });
}

function codeAgentSubmissionUnavailablePayload(failure = {}, { params = {}, options = {}, traceId } = {}) {
  const source = failure.payload ?? failure;
  const error = source.error ?? {};
  const blocker = source.blocker ?? null;
  const message = error.message ?? blocker?.summary ?? "Code Agent submission failed before durable admission.";
  const lifecycle = codeAgentTurnLifecycleFields(traceId, params);
  const resolvedTraceId = safeTraceId(traceId) || null;
  const failureIdentity = textValue(error.failureIdentity) || `admission:${lifecycle.assistantMessageId}`;
  const admission = source.admission && typeof source.admission === "object" ? source.admission : null;
  const failureFields = {
    failureKind: textValue(error.failureKind ?? blocker?.failureKind ?? error.code ?? blocker?.code) || "submission-unavailable",
    reason: textValue(error.reason ?? blocker?.reason) || "unknown-dispatch-failure",
    recoveryAction: textValue(error.recoveryAction ?? blocker?.recoveryAction) || "inspect-agentrun-diagnostic",
    failureIdentity,
    primaryPresentation: "assistant-message",
    traceId: resolvedTraceId,
    turnId: lifecycle.turnId,
    userMessageId: lifecycle.userMessageId,
    assistantMessageId: lifecycle.assistantMessageId,
    runId: textValue(error.runId ?? blocker?.runId ?? admission?.runId) || null,
    commandId: textValue(error.commandId ?? blocker?.commandId ?? admission?.commandId) || null,
    dispatchIntentId: textValue(error.dispatchIntentId ?? blocker?.dispatchIntentId ?? admission?.dispatchIntentId) || null,
    admissionState: textValue(error.admissionState ?? blocker?.admissionState ?? admission?.state) || "rejected-before-durable-dispatch",
    durableDispatch: admission?.durableDispatch === true,
    valuesPrinted: false
  };
  return {
    ...source,
    ok: false,
    accepted: false,
    status: "failed",
    traceId: safeTraceId(traceId) || null,
    ...codeAgentOtelTraceFields(traceId, options.env ?? process.env),
    ...lifecycle,
    conversationId: safeConversationId(params.conversationId) || null,
    sessionId: safeSessionId(params.sessionId) || null,
    threadId: safeOpaqueId(params.threadId) || null,
    error: {
      ...error,
      ...failureFields,
      code: error.code ?? blocker?.code ?? "submission_unavailable",
      layer: error.layer ?? blocker?.layer ?? "admission",
      retryable: error.retryable !== false,
      message,
      route: error.route ?? "/v1/agent/chat"
    },
    blocker: blocker ? { ...blocker, ...failureFields, summary: blocker.summary ?? message } : null,
    admission: {
      ...(admission ?? {}),
      state: failureFields.admissionState,
      runId: failureFields.runId,
      commandId: failureFields.commandId,
      dispatchIntentId: failureFields.dispatchIntentId,
      durableDispatch: failureFields.durableDispatch,
      valuesPrinted: false
    },
    valuesRedacted: true,
    secretMaterialStored: false
  };
}

function codeAgentPromotionUnavailableError(error, { payload = {}, params = {}, options = {}, traceId } = {}) {
  const message = error?.message ?? "Local Workbench admission promotion failed after AgentRun durable dispatch.";
  const responsePayload = codeAgentSubmissionUnavailablePayload({
    error: {
      code: "admission_promotion_unavailable",
      layer: "admission",
      retryable: true,
      message,
      userMessage: "AgentRun 已持久接纳本次请求，但本地可见性提交尚未完成；请使用同一 traceId 重试补提交。",
      admissionState: "promotion-pending",
      route: "/v1/agent/chat"
    },
    blocker: {
      code: "admission_promotion_unavailable",
      layer: "admission",
      retryable: true,
      summary: message
    },
    admission: {
      state: "promotion-pending",
      runId: payload.agentRun?.runId ?? null,
      commandId: payload.agentRun?.commandId ?? null,
      dispatchIntentId: payload.agentRun?.dispatchIntentId ?? null,
      durableDispatch: payload.agentRun?.durableDispatch === true,
      valuesPrinted: false
    }
  }, { params, options, traceId });
  responsePayload.admission = {
    state: "promotion-pending",
    runId: payload.agentRun?.runId ?? null,
    commandId: payload.agentRun?.commandId ?? null,
    dispatchIntentId: payload.agentRun?.dispatchIntentId ?? null,
    runnerJobId: payload.agentRun?.runnerJobId ?? null,
    durableDispatch: payload.agentRun?.durableDispatch === true,
    valuesRedacted: true
  };
  return Object.assign(new Error(message), {
    code: "admission_promotion_unavailable",
    statusCode: 503,
    payload: responsePayload,
    alreadyClassified: true
  });
}

function codeAgentAdmissionUnavailablePayload({ error, params = {}, options = {}, traceId } = {}) {
  const message = error?.message ?? "Code Agent turn admission is unavailable; the user message was not persisted.";
  return {
    ok: false,
    accepted: false,
    status: "failed",
    traceId: safeTraceId(traceId) || null,
    ...codeAgentOtelTraceFields(traceId, options.env ?? process.env),
    ...codeAgentTurnLifecycleFields(traceId, params),
    conversationId: safeConversationId(params.conversationId) || null,
    sessionId: safeSessionId(params.sessionId) || null,
    threadId: safeOpaqueId(params.threadId) || null,
    error: {
      code: "admission_unavailable",
      layer: "admission",
      retryable: true,
      message,
      userMessage: "本次输入尚未持久化，请保留草稿后重试。",
      route: "/v1/agent/chat"
    },
    blocker: {
      code: "admission_unavailable",
      layer: "admission",
      retryable: true,
      summary: message
    },
    valuesRedacted: true,
    secretMaterialStored: false
  };
}

function codeAgentDispatchFailure(error) {
  const failure = classifyCodeAgentDispatchFailure(error);
  const failureFields = {
    failureKind: failure.failureKind,
    reason: failure.reason,
    retryable: failure.retryable,
    userMessage: failure.userMessage,
    recoveryAction: failure.recoveryAction,
    dispatchStage: failure.dispatchStage,
    upstreamTraceId: failure.upstreamTraceId,
    runId: failure.runId,
    commandId: failure.commandId,
    dispatchIntentId: failure.dispatchIntentId,
    admissionState: "rejected-before-durable-dispatch",
    valuesPrinted: false
  };
  return {
    statusCode: 503,
    payload: {
      error: {
        ...failureFields,
        code: failure.failureKind,
        layer: "agentrun",
        message: failure.message,
        route: "/v1/agent/chat"
      },
      blocker: {
        ...failureFields,
        code: failure.failureKind,
        layer: "agentrun",
        summary: failure.message
      },
      admission: {
        state: "rejected-before-durable-dispatch",
        runId: failure.runId,
        commandId: failure.commandId,
        dispatchIntentId: failure.dispatchIntentId,
        durableDispatch: false,
        valuesPrinted: false
      }
    }
  };
}

function codeAgentDispatchErrorOtelAttributes(error) {
  const agentRunError = error?.agentRunError && typeof error.agentRunError === "object" ? error.agentRunError : null;
  const details = agentRunError?.error?.details && typeof agentRunError.error.details === "object" ? agentRunError.error.details : null;
  return {
    failureKind: safeOtelText(error?.code ?? agentRunError?.failureKind, 120),
    upstreamStatusCode: Number.isInteger(error?.statusCode) ? error.statusCode : null,
    upstreamTraceId: safeTraceId(agentRunError?.traceId) || null,
    upstreamMessage: safeOtelText(agentRunError?.message ?? error?.message, 300),
    upstreamStderrTail: safeOtelText(details?.stderr, 600)
  };
}

function safeOtelText(value, limit = 300) {
  const text = String(value ?? "").replace(/[\u0000-\u001f\u007f]+/gu, " ").trim();
  return text ? text.slice(0, limit) : null;
}

function codeAgentAdmittedFailureBasePayload({ params = {}, options = {}, traceId } = {}) {
  const now = new Date().toISOString();
  return {
    accepted: true,
    status: "running",
    shortConnection: true,
    traceId,
    ...codeAgentTurnLifecycleFields(traceId, params),
    messageId: codeAgentTurnLifecycleFields(traceId, params).assistantMessageId,
    projectId: params.projectId ?? null,
    conversationId: safeConversationId(params.conversationId) || null,
    sessionId: safeSessionId(params.sessionId) || null,
    threadId: safeOpaqueId(params.threadId) || null,
    ...codeAgentAdmissionTimingFields(now),
    provider: codeAgentAgentRunAdapterEnabled(options.env ?? process.env) ? "agentrun" : "codex-stdio",
    model: options.env?.HWLAB_CODE_AGENT_MODEL ?? "unknown",
    backend: codeAgentAgentRunAdapterEnabled(options.env ?? process.env) ? "agentrun-v01" : "hwlab-cloud-api/code-agent-chat",
    valuesPrinted: false
  };
}

function codeAgentAdmissionTimingFields(value = null) {
  const admittedAt = timestampIsoOrNow(value);
  const timing = {
    startedAt: admittedAt,
    lastEventAt: admittedAt,
    finishedAt: null,
    durationMs: null,
    observedAt: admittedAt,
    lastEventAgeMs: 0,
    valuesRedacted: true
  };
  return {
    createdAt: admittedAt,
    updatedAt: admittedAt,
    timing,
    startedAt: admittedAt,
    lastEventAt: admittedAt,
    finishedAt: null,
    durationMs: null
  };
}

async function settleAdmittedCodeAgentFailure({ base = {}, params = {}, options = {}, traceId, results, failure = {}, traceLabel = "code-agent:failed" } = {}) {
  const traceStore = options.traceStore ?? defaultCodeAgentTraceStore;
  const error = failure.payload?.error ?? failure.error ?? {};
  const blocker = failure.payload?.blocker ?? failure.blocker ?? null;
  const message = error.message ?? blocker?.summary ?? "Code Agent request failed after admission.";
  traceStore.append(traceId, {
    type: "result",
    status: "failed",
    label: traceLabel,
    errorCode: error.code ?? "code_agent_failed_after_admission",
    message,
    terminal: true,
    valuesPrinted: false
  });
  const now = new Date().toISOString();
  const payload = annotateOwner({
    ...base,
    accepted: true,
    status: "failed",
    traceId,
    ...codeAgentTurnLifecycleFields(traceId, base),
    messageId: base.messageId ?? codeAgentTurnLifecycleFields(traceId, base).assistantMessageId,
    conversationId: safeConversationId(base.conversationId ?? params.conversationId) || null,
    sessionId: safeSessionId(base.sessionId ?? params.sessionId) || null,
    threadId: safeOpaqueId(base.threadId ?? params.threadId) || null,
    error: {
      code: error.code ?? "code_agent_failed_after_admission",
      layer: error.layer ?? blocker?.layer ?? "api",
      retryable: error.retryable !== false,
      message,
      userMessage: error.userMessage ?? message,
      route: error.route ?? "/v1/agent/chat"
    },
    blocker: blocker ? {
      code: blocker.code ?? error.code ?? "code_agent_failed_after_admission",
      layer: blocker.layer ?? error.layer ?? "api",
      retryable: blocker.retryable !== false,
      summary: blocker.summary ?? message
    } : null,
    finalResponse: {
      text: error.userMessage ?? message,
      textChars: String(error.userMessage ?? message).length,
      role: "assistant",
      status: "failed",
      traceId,
      updatedAt: now,
      source: "code-agent-admitted-failure",
      valuesPrinted: false
    },
    runnerTrace: traceStore.snapshot(traceId),
    updatedAt: now,
    valuesPrinted: false,
    secretMaterialStored: false
  }, params);
  await finalizeCodeAgentBillingUsage({ payload, params, options });
  payload.runnerTrace = traceStore.snapshot(traceId);
  recordCodeAgentConversationFact(payload, options);
  results?.set?.(traceId, payload);
  await recordCodeAgentSessionOwner({ payload, params, options, status: codeAgentOwnerStatusForResult(payload) });
  return payload;
}
