feat: 增加纯 Kafka AgentRun 运行观察
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user