feat: e2e sexiness

pull/715/head
Travis Fischer 2025-06-11 13:05:24 +07:00
rodzic 1884597812
commit 9de0192922
5 zmienionych plików z 88 dodań i 21 usunięć

Wyświetl plik

@ -54,6 +54,30 @@ exports[`Basic MCP origin "add" tool call success > 5.1: GET @dev/test-basic-mcp
] ]
`; `;
exports[`Basic OpenAPI getPost errors > 1.9: POST @dev/test-basic-openapi/getPost 1`] = `
{
"body": "quia et suscipit
suscipit recusandae consequuntur expedita et cum
reprehenderit molestiae ut ut quas totam
nostrum rerum est autem sunt rem eveniet architecto",
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"userId": 1,
}
`;
exports[`Basic OpenAPI getPost errors > 1.10: GET @dev/test-basic-openapi/getPost 1`] = `
{
"body": "quia et suscipit
suscipit recusandae consequuntur expedita et cum
reprehenderit molestiae ut ut quas totam
nostrum rerum est autem sunt rem eveniet architecto",
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"userId": 1,
}
`;
exports[`Basic OpenAPI getPost success > 0.0: POST @dev/test-basic-openapi/getPost 1`] = ` exports[`Basic OpenAPI getPost success > 0.0: POST @dev/test-basic-openapi/getPost 1`] = `
{ {
"body": "quia et suscipit "body": "quia et suscipit
@ -222,14 +246,14 @@ et est aut quod aut provident voluptas autem voluptas",
} }
`; `;
exports[`OpenAPI kitchen sink pure tool > 7.0: POST @dev/test-everything-openapi@390e70bf/pure 1`] = ` exports[`OpenAPI kitchen sink pure tool > 7.0: POST @dev/test-everything-openapi/pure 1`] = `
{ {
"foo": "bar", "foo": "bar",
"nala": "kitten", "nala": "kitten",
} }
`; `;
exports[`OpenAPI kitchen sink pure tool > 7.1: POST @dev/test-everything-openapi@390e70bf/pure 1`] = ` exports[`OpenAPI kitchen sink pure tool > 7.1: POST @dev/test-everything-openapi/pure 1`] = `
{ {
"foo": "bar", "foo": "bar",
"nala": "kitten", "nala": "kitten",

Wyświetl plik

@ -201,12 +201,12 @@ export const fixtureSuites: E2ETestFixtureSuite[] = [
method: 'POST', method: 'POST',
json: { json: {
postId: 1, postId: 1,
// additional json body params should throw an error // additional json body params are allowed by default
foo: 'bar' foo: 'bar'
} }
}, },
response: { response: {
status: 400 status: 200
} }
}, },
{ {
@ -214,10 +214,40 @@ export const fixtureSuites: E2ETestFixtureSuite[] = [
request: { request: {
searchParams: { searchParams: {
postId: 1, postId: 1,
// additional search params should throw an error // additional search params should allowed by default
foo: 'bar' foo: 'bar'
} }
}, },
response: {
status: 200
}
},
{
path: '@dev/test-everything-openapi/strict_additional_properties',
request: {
method: 'POST',
json: {
foo: 'bar',
// additional json body params should throw an error if the tool
// config has `additionalProperties: false`
extra: 'nala'
}
},
response: {
status: 400
}
},
{
path: '@dev/test-everything-openapi/strict_additional_properties',
request: {
method: 'GET',
searchParams: {
foo: 'bar',
// additional search params should throw an error if the tool
// config has `additionalProperties: false`
extra: 'nala'
}
},
response: { response: {
status: 400 status: 400
} }
@ -482,7 +512,7 @@ export const fixtureSuites: E2ETestFixtureSuite[] = [
compareResponseBodies: true, compareResponseBodies: true,
fixtures: [ fixtures: [
{ {
path: '@dev/test-everything-openapi@390e70bf/pure', path: '@dev/test-everything-openapi/pure',
request: { request: {
method: 'POST', method: 'POST',
json: { json: {
@ -503,7 +533,7 @@ export const fixtureSuites: E2ETestFixtureSuite[] = [
}, },
{ {
// second request should hit the cache // second request should hit the cache
path: '@dev/test-everything-openapi@390e70bf/pure', path: '@dev/test-everything-openapi/pure',
request: { request: {
method: 'POST', method: 'POST',
json: { json: {

Wyświetl plik

@ -1,6 +1,7 @@
import type { import type {
AdminDeployment, AdminDeployment,
OpenAPIToolOperation OpenAPIToolOperation,
ToolConfig
} from '@agentic/platform-types' } from '@agentic/platform-types'
import { assert } from '@agentic/platform-core' import { assert } from '@agentic/platform-core'
@ -10,12 +11,14 @@ export async function createHttpRequestForOpenAPIOperation({
toolCallArgs, toolCallArgs,
operation, operation,
deployment, deployment,
request request,
toolConfig
}: { }: {
toolCallArgs: ToolCallArgs toolCallArgs: ToolCallArgs
operation: OpenAPIToolOperation operation: OpenAPIToolOperation
deployment: AdminDeployment deployment: AdminDeployment
request?: Request request?: Request
toolConfig?: ToolConfig
}): Promise<Request> { }): Promise<Request> {
assert(toolCallArgs, 500, 'Tool args are required') assert(toolCallArgs, 500, 'Tool args are required')
assert( assert(
@ -44,16 +47,20 @@ export async function createHttpRequestForOpenAPIOperation({
'Cookie parameters for OpenAPI operations are not yet supported. If you need cookie parameter support, please contact support@agentic.so.' 'Cookie parameters for OpenAPI operations are not yet supported. If you need cookie parameter support, please contact support@agentic.so.'
) )
// TODO: Make this more efficient... const extraArgs =
const extraArgs = Object.keys(toolCallArgs).filter((key) => { toolConfig?.additionalProperties === false
if (bodyParams.some(([paramKey]) => paramKey === key)) return false ? []
if (formDataParams.some(([paramKey]) => paramKey === key)) return false : // TODO: Make this more efficient...
if (headerParams.some(([paramKey]) => paramKey === key)) return false Object.keys(toolCallArgs).filter((key) => {
if (queryParams.some(([paramKey]) => paramKey === key)) return false if (bodyParams.some(([paramKey]) => paramKey === key)) return false
if (pathParams.some(([paramKey]) => paramKey === key)) return false if (formDataParams.some(([paramKey]) => paramKey === key))
if (cookieParams.some(([paramKey]) => paramKey === key)) return false return false
return true if (headerParams.some(([paramKey]) => paramKey === key)) return false
}) if (queryParams.some(([paramKey]) => paramKey === key)) return false
if (pathParams.some(([paramKey]) => paramKey === key)) return false
if (cookieParams.some(([paramKey]) => paramKey === key)) return false
return true
})
const extraArgsEntries = extraArgs const extraArgsEntries = extraArgs
.map((key) => [key, toolCallArgs[key]]) .map((key) => [key, toolCallArgs[key]])
.filter(([, value]) => value !== undefined) .filter(([, value]) => value !== undefined)

Wyświetl plik

@ -28,13 +28,17 @@ export async function getToolArgsFromRequest(
new URL(request.url).searchParams.entries() new URL(request.url).searchParams.entries()
) )
const toolConfig = deployment.toolConfigs.find(
(toolConfig) => toolConfig.name === tool.name
)
// Validate incoming request params against the tool's input schema. // Validate incoming request params against the tool's input schema.
const incomingRequestArgs = cfValidateJsonSchema<Record<string, any>>({ const incomingRequestArgs = cfValidateJsonSchema<Record<string, any>>({
schema: tool.inputSchema, schema: tool.inputSchema,
data: incomingRequestArgsRaw, data: incomingRequestArgsRaw,
errorPrefix: `Invalid request parameters for tool "${tool.name}"`, errorPrefix: `Invalid request parameters for tool "${tool.name}"`,
coerce: true, coerce: true,
strictAdditionalProperties: false strictAdditionalProperties: toolConfig?.additionalProperties === false
}) })
return incomingRequestArgs return incomingRequestArgs

Wyświetl plik

@ -176,7 +176,7 @@ export async function resolveOriginToolCall({
schema: tool.inputSchema, schema: tool.inputSchema,
data: args, data: args,
errorPrefix: `Invalid request parameters for tool "${tool.name}"`, errorPrefix: `Invalid request parameters for tool "${tool.name}"`,
strictAdditionalProperties: false strictAdditionalProperties: toolConfig?.additionalProperties === false
}) })
const originStartTimeMs = Date.now() const originStartTimeMs = Date.now()
@ -209,6 +209,8 @@ export async function resolveOriginToolCall({
}, },
waitUntil waitUntil
}) })
// Fetch the origin response without caching (useful for debugging)
// const originResponse = await fetch(originRequest) // const originResponse = await fetch(originRequest)
const cacheStatus = const cacheStatus =