feat: tiny kitty bean toes

pull/715/head
Travis Fischer 2025-06-01 02:08:54 +07:00
rodzic 1a4e697f0f
commit bb65d09ab0
10 zmienionych plików z 38 dodań i 28 usunięć

Wyświetl plik

@ -53,7 +53,7 @@ export function registerV1ConsumersRefreshConsumerToken(
;[consumer] = await db ;[consumer] = await db
.update(schema.consumers) .update(schema.consumers)
.set({ .set({
token: createConsumerToken() token: await createConsumerToken()
}) })
.where(eq(schema.consumers.id, consumer.id)) .where(eq(schema.consumers.id, consumer.id))
.returning() .returning()

Wyświetl plik

@ -80,7 +80,7 @@ export function registerV1DeploymentsCreateDeployment(
const projectId = project.id const projectId = project.id
// TODO: investigate better short hash generation // TODO: investigate better short hash generation
const hash = sha256().slice(0, 8) const hash = (await sha256()).slice(0, 8)
const deploymentIdentifier = `${project.identifier}@${hash}` const deploymentIdentifier = `${project.identifier}@${hash}`
assert( assert(
validators.deploymentIdentifier(deploymentIdentifier), validators.deploymentIdentifier(deploymentIdentifier),
@ -111,6 +111,8 @@ export function registerV1DeploymentsCreateDeployment(
// - origin API base URL // - origin API base URL
// - origin adapter OpenAPI or MCP specs // - origin adapter OpenAPI or MCP specs
// - tool definitions // - tool definitions
// TODO: fix types
const agenticProjectConfig = await resolveAgenticProjectConfig(body, { const agenticProjectConfig = await resolveAgenticProjectConfig(body, {
label: `deployment "${deploymentIdentifier}"`, label: `deployment "${deploymentIdentifier}"`,
logger logger

Wyświetl plik

@ -61,7 +61,7 @@ export function registerV1ProjectsCreateProject(
identifier, identifier,
teamId: teamMember?.teamId, teamId: teamMember?.teamId,
userId: user.id, userId: user.id,
_secret: sha256() _secret: await sha256()
}) })
.returning() .returning()
assert(project, 500, `Failed to create project "${body.name}"`) assert(project, 500, `Failed to create project "${body.name}"`)

Wyświetl plik

@ -148,7 +148,7 @@ export async function upsertConsumer(
userId, userId,
projectId, projectId,
deploymentId, deploymentId,
token: createConsumerToken(), token: await createConsumerToken(),
_stripeCustomerId: stripeCustomer.id _stripeCustomerId: stripeCustomer.id
}) })
} }

Wyświetl plik

@ -1,5 +1,7 @@
import { sha256 } from '@agentic/platform-core' import { sha256 } from '@agentic/platform-core'
export function createConsumerToken(): string { export async function createConsumerToken(): Promise<string> {
return sha256().slice(0, 24) const hash = await sha256()
return hash.slice(0, 24)
} }

Wyświetl plik

@ -29,7 +29,7 @@ export async function getUniqueNamespace(
namespace?: string, namespace?: string,
{ label = 'Namespace' }: { label?: string } = {} { label = 'Namespace' }: { label?: string } = {}
) { ) {
namespace ??= `${label}_${sha256().slice(0, 24)}` namespace ??= `${label}_${(await sha256()).slice(0, 24)}`
namespace = namespace namespace = namespace
.replaceAll(/[^a-zA-Z0-9_-]/g, '') .replaceAll(/[^a-zA-Z0-9_-]/g, '')
.toLowerCase() .toLowerCase()
@ -48,7 +48,7 @@ export async function getUniqueNamespace(
throw err throw err
} }
const suffix = sha256().slice(0, 8) const suffix = (await sha256()).slice(0, 8)
currentNamespace = `${namespace.slice(0, schema.namespaceMaxLength - 1 - suffix.length)}${suffix}` currentNamespace = `${namespace.slice(0, schema.namespaceMaxLength - 1 - suffix.length)}${suffix}`
} }
} while (true) } while (true)

Wyświetl plik

@ -36,6 +36,7 @@
"@hono/zod-validator": "catalog:", "@hono/zod-validator": "catalog:",
"@modelcontextprotocol/sdk": "catalog:", "@modelcontextprotocol/sdk": "catalog:",
"eventid": "catalog:", "eventid": "catalog:",
"fast-content-type-parse": "^3.0.0",
"hono": "catalog:", "hono": "catalog:",
"type-fest": "catalog:" "type-fest": "catalog:"
}, },

