mirror of
https://github.com/stackblitz-labs/bolt.diy
synced 2025-06-26 18:26:38 +00:00
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:
parent
fabf53b49c
commit
4795d02150
@ -6,7 +6,6 @@ import type { FileMap } from './stream-text';
|
|||||||
import { StreamingMessageParser } from '~/lib/runtime/message-parser';
|
import { StreamingMessageParser } from '~/lib/runtime/message-parser';
|
||||||
import { extractRelativePath } from '~/utils/diff';
|
import { extractRelativePath } from '~/utils/diff';
|
||||||
import { wrapWithSpan, getCurrentSpan } from '~/lib/.server/otel';
|
import { wrapWithSpan, getCurrentSpan } from '~/lib/.server/otel';
|
||||||
import { context } from '@opentelemetry/api';
|
|
||||||
|
|
||||||
const Model = 'claude-3-5-sonnet-20241022';
|
const Model = 'claude-3-5-sonnet-20241022';
|
||||||
const MaxMessageTokens = 8192;
|
const MaxMessageTokens = 8192;
|
||||||
@ -42,6 +41,10 @@ function flatMessageContent(content: string | ContentBlockParam[]): string {
|
|||||||
return "AnthropicUnknownContent";
|
return "AnthropicUnknownContent";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AnthropicApiKey {
|
||||||
|
key: string;
|
||||||
|
isUser: boolean;
|
||||||
|
}
|
||||||
export interface AnthropicCall {
|
export interface AnthropicCall {
|
||||||
systemPrompt: string;
|
systemPrompt: string;
|
||||||
messages: MessageParam[];
|
messages: MessageParam[];
|
||||||
@ -60,14 +63,15 @@ const callAnthropic = wrapWithSpan(
|
|||||||
},
|
},
|
||||||
|
|
||||||
// eslint-disable-next-line prefer-arrow-callback
|
// 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();
|
const span = getCurrentSpan();
|
||||||
span?.setAttributes({
|
span?.setAttributes({
|
||||||
"llm.chat.calls": 1, // so we can SUM(llm.chat.calls) without doing a COUNT + filter
|
"llm.chat.calls": 1, // so we can SUM(llm.chat.calls) without doing a COUNT + filter
|
||||||
"llm.chat.num_messages": messages.length,
|
"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("************************************************");
|
||||||
console.log("AnthropicMessageSend");
|
console.log("AnthropicMessageSend");
|
||||||
@ -141,7 +145,7 @@ function shouldRestorePartialFile(existingContent: string, newContent: string):
|
|||||||
async function restorePartialFile(
|
async function restorePartialFile(
|
||||||
existingContent: string,
|
existingContent: string,
|
||||||
newContent: string,
|
newContent: string,
|
||||||
apiKey: string,
|
apiKey: AnthropicApiKey,
|
||||||
responseDescription: string
|
responseDescription: string
|
||||||
) {
|
) {
|
||||||
const systemPrompt = `
|
const systemPrompt = `
|
||||||
@ -298,7 +302,7 @@ interface FileContents {
|
|||||||
content: string;
|
content: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fixupResponseFiles(files: FileMap, apiKey: string, responseText: string) {
|
async function fixupResponseFiles(files: FileMap, apiKey: AnthropicApiKey, responseText: string) {
|
||||||
const fileContents: FileContents[] = [];
|
const fileContents: FileContents[] = [];
|
||||||
|
|
||||||
const messageParser = new StreamingMessageParser({
|
const messageParser = new StreamingMessageParser({
|
||||||
@ -342,7 +346,7 @@ async function fixupResponseFiles(files: FileMap, apiKey: string, responseText:
|
|||||||
return { responseText, restoreCalls };
|
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[] = [];
|
const messageParams: MessageParam[] = [];
|
||||||
|
|
||||||
for (const message of messages) {
|
for (const message of messages) {
|
||||||
|
@ -2,7 +2,7 @@ import { type ActionFunctionArgs } from '@remix-run/cloudflare';
|
|||||||
import { ChatStreamController } from '~/utils/chatStreamController';
|
import { ChatStreamController } from '~/utils/chatStreamController';
|
||||||
import { assert } from '~/lib/replay/ReplayProtocolClient';
|
import { assert } from '~/lib/replay/ReplayProtocolClient';
|
||||||
import { getStreamTextArguments, type FileMap, type Messages } from '~/lib/.server/llm/stream-text';
|
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';
|
import { ensureOpenTelemetryInitialized } from '~/lib/.server/otel';
|
||||||
|
|
||||||
export async function action(args: ActionFunctionArgs) {
|
export async function action(args: ActionFunctionArgs) {
|
||||||
@ -41,11 +41,16 @@ async function chatAction({ context, request }: ActionFunctionArgs) {
|
|||||||
promptId,
|
promptId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const anthropicApiKey = clientAnthropicApiKey ?? context.cloudflare.env.ANTHROPIC_API_KEY;
|
const apiKey = clientAnthropicApiKey ?? context.cloudflare.env.ANTHROPIC_API_KEY;
|
||||||
if (!anthropicApiKey) {
|
if (!apiKey) {
|
||||||
throw new Error("Anthropic API key is not set");
|
throw new Error("Anthropic API key is not set");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const anthropicApiKey: AnthropicApiKey = {
|
||||||
|
key: apiKey,
|
||||||
|
isUser: !!clientAnthropicApiKey,
|
||||||
|
};
|
||||||
|
|
||||||
const resultStream = new ReadableStream({
|
const resultStream = new ReadableStream({
|
||||||
async start(controller) {
|
async start(controller) {
|
||||||
const chatController = new ChatStreamController(controller);
|
const chatController = new ChatStreamController(controller);
|
||||||
|
Loading…
Reference in New Issue
Block a user