feat: 增加纯 Kafka AgentRun 运行观察

This commit is contained in:
root
2026-07-15 04:21:06 +02:00
parent 990dd30723
commit f33604757b
20 changed files with 1101 additions and 4 deletions
+2 -1
View File
@@ -20,7 +20,8 @@ const FORWARDED_REQUEST_HEADERS = Object.freeze([
]);
export function isCloudWebSseRoute(pathname) {
return /^\/v1\/agent\/chat\/trace\/[^/]+\/stream$/u.test(String(pathname || ""));
const value = String(pathname || "");
return value === "/v1/agent-observer/events" || /^\/v1\/agent\/chat\/trace\/[^/]+\/stream$/u.test(value);
}
export function isEventStreamResponse(headers = {}) {
@@ -171,6 +171,8 @@ async function runtimeConfigFromEnv(options = {}) {
const config = { displayTime: displayTimeConfigFromEnv() };
const workbench = workbenchRuntimeConfigFromEnv();
if (workbench) config.workbench = workbench;
const agentObserver = agentObserverRuntimeConfigFromEnv();
if (agentObserver) config.agentObserver = agentObserver;
const opencode = await opencodeRuntimeConfigFromEnv(options);
if (opencode) config.opencode = opencode;
return config;
@@ -424,6 +426,52 @@ function workbenchRuntimeConfigFromEnv() {
return Object.keys(result).length > 0 ? result : null;
}
function agentObserverRuntimeConfigFromEnv() {
const names = [
"HWLAB_AGENT_OBSERVER_RECONNECT_DELAY_MS",
"HWLAB_AGENT_OBSERVER_BATCH_MAX_EVENTS",
"HWLAB_AGENT_OBSERVER_LIVE_BUFFER_LIMIT",
"HWLAB_AGENT_OBSERVER_REDUCER_EVENT_LIMIT",
"HWLAB_AGENT_OBSERVER_REDUCER_ENTITY_LIMIT",
"HWLAB_AGENT_OBSERVER_TREE_NODE_LIMIT",
"HWLAB_AGENT_OBSERVER_INSPECTOR_EVENT_TAIL_LIMIT",
"HWLAB_AGENT_OBSERVER_VIRTUAL_LIST_WINDOW_LIMIT",
"HWLAB_AGENT_OBSERVER_CHANGE_HIGHLIGHT_MS",
"HWLAB_AGENT_OBSERVER_STALE_AFTER_MS",
"HWLAB_AGENT_OBSERVER_REDUCED_MOTION"
];
if (names.every((name) => process.env[name] === undefined || process.env[name] === "")) return null;
const value = {
nodeId: requiredRuntimeConfigValue(process.env.HWLAB_AGENT_OBSERVER_NODE_ID, "HWLAB_AGENT_OBSERVER_NODE_ID"),
lane: requiredRuntimeConfigValue(process.env.HWLAB_AGENT_OBSERVER_LANE, "HWLAB_AGENT_OBSERVER_LANE"),
reconnectDelayMs: requiredPositiveWorkbenchInteger(process.env.HWLAB_AGENT_OBSERVER_RECONNECT_DELAY_MS, "HWLAB_AGENT_OBSERVER_RECONNECT_DELAY_MS"),
batchMaxEvents: requiredPositiveWorkbenchInteger(process.env.HWLAB_AGENT_OBSERVER_BATCH_MAX_EVENTS, "HWLAB_AGENT_OBSERVER_BATCH_MAX_EVENTS"),
liveBufferLimit: requiredPositiveWorkbenchInteger(process.env.HWLAB_AGENT_OBSERVER_LIVE_BUFFER_LIMIT, "HWLAB_AGENT_OBSERVER_LIVE_BUFFER_LIMIT"),
reducerEventLimit: requiredPositiveWorkbenchInteger(process.env.HWLAB_AGENT_OBSERVER_REDUCER_EVENT_LIMIT, "HWLAB_AGENT_OBSERVER_REDUCER_EVENT_LIMIT"),
reducerEntityLimit: requiredPositiveWorkbenchInteger(process.env.HWLAB_AGENT_OBSERVER_REDUCER_ENTITY_LIMIT, "HWLAB_AGENT_OBSERVER_REDUCER_ENTITY_LIMIT"),
treeNodeLimit: requiredPositiveWorkbenchInteger(process.env.HWLAB_AGENT_OBSERVER_TREE_NODE_LIMIT, "HWLAB_AGENT_OBSERVER_TREE_NODE_LIMIT"),
inspectorEventTailLimit: requiredPositiveWorkbenchInteger(process.env.HWLAB_AGENT_OBSERVER_INSPECTOR_EVENT_TAIL_LIMIT, "HWLAB_AGENT_OBSERVER_INSPECTOR_EVENT_TAIL_LIMIT"),
virtualListWindowLimit: requiredPositiveWorkbenchInteger(process.env.HWLAB_AGENT_OBSERVER_VIRTUAL_LIST_WINDOW_LIMIT, "HWLAB_AGENT_OBSERVER_VIRTUAL_LIST_WINDOW_LIMIT"),
changeHighlightMs: requiredNonNegativeInteger(process.env.HWLAB_AGENT_OBSERVER_CHANGE_HIGHLIGHT_MS, "HWLAB_AGENT_OBSERVER_CHANGE_HIGHLIGHT_MS"),
staleAfterMs: requiredPositiveWorkbenchInteger(process.env.HWLAB_AGENT_OBSERVER_STALE_AFTER_MS, "HWLAB_AGENT_OBSERVER_STALE_AFTER_MS"),
reducedMotion: requiredRuntimeConfigValue(process.env.HWLAB_AGENT_OBSERVER_REDUCED_MOTION, "HWLAB_AGENT_OBSERVER_REDUCED_MOTION")
};
if (value.reducedMotion !== "respect-system") throw new Error("HWLAB_AGENT_OBSERVER_REDUCED_MOTION must be respect-system");
return value;
}
function requiredNonNegativeInteger(value, name) {
const number = Number(value);
if (!Number.isInteger(number) || number < 0) throw new Error(`${name} is required and must be a non-negative integer`);
return number;
}
function requiredRuntimeConfigValue(value, name) {
const result = String(value ?? "").trim();
if (!result) throw new Error(`${name} is required`);
return result;
}
function requiredWorkbenchRealtimeFeature(value, name) {
const normalized = String(value ?? "").trim().toLowerCase();
if (normalized === "true" || normalized === "1") return true;