pull/715/head
Travis Fischer 2025-06-05 23:20:01 +07:00
rodzic ce86808d35
commit ee658f8d81
3 zmienionych plików z 124 dodań i 153 usunięć

Wyświetl plik

@ -0,0 +1,123 @@
import { assert } from '@agentic/platform-core'
import {
cors,
errorHandler,
init,
responseTime,
sentry
} from '@agentic/platform-hono'
import { Hono } from 'hono'
import type { GatewayHonoEnv } from './lib/types'
import { createAgenticClient } from './lib/agentic-client'
import { fetchCache } from './lib/fetch-cache'
import { getRequestCacheKey } from './lib/get-request-cache-key'
import { resolveOriginRequest } from './lib/resolve-origin-request'
export const app = new Hono<GatewayHonoEnv>()
app.onError(errorHandler)
app.use(sentry())
// TODO: Compression is causing a weird bug on dev even for simple responses.
// I think it's because wrangler is changing the response to be streamed
// with `transfer-encoding: chunked`, which is not compatible with
// `hono/compress`.
// app.use(compress())
app.use(
cors({
origin: '*',
allowHeaders: ['Content-Type', 'Authorization'],
allowMethods: ['POST', 'GET', 'OPTIONS'],
exposeHeaders: ['Content-Length'],
maxAge: 600,
credentials: true
})
)
app.use(init)
// Wrangler does this for us. TODO: Does this happen on prod?
// app.use(accessLogger)
app.use(responseTime)
app.all(async (ctx) => {
ctx.set('cache', caches.default)
ctx.set('client', createAgenticClient(ctx))
const resolvedOriginRequest = await resolveOriginRequest(ctx)
const originStartTime = Date.now()
let originResponse: Response | undefined
switch (resolvedOriginRequest.deployment.originAdapter.type) {
case 'openapi':
case 'raw': {
assert(
resolvedOriginRequest.originRequest,
500,
'Origin request is required'
)
const cacheKey = await getRequestCacheKey(
ctx,
resolvedOriginRequest.originRequest
)
originResponse = await fetchCache(ctx, {
cacheKey,
fetchResponse: () => fetch(resolvedOriginRequest.originRequest!)
})
break
}
case 'mcp':
throw new Error('MCP not yet supported')
}
assert(originResponse, 500, 'Origin response is required')
const res = new Response(originResponse.body, originResponse)
// Record the time it took for both the origin and gateway to respond
const now = Date.now()
const originTimespan = now - originStartTime
res.headers.set('x-origin-response-time', `${originTimespan}ms`)
// Reset server to agentic because Cloudflare likes to override things
res.headers.set('server', 'agentic')
res.headers.delete('x-powered-by')
res.headers.delete('via')
res.headers.delete('nel')
res.headers.delete('report-to')
res.headers.delete('server-timing')
res.headers.delete('reporting-endpoints')
// const id: DurableObjectId = env.DO_RATE_LIMITER.idFromName('foo')
// const stub = env.DO_RATE_LIMITER.get(id)
// const greeting = await stub.sayHello('world')
// return new Response(greeting)
return res
// TODO: move this `finally` blockto a middleware handler
// const now = Date.now()
// Report usage.
// Note that we are not awaiting the results of this on purpose so we can
// return the response to the client immediately.
// TODO
// ctx.waitUntil(
// reportUsage(ctx, {
// ...call,
// cache: res!.headers.get('cf-cache-status'),
// status: res!.status,
// timestamp: Math.ceil(now / 1000),
// computeTime: originTimespan!,
// gatewayTime: gatewayTimespan!,
// // TODO: record correct bandwidth of request + response content-length
// bandwidth: 0
// })
// )
})

Wyświetl plik