Wyświetl plik

@ -8,7 +8,7 @@ export async function fetchCache(
cacheKey, cacheKey,
fetchResponse fetchResponse
}: { }: {
cacheKey?: string cacheKey?: Request
fetchResponse: () => Promise<Response> fetchResponse: () => Promise<Response>
} }
): Promise<Response> { ): Promise<Response> {

Wyświetl plik

@ -1,10 +1,11 @@
import contentType from 'content-type' import { hashObject, sha256 } from '@agentic/platform-core'
import stableJsonStringify from 'fast-json-stable-stringify' import contentType from 'fast-content-type-parse'
import { normalizeUrl } from './normalize-url' import { normalizeUrl } from './normalize-url'
import * as sha256 from './sha256'
export async function getFaasRequestCacheKey(request) { export async function getRequestCacheKey(
request: Request
): Promise<Request | null> {
try { try {
const pragma = request.headers.get('pragma') const pragma = request.headers.get('pragma')
if (pragma === 'no-cache') { if (pragma === 'no-cache') {
@ -23,34 +24,35 @@ export async function getFaasRequestCacheKey(request) {
// useful for debugging since getting all the headers is awkward // useful for debugging since getting all the headers is awkward
// console.log(Object.fromEntries(request.headers.entries())) // console.log(Object.fromEntries(request.headers.entries()))
const contentLength = parseInt(request.headers.get('content-length')) const contentLength = Number.parseInt(
request.headers.get('content-length') ?? '0'
)
// TODO: what is a reasonable upper bound for hashing the POST body size? // TODO: what is a reasonable upper bound for hashing the POST body size?
if (contentLength && contentLength < 10000) { if (contentLength && contentLength < 10_000) {
const ct = contentType.parse( const { type } = contentType.safeParse(
request.headers.get('content-type') || 'application/octet-stream' request.headers.get('content-type') || 'application/octet-stream'
) )
const type = ct && ct.type
let hash let hash
// TODO: gracefully handle content-encoding compression // TODO: gracefully handle content-encoding compression
// TODO: more robust content-type detection // TODO: more robust content-type detection
if (type && type.indexOf('json') >= 0) { if (type?.includes('json')) {
const bodyJson = await request.clone().json() const bodyJson: any = await request.clone().json()
const bodyString = stableJsonStringify(bodyJson) hash = hashObject(bodyJson)
hash = await sha256.fromString(bodyString) } else if (type?.includes('text/')) {
} else if (type && type.indexOf('text/') >= 0) {
const bodyString = await request.clone().text() const bodyString = await request.clone().text()
hash = await sha256.fromString(bodyString) hash = await sha256(bodyString)
} else { } else {
const bodyBuffer = await request.clone().arrayBuffer() // TODO
hash = await sha256.fromBuffer(bodyBuffer) // const bodyBuffer = await request.clone().arrayBuffer()
// hash = await sha256.fromBuffer(bodyBuffer)
return null
} }
const cacheUrl = new URL(request.url) const cacheUrl = new URL(request.url)
cacheUrl.pathname = cacheUrl.pathname + '/' + hash cacheUrl.searchParams.set('x-agentic-cache-key', hash)
const normalizedUrl = normalizeUrl(cacheUrl.toString()) const normalizedUrl = normalizeUrl(cacheUrl.toString())
const newReq = normalizeRequestHeaders( const newReq = normalizeRequestHeaders(
@ -86,7 +88,7 @@ export async function getFaasRequestCacheKey(request) {
const requestHeaderWhitelist = new Set(['cache-control']) const requestHeaderWhitelist = new Set(['cache-control'])
function normalizeRequestHeaders(request) { function normalizeRequestHeaders(request: Request) {
const headers = Object.fromEntries(request.headers.entries()) const headers = Object.fromEntries(request.headers.entries())
const keys = Object.keys(headers) const keys = Object.keys(headers)

Wyświetl plik

@ -369,6 +369,9 @@ importers:
eventid: eventid:
specifier: 'catalog:' specifier: 'catalog:'
version: 2.0.1 version: 2.0.1
fast-content-type-parse:
specifier: ^3.0.0
version: 3.0.0
hono: hono:
specifier: 'catalog:' specifier: 'catalog:'
version: 4.7.10 version: 4.7.10