Files
pikasTech-HWLAB/internal/cloud/server-code-agent-http.ts
T

2643 lines
109 KiB
TypeScript

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,
refreshAgentRunTrace,
steerAgentRunChatTurn,
submitAgentRunChatTurn,
syncAgentRunChatResult
} 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 {
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_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",
"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 body = 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;
}
const traceId = safeTraceId(getHeader(request, "x-trace-id") || params.traceId) || `trc_${randomUUID()}`;
const chatParams = {
...params,
traceId,
ownerUserId: options.actor?.id ?? params.ownerUserId,
ownerRole: options.actor?.role ?? params.ownerRole
};
const manualSession = await prepareManualCodeAgentSession({ params: chatParams, options, traceId, response });
if (manualSession?.blocked) return;
const workspaceClaim = await claimWorkbenchWorkspaceTurn({ params: chatParams, options, traceId, response });
if (workspaceClaim?.blocked) return;
const billingPreflight = await preflightCodeAgentBilling({ params: chatParams, options, traceId, response });
if (billingPreflight?.blocked) return;
const nativeSessionChatParams = stripSyntheticConversationContext({ ...chatParams, userBillingReservation: billingPreflight?.reservation ?? null }, traceId, options);
if (codeAgentChatShortConnectionRequested(request, params, options)) {
submitCodeAgentChatTurn({
params: nativeSessionChatParams,
options,
traceId
});
const traceUrl = `/v1/agent/chat/trace/${encodeURIComponent(traceId)}`;
sendJson(response, 202, {
accepted: true,
status: "running",
shortConnection: true,
controlSemantics: "submit-and-poll",
traceId,
workspaceId: workspaceClaim?.workspace?.id ?? null,
workspaceRevision: workspaceClaim?.workspace?.revision ?? null,
conversationId: safeConversationId(nativeSessionChatParams.conversationId) || null,
sessionId: safeSessionId(nativeSessionChatParams.sessionId) || null,
traceUrl,
resultUrl: `/v1/agent/chat/result/${encodeURIComponent(traceId)}`,
streamUrl: `${traceUrl}/stream`,
cancelUrl: "/v1/agent/chat/cancel",
polling: {
resultIntervalMs: parsePositiveInteger(options.env?.HWLAB_CODE_AGENT_RESULT_POLL_INTERVAL_MS, 1000),
traceIntervalMs: parsePositiveInteger(options.env?.HWLAB_CODE_AGENT_TRACE_POLL_INTERVAL_MS, 1000)
},
runnerTrace: (options.traceStore ?? defaultCodeAgentTraceStore).snapshot(traceId)
});
return;
}
const payload = await runCodeAgentChat(nativeSessionChatParams, options);
await finalizeCodeAgentBillingUsage({ payload, params: nativeSessionChatParams, options });
await recordCodeAgentSessionOwner({ payload, params: nativeSessionChatParams, options, status: payload.status === "completed" ? "active" : payload.status });
const responsePayload = annotateOwner(payload, nativeSessionChatParams);
sendJson(response, responsePayload.status === "failed" && responsePayload.error?.code === "invalid_params" ? 400 : 200, responsePayload);
}
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 === "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
}
});
const workspace = await updateManualSessionWorkspace({ params, options, session, providerProfile, source: "code-agent-manual-session-create" });
sendJson(response, 201, {
ok: true,
status: "created",
contractVersion: "code-agent-manual-session-v1",
session: publicManualAgentSession(session),
workspace,
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 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;
}
const providerProfile = textValue(body.value.providerProfile) || session.session?.providerProfile || DEFAULT_CODE_AGENT_PROVIDER_PROFILE;
const workspace = await updateManualSessionWorkspace({ params: body.value, options, session, providerProfile, source: "code-agent-manual-session-select" });
sendJson(response, 200, {
ok: true,
status: "selected",
contractVersion: "code-agent-manual-session-v1",
session: publicManualAgentSession(session),
workspace,
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 };
}
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.`, 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 = textValue(params.projectId) || session.projectId || DEFAULT_CODE_AGENT_PROJECT_ID;
params.threadId = safeOpaqueId(params.threadId) || safeOpaqueId(session.threadId) || undefined;
return { session };
}
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;
}
async function updateManualSessionWorkspace({ params = {}, options = {}, session, providerProfile, source }) {
const store = options.accessController?.store;
if (!store || !options.actor?.id || !session) return null;
const workspaceId = safeWorkspaceId(params.workspaceId);
const projectId = textValue(params.projectId) || session.projectId || DEFAULT_CODE_AGENT_PROJECT_ID;
const current = workspaceId
? await store.getWorkspaceForUser?.({ workspaceId, ownerUserId: options.actor.id, actorRole: options.actor.role })
: await store.getOrCreateDefaultWorkspace?.({ ownerUserId: options.actor.id, projectId });
if (!current) return null;
const selectedActiveTraceId = manualSessionSelectableActiveTraceId(session);
const selectedLastTraceId = safeTraceId(session.lastTraceId) || selectedActiveTraceId || null;
const updated = await store.updateWorkspace?.({
workspaceId: current.id,
ownerUserId: options.actor.id,
actorRole: options.actor.role,
projectId: current.projectId ?? projectId,
name: current.name,
status: current.status,
selectedConversationId: session.conversationId,
selectedAgentSessionId: session.id,
activeTraceId: selectedActiveTraceId,
providerProfile,
patch: {
...(current.workspace && typeof current.workspace === "object" ? current.workspace : {}),
selectedConversationId: session.conversationId,
selectedAgentSessionId: session.id,
activeTraceId: selectedActiveTraceId,
...(selectedLastTraceId ? { lastTraceId: selectedLastTraceId } : {}),
sessionStatus: session.status,
threadId: safeOpaqueId(session.threadId) || null,
providerProfile,
source,
updatedAt: new Date().toISOString(),
valuesRedacted: true,
secretMaterialStored: false
},
updatedBySessionId: options.authSession?.id ?? null,
updatedByClient: textValue(params.updatedByClient ?? params.client) || source,
now: new Date().toISOString()
});
if (typeof options.accessController.publicWorkbenchWorkspace === "function") {
return await options.accessController.publicWorkbenchWorkspace(updated ?? current, options.actor);
}
return updated ?? current;
}
function manualSessionSelectableActiveTraceId(session = {}) {
if (!manualSessionHasRunningTraceStatus(session)) return null;
return safeTraceId(
session.currentTraceId
?? session.session?.currentTraceId
?? session.session?.traceId
?? session.session?.runnerTrace?.traceId
?? session.session?.agentRun?.traceId
) || safeTraceId(session.lastTraceId) || null;
}
function manualSessionHasRunningTraceStatus(session = {}) {
return [
session.status,
session.session?.sessionStatus,
session.session?.lifecycleStatus,
session.session?.runnerTrace?.sessionStatus,
session.session?.runnerTrace?.status,
session.session?.agentRun?.runStatus,
session.session?.agentRun?.commandState,
session.session?.agentRun?.terminalStatus
].map((value) => String(value ?? "").trim().toLowerCase().replace(/_/gu, "-"))
.some((value) => ["running", "busy", "pending", "creating"].includes(value));
}
function publicManualAgentSession(session) {
if (!session || typeof session !== "object") return null;
return {
sessionId: session.id,
projectId: session.projectId ?? null,
agentId: session.agentId ?? "hwlab-code-agent",
status: session.status ?? null,
usable: manualSessionUsable(session.status),
conversationId: safeConversationId(session.conversationId) || null,
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 !["failed", "timeout", "canceled", "cancelled", "error", "blocked", "expired", "interrupted", "stale", "thread-resume-failed"].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 runtimeNamespace = runtimeNamespaceForEnv(env);
const runtimeLane = runtimeLaneForNamespace(runtimeNamespace) ?? runtimeLaneForEnv(env);
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 profile = String(firstNonEmptyValue(env.HWLAB_RUNTIME_LANE, env.HWLAB_GITOPS_LANE, env.HWLAB_GITOPS_PROFILE, env.HWLAB_ENVIRONMENT, env.HWLAB_BOOT_REF, "dev") ?? "dev").trim().toLowerCase();
if (profile === "prod" || profile === "production") return "prod";
if (profile === "v02" || profile === "v0.2" || profile === "0.2") return "v02";
return "dev";
}
function runtimeLaneForNamespace(namespace) {
if (namespace === "hwlab-v02") return "v02";
if (namespace === "hwlab-prod") return "prod";
if (namespace === "hwlab-dev") return "dev";
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();
if (/hwlab-v02|:19666(?:\/|$)|:19667(?:\/|$)/u.test(text)) return "v02";
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 defaultRuntimeNamespace(env = process.env) {
const profile = runtimeLaneForEnv(env);
if (profile === "prod") return "hwlab-prod";
if (profile === "v02") return "hwlab-v02";
return "hwlab-dev";
}
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 ?? 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 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 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 firstNonEmptyValue(...values) {
for (const value of values) {
const text = String(value ?? "").trim();
if (text) return text;
}
return null;
}
function submitCodeAgentChatTurn({ params, options, traceId }) {
const traceStore = options.traceStore ?? defaultCodeAgentTraceStore;
const results = options.codeAgentChatResults ?? createCodeAgentChatResultStore();
if (codeAgentAgentRunAdapterEnabled(options.env ?? process.env)) {
const initial = withCodeAgentBillingReservation(initialAgentRunChatResult({ params, options, traceId }), params);
results.set(traceId, annotateOwner(initial, params));
const run = async () => {
let executionOptions = options;
try {
executionOptions = { ...options, ...(await codeAgentChatExecutionOptions(options, params)) };
const payload = await submitAgentRunChatTurn({ params, options: executionOptions, traceId, traceStore, results });
if (isCodeAgentResultCanceled(results.get(traceId))) return;
const owned = annotateOwner(withCodeAgentBillingReservation(payload, params), params);
await recordCodeAgentSessionOwner({ payload: owned, params, options: executionOptions, status: "running" });
results.set(traceId, owned);
} catch (error) {
if (isCodeAgentResultCanceled(results.get(traceId))) return;
const payload = annotateOwner({
...initial,
status: "failed",
error: {
code: error?.code ?? "agentrun_dispatch_failed",
layer: "agentrun",
retryable: true,
message: error?.message ?? "AgentRun dispatch failed",
userMessage: "AgentRun 调度失败;trace/result 轮询已保留错误。"
},
blocker: {
code: error?.code ?? "agentrun_dispatch_failed",
layer: "agentrun",
retryable: true,
summary: error?.message ?? "AgentRun dispatch failed"
},
runnerTrace: traceStore.snapshot(traceId),
updatedAt: new Date().toISOString()
}, params);
recordCodeAgentConversationFact(payload, executionOptions);
await finalizeCodeAgentBillingUsage({ payload, params, options: executionOptions });
results.set(traceId, payload);
traceStore.append(traceId, {
type: "result",
status: "failed",
label: "agentrun:dispatch:failed",
errorCode: payload.error.code,
message: payload.error.message,
terminal: true
});
await recordCodeAgentSessionOwner({ payload, params, options: executionOptions, status: "failed" });
}
};
setImmediate(() => { run(); });
return;
}
results.set(traceId, {
accepted: true,
status: "running",
traceId,
conversationId: safeConversationId(params.conversationId) || null,
sessionId: safeSessionId(params.sessionId) || null,
updatedAt: new Date().toISOString()
});
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; client must poll trace/result with short HTTP requests.",
waitingFor: "codex-stdio"
});
const run = async () => {
try {
const payload = await runCodeAgentChat(params, options);
if (isCodeAgentResultCanceled(results.get(traceId))) return;
await finalizeCodeAgentBillingUsage({ payload, params, options });
await recordCodeAgentSessionOwner({ payload, params, options, status: payload.status === "completed" ? "active" : payload.status });
results.set(traceId, annotateOwner(payload, params));
traceStore.append(traceId, {
type: "result",
status: payload.status === "completed" ? "completed" : "failed",
label: `result:${payload.status}`,
message: payload.status === "completed"
? "Code Agent result is ready for short-connection polling."
: 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 后台任务失败;trace/result 轮询已保留错误。"
},
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();
});
}
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 } = {}) {
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;
sendJson(response, status, {
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
});
return { blocked: true };
}
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;
}
export async function handleCodeAgentChatResultHttp(request, response, url, options) {
const parts = url.pathname.split("/").filter(Boolean);
const traceId = decodeURIComponent(parts[4] ?? "");
if (!safeTraceId(traceId)) {
sendJson(response, 400, {
error: {
code: "invalid_trace_id",
message: "traceId must start with trc_ and contain only safe identifier characters"
}
});
return;
}
const results = options.codeAgentChatResults;
const result = results?.get(traceId) ?? null;
if (result && !canAccessOwnedResult(result, options.actor)) {
sendJson(response, 403, {
error: {
code: "agent_session_owner_required",
message: "Only the session owner or admin can read this Code Agent result"
}
});
return;
}
const adapterEnabled = codeAgentAgentRunAdapterEnabled(options.env ?? process.env);
if ((result?.agentRun?.runId && adapterEnabled) || (!result && adapterEnabled)) {
try {
const synced = await syncAgentRunChatResult({ traceId, currentResult: result, options, traceStore: options.traceStore ?? defaultCodeAgentTraceStore });
if (synced.result && !canAccessOwnedResult(synced.result, options.actor)) {
sendJson(response, 403, {
error: {
code: "agent_session_owner_required",
message: "Only the session owner or admin can read this Code Agent result"
}
});
return;
}
if (synced.result && synced.result.status !== "running") {
await finalizeCodeAgentBillingUsage({ payload: synced.result, params: synced.result, options });
recordCodeAgentConversationFact(synced.result, options);
await recordCodeAgentSessionOwner({ payload: synced.result, params: synced.result, options, status: codeAgentOwnerStatusForResult(synced.result) });
sendJson(response, 200, compactCodeAgentChatResultPayload(synced.result, options));
return;
}
if (synced.result) {
sendJson(response, 202, {
accepted: true,
status: "running",
shortConnection: true,
traceId,
agentRun: synced.result.agentRun,
runnerTrace: compactRunnerTraceForResult(synced.runnerTrace, resultTraceEventLimit(options)),
waitingFor: synced.runnerTrace?.waitingFor ?? "agentrun-result"
});
return;
}
} catch (error) {
const traceStore = options.traceStore ?? defaultCodeAgentTraceStore;
traceStore.append(traceId, {
type: "result",
status: "degraded",
label: "agentrun:result:poll-failed",
errorCode: error?.code ?? "agentrun_result_poll_failed",
message: error?.message ?? "AgentRun result polling failed",
waitingFor: "agentrun-result"
});
if (result?.agentRun && result.status === "running") {
sendJson(response, 202, {
accepted: true,
status: "running",
shortConnection: true,
traceId,
agentRun: result.agentRun,
runnerTrace: compactRunnerTraceForResult(traceStore.snapshot(traceId), resultTraceEventLimit(options)),
waitingFor: "agentrun-result",
degraded: true,
error: { code: error?.code ?? "agentrun_result_poll_failed", message: error?.message ?? "AgentRun result polling failed" }
});
return;
}
if (result?.agentRun) {
sendJson(response, error?.statusCode === 404 ? 404 : 502, {
error: {
code: error?.code ?? "agentrun_result_poll_failed",
message: error?.message ?? "AgentRun result polling failed",
traceId,
runId: result.agentRun.runId ?? null,
commandId: result.agentRun.commandId ?? null
}
});
return;
}
}
}
if (result && result.status !== "running") {
sendJson(response, 200, compactCodeAgentChatResultPayload(result, options));
return;
}
const traceStore = options.traceStore ?? defaultCodeAgentTraceStore;
const runnerTrace = traceStore.snapshot(traceId);
if (result || runnerTrace.status !== "missing") {
sendJson(response, 202, {
accepted: true,
status: "running",
shortConnection: true,
traceId,
runnerTrace: compactRunnerTraceForResult(runnerTrace, resultTraceEventLimit(options)),
waitingFor: runnerTrace.waitingFor ?? "codex-stdio"
});
return;
}
sendJson(response, 404, {
error: {
code: "code_agent_result_not_found",
message: `No Code Agent result is registered for ${traceId}`
}
});
}
export async function handleCodeAgentInspectHttp(request, response, url, options) {
const query = {
conversationId: safeConversationId(url.searchParams.get("conversationId")),
sessionId: safeSessionId(url.searchParams.get("sessionId")),
threadId: safeOpaqueId(url.searchParams.get("threadId")),
traceId: safeTraceId(url.searchParams.get("traceId"))
};
const sessionRegistry = options.sessionRegistry;
const traceStore = options.traceStore ?? defaultCodeAgentTraceStore;
const manager = options.codexStdioManager;
const managerDescription = manager && typeof manager.describe === "function" ? manager.describe() : null;
const managerRecentSessions = Array.isArray(managerDescription?.recentSessions) ? managerDescription.recentSessions : [];
const directManagerSession = query.sessionId && manager && typeof manager.get === "function"
? manager.get(query.sessionId, { conversationId: query.conversationId })
: null;
const matchedManagerSession = directManagerSession ?? managerRecentSessions.find((session) => sessionMatchesInspectQuery(session, query)) ?? null;
const registryInspect = sessionRegistry && typeof sessionRegistry.inspect === "function"
? sessionRegistry.inspect(query)
: { ok: false, status: "unavailable", traceIds: [], session: null, conversationFacts: null };
const resultEvidence = await codeAgentInspectResultEvidence(query.traceId, options);
const session = matchedManagerSession ?? registryInspect.session ?? resultEvidence.session ?? null;
const conversationFacts = registryInspect.conversationFacts ?? resultEvidence.conversationFacts ?? null;
const requestedRunnerTrace = query.traceId ? traceStore.snapshot(query.traceId) : null;
const requestedTraceFound = Boolean(requestedRunnerTrace && requestedRunnerTrace.status !== "missing");
const traceIds = uniqueStrings([
requestedTraceFound ? query.traceId : null,
session?.currentTraceId,
session?.lastTraceId,
conversationFacts?.latestTraceId,
resultEvidence.latestTraceId,
...(Array.isArray(conversationFacts?.traceIds) ? conversationFacts.traceIds : []),
...(Array.isArray(registryInspect.traceIds) ? registryInspect.traceIds : [])
]);
const latestTraceId = traceIds[0] ?? null;
const runnerTrace = latestTraceId
? latestTraceId === query.traceId && requestedRunnerTrace
? requestedRunnerTrace
: traceStore.snapshot(latestTraceId)
: null;
const found = Boolean(registryInspect.ok || session || latestTraceId);
sendJson(response, found ? 200 : 404, {
ok: found,
action: "code-agent.chat.inspect",
status: found ? "found" : "not_found",
query,
session,
conversationFacts,
traceIds,
latestTraceId,
traceUrl: latestTraceId ? `/v1/agent/chat/trace/${encodeURIComponent(latestTraceId)}` : null,
resultUrl: latestTraceId ? `/v1/agent/chat/result/${encodeURIComponent(latestTraceId)}` : null,
runnerTrace,
valuesRedacted: true,
secretMaterialStored: false
});
}
async function codeAgentInspectResultEvidence(traceId, options = {}) {
if (!safeTraceId(traceId)) return { session: null, conversationFacts: null, latestTraceId: null };
const cached = options.codeAgentChatResults?.get?.(traceId) ?? null;
const persisted = cached ? null : await loadPersistedAgentRunResult(traceId, options);
const result = cached ?? persisted ?? null;
if (!result || typeof result !== "object") return { session: null, conversationFacts: null, latestTraceId: null };
const agentRun = result.agentRun && typeof result.agentRun === "object" ? result.agentRun : null;
const resultSession = result.session && typeof result.session === "object" ? result.session : null;
const sessionReuse = result.sessionReuse && typeof result.sessionReuse === "object" ? result.sessionReuse : null;
const providerTrace = result.providerTrace && typeof result.providerTrace === "object" ? result.providerTrace : null;
const sessionId = safeSessionId(result.sessionId ?? resultSession?.sessionId ?? sessionReuse?.sessionId ?? agentRun?.sessionId) || null;
const conversationId = safeConversationId(result.conversationId ?? resultSession?.conversationId ?? sessionReuse?.conversationId ?? agentRun?.conversationId) || null;
const threadId = safeOpaqueId(result.threadId ?? resultSession?.threadId ?? sessionReuse?.threadId ?? providerTrace?.threadId ?? agentRun?.threadId) || null;
const status = textValue(resultSession?.status ?? result.status ?? agentRun?.status) || null;
const updatedAt = textValue(result.updatedAt ?? agentRun?.updatedAt ?? resultSession?.updatedAt) || null;
const session = sessionId || conversationId || threadId ? {
sessionId,
conversationId,
threadId,
status,
lastTraceId: traceId,
source: "code-agent-result",
agentRun: agentRun ? agentRunSessionEvidence(result).agentRun : null,
valuesRedacted: true,
secretMaterialStored: false
} : null;
const conversationFacts = conversationId ? {
conversationId,
sessionId,
threadId,
latestTraceId: traceId,
traceIds: [traceId],
turnCount: 1,
source: "code-agent-result",
latestStatus: status,
updatedAt,
valuesRedacted: true,
secretMaterialStored: false
} : null;
return { session, conversationFacts, latestTraceId: traceId };
}
function sessionMatchesInspectQuery(session, query) {
if (!session || typeof session !== "object") return false;
if (query.sessionId && session.sessionId === query.sessionId) return true;
if (query.threadId && session.threadId === query.threadId) return true;
if (query.conversationId && session.conversationId === query.conversationId) return true;
if (query.traceId && (session.currentTraceId === query.traceId || session.lastTraceId === query.traceId)) return true;
return false;
}
export async function handleCodeAgentCancelHttp(request, response, options) {
const body = 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",
layer: "api",
retryable: true
})
});
return;
}
if (!params || typeof params !== "object" || Array.isArray(params)) {
sendJson(response, 400, {
...createCodeAgentErrorPayload({
code: "invalid_params",
message: "Code Agent cancel body must be a JSON object",
traceId: getHeader(request, "x-trace-id") || "trc_unassigned",
layer: "api",
retryable: true
})
});
return;
}
const traceId = safeTraceId(getHeader(request, "x-trace-id") || params.traceId);
const traceStore = options.traceStore ?? defaultCodeAgentTraceStore;
const snapshot = traceId ? traceStore.snapshot(traceId) : null;
const currentResult = traceId ? options.codeAgentChatResults?.get(traceId) ?? await loadPersistedAgentRunResult(traceId, options) : null;
if (currentResult?.agentRun?.commandId) {
const payload = await cancelAgentRunChatTurn({ traceId, currentResult, options, traceStore });
if (payload) {
await recordCodeAgentSessionOwner({ payload, params: { ...params, traceId, ownerUserId: options.actor?.id, ownerRole: options.actor?.role }, options, status: "canceled" });
sendJson(response, 200, payload);
return;
}
}
const sessionId = safeSessionId(params.sessionId) || safeSessionId(snapshot?.sessionId);
const conversationId = safeConversationId(params.conversationId);
const manager = options.codexStdioManager;
if (!traceId) {
sendJson(response, 400, cancelBlockedPayload({
code: "cancel_trace_missing",
message: "traceId is required to cancel the current Code Agent request.",
traceId: "trc_unassigned",
conversationId,
sessionId
}));
return;
}
if (!manager || typeof manager.get !== "function" || typeof manager.cancel !== "function") {
traceStore.append(traceId, {
type: "cancel",
status: "unsupported",
label: "cancel:unsupported",
errorCode: "cancel_unsupported",
message: "Codex stdio cancel/interrupt backend is not available on this runtime.",
waitingFor: "session-control"
});
const runnerTrace = traceStore.snapshot(traceId);
sendJson(response, 501, cancelBlockedPayload({
code: "cancel_unsupported",
message: "当前后端不支持 Code Agent interrupt/cancel;本次按 unsupported/degraded 返回,不会静默假装已中断。",
traceId,
conversationId,
sessionId,
runnerTrace,
status: "degraded",
unsupported: true,
degraded: true
}));
return;
}
if (!sessionId) {
traceStore.append(traceId, {
type: "cancel",
status: "blocked",
label: "cancel:not_cancelable",
errorCode: "cancel_session_missing",
message: "Cancel request did not include a bound Codex stdio sessionId.",
waitingFor: "session-binding"
});
sendJson(response, 409, cancelBlockedPayload({
code: "cancel_session_missing",
message: "当前请求尚未暴露可取消的 Codex stdio sessionId;页面不能只隐藏 UI,已保留输入和 trace。",
traceId,
conversationId,
sessionId: null,
runnerTrace: traceStore.snapshot(traceId)
}));
return;
}
const currentSession = manager.get(sessionId, { conversationId }) ?? null;
if (!currentSession || !["busy", "creating"].includes(currentSession.status)) {
traceStore.append(traceId, {
type: "cancel",
status: "blocked",
label: "cancel:not_in_flight",
errorCode: "cancel_not_in_flight",
message: `Session ${sessionId} is not an in-flight Codex stdio request.`,
sessionId,
sessionStatus: currentSession?.status ?? "missing"
});
sendJson(response, 409, cancelBlockedPayload({
code: currentSession ? "cancel_not_in_flight" : "cancel_session_not_found",
message: currentSession
? `当前 session 状态为 ${currentSession.status},没有可取消的 in-flight Codex stdio 请求。`
: `没有找到 sessionId=${sessionId} 的 Codex stdio session。`,
traceId,
conversationId,
sessionId,
session: currentSession,
runnerTrace: traceStore.snapshot(traceId)
}));
return;
}
const canceledSession = manager.cancel(sessionId, {
traceId,
conversationId,
reason: "user_cancel"
});
traceStore.append(traceId, {
type: "cancel",
status: "canceled",
label: "cancel:canceled",
message: "User canceled the current Codex stdio request.",
sessionId,
sessionStatus: canceledSession?.status ?? "canceled",
sessionLifecycleStatus: codeAgentSessionLifecycleSummary({ session: canceledSession, status: "canceled" }).status,
waitingFor: "user-retry",
terminal: true
});
const runnerTraceSnapshot = traceStore.snapshot(traceId);
const sessionSummary = codeAgentSessionLifecycleSummary({
session: canceledSession,
runnerTrace: runnerTraceSnapshot,
status: "canceled"
});
const runnerTrace = {
...runnerTraceSnapshot,
sessionLifecycleStatus: sessionSummary.status
};
const payload = {
accepted: true,
canceled: true,
status: "canceled",
conversationId: conversationId ?? canceledSession?.conversationId ?? null,
sessionId,
traceId,
session: canceledSession,
sessionLifecycleStatus: sessionSummary.status,
sessionLifecycle: sessionSummary,
sessionSummary,
runnerTrace,
lastTraceEvent: runnerTrace.lastEvent,
retryable: true,
error: {
code: "codex_stdio_canceled",
layer: "session",
category: "canceled",
retryable: true,
message: "user canceled current Code Agent request",
userMessage: "当前 Codex stdio 请求已取消;输入、sessionId、traceId 和最后 trace event 已保留,可重试上一条消息。",
traceId,
route: "/v1/agent/chat/cancel",
toolName: "codex-stdio.cancel"
},
userMessage: "当前 Codex stdio 请求已取消;输入、sessionId、traceId 和最后 trace event 已保留,可重试上一条消息。",
updatedAt: new Date().toISOString()
};
await recordCodeAgentSessionOwner({ payload, params: { ...params, traceId, ownerUserId: options.actor?.id, ownerRole: options.actor?.role }, options, status: "canceled" });
recordCodeAgentConversationFact(payload, options);
options.codeAgentChatResults?.set(traceId, annotateOwner(payload, { ownerUserId: options.actor?.id, ownerRole: options.actor?.role }));
sendJson(response, 200, payload);
}
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;
}
}
export async function handleCodeAgentSteerHttp(request, response, options) {
const body = 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",
layer: "api",
retryable: true,
route: "/v1/agent/chat/steer"
})
});
return;
}
if (!params || typeof params !== "object" || Array.isArray(params)) {
sendJson(response, 400, {
...createCodeAgentErrorPayload({
code: "invalid_params",
message: "Code Agent steer body must be a JSON object",
traceId: getHeader(request, "x-trace-id") || "trc_unassigned",
layer: "api",
retryable: true,
route: "/v1/agent/chat/steer"
})
});
return;
}
const traceId = safeTraceId(getHeader(request, "x-trace-id") || params.traceId || params.targetTraceId);
const message = firstNonEmptyValue(params.message, params.prompt, params.text);
if (!traceId || !message) {
sendJson(response, 400, {
...createCodeAgentErrorPayload({
code: !traceId ? "steer_trace_missing" : "steer_message_missing",
message: !traceId ? "traceId is required to steer the current Code Agent turn." : "message is required to steer the current Code Agent turn.",
traceId: traceId || "trc_unassigned",
layer: "api",
retryable: true,
route: "/v1/agent/chat/steer"
})
});
return;
}
const traceStore = options.traceStore ?? defaultCodeAgentTraceStore;
const currentResult = options.codeAgentChatResults?.get?.(traceId) ?? await loadPersistedAgentRunResult(traceId, options);
if (!canAccessOwnedResult(currentResult, options.actor)) {
sendJson(response, 403, {
ok: false,
status: "forbidden",
traceId,
error: { code: "code_agent_trace_forbidden", message: "Code Agent trace is not visible to the current actor" }
});
return;
}
if (!currentResult?.agentRun?.runId || !currentResult?.agentRun?.commandId) {
await clearStaleWorkbenchSteerTrace({ params, options, traceId, reason: "steer-trace-not-found" });
sendJson(response, 404, {
ok: false,
status: "not_found",
traceId,
error: { code: "steer_trace_not_found", message: "No AgentRun-backed Code Agent turn was found for the requested traceId." },
route: "/v1/agent/chat/steer",
runnerTrace: traceStore.snapshot(traceId)
});
return;
}
try {
const payload = await steerAgentRunChatTurn({
traceId,
currentResult,
params: {
...params,
message,
ownerUserId: options.actor?.id ?? params.ownerUserId,
ownerRole: options.actor?.role ?? params.ownerRole
},
options,
traceStore
});
sendJson(response, 202, payload);
setImmediate(() => {
void recordCodeAgentSessionOwner({ payload: currentResult, params: { ...params, traceId, ownerUserId: options.actor?.id, ownerRole: options.actor?.role }, options, status: "running" });
});
} catch (error) {
traceStore.append(traceId, {
type: "backend",
status: "failed",
label: "agentrun:steer:failed",
errorCode: error?.code ?? "agentrun_steer_failed",
message: error?.message ?? "AgentRun steer command failed.",
terminal: false,
valuesPrinted: false
});
sendJson(response, error?.statusCode === 404 ? 404 : 409, {
ok: false,
accepted: false,
status: "failed",
traceId,
route: "/v1/agent/chat/steer",
conversationId: safeConversationId(currentResult.conversationId ?? params.conversationId) || null,
sessionId: safeSessionId(currentResult.sessionId ?? params.sessionId) || null,
threadId: safeOpaqueId(currentResult.threadId ?? params.threadId) || null,
agentRun: currentResult.agentRun,
runnerTrace: traceStore.snapshot(traceId),
error: {
code: error?.code ?? "agentrun_steer_failed",
layer: "agentrun",
category: "steer_failed",
retryable: true,
message: error?.message ?? "AgentRun steer command failed.",
traceId,
route: "/v1/agent/chat/steer",
toolName: "agentrun.command.steer"
}
});
}
}
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;
try {
return await options.accessController.recordAgentSessionOwner({
ownerUserId,
ownerRole: options.actor?.role ?? params.ownerRole ?? null,
sessionId,
projectId: params.projectId ?? payload.projectId ?? null,
conversationId,
threadId,
traceId: preserveLastTraceId ? undefined : traceId,
status,
session: codeAgentSessionOwnerEvidence(payload, params)
});
} catch (error) {
const traceStore = options.traceStore ?? defaultCodeAgentTraceStore;
if (traceId) {
traceStore.append(traceId, {
type: "session-owner",
status: "degraded",
label: "session-owner:persist-failed",
errorCode: "agent_session_owner_persist_failed",
message: error?.message ?? "Code Agent session owner binding persistence failed.",
valuesPrinted: false
});
}
return null;
}
}
function codeAgentOwnerStatusForResult(result = {}) {
if (result?.status === "completed") return "active";
if (result?.status === "canceled" || result?.status === "cancelled") return "canceled";
return result?.status ?? "active";
}
async function claimWorkbenchWorkspaceTurn({ params = {}, options = {}, traceId, response } = {}) {
const workspaceId = safeWorkspaceId(params.workspaceId);
if (!workspaceId || !options.accessController?.store || !options.actor) return null;
const store = options.accessController.store;
const workspace = await store.getWorkspaceForUser?.({ workspaceId, ownerUserId: options.actor.id, actorRole: options.actor.role });
if (!workspace) {
sendJson(response, 404, {
ok: false,
status: "failed",
error: { code: "workbench_workspace_not_found", message: "Workbench workspace is not visible to the current actor" },
workspaceId
});
return { blocked: true };
}
const expectedRevision = Number.parseInt(String(params.expectedWorkspaceRevision ?? params.workspaceRevision ?? ""), 10);
const workspaceRevisionConflict = Number.isInteger(expectedRevision) && expectedRevision > 0 && workspace.revision !== expectedRevision;
const requestedConversationId = safeConversationId(params.conversationId) || null;
const requestedSessionId = safeSessionId(params.sessionId) || null;
const nextSelectedConversationId = requestedConversationId || workspace.selectedConversationId;
const nextSelectedAgentSessionId = requestedSessionId || (requestedConversationId && requestedConversationId !== workspace.selectedConversationId ? null : workspace.selectedAgentSessionId);
const activeTraceId = safeTraceId(workspace.activeTraceId);
const activeTraceSnapshot = activeTraceId ? (options.traceStore ?? defaultCodeAgentTraceStore).snapshot(activeTraceId) : null;
const activeTraceOrphaned = Boolean(activeTraceId && isWorkbenchOrphanActiveTrace(activeTraceSnapshot));
if (activeTraceOrphaned) {
await store.updateWorkspace?.({
workspaceId,
ownerUserId: options.actor.id,
actorRole: options.actor.role,
selectedConversationId: workspace.selectedConversationId,
selectedAgentSessionId: workspace.selectedAgentSessionId,
activeTraceId: null,
providerProfile: workspace.providerProfile,
patch: {
...(workspace.workspace && typeof workspace.workspace === "object" ? workspace.workspace : {}),
activeTraceId: null,
staleActiveTraceId: activeTraceId,
staleActiveTraceReason: "orphan-cancel-session-missing",
sessionStatus: "failed",
updatedAt: new Date().toISOString(),
source: "code-agent-submit-active-trace-repair",
valuesRedacted: true,
secretMaterialStored: false
},
updatedBySessionId: options.authSession?.id ?? null,
updatedByClient: "code-agent-submit-active-trace-repair",
now: new Date().toISOString()
});
}
const updated = await store.updateWorkspace?.({
workspaceId,
ownerUserId: options.actor.id,
actorRole: options.actor.role,
selectedConversationId: nextSelectedConversationId,
selectedAgentSessionId: nextSelectedAgentSessionId,
activeTraceId: traceId,
providerProfile: textValue(params.providerProfile) || workspace.providerProfile,
patch: {
selectedConversationId: nextSelectedConversationId,
selectedAgentSessionId: nextSelectedAgentSessionId,
previousActiveTraceId: activeTraceId || null,
workspaceRevisionConflict,
expectedWorkspaceRevision: Number.isInteger(expectedRevision) && expectedRevision > 0 ? expectedRevision : null,
activeTraceId: traceId,
providerProfile: textValue(params.providerProfile) || workspace.providerProfile,
sessionStatus: "running",
updatedAt: new Date().toISOString(),
source: "code-agent-submit",
valuesRedacted: true,
secretMaterialStored: false
},
updatedBySessionId: options.authSession?.id ?? null,
updatedByClient: textValue(params.updatedByClient ?? params.client) || "code-agent-chat",
now: new Date().toISOString()
});
return { workspace: updated ?? workspace };
}
async function clearStaleWorkbenchSteerTrace({ params = {}, options = {}, traceId, reason }) {
const workspaceId = safeWorkspaceId(params.workspaceId);
if (!workspaceId || !safeTraceId(traceId) || !options.accessController?.store || !options.actor) return null;
const store = options.accessController.store;
const workspace = await store.getWorkspaceForUser?.({ workspaceId, ownerUserId: options.actor.id, actorRole: options.actor.role });
if (!workspace || safeTraceId(workspace.activeTraceId) !== traceId) return null;
return await store.updateWorkspace?.({
workspaceId,
ownerUserId: options.actor.id,
actorRole: options.actor.role,
selectedConversationId: workspace.selectedConversationId,
selectedAgentSessionId: workspace.selectedAgentSessionId,
activeTraceId: null,
providerProfile: workspace.providerProfile,
patch: {
...(workspace.workspace && typeof workspace.workspace === "object" ? workspace.workspace : {}),
activeTraceId: null,
staleActiveTraceId: traceId,
staleActiveTraceReason: reason,
sessionStatus: "failed",
updatedAt: new Date().toISOString(),
source: "code-agent-steer-active-trace-repair",
valuesRedacted: true,
secretMaterialStored: false
},
updatedBySessionId: options.authSession?.id ?? null,
updatedByClient: "code-agent-steer-active-trace-repair",
now: new Date().toISOString()
});
}
function isWorkbenchOrphanActiveTrace(snapshot) {
if (!snapshot || typeof snapshot !== "object") return false;
const last = snapshot.lastEvent && typeof snapshot.lastEvent === "object" ? snapshot.lastEvent : null;
if (!last) return false;
if (last.errorCode !== "cancel_session_missing" && last.label !== "cancel:not_cancelable") return false;
return !snapshot.sessionId && !snapshot.runId && !snapshot.commandId && !snapshot.sessionStatus && !snapshot.turn;
}
async function resolveWorkbenchActiveTraceResult(traceId, options = {}) {
if (!safeTraceId(traceId)) return null;
const cached = options.codeAgentChatResults?.get?.(traceId) ?? null;
if (cached?.agentRun?.runId) {
try {
const synced = await syncAgentRunChatResult({ traceId, currentResult: cached, options, traceStore: options.traceStore ?? defaultCodeAgentTraceStore });
return synced.result ?? null;
} catch {
return null;
}
}
if (cached) return cached;
if (!codeAgentAgentRunAdapterEnabled(options.env ?? process.env)) return null;
try {
const persisted = await loadPersistedAgentRunResult(traceId, options);
if (!persisted?.agentRun?.runId) return persisted;
const synced = await syncAgentRunChatResult({ traceId, currentResult: persisted, options, traceStore: options.traceStore ?? defaultCodeAgentTraceStore });
return synced.result ?? null;
} catch {
return null;
}
}
function safeWorkspaceId(value) {
const text = textValue(value);
return /^wsp_[A-Za-z0-9_.:-]+$/u.test(text) ? text : "";
}
function textValue(value) {
return String(value ?? "").trim();
}
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);
return {
provider: payload.provider ?? null,
model: payload.model ?? null,
backend: payload.backend ?? null,
status: payload.status ?? null,
sessionMode: payload.sessionMode ?? payload.session?.sessionMode ?? null,
sessionLifecycleStatus: payload.sessionLifecycleStatus ?? null,
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 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: 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 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 traceSuffix = codeAgentMessageTraceSuffix(resolvedTraceId);
const userMessage = {
id: `msg_${traceSuffix}_user`,
role: "user",
title: "用户",
text: userText,
status: "sent",
traceId: resolvedTraceId,
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: `msg_${traceSuffix}_agent`,
role: "agent",
title: agentStatus === "failed" ? "Code Agent 返回阻塞" : agentStatus === "running" ? "Code Agent 处理中" : "Code Agent 回复",
text: agentText || (agentStatus === "running" ? "正在处理这次 Code Agent 请求;复杂问题可能需要几分钟。" : "Code Agent 请求已结束,请查看 Trace 详情。"),
status: agentStatus,
traceId: resolvedTraceId,
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(/\s+/gu, " ").trim();
if (!extracted || extracted === "[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 codeAgentConversationAgentMessageStatus(payload = {}) {
const status = textValue(payload.status ?? payload.agentRun?.terminalStatus ?? payload.commandState ?? payload.runStatus).toLowerCase();
if (["completed", "done", "success", "active"].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 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 = textValue(payload.reply?.content ?? payload.message?.content ?? payload.assistantText);
if (!text) return null;
return {
text,
textChars: text.length,
messageId: payload.reply?.messageId ?? payload.messageId ?? null,
role: payload.reply?.role ?? payload.message?.role ?? "assistant",
status: payload.status ?? null,
traceId,
createdAt: payload.reply?.createdAt ?? payload.createdAt ?? null,
updatedAt: payload.updatedAt ?? null,
source: "code-agent-result",
valuesPrinted: false
};
}
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 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"
}
};
}
export async function handleCodeAgentTraceHttp(request, response, url, options) {
const parts = url.pathname.split("/").filter(Boolean);
const traceId = decodeURIComponent(parts[4] ?? "");
const traceStore = options.traceStore ?? defaultCodeAgentTraceStore;
if (!/^trc_[A-Za-z0-9_.:-]+$/u.test(traceId)) {
sendJson(response, 400, {
error: {
code: "invalid_trace_id",
message: "traceId must start with trc_ and contain only safe identifier characters"
}
});
return;
}
const result = options.codeAgentChatResults?.get(traceId) ?? null;
if (result && !canAccessOwnedResult(result, options.actor)) {
sendJson(response, 403, {
error: {
code: "agent_session_owner_required",
message: "Only the session owner or admin can read this Code Agent trace"
}
});
return;
}
let agentRunResult = result?.agentRun ? result : await loadPersistedAgentRunResult(traceId, options);
let refreshError = null;
if (agentRunResult && !canAccessOwnedResult(agentRunResult, options.actor)) {
sendJson(response, 403, {
error: {
code: "agent_session_owner_required",
message: "Only the session owner or admin can read this Code Agent trace"
}
});
return;
}
if (agentRunResult?.agentRun) {
try {
const snapshot = await refreshAgentRunTrace({ traceId, result: agentRunResult, options, traceStore });
agentRunResult = options.codeAgentChatResults?.get?.(traceId) ?? agentRunResult;
if (traceNeedsCommandResultSync(agentRunResult, snapshot)) {
const synced = await syncAgentRunChatResult({ traceId, currentResult: agentRunResult, options, traceStore, appendResultEvent: false, refreshEvents: false });
agentRunResult = synced.result ?? agentRunResult;
}
if (isTraceCommandTerminalStatus(agentRunResult?.status)) {
await finalizeCodeAgentBillingUsage({ payload: agentRunResult, params: agentRunResult, options });
recordCodeAgentConversationFact(agentRunResult, options);
await recordCodeAgentSessionOwner({ payload: agentRunResult, params: agentRunResult, options, status: codeAgentOwnerStatusForResult(agentRunResult), preserveLastTraceId: true });
}
} catch (error) {
sendJson(response, Number(error?.statusCode ?? 502), {
error: {
code: error?.code ?? "agentrun_trace_command_result_unavailable",
message: error?.message ?? "AgentRun command result could not be resolved for this traceId",
traceId,
valuesPrinted: false
}
});
return;
}
}
if (parts[5] === "stream") {
sendTraceSse(response, traceStore, traceId, options);
return;
}
const snapshot = traceStore.snapshot(traceId);
sendJson(response, 200, traceSnapshotWithTerminalEvidence(snapshot, agentRunResult, traceId, refreshError));
}
function traceNeedsCommandResultSync(result, snapshot) {
if (!result?.agentRun) return false;
const status = String(result.status ?? result.agentRun.status ?? result.agentRun.commandState ?? result.agentRun.terminalStatus ?? "running");
if (isTraceCommandTerminalStatus(status)) return true;
if (snapshotHasTerminalEvent(snapshot)) return true;
return false;
}
function isTraceCommandTerminalStatus(status) {
return CODE_AGENT_TERMINAL_STATUSES.has(String(status ?? "").trim().toLowerCase().replace(/_/gu, "-"));
}
function snapshotHasTerminalEvent(snapshot) {
const events = Array.isArray(snapshot?.events) ? snapshot.events : [];
return events.some((event) => event?.terminal === true || (event?.type === "result" && isTraceCommandTerminalStatus(event?.status)));
}
function traceSnapshotWithTerminalEvidence(snapshot, result, traceId, refreshError = null) {
const evidence = agentRunTerminalTraceEvidence(result, traceId);
if (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",
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;
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 ?? result.agentRun?.terminalStatus ?? result.status ?? null,
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 sendTraceSse(response, traceStore, traceId, options = {}) {
response.writeHead(200, {
"content-type": "text/event-stream; charset=utf-8",
"cache-control": "no-store",
connection: "keep-alive",
"x-accel-buffering": "no"
});
const writeEvent = (eventName, payload) => {
response.write(`event: ${eventName}\n`);
response.write(`data: ${JSON.stringify(payload)}\n\n`);
};
writeEvent("snapshot", traceStore.snapshot(traceId));
const unsubscribe = traceStore.subscribe(traceId, (event, snapshot) => {
writeEvent("runnerTrace", { event, snapshot });
});
const heartbeatMs = parsePositiveInteger(options.env?.HWLAB_CODE_AGENT_TRACE_HEARTBEAT_MS, 15000);
const heartbeat = setInterval(() => {
writeEvent("heartbeat", traceStore.snapshot(traceId));
}, heartbeatMs);
response.on("close", () => {
clearInterval(heartbeat);
unsubscribe();
});
}
export 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,
...(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: `Result polling response compacted ${omitted} trace events; fetch /v1/agent/chat/trace/${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 uniqueStrings(values) {
return [...new Set(values.map((value) => String(value ?? "").trim()).filter(Boolean))];
}