feat: WIP kittens

pull/715/head
Travis Fischer 2025-05-31 23:28:09 +07:00
rodzic b0d3dcf589
commit 4223db8a9a
4 zmienionych plików z 29 dodań i 35 usunięć

Wyświetl plik

@ -24,8 +24,8 @@ export function getTool({
return false
})
assert(tool, 404, `Tool not found "${toolPath}"`)
if (deployment.originAdapter.type === 'openapi') {
const operation = deployment.originAdapter.toolToOperationMap[tool.name]
assert(

Wyświetl plik

@ -25,10 +25,10 @@ export async function resolveOriginRequest(
const { search, pathname } = requestUrl
const method = req.method.toLowerCase()
const requestPathParts = pathname.split('/')
const requestPath =
requestPathParts[0] === 'mcp'
? requestPathParts.slice(1).join('/')
: pathname
const isMCPRequest = requestPathParts[0] === 'mcp'
const requestPath = isMCPRequest
? requestPathParts.slice(1).join('/')
: pathname
const { deployment, toolPath } = await getAdminDeployment(ctx, requestPath)
@ -171,23 +171,30 @@ export async function resolveOriginRequest(
})
}
// TODO: Everything from here on depends on the origin adapter type.
// For MCP, we need(?) to use an McpClient and SSEClientTransport?
// For OpenAPI and raw, we need to make an origin HTTP request.
// 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 (
deployment.originAdapter.type === 'openapi' ||
deployment.originAdapter.type === 'raw'
) {
if (originAdapter.type === 'openapi' || originAdapter.type === 'raw') {
const originRequestUrl = `${deployment.originUrl}${toolPath}${search}`
console.log('originRequestUrl', originRequestUrl)
originRequest = new Request(originRequestUrl, req)
updateOriginRequest(originRequest, { consumer, deployment, ip })
// 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
} else {
originRequest = new Request(originRequestUrl, req)
}
updateOriginRequest(originRequest, { consumer, deployment })
}
return {

Wyświetl plik

@ -62,40 +62,27 @@ export default {
const resolvedOriginRequest = await resolveOriginRequest(ctx)
try {
originStartTime = Date.now()
switch (resolvedOriginRequest.deployment.originAdapter.type) {
case 'openapi':
break
return fetch(resolvedOriginRequest.originRequest!)
case 'raw':
break
return fetch(resolvedOriginRequest.originRequest!)
case 'mcp':
break
}
const originReqCacheKey = await getOriginRequestCacheKey(originReq)
originStartTime = Date.now()
const originRes = await fetchCache({
event,
cacheKey: originReqCacheKey,
fetch: () => fetchOriginRequest(event, { originReq, call })
})
res = new Response(originRes.body, originRes)
recordTimespans()
// Record the time it took for both the origin and gateway proxy to respond
res.headers.set('x-response-time', `${originTimespan!}ms`)
res.headers.set('x-proxy-response-time', `${gatewayTimespan!}ms`)
// Upsert Vary header so browser will cache response correctly
// TODO: why is this necessary according to cloudflare? it's actually incorrect
// in that the responses explicitly do not vary by request origin...
// res.headers.append('vary', 'Origin')
// Reset server to saasify because Cloudflare likes to override things
res.headers.set('server', 'saasify')
// Reset server to agentic because Cloudflare likes to override things
res.headers.set('server', 'agentic')
// const id: DurableObjectId = env.DO_RATE_LIMITER.idFromName('foo')
// const stub = env.DO_RATE_LIMITER.get(id)

Wyświetl plik

@ -45,11 +45,11 @@
- 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
- add support for caching
- add support for custom headers on response
- add support for custom headers on responses
- signed requests
## License