chore(subagents): add regression coverage and changelog

This commit is contained in:
Sebastian
2026-02-17 08:40:36 -05:00
parent 85b5ac8520
commit 210bc37971
6 changed files with 60 additions and 6 deletions

View File

@@ -838,4 +838,48 @@ describe("subagent announce formatting", () => {
expect(call?.params?.deliver).toBe(true);
expect(call?.params?.channel).toBe("discord");
});
it("falls back when parent session is missing a sessionId (#18037)", async () => {
const { runSubagentAnnounceFlow } = await import("./subagent-announce.js");
embeddedRunMock.isEmbeddedPiRunActive.mockReturnValue(false);
embeddedRunMock.isEmbeddedPiRunStreaming.mockReturnValue(false);
subagentRegistryMock.isSubagentSessionRunActive.mockReturnValue(false);
sessionStore = {
"agent:main:subagent:newton": {
sessionId: " ",
inputTokens: 100,
outputTokens: 50,
},
"agent:main:subagent:newton:subagent:birdie": {
sessionId: "birdie-session-id",
inputTokens: 20,
outputTokens: 10,
},
};
subagentRegistryMock.resolveRequesterForChildSession.mockReturnValue({
requesterSessionKey: "agent:main:main",
requesterOrigin: { channel: "discord" },
});
const didAnnounce = await runSubagentAnnounceFlow({
childSessionKey: "agent:main:subagent:newton:subagent:birdie",
childRunId: "run-birdie-empty-parent",
requesterSessionKey: "agent:main:subagent:newton",
requesterDisplayKey: "subagent:newton",
task: "QA task",
timeoutMs: 1000,
cleanup: "keep",
waitForCompletion: false,
startedAt: 10,
endedAt: 20,
outcome: { status: "ok" },
});
expect(didAnnounce).toBe(true);
const call = agentSpy.mock.calls[0]?.[0] as { params?: Record<string, unknown> };
expect(call?.params?.sessionKey).toBe("agent:main:main");
expect(call?.params?.deliver).toBe(true);
expect(call?.params?.channel).toBe("discord");
});
});

View File

@@ -29,12 +29,12 @@ vi.mock("./session-utils.js", () => ({
}));
import type { CliDeps } from "../cli/deps.js";
import type { HealthSummary } from "../commands/health.js";
import type { NodeEventContext } from "./server-node-events-types.js";
import { agentCommand } from "../commands/agent.js";
import type { HealthSummary } from "../commands/health.js";
import { updateSessionStore } from "../config/sessions.js";
import { requestHeartbeatNow } from "../infra/heartbeat-wake.js";
import { enqueueSystemEvent } from "../infra/system-events.js";
import type { NodeEventContext } from "./server-node-events-types.js";
import { handleNodeEvent } from "./server-node-events.js";
const enqueueSystemEventMock = vi.mocked(enqueueSystemEvent);

View File

@@ -76,7 +76,10 @@ function shouldDropDuplicateVoiceTranscript(params: {
) {
return true;
}
recentVoiceTranscripts.set(params.sessionKey, { fingerprint: params.fingerprint, ts: params.now });
recentVoiceTranscripts.set(params.sessionKey, {
fingerprint: params.fingerprint,
ts: params.now,
});
if (recentVoiceTranscripts.size > MAX_RECENT_VOICE_TRANSCRIPTS) {
const cutoff = params.now - VOICE_TRANSCRIPT_DEDUPE_WINDOW_MS * 2;

View File

@@ -1,7 +1,7 @@
import { Command } from "commander";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { Command } from "commander";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
let runtimeStub: {