Remove unjustified test-only exports

This commit is contained in:
murashit 2026-06-27 14:15:44 +09:00
parent 582bc0195d
commit e39d4b90a4
5 changed files with 119 additions and 59 deletions

View file

@ -1,7 +1,7 @@
import type { ServerInitialization } from "./initialization";
import { cloneToolInventorySnapshot, type ToolInventorySnapshot } from "./tool-inventory";
export const DIAGNOSTIC_PROBE_METHODS = [
const DIAGNOSTIC_PROBE_METHODS = [
"model/list",
"skills/list",
"app/list",

View file

@ -316,18 +316,6 @@ const THREAD_LIFECYCLE_PLANNERS = {
},
} satisfies ServerNotificationStatePlannerMap<ThreadLifecycleNotificationMethod>;
export const PLANNED_SERVER_NOTIFICATION_METHODS_BY_ROUTE_KIND = {
streamUpdate: plannerMethods(STREAM_UPDATE_PLANNERS),
turnLifecycle: plannerMethods(TURN_LIFECYCLE_PLANNERS),
threadLifecycle: plannerMethods(THREAD_LIFECYCLE_PLANNERS),
requestResolved: ["serverRequest/resolved"],
diagnosticStatus: plannerMethods(DIAGNOSTIC_STATUS_PLANNERS),
userVisibleNotice: plannerMethods(USER_VISIBLE_NOTICE_PLANNERS),
} satisfies Record<
Exclude<ReturnType<typeof routeServerNotification>["kind"], "inactive" | "unhandled" | "ignored">,
readonly ServerNotification["method"][]
>;
export function planChatNotification(
state: ChatState,
notification: ServerNotification,
@ -419,10 +407,6 @@ function planNotificationWithStateByMethod<M extends ServerNotification["method"
return planner(state, notification, localItemId);
}
function plannerMethods<M extends ServerNotification["method"]>(planners: Record<M, unknown>): readonly M[] {
return Object.keys(planners) as M[];
}
function jsonNoticePlan(
notification: Extract<ServerNotification, { method: Exclude<UserVisibleNoticeNotificationMethod, "thread/compacted"> }>,
localItemId: LocalItemIdProvider,

View file

@ -103,7 +103,7 @@ const USER_VISIBLE_NOTICE_NOTIFICATION_METHODS = [
export type UserVisibleNoticeNotificationMethod = (typeof USER_VISIBLE_NOTICE_NOTIFICATION_METHODS)[number];
export const IGNORED_SERVER_NOTIFICATION_METHODS = [
const IGNORED_SERVER_NOTIFICATION_METHODS = [
"thread/status/changed",
"thread/closed",
"rawResponseItem/completed",
@ -134,15 +134,6 @@ export const IGNORED_SERVER_NOTIFICATION_METHODS = [
type IgnoredServerNotificationMethod = (typeof IGNORED_SERVER_NOTIFICATION_METHODS)[number];
export const ROUTED_SERVER_NOTIFICATION_METHODS_BY_ROUTE_KIND = {
streamUpdate: STREAM_UPDATE_NOTIFICATION_METHODS,
turnLifecycle: TURN_LIFECYCLE_NOTIFICATION_METHODS,
threadLifecycle: THREAD_LIFECYCLE_NOTIFICATION_METHODS,
requestResolved: ["serverRequest/resolved"],
diagnosticStatus: DIAGNOSTIC_STATUS_NOTIFICATION_METHODS,
userVisibleNotice: USER_VISIBLE_NOTICE_NOTIFICATION_METHODS,
} satisfies Record<Exclude<ServerNotificationRoute["kind"], "inactive" | "unhandled" | "ignored">, readonly ServerNotificationMethod[]>;
const SERVER_NOTIFICATION_SCOPE_EXTRACTORS: ServerNotificationScopeExtractors = {
error: threadTurnNotificationScope,
"thread/started": threadStartedNotificationScope,

View file

@ -2,7 +2,6 @@ import { describe, expect, it } from "vitest";
import {
createServerDiagnostics,
DIAGNOSTIC_PROBE_METHODS,
diagnosticProbeError,
diagnosticProbeOk,
serverIdentity,
@ -27,7 +26,14 @@ describe("app-server diagnostics", () => {
it("creates generic capability probe defaults", () => {
const diagnostics = createServerDiagnostics();
expect(Object.keys(diagnostics.probes)).toEqual([...DIAGNOSTIC_PROBE_METHODS]);
expect(Object.keys(diagnostics.probes)).toEqual([
"model/list",
"skills/list",
"app/list",
"plugin/installed",
"account/rateLimits/read",
"mcpServerStatus/list",
]);
expect(diagnostics.probes["model/list"]).toMatchObject({
method: "model/list",
status: "unknown",

View file

@ -3,15 +3,8 @@ import path from "node:path";
import { describe, expect, it } from "vitest";
import type { ServerNotification, ServerRequest } from "../../../../../src/app-server/connection/rpc-messages";
import { routeServerRequest } from "../../../../../src/app-server/server-requests";
import {
PLANNED_SERVER_NOTIFICATION_METHODS_BY_ROUTE_KIND,
planChatNotification,
} from "../../../../../src/features/chat/app-server/inbound/notification-plan";
import {
IGNORED_SERVER_NOTIFICATION_METHODS,
ROUTED_SERVER_NOTIFICATION_METHODS_BY_ROUTE_KIND,
routeServerNotification,
} from "../../../../../src/features/chat/app-server/inbound/notification-routing";
import { planChatNotification } from "../../../../../src/features/chat/app-server/inbound/notification-plan";
import { routeServerNotification } from "../../../../../src/features/chat/app-server/inbound/notification-routing";
import { chatStateFixture, chatStateWith } from "../../support/state";
const activeScope = { activeThreadId: "thread-active", activeTurnId: "turn-active" };
@ -20,18 +13,28 @@ type NotificationRouteKind = ReturnType<typeof routeServerNotification>["kind"];
type RequestRouteKind = ReturnType<typeof routeServerRequest>["kind"];
describe("chat inbound routing", () => {
it("keeps routed notification methods covered by matching planners", () => {
expect(sortedMethods(PLANNED_SERVER_NOTIFICATION_METHODS_BY_ROUTE_KIND)).toEqual(
sortedMethods(ROUTED_SERVER_NOTIFICATION_METHODS_BY_ROUTE_KIND),
it("keeps generated app-server notifications explicitly routed or ignored", () => {
const unhandled = generatedServerNotificationMethods().filter(
(method) => routeServerNotification(notificationFixture(method), activeScope).kind === "unhandled",
);
expect(unhandled).toEqual([]);
});
it("keeps generated app-server notifications explicitly routed or ignored", () => {
const routed = flattenedMethods(ROUTED_SERVER_NOTIFICATION_METHODS_BY_ROUTE_KIND);
const ignored = [...IGNORED_SERVER_NOTIFICATION_METHODS];
it("keeps routed notification methods covered by matching planners", () => {
let state = chatStateFixture();
state = chatStateWith(state, { activeThread: { id: "thread-active" } });
state = chatStateWith(state, { turn: { lifecycle: { kind: "running", turnId: "turn-active" } } });
const plannedMethods = generatedServerNotificationMethods().filter((method) => {
const kind = routeServerNotification(notificationFixture(method), activeScope).kind;
return kind !== "inactive" && kind !== "ignored" && kind !== "unhandled";
});
expect(intersection(routed, ignored)).toEqual([]);
expect([...new Set([...routed, ...ignored])].sort()).toEqual(generatedServerNotificationMethods());
expect(() => {
for (const method of plannedMethods) {
planChatNotification(state, notificationFixture(method), (prefix) => `${prefix}-1`);
}
}).not.toThrow();
});
it("routes turn-scoped app-server messages for the active scope", () => {
@ -442,19 +445,6 @@ function turnStartedNotification(): ServerNotification {
};
}
function sortedMethods(methodsByRouteKind: Record<string, readonly string[]>): Record<string, readonly string[]> {
return Object.fromEntries(Object.entries(methodsByRouteKind).map(([kind, methods]) => [kind, [...methods].sort()]));
}
function flattenedMethods(methodsByRouteKind: Record<string, readonly string[]>): string[] {
return Object.values(methodsByRouteKind).flat().sort();
}
function intersection(left: readonly string[], right: readonly string[]): string[] {
const rightSet = new Set(right);
return left.filter((method) => rightSet.has(method)).sort();
}
function generatedServerNotificationMethods(): string[] {
const generated = readFileSync(path.join(process.cwd(), "src/generated/app-server/ServerNotification.ts"), "utf8");
return [...generated.matchAll(/"method": "([^"]+)"/g)]
@ -466,6 +456,95 @@ function generatedServerNotificationMethods(): string[] {
.sort();
}
function notificationFixture(method: string): ServerNotification {
return {
method,
params: {
threadId: "thread-active",
turnId: "turn-active",
thread: threadSnapshot("thread-active"),
turn: {
id: "turn-active",
status: "completed",
error: null,
startedAt: null,
completedAt: null,
durationMs: null,
itemsView: "full",
items: [],
},
item: { type: "agentMessage", id: "item", text: "hello" },
itemId: "item",
requestId: 1,
delta: "delta",
diff: "",
changes: [],
explanation: null,
plan: [],
run: {
id: "run",
eventName: "userPromptSubmit",
status: "completed",
statusMessage: null,
startedAt: 1,
durationMs: null,
entries: [],
},
name: "github",
status: "ready",
error: null,
message: "notice",
success: true,
tokenUsage: {
total: tokenBreakdownFixture(),
last: tokenBreakdownFixture(),
modelContextWindow: null,
},
threadSettings: {
cwd: "/vault",
model: "gpt-5.5",
effort: "medium",
collaborationMode: { mode: "default" },
serviceTier: null,
approvalsReviewer: "user",
},
goal: {
threadId: "thread-active",
objective: "Finish",
status: "active",
tokenBudget: null,
tokensUsed: 0,
timeUsedSeconds: 0,
createdAt: 1,
updatedAt: 1,
},
startedAtMs: 1,
reviewId: "review",
targetItemId: null,
review: { status: "approved", riskLevel: null, userAuthorization: null, rationale: null },
action: { type: "command", source: "user", command: "npm test", cwd: "/vault" },
completedAtMs: 2,
decisionSource: "auto",
},
} as unknown as ServerNotification;
}
function tokenBreakdownFixture(): {
totalTokens: number;
inputTokens: number;
cachedInputTokens: number;
outputTokens: number;
reasoningOutputTokens: number;
} {
return {
totalTokens: 0,
inputTokens: 0,
cachedInputTokens: 0,
outputTokens: 0,
reasoningOutputTokens: 0,
};
}
function threadArchivedNotification(threadId = "thread-active"): ServerNotification {
return {
method: "thread/archived",