Context: PR #26569 narrowly fixed a crash where the generated SDK sent GET /session/{sessionID}/message?limit=80&directory=... because public.ts manually injected InstanceQueryParameters (directory/workspace) into OpenAPI, but the runtime MessagesQuery schema omitted directory, causing empty 400. This change eliminates the drift by: 1. Creating a shared schema helper in query.ts that adds directory/workspace fields to all instance route query schemas. 2. Updating all instance route query schemas to use the helper: - session.ts: MessagesQuery, ListQuery - file.ts: FileQuery, FindTextQuery, FindFileQuery, FindSymbolQuery - experimental.ts: ToolListQuery, SessionListQuery - control.ts: LogQuery (already correct, now uses helper) - instance.ts, v2/session.ts, v2/message.ts 3. Adding reproducer tests in httpapi-query-schema-drift.test.ts that verify the runtime accepts directory/workspace params on affected routes. The OpenAPI spec generation in public.ts still manually injects params for backward compatibility with the legacy SDK format, but now the runtime schemas match, eliminating the validation errors. Verification: - bun typecheck passes - 4 drift reproducer tests pass - 24 httpapi tests pass across session, file, experimental, workspace-routing
73 lines
2.5 KiB
TypeScript
73 lines
2.5 KiB
TypeScript
import { Auth } from "@/auth"
|
|
import { ProviderID } from "@/provider/schema"
|
|
import { Schema } from "effect"
|
|
import { HttpApi, HttpApiEndpoint, HttpApiError, HttpApiGroup, OpenApi } from "effect/unstable/httpapi"
|
|
import { withWorkspaceRouting } from "../query"
|
|
import { described } from "./metadata"
|
|
|
|
const AuthParams = Schema.Struct({
|
|
providerID: ProviderID,
|
|
})
|
|
|
|
const LogQuery = withWorkspaceRouting({})
|
|
|
|
export const LogInput = Schema.Struct({
|
|
service: Schema.String.annotate({ description: "Service name for the log entry" }),
|
|
level: Schema.Union([
|
|
Schema.Literal("debug"),
|
|
Schema.Literal("info"),
|
|
Schema.Literal("error"),
|
|
Schema.Literal("warn"),
|
|
]).annotate({ description: "Log level" }),
|
|
message: Schema.String.annotate({ description: "Log message" }),
|
|
extra: Schema.optional(Schema.Record(Schema.String, Schema.Unknown)).annotate({
|
|
description: "Additional metadata for the log entry",
|
|
}),
|
|
})
|
|
|
|
export const ControlPaths = {
|
|
auth: "/auth/:providerID",
|
|
log: "/log",
|
|
} as const
|
|
|
|
export const ControlApi = HttpApi.make("control").add(
|
|
HttpApiGroup.make("control")
|
|
.add(
|
|
HttpApiEndpoint.put("authSet", ControlPaths.auth, {
|
|
params: AuthParams,
|
|
payload: Auth.Info,
|
|
success: described(Schema.Boolean, "Successfully set authentication credentials"),
|
|
error: HttpApiError.BadRequest,
|
|
}).annotateMerge(
|
|
OpenApi.annotations({
|
|
identifier: "auth.set",
|
|
summary: "Set auth credentials",
|
|
description: "Set authentication credentials",
|
|
}),
|
|
),
|
|
HttpApiEndpoint.delete("authRemove", ControlPaths.auth, {
|
|
params: AuthParams,
|
|
success: described(Schema.Boolean, "Successfully removed authentication credentials"),
|
|
error: HttpApiError.BadRequest,
|
|
}).annotateMerge(
|
|
OpenApi.annotations({
|
|
identifier: "auth.remove",
|
|
summary: "Remove auth credentials",
|
|
description: "Remove authentication credentials",
|
|
}),
|
|
),
|
|
HttpApiEndpoint.post("log", ControlPaths.log, {
|
|
query: LogQuery,
|
|
payload: LogInput,
|
|
success: described(Schema.Boolean, "Log entry written successfully"),
|
|
error: HttpApiError.BadRequest,
|
|
}).annotateMerge(
|
|
OpenApi.annotations({
|
|
identifier: "app.log",
|
|
summary: "Write log",
|
|
description: "Write a log entry to the server logs with specified level and metadata.",
|
|
}),
|
|
),
|
|
)
|
|
.annotateMerge(OpenApi.annotations({ title: "control", description: "Control plane routes." })),
|
|
)
|