pull/715/head
Travis Fischer 2025-06-05 08:41:59 +07:00
rodzic e9f63bb86b
commit 87d75237c0
4 zmienionych plików z 97 dodań i 16 usunięć

Wyświetl plik

@ -36,7 +36,7 @@ et est aut quod aut provident voluptas autem voluptas",
}
`;
exports[`Basic OpenAPI getPost(1) > 0.0: GET dev/test-basic-openapi/getPost 1`] = `
exports[`Basic OpenAPI getPost success > 0.0: GET dev/test-basic-openapi/getPost 1`] = `
{
"body": "quia et suscipit
suscipit recusandae consequuntur expedita et cum
@ -48,7 +48,7 @@ nostrum rerum est autem sunt rem eveniet architecto",
}
`;
exports[`Basic OpenAPI getPost(1) > 0.1: GET dev/test-basic-openapi@b6e21206/getPost?postId=1 1`] = `
exports[`Basic OpenAPI getPost success > 0.1: GET dev/test-basic-openapi@b6e21206/getPost?postId=1 1`] = `
{
"body": "quia et suscipit
suscipit recusandae consequuntur expedita et cum
@ -60,7 +60,7 @@ nostrum rerum est autem sunt rem eveniet architecto",
}
`;
exports[`Basic OpenAPI getPost(1) > 0.2: GET dev/test-basic-openapi@b6e21206/get_post?postId=1 1`] = `
exports[`Basic OpenAPI getPost success > 0.2: GET dev/test-basic-openapi@b6e21206/get_post?postId=1 1`] = `
{
"body": "quia et suscipit
suscipit recusandae consequuntur expedita et cum
@ -72,7 +72,7 @@ nostrum rerum est autem sunt rem eveniet architecto",
}
`;
exports[`Basic OpenAPI getPost(1) > 0.3: GET dev/test-basic-openapi@b6e21206/getPost 1`] = `
exports[`Basic OpenAPI getPost success > 0.3: GET dev/test-basic-openapi@b6e21206/getPost 1`] = `
{
"body": "quia et suscipit
suscipit recusandae consequuntur expedita et cum
@ -84,7 +84,7 @@ nostrum rerum est autem sunt rem eveniet architecto",
}
`;
exports[`Basic OpenAPI getPost(1) > 0.4: POST dev/test-basic-openapi/getPost 1`] = `
exports[`Basic OpenAPI getPost success > 0.4: POST dev/test-basic-openapi/getPost 1`] = `
{
"body": "quia et suscipit
suscipit recusandae consequuntur expedita et cum
@ -96,7 +96,7 @@ nostrum rerum est autem sunt rem eveniet architecto",
}
`;
exports[`Basic OpenAPI getPost(1) > 0.5: POST dev/test-basic-openapi@latest/getPost 1`] = `
exports[`Basic OpenAPI getPost success > 0.5: POST dev/test-basic-openapi@latest/getPost 1`] = `
{
"body": "quia et suscipit
suscipit recusandae consequuntur expedita et cum

Wyświetl plik

@ -45,7 +45,7 @@ export type E2ETestFixtureSuite = {
export const fixtureSuites: E2ETestFixtureSuite[] = [
{
title: 'Basic OpenAPI getPost(1)',
title: 'Basic OpenAPI getPost success',
compareResponseBodies: true,
fixtures: [
{
@ -130,7 +130,75 @@ export const fixtureSuites: E2ETestFixtureSuite[] = [
response: {
status: 404
}
},
{
path: 'dev/test-basic-openapi/getPost',
request: {
searchParams: {
// invalid `postId` field type
postId: 'not-a-number'
}
},
response: {
status: 400
}
},
{
path: 'dev/test-basic-openapi/getPost',
request: {
method: 'POST',
json: {
// missing required `postId` field
}
},
response: {
status: 400
}
},
{
path: 'dev/test-basic-openapi/getPost',
request: {
method: 'POST',
json: {
// invalid `postId` field type
postId: 'foo'
}
},
response: {
status: 400
}
},
{
path: 'dev/test-basic-openapi/getPost',
request: {
method: 'POST',
json: {
// invalid `postId` field type
postId: 'foo'
}
},
response: {
status: 400
}
}
// TODO: This should throw an error, but `cfValidateJsonSchemaObject`
// currently does not validate additional properties.
// TODO: also add a similar test for extra searchParams.
// {
// path: 'dev/test-basic-openapi/getPost',
// only: true,
// request: {
// method: 'POST',
// json: {
// postId: 1,
// // additional properties should throw an error
// foo: 'bar'
// }
// },
// response: {
// status: 400
// }
// }
]
},
{
@ -138,6 +206,7 @@ export const fixtureSuites: E2ETestFixtureSuite[] = [
compareResponseBodies: true,
fixtures: [
{
// ensure we bypass the cache for requests with `pragma: no-cache`
path: 'dev/test-basic-openapi@b6e21206/getPost',
request: {
headers: {
@ -154,6 +223,7 @@ export const fixtureSuites: E2ETestFixtureSuite[] = [
}
},
{
// ensure we bypass the cache for requests with `pragma: no-cache`
path: 'dev/test-basic-openapi@b6e21206/getPost?postId=9',
request: {
headers: {
@ -167,6 +237,7 @@ export const fixtureSuites: E2ETestFixtureSuite[] = [
}
},
{
// ensure we bypass the cache for requests with `cache-control: no-store`
path: 'dev/test-basic-openapi@b6e21206/get_post?postId=9',
request: {
headers: {
@ -200,6 +271,7 @@ export const fixtureSuites: E2ETestFixtureSuite[] = [
sequential: true,
fixtures: [
{
// first request to ensure the cache is populated
path: 'dev/test-basic-openapi@b6e21206/getPost',
request: {
searchParams: {
@ -208,6 +280,7 @@ export const fixtureSuites: E2ETestFixtureSuite[] = [
}
},
{
// second request should hit the cache
path: 'dev/test-basic-openapi@b6e21206/getPost?postId=9',
response: {
headers: {
@ -216,6 +289,7 @@ export const fixtureSuites: E2ETestFixtureSuite[] = [
}
},
{
// normalized request should also hit the cache
path: 'dev/test-basic-openapi@b6e21206/get_post?postId=9',
response: {
headers: {
@ -231,6 +305,7 @@ export const fixtureSuites: E2ETestFixtureSuite[] = [
sequential: true,
fixtures: [
{
// first request to ensure the cache is populated
path: 'dev/test-basic-openapi@b6e21206/get_post',
request: {
method: 'POST',
@ -240,6 +315,7 @@ export const fixtureSuites: E2ETestFixtureSuite[] = [
}
},
{
// second request should hit the cache
path: 'dev/test-basic-openapi@b6e21206/get_post',
request: {
method: 'POST',

Wyświetl plik

@ -14,7 +14,7 @@ import plur from 'plur'
* `@agentic/platform-openapi-utils`.
*/
export function cfValidateJsonSchemaObject<
T extends Record<string, unknown> = Record<string, unknown>
T extends Record<string, any> = Record<string, any>
>({
schema,
data,
@ -27,7 +27,7 @@ export function cfValidateJsonSchemaObject<
coerce?: boolean
}): T {
// Special-case check for required fields to give better error messages
if (Array.isArray(schema.required)) {
if (schema.required && Array.isArray(schema.required)) {
const missingRequiredFields: string[] = schema.required.filter(
(field: string) => (data as T)[field] === undefined
)
@ -43,7 +43,8 @@ export function cfValidateJsonSchemaObject<
const validator = new Validator({ schema, coerce })
const result = validator.validate(data)
if (result.valid) {
return data as T
// Return the (possibly) coerced data
return result.instance as T
}
const finalErrorMessage = `${

Wyświetl plik

@ -27,10 +27,11 @@ export async function createRequestForOpenAPIOperation(
`Unexpected origin adapter type: "${deployment.originAdapter.type}"`
)
let incomingRequestParams: Record<string, any> = {}
let incomingRequestParamsRaw: Record<string, any> = {}
if (request.method === 'GET') {
// TODO: coerce data types to match input schema since all values will be strings
incomingRequestParams = Object.fromEntries(
// Params will be coerced to match their expected types via
// `cfValidateJsonSchemaObject` since all values will be strings.
incomingRequestParamsRaw = Object.fromEntries(
new URL(request.url).searchParams.entries()
)
@ -40,18 +41,21 @@ export async function createRequestForOpenAPIOperation(
// searchParams: new URL(request.url).searchParams
// })
} else if (request.method === 'POST') {
incomingRequestParams = (await request.clone().json()) as Record<
incomingRequestParamsRaw = (await request.clone().json()) as Record<
string,
any
>
// TODO: Support empty params for POST requests
assert(incomingRequestParamsRaw, 400, 'Invalid empty request body')
}
// TODO: Validate incoming request params against the tool's input JSON schema
// TODO: we want to coerce data types to match the schema for booleans, dates, etc
// Currently, these will fail if given as body params, for instance, on the origin server.
cfValidateJsonSchemaObject({
const incomingRequestParams = cfValidateJsonSchemaObject({
schema: tool.inputSchema,
data: incomingRequestParams,
data: incomingRequestParamsRaw,
errorMessage: `Invalid request parameters for tool "${tool.name}"`
})