Send api token properly

This commit is contained in:
David Corbitt
2023-08-07 21:04:38 -07:00
parent 0f9a83cf45
commit 8fed9730da
5 changed files with 46 additions and 33 deletions

View File

@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "LoggedCall" ALTER COLUMN "modelResponseId" DROP NOT NULL;

View File

@@ -265,11 +265,11 @@ model LoggedCall {
// A LoggedCall is always associated with a LoggedCallModelResponse. If this // A LoggedCall is always associated with a LoggedCallModelResponse. If this
// is a cache miss, we create a new LoggedCallModelResponse. // is a cache miss, we create a new LoggedCallModelResponse.
// If it's a cache hit, it's a pre-existing LoggedCallModelResponse. // If it's a cache hit, it's a pre-existing LoggedCallModelResponse.
modelResponseId String @db.Uuid modelResponseId String? @db.Uuid
modelResponse LoggedCallModelResponse @relation(fields: [modelResponseId], references: [id], onDelete: Cascade) 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. // The responses created by this LoggedCall. Will be empty if this LoggedCall was a cache hit.
createdResponse LoggedCallModelResponse[] @relation(name: "ModelResponseOriginalCall") createdResponses LoggedCallModelResponse[] @relation(name: "ModelResponseOriginalCall")
organizationId String @db.Uuid organizationId String @db.Uuid
organization Organization? @relation(fields: [organizationId], references: [id], onDelete: Cascade) organization Organization? @relation(fields: [organizationId], references: [id], onDelete: Cascade)

View File

@@ -2,6 +2,7 @@ import { type Prisma } from "@prisma/client";
import { type JsonValue } from "type-fest"; import { type JsonValue } from "type-fest";
import { z } from "zod"; import { z } from "zod";
import { v4 as uuidv4 } from "uuid"; import { v4 as uuidv4 } from "uuid";
import { TRPCError } from "@trpc/server";
import { createTRPCRouter, publicProcedure } from "~/server/api/trpc"; import { createTRPCRouter, publicProcedure } from "~/server/api/trpc";
import { prisma } from "~/server/db"; import { prisma } from "~/server/db";
@@ -56,13 +57,13 @@ export const externalApiRouter = createTRPCRouter({
.mutation(async ({ input, ctx }) => { .mutation(async ({ input, ctx }) => {
const apiKey = ctx.apiKey; const apiKey = ctx.apiKey;
if (!apiKey) { if (!apiKey) {
throw new Error("Missing API key"); throw new TRPCError({ code: "UNAUTHORIZED" });
} }
const key = await prisma.apiKey.findUnique({ const key = await prisma.apiKey.findUnique({
where: { apiKey }, where: { apiKey },
}); });
if (!key) { if (!key) {
throw new Error("Invalid API key"); throw new TRPCError({ code: "UNAUTHORIZED" });
} }
const reqPayload = await reqValidator.spa(input.reqPayload); const reqPayload = await reqValidator.spa(input.reqPayload);
const cacheKey = hashRequest(key.organizationId, reqPayload as JsonValue); const cacheKey = hashRequest(key.organizationId, reqPayload as JsonValue);
@@ -76,19 +77,19 @@ export const externalApiRouter = createTRPCRouter({
}, },
orderBy: { orderBy: {
startTime: "desc", startTime: "desc",
} },
}); });
if (!existingResponse) return { respPayload: null }; if (!existingResponse) return { respPayload: null };
await prisma.loggedCall.create({ await prisma.loggedCall.create({
data: { data: {
organizationId: key.organizationId, organizationId: key.organizationId,
startTime: new Date(input.startTime), startTime: new Date(input.startTime),
cacheHit: true, cacheHit: true,
modelResponseId: existingResponse.id, modelResponseId: existingResponse.id,
} },
}) });
return { return {
respPayload: existingResponse.respPayload, respPayload: existingResponse.respPayload,
@@ -123,13 +124,13 @@ export const externalApiRouter = createTRPCRouter({
.mutation(async ({ input, ctx }) => { .mutation(async ({ input, ctx }) => {
const apiKey = ctx.apiKey; const apiKey = ctx.apiKey;
if (!apiKey) { if (!apiKey) {
throw new Error("Missing API key"); throw new TRPCError({ code: "UNAUTHORIZED" });
} }
const key = await prisma.apiKey.findUnique({ const key = await prisma.apiKey.findUnique({
where: { apiKey }, where: { apiKey },
}); });
if (!key) { if (!key) {
throw new Error("Invalid API key"); throw new TRPCError({ code: "UNAUTHORIZED" });
} }
const reqPayload = await reqValidator.spa(input.reqPayload); const reqPayload = await reqValidator.spa(input.reqPayload);
const respPayload = await respValidator.spa(input.respPayload); const respPayload = await respValidator.spa(input.respPayload);
@@ -148,7 +149,6 @@ export const externalApiRouter = createTRPCRouter({
organizationId: key.organizationId, organizationId: key.organizationId,
startTime: new Date(input.startTime), startTime: new Date(input.startTime),
cacheHit: false, cacheHit: false,
modelResponseId: newModelResponseId,
}, },
}), }),
prisma.loggedCallModelResponse.create({ prisma.loggedCallModelResponse.create({
@@ -167,11 +167,19 @@ export const externalApiRouter = createTRPCRouter({
cacheKey: requestHash, cacheKey: requestHash,
inputTokens: usage ? usage.prompt_tokens : undefined, inputTokens: usage ? usage.prompt_tokens : undefined,
outputTokens: usage ? usage.completion_tokens : undefined, outputTokens: usage ? usage.completion_tokens : undefined,
model: respPayload.data.model,
} }
: null), : null),
}, },
}), }),
// Avoid foreign key constraint error by updating the logged call after the model response is created
prisma.loggedCall.update({
where: {
id: newLoggedCallId,
},
data: {
modelResponseId: newModelResponseId,
},
}),
]); ]);
if (input.tags) { if (input.tags) {

View File

@@ -64,9 +64,7 @@ export const createTRPCContext = async (opts: CreateNextContextOptions) => {
// Get the session from the server using the getServerSession wrapper function // Get the session from the server using the getServerSession wrapper function
const session = await getServerAuthSession({ req, res }); const session = await getServerAuthSession({ req, res });
const apiKey = req.headers["X-Openpipe-Api-Key"] as string | null; const apiKey = req.headers["x-openpipe-api-key"] as string | null;
console.log('api key is', apiKey)
return createInnerTRPCContext({ return createInnerTRPCContext({
session, session,

View File

@@ -1,11 +1,7 @@
import * as openai from "openai-beta"; import * as openai from "openai-beta";
import { import { readEnv, type RequestOptions } from "openai-beta/core";
readEnv, import { CompletionCreateParams } from "openai-beta/resources/chat/completions";
type RequestOptions, import axios from "axios";
} from "openai-beta/core";
import {
CompletionCreateParams,
} from "openai-beta/resources/chat/completions";
export * as openai from "openai-beta"; export * as openai from "openai-beta";
import * as openPipeClient from "../codegen"; import * as openPipeClient from "../codegen";
@@ -27,10 +23,20 @@ export class OpenAI extends openai.OpenAI {
super({ ...opts }); super({ ...opts });
if (openPipeApiKey) { if (openPipeApiKey) {
this.openPipeApi = new openPipeClient.DefaultApi(new openPipeClient.Configuration({ const axiosInstance = axios.create({
apiKey: openPipeApiKey, baseURL: openPipeBaseUrl,
basePath: openPipeBaseUrl, headers: {
})); 'x-openpipe-api-key': openPipeApiKey,
},
});
this.openPipeApi = new openPipeClient.DefaultApi(
new openPipeClient.Configuration({
apiKey: openPipeApiKey,
basePath: openPipeBaseUrl,
}),
undefined,
axiosInstance
);
} }
// Override the chat property // Override the chat property
@@ -87,8 +93,7 @@ class ExtendedCompletions extends openai.OpenAI.Chat.Completions {
params as CompletionCreateParams.CreateChatCompletionRequestNonStreaming, params as CompletionCreateParams.CreateChatCompletionRequestNonStreaming,
options options
); );
console.log('result is this', result) await this.openaiInstance.openPipeApi?.externalApiReport({
this.openaiInstance.openPipeApi?.externalApiReport({
startTime, startTime,
endTime: Date.now(), endTime: Date.now(),
reqPayload: params, reqPayload: params,