Files
horus-3d/tests/unit/runtimeEventCoordinatorWorkflow.test.ts
Luke The Dev 4fa4f13558 First Release of Claw3D (#11)
Co-authored-by: iamlukethedev <iamlukethedev@users.noreply.github.com>
2026-03-19 23:14:04 -05:00

368 lines
10 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { AgentState } from "@/features/agents/state/store";
import {
createRuntimeEventCoordinatorState,
markChatRunSeen,
reduceClearRunTracking,
reduceLifecycleFallbackFired,
reduceMarkActivityThrottled,
reduceRuntimeAgentWorkflowCommands,
reduceRuntimePolicyIntents,
} from "@/features/agents/state/runtimeEventCoordinatorWorkflow";
import {
applyTerminalCommit,
createRuntimeTerminalState,
deriveLifecycleTerminalDecision,
} from "@/features/agents/state/runtimeTerminalWorkflow";
import type { AgentEventPayload } from "@/features/agents/state/runtimeEventBridge";
const createAgent = (overrides?: Partial<AgentState>): AgentState => ({
agentId: "agent-1",
name: "Agent One",
sessionKey: "agent:agent-1:studio:test-session",
status: "running",
sessionCreated: true,
awaitingUserInput: false,
hasUnseenActivity: false,
outputLines: [],
lastResult: null,
lastDiff: null,
runId: "run-1",
runStartedAt: 100,
streamText: null,
thinkingTrace: null,
latestOverride: null,
latestOverrideKind: null,
lastAssistantMessageAt: null,
lastActivityAt: null,
latestPreview: null,
lastUserMessage: null,
draft: "",
sessionSettingsSynced: true,
historyLoadedAt: null,
historyFetchLimit: null,
historyFetchedCount: null,
historyMaybeTruncated: false,
toolCallingEnabled: true,
showThinkingTraces: true,
model: "openai/gpt-5",
thinkingLevel: "medium",
avatarSeed: "seed-1",
avatarUrl: null,
...(overrides ?? {}),
});
const createAgentPayload = (overrides?: Partial<AgentEventPayload>): AgentEventPayload => ({
runId: "run-1",
sessionKey: "agent:agent-1:studio:test-session",
stream: "assistant",
data: { delta: "hello" },
...(overrides ?? {}),
});
describe("runtimeEventCoordinatorWorkflow", () => {
it("reduces runtime policy intents into effects and run cleanup", () => {
let state = createRuntimeEventCoordinatorState();
state = markChatRunSeen(state, "run-1");
state.thinkingStartedAtByRun.set("run-1", 900);
const reduced = reduceRuntimePolicyIntents({
state,
nowMs: 1000,
intents: [
{ kind: "queueLivePatch", agentId: "agent-1", patch: { streamText: "stream" } },
{
kind: "dispatchUpdateAgent",
agentId: "agent-1",
patch: { status: "running", runId: "run-1" },
},
{
kind: "requestHistoryRefresh",
agentId: "agent-1",
reason: "chat-final-no-trace",
},
{
kind: "scheduleSummaryRefresh",
delayMs: 750,
includeHeartbeatRefresh: true,
},
{ kind: "clearRunTracking", runId: "run-1" },
],
});
expect(reduced.effects).toEqual(
expect.arrayContaining([
{
kind: "queueLivePatch",
agentId: "agent-1",
patch: { streamText: "stream" },
},
{
kind: "dispatch",
action: {
type: "updateAgent",
agentId: "agent-1",
patch: { status: "running", runId: "run-1" },
},
},
{
kind: "requestHistoryRefresh",
agentId: "agent-1",
reason: "chat-final-no-trace",
deferMs: 0,
},
{
kind: "scheduleSummaryRefresh",
delayMs: 750,
includeHeartbeatRefresh: true,
},
{
kind: "cancelLifecycleFallback",
runId: "run-1",
},
])
);
expect(reduced.state.chatRunSeen.has("run-1")).toBe(false);
expect(reduced.state.thinkingStartedAtByRun.has("run-1")).toBe(false);
});
it("reduces lifecycle decision into fallback scheduling/cancellation effects", () => {
const initial = createRuntimeEventCoordinatorState();
const scheduleDecision = deriveLifecycleTerminalDecision({
mode: "event",
state: initial.runtimeTerminalState,
runId: "run-1",
phase: "end",
hasPendingFallbackTimer: false,
fallbackDelayMs: 250,
fallbackFinalText: "fallback final",
transitionClearsRunTracking: true,
});
const scheduleReduced = reduceRuntimeAgentWorkflowCommands({
state: initial,
payload: createAgentPayload({
stream: "lifecycle",
data: { phase: "end" },
}),
agentId: "agent-1",
agent: createAgent(),
nowMs: 1000,
commands: [
{
kind: "applyLifecycleDecision",
decision: scheduleDecision,
transitionPatch: { status: "idle", runId: null },
shouldClearPendingLivePatch: true,
},
],
});
expect(scheduleReduced.effects).toEqual(
expect.arrayContaining([
{ kind: "clearPendingLivePatch", agentId: "agent-1" },
{ kind: "cancelLifecycleFallback", runId: "run-1" },
{
kind: "scheduleLifecycleFallback",
runId: "run-1",
delayMs: 250,
agentId: "agent-1",
sessionKey: "agent:agent-1:studio:test-session",
finalText: "fallback final",
transitionPatch: { status: "idle", runId: null },
},
])
);
expect(
scheduleReduced.effects.some(
(effect) =>
effect.kind === "dispatch" &&
effect.action.type === "updateAgent" &&
effect.action.patch.status === "idle"
)
).toBe(false);
const cancelDecision = deriveLifecycleTerminalDecision({
mode: "event",
state: initial.runtimeTerminalState,
runId: "run-2",
phase: "start",
hasPendingFallbackTimer: true,
fallbackDelayMs: 250,
fallbackFinalText: null,
transitionClearsRunTracking: false,
});
const cancelReduced = reduceRuntimeAgentWorkflowCommands({
state: initial,
payload: createAgentPayload({ runId: "run-2", stream: "lifecycle", data: { phase: "start" } }),
agentId: "agent-1",
agent: createAgent({ runId: "run-2" }),
nowMs: 1000,
commands: [
{
kind: "applyLifecycleDecision",
decision: cancelDecision,
transitionPatch: { status: "running", runId: "run-2" },
shouldClearPendingLivePatch: false,
},
],
});
expect(
cancelReduced.effects.some(
(effect) => effect.kind === "cancelLifecycleFallback" && effect.runId === "run-2"
)
).toBe(true);
});
it("applies fallback-fired commits only when chat final has not already committed", () => {
const baseDecision = deriveLifecycleTerminalDecision({
mode: "event",
state: createRuntimeTerminalState(),
runId: "run-1",
phase: "end",
hasPendingFallbackTimer: false,
fallbackDelayMs: 0,
fallbackFinalText: "fallback final",
transitionClearsRunTracking: true,
});
const state = {
...createRuntimeEventCoordinatorState(),
runtimeTerminalState: baseDecision.state,
thinkingStartedAtByRun: new Map<string, number>([["run-1", 1000]]),
};
const committed = reduceLifecycleFallbackFired({
state,
runId: "run-1",
agentId: "agent-1",
sessionKey: "agent:agent-1:studio:test-session",
finalText: "fallback final",
transitionPatch: { status: "idle", runId: null },
nowMs: 1300,
});
expect(
committed.effects.some(
(effect) =>
effect.kind === "dispatch" &&
effect.action.type === "appendOutput" &&
effect.action.transcript?.kind === "meta"
)
).toBe(true);
expect(
committed.effects.some(
(effect) =>
effect.kind === "dispatch" &&
effect.action.type === "appendOutput" &&
effect.action.line === "fallback final"
)
).toBe(true);
expect(
committed.effects.some(
(effect) =>
effect.kind === "dispatch" &&
effect.action.type === "updateAgent" &&
effect.action.patch.lastResult === "fallback final"
)
).toBe(true);
const chatFinalCommittedState = {
...state,
runtimeTerminalState: applyTerminalCommit(state.runtimeTerminalState, {
runId: "run-1",
source: "chat-final",
seq: 1,
}),
};
const skipped = reduceLifecycleFallbackFired({
state: chatFinalCommittedState,
runId: "run-1",
agentId: "agent-1",
sessionKey: "agent:agent-1:studio:test-session",
finalText: "fallback final",
transitionPatch: { status: "idle", runId: null },
nowMs: 1400,
});
expect(skipped.effects).toEqual([]);
});
it("tracks history refresh state per run and clears it with run cleanup", () => {
const reduced = reduceRuntimeAgentWorkflowCommands({
state: createRuntimeEventCoordinatorState(),
payload: createAgentPayload({
stream: "tool",
data: { phase: "result" },
}),
agentId: "agent-1",
agent: createAgent(),
nowMs: 2000,
commands: [
{ kind: "markHistoryRefreshRequested", runId: "run-1" },
{
kind: "scheduleHistoryRefresh",
delayMs: 750,
reason: "chat-final-no-trace",
},
],
});
expect(reduced.state.historyRefreshRequestedByRun.has("run-1")).toBe(true);
expect(reduced.effects).toContainEqual({
kind: "requestHistoryRefresh",
agentId: "agent-1",
reason: "chat-final-no-trace",
sessionKey: "agent:agent-1:studio:test-session",
deferMs: 750,
});
const cleared = reduceClearRunTracking({ state: reduced.state, runId: "run-1" });
expect(cleared.state.historyRefreshRequestedByRun.has("run-1")).toBe(false);
expect(cleared.effects).toContainEqual({
kind: "cancelLifecycleFallback",
runId: "run-1",
});
});
it("throttles mark-activity effects by agent", () => {
const first = reduceMarkActivityThrottled({
state: createRuntimeEventCoordinatorState(),
agentId: "agent-1",
at: 1000,
});
expect(first.effects).toContainEqual({
kind: "dispatch",
action: {
type: "markActivity",
agentId: "agent-1",
at: 1000,
},
});
const second = reduceMarkActivityThrottled({
state: first.state,
agentId: "agent-1",
at: 1100,
});
expect(second.effects).toEqual([]);
const third = reduceMarkActivityThrottled({
state: second.state,
agentId: "agent-1",
at: 1301,
});
expect(third.effects).toContainEqual({
kind: "dispatch",
action: {
type: "markActivity",
agentId: "agent-1",
at: 1301,
},
});
});
});