kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
feat: WIP kittens
rodzic
b0d3dcf589
commit
4223db8a9a
|
@ -24,8 +24,8 @@ export function getTool({
|
||||||
|
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
|
|
||||||
assert(tool, 404, `Tool not found "${toolPath}"`)
|
assert(tool, 404, `Tool not found "${toolPath}"`)
|
||||||
|
|
||||||
if (deployment.originAdapter.type === 'openapi') {
|
if (deployment.originAdapter.type === 'openapi') {
|
||||||
const operation = deployment.originAdapter.toolToOperationMap[tool.name]
|
const operation = deployment.originAdapter.toolToOperationMap[tool.name]
|
||||||
assert(
|
assert(
|
||||||
|
|
|
@ -25,10 +25,10 @@ export async function resolveOriginRequest(
|
||||||
const { search, pathname } = requestUrl
|
const { search, pathname } = requestUrl
|
||||||
const method = req.method.toLowerCase()
|
const method = req.method.toLowerCase()
|
||||||
const requestPathParts = pathname.split('/')
|
const requestPathParts = pathname.split('/')
|
||||||
const requestPath =
|
const isMCPRequest = requestPathParts[0] === 'mcp'
|
||||||
requestPathParts[0] === 'mcp'
|
const requestPath = isMCPRequest
|
||||||
? requestPathParts.slice(1).join('/')
|
? requestPathParts.slice(1).join('/')
|
||||||
: pathname
|
: pathname
|
||||||
|
|
||||||
const { deployment, toolPath } = await getAdminDeployment(ctx, requestPath)
|
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?
|
// TODO: what do we want the API gateway's interface to be?
|
||||||
// - support both MCP and OpenAPI / raw?
|
// - support both MCP and OpenAPI / raw?
|
||||||
|
|
||||||
|
const { originAdapter } = deployment
|
||||||
let originRequest: Request | undefined
|
let originRequest: Request | undefined
|
||||||
if (
|
|
||||||
deployment.originAdapter.type === 'openapi' ||
|
if (originAdapter.type === 'openapi' || originAdapter.type === 'raw') {
|
||||||
deployment.originAdapter.type === 'raw'
|
|
||||||
) {
|
|
||||||
const originRequestUrl = `${deployment.originUrl}${toolPath}${search}`
|
const originRequestUrl = `${deployment.originUrl}${toolPath}${search}`
|
||||||
console.log('originRequestUrl', originRequestUrl)
|
console.log('originRequestUrl', originRequestUrl)
|
||||||
|
|
||||||
originRequest = new Request(originRequestUrl, req)
|
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 {
|
return {
|
||||||
|
|
|
@ -62,40 +62,27 @@ export default {
|
||||||
const resolvedOriginRequest = await resolveOriginRequest(ctx)
|
const resolvedOriginRequest = await resolveOriginRequest(ctx)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
originStartTime = Date.now()
|
||||||
|
|
||||||
switch (resolvedOriginRequest.deployment.originAdapter.type) {
|
switch (resolvedOriginRequest.deployment.originAdapter.type) {
|
||||||
case 'openapi':
|
case 'openapi':
|
||||||
break
|
return fetch(resolvedOriginRequest.originRequest!)
|
||||||
|
|
||||||
case 'raw':
|
case 'raw':
|
||||||
break
|
return fetch(resolvedOriginRequest.originRequest!)
|
||||||
|
|
||||||
case 'mcp':
|
case 'mcp':
|
||||||
break
|
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()
|
recordTimespans()
|
||||||
|
|
||||||
// Record the time it took for both the origin and gateway proxy to respond
|
// 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-response-time', `${originTimespan!}ms`)
|
||||||
res.headers.set('x-proxy-response-time', `${gatewayTimespan!}ms`)
|
res.headers.set('x-proxy-response-time', `${gatewayTimespan!}ms`)
|
||||||
|
|
||||||
// Upsert Vary header so browser will cache response correctly
|
// Reset server to agentic because Cloudflare likes to override things
|
||||||
// TODO: why is this necessary according to cloudflare? it's actually incorrect
|
res.headers.set('server', 'agentic')
|
||||||
// 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')
|
|
||||||
|
|
||||||
// const id: DurableObjectId = env.DO_RATE_LIMITER.idFromName('foo')
|
// const id: DurableObjectId = env.DO_RATE_LIMITER.idFromName('foo')
|
||||||
// const stub = env.DO_RATE_LIMITER.get(id)
|
// const stub = env.DO_RATE_LIMITER.get(id)
|
||||||
|
|
|
@ -45,11 +45,11 @@
|
||||||
- REST: `POST gateway.agentic.so/deploymentIdentifier/toolName`
|
- REST: `POST gateway.agentic.so/deploymentIdentifier/toolName`
|
||||||
- => MCP: `MCPClient.callTool` with JSON body parameters
|
- => MCP: `MCPClient.callTool` with JSON body parameters
|
||||||
- => OpenAPI: `GET/POST/ETC originUrl/toolName` operation with transformed JSON body params
|
- => 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
|
- => MCP: `MCPClient.callTool` just proxying tool call
|
||||||
- => OpenAPI: `GET/POST/ETC originUrl/toolName` operation with transformed tool params
|
- => OpenAPI: `GET/POST/ETC originUrl/toolName` operation with transformed tool params
|
||||||
- add support for caching
|
- add support for caching
|
||||||
- add support for custom headers on response
|
- add support for custom headers on responses
|
||||||
- signed requests
|
- signed requests
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
Ładowanie…
Reference in New Issue