feat: WIP kittens

pull/715/head
Travis Fischer 2025-06-01 01:12:20 +07:00
rodzic 4223db8a9a
commit 2e458b226f
2 zmienionych plików z 92 dodań i 13 usunięć

Wyświetl plik

@ -171,29 +171,108 @@ export async function resolveOriginRequest(
})
}
// TODO: what do we want the API gateway's interface to be?
// - support both MCP and OpenAPI / raw?
const { originAdapter } = deployment
let originRequest: Request | undefined
if (originAdapter.type === 'openapi' || originAdapter.type === 'raw') {
const originRequestUrl = `${deployment.originUrl}${toolPath}${search}`
console.log('originRequestUrl', originRequestUrl)
originRequest = new Request(originRequestUrl, req)
// TODO: For OpenAPI, we need to convert from POST to the correct operation?
// Or, do we only support a single public MCP interface?
if (originAdapter.type === 'openapi') {
const operation = originAdapter.toolToOperationMap[tool.name]
assert(operation, 404, `Tool "${tool.name}" not found in OpenAPI spec`)
// req.method = operation.method
const tempInitialRequest = ctx.req.clone()
const tempInitialRequestBody: any = await tempInitialRequest.json()
const params = Object.entries(operation.parameterSources)
const bodyParams = params.filter(([_key, source]) => source === 'body')
const formDataParams = params.filter(
([_key, source]) => source === 'formData'
)
const headerParams = params.filter(
([_key, source]) => source === 'header'
)
const pathParams = params.filter(([_key, source]) => source === 'path')
const queryParams = params.filter(([_key, source]) => source === 'query')
const cookieParams = params.filter(
([_key, source]) => source === 'cookie'
)
const headers: Record<string, string> = {}
if (headerParams.length > 0) {
for (const [key] of headerParams) {
headers[key] = tempInitialRequest.headers.get(key) as string
}
}
let body: string | undefined
if (bodyParams.length > 0) {
body = JSON.stringify(
Object.fromEntries(
bodyParams.map(([key]) => [key, tempInitialRequestBody[key] as any])
)
)
headers['content-type'] ??= 'application/json'
} else if (formDataParams.length > 0) {
body = JSON.stringify(
Object.fromEntries(
formDataParams.map(([key]) => [
key,
tempInitialRequestBody[key] as any
])
)
)
headers['content-type'] ??= 'application/x-www-form-urlencoded'
}
let path = operation.path
if (pathParams.length > 0) {
for (const [key] of pathParams) {
const value: string = tempInitialRequestBody[key]
assert(value, 400, `Missing required parameter "${key}"`)
const pathParamPlaceholder = `{${key}}`
assert(
path.includes(pathParamPlaceholder),
500,
`Misconfigured OpenAPI deployment "${deployment.id}": invalid path "${operation.path}" missing required path parameter "${key}"`
)
path = path.replaceAll(pathParamPlaceholder, value)
}
}
assert(
!/\{\w+\}/.test(path),
500,
`Misconfigured OpenAPI deployment "${deployment.id}": invalid path "${operation.path}"`
)
const query = new URLSearchParams()
for (const [key] of queryParams) {
query.set(key, tempInitialRequestBody[key] as string)
}
for (const [key] of cookieParams) {
headers[key] = tempInitialRequestBody[key] as string
}
const queryString = query.toString()
const originRequestUrl = `${deployment.originUrl}${path}${
queryString ? `?${queryString}` : ''
}`
originRequest = new Request(originRequestUrl, {
method: operation.method,
body,
headers
})
} else {
const originRequestUrl = `${deployment.originUrl}${toolPath}${search}`
originRequest = new Request(originRequestUrl, req)
}
console.log('originRequestUrl', originRequest.url)
updateOriginRequest(originRequest, { consumer, deployment })
}

Wyświetl plik

@ -40,14 +40,14 @@
- share hono middleware and utils across apps/api and apps/gateway
- or combine these together? ehhhh
- MCP server vs REST gateway on public and internal sides
- RAW: `METHOD gateway.agentic.so/deploymentIdentifier/<pathname>`
- => Raw HTTP: `METHOD originUrl/<pathname>` simple HTTP proxy request
- REST: `POST gateway.agentic.so/deploymentIdentifier/toolName`
- **REST**: `POST gateway.agentic.so/deploymentIdentifier/toolName`
- => MCP: `MCPClient.callTool` with JSON body parameters
- => OpenAPI: `GET/POST/ETC originUrl/toolName` operation with transformed JSON body params
- MCP: `mcp.agentic.so/deploymentIdentifier/sse` MCP server?
- **MCP**: `mcp.agentic.so/deploymentIdentifier/sse` MCP server?
- => MCP: `MCPClient.callTool` just proxying tool call
- => OpenAPI: `GET/POST/ETC originUrl/toolName` operation with transformed tool params
- RAW: `METHOD gateway.agentic.so/deploymentIdentifier/<pathname>`
- => Raw HTTP: `METHOD originUrl/<pathname>` simple HTTP proxy request
- add support for caching
- add support for custom headers on responses
- signed requests