feat: 拉通 Workbench 纯 Kafka 实时链路

This commit is contained in:
root
2026-07-10 10:22:28 +02:00
parent d5230cb923
commit 8ad5976a07
59 changed files with 4700 additions and 498 deletions
@@ -72,27 +72,39 @@ function firstNonEmptyValue(...values) {
return null;
}
async function recordCodeAgentSessionInputFact({ params = {}, options = {}, traceId, delivery = "queue", status = "admitted", messageId = null, commandId = null, error = null } = {}) {
async function recordCodeAgentSessionInputFact({ params = {}, options = {}, traceId, delivery = "queue", status = "admitted", messageId = null, commandId = null, agentRun = null, error = null } = {}) {
const runtimeStore = options.runtimeStore ?? null;
if (typeof runtimeStore?.writeWorkbenchFacts !== "function") return null;
const fact = buildCodeAgentSessionInputFact({ params, options, traceId, delivery, status, messageId, commandId, agentRun, error });
if (!fact) return null;
return runtimeStore.writeWorkbenchFacts({ facts: { inputs: [fact] } }, codeAgentSessionInputRequestMeta(fact, params, options));
}
function buildCodeAgentSessionInputFact({ params = {}, options = {}, traceId, delivery = "queue", status = "admitted", messageId = null, commandId = null, agentRun = null, error = null } = {}) {
const resolvedTraceId = safeTraceId(traceId ?? params.traceId) || null;
const lifecycle = codeAgentTurnLifecycleFields(resolvedTraceId, params);
const sessionId = safeSessionId(params.sessionId ?? params.session?.sessionId) || null;
if (!sessionId) return null;
const resolvedMessageId = safeMessageId(messageId ?? params.messageId ?? lifecycle.userMessageId) || lifecycle.userMessageId;
const resolvedCommandId = textValue(commandId ?? params.commandId ?? params.agentRun?.commandId) || null;
const resolvedCommandId = textValue(commandId ?? agentRun?.commandId ?? params.commandId ?? params.agentRun?.commandId) || null;
const normalizedDelivery = codeAgentInputDelivery(delivery);
const normalizedStatus = codeAgentInputStatus(status);
const now = new Date().toISOString();
const sourceEventId = `${sessionId}:${lifecycle.turnId}:${normalizedDelivery}:${resolvedTraceId ?? resolvedCommandId ?? resolvedMessageId}`;
const inputId = stableCodeAgentInputId({ sessionId, turnId: lifecycle.turnId, traceId: resolvedTraceId, messageId: resolvedMessageId, commandId: resolvedCommandId, delivery: normalizedDelivery, sourceEventId });
const fact = {
// Command allocation happens after the initial admitting write. Keep one stable
// row across admitting -> blocked/failed/promoted transitions for the trace.
const inputId = stableCodeAgentInputId({ sessionId, turnId: lifecycle.turnId, traceId: resolvedTraceId, messageId: resolvedMessageId, delivery: normalizedDelivery, sourceEventId });
return {
inputId,
sessionId,
turnId: lifecycle.turnId,
traceId: resolvedTraceId,
messageId: resolvedMessageId,
commandId: resolvedCommandId,
runId: textValue(agentRun?.runId ?? params.agentRun?.runId) || null,
dispatchIntentId: textValue(agentRun?.dispatchIntentId ?? params.agentRun?.dispatchIntentId) || null,
runnerJobId: textValue(agentRun?.runnerJobId ?? params.agentRun?.runnerJobId) || null,
durableDispatch: agentRun?.durableDispatch === true || params.agentRun?.durableDispatch === true,
delivery: normalizedDelivery,
status: normalizedStatus,
errorCode: textValue(error?.code ?? error?.error?.code) || null,
@@ -104,15 +116,18 @@ async function recordCodeAgentSessionInputFact({ params = {}, options = {}, trac
createdAt: now,
updatedAt: now
};
return runtimeStore.writeWorkbenchFacts({ facts: { inputs: [fact] } }, {
sessionId,
traceId: resolvedTraceId,
turnId: lifecycle.turnId,
messageId: resolvedMessageId,
}
function codeAgentSessionInputRequestMeta(fact, params = {}, options = {}) {
return {
sessionId: fact.sessionId,
traceId: fact.traceId,
turnId: fact.turnId,
messageId: fact.messageId,
ownerUserId: options.actor?.id ?? params.ownerUserId,
projectId: params.projectId ?? DEFAULT_CODE_AGENT_PROJECT_ID,
valuesPrinted: false
});
};
}
function stableCodeAgentInputId(value) {
@@ -127,7 +142,7 @@ function codeAgentInputDelivery(value) {
function codeAgentInputStatus(value) {
const text = textValue(value).toLowerCase().replace(/-/gu, "_");
return ["admitted", "promoted", "blocked", "failed", "canceled", "completed"].includes(text) ? text : "admitted";
return ["admitting", "admitted", "promoted", "blocked", "failed", "canceled", "completed"].includes(text) ? text : "admitted";
}
function codeAgentResultTimingFields(...sources) {
@@ -1507,6 +1522,7 @@ export {
normalizeCodeAgentProviderProfile,
firstNonEmptyValue,
recordCodeAgentSessionInputFact,
buildCodeAgentSessionInputFact,
stableCodeAgentInputId,
codeAgentInputDelivery,
codeAgentInputStatus,