two LoggedCall tables
This commit is contained in:
@@ -254,14 +254,53 @@ model WorldChampEntrant {
|
|||||||
model LoggedCall {
|
model LoggedCall {
|
||||||
id String @id @default(uuid()) @db.Uuid
|
id String @id @default(uuid()) @db.Uuid
|
||||||
|
|
||||||
|
startTime DateTime
|
||||||
|
|
||||||
|
// True if this call was served from the cache, false otherwise
|
||||||
|
cacheHit Boolean
|
||||||
|
|
||||||
|
// A LoggedCall is always associated with a LoggedCallModelResponse. If this
|
||||||
|
// is a cache miss, it's a new LoggedCallModelResponse we created for this.
|
||||||
|
// If it's a cache hit, it's the existing LoggedCallModelResponse we served.
|
||||||
|
modelResponseId String @db.Uuid
|
||||||
|
modelResponse LoggedCallModelResponse @relation(fields: [modelResponseId], references: [id], onDelete: Cascade)
|
||||||
|
|
||||||
|
// The response created by this LoggedCall. Will be null if this LoggedCall is a cache hit.
|
||||||
|
createdResponse LoggedCallModelResponse[] @relation(name: "ModelResponseCreatedBy")
|
||||||
|
|
||||||
|
organizationId String @db.Uuid
|
||||||
|
organization Organization? @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
||||||
|
|
||||||
|
tags LoggedCallTag[]
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
|
@@index([startTime])
|
||||||
|
}
|
||||||
|
|
||||||
|
model LoggedCallModelResponse {
|
||||||
|
id String @id @default(uuid()) @db.Uuid
|
||||||
|
|
||||||
|
reqPayload Json
|
||||||
|
|
||||||
|
// The HTTP status returned by the model provider
|
||||||
|
respStatus Int?
|
||||||
|
respPayload Json?
|
||||||
|
|
||||||
|
// Should be null if the request was successful, and some string if the request failed.
|
||||||
|
error String?
|
||||||
|
|
||||||
startTime DateTime
|
startTime DateTime
|
||||||
endTime DateTime
|
endTime DateTime
|
||||||
|
|
||||||
reqPayload Json
|
// Note: the function to calculate the cacheKey should include the project
|
||||||
respPayload Json?
|
// ID so we don't share cached responses between projects, which could be an
|
||||||
respStatus Int?
|
// attack vector. Also, we should only set the cacheKey on the model if the
|
||||||
error String?
|
// request was successful.
|
||||||
|
cacheKey String?
|
||||||
|
|
||||||
|
// Derived fields
|
||||||
durationMs Int?
|
durationMs Int?
|
||||||
inputTokens Int?
|
inputTokens Int?
|
||||||
outputTokens Int?
|
outputTokens Int?
|
||||||
@@ -269,19 +308,15 @@ model LoggedCall {
|
|||||||
completionId String?
|
completionId String?
|
||||||
totalCost Decimal? @db.Decimal(18, 12)
|
totalCost Decimal? @db.Decimal(18, 12)
|
||||||
|
|
||||||
cacheParentId String? @db.Uuid
|
// The LoggedCall that created this LoggedCallModelResponse
|
||||||
cacheParent LoggedCall? @relation(name: "CacheParentChild", fields: [cacheParentId], references: [id], onDelete: Cascade)
|
createdById String @unique @db.Uuid
|
||||||
|
createdBy LoggedCall @relation(name: "ModelResponseCreatedBy", fields: [createdById], references: [id], onDelete: Cascade)
|
||||||
|
|
||||||
organizationId String @db.Uuid
|
createdAt DateTime @default(now())
|
||||||
organization Organization? @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
updatedAt DateTime @updatedAt
|
||||||
|
loggedCalls LoggedCall[]
|
||||||
|
|
||||||
tags LoggedCallTag[]
|
@@index([cacheKey])
|
||||||
cacheChildren LoggedCall[] @relation(name: "CacheParentChild")
|
|
||||||
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @updatedAt
|
|
||||||
|
|
||||||
@@index([startTime])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
model LoggedCallTag {
|
model LoggedCallTag {
|
||||||
|
|||||||
63
app/src/server/scripts/test-queries.ts
Normal file
63
app/src/server/scripts/test-queries.ts
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import dayjs from "dayjs";
|
||||||
|
import { prisma } from "../db";
|
||||||
|
|
||||||
|
const projectId = "1234";
|
||||||
|
|
||||||
|
// Find all calls in the last 24 hours
|
||||||
|
const responses = await prisma.loggedCall.findMany({
|
||||||
|
where: {
|
||||||
|
organizationId: projectId,
|
||||||
|
startTime: {
|
||||||
|
gt: dayjs()
|
||||||
|
.subtract(24 * 3600)
|
||||||
|
.toDate(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
modelResponse: true,
|
||||||
|
},
|
||||||
|
orderBy: {
|
||||||
|
startTime: "desc",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Find all calls in the last 24 hours with promptId 'hello-world'
|
||||||
|
const helloWorld = await prisma.loggedCall.findMany({
|
||||||
|
where: {
|
||||||
|
organizationId: projectId,
|
||||||
|
startTime: {
|
||||||
|
gt: dayjs()
|
||||||
|
.subtract(24 * 3600)
|
||||||
|
.toDate(),
|
||||||
|
},
|
||||||
|
tags: {
|
||||||
|
some: {
|
||||||
|
name: "promptId",
|
||||||
|
value: "hello-world",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
modelResponse: true,
|
||||||
|
},
|
||||||
|
orderBy: {
|
||||||
|
startTime: "desc",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Total spent on OpenAI in the last month
|
||||||
|
const totalSpent = await prisma.loggedCallModelResponse.aggregate({
|
||||||
|
_sum: {
|
||||||
|
totalCost: true,
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
createdBy: {
|
||||||
|
organizationId: projectId,
|
||||||
|
},
|
||||||
|
startTime: {
|
||||||
|
gt: dayjs()
|
||||||
|
.subtract(30 * 24 * 3600)
|
||||||
|
.toDate(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user