fix: centralize verbose overrides and tool stream gating

This commit is contained in:
Peter Steinberger
2026-01-10 00:52:11 +01:00
parent 9a8d3aed26
commit 097550c299
15 changed files with 203 additions and 127 deletions

View File

@@ -1,13 +1,8 @@
import type { AssistantMessage } from "@mariozechner/pi-ai";
import { describe, expect, it, vi } from "vitest";
import { emitAgentEvent } from "../infra/agent-events.js";
import { subscribeEmbeddedPiSession } from "./pi-embedded-subscribe.js";
vi.mock("../infra/agent-events.js", () => ({
emitAgentEvent: vi.fn(),
}));
type StubSession = {
subscribe: (fn: (evt: unknown) => void) => () => void;
};
@@ -15,8 +10,6 @@ type StubSession = {
type SessionEventHandler = (evt: unknown) => void;
describe("subscribeEmbeddedPiSession", () => {
const emitAgentEventMock = vi.mocked(emitAgentEvent);
it("filters to <final> and falls back when tags are malformed", () => {
let handler: ((evt: unknown) => void) | undefined;
const session: StubSession = {
@@ -1474,48 +1467,6 @@ describe("subscribeEmbeddedPiSession", () => {
expect(onToolResult).not.toHaveBeenCalled();
});
it("skips tool stream events when tool verbose is off", () => {
let handler: ((evt: unknown) => void) | undefined;
const session: StubSession = {
subscribe: (fn) => {
handler = fn;
return () => {};
},
};
emitAgentEventMock.mockReset();
subscribeEmbeddedPiSession({
session: session as unknown as Parameters<
typeof subscribeEmbeddedPiSession
>[0]["session"],
runId: "run-tool-events-off",
shouldEmitToolResult: () => false,
});
handler?.({
type: "tool_execution_start",
toolName: "read",
toolCallId: "tool-evt-1",
args: { path: "/tmp/off.txt" },
});
handler?.({
type: "tool_execution_update",
toolName: "read",
toolCallId: "tool-evt-1",
partialResult: "partial",
});
handler?.({
type: "tool_execution_end",
toolName: "read",
toolCallId: "tool-evt-1",
isError: false,
result: "ok",
});
expect(emitAgentEventMock).not.toHaveBeenCalled();
});
it("emits tool summaries when shouldEmitToolResult overrides verbose", () => {
let handler: ((evt: unknown) => void) | undefined;
const session: StubSession = {

View File

@@ -368,7 +368,6 @@ export function subscribeEmbeddedPiSession(params: {
const toolMetas: Array<{ toolName?: string; meta?: string }> = [];
const toolMetaById = new Map<string, string | undefined>();
const toolSummaryById = new Set<string>();
const toolEventById = new Set<string>();
const blockReplyBreak = params.blockReplyBreak ?? "text_end";
const reasoningMode = params.reasoningMode ?? "off";
const includeReasoning = reasoningMode === "on";
@@ -590,7 +589,6 @@ export function subscribeEmbeddedPiSession(params: {
toolMetas.length = 0;
toolMetaById.clear();
toolSummaryById.clear();
toolEventById.clear();
messagingToolSentTexts.length = 0;
messagingToolSentTargets.length = 0;
pendingMessagingTexts.clear();
@@ -642,19 +640,16 @@ export function subscribeEmbeddedPiSession(params: {
);
const shouldEmitToolEvents = shouldEmitToolResult();
if (shouldEmitToolEvents) {
toolEventById.add(toolCallId);
emitAgentEvent({
runId: params.runId,
stream: "tool",
data: {
phase: "start",
name: toolName,
toolCallId,
args: args as Record<string, unknown>,
},
});
}
emitAgentEvent({
runId: params.runId,
stream: "tool",
data: {
phase: "start",
name: toolName,
toolCallId,
args: args as Record<string, unknown>,
},
});
params.onAgentEvent?.({
stream: "tool",
data: { phase: "start", name: toolName, toolCallId },
@@ -710,18 +705,16 @@ export function subscribeEmbeddedPiSession(params: {
const partial = (evt as AgentEvent & { partialResult?: unknown })
.partialResult;
const sanitized = sanitizeToolResult(partial);
if (toolEventById.has(toolCallId)) {
emitAgentEvent({
runId: params.runId,
stream: "tool",
data: {
phase: "update",
name: toolName,
toolCallId,
partialResult: sanitized,
},
});
}
emitAgentEvent({
runId: params.runId,
stream: "tool",
data: {
phase: "update",
name: toolName,
toolCallId,
partialResult: sanitized,
},
});
params.onAgentEvent?.({
stream: "tool",
data: {
@@ -768,22 +761,18 @@ export function subscribeEmbeddedPiSession(params: {
}
}
const shouldEmitToolEvents = toolEventById.has(toolCallId);
if (shouldEmitToolEvents) {
emitAgentEvent({
runId: params.runId,
stream: "tool",
data: {
phase: "result",
name: toolName,
toolCallId,
meta,
isError,
result: sanitizedResult,
},
});
}
toolEventById.delete(toolCallId);
emitAgentEvent({
runId: params.runId,
stream: "tool",
data: {
phase: "result",
name: toolName,
toolCallId,
meta,
isError,
result: sanitizedResult,
},
});
params.onAgentEvent?.({
stream: "tool",
data: {