Spracherkennung für: .ts vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]
import type { SessionLifecycleEvent } from "../sessions/session-lifecycle-events.js";
import type { SessionTranscriptUpdate } from "../sessions/transcript-events.js";
import type { GatewayBroadcastToConnIdsFn } from "./server-broadcast-types.js";
import type {
SessionEventSubscriberRegistry,
SessionMessageSubscriberRegistry,
} from "./server-chat.js";
import { resolveSessionKeyForTranscriptFile } from "./session-transcript-key.js";
import {
attachOpenClawTranscriptMeta,
loadGatewaySessionRow,
loadSessionEntry,
readSessionMessages,
type GatewaySessionRow,
} from "./session-utils.js";
type SessionEventSubscribers = Pick<SessionEventSubscriberRegistry, "getAll">;
type SessionMessageSubscribers = Pick<SessionMessageSubscriberRegistry, "get">;
function buildGatewaySessionSnapshot(params: {
sessionRow: GatewaySessionRow | null | undefined;
includeSession?: boolean;
label?: string;
displayName?: string;
parentSessionKey?: string;
}): Record<string, unknown> {
const { sessionRow } = params;
if (!sessionRow) {
return {};
}
return {
...(params.includeSession ? { session: sessionRow } : {}),
updatedAt: sessionRow.updatedAt ?? undefined,
sessionId: sessionRow.sessionId,
kind: sessionRow.kind,
channel: sessionRow.channel,
subject: sessionRow.subject,
groupChannel: sessionRow.groupChannel,
space: sessionRow.space,
chatType: sessionRow.chatType,
origin: sessionRow.origin,
spawnedBy: sessionRow.spawnedBy,
spawnedWorkspaceDir: sessionRow.spawnedWorkspaceDir,
forkedFromParent: sessionRow.forkedFromParent,
spawnDepth: sessionRow.spawnDepth,
subagentRole: sessionRow.subagentRole,
subagentControlScope: sessionRow.subagentControlScope,
label: params.label ?? sessionRow.label,
displayName: params.displayName ?? sessionRow.displayName,
deliveryContext: sessionRow.deliveryContext,
parentSessionKey: params.parentSessionKey ?? sessionRow.parentSessionKey,
childSessions: sessionRow.childSessions,
thinkingLevel: sessionRow.thinkingLevel,
fastMode: sessionRow.fastMode,
verboseLevel: sessionRow.verboseLevel,
reasoningLevel: sessionRow.reasoningLevel,
elevatedLevel: sessionRow.elevatedLevel,
sendPolicy: sessionRow.sendPolicy,
systemSent: sessionRow.systemSent,
abortedLastRun: sessionRow.abortedLastRun,
inputTokens: sessionRow.inputTokens,
outputTokens: sessionRow.outputTokens,
lastChannel: sessionRow.lastChannel,
lastTo: sessionRow.lastTo,
lastAccountId: sessionRow.lastAccountId,
lastThreadId: sessionRow.lastThreadId,
totalTokens: sessionRow.totalTokens,
totalTokensFresh: sessionRow.totalTokensFresh,
contextTokens: sessionRow.contextTokens,
estimatedCostUsd: sessionRow.estimatedCostUsd,
responseUsage: sessionRow.responseUsage,
modelProvider: sessionRow.modelProvider,
model: sessionRow.model,
status: sessionRow.status,
subagentRunState: sessionRow.subagentRunState,
hasActiveSubagentRun: sessionRow.hasActiveSubagentRun,
startedAt: sessionRow.startedAt,
endedAt: sessionRow.endedAt,
runtimeMs: sessionRow.runtimeMs,
compactionCheckpointCount: sessionRow.compactionCheckpointCount,
latestCompactionCheckpoint: sessionRow.latestCompactionCheckpoint,
};
}
export function createTranscriptUpdateBroadcastHandler(params: {
broadcastToConnIds: GatewayBroadcastToConnIdsFn;
sessionEventSubscribers: SessionEventSubscribers;
sessionMessageSubscribers: SessionMessageSubscribers;
}) {
return (update: SessionTranscriptUpdate): void => {
const sessionKey = update.sessionKey ?? resolveSessionKeyForTranscriptFile(update.sessionFile);
if (!sessionKey || update.message === undefined) {
return;
}
const connIds = new Set<string>();
for (const connId of params.sessionEventSubscribers.getAll()) {
connIds.add(connId);
}
for (const connId of params.sessionMessageSubscribers.get(sessionKey)) {
connIds.add(connId);
}
if (connIds.size === 0) {
return;
}
const { entry, storePath } = loadSessionEntry(sessionKey);
const messageSeq = entry?.sessionId
? readSessionMessages(entry.sessionId, storePath, entry.sessionFile).length
: undefined;
const sessionSnapshot = buildGatewaySessionSnapshot({
sessionRow: loadGatewaySessionRow(sessionKey),
includeSession: true,
});
const message = attachOpenClawTranscriptMeta(update.message, {
...(typeof update.messageId === "string" ? { id: update.messageId } : {}),
...(typeof messageSeq === "number" ? { seq: messageSeq } : {}),
});
params.broadcastToConnIds(
"session.message",
{
sessionKey,
message,
...(typeof update.messageId === "string" ? { messageId: update.messageId } : {}),
...(typeof messageSeq === "number" ? { messageSeq } : {}),
...sessionSnapshot,
},
connIds,
{ dropIfSlow: true },
);
const sessionEventConnIds = params.sessionEventSubscribers.getAll();
if (sessionEventConnIds.size === 0) {
return;
}
params.broadcastToConnIds(
"sessions.changed",
{
sessionKey,
phase: "message",
ts: Date.now(),
...(typeof update.messageId === "string" ? { messageId: update.messageId } : {}),
...(typeof messageSeq === "number" ? { messageSeq } : {}),
...sessionSnapshot,
},
sessionEventConnIds,
{ dropIfSlow: true },
);
};
}
export function createLifecycleEventBroadcastHandler(params: {
broadcastToConnIds: GatewayBroadcastToConnIdsFn;
sessionEventSubscribers: SessionEventSubscribers;
}) {
return (event: SessionLifecycleEvent): void => {
const connIds = params.sessionEventSubscribers.getAll();
if (connIds.size === 0) {
return;
}
params.broadcastToConnIds(
"sessions.changed",
{
sessionKey: event.sessionKey,
reason: event.reason,
parentSessionKey: event.parentSessionKey,
label: event.label,
displayName: event.displayName,
ts: Date.now(),
...buildGatewaySessionSnapshot({
sessionRow: loadGatewaySessionRow(event.sessionKey),
label: event.label,
displayName: event.displayName,
parentSessionKey: event.parentSessionKey,
}),
},
connIds,
{ dropIfSlow: true },
);
};
}
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-04-27)
¤
*© Formatika GbR, Deutschland
|
|