@ -1,30 +0,0 @@
const allowedMethods = 'GET, HEAD, POST, PUT, DELETE, TRACE, PATCH, OPTIONS'
// TODO: Remove; currently unused in favor of hono/cors
export function handleOptions(req: Request) {
// Make sure the necessary headers are present for this to be a valid pre-
// flight request
if (
req.headers.get('Origin') &&
req.headers.get('Access-Control-req-Method') &&
req.headers.get('Access-Control-Request-Headers')
) {
// Handle CORS pre-flight request.
return new Response(null, {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': allowedMethods,
'Access-Control-Allow-Headers':
req.headers.get('Access-Control-Request-Headers') ?? '*'
}
})
} else {
// Handle standard OPTIONS request.
// If you want to allow other HTTP Methods, you can do that here.
return new Response(null, {
headers: {
Allow: allowedMethods
}
})
}
}

Wyświetl plik

@ -1,131 +1,9 @@
import { assert } from '@agentic/platform-core'
import {
cors,
errorHandler,
init,
responseTime,
sentry
} from '@agentic/platform-hono'
import { Hono } from 'hono'
import type { GatewayHonoEnv } from './lib/types'
import { createAgenticClient } from './lib/agentic-client'
import { app } from './app'
import { type Env, parseEnv } from './lib/env'
import { fetchCache } from './lib/fetch-cache'
import { getRequestCacheKey } from './lib/get-request-cache-key'
import { resolveOriginRequest } from './lib/resolve-origin-request'
// Export Durable Objects for cloudflare
export { DurableObjectRateLimiter } from './durable-object'
export const app = new Hono<GatewayHonoEnv>()
app.onError(errorHandler)
app.use(sentry())
// TODO: Compression is causing a weird bug on dev even for simple responses.
// I think it's because wrangler is changing the response to be streamed
// with `transfer-encoding: chunked`, which is not compatible with
// `hono/compress`.
// app.use(compress())
app.use(
cors({
origin: '*',
allowHeaders: ['Content-Type', 'Authorization'],
allowMethods: ['POST', 'GET', 'OPTIONS'],
exposeHeaders: ['Content-Length'],
maxAge: 600,
credentials: true
})
)
app.use(init)
// Wrangler does this for us. TODO: Does this happen on prod?
// app.use(accessLogger)
app.use(responseTime)
app.all(async (ctx) => {
ctx.set('cache', caches.default)
ctx.set('client', createAgenticClient(ctx))
const resolvedOriginRequest = await resolveOriginRequest(ctx)
const originStartTime = Date.now()
let originResponse: Response | undefined
switch (resolvedOriginRequest.deployment.originAdapter.type) {
case 'openapi':
case 'raw': {
assert(
resolvedOriginRequest.originRequest,
500,
'Origin request is required'
)
const cacheKey = await getRequestCacheKey(
ctx,
resolvedOriginRequest.originRequest
)
originResponse = await fetchCache(ctx, {
cacheKey,
fetchResponse: () => fetch(resolvedOriginRequest.originRequest!)
})
break
}
case 'mcp':
throw new Error('MCP not yet supported')
}
assert(originResponse, 500, 'Origin response is required')
const res = new Response(originResponse.body, originResponse)
// Record the time it took for both the origin and gateway to respond
const now = Date.now()
const originTimespan = now - originStartTime
res.headers.set('x-origin-response-time', `${originTimespan}ms`)
// Reset server to agentic because Cloudflare likes to override things
res.headers.set('server', 'agentic')
res.headers.delete('x-powered-by')
res.headers.delete('via')
res.headers.delete('nel')
res.headers.delete('report-to')
res.headers.delete('server-timing')
res.headers.delete('reporting-endpoints')
// const id: DurableObjectId = env.DO_RATE_LIMITER.idFromName('foo')
// const stub = env.DO_RATE_LIMITER.get(id)
// const greeting = await stub.sayHello('world')
// return new Response(greeting)
return res
// TODO: move this `finally` blockto a middleware handler
// const now = Date.now()
// Report usage.
// Note that we are not awaiting the results of this on purpose so we can
// return the response to the client immediately.
// TODO
// ctx.waitUntil(
// reportUsage(ctx, {
// ...call,
// cache: res!.headers.get('cf-cache-status'),
// status: res!.status,
// timestamp: Math.ceil(now / 1000),
// computeTime: originTimespan!,
// gatewayTime: gatewayTimespan!,
// // TODO: record correct bandwidth of request + response content-length
// bandwidth: 0
// })
// )
})
export default {
async fetch(
request: Request,