feat(core): add embedded v2 session runtime and tool foundation (#30632)
This commit is contained in:
@@ -3,7 +3,7 @@ import { OpenApi } from "effect/unstable/httpapi"
|
||||
import { PublicApi } from "../../src/server/routes/instance/httpapi/public"
|
||||
|
||||
type Method = "get" | "post" | "put" | "delete" | "patch"
|
||||
type OpenApiSchema = { readonly $ref?: string }
|
||||
type OpenApiSchema = { readonly $ref?: string; readonly anyOf?: ReadonlyArray<OpenApiSchema> }
|
||||
type OpenApiResponse = {
|
||||
readonly description?: string
|
||||
readonly content?: Record<string, { readonly schema?: OpenApiSchema }>
|
||||
@@ -16,6 +16,7 @@ type OpenApiOperation = {
|
||||
readonly schema?: { readonly type?: string }
|
||||
}>
|
||||
readonly responses?: Record<string, OpenApiResponse>
|
||||
readonly requestBody?: { readonly required?: boolean }
|
||||
readonly security?: unknown
|
||||
}
|
||||
type OpenApiPathItem = Partial<Record<Method, OpenApiOperation>>
|
||||
@@ -44,6 +45,12 @@ function componentName(ref: string) {
|
||||
return ref.replace("#/components/schemas/", "")
|
||||
}
|
||||
|
||||
function componentNames(response: OpenApiResponse | undefined) {
|
||||
const schema = response?.content?.["application/json"]?.schema
|
||||
if (!schema) return []
|
||||
return [schema, ...(schema.anyOf ?? [])].flatMap((item) => (item.$ref ? [componentName(item.$ref)] : []))
|
||||
}
|
||||
|
||||
function isBuiltInEndpointError(name: string) {
|
||||
return name.startsWith("EffectHttpApiError") || name.startsWith("effect_HttpApiError_")
|
||||
}
|
||||
@@ -71,6 +78,18 @@ describe("PublicApi OpenAPI v2 errors", () => {
|
||||
}
|
||||
})
|
||||
|
||||
test("preserves required request bodies for v2 mutations", () => {
|
||||
const spec = OpenApi.fromApi(PublicApi) as OpenApiSpec
|
||||
|
||||
for (const path of [
|
||||
"/api/session/{sessionID}/prompt",
|
||||
"/api/session/{sessionID}/permission/request/{requestID}/reply",
|
||||
"/api/session/{sessionID}/question/request/{requestID}/reply",
|
||||
]) {
|
||||
expect(spec.paths[path]?.post?.requestBody?.required, path).toBe(true)
|
||||
}
|
||||
})
|
||||
|
||||
test("does not rewrite /api endpoint errors to legacy error components", () => {
|
||||
const spec = OpenApi.fromApi(PublicApi) as OpenApiSpec
|
||||
const refs = v2Operations(spec)
|
||||
@@ -139,7 +158,6 @@ describe("PublicApi OpenAPI v2 errors", () => {
|
||||
const spec = OpenApi.fromApi(PublicApi) as OpenApiSpec
|
||||
|
||||
for (const route of [
|
||||
["post", "/api/session/{sessionID}/prompt"],
|
||||
["post", "/api/session/{sessionID}/compact"],
|
||||
["post", "/api/session/{sessionID}/wait"],
|
||||
] as const) {
|
||||
@@ -191,6 +209,15 @@ describe("PublicApi OpenAPI v2 errors", () => {
|
||||
"QuestionNotFoundError",
|
||||
)
|
||||
}
|
||||
for (const route of [
|
||||
["post", "/api/session/{sessionID}/question/request/{requestID}/reply"],
|
||||
["post", "/api/session/{sessionID}/question/request/{requestID}/reject"],
|
||||
] as const) {
|
||||
expect(componentNames(spec.paths[route[1]]?.[route[0]]?.responses?.["404"])).toEqual([
|
||||
"SessionNotFoundError",
|
||||
"QuestionNotFoundError",
|
||||
])
|
||||
}
|
||||
})
|
||||
|
||||
test("documents MCP server not-found errors", () => {
|
||||
|
||||
Reference in New Issue
Block a user