pull/715/head
Travis Fischer 2025-06-11 10:09:42 +07:00
rodzic add1a43cd7
commit 492396423c
4 zmienionych plików z 67 dodań i 50 usunięć

Wyświetl plik

@ -59,23 +59,25 @@ app.all(async (ctx) => {
createAgenticClient({
env: ctx.env,
cache: caches.default,
waitUntil,
isCachingEnabled: isRequestPubliclyCacheable(ctx.req.raw)
isCachingEnabled: isRequestPubliclyCacheable(ctx.req.raw),
waitUntil
})
)
// TODO: Clean up the duplication between this block,
// `resolveMcpEdgeRequest`, and `resolveHttpEdgeRequest`.
const requestUrl = new URL(ctx.req.url)
const { pathname } = requestUrl
const requestedToolIdentifier = pathname.replace(/^\//, '').replace(/\/$/, '')
const { toolName } = parseToolIdentifier(requestedToolIdentifier)
// Handle MCP requests
if (toolName === 'mcp') {
ctx.set('isJsonRpcRequest', true)
const executionCtx = ctx.executionCtx as any
const mcpInfo = await resolveMcpEdgeRequest(ctx)
executionCtx.props = mcpInfo
// Handle MCP requests
return DurableMcpServer.serve(pathname, {
binding: 'DO_MCP_SERVER'
}).fetch(ctx.req.raw, ctx.env, executionCtx)
@ -86,7 +88,63 @@ app.all(async (ctx) => {
let originResponse: Response | undefined
let res: Response | undefined
function updateResponse(response: Response) {
try {
// Resolve the http edge request to a specific deployment, consumer, and
// tool call.
resolvedHttpEdgeRequest = await resolveHttpEdgeRequest(ctx)
// Invoke the origin tool call.
resolvedOriginToolCallResult = await resolveOriginToolCall({
...resolvedHttpEdgeRequest,
args: resolvedHttpEdgeRequest.toolCallArgs,
sessionId: ctx.get('sessionId')!,
ip: ctx.get('ip'),
env: ctx.env,
waitUntil
})
// Transform the origin tool call response into an http response.
if (resolvedOriginToolCallResult.originResponse) {
originResponse = resolvedOriginToolCallResult.originResponse
} else {
originResponse = await createHttpResponseFromMcpToolCallResponse(ctx, {
...resolvedHttpEdgeRequest,
toolCallResponse: resolvedOriginToolCallResult.toolCallResponse
})
}
assert(originResponse, 500, 'Origin response is required')
// Post-process the origin response.
res = updateResponse(originResponse, resolvedOriginToolCallResult)
return res
} catch (err: any) {
// Convert the error into an http response and post-process it.
res = errorHandler(err, ctx)
res = updateResponse(res, resolvedOriginToolCallResult)
return res
} finally {
// Record the tool call usage.
if (resolvedHttpEdgeRequest && res) {
recordToolCallUsage({
...resolvedHttpEdgeRequest,
requestMode: 'http',
httpResponse: res,
resolvedOriginToolCallResult,
sessionId: ctx.get('sessionId')!,
requestId: ctx.get('requestId')!,
ip: ctx.get('ip'),
env: ctx.env,
waitUntil
})
}
}
})
function updateResponse(
response: Response,
resolvedOriginToolCallResult?: ResolvedOriginToolCallResult
) {
const res = new Response(response.body, response)
if (resolvedOriginToolCallResult) {
@ -116,48 +174,4 @@ app.all(async (ctx) => {
res.headers.delete('reporting-endpoints')
return res
}
try {
resolvedHttpEdgeRequest = await resolveHttpEdgeRequest(ctx)
resolvedOriginToolCallResult = await resolveOriginToolCall({
...resolvedHttpEdgeRequest,
args: resolvedHttpEdgeRequest.toolCallArgs,
sessionId: ctx.get('sessionId')!,
ip: ctx.get('ip'),
env: ctx.env,
waitUntil
})
if (resolvedOriginToolCallResult.originResponse) {
originResponse = resolvedOriginToolCallResult.originResponse
} else {
originResponse = await createHttpResponseFromMcpToolCallResponse(ctx, {
...resolvedHttpEdgeRequest,
toolCallResponse: resolvedOriginToolCallResult.toolCallResponse
})
}
assert(originResponse, 500, 'Origin response is required')
res = updateResponse(originResponse)
return res
} catch (err: any) {
res = updateResponse(errorHandler(err, ctx))
return res
} finally {
if (resolvedHttpEdgeRequest && res) {
recordToolCallUsage({
...resolvedHttpEdgeRequest,
requestMode: 'http',
httpResponse: res,
resolvedOriginToolCallResult,
sessionId: ctx.get('sessionId')!,
requestId: ctx.get('requestId')!,
ip: ctx.get('ip'),
env: ctx.env,
waitUntil
})
}
}
})
}

Wyświetl plik

@ -19,9 +19,8 @@ export function createAgenticClient({
const client = new AgenticApiClient({
apiBaseUrl: env.AGENTIC_API_BASE_URL,
apiKey: env.AGENTIC_API_KEY,
ky: !isCachingEnabled
? defaultKy
: defaultKy.extend({
ky: isCachingEnabled
? defaultKy.extend({
hooks: {
// NOTE: The order of the `beforeRequest` hook matters, and it only
// works alongside the one in AgenticApiClient because that one's body
@ -39,10 +38,13 @@ export function createAgenticClient({
afterResponse: [
async (request, _options, response) => {
if (
isCacheControlPubliclyCacheable(
!isCacheControlPubliclyCacheable(
response.headers.get('cache-control')
)
) {
return
}
// Asynchronously update the cache with the response from
// Agentic's backend API.
waitUntil(
@ -52,10 +54,10 @@ export function createAgenticClient({
})
)
}
}
]
}
})
: defaultKy
})
return client

Wyświetl plik

@ -28,7 +28,7 @@ export default Sentry.withSentry(
parsedEnv = parseEnv(env)
} catch (err: any) {
// eslint-disable-next-line no-console
console.error('error api gateway invalid env:', err.message)
console.error('api gateway error invalid env:', err.message)
return new Response(
JSON.stringify({ error: 'Invalid api gateway environment' }),

Wyświetl plik

@ -54,6 +54,7 @@
## TODO Post-MVP
- first-party deployment hosting
- api gateway stress tests
- auth
- custom auth provider configs for projects/deployments
- stripe