instrument whether an api key is the user's or ours (#33)

introduce an `AnthropicApiKey` type so we aren't passing a string/boolean everywhere.
This commit is contained in:
Chris Toshok 2025-02-19 13:58:40 -08:00 committed by GitHub
parent fabf53b49c
commit 4795d02150
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 18 additions and 9 deletions

View File

@ -6,7 +6,6 @@ import type { FileMap } from './stream-text';
import { StreamingMessageParser } from '~/lib/runtime/message-parser';
import { extractRelativePath } from '~/utils/diff';
import { wrapWithSpan, getCurrentSpan } from '~/lib/.server/otel';
import { context } from '@opentelemetry/api';
const Model = 'claude-3-5-sonnet-20241022';
const MaxMessageTokens = 8192;
@ -42,6 +41,10 @@ function flatMessageContent(content: string | ContentBlockParam[]): string {
return "AnthropicUnknownContent";
}
export interface AnthropicApiKey {
key: string;
isUser: boolean;
}
export interface AnthropicCall {
systemPrompt: string;
messages: MessageParam[];
@ -60,14 +63,15 @@ const callAnthropic = wrapWithSpan(
},
// eslint-disable-next-line prefer-arrow-callback
async function callAnthropic(apiKey: string, systemPrompt: string, messages: MessageParam[]): Promise<AnthropicCall> {
async function callAnthropic(apiKey: AnthropicApiKey, systemPrompt: string, messages: MessageParam[]): Promise<AnthropicCall> {
const span = getCurrentSpan();
span?.setAttributes({
"llm.chat.calls": 1, // so we can SUM(llm.chat.calls) without doing a COUNT + filter
"llm.chat.num_messages": messages.length,
"llm.chat.is_user_api_key": apiKey.isUser,
});
const anthropic = new Anthropic({ apiKey });
const anthropic = new Anthropic({ apiKey: apiKey.key });
console.log("************************************************");
console.log("AnthropicMessageSend");
@ -141,7 +145,7 @@ function shouldRestorePartialFile(existingContent: string, newContent: string):
async function restorePartialFile(
existingContent: string,
newContent: string,
apiKey: string,
apiKey: AnthropicApiKey,
responseDescription: string
) {
const systemPrompt = `
@ -298,7 +302,7 @@ interface FileContents {
content: string;
}
async function fixupResponseFiles(files: FileMap, apiKey: string, responseText: string) {
async function fixupResponseFiles(files: FileMap, apiKey: AnthropicApiKey, responseText: string) {
const fileContents: FileContents[] = [];
const messageParser = new StreamingMessageParser({
@ -342,7 +346,7 @@ async function fixupResponseFiles(files: FileMap, apiKey: string, responseText:
return { responseText, restoreCalls };
}
export async function chatAnthropic(chatController: ChatStreamController, files: FileMap, apiKey: string, systemPrompt: string, messages: CoreMessage[]) {
export async function chatAnthropic(chatController: ChatStreamController, files: FileMap, apiKey: AnthropicApiKey, systemPrompt: string, messages: CoreMessage[]) {
const messageParams: MessageParam[] = [];
for (const message of messages) {

View File

@ -2,7 +2,7 @@ import { type ActionFunctionArgs } from '@remix-run/cloudflare';
import { ChatStreamController } from '~/utils/chatStreamController';
import { assert } from '~/lib/replay/ReplayProtocolClient';
import { getStreamTextArguments, type FileMap, type Messages } from '~/lib/.server/llm/stream-text';
import { chatAnthropic } from '~/lib/.server/llm/chat-anthropic';
import { chatAnthropic, type AnthropicApiKey } from '~/lib/.server/llm/chat-anthropic';
import { ensureOpenTelemetryInitialized } from '~/lib/.server/otel';
export async function action(args: ActionFunctionArgs) {
@ -41,11 +41,16 @@ async function chatAction({ context, request }: ActionFunctionArgs) {
promptId,
});
const anthropicApiKey = clientAnthropicApiKey ?? context.cloudflare.env.ANTHROPIC_API_KEY;
if (!anthropicApiKey) {
const apiKey = clientAnthropicApiKey ?? context.cloudflare.env.ANTHROPIC_API_KEY;
if (!apiKey) {
throw new Error("Anthropic API key is not set");
}
const anthropicApiKey: AnthropicApiKey = {
key: apiKey,
isUser: !!clientAnthropicApiKey,
};
const resultStream = new ReadableStream({
async start(controller) {
const chatController = new ChatStreamController(controller);